[clang] b5fc1de - Use libClangTesting in the unittest for AST matchers

Dmitri Gribenko via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 4 08:44:56 PDT 2020


Author: Dmitri Gribenko
Date: 2020-06-04T17:40:39+02:00
New Revision: b5fc1deb5ba1f3cd432ecb8b86c2536470463163

URL: https://github.com/llvm/llvm-project/commit/b5fc1deb5ba1f3cd432ecb8b86c2536470463163
DIFF: https://github.com/llvm/llvm-project/commit/b5fc1deb5ba1f3cd432ecb8b86c2536470463163.diff

LOG: Use libClangTesting in the unittest for AST matchers

Summary:
The unittest for AST matchers has its own way to specify language
standards. I unified it with the shared infrastructure from
libClangTesting.

Reviewers: jdoerfert, hlopko

Reviewed By: hlopko

Subscribers: mgorny, sstefan1, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D81150

Added: 
    

Modified: 
    clang/include/clang/Testing/CommandLineArgs.h
    clang/lib/Testing/CommandLineArgs.cpp
    clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
    clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
    clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
    clang/unittests/ASTMatchers/ASTMatchersTest.h
    clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
    clang/unittests/ASTMatchers/CMakeLists.txt
    clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt
    clang/unittests/Sema/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Testing/CommandLineArgs.h b/clang/include/clang/Testing/CommandLineArgs.h
index 432a112b2e15..95979a2bfb80 100644
--- a/clang/include/clang/Testing/CommandLineArgs.h
+++ b/clang/include/clang/Testing/CommandLineArgs.h
@@ -13,6 +13,8 @@
 #ifndef LLVM_CLANG_TESTING_COMMANDLINEARGS_H
 #define LLVM_CLANG_TESTING_COMMANDLINEARGS_H
 
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
 #include <string>
 #include <vector>
 
@@ -32,6 +34,8 @@ enum TestLanguage {
 
 std::vector<std::string> getCommandLineArgsForTesting(TestLanguage Lang);
 
+StringRef getFilenameForTesting(TestLanguage Lang);
+
 } // end namespace clang
 
 #endif

diff  --git a/clang/lib/Testing/CommandLineArgs.cpp b/clang/lib/Testing/CommandLineArgs.cpp
index 1d12187494be..7375dbc6ee70 100644
--- a/clang/lib/Testing/CommandLineArgs.cpp
+++ b/clang/lib/Testing/CommandLineArgs.cpp
@@ -45,4 +45,25 @@ std::vector<std::string> getCommandLineArgsForTesting(TestLanguage Lang) {
   return Args;
 }
 
+StringRef getFilenameForTesting(TestLanguage Lang) {
+  switch (Lang) {
+  case Lang_C89:
+  case Lang_C99:
+    return "input.c";
+
+  case Lang_CXX03:
+  case Lang_CXX11:
+  case Lang_CXX14:
+  case Lang_CXX17:
+  case Lang_CXX20:
+    return "input.cc";
+
+  case Lang_OpenCL:
+    return "input.cl";
+
+  case Lang_OBJCXX:
+    return "input.mm";
+  }
+}
+
 } // end namespace clang

diff  --git a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
index 2886481ea262..2354f45de409 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
@@ -212,18 +212,18 @@ TEST(Matcher, IsExpansionInMainFileMatcher) {
   M.push_back(std::make_pair("/other", "class X {};"));
   EXPECT_TRUE(matchesConditionally("#include <other>\n",
                                    recordDecl(isExpansionInMainFile()), false,
-                                   "-isystem/", M));
+                                   {"-isystem/"}, M));
 }
 
 TEST(Matcher, IsExpansionInSystemHeader) {
   FileContentMappings M;
   M.push_back(std::make_pair("/other", "class X {};"));
-  EXPECT_TRUE(matchesConditionally(
-      "#include \"other\"\n", recordDecl(isExpansionInSystemHeader()), true,
-      "-isystem/", M));
   EXPECT_TRUE(matchesConditionally("#include \"other\"\n",
                                    recordDecl(isExpansionInSystemHeader()),
-                                   false, "-I/", M));
+                                   true, {"-isystem/"}, M));
+  EXPECT_TRUE(matchesConditionally("#include \"other\"\n",
+                                   recordDecl(isExpansionInSystemHeader()),
+                                   false, {"-I/"}, M));
   EXPECT_TRUE(notMatches("class X {};",
                          recordDecl(isExpansionInSystemHeader())));
   EXPECT_TRUE(notMatches("", recordDecl(isExpansionInSystemHeader())));
@@ -238,13 +238,13 @@ TEST(Matcher, IsExpansionInFileMatching) {
       "#include <bar>\n"
       "class X {};",
       recordDecl(isExpansionInFileMatching("b.*"), hasName("B")), true,
-      "-isystem/", M));
+      {"-isystem/"}, M));
   EXPECT_TRUE(matchesConditionally(
       "#include <foo>\n"
       "#include <bar>\n"
       "class X {};",
       recordDecl(isExpansionInFileMatching("f.*"), hasName("X")), false,
-      "-isystem/", M));
+      {"-isystem/"}, M));
 }
 
 #endif // _WIN32

diff  --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 80eebf227a31..fa5c61eece29 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1101,15 +1101,13 @@ TEST(ConversionDeclaration, IsExplicit) {
                       cxxConversionDecl(isExplicit())));
   EXPECT_TRUE(notMatches("struct S { operator int(); };",
                          cxxConversionDecl(isExplicit())));
-  EXPECT_TRUE(matchesConditionally(
-      "template<bool b> struct S { explicit(b) operator int(); };",
-      cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
-  EXPECT_TRUE(matchesConditionally(
-      "struct S { explicit(true) operator int(); };",
-      cxxConversionDecl(isExplicit()), true, "-std=c++2a"));
-  EXPECT_TRUE(matchesConditionally(
-      "struct S { explicit(false) operator int(); };",
-      cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
+  EXPECT_TRUE(
+      notMatches("template<bool b> struct S { explicit(b) operator int(); };",
+                 cxxConversionDecl(isExplicit()), langCxx20OrLater()));
+  EXPECT_TRUE(matches("struct S { explicit(true) operator int(); };",
+                      cxxConversionDecl(isExplicit()), langCxx20OrLater()));
+  EXPECT_TRUE(notMatches("struct S { explicit(false) operator int(); };",
+                         cxxConversionDecl(isExplicit()), langCxx20OrLater()));
 }
 
 TEST(Matcher, ArgumentCount) {
@@ -1215,22 +1213,22 @@ TEST(isConstexpr, MatchesConstexprDeclarations) {
   EXPECT_TRUE(matches("constexpr int bar();",
                       functionDecl(hasName("bar"), isConstexpr())));
   EXPECT_TRUE(matches("void baz() { if constexpr(1 > 0) {} }",
-                      ifStmt(isConstexpr()), LanguageMode::Cxx17OrLater));
+                      ifStmt(isConstexpr()), langCxx17OrLater()));
   EXPECT_TRUE(notMatches("void baz() { if (1 > 0) {} }", ifStmt(isConstexpr()),
-                         LanguageMode::Cxx17OrLater));
+                         langCxx17OrLater()));
 }
 
 TEST(hasInitStatement, MatchesSelectionInitializers) {
   EXPECT_TRUE(matches("void baz() { if (int i = 1; i > 0) {} }",
                       ifStmt(hasInitStatement(anything())),
-                      LanguageMode::Cxx17OrLater));
+                      langCxx17OrLater()));
   EXPECT_TRUE(notMatches("void baz() { if (int i = 1) {} }",
                          ifStmt(hasInitStatement(anything()))));
   EXPECT_TRUE(notMatches("void baz() { if (1 > 0) {} }",
                          ifStmt(hasInitStatement(anything()))));
-  EXPECT_TRUE(matches(
-      "void baz(int i) { switch (int j = i; j) { default: break; } }",
-      switchStmt(hasInitStatement(anything())), LanguageMode::Cxx17OrLater));
+  EXPECT_TRUE(
+      matches("void baz(int i) { switch (int j = i; j) { default: break; } }",
+              switchStmt(hasInitStatement(anything())), langCxx17OrLater()));
   EXPECT_TRUE(notMatches("void baz(int i) { switch (i) { default: break; } }",
                          switchStmt(hasInitStatement(anything()))));
 }
@@ -1241,7 +1239,7 @@ TEST(hasInitStatement, MatchesRangeForInitializers) {
                       "for (auto &arr = items; auto &item : arr) {}"
                       "}",
                       cxxForRangeStmt(hasInitStatement(anything())),
-                      LanguageMode::Cxx2aOrLater));
+                      langCxx20OrLater()));
   EXPECT_TRUE(notMatches("void baz() {"
                          "int items[] = {};"
                          "for (auto &item : items) {}"
@@ -1463,38 +1461,33 @@ TEST(ConstructorDeclaration, IsExplicit) {
                       cxxConstructorDecl(isExplicit())));
   EXPECT_TRUE(notMatches("struct S { S(int); };",
                          cxxConstructorDecl(isExplicit())));
-  EXPECT_TRUE(matchesConditionally(
-      "template<bool b> struct S { explicit(b) S(int);};",
-      cxxConstructorDecl(isExplicit()), false, "-std=c++2a"));
-  EXPECT_TRUE(matchesConditionally("struct S { explicit(true) S(int);};",
-                                   cxxConstructorDecl(isExplicit()), true,
-                                   "-std=c++2a"));
-  EXPECT_TRUE(matchesConditionally("struct S { explicit(false) S(int);};",
-                                   cxxConstructorDecl(isExplicit()), false,
-                                   "-std=c++2a"));
+  EXPECT_TRUE(notMatches("template<bool b> struct S { explicit(b) S(int);};",
+                         cxxConstructorDecl(isExplicit()), langCxx20OrLater()));
+  EXPECT_TRUE(matches("struct S { explicit(true) S(int);};",
+                      cxxConstructorDecl(isExplicit()), langCxx20OrLater()));
+  EXPECT_TRUE(notMatches("struct S { explicit(false) S(int);};",
+                         cxxConstructorDecl(isExplicit()), langCxx20OrLater()));
 }
 
 TEST(DeductionGuideDeclaration, IsExplicit) {
-  EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int);};"
-                                   "S(int) -> S<int>;",
-                                   cxxDeductionGuideDecl(isExplicit()), false,
-                                   "-std=c++17"));
-  EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int);};"
-                                   "explicit S(int) -> S<int>;",
-                                   cxxDeductionGuideDecl(isExplicit()), true,
-                                   "-std=c++17"));
-  EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int);};"
-                                   "explicit(true) S(int) -> S<int>;",
-                                   cxxDeductionGuideDecl(isExplicit()), true,
-                                   "-std=c++2a"));
-  EXPECT_TRUE(matchesConditionally("template<typename T> struct S { S(int);};"
-                                   "explicit(false) S(int) -> S<int>;",
-                                   cxxDeductionGuideDecl(isExplicit()), false,
-                                   "-std=c++2a"));
-  EXPECT_TRUE(matchesConditionally(
-      "template<typename T> struct S { S(int);};"
-      "template<bool b = true> explicit(b) S(int) -> S<int>;",
-      cxxDeductionGuideDecl(isExplicit()), false, "-std=c++2a"));
+  EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"
+                         "S(int) -> S<int>;",
+                         cxxDeductionGuideDecl(isExplicit()),
+                         langCxx17OrLater()));
+  EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"
+                      "explicit S(int) -> S<int>;",
+                      cxxDeductionGuideDecl(isExplicit()), langCxx17OrLater()));
+  EXPECT_TRUE(matches("template<typename T> struct S { S(int);};"
+                      "explicit(true) S(int) -> S<int>;",
+                      cxxDeductionGuideDecl(isExplicit()), langCxx20OrLater()));
+  EXPECT_TRUE(notMatches("template<typename T> struct S { S(int);};"
+                         "explicit(false) S(int) -> S<int>;",
+                         cxxDeductionGuideDecl(isExplicit()),
+                         langCxx20OrLater()));
+  EXPECT_TRUE(
+      notMatches("template<typename T> struct S { S(int);};"
+                 "template<bool b = true> explicit(b) S(int) -> S<int>;",
+                 cxxDeductionGuideDecl(isExplicit()), langCxx20OrLater()));
 }
 
 TEST(ConstructorDeclaration, Kinds) {

diff  --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index c6f40955e2a0..1d262fc1a655 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -202,7 +202,7 @@ TEST(Matcher, UnresolvedLookupExpr) {
                                    "}",
                                    unresolvedLookupExpr(),
                                    /*ExpectMatch=*/true,
-                                   "-fno-delayed-template-parsing"));
+                                   {"-fno-delayed-template-parsing"}));
 }
 
 TEST(Matcher, ADLCall) {
@@ -789,50 +789,29 @@ TEST(Matcher, Initializers) {
     "  struct point ptarray[10] = "
     "      { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }";
   EXPECT_TRUE(matchesConditionally(
-    ToMatch,
-    initListExpr(
-      has(
-        cxxConstructExpr(
-          requiresZeroInitialization())),
-      has(
-        initListExpr(
-          hasType(asString("struct point")),
-          has(floatLiteral(equals(1.0))),
-          has(implicitValueInitExpr(
-            hasType(asString("double")))))),
-      has(
-        initListExpr(
-          hasType(asString("struct point")),
-          has(floatLiteral(equals(2.0))),
-          has(floatLiteral(equals(1.0)))))
-    ), true, "-std=gnu++98"));
-
-  EXPECT_TRUE(matchesC99(ToMatch,
-                         initListExpr(
-                           hasSyntacticForm(
-                             initListExpr(
-                               has(
-                                 designatedInitExpr(
-                                   designatorCountIs(2),
-                                   hasDescendant(floatLiteral(
-                                     equals(1.0))),
-                                   hasDescendant(integerLiteral(
-                                     equals(2))))),
-                               has(
-                                 designatedInitExpr(
-                                   designatorCountIs(2),
-                                   hasDescendant(floatLiteral(
-                                     equals(2.0))),
-                                   hasDescendant(integerLiteral(
-                                     equals(2))))),
-                               has(
-                                 designatedInitExpr(
-                                   designatorCountIs(2),
-                                   hasDescendant(floatLiteral(
-                                     equals(1.0))),
-                                   hasDescendant(integerLiteral(
-                                     equals(0)))))
-                             )))));
+      ToMatch,
+      initListExpr(
+          has(cxxConstructExpr(requiresZeroInitialization())),
+          has(initListExpr(
+              hasType(asString("struct point")), has(floatLiteral(equals(1.0))),
+              has(implicitValueInitExpr(hasType(asString("double")))))),
+          has(initListExpr(hasType(asString("struct point")),
+                           has(floatLiteral(equals(2.0))),
+                           has(floatLiteral(equals(1.0)))))),
+      true, {"-std=gnu++03"}));
+
+  EXPECT_TRUE(matchesC99(
+      ToMatch,
+      initListExpr(hasSyntacticForm(initListExpr(
+          has(designatedInitExpr(designatorCountIs(2),
+                                 hasDescendant(floatLiteral(equals(1.0))),
+                                 hasDescendant(integerLiteral(equals(2))))),
+          has(designatedInitExpr(designatorCountIs(2),
+                                 hasDescendant(floatLiteral(equals(2.0))),
+                                 hasDescendant(integerLiteral(equals(2))))),
+          has(designatedInitExpr(
+              designatorCountIs(2), hasDescendant(floatLiteral(equals(1.0))),
+              hasDescendant(integerLiteral(equals(0))))))))));
 }
 
 TEST(Matcher, ParenListExpr) {
@@ -1475,9 +1454,9 @@ TEST(TypeMatching, MatchesTemplateSpecializationType) {
 }
 
 TEST(TypeMatching, MatchesDeucedTemplateSpecializationType) {
-  EXPECT_TRUE(matches("template <typename T> class A{ public: A(T) {} }; A a(1);",
-                      deducedTemplateSpecializationType(),
-                      LanguageMode::Cxx17OrLater));
+  EXPECT_TRUE(
+      matches("template <typename T> class A{ public: A(T) {} }; A a(1);",
+              deducedTemplateSpecializationType(), langCxx17OrLater()));
 }
 
 TEST(TypeMatching, MatchesRecordType) {

diff  --git a/clang/unittests/ASTMatchers/ASTMatchersTest.h b/clang/unittests/ASTMatchers/ASTMatchersTest.h
index 65cb6b07af70..54f73826af60 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTest.h
+++ b/clang/unittests/ASTMatchers/ASTMatchersTest.h
@@ -11,6 +11,7 @@
 
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Frontend/ASTUnit.h"
+#include "clang/Testing/CommandLineArgs.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
 
@@ -57,21 +58,32 @@ class VerifyMatch : public MatchFinder::MatchCallback {
   const std::unique_ptr<BoundNodesCallback> FindResultReviewer;
 };
 
-enum class LanguageMode {
-  Cxx11,
-  Cxx14,
-  Cxx17,
-  Cxx2a,
-  Cxx11OrLater,
-  Cxx14OrLater,
-  Cxx17OrLater,
-  Cxx2aOrLater
-};
+inline ArrayRef<TestLanguage> langCxx11OrLater() {
+  static std::vector<TestLanguage> Result = {Lang_CXX11, Lang_CXX14, Lang_CXX17,
+                                             Lang_CXX20};
+  return Result;
+}
+
+inline ArrayRef<TestLanguage> langCxx14OrLater() {
+  static std::vector<TestLanguage> Result = {Lang_CXX14, Lang_CXX17,
+                                             Lang_CXX20};
+  return Result;
+}
+
+inline ArrayRef<TestLanguage> langCxx17OrLater() {
+  static std::vector<TestLanguage> Result = {Lang_CXX17, Lang_CXX20};
+  return Result;
+}
+
+inline ArrayRef<TestLanguage> langCxx20OrLater() {
+  static std::vector<TestLanguage> Result = {Lang_CXX20};
+  return Result;
+}
 
 template <typename T>
 testing::AssertionResult matchesConditionally(
     const Twine &Code, const T &AMatcher, bool ExpectMatch,
-    llvm::ArrayRef<llvm::StringRef> CompileArgs,
+    ArrayRef<std::string> CompileArgs,
     const FileContentMappings &VirtualMappedFiles = FileContentMappings(),
     StringRef Filename = "input.cc") {
   bool Found = false, DynamicFound = false;
@@ -115,66 +127,18 @@ testing::AssertionResult matchesConditionally(
   return testing::AssertionSuccess();
 }
 
-template <typename T>
-testing::AssertionResult matchesConditionally(
-    const Twine &Code, const T &AMatcher, bool ExpectMatch,
-    llvm::StringRef CompileArg,
-    const FileContentMappings &VirtualMappedFiles = FileContentMappings(),
-    StringRef Filename = "input.cc") {
-  return matchesConditionally(Code, AMatcher, ExpectMatch,
-                              llvm::makeArrayRef(CompileArg),
-                              VirtualMappedFiles, Filename);
-}
-
 template <typename T>
 testing::AssertionResult
 matchesConditionally(const Twine &Code, const T &AMatcher, bool ExpectMatch,
-                     const LanguageMode &Mode) {
-  std::vector<LanguageMode> LangModes;
-  switch (Mode) {
-  case LanguageMode::Cxx11:
-  case LanguageMode::Cxx14:
-  case LanguageMode::Cxx17:
-  case LanguageMode::Cxx2a:
-    LangModes = {Mode};
-    break;
-  case LanguageMode::Cxx11OrLater:
-    LangModes = {LanguageMode::Cxx11, LanguageMode::Cxx14, LanguageMode::Cxx17,
-                 LanguageMode::Cxx2a};
-    break;
-  case LanguageMode::Cxx14OrLater:
-    LangModes = {LanguageMode::Cxx14, LanguageMode::Cxx17, LanguageMode::Cxx2a};
-    break;
-  case LanguageMode::Cxx17OrLater:
-    LangModes = {LanguageMode::Cxx17, LanguageMode::Cxx2a};
-    break;
-  case LanguageMode::Cxx2aOrLater:
-    LangModes = {LanguageMode::Cxx2a};
-  }
-
-  for (auto Mode : LangModes) {
-    StringRef LangModeArg;
-    switch (Mode) {
-    case LanguageMode::Cxx11:
-      LangModeArg = "-std=c++11";
-      break;
-    case LanguageMode::Cxx14:
-      LangModeArg = "-std=c++14";
-      break;
-    case LanguageMode::Cxx17:
-      LangModeArg = "-std=c++17";
-      break;
-    case LanguageMode::Cxx2a:
-      LangModeArg = "-std=c++2a";
-      break;
-    default:
-      llvm_unreachable("Invalid language mode");
-    }
-
-    auto Result = matchesConditionally(Code, AMatcher, ExpectMatch,
-                                       {LangModeArg, "-Werror=c++14-extensions",
-                                        "-Werror=c++17-extensions",
-                                        "-Werror=c++20-extensions"});
+                     ArrayRef<TestLanguage> TestLanguages) {
+  for (auto Lang : TestLanguages) {
+    std::vector<std::string> Args = getCommandLineArgsForTesting(Lang);
+    Args.insert(Args.end(),
+                {"-Werror=c++14-extensions", "-Werror=c++17-extensions",
+                 "-Werror=c++20-extensions"});
+    auto Result = matchesConditionally(Code, AMatcher, ExpectMatch, Args,
+                                       FileContentMappings(),
+                                       getFilenameForTesting(Lang));
     if (!Result)
       return Result;
   }
@@ -185,15 +149,15 @@ matchesConditionally(const Twine &Code, const T &AMatcher, bool ExpectMatch,
 template <typename T>
 testing::AssertionResult
 matches(const Twine &Code, const T &AMatcher,
-        const LanguageMode &Mode = LanguageMode::Cxx11) {
-  return matchesConditionally(Code, AMatcher, true, Mode);
+        ArrayRef<TestLanguage> TestLanguages = {Lang_CXX11}) {
+  return matchesConditionally(Code, AMatcher, true, TestLanguages);
 }
 
 template <typename T>
 testing::AssertionResult
 notMatches(const Twine &Code, const T &AMatcher,
-           const LanguageMode &Mode = LanguageMode::Cxx11) {
-  return matchesConditionally(Code, AMatcher, false, Mode);
+           ArrayRef<TestLanguage> TestLanguages = {Lang_CXX11}) {
+  return matchesConditionally(Code, AMatcher, false, TestLanguages);
 }
 
 template <typename T>
@@ -207,20 +171,18 @@ testing::AssertionResult matchesObjC(const Twine &Code, const T &AMatcher,
 
 template <typename T>
 testing::AssertionResult matchesC(const Twine &Code, const T &AMatcher) {
-  return matchesConditionally(Code, AMatcher, true, "", FileContentMappings(),
+  return matchesConditionally(Code, AMatcher, true, {}, FileContentMappings(),
                               "input.c");
 }
 
 template <typename T>
 testing::AssertionResult matchesC99(const Twine &Code, const T &AMatcher) {
-  return matchesConditionally(Code, AMatcher, true, "-std=c99",
-                              FileContentMappings(), "input.c");
+  return matchesConditionally(Code, AMatcher, true, {Lang_C99});
 }
 
 template <typename T>
 testing::AssertionResult notMatchesC(const Twine &Code, const T &AMatcher) {
-  return matchesConditionally(Code, AMatcher, false, "", FileContentMappings(),
-                              "input.c");
+  return matchesConditionally(Code, AMatcher, false, {Lang_C89});
 }
 
 template <typename T>
@@ -302,13 +264,13 @@ testing::AssertionResult notMatchesWithCuda(const Twine &Code,
 template <typename T>
 testing::AssertionResult matchesWithOpenMP(const Twine &Code,
                                            const T &AMatcher) {
-  return matchesConditionally(Code, AMatcher, true, "-fopenmp=libomp");
+  return matchesConditionally(Code, AMatcher, true, {"-fopenmp=libomp"});
 }
 
 template <typename T>
 testing::AssertionResult notMatchesWithOpenMP(const Twine &Code,
                                               const T &AMatcher) {
-  return matchesConditionally(Code, AMatcher, false, "-fopenmp=libomp");
+  return matchesConditionally(Code, AMatcher, false, {"-fopenmp=libomp"});
 }
 
 template <typename T>

diff  --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 445bfd0b9f15..50d101167ff2 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -951,13 +951,13 @@ TEST(TemplateTypeParmDecl, VarTemplatePartialSpecializationDecl) {
       "template<typename U2>\n"
       "int Struct<U>::field<U2*> = 123;\n";
   EXPECT_TRUE(
-      matches(input, templateTypeParmDecl(hasName("T")), LanguageMode::Cxx14));
+      matches(input, templateTypeParmDecl(hasName("T")), langCxx14OrLater()));
   EXPECT_TRUE(
-      matches(input, templateTypeParmDecl(hasName("T2")), LanguageMode::Cxx14));
+      matches(input, templateTypeParmDecl(hasName("T2")), langCxx14OrLater()));
   EXPECT_TRUE(
-      matches(input, templateTypeParmDecl(hasName("U")), LanguageMode::Cxx14));
+      matches(input, templateTypeParmDecl(hasName("U")), langCxx14OrLater()));
   EXPECT_TRUE(
-      matches(input, templateTypeParmDecl(hasName("U2")), LanguageMode::Cxx14));
+      matches(input, templateTypeParmDecl(hasName("U2")), langCxx14OrLater()));
 }
 
 TEST(TemplateTypeParmDecl, ClassTemplatePartialSpecializationDecl) {
@@ -1487,18 +1487,18 @@ TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
 TEST(Member, MatchesMemberAllocationFunction) {
   // Fails in C++11 mode
   EXPECT_TRUE(matchesConditionally(
-    "namespace std { typedef typeof(sizeof(int)) size_t; }"
+      "namespace std { typedef typeof(sizeof(int)) size_t; }"
       "class X { void *operator new(std::size_t); };",
-    cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
+      cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
 
   EXPECT_TRUE(matches("class X { void operator delete(void*); };",
                       cxxMethodDecl(ofClass(hasName("X")))));
 
   // Fails in C++11 mode
   EXPECT_TRUE(matchesConditionally(
-    "namespace std { typedef typeof(sizeof(int)) size_t; }"
+      "namespace std { typedef typeof(sizeof(int)) size_t; }"
       "class X { void operator delete[](void*, std::size_t); };",
-    cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
+      cxxMethodDecl(ofClass(hasName("X"))), true, {"-std=gnu++03"}));
 }
 
 TEST(HasDestinationType, MatchesSimpleCase) {
@@ -1542,7 +1542,7 @@ TEST(Matcher, IgnoresElidableConstructors) {
               cxxOperatorCallExpr(hasArgument(
                   1, callExpr(hasArgument(
                          0, ignoringElidableConstructorCall(callExpr()))))),
-              LanguageMode::Cxx11OrLater));
+              langCxx11OrLater()));
   EXPECT_TRUE(
       matches("struct H {};"
               "template<typename T> H B(T A);"
@@ -1553,7 +1553,7 @@ TEST(Matcher, IgnoresElidableConstructors) {
               cxxOperatorCallExpr(hasArgument(
                   1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
                                                  integerLiteral()))))),
-              LanguageMode::Cxx11OrLater));
+              langCxx11OrLater()));
   EXPECT_TRUE(matches(
       "struct H {};"
       "H G();"
@@ -1563,7 +1563,7 @@ TEST(Matcher, IgnoresElidableConstructors) {
       varDecl(hasInitializer(anyOf(
           ignoringElidableConstructorCall(callExpr()),
           exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())))))),
-      LanguageMode::Cxx11OrLater));
+      langCxx11OrLater()));
 }
 
 TEST(Matcher, IgnoresElidableInReturn) {
@@ -1573,12 +1573,12 @@ TEST(Matcher, IgnoresElidableInReturn) {
                       "  H g;"
                       "  return g;"
                       "}",
-                      matcher, LanguageMode::Cxx11OrLater));
+                      matcher, langCxx11OrLater()));
   EXPECT_TRUE(notMatches("struct H {};"
                          "H f() {"
                          "  return H();"
                          "}",
-                         matcher, LanguageMode::Cxx11OrLater));
+                         matcher, langCxx11OrLater()));
 }
 
 TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
@@ -1588,7 +1588,7 @@ TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
                       "}",
                       varDecl(hasInitializer(
                           ignoringElidableConstructorCall(cxxConstructExpr()))),
-                      LanguageMode::Cxx11OrLater));
+                      langCxx11OrLater()));
 }
 
 TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
@@ -1596,7 +1596,7 @@ TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
                       "  int D = 10;"
                       "}",
                       expr(ignoringElidableConstructorCall(integerLiteral())),
-                      LanguageMode::Cxx11OrLater));
+                      langCxx11OrLater()));
 }
 
 TEST(Matcher, IgnoresElidableInVarInit) {
@@ -1607,13 +1607,13 @@ TEST(Matcher, IgnoresElidableInVarInit) {
                       "void f(H D = G()) {"
                       "  return;"
                       "}",
-                      matcher, LanguageMode::Cxx11OrLater));
+                      matcher, langCxx11OrLater()));
   EXPECT_TRUE(matches("struct H {};"
                       "H G();"
                       "void f() {"
                       "  H D = G();"
                       "}",
-                      matcher, LanguageMode::Cxx11OrLater));
+                      matcher, langCxx11OrLater()));
 }
 
 TEST(IgnoringImplicit, MatchesImplicit) {
@@ -2070,7 +2070,7 @@ void func14() {
               traverse(TK_IgnoreUnlessSpelledInSource,
                        returnStmt(forFunction(functionDecl(hasName("func1"))),
                                   hasReturnValue(integerLiteral(equals(42))))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
@@ -2078,7 +2078,7 @@ void func14() {
                        integerLiteral(equals(42),
                                       hasParent(returnStmt(forFunction(
                                           functionDecl(hasName("func1"))))))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(matches(
       Code,
@@ -2086,7 +2086,7 @@ void func14() {
                returnStmt(forFunction(functionDecl(hasName("func2"))),
                           hasReturnValue(cxxTemporaryObjectExpr(
                               hasArgument(0, integerLiteral(equals(42))))))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
   EXPECT_TRUE(matches(
       Code,
       traverse(
@@ -2094,7 +2094,7 @@ void func14() {
           integerLiteral(equals(42),
                          hasParent(cxxTemporaryObjectExpr(hasParent(returnStmt(
                              forFunction(functionDecl(hasName("func2"))))))))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
 
   EXPECT_TRUE(matches(
       Code,
@@ -2103,7 +2103,7 @@ void func14() {
           returnStmt(forFunction(functionDecl(hasName("func3"))),
                      hasReturnValue(cxxFunctionalCastExpr(
                          hasSourceExpression(integerLiteral(equals(42))))))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
 
   EXPECT_TRUE(matches(
       Code,
@@ -2112,35 +2112,35 @@ void func14() {
           integerLiteral(equals(42),
                          hasParent(cxxFunctionalCastExpr(hasParent(returnStmt(
                              forFunction(functionDecl(hasName("func3"))))))))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
               traverse(TK_IgnoreUnlessSpelledInSource,
                        returnStmt(forFunction(functionDecl(hasName("func4"))),
                                   hasReturnValue(cxxTemporaryObjectExpr()))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
               traverse(TK_IgnoreUnlessSpelledInSource,
                        returnStmt(forFunction(functionDecl(hasName("func5"))),
                                   hasReturnValue(cxxTemporaryObjectExpr()))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
               traverse(TK_IgnoreUnlessSpelledInSource,
                        returnStmt(forFunction(functionDecl(hasName("func6"))),
                                   hasReturnValue(cxxTemporaryObjectExpr()))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
               traverse(TK_IgnoreUnlessSpelledInSource,
                        returnStmt(forFunction(functionDecl(hasName("func7"))),
                                   hasReturnValue(cxxTemporaryObjectExpr()))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
@@ -2148,7 +2148,7 @@ void func14() {
                        returnStmt(forFunction(functionDecl(hasName("func8"))),
                                   hasReturnValue(cxxFunctionalCastExpr(
                                       hasSourceExpression(initListExpr()))))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
@@ -2156,7 +2156,7 @@ void func14() {
                        returnStmt(forFunction(functionDecl(hasName("func9"))),
                                   hasReturnValue(cxxFunctionalCastExpr(
                                       hasSourceExpression(initListExpr()))))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(matches(
       Code,
@@ -2164,7 +2164,7 @@ void func14() {
           TK_IgnoreUnlessSpelledInSource,
           returnStmt(forFunction(functionDecl(hasName("func10"))),
                      hasReturnValue(declRefExpr(to(varDecl(hasName("a"))))))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
@@ -2172,7 +2172,7 @@ void func14() {
                        declRefExpr(to(varDecl(hasName("a"))),
                                    hasParent(returnStmt(forFunction(
                                        functionDecl(hasName("func10"))))))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(matches(
       Code,
@@ -2180,7 +2180,7 @@ void func14() {
           TK_IgnoreUnlessSpelledInSource,
           returnStmt(forFunction(functionDecl(hasName("func11"))),
                      hasReturnValue(declRefExpr(to(varDecl(hasName("b"))))))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
@@ -2188,7 +2188,7 @@ void func14() {
                        declRefExpr(to(varDecl(hasName("b"))),
                                    hasParent(returnStmt(forFunction(
                                        functionDecl(hasName("func11"))))))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(matches(
       Code,
@@ -2196,7 +2196,7 @@ void func14() {
           TK_IgnoreUnlessSpelledInSource,
           returnStmt(forFunction(functionDecl(hasName("func12"))),
                      hasReturnValue(declRefExpr(to(varDecl(hasName("c"))))))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
@@ -2204,7 +2204,7 @@ void func14() {
                        declRefExpr(to(varDecl(hasName("c"))),
                                    hasParent(returnStmt(forFunction(
                                        functionDecl(hasName("func12"))))))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(matches(
       Code,
@@ -2216,7 +2216,7 @@ void func14() {
                      has(varDecl(hasName("b"), hasInitializer(declRefExpr(to(
                                                    varDecl(hasName("c"))))))),
                      has(parmVarDecl(hasName("d"))))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
 
   EXPECT_TRUE(
       matches(Code,
@@ -2224,7 +2224,7 @@ void func14() {
                        declRefExpr(to(varDecl(hasName("a"))),
                                    hasParent(lambdaExpr(forFunction(
                                        functionDecl(hasName("func13"))))))),
-              LanguageMode::Cxx2a));
+              langCxx20OrLater()));
 
   EXPECT_TRUE(matches(
       Code,
@@ -2233,20 +2233,20 @@ void func14() {
                        hasInitializer(declRefExpr(to(varDecl(hasName("c"))))),
                        hasParent(lambdaExpr(
                            forFunction(functionDecl(hasName("func13"))))))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
 
   EXPECT_TRUE(matches(
       Code,
       traverse(TK_IgnoreUnlessSpelledInSource,
                lambdaExpr(forFunction(functionDecl(hasName("func14"))),
                           has(templateTypeParmDecl(hasName("TemplateType"))))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
 
   EXPECT_TRUE(matches(
       Code,
       traverse(TK_IgnoreUnlessSpelledInSource,
                functionDecl(hasName("func14"), hasDescendant(floatLiteral()))),
-      LanguageMode::Cxx2a));
+      langCxx20OrLater()));
 }
 
 TEST(IgnoringImpCasts, MatchesImpCasts) {
@@ -2481,68 +2481,63 @@ TEST(SwitchCase, MatchesEachCase) {
 
 TEST(Declaration, HasExplicitSpecifier) {
 
-  EXPECT_TRUE(matchesConditionally(
-      "void f();", functionDecl(hasExplicitSpecifier(constantExpr())), false,
-      "-std=c++2a"));
-  EXPECT_TRUE(matchesConditionally(
-      "template<bool b> struct S { explicit operator int(); };",
-      cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
-      false, "-std=c++2a"));
-  EXPECT_TRUE(matchesConditionally(
-      "template<bool b> struct S { explicit(b) operator int(); };",
-      cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
-      false, "-std=c++2a"));
-  EXPECT_TRUE(
-      matchesConditionally("struct S { explicit(true) operator int(); };",
-                           traverse(ast_type_traits::TK_AsIs,
-                                    cxxConversionDecl(hasExplicitSpecifier(
-                                        constantExpr(has(cxxBoolLiteral()))))),
-                           true, "-std=c++2a"));
-  EXPECT_TRUE(
-      matchesConditionally("struct S { explicit(false) operator int(); };",
-                           traverse(ast_type_traits::TK_AsIs,
-                                    cxxConversionDecl(hasExplicitSpecifier(
-                                        constantExpr(has(cxxBoolLiteral()))))),
-                           true, "-std=c++2a"));
-  EXPECT_TRUE(
-      matchesConditionally("template<bool b> struct S { explicit(b) S(int); };",
-                           traverse(ast_type_traits::TK_AsIs,
-                                    cxxConstructorDecl(hasExplicitSpecifier(
-                                        constantExpr(has(cxxBoolLiteral()))))),
-                           false, "-std=c++2a"));
-  EXPECT_TRUE(
-      matchesConditionally("struct S { explicit(true) S(int); };",
-                           traverse(ast_type_traits::TK_AsIs,
-                                    cxxConstructorDecl(hasExplicitSpecifier(
-                                        constantExpr(has(cxxBoolLiteral()))))),
-                           true, "-std=c++2a"));
-  EXPECT_TRUE(
-      matchesConditionally("struct S { explicit(false) S(int); };",
-                           traverse(ast_type_traits::TK_AsIs,
-                                    cxxConstructorDecl(hasExplicitSpecifier(
-                                        constantExpr(has(cxxBoolLiteral()))))),
-                           true, "-std=c++2a"));
-  EXPECT_TRUE(matchesConditionally(
-      "template<typename T> struct S { S(int); };"
-      "template<bool b = true> explicit(b) S(int) -> S<int>;",
-      traverse(ast_type_traits::TK_AsIs,
-               cxxDeductionGuideDecl(
-                   hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral()))))),
-      false, "-std=c++2a"));
-  EXPECT_TRUE(
-      matchesConditionally("template<typename T> struct S { S(int); };"
-                           "explicit(true) S(int) -> S<int>;",
-                           traverse(ast_type_traits::TK_AsIs,
-                                    cxxDeductionGuideDecl(hasExplicitSpecifier(
-                                        constantExpr(has(cxxBoolLiteral()))))),
-                           true, "-std=c++2a"));
-  EXPECT_TRUE(
-      matchesConditionally("template<typename T> struct S { S(int); };"
-                           "explicit(false) S(int) -> S<int>;",
-                           traverse(ast_type_traits::TK_AsIs,
-                                    cxxDeductionGuideDecl(hasExplicitSpecifier(
-                                        constantExpr(has(cxxBoolLiteral()))))),
-                           true, "-std=c++2a"));
+  EXPECT_TRUE(notMatches("void f();",
+                         functionDecl(hasExplicitSpecifier(constantExpr())),
+                         langCxx20OrLater()));
+  EXPECT_TRUE(
+      notMatches("template<bool b> struct S { explicit operator int(); };",
+                 cxxConversionDecl(
+                     hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
+                 langCxx20OrLater()));
+  EXPECT_TRUE(
+      notMatches("template<bool b> struct S { explicit(b) operator int(); };",
+                 cxxConversionDecl(
+                     hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral())))),
+                 langCxx20OrLater()));
+  EXPECT_TRUE(matches("struct S { explicit(true) operator int(); };",
+                      traverse(ast_type_traits::TK_AsIs,
+                               cxxConversionDecl(hasExplicitSpecifier(
+                                   constantExpr(has(cxxBoolLiteral()))))),
+                      langCxx20OrLater()));
+  EXPECT_TRUE(matches("struct S { explicit(false) operator int(); };",
+                      traverse(ast_type_traits::TK_AsIs,
+                               cxxConversionDecl(hasExplicitSpecifier(
+                                   constantExpr(has(cxxBoolLiteral()))))),
+                      langCxx20OrLater()));
+  EXPECT_TRUE(notMatches("template<bool b> struct S { explicit(b) S(int); };",
+                         traverse(ast_type_traits::TK_AsIs,
+                                  cxxConstructorDecl(hasExplicitSpecifier(
+                                      constantExpr(has(cxxBoolLiteral()))))),
+                         langCxx20OrLater()));
+  EXPECT_TRUE(matches("struct S { explicit(true) S(int); };",
+                      traverse(ast_type_traits::TK_AsIs,
+                               cxxConstructorDecl(hasExplicitSpecifier(
+                                   constantExpr(has(cxxBoolLiteral()))))),
+                      langCxx20OrLater()));
+  EXPECT_TRUE(matches("struct S { explicit(false) S(int); };",
+                      traverse(ast_type_traits::TK_AsIs,
+                               cxxConstructorDecl(hasExplicitSpecifier(
+                                   constantExpr(has(cxxBoolLiteral()))))),
+                      langCxx20OrLater()));
+  EXPECT_TRUE(
+      notMatches("template<typename T> struct S { S(int); };"
+                 "template<bool b = true> explicit(b) S(int) -> S<int>;",
+                 traverse(ast_type_traits::TK_AsIs,
+                          cxxDeductionGuideDecl(hasExplicitSpecifier(
+                              constantExpr(has(cxxBoolLiteral()))))),
+                 langCxx20OrLater()));
+  EXPECT_TRUE(matches("template<typename T> struct S { S(int); };"
+                      "explicit(true) S(int) -> S<int>;",
+                      traverse(ast_type_traits::TK_AsIs,
+                               cxxDeductionGuideDecl(hasExplicitSpecifier(
+                                   constantExpr(has(cxxBoolLiteral()))))),
+                      langCxx20OrLater()));
+  EXPECT_TRUE(matches("template<typename T> struct S { S(int); };"
+                      "explicit(false) S(int) -> S<int>;",
+                      traverse(ast_type_traits::TK_AsIs,
+                               cxxDeductionGuideDecl(hasExplicitSpecifier(
+                                   constantExpr(has(cxxBoolLiteral()))))),
+                      langCxx20OrLater()));
 }
 
 TEST(ForEachConstructorInitializer, MatchesInitializers) {

diff  --git a/clang/unittests/ASTMatchers/CMakeLists.txt b/clang/unittests/ASTMatchers/CMakeLists.txt
index bcc829ac6466..c9ac6c57d689 100644
--- a/clang/unittests/ASTMatchers/CMakeLists.txt
+++ b/clang/unittests/ASTMatchers/CMakeLists.txt
@@ -27,6 +27,7 @@ clang_target_link_libraries(ASTMatchersTests
   clangBasic
   clangFrontend
   clangSerialization
+  clangTesting
   clangTooling
   )
 

diff  --git a/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt b/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt
index 85556b01cae1..7a0ba01f838b 100644
--- a/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt
+++ b/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt
@@ -17,5 +17,6 @@ clang_target_link_libraries(DynamicASTMatchersTests
   clangDynamicASTMatchers
   clangFrontend
   clangSerialization
+  clangTesting
   clangTooling
   )

diff  --git a/clang/unittests/Sema/CMakeLists.txt b/clang/unittests/Sema/CMakeLists.txt
index 24105d7756f4..194b7640b3c1 100644
--- a/clang/unittests/Sema/CMakeLists.txt
+++ b/clang/unittests/Sema/CMakeLists.txt
@@ -18,6 +18,7 @@ clang_target_link_libraries(SemaTests
   clangParse
   clangSema
   clangSerialization
+  clangTesting
   clangTooling
   )
 


        


More information about the cfe-commits mailing list