diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index e70d1ec3fac7..74bbf9e47334 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -307,6 +307,19 @@ Example matches X, Z
+
| Matcher<Decl> | translationUnitDecl | Matcher<TranslationUnitDecl>... |
+Matches the top declaration context.
+
+Given
+ int X;
+ namespace NS {
+ int Y;
+ } namespace NS
+decl(hasDeclContext(translationUnitDecl()))
+ matches "int X", but not "int Y".
+ |
+
+
| Matcher<Decl> | typedefDecl | Matcher<TypedefDecl>... |
Matches typedef declarations.
@@ -1525,7 +1538,7 @@ Usable as: Matcher<CXXRecordDecl> | isDerivedFrom | StringRef BaseName |
+| Matcher<CXXRecordDecl> | isDerivedFrom | std::string BaseName |
Overloaded method as shortcut for isDerivedFrom(hasName(...)).
|
@@ -1544,7 +1557,7 @@ Usable as: Matcher<CXXRecordDecl>isSameOrDerivedFrom | StringRef BaseName |
+| Matcher<CXXRecordDecl> | isSameOrDerivedFrom | std::string BaseName |
Overloaded method as shortcut for
isSameOrDerivedFrom(hasName(...)).
|
@@ -1721,19 +1734,6 @@ by the compiler (eg. implicit defaultcopy constructors).
-| Matcher<Decl> | isInstantiated | |
-Matches declarations that are template instantiations or are inside
-template instantiations.
-
-Given
- template<typename T> void A(T t) { T i; }
- A(0);
- A(0U);
-functionDecl(isInstantiated())
- matches 'A(int) {...};' and 'A(unsigned) {...}'.
- |
-
-
| Matcher<Decl> | isPrivate | |
Matches private C++ declarations.
@@ -2093,22 +2093,6 @@ Usable as: Matcher<Stmt> | isInTemplateInstantiation | |
-Matches statements inside of a template instantiation.
-
-Given
- int j;
- template<typename T> void A(T t) { T i; j += 42;}
- A(0);
- A(0U);
-declStmt(isInTemplateInstantiation())
- matches 'int i;' and 'unsigned i'.
-unless(stmt(isInTemplateInstantiation()))
- will NOT match j += 42; as it's shared between the template definition and
- instantiation.
- |
-
-
| Matcher<TagDecl> | isDefinition | |
Matches if a declaration has a body attached.
@@ -2229,6 +2213,16 @@ and reference to that variable declaration within a compound statement.
|
+| Matcher<Type> | voidType | |
+Matches type void.
+
+Given
+ struct S { void func(); };
+functionDecl(returns(voidType()))
+ matches "void func();"
+ |
+
+
| Matcher<UnaryExprOrTypeTraitExpr> | ofKind | UnaryExprOrTypeTrait Kind |
Matches unary expressions of a certain kind.
@@ -2323,6 +2317,35 @@ recordDecl(hasName("::X"), isTemplateInstantiation())
Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
|
+
+| Matcher<internal::Matcher<Decl>> | isInstantiated | |
+Matches declarations that are template instantiations or are inside
+template instantiations.
+
+Given
+ template<typename T> void A(T t) { T i; }
+ A(0);
+ A(0U);
+functionDecl(isInstantiated())
+ matches 'A(int) {...};' and 'A(unsigned) {...}'.
+ |
+
+
+| Matcher<internal::Matcher<Stmt>> | isInTemplateInstantiation | |
+Matches statements inside of a template instantiation.
+
+Given
+ int j;
+ template<typename T> void A(T t) { T i; j += 42;}
+ A(0);
+ A(0U);
+declStmt(isInTemplateInstantiation())
+ matches 'int i;' and 'unsigned i'.
+unless(stmt(isInTemplateInstantiation()))
+ will NOT match j += 42; as it's shared between the template definition and
+ instantiation.
+ |
+
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index f002cb9cbaba..f317981517fd 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -143,6 +143,20 @@ typedef internal::Matcher NestedNameSpecifierLocMatcher;
/// Usable as: Any Matcher
inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
+/// \brief Matches the top declaration context.
+///
+/// Given
+/// \code
+/// int X;
+/// namespace NS {
+/// int Y;
+/// } // namespace NS
+/// \endcode
+/// decl(hasDeclContext(translationUnitDecl()))
+/// matches "int X", but not "int Y".
+const internal::VariadicDynCastAllOfMatcher
+ translationUnitDecl;
+
/// \brief Matches typedef declarations.
///
/// Given
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index d550a89cad49..c074279a9097 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -315,6 +315,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(throughUsingDecl);
REGISTER_MATCHER(throwExpr);
REGISTER_MATCHER(to);
+ REGISTER_MATCHER(translationUnitDecl);
REGISTER_MATCHER(tryStmt);
REGISTER_MATCHER(type);
REGISTER_MATCHER(typedefDecl);
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
index 6485803a965e..0d27b5db0348 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -379,6 +379,21 @@ TEST(DeclarationMatcher, hasDeclContext) {
EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl()))));
}
+TEST(DeclarationMatcher, translationUnitDecl) {
+ const std::string Code = "int MyVar1;\n"
+ "namespace NameSpace {\n"
+ "int MyVar2;\n"
+ "} // namespace NameSpace\n";
+ EXPECT_TRUE(matches(
+ Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl()))));
+ EXPECT_FALSE(matches(
+ Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl()))));
+ EXPECT_TRUE(matches(
+ Code,
+ varDecl(hasName("MyVar2"),
+ hasDeclContext(decl(hasDeclContext(translationUnitDecl()))))));
+}
+
TEST(DeclarationMatcher, LinkageSpecification) {
EXPECT_TRUE(matches("extern \"C\" { void foo() {}; }", linkageSpecDecl()));
EXPECT_TRUE(notMatches("void foo() {};", linkageSpecDecl()));