Updated to Clang 3.5a.
Change-Id: I8127eb568f674c2e72635b639a3295381fe8af82
diff --git a/unittests/AST/ASTContextParentMapTest.cpp b/unittests/AST/ASTContextParentMapTest.cpp
index c1910a8..0dcb175 100644
--- a/unittests/AST/ASTContextParentMapTest.cpp
+++ b/unittests/AST/ASTContextParentMapTest.cpp
@@ -12,11 +12,11 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
+#include "MatchVerifier.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"
-#include "MatchVerifier.h"
namespace clang {
namespace ast_matchers {
diff --git a/unittests/AST/ASTTypeTraitsTest.cpp b/unittests/AST/ASTTypeTraitsTest.cpp
index dd73b52..0e73f76 100644
--- a/unittests/AST/ASTTypeTraitsTest.cpp
+++ b/unittests/AST/ASTTypeTraitsTest.cpp
@@ -9,8 +9,8 @@
#include "clang/AST/ASTTypeTraits.h"
-#include "gtest/gtest.h"
#include "MatchVerifier.h"
+#include "gtest/gtest.h"
using namespace clang::ast_matchers;
@@ -34,6 +34,19 @@
EXPECT_TRUE(DNT<Decl>().isSame(DNT<Decl>()));
}
+TEST(ASTNodeKind, BaseDistances) {
+ unsigned Distance = 1;
+ EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<Expr>(), &Distance));
+ EXPECT_EQ(0u, Distance);
+
+ EXPECT_TRUE(DNT<Stmt>().isBaseOf(DNT<IfStmt>(), &Distance));
+ EXPECT_EQ(1u, Distance);
+
+ Distance = 3;
+ EXPECT_TRUE(DNT<DeclaratorDecl>().isBaseOf(DNT<ParmVarDecl>(), &Distance));
+ EXPECT_EQ(2u, Distance);
+}
+
TEST(ASTNodeKind, SameBase) {
EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<CallExpr>()));
EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<BinaryOperator>()));
diff --git a/unittests/AST/CMakeLists.txt b/unittests/AST/CMakeLists.txt
index 70f86d3..9a55626 100644
--- a/unittests/AST/CMakeLists.txt
+++ b/unittests/AST/CMakeLists.txt
@@ -1,3 +1,7 @@
+set(LLVM_LINK_COMPONENTS
+ Support
+ )
+
add_clang_unittest(ASTTests
ASTContextParentMapTest.cpp
ASTTypeTraitsTest.cpp
@@ -6,10 +10,16 @@
CommentParser.cpp
DeclPrinterTest.cpp
DeclTest.cpp
+ EvaluateAsRValueTest.cpp
+ ExternalASTSourceTest.cpp
SourceLocationTest.cpp
StmtPrinterTest.cpp
)
target_link_libraries(ASTTests
- clangAST clangASTMatchers clangTooling
+ clangAST
+ clangASTMatchers
+ clangBasic
+ clangFrontend
+ clangTooling
)
diff --git a/unittests/AST/CommentParser.cpp b/unittests/AST/CommentParser.cpp
index f75c636..c72aef1 100644
--- a/unittests/AST/CommentParser.cpp
+++ b/unittests/AST/CommentParser.cpp
@@ -1420,6 +1420,26 @@
}
}
+TEST_F(CommentParserTest, Deprecated) {
+ const char *Sources[] = {
+ "/** @deprecated*/",
+ "/// @deprecated\n"
+ };
+
+ for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
+ FullComment *FC = parseString(Sources[i]);
+ ASSERT_TRUE(HasChildCount(FC, 2));
+
+ ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
+ {
+ BlockCommandComment *BCC;
+ ParagraphComment *PC;
+ ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "deprecated", PC));
+ ASSERT_TRUE(HasChildCount(PC, 0));
+ }
+ }
+}
+
} // unnamed namespace
} // end namespace comments
diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp
index 44fa742..5340756 100644
--- a/unittests/AST/DeclPrinterTest.cpp
+++ b/unittests/AST/DeclPrinterTest.cpp
@@ -74,10 +74,12 @@
PrintMatch Printer;
MatchFinder Finder;
Finder.addMatcher(NodeMatch, &Printer);
- OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
+ std::unique_ptr<FrontendActionFactory> Factory(
+ newFrontendActionFactory(&Finder));
if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
- return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
+ return testing::AssertionFailure()
+ << "Parsing error in \"" << Code.str() << "\"";
if (Printer.getNumFoundDecls() == 0)
return testing::AssertionFailure()
@@ -90,8 +92,8 @@
if (Printer.getPrinted() != ExpectedPrinted)
return ::testing::AssertionFailure()
- << "Expected \"" << ExpectedPrinted << "\", "
- "got \"" << Printer.getPrinted() << "\"";
+ << "Expected \"" << ExpectedPrinted.str() << "\", "
+ "got \"" << Printer.getPrinted().str() << "\"";
return ::testing::AssertionSuccess();
}
@@ -142,6 +144,19 @@
"input.cc");
}
+::testing::AssertionResult PrintedDeclCXX11nonMSCMatches(
+ StringRef Code,
+ const DeclarationMatcher &NodeMatch,
+ StringRef ExpectedPrinted) {
+ std::vector<std::string> Args(1, "-std=c++11");
+ Args.push_back("-fno-delayed-template-parsing");
+ return PrintedDeclMatches(Code,
+ Args,
+ NodeMatch,
+ ExpectedPrinted,
+ "input.cc");
+}
+
::testing::AssertionResult PrintedDeclObjCMatches(
StringRef Code,
const DeclarationMatcher &NodeMatch,
@@ -156,6 +171,40 @@
} // unnamed namespace
+TEST(DeclPrinter, TestTypedef1) {
+ ASSERT_TRUE(PrintedDeclCXX98Matches(
+ "typedef int A;",
+ "A",
+ "typedef int A"));
+ // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTypedef2) {
+ ASSERT_TRUE(PrintedDeclCXX98Matches(
+ "typedef const char *A;",
+ "A",
+ "typedef const char *A"));
+ // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTypedef3) {
+ ASSERT_TRUE(PrintedDeclCXX98Matches(
+ "template <typename Y> class X {};"
+ "typedef X<int> A;",
+ "A",
+ "typedef X<int> A"));
+ // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTypedef4) {
+ ASSERT_TRUE(PrintedDeclCXX98Matches(
+ "namespace X { class Y {}; }"
+ "typedef X::Y A;",
+ "A",
+ "typedef X::Y A"));
+ // Should be: with semicolon
+}
+
TEST(DeclPrinter, TestNamespace1) {
ASSERT_TRUE(PrintedDeclCXX98Matches(
"namespace A { int B; }",
@@ -340,8 +389,8 @@
ASSERT_TRUE(PrintedDeclCXX11Matches(
"constexpr int A(int a);",
"A",
- "int A(int a)"));
- // WRONG; Should be: "constexpr int A(int a);"
+ "constexpr int A(int a)"));
+ // Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionDecl8) {
@@ -370,11 +419,11 @@
TEST(DeclPrinter, TestFunctionDecl11) {
ASSERT_TRUE(PrintedDeclCXX98Matches(
- "typedef long size_t;"
+ "typedef long ssize_t;"
"typedef int *pInt;"
- "void A(int a, pInt b, size_t c);",
+ "void A(int a, pInt b, ssize_t c);",
"A",
- "void A(int a, pInt b, size_t c)"));
+ "void A(int a, pInt b, ssize_t c)"));
// Should be: with semicolon
}
@@ -466,8 +515,7 @@
" constexpr A();"
"};",
constructorDecl(ofClass(hasName("A"))).bind("id"),
- "A()"));
- // WRONG; Should be: "constexpr A();"
+ "constexpr A()"));
}
TEST(DeclPrinter, TestCXXConstructorDecl8) {
@@ -498,18 +546,16 @@
"A<T...>(const A<T...> &a)"));
}
-#if !defined(_MSC_VER)
TEST(DeclPrinter, TestCXXConstructorDecl11) {
- ASSERT_TRUE(PrintedDeclCXX11Matches(
+ ASSERT_TRUE(PrintedDeclCXX11nonMSCMatches(
"template<typename... T>"
"struct A : public T... {"
" A(T&&... ts) : T(ts)... {}"
"};",
constructorDecl(ofClass(hasName("A"))).bind("id"),
- "A<T...>(T &&ts...) : T(ts)"));
+ "A<T...>(T &&ts...) : T(ts)..."));
// WRONG; Should be: "A(T&&... ts) : T(ts)..."
}
-#endif
TEST(DeclPrinter, TestCXXDestructorDecl1) {
ASSERT_TRUE(PrintedDeclCXX98Matches(
@@ -517,8 +563,7 @@
" ~A();"
"};",
destructorDecl(ofClass(hasName("A"))).bind("id"),
- "void ~A()"));
- // WRONG; Should be: "~A();"
+ "~A()"));
}
TEST(DeclPrinter, TestCXXDestructorDecl2) {
@@ -527,8 +572,7 @@
" virtual ~A();"
"};",
destructorDecl(ofClass(hasName("A"))).bind("id"),
- "virtual void ~A()"));
- // WRONG; Should be: "virtual ~A();"
+ "virtual ~A()"));
}
TEST(DeclPrinter, TestCXXConversionDecl1) {
@@ -537,8 +581,7 @@
" operator int();"
"};",
methodDecl(ofClass(hasName("A"))).bind("id"),
- "int operator int()"));
- // WRONG; Should be: "operator int();"
+ "operator int()"));
}
TEST(DeclPrinter, TestCXXConversionDecl2) {
@@ -547,8 +590,7 @@
" operator bool();"
"};",
methodDecl(ofClass(hasName("A"))).bind("id"),
- "bool operator _Bool()"));
- // WRONG; Should be: "operator bool();"
+ "operator bool()"));
}
TEST(DeclPrinter, TestCXXConversionDecl3) {
@@ -558,8 +600,7 @@
" operator Z();"
"};",
methodDecl(ofClass(hasName("A"))).bind("id"),
- "Z operator struct Z()"));
- // WRONG; Should be: "operator Z();"
+ "operator Z()"));
}
TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
@@ -756,8 +797,8 @@
" void A(int a) &;"
"};",
"A",
- "void A(int a)"));
- // WRONG; Should be: "void A(int a) &;"
+ "void A(int a) &"));
+ // Should be: with semicolon
}
TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
@@ -766,8 +807,8 @@
" void A(int a) &&;"
"};",
"A",
- "void A(int a)"));
- // WRONG; Should be: "void A(int a) &&;"
+ "void A(int a) &&"));
+ // Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
diff --git a/unittests/AST/DeclTest.cpp b/unittests/AST/DeclTest.cpp
index c845da2..87aeef4 100644
--- a/unittests/AST/DeclTest.cpp
+++ b/unittests/AST/DeclTest.cpp
@@ -20,7 +20,7 @@
TEST(Decl, CleansUpAPValues) {
MatchFinder Finder;
- llvm::OwningPtr<FrontendActionFactory> Factory(
+ std::unique_ptr<FrontendActionFactory> Factory(
newFrontendActionFactory(&Finder));
// This is a regression test for a memory leak in APValues for structs that
diff --git a/unittests/AST/EvaluateAsRValueTest.cpp b/unittests/AST/EvaluateAsRValueTest.cpp
new file mode 100644
index 0000000..9120c93
--- /dev/null
+++ b/unittests/AST/EvaluateAsRValueTest.cpp
@@ -0,0 +1,112 @@
+//===- unittests/AST/EvaluateAsRValueTest.cpp -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// \brief Unit tests for evaluation of constant initializers.
+//
+//===----------------------------------------------------------------------===//
+
+#include <map>
+#include <string>
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+#include "clang/AST/ASTConsumer.h"
+
+using namespace clang::tooling;
+
+namespace {
+// For each variable name encountered, whether its initializer was a
+// constant.
+typedef std::map<std::string, bool> VarInfoMap;
+
+/// \brief Records information on variable initializers to a map.
+class EvaluateConstantInitializersVisitor
+ : public clang::RecursiveASTVisitor<EvaluateConstantInitializersVisitor> {
+ public:
+ explicit EvaluateConstantInitializersVisitor(VarInfoMap &VarInfo)
+ : VarInfo(VarInfo) {}
+
+ /// \brief Checks that isConstantInitializer and EvaluateAsRValue agree
+ /// and don't crash.
+ ///
+ /// For each VarDecl with an initializer this also records in VarInfo
+ /// whether the initializer could be evaluated as a constant.
+ bool VisitVarDecl(const clang::VarDecl *VD) {
+ if (const clang::Expr *Init = VD->getInit()) {
+ clang::Expr::EvalResult Result;
+ bool WasEvaluated = Init->EvaluateAsRValue(Result, VD->getASTContext());
+ VarInfo[VD->getNameAsString()] = WasEvaluated;
+ EXPECT_EQ(WasEvaluated, Init->isConstantInitializer(VD->getASTContext(),
+ false /*ForRef*/));
+ }
+ return true;
+ }
+
+ private:
+ VarInfoMap &VarInfo;
+};
+
+class EvaluateConstantInitializersAction : public clang::ASTFrontendAction {
+ public:
+ clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &Compiler,
+ llvm::StringRef FilePath) override {
+ return new Consumer;
+ }
+
+ private:
+ class Consumer : public clang::ASTConsumer {
+ public:
+ ~Consumer() override {}
+
+ void HandleTranslationUnit(clang::ASTContext &Ctx) override {
+ VarInfoMap VarInfo;
+ EvaluateConstantInitializersVisitor Evaluator(VarInfo);
+ Evaluator.TraverseDecl(Ctx.getTranslationUnitDecl());
+ EXPECT_EQ(2u, VarInfo.size());
+ EXPECT_FALSE(VarInfo["Dependent"]);
+ EXPECT_TRUE(VarInfo["Constant"]);
+ EXPECT_EQ(2u, VarInfo.size());
+ }
+ };
+};
+}
+
+TEST(EvaluateAsRValue, FailsGracefullyForUnknownTypes) {
+ // This is a regression test; the AST library used to trigger assertion
+ // failures because it assumed that the type of initializers was always
+ // known (which is true only after template instantiation).
+ std::string ModesToTest[] = {"-std=c++03", "-std=c++11", "-std=c++1y"};
+ for (std::string const &Mode : ModesToTest) {
+ std::vector<std::string> Args(1, Mode);
+ Args.push_back("-fno-delayed-template-parsing");
+ ASSERT_TRUE(runToolOnCodeWithArgs(
+ new EvaluateConstantInitializersAction(),
+ "template <typename T>"
+ "struct vector {"
+ " explicit vector(int size);"
+ "};"
+ "template <typename R>"
+ "struct S {"
+ " vector<R> intervals() const {"
+ " vector<R> Dependent(2);"
+ " return Dependent;"
+ " }"
+ "};"
+ "void doSomething() {"
+ " int Constant = 2 + 2;"
+ " (void) Constant;"
+ "}",
+ Args));
+ }
+}
diff --git a/unittests/AST/ExternalASTSourceTest.cpp b/unittests/AST/ExternalASTSourceTest.cpp
new file mode 100644
index 0000000..5cc2def
--- /dev/null
+++ b/unittests/AST/ExternalASTSourceTest.cpp
@@ -0,0 +1,83 @@
+//===- unittest/AST/ExternalASTSourceTest.cpp -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains tests for Clang's ExternalASTSource.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace llvm;
+
+
+class TestFrontendAction : public ASTFrontendAction {
+public:
+ TestFrontendAction(ExternalASTSource *Source) : Source(Source) {}
+
+private:
+ virtual void ExecuteAction() {
+ getCompilerInstance().getASTContext().setExternalSource(Source);
+ getCompilerInstance().getASTContext().getTranslationUnitDecl()
+ ->setHasExternalVisibleStorage();
+ return ASTFrontendAction::ExecuteAction();
+ }
+
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) {
+ return new ASTConsumer;
+ }
+
+ IntrusiveRefCntPtr<ExternalASTSource> Source;
+};
+
+bool testExternalASTSource(ExternalASTSource *Source,
+ StringRef FileContents) {
+ CompilerInstance Compiler;
+ Compiler.createDiagnostics();
+
+ CompilerInvocation *Invocation = new CompilerInvocation;
+ Invocation->getPreprocessorOpts().addRemappedFile(
+ "test.cc", MemoryBuffer::getMemBuffer(FileContents));
+ const char *Args[] = { "test.cc" };
+ CompilerInvocation::CreateFromArgs(*Invocation, Args,
+ Args + array_lengthof(Args),
+ Compiler.getDiagnostics());
+ Compiler.setInvocation(Invocation);
+
+ TestFrontendAction Action(Source);
+ return Compiler.ExecuteAction(Action);
+}
+
+
+// Ensure that a failed name lookup into an external source only occurs once.
+TEST(ExternalASTSourceTest, FailedLookupOccursOnce) {
+ struct TestSource : ExternalASTSource {
+ TestSource(unsigned &Calls) : Calls(Calls) {}
+
+ bool FindExternalVisibleDeclsByName(const DeclContext*,
+ DeclarationName Name) {
+ if (Name.getAsString() == "j")
+ ++Calls;
+ return false;
+ }
+
+ unsigned &Calls;
+ };
+
+ unsigned Calls = 0;
+ ASSERT_TRUE(testExternalASTSource(new TestSource(Calls), "int j, k = j;"));
+ EXPECT_EQ(1u, Calls);
+}
diff --git a/unittests/AST/MatchVerifier.h b/unittests/AST/MatchVerifier.h
index 5a29cde..0265f4a 100644
--- a/unittests/AST/MatchVerifier.h
+++ b/unittests/AST/MatchVerifier.h
@@ -79,7 +79,7 @@
std::vector<std::string>& Args, Language L) {
MatchFinder Finder;
Finder.addMatcher(AMatcher.bind(""), this);
- OwningPtr<tooling::FrontendActionFactory> Factory(
+ std::unique_ptr<tooling::FrontendActionFactory> Factory(
tooling::newFrontendActionFactory(&Finder));
StringRef FileName;
diff --git a/unittests/AST/SourceLocationTest.cpp b/unittests/AST/SourceLocationTest.cpp
index 29156bc..6e94442 100644
--- a/unittests/AST/SourceLocationTest.cpp
+++ b/unittests/AST/SourceLocationTest.cpp
@@ -17,11 +17,11 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
+#include "MatchVerifier.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"
-#include "MatchVerifier.h"
namespace clang {
namespace ast_matchers {
@@ -211,6 +211,16 @@
functionalCastExpr(), Lang_CXX11));
}
+TEST(CXXConstructExpr, SourceRange) {
+ RangeVerifier<CXXConstructExpr> Verifier;
+ Verifier.expectRange(3, 14, 3, 19);
+ EXPECT_TRUE(Verifier.match(
+ "struct A { A(int, int); };\n"
+ "void f(A a);\n"
+ "void g() { f({0, 0}); }",
+ constructExpr(), Lang_CXX11));
+}
+
TEST(CXXTemporaryObjectExpr, SourceRange) {
RangeVerifier<CXXTemporaryObjectExpr> Verifier;
Verifier.expectRange(2, 6, 2, 12);
diff --git a/unittests/AST/StmtPrinterTest.cpp b/unittests/AST/StmtPrinterTest.cpp
index 473ee13..d726517 100644
--- a/unittests/AST/StmtPrinterTest.cpp
+++ b/unittests/AST/StmtPrinterTest.cpp
@@ -64,19 +64,20 @@
}
};
-::testing::AssertionResult PrintedStmtMatches(
- StringRef Code,
- const std::vector<std::string> &Args,
- const DeclarationMatcher &NodeMatch,
- StringRef ExpectedPrinted) {
+template <typename T>
+::testing::AssertionResult
+PrintedStmtMatches(StringRef Code, const std::vector<std::string> &Args,
+ const T &NodeMatch, StringRef ExpectedPrinted) {
PrintMatch Printer;
MatchFinder Finder;
Finder.addMatcher(NodeMatch, &Printer);
- OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
+ std::unique_ptr<FrontendActionFactory> Factory(
+ newFrontendActionFactory(&Finder));
if (!runToolOnCodeWithArgs(Factory->create(), Code, Args))
- return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
+ return testing::AssertionFailure()
+ << "Parsing error in \"" << Code.str() << "\"";
if (Printer.getNumFoundStmts() == 0)
return testing::AssertionFailure()
@@ -89,12 +90,21 @@
if (Printer.getPrinted() != ExpectedPrinted)
return ::testing::AssertionFailure()
- << "Expected \"" << ExpectedPrinted << "\", "
- "got \"" << Printer.getPrinted() << "\"";
+ << "Expected \"" << ExpectedPrinted.str() << "\", "
+ "got \"" << Printer.getPrinted().str() << "\"";
return ::testing::AssertionSuccess();
}
+::testing::AssertionResult
+PrintedStmtCXX98Matches(StringRef Code, const StatementMatcher &NodeMatch,
+ StringRef ExpectedPrinted) {
+ std::vector<std::string> Args;
+ Args.push_back("-std=c++98");
+ Args.push_back("-Wno-unused-value");
+ return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted);
+}
+
::testing::AssertionResult PrintedStmtCXX98Matches(
StringRef Code,
StringRef ContainingFunction,
@@ -109,6 +119,15 @@
ExpectedPrinted);
}
+::testing::AssertionResult
+PrintedStmtCXX11Matches(StringRef Code, const StatementMatcher &NodeMatch,
+ StringRef ExpectedPrinted) {
+ std::vector<std::string> Args;
+ Args.push_back("-std=c++11");
+ Args.push_back("-Wno-unused-value");
+ return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted);
+}
+
::testing::AssertionResult PrintedStmtMSMatches(
StringRef Code,
StringRef ContainingFunction,
@@ -163,3 +182,32 @@
"1.F , -1.F , 1. , -1. , 1.L , -1.L"));
// Should be: with semicolon
}
+
+TEST(StmtPrinter, TestCXXConversionDeclImplicit) {
+ ASSERT_TRUE(PrintedStmtCXX98Matches(
+ "struct A {"
+ "operator void *();"
+ "A operator&(A);"
+ "};"
+ "void bar(void *);"
+ "void foo(A a, A b) {"
+ " bar(a & b);"
+ "}",
+ memberCallExpr(anything()).bind("id"),
+ "a & b"));
+}
+
+TEST(StmtPrinter, TestCXXConversionDeclExplicit) {
+ ASSERT_TRUE(PrintedStmtCXX11Matches(
+ "struct A {"
+ "operator void *();"
+ "A operator&(A);"
+ "};"
+ "void bar(void *);"
+ "void foo(A a, A b) {"
+ " auto x = (a & b).operator void *();"
+ "}",
+ memberCallExpr(anything()).bind("id"),
+ "(a & b)"));
+ // WRONG; Should be: (a & b).operator void *()
+}