Update Clang for 3.5 rebase (r209713).
Change-Id: I8c9133b0f8f776dc915f270b60f94962e771bc83
diff --git a/unittests/AST/CommentLexer.cpp b/unittests/AST/CommentLexer.cpp
index fc0fd77..cb8de27 100644
--- a/unittests/AST/CommentLexer.cpp
+++ b/unittests/AST/CommentLexer.cpp
@@ -61,7 +61,7 @@
void CommentLexerTest::lexString(const char *Source,
std::vector<Token> &Toks) {
MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source);
- FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
+ FileID File = SourceMgr.createFileID(Buf);
SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
Lexer L(Allocator, Diags, Traits, Begin, Source, Source + strlen(Source));
diff --git a/unittests/AST/CommentParser.cpp b/unittests/AST/CommentParser.cpp
index c72aef1..0064078 100644
--- a/unittests/AST/CommentParser.cpp
+++ b/unittests/AST/CommentParser.cpp
@@ -55,7 +55,7 @@
FullComment *CommentParserTest::parseString(const char *Source) {
MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source);
- FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
+ FileID File = SourceMgr.createFileID(Buf);
SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
Lexer L(Allocator, Diags, Traits, Begin, Source, Source + strlen(Source));
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index 5d09700..691719c 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -1773,6 +1773,9 @@
constructorDecl(isImplicit())));
EXPECT_TRUE(matches("class Foo { Foo(){} };",
constructorDecl(unless(isImplicit()))));
+ // The compiler added an implicit assignment operator.
+ EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
+ methodDecl(isImplicit(), hasName("operator="))));
}
TEST(DestructorDeclaration, MatchesVirtualDestructor) {
@@ -1963,6 +1966,17 @@
EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
}
+TEST(IfStmt, ChildTraversalMatchers) {
+ EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
+ ifStmt(hasThen(boolLiteral(equals(true))))));
+ EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
+ ifStmt(hasThen(boolLiteral(equals(true))))));
+ EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
+ ifStmt(hasElse(boolLiteral(equals(true))))));
+ EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
+ ifStmt(hasElse(boolLiteral(equals(true))))));
+}
+
TEST(MatchBinaryOperator, HasOperatorName) {
StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
@@ -2388,6 +2402,9 @@
TEST(For, ForRangeLoopInternals) {
EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
forRangeStmt(hasLoopVariable(anything()))));
+ EXPECT_TRUE(matches(
+ "void f(){ int a[] {1, 2}; for (int i : a); }",
+ forRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
}
TEST(For, NegativeForLoopInternals) {
@@ -2426,6 +2443,8 @@
whileStmt(hasBody(compoundStmt()))));
EXPECT_TRUE(matches("void f() { do {} while(true); }",
doStmt(hasBody(compoundStmt()))));
+ EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
+ forRangeStmt(hasBody(compoundStmt()))));
}
TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
@@ -4139,24 +4158,32 @@
}
bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
+ // Use the original typed pointer to verify we can pass pointers to subtypes
+ // to equalsNode.
+ const T *TypedNode = cast<T>(Node);
return selectFirst<const T>(
- "", match(stmt(hasParent(stmt(has(stmt(equalsNode(Node)))).bind(""))),
- *Node, Context)) != NULL;
+ "", match(stmt(hasParent(
+ stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
+ *Node, Context)) != NULL;
}
bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
+ // Use the original typed pointer to verify we can pass pointers to subtypes
+ // to equalsNode.
+ const T *TypedNode = cast<T>(Node);
return selectFirst<const T>(
- "", match(decl(hasParent(decl(has(decl(equalsNode(Node)))).bind(""))),
- *Node, Context)) != NULL;
+ "", match(decl(hasParent(
+ decl(has(decl(equalsNode(TypedNode)))).bind(""))),
+ *Node, Context)) != NULL;
}
};
TEST(IsEqualTo, MatchesNodesByIdentity) {
EXPECT_TRUE(matchAndVerifyResultTrue(
"class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
- new VerifyAncestorHasChildIsEqual<Decl>()));
- EXPECT_TRUE(
- matchAndVerifyResultTrue("void f() { if(true) {} }", ifStmt().bind(""),
- new VerifyAncestorHasChildIsEqual<Stmt>()));
+ new VerifyAncestorHasChildIsEqual<CXXRecordDecl>()));
+ EXPECT_TRUE(matchAndVerifyResultTrue(
+ "void f() { if (true) if(true) {} }", ifStmt().bind(""),
+ new VerifyAncestorHasChildIsEqual<IfStmt>()));
}
class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
diff --git a/unittests/ASTMatchers/ASTMatchersTest.h b/unittests/ASTMatchers/ASTMatchersTest.h
index e224722..8e243cf 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.h
+++ b/unittests/ASTMatchers/ASTMatchersTest.h
@@ -64,8 +64,10 @@
llvm::StringRef CompileArg) {
bool Found = false, DynamicFound = false;
MatchFinder Finder;
- Finder.addMatcher(AMatcher, new VerifyMatch(0, &Found));
- if (!Finder.addDynamicMatcher(AMatcher, new VerifyMatch(0, &DynamicFound)))
+ VerifyMatch VerifyFound(0, &Found);
+ Finder.addMatcher(AMatcher, &VerifyFound);
+ VerifyMatch VerifyDynamicFound(0, &DynamicFound);
+ if (!Finder.addDynamicMatcher(AMatcher, &VerifyDynamicFound))
return testing::AssertionFailure() << "Could not add dynamic matcher";
std::unique_ptr<FrontendActionFactory> Factory(
newFrontendActionFactory(&Finder));
@@ -109,8 +111,8 @@
std::unique_ptr<BoundNodesCallback> ScopedVerifier(FindResultVerifier);
bool VerifiedResult = false;
MatchFinder Finder;
- Finder.addMatcher(
- AMatcher, new VerifyMatch(FindResultVerifier, &VerifiedResult));
+ VerifyMatch VerifyVerifiedResult(FindResultVerifier, &VerifiedResult);
+ Finder.addMatcher(AMatcher, &VerifyVerifiedResult);
std::unique_ptr<FrontendActionFactory> Factory(
newFrontendActionFactory(&Finder));
// Some tests use typeof, which is a gnu extension.
diff --git a/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
index cdf4f92..4e3239f 100644
--- a/unittests/ASTMatchers/Dynamic/ParserTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
@@ -39,9 +39,7 @@
Errors.push_back(Error.toStringFull());
}
- llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName,
- const SourceRange &NameRange,
- Diagnostics *Error) {
+ llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName) {
const ExpectedMatchersTy::value_type *Matcher =
&*ExpectedMatchers.find(MatcherName);
return reinterpret_cast<MatcherCtor>(Matcher);
@@ -175,6 +173,29 @@
EXPECT_TRUE(matches("void f(int a, int x);", M));
EXPECT_FALSE(matches("void f(int x, int a);", M));
+ // Test named values.
+ struct NamedSema : public Parser::RegistrySema {
+ public:
+ virtual VariantValue getNamedValue(StringRef Name) {
+ if (Name == "nameX")
+ return std::string("x");
+ if (Name == "param0")
+ return VariantMatcher::SingleMatcher(hasParameter(0, hasName("a")));
+ return VariantValue();
+ }
+ };
+ NamedSema Sema;
+ llvm::Optional<DynTypedMatcher> HasParameterWithNamedValues(
+ Parser::parseMatcherExpression(
+ "functionDecl(param0, hasParameter(1, hasName(nameX)))", &Sema,
+ &Error));
+ EXPECT_EQ("", Error.toStringFull());
+ M = HasParameterWithNamedValues->unconditionalConvertTo<Decl>();
+
+ EXPECT_TRUE(matches("void f(int a, int x);", M));
+ EXPECT_FALSE(matches("void f(int x, int a);", M));
+
+
EXPECT_TRUE(!Parser::parseMatcherExpression(
"hasInitializer(\n binaryOperator(hasLHS(\"A\")))",
&Error).hasValue());
@@ -208,6 +229,10 @@
"1:9: Error parsing matcher. Found token <123> while looking for ','.",
ParseWithError("Foo(\"A\" 123)"));
EXPECT_EQ(
+ "1:1: Error parsing argument 1 for matcher stmt.\n"
+ "1:6: Value not found: someValue",
+ ParseWithError("stmt(someValue)"));
+ EXPECT_EQ(
"1:1: Matcher not found: Foo\n"
"1:4: Error parsing matcher. Found end-of-code while looking for ')'.",
ParseWithError("Foo("));
@@ -232,7 +257,7 @@
"1:1: Matcher does not support binding.",
ParseWithError("isArrow().bind(\"foo\")"));
EXPECT_EQ("Input value has unresolved overloaded type: "
- "Matcher<DoStmt|ForStmt|WhileStmt>",
+ "Matcher<DoStmt|ForStmt|WhileStmt|CXXForRangeStmt>",
ParseMatcherWithError("hasBody(stmt())"));
}
diff --git a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
index 150f8c9..abacb6f 100644
--- a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -35,21 +35,15 @@
return Out;
}
- llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName,
- Diagnostics *Error = 0) {
- Diagnostics DummyError;
- if (!Error) Error = &DummyError;
- llvm::Optional<MatcherCtor> Ctor =
- Registry::lookupMatcherCtor(MatcherName, SourceRange(), Error);
- EXPECT_EQ("", DummyError.toStringFull());
- return Ctor;
+ llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName) {
+ return Registry::lookupMatcherCtor(MatcherName);
}
VariantMatcher constructMatcher(StringRef MatcherName,
Diagnostics *Error = NULL) {
Diagnostics DummyError;
if (!Error) Error = &DummyError;
- llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName, Error);
+ llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName);
VariantMatcher Out;
if (Ctor)
Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(), Error);
@@ -62,7 +56,7 @@
Diagnostics *Error = NULL) {
Diagnostics DummyError;
if (!Error) Error = &DummyError;
- llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName, Error);
+ llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName);
VariantMatcher Out;
if (Ctor)
Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(Arg1), Error);
@@ -76,7 +70,7 @@
Diagnostics *Error = NULL) {
Diagnostics DummyError;
if (!Error) Error = &DummyError;
- llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName, Error);
+ llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName);
VariantMatcher Out;
if (Ctor)
Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(Arg1, Arg2),
diff --git a/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp b/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
index e62a464..524b73d 100644
--- a/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
@@ -26,6 +26,7 @@
EXPECT_TRUE(Value.isUnsigned());
EXPECT_EQ(kUnsigned, Value.getUnsigned());
+ EXPECT_TRUE(Value.hasValue());
EXPECT_FALSE(Value.isString());
EXPECT_FALSE(Value.isMatcher());
}
@@ -38,6 +39,7 @@
EXPECT_EQ(kString, Value.getString());
EXPECT_EQ("String", Value.getTypeAsString());
+ EXPECT_TRUE(Value.hasValue());
EXPECT_FALSE(Value.isUnsigned());
EXPECT_FALSE(Value.isMatcher());
}
@@ -45,6 +47,7 @@
TEST(VariantValueTest, DynTypedMatcher) {
VariantValue Value = VariantMatcher::SingleMatcher(stmt());
+ EXPECT_TRUE(Value.hasValue());
EXPECT_FALSE(Value.isUnsigned());
EXPECT_FALSE(Value.isString());
@@ -74,11 +77,13 @@
VariantValue Value = std::string("A");
EXPECT_TRUE(Value.isString());
EXPECT_EQ("A", Value.getString());
+ EXPECT_TRUE(Value.hasValue());
EXPECT_FALSE(Value.isUnsigned());
EXPECT_FALSE(Value.isMatcher());
EXPECT_EQ("String", Value.getTypeAsString());
Value = VariantMatcher::SingleMatcher(recordDecl());
+ EXPECT_TRUE(Value.hasValue());
EXPECT_FALSE(Value.isUnsigned());
EXPECT_FALSE(Value.isString());
EXPECT_TRUE(Value.isMatcher());
@@ -89,16 +94,36 @@
Value = 17;
EXPECT_TRUE(Value.isUnsigned());
EXPECT_EQ(17U, Value.getUnsigned());
+ EXPECT_TRUE(Value.hasValue());
EXPECT_FALSE(Value.isMatcher());
EXPECT_FALSE(Value.isString());
Value = VariantValue();
+ EXPECT_FALSE(Value.hasValue());
EXPECT_FALSE(Value.isUnsigned());
EXPECT_FALSE(Value.isString());
EXPECT_FALSE(Value.isMatcher());
EXPECT_EQ("Nothing", Value.getTypeAsString());
}
+TEST(VariantValueTest, ImplicitBool) {
+ VariantValue Value;
+ bool IfTrue = false;
+ if (Value) {
+ IfTrue = true;
+ }
+ EXPECT_FALSE(IfTrue);
+ EXPECT_TRUE(!Value);
+
+ Value = std::string();
+ IfTrue = false;
+ if (Value) {
+ IfTrue = true;
+ }
+ EXPECT_TRUE(IfTrue);
+ EXPECT_FALSE(!Value);
+}
+
TEST(VariantValueTest, Matcher) {
EXPECT_TRUE(matches("class X {};", VariantValue(VariantMatcher::SingleMatcher(
recordDecl(hasName("X"))))
diff --git a/unittests/Basic/SourceManagerTest.cpp b/unittests/Basic/SourceManagerTest.cpp
index d94cfe9..f227d0d 100644
--- a/unittests/Basic/SourceManagerTest.cpp
+++ b/unittests/Basic/SourceManagerTest.cpp
@@ -52,17 +52,22 @@
};
class VoidModuleLoader : public ModuleLoader {
- virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
- ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) {
+ ModuleLoadResult loadModule(SourceLocation ImportLoc,
+ ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) override {
return ModuleLoadResult();
}
- virtual void makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind Visibility,
- SourceLocation ImportLoc,
- bool Complain) { }
+ void makeModuleVisible(Module *Mod,
+ Module::NameVisibilityKind Visibility,
+ SourceLocation ImportLoc,
+ bool Complain) override { }
+
+ GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+ { return 0; }
+ bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+ { return 0; };
};
TEST_F(SourceManagerTest, isBeforeInTranslationUnit) {
@@ -70,16 +75,17 @@
"#define M(x) [x]\n"
"M(foo)";
MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source);
- FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(buf);
+ FileID mainFileID = SourceMgr.createFileID(buf);
+ SourceMgr.setMainFileID(mainFileID);
VoidModuleLoader ModLoader;
HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts,
&*Target);
- Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, Target.getPtr(),
- SourceMgr, HeaderInfo, ModLoader,
- /*IILookup =*/ 0,
- /*OwnsHeaderSearch =*/false,
- /*DelayInitialization =*/ false);
+ Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
+ HeaderInfo, ModLoader,
+ /*IILookup =*/0,
+ /*OwnsHeaderSearch =*/false);
+ PP.Initialize(*Target);
PP.EnterMainSourceFile();
std::vector<Token> toks;
@@ -122,7 +128,8 @@
"int y;";
MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source);
- FileID MainFileID = SourceMgr.createMainFileIDForMemBuffer(Buf);
+ FileID MainFileID = SourceMgr.createFileID(Buf);
+ SourceMgr.setMainFileID(MainFileID);
bool Invalid;
@@ -181,7 +188,8 @@
MemoryBuffer *headerBuf = MemoryBuffer::getMemBuffer(header);
MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main);
- FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(mainBuf);
+ FileID mainFileID = SourceMgr.createFileID(mainBuf);
+ SourceMgr.setMainFileID(mainFileID);
const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h",
headerBuf->getBufferSize(), 0);
@@ -190,11 +198,11 @@
VoidModuleLoader ModLoader;
HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts,
&*Target);
- Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, Target.getPtr(),
- SourceMgr, HeaderInfo, ModLoader,
- /*IILookup =*/ 0,
- /*OwnsHeaderSearch =*/false,
- /*DelayInitialization =*/ false);
+ Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
+ HeaderInfo, ModLoader,
+ /*IILookup =*/0,
+ /*OwnsHeaderSearch =*/false);
+ PP.Initialize(*Target);
PP.EnterMainSourceFile();
std::vector<Token> toks;
@@ -279,7 +287,7 @@
MemoryBuffer *headerBuf = MemoryBuffer::getMemBuffer(header);
MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main);
- SourceMgr.createMainFileIDForMemBuffer(mainBuf);
+ SourceMgr.setMainFileID(SourceMgr.createFileID(mainBuf));
const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h",
headerBuf->getBufferSize(), 0);
@@ -288,11 +296,11 @@
VoidModuleLoader ModLoader;
HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts,
&*Target);
- Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, Target.getPtr(),
- SourceMgr, HeaderInfo, ModLoader,
- /*IILookup =*/ 0,
- /*OwnsHeaderSearch =*/false,
- /*DelayInitialization =*/ false);
+ Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
+ HeaderInfo, ModLoader,
+ /*IILookup =*/0,
+ /*OwnsHeaderSearch =*/false);
+ PP.Initialize(*Target);
std::vector<MacroAction> Macros;
PP.addPPCallbacks(new MacroTracker(Macros));
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 7606260..94d4bbb 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "format-test"
-
#include "FormatTestUtils.h"
#include "clang/Format/Format.h"
#include "llvm/Support/Debug.h"
#include "gtest/gtest.h"
+#define DEBUG_TYPE "format-test"
+
namespace clang {
namespace format {
@@ -270,6 +270,17 @@
9, 5, getLLVMStyle()));
}
+TEST_F(FormatTest, RecognizesBinaryOperatorKeywords) {
+ verifyFormat("x = (a) and (b);");
+ verifyFormat("x = (a) or (b);");
+ verifyFormat("x = (a) bitand (b);");
+ verifyFormat("x = (a) bitor (b);");
+ verifyFormat("x = (a) not_eq (b);");
+ verifyFormat("x = (a) and_eq (b);");
+ verifyFormat("x = (a) or_eq (b);");
+ verifyFormat("x = (a) xor (b);");
+}
+
//===----------------------------------------------------------------------===//
// Tests for control statements.
//===----------------------------------------------------------------------===//
@@ -344,6 +355,51 @@
AllowsMergedLoops);
}
+TEST_F(FormatTest, FormatShortBracedStatements) {
+ FormatStyle AllowSimpleBracedStatements = getLLVMStyle();
+ AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = true;
+
+ AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = true;
+ AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true;
+
+ verifyFormat("if (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("while (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("for (;;) {}", AllowSimpleBracedStatements);
+ verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("if (true) { //\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("if (true) {\n"
+ " f();\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+
+ verifyFormat("template <int> struct A2 {\n"
+ " struct B {};\n"
+ "};",
+ AllowSimpleBracedStatements);
+
+ AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false;
+ verifyFormat("if (true) {\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+
+ AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false;
+ verifyFormat("while (true) {\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("for (;;) {\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+}
+
TEST_F(FormatTest, ParseIfElse) {
verifyFormat("if (true)\n"
" if (true)\n"
@@ -390,6 +446,11 @@
"else {\n"
" g()\n"
"}");
+
+ verifyFormat("if (a) {\n"
+ "} else if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaa)) {\n"
+ "}");
}
TEST_F(FormatTest, FormatsForLoop) {
@@ -511,6 +572,9 @@
" f();\n"
" break;\n"
"}\n"
+ "case 2: {\n"
+ " break;\n"
+ "}\n"
"}");
verifyFormat("switch (x) {\n"
"case 1: {\n"
@@ -615,6 +679,10 @@
" break;\n"
" }\n"
"});");
+ verifyFormat("switch (a) {\n"
+ "case (b):\n"
+ " return;\n"
+ "}");
}
TEST_F(FormatTest, CaseRanges) {
@@ -829,6 +897,29 @@
" // first\n"
"// at start\n"
"otherLine();"));
+
+ verifyFormat(
+ "#define A \\\n"
+ " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n"
+ " int jjjjjjjjjjjjjjjjjjjjjjjj; /* */",
+ getLLVMStyleWithColumns(60));
+ verifyFormat(
+ "#define A \\\n"
+ " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n"
+ " int jjjjjjjjjjjjjjjjjjjjjjjj; /* */",
+ getLLVMStyleWithColumns(61));
+
+ verifyFormat("if ( // This is some comment\n"
+ " x + 3) {\n"
+ "}");
+ EXPECT_EQ("if ( // This is some comment\n"
+ " // spanning two lines\n"
+ " x + 3) {\n"
+ "}",
+ format("if( // This is some comment\n"
+ " // spanning two lines\n"
+ " x + 3) {\n"
+ "}"));
}
TEST_F(FormatTest, KeepsParameterWithTrailingCommentsOnTheirOwnLine) {
@@ -1010,6 +1101,30 @@
format("int i; /* Comment with empty...\n"
" *\n"
" * line. */"));
+ EXPECT_EQ("int foobar = 0; /* comment */\n"
+ "int bar = 0; /* multiline\n"
+ " comment 1 */\n"
+ "int baz = 0; /* multiline\n"
+ " comment 2 */\n"
+ "int bzz = 0; /* multiline\n"
+ " comment 3 */",
+ format("int foobar = 0; /* comment */\n"
+ "int bar = 0; /* multiline\n"
+ " comment 1 */\n"
+ "int baz = 0; /* multiline\n"
+ " comment 2 */\n"
+ "int bzz = 0; /* multiline\n"
+ " comment 3 */"));
+ EXPECT_EQ("int foobar = 0; /* comment */\n"
+ "int bar = 0; /* multiline\n"
+ " comment */\n"
+ "int baz = 0; /* multiline\n"
+ "comment */",
+ format("int foobar = 0; /* comment */\n"
+ "int bar = 0; /* multiline\n"
+ "comment */\n"
+ "int baz = 0; /* multiline\n"
+ "comment */"));
}
TEST_F(FormatTest, CorrectlyHandlesLengthOfBlockComments) {
@@ -1930,32 +2045,81 @@
}
TEST_F(FormatTest, FormatTryCatch) {
- // FIXME: Handle try-catch explicitly in the UnwrappedLineParser, then we'll
- // also not create single-line-blocks.
verifyFormat("try {\n"
" throw a * b;\n"
- "}\n"
- "catch (int a) {\n"
+ "} catch (int a) {\n"
" // Do nothing.\n"
- "}\n"
- "catch (...) {\n"
+ "} catch (...) {\n"
" exit(42);\n"
"}");
// Function-level try statements.
- verifyFormat("int f() try { return 4; }\n"
- "catch (...) {\n"
+ verifyFormat("int f() try { return 4; } catch (...) {\n"
" return 5;\n"
"}");
verifyFormat("class A {\n"
" int a;\n"
- " A() try : a(0) {}\n"
- " catch (...) {\n"
+ " A() try : a(0) {\n"
+ " } catch (...) {\n"
" throw;\n"
" }\n"
"};\n");
}
+TEST_F(FormatTest, IncompleteTryCatchBlocks) {
+ verifyFormat("try {\n"
+ " f();\n"
+ "} catch {\n"
+ " g();\n"
+ "}");
+ verifyFormat("try {\n"
+ " f();\n"
+ "} catch (A a) MACRO(x) {\n"
+ " g();\n"
+ "} catch (B b) MACRO(x) {\n"
+ " g();\n"
+ "}");
+}
+
+TEST_F(FormatTest, FormatTryCatchBraceStyles) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBraces = FormatStyle::BS_Attach;
+ verifyFormat("try {\n"
+ " // something\n"
+ "} catch (...) {\n"
+ " // something\n"
+ "}",
+ Style);
+ Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
+ verifyFormat("try {\n"
+ " // something\n"
+ "}\n"
+ "catch (...) {\n"
+ " // something\n"
+ "}",
+ Style);
+ Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+ verifyFormat("try\n"
+ "{\n"
+ " // something\n"
+ "}\n"
+ "catch (...)\n"
+ "{\n"
+ " // something\n"
+ "}",
+ Style);
+ Style.BreakBeforeBraces = FormatStyle::BS_GNU;
+ verifyFormat("try\n"
+ " {\n"
+ " // something\n"
+ " }\n"
+ "catch (...)\n"
+ " {\n"
+ " // something\n"
+ " }",
+ Style);
+}
+
TEST_F(FormatTest, FormatObjCTryCatch) {
verifyFormat("@try {\n"
" f();\n"
@@ -2383,8 +2547,7 @@
" F(x)\n"
" try {\n"
" Q();\n"
- " }\n"
- " catch (...) {\n"
+ " } catch (...) {\n"
" }\n"
"}\n",
format("int q() {\n"
@@ -2399,14 +2562,15 @@
"}\n"));
EXPECT_EQ("class A {\n"
" A() : t(0) {}\n"
+ " A(int i) noexcept() : {}\n"
" A(X x)\n" // FIXME: function-level try blocks are broken.
" try : t(0) {\n"
- " }\n"
- " catch (...) {\n"
+ " } catch (...) {\n"
" }\n"
"};",
format("class A {\n"
" A()\n : t(0) {}\n"
+ " A(int i)\n noexcept() : {}\n"
" A(X x)\n"
" try : t(0) {} catch (...) {}\n"
"};"));
@@ -2802,9 +2966,21 @@
"bool aaaaaaa =\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaa).aaaaaaaaaaaaaaaaaaa() ||\n"
" bbbbbbbb();");
+ verifyFormat(
+ "bool aaaaaaa =\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaa).aaaaaaaaaaaaaaaaaaa() or\n"
+ " bbbbbbbb();");
+
verifyFormat("bool aaaaaaaaaaaaaaaaaaaaa =\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa != bbbbbbbbbbbbbbbbbb &&\n"
" ccccccccc == ddddddddddd;");
+ verifyFormat("bool aaaaaaaaaaaaaaaaaaaaa =\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa != bbbbbbbbbbbbbbbbbb and\n"
+ " ccccccccc == ddddddddddd;");
+ verifyFormat(
+ "bool aaaaaaaaaaaaaaaaaaaaa =\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa not_eq bbbbbbbbbbbbbbbbbb and\n"
+ " ccccccccc == ddddddddddd;");
verifyFormat("aaaaaa = aaaaaaa(aaaaaaa, // break\n"
" aaaaaa) &&\n"
@@ -2937,8 +3113,9 @@
" + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}",
Style);
verifyFormat("if () {\n"
- "} else if (aaaaa && bbbbb // break\n"
- " > ccccc) {\n"
+ "} else if (aaaaa\n"
+ " && bbbbb // break\n"
+ " > ccccc) {\n"
"}",
Style);
@@ -2953,6 +3130,12 @@
verifyFormat("return boost::fusion::at_c<0>(iiii).second\n"
" == boost::fusion::at_c<1>(iiii).second;",
Style);
+
+ Style.ColumnLimit = 60;
+ verifyFormat("zzzzzzzzzz\n"
+ " = bbbbbbbbbbbbbbbbb\n"
+ " >> aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaa);",
+ Style);
}
TEST_F(FormatTest, ConstructorInitializers) {
@@ -3267,9 +3450,15 @@
" int someLongParameter) override {}",
Style);
verifyFormat("void someLongFunction(\n"
+ " int someLongParameter) OVERRIDE {}",
+ Style);
+ verifyFormat("void someLongFunction(\n"
" int someLongParameter) final {}",
Style);
verifyFormat("void someLongFunction(\n"
+ " int someLongParameter) FINAL {}",
+ Style);
+ verifyFormat("void someLongFunction(\n"
" int parameter) const override {}",
Style);
@@ -3286,6 +3475,8 @@
" LOCKS_EXCLUDED(aaaaaaaaaaaaa);");
verifyFormat("void aaaaaaaaaaaa(int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) const\n"
" LOCKS_EXCLUDED(aaaaaaaaaaaaa) {}");
+ verifyGoogleFormat("void aaaaaaaaaaaaaa(aaaaaaaa aaa) override\n"
+ " AAAAAAAAAAAAAAAAAAAAAAAA(aaaaaaaaaaaaaaa);");
verifyFormat(
"void aaaaaaaaaaaaaaaaaa()\n"
@@ -3293,14 +3484,15 @@
" aaaaaaaaaaaaaaaaaaaaaaaaa));");
verifyFormat("bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" __attribute__((unused));");
- verifyFormat(
+ verifyGoogleFormat(
"bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
- " GUARDED_BY(aaaaaaaaaaaa);",
- getGoogleStyle());
- verifyFormat(
+ " GUARDED_BY(aaaaaaaaaaaa);");
+ verifyGoogleFormat(
"bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
- " GUARDED_BY(aaaaaaaaaaaa);",
- getGoogleStyle());
+ " GUARDED_BY(aaaaaaaaaaaa);");
+ verifyGoogleFormat(
+ "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa GUARDED_BY(aaaaaaaaaaaa) =\n"
+ " aaaaaaaa::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
}
TEST_F(FormatTest, BreaksDesireably) {
@@ -3540,20 +3732,42 @@
verifyFormat(
"if (aaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
" bbbbbbbbbbbbbbbbbbbbbbbbb && ccccccccccccccccccccccccc) {\n}");
+ verifyFormat(
+ "if (aaaaaaaaaaaaaaaaaaaaaaaaa or\n"
+ " bbbbbbbbbbbbbbbbbbbbbbbbb and cccccccccccccccccccccccc) {\n}");
+
verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa && bbbbbbbbbbbbbbbbbbbbbbbbb ||\n"
" ccccccccccccccccccccccccc) {\n}");
+ verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa and bbbbbbbbbbbbbbbbbbbbbbbb or\n"
+ " ccccccccccccccccccccccccc) {\n}");
+
verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa || bbbbbbbbbbbbbbbbbbbbbbbbb ||\n"
" ccccccccccccccccccccccccc) {\n}");
+ verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa or bbbbbbbbbbbbbbbbbbbbbbbbb or\n"
+ " ccccccccccccccccccccccccc) {\n}");
+
verifyFormat(
"if ((aaaaaaaaaaaaaaaaaaaaaaaaa || bbbbbbbbbbbbbbbbbbbbbbbbb) &&\n"
" ccccccccccccccccccccccccc) {\n}");
+ verifyFormat(
+ "if ((aaaaaaaaaaaaaaaaaaaaaaaaa or bbbbbbbbbbbbbbbbbbbbbbbbb) and\n"
+ " ccccccccccccccccccccccccc) {\n}");
+
verifyFormat("return aaaa & AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ||\n"
" bbbb & BBBBBBBBBBBBBBBBBBBBBBBBBBBBB ||\n"
" cccc & CCCCCCCCCCCCCCCCCCCCCCCCCC ||\n"
" dddd & DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD;");
+ verifyFormat("return aaaa & AAAAAAAAAAAAAAAAAAAAAAAAAAAAA or\n"
+ " bbbb & BBBBBBBBBBBBBBBBBBBBBBBBBBBBB or\n"
+ " cccc & CCCCCCCCCCCCCCCCCCCCCCCCCC or\n"
+ " dddd & DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD;");
+
verifyFormat("if ((aaaaaaaaaa != aaaaaaaaaaaaaaa ||\n"
" aaaaaaaaaaaaaaaaaaaaaaaa() >= aaaaaaaaaaaaaaaaaaaa) &&\n"
" aaaaaaaaaaaaaaa != aa) {\n}");
+ verifyFormat("if ((aaaaaaaaaa != aaaaaaaaaaaaaaa or\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaa() >= aaaaaaaaaaaaaaaaaaaa) and\n"
+ " aaaaaaaaaaaaaaa != aa) {\n}");
}
TEST_F(FormatTest, BreaksAfterAssignments) {
@@ -3685,6 +3899,12 @@
" : (bbbbbbbbbbbbbbb //\n"
" ? ccccccccccccccc\n"
" : ddddddddddddddd);");
+ verifyFormat(
+ "int aaaaaaaaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " ? aaaaaaaaaaaaaaaaaaaaaaaaa +\n"
+ " aaaaaaaaaaaaaaaaaaaaa +\n"
+ " aaaaaaaaaaaaaaaaaaaaa\n"
+ " : aaaaaaaaaa;");
FormatStyle NoBinPacking = getLLVMStyle();
NoBinPacking.BinPackParameters = false;
@@ -3964,6 +4184,18 @@
"aaaaaaaa << (aaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
" << aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+ verifyFormat(
+ "llvm::errs() << \"a: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+ verifyFormat(
+ "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+ " << bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;");
+ verifyFormat(
+ "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
verifyFormat("return out << \"somepacket = {\\n\"\n"
" << \" aaaaaa = \" << pkt.aaaaaa << \"\\n\"\n"
@@ -3988,6 +4220,8 @@
" llvm::outs() << \"aaaaaaaaaaaaaaaaaaaa: \"\n"
" << aaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n"
"}");
+ verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \"\n"
+ " << aaaaaaaa.aaaaaaaaaaaa(aaa)->aaaaaaaaaaaaaa();");
// Breaking before the first "<<" is generally not desirable.
verifyFormat(
@@ -4451,6 +4685,7 @@
verifyIndependentOfContext("a * [self dostuff];");
verifyIndependentOfContext("int x = a * (a + b);");
verifyIndependentOfContext("(a *)(a + b);");
+ verifyIndependentOfContext("*(int *)(p & ~3UL) = 0;");
verifyIndependentOfContext("int *pa = (int *)&a;");
verifyIndependentOfContext("return sizeof(int **);");
verifyIndependentOfContext("return sizeof(int ******);");
@@ -4464,18 +4699,21 @@
verifyFormat("auto PointerBinding = [](const char *S) {};");
verifyFormat("typedef typeof(int(int, int)) *MyFunc;");
verifyIndependentOfContext("typedef void (*f)(int *a);");
+ verifyIndependentOfContext("int i{a * b};");
verifyIndependentOfContext("InvalidRegions[*R] = 0;");
verifyIndependentOfContext("A<int *> a;");
verifyIndependentOfContext("A<int **> a;");
verifyIndependentOfContext("A<int *, int *> a;");
+ verifyIndependentOfContext("A<int *[]> a;");
verifyIndependentOfContext(
"const char *const p = reinterpret_cast<const char *const>(q);");
verifyIndependentOfContext("A<int **, int **> a;");
verifyIndependentOfContext("void f(int *a = d * e, int *b = c * d);");
verifyFormat("for (char **a = b; *a; ++a) {\n}");
verifyFormat("for (; a && b;) {\n}");
+ verifyFormat("bool foo = true && [] { return false; }();");
verifyFormat(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
@@ -4504,8 +4742,9 @@
verifyIndependentOfContext("f(b * /* confusing comment */ ++c);");
verifyFormat(
- "int *MyValues = {*A, // Operator detection might be confused by the '{'\n"
- " *BB // Operator detection might be confused by previous comment\n"
+ "int *MyValues = {\n"
+ " *A, // Operator detection might be confused by the '{'\n"
+ " *BB // Operator detection might be confused by previous comment\n"
"};");
verifyIndependentOfContext("if (int *a = &b)");
@@ -4561,6 +4800,16 @@
// FIXME: Is there a way to make this work?
// verifyIndependentOfContext("MACRO(A *a);");
+ EXPECT_EQ("#define OP(x) \\\n"
+ " ostream &operator<<(ostream &s, const A &a) { \\\n"
+ " return s << a.DebugString(); \\\n"
+ " }",
+ format("#define OP(x) \\\n"
+ " ostream &operator<<(ostream &s, const A &a) { \\\n"
+ " return s << a.DebugString(); \\\n"
+ " }",
+ getLLVMStyleWithColumns(50)));
+
// FIXME: We cannot handle this case yet; we might be able to figure out that
// foo<x> d > v; doesn't make sense.
verifyFormat("foo<a < b && c> d > v;");
@@ -4624,6 +4873,7 @@
"};");
verifyGoogleFormat("#define IF(a, b, c) if (a && (b == c))");
verifyGoogleFormat("#define WHILE(a, b, c) while (a && (b == c))");
+ verifyFormat("#define A(a, b) (a && b)");
}
TEST_F(FormatTest, FormatsBinaryOperatorsPrecedingEquals) {
@@ -4655,12 +4905,20 @@
verifyFormat("#define x ((int)-1)");
verifyFormat("#define p(q) ((int *)&q)");
- // FIXME: Without type knowledge, this can still fall apart miserably.
- verifyFormat("void f() { my_int a = (my_int) * b; }");
- verifyFormat("void f() { return P ? (my_int) * P : (my_int)0; }");
- verifyFormat("my_int a = (my_int) ~0;");
- verifyFormat("my_int a = (my_int)++ a;");
- verifyFormat("my_int a = (my_int) + 2;");
+ verifyFormat("void f() { my_int a = (my_int)*b; }");
+ verifyFormat("void f() { return P ? (my_int)*P : (my_int)0; }");
+ verifyFormat("my_int a = (my_int)~0;");
+ verifyFormat("my_int a = (my_int)++a;");
+ verifyFormat("my_int a = (my_int)+2;");
+ verifyFormat("my_int a = (my_int)1;");
+ verifyFormat("my_int a = (my_int *)1;");
+ verifyFormat("my_int a = (const my_int)-1;");
+ verifyFormat("my_int a = (const my_int *)-1;");
+
+ // FIXME: single value wrapped with paren will be treated as cast.
+ verifyFormat("void f(int i = (kValue)*kMask) {}");
+
+ verifyFormat("{ (void)F; }");
// Don't break after a cast's
verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
@@ -4681,7 +4939,6 @@
verifyFormat("void f(SmallVector<int>) {}");
verifyFormat("void f(SmallVector<int>);");
verifyFormat("void f(SmallVector<int>) = 0;");
- verifyFormat("void f(int i = (kValue) * kMask) {}");
verifyFormat("void f(int i = (kA * kB) & kMask) {}");
verifyFormat("int a = sizeof(int) * b;");
verifyFormat("int a = alignof(int) * b;", getGoogleStyle());
@@ -4749,6 +5006,8 @@
"LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType const\n"
"LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
+ verifyFormat("decltype(LoooooooooooooooooooooooooooooooooooooooongName)\n"
+ "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
// FIXME: Without the comment, this breaks after "(".
verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType // break\n"
@@ -4842,6 +5101,11 @@
// Protocol buffer definition or missing "#".
verifyFormat("import \"aaaaaaaaaaaaaaaaa/aaaaaaaaaaaaaaa\";",
getLLVMStyleWithColumns(30));
+
+ FormatStyle Style = getLLVMStyle();
+ Style.AlwaysBreakBeforeMultilineStrings = true;
+ Style.ColumnLimit = 0;
+ verifyFormat("#import \"abc.h\"", Style);
}
//===----------------------------------------------------------------------===//
@@ -4981,7 +5245,7 @@
verifyFormat("return (a)(b) {1, 2, 3};");
}
-TEST_F(FormatTest, LayoutCxx11ConstructorBraceInitializers) {
+TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
verifyFormat("vector<int> x{1, 2, 3, 4};");
verifyFormat("vector<int> x{\n"
" 1, 2, 3, 4,\n"
@@ -4993,6 +5257,7 @@
verifyFormat("Class::Class : member{1, 2, 3} {}");
verifyFormat("new vector<int>{1, 2, 3};");
verifyFormat("new int[3]{1, 2, 3};");
+ verifyFormat("new int{1};");
verifyFormat("return {arg1, arg2};");
verifyFormat("return {arg1, SomeType{parameter}};");
verifyFormat("int count = set<int>{f(), g(), h()}.size();");
@@ -5002,6 +5267,41 @@
" T member = {arg1, arg2};\n"
"};");
verifyFormat("vector<int> foo = {::SomeGlobalFunction()};");
+ verifyFormat("static_assert(std::is_integral<int>{} + 0, \"\");");
+ verifyFormat("int a = std::is_integral<int>{} + 0;");
+
+ verifyFormat("int foo(int i) { return fo1{}(i); }");
+ verifyFormat("int foo(int i) { return fo1{}(i); }");
+
+ // In combination with BinPackParameters = false.
+ FormatStyle NoBinPacking = getLLVMStyle();
+ NoBinPacking.BinPackParameters = false;
+ verifyFormat("const Aaaaaa aaaaa = {aaaaa,\n"
+ " bbbbb,\n"
+ " ccccc,\n"
+ " ddddd,\n"
+ " eeeee,\n"
+ " ffffff,\n"
+ " ggggg,\n"
+ " hhhhhh,\n"
+ " iiiiii,\n"
+ " jjjjjj,\n"
+ " kkkkkk};",
+ NoBinPacking);
+ verifyFormat("const Aaaaaa aaaaa = {\n"
+ " aaaaa,\n"
+ " bbbbb,\n"
+ " ccccc,\n"
+ " ddddd,\n"
+ " eeeee,\n"
+ " ffffff,\n"
+ " ggggg,\n"
+ " hhhhhh,\n"
+ " iiiiii,\n"
+ " jjjjjj,\n"
+ " kkkkkk,\n"
+ "};",
+ NoBinPacking);
// FIXME: The alignment of these trailing comments might be bad. Then again,
// this might be utterly useless in real code.
@@ -5060,7 +5360,10 @@
" bbbbbbbbbbbbbbbbbbbb, bbbbb };",
ExtraSpaces);
verifyFormat("DoSomethingWithVector({} /* No data */);", ExtraSpaces);
- verifyFormat("DoSomethingWithVector({ {} /* No data */ }, { { 1, 2 } });",
+ verifyFormat("DoSomethingWithVector({\n"
+ " {} /* No data */\n"
+ " },\n"
+ " { { 1, 2 } });",
ExtraSpaces);
verifyFormat(
"someFunction(OtherParam,\n"
@@ -5125,13 +5428,14 @@
" 1, 1, 1, 1, 1, 1, 1, 1,\n"
"};",
getLLVMStyleWithColumns(39));
- verifyFormat("vector<int> x = {1, 1, 1, 1,\n"
- " 1, 1, 1, 1, //\n"
+ verifyFormat("vector<int> x = {\n"
+ " 1, 1, 1, 1, 1, 1, 1, 1, //\n"
"};",
getLLVMStyleWithColumns(39));
- verifyFormat("vector<int> x = {1, 1, 1, 1,\n"
- " 1, 1, 1, 1,\n"
- " /**/ /**/};",
+ verifyFormat("vector<int> x = {\n"
+ " 1, 1, 1, 1, 1, 1, 1, 1,\n"
+ " /**/ /**/\n"
+ "};",
getLLVMStyleWithColumns(39));
verifyFormat("return {{aaaaaaaaaaaaaaaaaaaaa},\n"
" {aaaaaaaaaaaaaaaaaaa},\n"
@@ -5159,7 +5463,7 @@
TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
FormatStyle DoNotMerge = getLLVMStyle();
- DoNotMerge.AllowShortFunctionsOnASingleLine = false;
+ DoNotMerge.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
verifyFormat("void f() { return 42; }");
verifyFormat("void f() {\n"
@@ -5216,7 +5520,8 @@
format("A()\n:b(0)\n{\n}", NoColumnLimit));
FormatStyle DoNotMergeNoColumnLimit = NoColumnLimit;
- DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine = false;
+ DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine =
+ FormatStyle::SFS_None;
EXPECT_EQ("A()\n"
" : b(0) {\n"
"}",
@@ -5246,6 +5551,19 @@
getLLVMStyleWithColumns(23));
}
+TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
+ FormatStyle MergeInlineOnly = getLLVMStyle();
+ MergeInlineOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ verifyFormat("class C {\n"
+ " int f() { return 42; }\n"
+ "};",
+ MergeInlineOnly);
+ verifyFormat("int f() {\n"
+ " return 42;\n"
+ "}",
+ MergeInlineOnly);
+}
+
TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) {
// Elaborate type variable declarations.
verifyFormat("struct foo a = {bar};\nint n;");
@@ -5719,6 +6037,16 @@
"}\n"
"+ (id)init;\n"
"@end");
+
+ FormatStyle OnePerLine = getGoogleStyle();
+ OnePerLine.BinPackParameters = false;
+ verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ()<\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n"
+ "}",
+ OnePerLine);
}
TEST_F(FormatTest, FormatObjCImplementation) {
@@ -5767,10 +6095,14 @@
"@implementation Bar\n"
"@end");
- verifyFormat("@implementation Foo : Bar\n"
- "+ (id)init {\n}\n"
- "- (void)foo {\n}\n"
- "@end");
+ EXPECT_EQ("@implementation Foo : Bar\n"
+ "+ (id)init {\n}\n"
+ "- (void)foo {\n}\n"
+ "@end",
+ format("@implementation Foo : Bar\n"
+ "+(id)init{}\n"
+ "-(void)foo{}\n"
+ "@end"));
verifyFormat("@implementation Foo {\n"
" int _i;\n"
@@ -6314,7 +6646,7 @@
67, 0, getLLVMStyle()));
}
-TEST_F(FormatTest, BreakStringLiterals) {
+TEST_F(FormatTest, BreaksStringLiterals) {
EXPECT_EQ("\"some text \"\n"
"\"other\";",
format("\"some text other\";", getLLVMStyleWithColumns(12)));
@@ -6474,6 +6806,16 @@
format("#define A \"some text other\";", AlignLeft));
}
+TEST_F(FormatTest, BreaksStringLiteralsWithTabs) {
+ EXPECT_EQ(
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "(\n"
+ " \"x\t\");",
+ format("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaa("
+ "\"x\t\");"));
+}
+
TEST_F(FormatTest, BreaksWideAndNSStringLiterals) {
EXPECT_EQ(
"u8\"utf8 string \"\n"
@@ -6611,6 +6953,10 @@
format("#define x(_a) printf(\"foo\"_a);", Style));
}
+TEST_F(FormatTest, UnderstandsCpp1y) {
+ verifyFormat("int bi{1'000'000};");
+}
+
TEST_F(FormatTest, BreakStringLiteralsBeforeUnbreakableTokenSequence) {
EXPECT_EQ("someFunction(\"aaabbbcccd\"\n"
" \"ddeeefff\");",
@@ -6713,9 +7059,7 @@
TEST_F(FormatTest, DoNotPrematurelyEndUnwrappedLineForReturnStatements) {
verifyFormat(
- "void f() {\n"
- " return C{param1, param2}.SomeCall(param1, param2);\n"
- "}\n");
+ "void f() { return C{param1, param2}.SomeCall(param1, param2); }");
}
TEST_F(FormatTest, FormatsClosingBracesInEmptyNestedBlocks) {
@@ -7204,6 +7548,36 @@
"}\n"
"}",
BreakBeforeBrace);
+
+ verifyFormat("#ifdef _DEBUG\n"
+ "int foo(int i = 0)\n"
+ "#else\n"
+ "int foo(int i = 5)\n"
+ "#endif\n"
+ "{\n"
+ " return i;\n"
+ "}",
+ BreakBeforeBrace);
+
+ verifyFormat("void foo() {}\n"
+ "void bar()\n"
+ "#ifdef _DEBUG\n"
+ "{\n"
+ " foo();\n"
+ "}\n"
+ "#else\n"
+ "{\n"
+ "}\n"
+ "#endif",
+ BreakBeforeBrace);
+
+ verifyFormat("void foobar() { int i = 5; }\n"
+ "#ifdef _DEBUG\n"
+ "void bar() {}\n"
+ "#else\n"
+ "void bar() { foobar(); }\n"
+ "#endif",
+ BreakBeforeBrace);
}
TEST_F(FormatTest, AllmanBraceBreaking) {
@@ -7286,6 +7660,62 @@
"}\n",
BreakBeforeBrace);
+ verifyFormat("@interface BSApplicationController ()\n"
+ "{\n"
+ "@private\n"
+ " id _extraIvar;\n"
+ "}\n"
+ "@end\n",
+ BreakBeforeBrace);
+
+ verifyFormat("#ifdef _DEBUG\n"
+ "int foo(int i = 0)\n"
+ "#else\n"
+ "int foo(int i = 5)\n"
+ "#endif\n"
+ "{\n"
+ " return i;\n"
+ "}",
+ BreakBeforeBrace);
+
+ verifyFormat("void foo() {}\n"
+ "void bar()\n"
+ "#ifdef _DEBUG\n"
+ "{\n"
+ " foo();\n"
+ "}\n"
+ "#else\n"
+ "{\n"
+ "}\n"
+ "#endif",
+ BreakBeforeBrace);
+
+ verifyFormat("void foobar() { int i = 5; }\n"
+ "#ifdef _DEBUG\n"
+ "void bar() {}\n"
+ "#else\n"
+ "void bar() { foobar(); }\n"
+ "#endif",
+ BreakBeforeBrace);
+
+ // This shouldn't affect ObjC blocks..
+ verifyFormat("[self doSomeThingWithACompletionHandler:^{\n"
+ " // ...\n"
+ " int i;\n"
+ "}];",
+ BreakBeforeBrace);
+ verifyFormat("void (^block)(void) = ^{\n"
+ " // ...\n"
+ " int i;\n"
+ "};",
+ BreakBeforeBrace);
+ // .. or dict literals.
+ verifyFormat("void f()\n"
+ "{\n"
+ " [object someMethod:@{ @\"a\" : @\"b\" }];\n"
+ "}",
+ BreakBeforeBrace);
+
BreakBeforeBrace.ColumnLimit = 19;
verifyFormat("void f() { int i; }", BreakBeforeBrace);
BreakBeforeBrace.ColumnLimit = 18;
@@ -7406,12 +7836,49 @@
" Y = 0,\n"
"}\n",
GNUBraceStyle);
+
+ verifyFormat("@interface BSApplicationController ()\n"
+ "{\n"
+ "@private\n"
+ " id _extraIvar;\n"
+ "}\n"
+ "@end\n",
+ GNUBraceStyle);
+
+ verifyFormat("#ifdef _DEBUG\n"
+ "int foo(int i = 0)\n"
+ "#else\n"
+ "int foo(int i = 5)\n"
+ "#endif\n"
+ "{\n"
+ " return i;\n"
+ "}",
+ GNUBraceStyle);
+
+ verifyFormat("void foo() {}\n"
+ "void bar()\n"
+ "#ifdef _DEBUG\n"
+ "{\n"
+ " foo();\n"
+ "}\n"
+ "#else\n"
+ "{\n"
+ "}\n"
+ "#endif",
+ GNUBraceStyle);
+
+ verifyFormat("void foobar() { int i = 5; }\n"
+ "#ifdef _DEBUG\n"
+ "void bar() {}\n"
+ "#else\n"
+ "void bar() { foobar(); }\n"
+ "#endif",
+ GNUBraceStyle);
}
TEST_F(FormatTest, CatchExceptionReferenceBinding) {
verifyFormat("void f() {\n"
" try {\n"
- " }\n"
- " catch (const Exception &e) {\n"
+ " } catch (const Exception &e) {\n"
" }\n"
"}\n",
getLLVMStyle());
@@ -7534,7 +8001,7 @@
CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft);
CHECK_PARSE_BOOL(AlignTrailingComments);
CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
- CHECK_PARSE_BOOL(AllowShortFunctionsOnASingleLine);
+ CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine);
CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine);
CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations);
@@ -7587,6 +8054,18 @@
CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always);
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
+ AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None);
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
+ AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
+ AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None);
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
+ AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Inline);
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
+ AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
+
Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
CHECK_PARSE("SpaceBeforeParens: Never", SpaceBeforeParens,
FormatStyle::SBPO_Never);
@@ -7940,7 +8419,7 @@
"}",
Style);
- Style.AllowShortFunctionsOnASingleLine = false;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
verifyFormat("SomeClass::Constructor()\n"
" : a(a)\n"
" , b(b)\n"
@@ -7951,7 +8430,7 @@
Style);
Style.ColumnLimit = 80;
- Style.AllowShortFunctionsOnASingleLine = true;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
Style.ConstructorInitializerIndentWidth = 2;
verifyFormat("SomeClass::Constructor()\n"
" : a(a)\n"
@@ -8029,6 +8508,9 @@
"}",
Style));
+ // Allow functions on a single line.
+ verifyFormat("void f() { return; }", Style);
+
// Constructor initializers are formatted one per line with the "," on the
// new line.
verifyFormat("Constructor()\n"
@@ -8096,24 +8578,50 @@
format("#define aNumber \\\n"
" 10",
Style));
+
+ // Keep empty and one-element array literals on a single line.
+ EXPECT_EQ("NSArray* a = [[NSArray alloc] initWithArray:@[]\n"
+ " copyItems:YES];",
+ format("NSArray*a=[[NSArray alloc] initWithArray:@[]\n"
+ "copyItems:YES];",
+ Style));
+ EXPECT_EQ("NSArray* a = [[NSArray alloc] initWithArray:@[ @\"a\" ]\n"
+ " copyItems:YES];",
+ format("NSArray*a=[[NSArray alloc]initWithArray:@[ @\"a\" ]\n"
+ " copyItems:YES];",
+ Style));
+ EXPECT_EQ("NSArray* a = [[NSArray alloc] initWithArray:@[\n"
+ " @\"a\",\n"
+ " @\"a\"\n"
+ " ]\n"
+ " copyItems:YES];",
+ format("NSArray* a = [[NSArray alloc] initWithArray:@[\n"
+ " @\"a\",\n"
+ " @\"a\"\n"
+ " ]\n"
+ " copyItems:YES];",
+ Style));
+ EXPECT_EQ(
+ "NSArray* a = [[NSArray alloc] initWithArray:@[ @\"a\", @\"a\" ]\n"
+ " copyItems:YES];",
+ format("NSArray* a = [[NSArray alloc] initWithArray:@[ @\"a\", @\"a\" ]\n"
+ " copyItems:YES];",
+ Style));
+
+ verifyFormat("[self.a b:c c:d];", Style);
+ EXPECT_EQ("[self.a b:c\n"
+ " c:d];",
+ format("[self.a b:c\n"
+ "c:d];",
+ Style));
}
TEST_F(FormatTest, FormatsLambdas) {
- verifyFormat("int c = [b]() mutable {\n"
- " return [&b] { return b++; }();\n"
- "}();\n");
- verifyFormat("int c = [&] {\n"
- " [=] { return b++; }();\n"
- "}();\n");
- verifyFormat("int c = [&, &a, a] {\n"
- " [=, c, &d] { return b++; }();\n"
- "}();\n");
- verifyFormat("int c = [&a, &a, a] {\n"
- " [=, a, b, &c] { return b++; }();\n"
- "}();\n");
- verifyFormat("auto c = {[&a, &a, a] {\n"
- " [=, a, b, &c] { return b++; }();\n"
- "}}\n");
+ verifyFormat("int c = [b]() mutable { return [&b] { return b++; }(); }();\n");
+ verifyFormat("int c = [&] { [=] { return b++; }(); }();\n");
+ verifyFormat("int c = [&, &a, a] { [=, c, &d] { return b++; }(); }();\n");
+ verifyFormat("int c = [&a, &a, a] { [=, a, b, &c] { return b++; }(); }();\n");
+ verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] { return b++; }(); }}\n");
verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] {}(); }}\n");
verifyFormat("void f() {\n"
" other(x.begin(), x.end(), [&](int, int) { return 1; });\n"
@@ -8123,6 +8631,12 @@
" x.end(), //\n"
" [&](int, int) { return 1; });\n"
"}\n");
+ verifyFormat("SomeFunction([]() { // A cool function...\n"
+ " return 43;\n"
+ "});");
+ verifyFormat("void f() {\n"
+ " SomeFunction([](decltype(x), A *a) {});\n"
+ "}");
// Lambdas with return types.
verifyFormat("int c = []() -> int { return 2; }();\n");
@@ -8133,6 +8647,16 @@
" return fffffffffffffffffffffffffffffffffffffff(i * j);\n"
"};");
+ // Multiple lambdas in the same parentheses change indentation rules.
+ verifyFormat("SomeFunction([]() {\n"
+ " int i = 42;\n"
+ " return i;\n"
+ " },\n"
+ " []() {\n"
+ " int j = 43;\n"
+ " return j;\n"
+ " });");
+
// Not lambdas.
verifyFormat("constexpr char hello[]{\"hello\"};");
verifyFormat("double &operator[](int i) { return 0; }\n"
@@ -8173,7 +8697,7 @@
verifyFormat("int a = [operation block:^int(int *i) { return 1; }];");
verifyFormat("[myObject doSomethingWith:arg1\n"
" aaa:^int(int *a) { return 1; }\n"
- " bbb:f(a * b)];");
+ " bbb:f(a * bbbbbbbb)];");
verifyFormat("[operation setCompletionBlock:^{\n"
" [self.delegate newDataAvailable];\n"
@@ -8220,6 +8744,12 @@
" // ...\n"
" int i;\n"
" }];");
+ verifyFormat("[myObject doSomethingWith:arg1\n"
+ " firstBlock:-1\n"
+ " secondBlock:^(Bar *b) {\n"
+ " // ...\n"
+ " int i;\n"
+ " }];");
verifyFormat("f(^{\n"
" @autoreleasepool {\n"
@@ -8340,5 +8870,97 @@
EXPECT_EQ(code, format(code));
}
+TEST_F(FormatTest, HandleConflictMarkers) {
+ // Git/SVN conflict markers.
+ EXPECT_EQ("int a;\n"
+ "void f() {\n"
+ " callme(some(parameter1,\n"
+ "<<<<<<< text by the vcs\n"
+ " parameter2),\n"
+ "||||||| text by the vcs\n"
+ " parameter2),\n"
+ " parameter3,\n"
+ "======= text by the vcs\n"
+ " parameter2, parameter3),\n"
+ ">>>>>>> text by the vcs\n"
+ " otherparameter);\n",
+ format("int a;\n"
+ "void f() {\n"
+ " callme(some(parameter1,\n"
+ "<<<<<<< text by the vcs\n"
+ " parameter2),\n"
+ "||||||| text by the vcs\n"
+ " parameter2),\n"
+ " parameter3,\n"
+ "======= text by the vcs\n"
+ " parameter2,\n"
+ " parameter3),\n"
+ ">>>>>>> text by the vcs\n"
+ " otherparameter);\n"));
+
+ // Perforce markers.
+ EXPECT_EQ("void f() {\n"
+ " function(\n"
+ ">>>> text by the vcs\n"
+ " parameter,\n"
+ "==== text by the vcs\n"
+ " parameter,\n"
+ "==== text by the vcs\n"
+ " parameter,\n"
+ "<<<< text by the vcs\n"
+ " parameter);\n",
+ format("void f() {\n"
+ " function(\n"
+ ">>>> text by the vcs\n"
+ " parameter,\n"
+ "==== text by the vcs\n"
+ " parameter,\n"
+ "==== text by the vcs\n"
+ " parameter,\n"
+ "<<<< text by the vcs\n"
+ " parameter);\n"));
+
+ EXPECT_EQ("<<<<<<<\n"
+ "|||||||\n"
+ "=======\n"
+ ">>>>>>>",
+ format("<<<<<<<\n"
+ "|||||||\n"
+ "=======\n"
+ ">>>>>>>"));
+
+ EXPECT_EQ("<<<<<<<\n"
+ "|||||||\n"
+ "int i;\n"
+ "=======\n"
+ ">>>>>>>",
+ format("<<<<<<<\n"
+ "|||||||\n"
+ "int i;\n"
+ "=======\n"
+ ">>>>>>>"));
+
+ // FIXME: Handle parsing of macros around conflict markers correctly:
+ EXPECT_EQ("#define Macro \\\n"
+ "<<<<<<<\n"
+ "Something \\\n"
+ "|||||||\n"
+ "Else \\\n"
+ "=======\n"
+ "Other \\\n"
+ ">>>>>>>\n"
+ "End int i;\n",
+ format("#define Macro \\\n"
+ "<<<<<<<\n"
+ " Something \\\n"
+ "|||||||\n"
+ " Else \\\n"
+ "=======\n"
+ " Other \\\n"
+ ">>>>>>>\n"
+ " End\n"
+ "int i;\n"));
+}
+
} // end namespace tooling
} // end namespace clang
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp
index c0215e7..ecf4e69 100644
--- a/unittests/Format/FormatTestJS.cpp
+++ b/unittests/Format/FormatTestJS.cpp
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "format-test"
-
#include "FormatTestUtils.h"
#include "clang/Format/Format.h"
#include "llvm/Support/Debug.h"
#include "gtest/gtest.h"
+#define DEBUG_TYPE "format-test"
+
namespace clang {
namespace format {
@@ -31,7 +31,9 @@
return Result;
}
- static std::string format(llvm::StringRef Code, const FormatStyle &Style) {
+ static std::string format(
+ llvm::StringRef Code,
+ const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_JavaScript)) {
return format(Code, 0, Code.size(), Style);
}
@@ -77,19 +79,170 @@
" bbbbbb :\n"
" ccc;",
getGoogleJSStyleWithColumns(20));
+
+ verifyFormat("var b = a.map((x) => x + 1);");
+}
+
+TEST_F(FormatTestJS, ES6DestructuringAssignment) {
+ verifyFormat("var [a, b, c] = [1, 2, 3];");
+ verifyFormat("var {a, b} = {a: 1, b: 2};");
}
TEST_F(FormatTestJS, SpacesInContainerLiterals) {
verifyFormat("var arr = [1, 2, 3];");
verifyFormat("var obj = {a: 1, b: 2, c: 3};");
+ verifyFormat("var object_literal_with_long_name = {\n"
+ " a: 'aaaaaaaaaaaaaaaaaa',\n"
+ " b: 'bbbbbbbbbbbbbbbbbb'\n"
+ "};");
+
verifyFormat("var obj = {a: 1, b: 2, c: 3};",
getChromiumStyle(FormatStyle::LK_JavaScript));
+ verifyFormat("someVariable = {'a': [{}]};");
}
TEST_F(FormatTestJS, SingleQuoteStrings) {
verifyFormat("this.function('', true);");
}
+TEST_F(FormatTestJS, GoogScopes) {
+ verifyFormat("goog.scope(function() {\n"
+ "var x = a.b;\n"
+ "var y = c.d;\n"
+ "}); // goog.scope");
+}
+
+TEST_F(FormatTestJS, Closures) {
+ verifyFormat("doFoo(function() { return 1; });");
+ verifyFormat("var func = function() { return 1; };");
+ verifyFormat("return {\n"
+ " body: {\n"
+ " setAttribute: function(key, val) { this[key] = val; },\n"
+ " getAttribute: function(key) { return this[key]; },\n"
+ " style: {direction: ''}\n"
+ " }\n"
+ "};");
+ EXPECT_EQ("abc = xyz ? function() { return 1; } : function() { return -1; };",
+ format("abc=xyz?function(){return 1;}:function(){return -1;};"));
+
+ verifyFormat("var closure = goog.bind(\n"
+ " function() { // comment\n"
+ " foo();\n"
+ " bar();\n"
+ " },\n"
+ " this, arg1IsReallyLongAndNeeedsLineBreaks,\n"
+ " arg3IsReallyLongAndNeeedsLineBreaks);");
+ verifyFormat("var closure = goog.bind(function() { // comment\n"
+ " foo();\n"
+ " bar();\n"
+ "}, this);");
+
+ verifyFormat("var x = {a: function() { return 1; }};",
+ getGoogleJSStyleWithColumns(38));
+ verifyFormat("var x = {\n"
+ " a: function() { return 1; }\n"
+ "};",
+ getGoogleJSStyleWithColumns(37));
+}
+
+TEST_F(FormatTestJS, ReturnStatements) {
+ verifyFormat("function() { return [hello, world]; }");
+}
+
+TEST_F(FormatTestJS, ClosureStyleComments) {
+ verifyFormat("var x = /** @type {foo} */ (bar);");
+}
+
+TEST_F(FormatTestJS, TryCatch) {
+ verifyFormat("try {\n"
+ " f();\n"
+ "} catch (e) {\n"
+ " g();\n"
+ "} finally {\n"
+ " h();\n"
+ "}");
+}
+
+TEST_F(FormatTestJS, StringLiteralConcatenation) {
+ verifyFormat("var literal = 'hello ' +\n"
+ " 'world';");
+}
+
+TEST_F(FormatTestJS, RegexLiteralClassification) {
+ // Regex literals.
+ verifyFormat("var regex = /abc/;");
+ verifyFormat("f(/abc/);");
+ verifyFormat("f(abc, /abc/);");
+ verifyFormat("some_map[/abc/];");
+ verifyFormat("var x = a ? /abc/ : /abc/;");
+ verifyFormat("for (var i = 0; /abc/.test(s[i]); i++) {\n}");
+ verifyFormat("var x = !/abc/.test(y);");
+ verifyFormat("var x = a && /abc/.test(y);");
+ verifyFormat("var x = a || /abc/.test(y);");
+ verifyFormat("var x = a + /abc/.search(y);");
+ verifyFormat("var regexs = {/abc/, /abc/};");
+ verifyFormat("return /abc/;");
+
+ // Not regex literals.
+ verifyFormat("var a = a / 2 + b / 3;");
+}
+
+TEST_F(FormatTestJS, RegexLiteralSpecialCharacters) {
+ verifyFormat("var regex = /a*/;");
+ verifyFormat("var regex = /a+/;");
+ verifyFormat("var regex = /a?/;");
+ verifyFormat("var regex = /.a./;");
+ verifyFormat("var regex = /a\\*/;");
+ verifyFormat("var regex = /^a$/;");
+ verifyFormat("var regex = /\\/a/;");
+ verifyFormat("var regex = /(?:x)/;");
+ verifyFormat("var regex = /x(?=y)/;");
+ verifyFormat("var regex = /x(?!y)/;");
+ verifyFormat("var regex = /x|y/;");
+ verifyFormat("var regex = /a{2}/;");
+ verifyFormat("var regex = /a{1,3}/;");
+ verifyFormat("var regex = /[abc]/;");
+ verifyFormat("var regex = /[^abc]/;");
+ verifyFormat("var regex = /[\\b]/;");
+ verifyFormat("var regex = /\\b/;");
+ verifyFormat("var regex = /\\B/;");
+ verifyFormat("var regex = /\\d/;");
+ verifyFormat("var regex = /\\D/;");
+ verifyFormat("var regex = /\\f/;");
+ verifyFormat("var regex = /\\n/;");
+ verifyFormat("var regex = /\\r/;");
+ verifyFormat("var regex = /\\s/;");
+ verifyFormat("var regex = /\\S/;");
+ verifyFormat("var regex = /\\t/;");
+ verifyFormat("var regex = /\\v/;");
+ verifyFormat("var regex = /\\w/;");
+ verifyFormat("var regex = /\\W/;");
+ verifyFormat("var regex = /a(a)\\1/;");
+ verifyFormat("var regex = /\\0/;");
+ verifyFormat("var regex = /\\\\/g;");
+ verifyFormat("var regex = /\\a\\\\/g;");
+ verifyFormat("var regex = /\a\\//g;");
+}
+
+TEST_F(FormatTestJS, RegexLiteralModifiers) {
+ verifyFormat("var regex = /abc/g;");
+ verifyFormat("var regex = /abc/i;");
+ verifyFormat("var regex = /abc/m;");
+ verifyFormat("var regex = /abc/y;");
+}
+
+TEST_F(FormatTestJS, RegexLiteralLength) {
+ verifyFormat("var regex = /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
+ getGoogleJSStyleWithColumns(60));
+ verifyFormat("var regex =\n"
+ " /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
+ getGoogleJSStyleWithColumns(60));
+}
+
+TEST_F(FormatTestJS, RegexLiteralExamples) {
+ verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);");
+}
+
} // end namespace tooling
} // end namespace clang
diff --git a/unittests/Format/FormatTestProto.cpp b/unittests/Format/FormatTestProto.cpp
index 0a4416e..6506a6d 100644
--- a/unittests/Format/FormatTestProto.cpp
+++ b/unittests/Format/FormatTestProto.cpp
@@ -7,13 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "format-test"
-
#include "FormatTestUtils.h"
#include "clang/Format/Format.h"
#include "llvm/Support/Debug.h"
#include "gtest/gtest.h"
+#define DEBUG_TYPE "format-test"
+
namespace clang {
namespace format {
@@ -52,10 +52,10 @@
"}");
verifyFormat("message SomeMessage {\n"
- " optional really.really.long.and.qualified.type.aaaaaaa\n"
+ " optional really.really.long.qualified.type.aaa.aaaaaaa\n"
" fiiiiiiiiiiiiiiiiiiiiiiiiield = 1;\n"
" optional\n"
- " really.really.long.and.qualified.type.aaaaaaa.aaaaaaaa\n"
+ " really.really.long.qualified.type.aaa.aaaaaaa.aaaaaaaa\n"
" another_fiiiiiiiiiiiiiiiiiiiiield = 2;\n"
"}");
}
@@ -81,10 +81,17 @@
verifyFormat("optional LongMessageType long_proto_field = 1\n"
" [default = REALLY_REALLY_LONG_CONSTANT_VALUE];");
verifyFormat("repeated double value = 1\n"
- " [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaaa : AAAAAAAA}];");
+ " [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaaa: AAAAAAAA}];");
verifyFormat("repeated double value = 1\n"
- " [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaa : AAAAAAAAAA,\n"
- " bbbbbbbbbbbbbbbb : BBBBBBBBBB}];");
+ " [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaa: AAAAAAAAAA,\n"
+ " bbbbbbbbbbbbbbbb: BBBBBBBBBB}];");
+ verifyFormat("repeated double value = 1\n"
+ " [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaa: AAAAAAAAAA\n"
+ " bbbbbbbbbbbbbbbb: BBBBBBBBBB}];");
+ verifyFormat("repeated double value = 1\n"
+ " [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaa: AAAAAAAAAA,\n"
+ " bbbbbbb: BBBB,\n"
+ " bbbb: BBB}];");
}
TEST_F(FormatTestProto, FormatsOptions) {
@@ -92,5 +99,13 @@
verifyFormat("option (my_custom_option) = \"abc\";");
}
+TEST_F(FormatTestProto, FormatsService) {
+ verifyFormat("service SearchService {\n"
+ " rpc Search(SearchRequest) returns (SearchResponse) {\n"
+ " option foo = true;\n"
+ " }\n"
+ "};");
+}
+
} // end namespace tooling
} // end namespace clang
diff --git a/unittests/Lex/CMakeLists.txt b/unittests/Lex/CMakeLists.txt
index 461e0d9..1fb57cf 100644
--- a/unittests/Lex/CMakeLists.txt
+++ b/unittests/Lex/CMakeLists.txt
@@ -14,4 +14,5 @@
clangLex
clangParse
clangSema
+ clangSerialization
)
diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp
index 40ce928..3d30352 100644
--- a/unittests/Lex/LexerTest.cpp
+++ b/unittests/Lex/LexerTest.cpp
@@ -29,17 +29,22 @@
namespace {
class VoidModuleLoader : public ModuleLoader {
- virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
- ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) {
+ ModuleLoadResult loadModule(SourceLocation ImportLoc,
+ ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) override {
return ModuleLoadResult();
}
- virtual void makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind Visibility,
- SourceLocation ImportLoc,
- bool Complain) { }
+ void makeModuleVisible(Module *Mod,
+ Module::NameVisibilityKind Visibility,
+ SourceLocation ImportLoc,
+ bool Complain) override { }
+
+ GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+ { return 0; }
+ bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+ { return 0; };
};
// The test fixture.
@@ -59,15 +64,15 @@
std::vector<Token> CheckLex(StringRef Source,
ArrayRef<tok::TokenKind> ExpectedTokens) {
MemoryBuffer *buf = MemoryBuffer::getMemBuffer(Source);
- (void) SourceMgr.createMainFileIDForMemBuffer(buf);
+ SourceMgr.setMainFileID(SourceMgr.createFileID(buf));
VoidModuleLoader ModLoader;
HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts,
Target.getPtr());
- Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, Target.getPtr(),
- SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/ 0,
- /*OwnsHeaderSearch =*/ false,
- /*DelayInitialization =*/ false);
+ Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
+ HeaderInfo, ModLoader, /*IILookup =*/0,
+ /*OwnsHeaderSearch =*/false);
+ PP.Initialize(*Target);
PP.EnterMainSourceFile();
std::vector<Token> toks;
diff --git a/unittests/Lex/Makefile b/unittests/Lex/Makefile
index fa233ce..071d01c 100644
--- a/unittests/Lex/Makefile
+++ b/unittests/Lex/Makefile
@@ -9,8 +9,8 @@
CLANG_LEVEL = ../..
TESTNAME = Lex
-LINK_COMPONENTS := mcparser support mc
+LINK_COMPONENTS := mcparser support mc bitreader
USEDLIBS = clangParse.a clangSema.a clangAnalysis.a clangEdit.a \
- clangAST.a clangLex.a clangBasic.a
+ clangSerialization.a clangAST.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/unittests/Makefile
diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index e3a4a76..cceebea 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -11,6 +11,7 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
@@ -34,17 +35,22 @@
// Stub out module loading.
class VoidModuleLoader : public ModuleLoader {
- virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
- ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) {
+ ModuleLoadResult loadModule(SourceLocation ImportLoc,
+ ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) override {
return ModuleLoadResult();
}
- virtual void makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind Visibility,
- SourceLocation ImportLoc,
- bool Complain) { }
+ void makeModuleVisible(Module *Mod,
+ Module::NameVisibilityKind Visibility,
+ SourceLocation ImportLoc,
+ bool Complain) override { }
+
+ GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+ { return 0; }
+ bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+ { return 0; };
};
// Stub to collect data from InclusionDirective callbacks.
@@ -157,7 +163,7 @@
CharSourceRange InclusionDirectiveFilenameRange(const char* SourceText,
const char* HeaderPath, bool SystemHeader) {
MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(SourceText);
- (void)SourceMgr.createMainFileIDForMemBuffer(Buf);
+ SourceMgr.setMainFileID(SourceMgr.createFileID(Buf));
VoidModuleLoader ModLoader;
@@ -167,12 +173,10 @@
AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
IntrusiveRefCntPtr<PreprocessorOptions> PPOpts = new PreprocessorOptions();
- Preprocessor PP(PPOpts, Diags, LangOpts,
- Target.getPtr(),
- SourceMgr, HeaderInfo, ModLoader,
- /*IILookup =*/ 0,
- /*OwnsHeaderSearch =*/false,
- /*DelayInitialization =*/ false);
+ Preprocessor PP(PPOpts, Diags, LangOpts, SourceMgr, HeaderInfo, ModLoader,
+ /*IILookup =*/0,
+ /*OwnsHeaderSearch =*/false);
+ PP.Initialize(*Target);
InclusionDirectiveCallbacks* Callbacks = new InclusionDirectiveCallbacks;
PP.addPPCallbacks(Callbacks); // Takes ownership.
@@ -196,25 +200,25 @@
OpenCLLangOpts.OpenCL = 1;
MemoryBuffer* sourceBuf = MemoryBuffer::getMemBuffer(SourceText, "test.cl");
- (void)SourceMgr.createMainFileIDForMemBuffer(sourceBuf);
+ SourceMgr.setMainFileID(SourceMgr.createFileID(sourceBuf));
VoidModuleLoader ModLoader;
HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags,
OpenCLLangOpts, Target.getPtr());
- Preprocessor PP(new PreprocessorOptions(), Diags, OpenCLLangOpts,
- Target.getPtr(),
- SourceMgr, HeaderInfo, ModLoader,
- /*IILookup =*/ 0,
- /*OwnsHeaderSearch =*/false,
- /*DelayInitialization =*/ false);
+ Preprocessor PP(new PreprocessorOptions(), Diags, OpenCLLangOpts, SourceMgr,
+ HeaderInfo, ModLoader, /*IILookup =*/0,
+ /*OwnsHeaderSearch =*/false);
+ PP.Initialize(*Target);
// parser actually sets correct pragma handlers for preprocessor
// according to LangOptions, so we init Parser to register opencl
// pragma handlers
- ASTContext Context(OpenCLLangOpts, SourceMgr, Target.getPtr(),
+ ASTContext Context(OpenCLLangOpts, SourceMgr,
PP.getIdentifierTable(), PP.getSelectorTable(),
- PP.getBuiltinInfo(), 0);
+ PP.getBuiltinInfo());
+ Context.InitBuiltinTypes(*Target);
+
ASTConsumer Consumer;
Sema S(PP, Context, Consumer);
Parser P(PP, S, false);
diff --git a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
index 58857fa..f7ed8e5 100644
--- a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -53,17 +53,22 @@
};
class VoidModuleLoader : public ModuleLoader {
- virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
- ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) {
+ ModuleLoadResult loadModule(SourceLocation ImportLoc,
+ ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) override {
return ModuleLoadResult();
}
- virtual void makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind Visibility,
- SourceLocation ImportLoc,
- bool Complain) { }
+ void makeModuleVisible(Module *Mod,
+ Module::NameVisibilityKind Visibility,
+ SourceLocation ImportLoc,
+ bool Complain) override { }
+
+ GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+ { return 0; }
+ bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+ { return 0; };
};
TEST_F(PPConditionalDirectiveRecordTest, PPRecAPI) {
@@ -87,16 +92,16 @@
"9\n";
MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source);
- SourceMgr.createMainFileIDForMemBuffer(buf);
+ SourceMgr.setMainFileID(SourceMgr.createFileID(buf));
VoidModuleLoader ModLoader;
HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts,
Target.getPtr());
- Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts,Target.getPtr(),
- SourceMgr, HeaderInfo, ModLoader,
- /*IILookup =*/ 0,
- /*OwnsHeaderSearch =*/false,
- /*DelayInitialization =*/ false);
+ Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
+ HeaderInfo, ModLoader,
+ /*IILookup =*/0,
+ /*OwnsHeaderSearch =*/false);
+ PP.Initialize(*Target);
PPConditionalDirectiveRecord *
PPRec = new PPConditionalDirectiveRecord(SourceMgr);
PP.addPPCallbacks(PPRec);
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index a5f85ff..837a15f 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -10,7 +10,9 @@
#include "TestVisitor.h"
#include <stack>
-namespace clang {
+using namespace clang;
+
+namespace {
class TypeLocVisitor : public ExpectedLocationVisitor<TypeLocVisitor> {
public:
@@ -614,5 +616,4 @@
"};\n"));
}
-
-} // end namespace clang
+} // end anonymous namespace
diff --git a/unittests/Tooling/RefactoringTest.cpp b/unittests/Tooling/RefactoringTest.cpp
index 8c7bfa1..b1ed3c7 100644
--- a/unittests/Tooling/RefactoringTest.cpp
+++ b/unittests/Tooling/RefactoringTest.cpp
@@ -252,7 +252,9 @@
// descriptor, which might not see the changes made.
// FIXME: Figure out whether there is a way to get the SourceManger to
// reopen the file.
- return Context.Files.getBufferForFile(Path, NULL)->getBuffer();
+ std::unique_ptr<const llvm::MemoryBuffer> FileBuffer(
+ Context.Files.getBufferForFile(Path, NULL));
+ return FileBuffer->getBuffer();
}
llvm::StringMap<std::string> TemporaryFiles;
diff --git a/unittests/Tooling/RewriterTestContext.h b/unittests/Tooling/RewriterTestContext.h
index 841cd0f..f02ba1a 100644
--- a/unittests/Tooling/RewriterTestContext.h
+++ b/unittests/Tooling/RewriterTestContext.h
@@ -52,7 +52,7 @@
llvm::MemoryBuffer::getMemBuffer(Content);
const FileEntry *Entry =
Files.getVirtualFile(Name, Source->getBufferSize(), 0);
- Sources.overrideFileContents(Entry, Source, true);
+ Sources.overrideFileContents(Entry, Source);
assert(Entry != NULL);
return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
}
@@ -102,7 +102,9 @@
// descriptor, which might not see the changes made.
// FIXME: Figure out whether there is a way to get the SourceManger to
// reopen the file.
- return Files.getBufferForFile(Path, NULL)->getBuffer();
+ std::unique_ptr<const llvm::MemoryBuffer> FileBuffer(
+ Files.getBufferForFile(Path, NULL));
+ return FileBuffer->getBuffer();
}
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp
index 1eff6d0..2d055e7 100644
--- a/unittests/Tooling/ToolingTest.cpp
+++ b/unittests/Tooling/ToolingTest.cpp
@@ -108,11 +108,11 @@
}
TEST(buildASTFromCode, FindsClassDecl) {
- std::unique_ptr<ASTUnit> AST(buildASTFromCode("class X;"));
+ std::unique_ptr<ASTUnit> AST = buildASTFromCode("class X;");
ASSERT_TRUE(AST.get());
EXPECT_TRUE(FindClassDeclX(AST.get()));
- AST.reset(buildASTFromCode("class Y;"));
+ AST = buildASTFromCode("class Y;");
ASSERT_TRUE(AST.get());
EXPECT_FALSE(FindClassDeclX(AST.get()));
}
@@ -206,7 +206,9 @@
Tool.mapVirtualFile("/a.cc", "void a() {}");
Tool.mapVirtualFile("/b.cc", "void b() {}");
- Tool.run(newFrontendActionFactory(&EndCallback, &EndCallback));
+ std::unique_ptr<FrontendActionFactory> Action(
+ newFrontendActionFactory(&EndCallback, &EndCallback));
+ Tool.run(Action.get());
EXPECT_TRUE(EndCallback.Matched);
EXPECT_EQ(2u, EndCallback.BeginCalled);
@@ -277,10 +279,13 @@
ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
Tool.mapVirtualFile("/a.cc", "void a() {}");
+ std::unique_ptr<FrontendActionFactory> Action(
+ newFrontendActionFactory<SyntaxOnlyAction>());
+
bool Found = false;
bool Ran = false;
Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
- Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
+ Tool.run(Action.get());
EXPECT_TRUE(Ran);
EXPECT_TRUE(Found);
@@ -288,7 +293,7 @@
Tool.clearArgumentsAdjusters();
Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
Tool.appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster());
- Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
+ Tool.run(Action.get());
EXPECT_TRUE(Ran);
EXPECT_FALSE(Found);
}
@@ -305,11 +310,9 @@
Tool.mapVirtualFile("/a.cc", "void a() {}");
Tool.mapVirtualFile("/b.cc", "void b() {}");
- std::vector<ASTUnit *> ASTs;
+ std::vector<std::unique_ptr<ASTUnit>> ASTs;
EXPECT_EQ(0, Tool.buildASTs(ASTs));
EXPECT_EQ(2u, ASTs.size());
-
- llvm::DeleteContainerPointers(ASTs);
}
struct TestDiagnosticConsumer : public DiagnosticConsumer {
@@ -327,7 +330,9 @@
Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
TestDiagnosticConsumer Consumer;
Tool.setDiagnosticConsumer(&Consumer);
- Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
+ std::unique_ptr<FrontendActionFactory> Action(
+ newFrontendActionFactory<SyntaxOnlyAction>());
+ Tool.run(Action.get());
EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
}
@@ -337,7 +342,7 @@
Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
TestDiagnosticConsumer Consumer;
Tool.setDiagnosticConsumer(&Consumer);
- std::vector<ASTUnit*> ASTs;
+ std::vector<std::unique_ptr<ASTUnit>> ASTs;
Tool.buildASTs(ASTs);
EXPECT_EQ(1u, ASTs.size());
EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp
index 64128f1..213222c 100644
--- a/unittests/libclang/LibclangTest.cpp
+++ b/unittests/libclang/LibclangTest.cpp
@@ -49,120 +49,263 @@
}
~TestVFO() {
- if (!Contents)
- return;
- char *BufPtr;
- unsigned BufSize;
- clang_VirtualFileOverlay_writeToBuffer(VFO, 0, &BufPtr, &BufSize);
- std::string BufStr(BufPtr, BufSize);
- EXPECT_STREQ(Contents, BufStr.c_str());
- free(BufPtr);
+ if (Contents) {
+ char *BufPtr;
+ unsigned BufSize;
+ clang_VirtualFileOverlay_writeToBuffer(VFO, 0, &BufPtr, &BufSize);
+ std::string BufStr(BufPtr, BufSize);
+ EXPECT_STREQ(Contents, BufStr.c_str());
+ free(BufPtr);
+ }
clang_VirtualFileOverlay_dispose(VFO);
}
};
}
-TEST(libclang, VirtualFileOverlay) {
- {
- const char *contents =
- "{\n"
- " 'version': 0,\n"
- " 'roots': [\n"
- " {\n"
- " 'type': 'directory',\n"
- " 'name': \"/path/virtual\",\n"
- " 'contents': [\n"
- " {\n"
- " 'type': 'file',\n"
- " 'name': \"foo.h\",\n"
- " 'external-contents': \"/real/foo.h\"\n"
- " }\n"
- " ]\n"
- " }\n"
- " ]\n"
- "}\n";
- TestVFO T(contents);
- T.map("/path/virtual/foo.h", "/real/foo.h");
- }
- {
- TestVFO T(NULL);
- T.mapError("/path/./virtual/../foo.h", "/real/foo.h",
- CXError_InvalidArguments);
- }
- {
- const char *contents =
- "{\n"
- " 'version': 0,\n"
- " 'roots': [\n"
- " {\n"
- " 'type': 'directory',\n"
- " 'name': \"/another/dir\",\n"
- " 'contents': [\n"
- " {\n"
- " 'type': 'file',\n"
- " 'name': \"foo2.h\",\n"
- " 'external-contents': \"/real/foo2.h\"\n"
- " }\n"
- " ]\n"
- " },\n"
- " {\n"
- " 'type': 'directory',\n"
- " 'name': \"/path/virtual/dir\",\n"
- " 'contents': [\n"
- " {\n"
- " 'type': 'file',\n"
- " 'name': \"foo1.h\",\n"
- " 'external-contents': \"/real/foo1.h\"\n"
- " },\n"
- " {\n"
- " 'type': 'file',\n"
- " 'name': \"foo3.h\",\n"
- " 'external-contents': \"/real/foo3.h\"\n"
- " },\n"
- " {\n"
- " 'type': 'directory',\n"
- " 'name': \"in/subdir\",\n"
- " 'contents': [\n"
- " {\n"
- " 'type': 'file',\n"
- " 'name': \"foo4.h\",\n"
- " 'external-contents': \"/real/foo4.h\"\n"
- " }\n"
- " ]\n"
- " }\n"
- " ]\n"
- " }\n"
- " ]\n"
- "}\n";
- TestVFO T(contents);
- T.map("/path/virtual/dir/foo1.h", "/real/foo1.h");
- T.map("/another/dir/foo2.h", "/real/foo2.h");
- T.map("/path/virtual/dir/foo3.h", "/real/foo3.h");
- T.map("/path/virtual/dir/in/subdir/foo4.h", "/real/foo4.h");
- }
- {
- const char *contents =
- "{\n"
- " 'version': 0,\n"
- " 'case-sensitive': 'false',\n"
- " 'roots': [\n"
- " {\n"
- " 'type': 'directory',\n"
- " 'name': \"/path/virtual\",\n"
- " 'contents': [\n"
- " {\n"
- " 'type': 'file',\n"
- " 'name': \"foo.h\",\n"
- " 'external-contents': \"/real/foo.h\"\n"
- " }\n"
- " ]\n"
- " }\n"
- " ]\n"
- "}\n";
- TestVFO T(contents);
- T.map("/path/virtual/foo.h", "/real/foo.h");
- clang_VirtualFileOverlay_setCaseSensitivity(T.VFO, false);
- }
+TEST(libclang, VirtualFileOverlay_Basic) {
+ const char *contents =
+ "{\n"
+ " 'version': 0,\n"
+ " 'roots': [\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path/virtual\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"foo.h\",\n"
+ " 'external-contents': \"/real/foo.h\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ "}\n";
+ TestVFO T(contents);
+ T.map("/path/virtual/foo.h", "/real/foo.h");
+}
+
+TEST(libclang, VirtualFileOverlay_Unicode) {
+ const char *contents =
+ "{\n"
+ " 'version': 0,\n"
+ " 'roots': [\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path/\\u266B\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"\\u2602.h\",\n"
+ " 'external-contents': \"/real/\\u2602.h\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ "}\n";
+ TestVFO T(contents);
+ T.map("/path/♫/☂.h", "/real/☂.h");
+}
+
+TEST(libclang, VirtualFileOverlay_InvalidArgs) {
+ TestVFO T(NULL);
+ T.mapError("/path/./virtual/../foo.h", "/real/foo.h",
+ CXError_InvalidArguments);
+}
+
+TEST(libclang, VirtualFileOverlay_RemapDirectories) {
+ const char *contents =
+ "{\n"
+ " 'version': 0,\n"
+ " 'roots': [\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/another/dir\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"foo2.h\",\n"
+ " 'external-contents': \"/real/foo2.h\"\n"
+ " }\n"
+ " ]\n"
+ " },\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path/virtual/dir\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"foo1.h\",\n"
+ " 'external-contents': \"/real/foo1.h\"\n"
+ " },\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"foo3.h\",\n"
+ " 'external-contents': \"/real/foo3.h\"\n"
+ " },\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"in/subdir\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"foo4.h\",\n"
+ " 'external-contents': \"/real/foo4.h\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ "}\n";
+ TestVFO T(contents);
+ T.map("/path/virtual/dir/foo1.h", "/real/foo1.h");
+ T.map("/another/dir/foo2.h", "/real/foo2.h");
+ T.map("/path/virtual/dir/foo3.h", "/real/foo3.h");
+ T.map("/path/virtual/dir/in/subdir/foo4.h", "/real/foo4.h");
+}
+
+TEST(libclang, VirtualFileOverlay_CaseInsensitive) {
+ const char *contents =
+ "{\n"
+ " 'version': 0,\n"
+ " 'case-sensitive': 'false',\n"
+ " 'roots': [\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path/virtual\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"foo.h\",\n"
+ " 'external-contents': \"/real/foo.h\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ "}\n";
+ TestVFO T(contents);
+ T.map("/path/virtual/foo.h", "/real/foo.h");
+ clang_VirtualFileOverlay_setCaseSensitivity(T.VFO, false);
+}
+
+TEST(libclang, VirtualFileOverlay_SharedPrefix) {
+ const char *contents =
+ "{\n"
+ " 'version': 0,\n"
+ " 'roots': [\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path/foo\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"bar\",\n"
+ " 'external-contents': \"/real/bar\"\n"
+ " },\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"bar.h\",\n"
+ " 'external-contents': \"/real/bar.h\"\n"
+ " }\n"
+ " ]\n"
+ " },\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path/foobar\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"baz.h\",\n"
+ " 'external-contents': \"/real/baz.h\"\n"
+ " }\n"
+ " ]\n"
+ " },\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"foobarbaz.h\",\n"
+ " 'external-contents': \"/real/foobarbaz.h\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ "}\n";
+ TestVFO T(contents);
+ T.map("/path/foo/bar.h", "/real/bar.h");
+ T.map("/path/foo/bar", "/real/bar");
+ T.map("/path/foobar/baz.h", "/real/baz.h");
+ T.map("/path/foobarbaz.h", "/real/foobarbaz.h");
+}
+
+TEST(libclang, VirtualFileOverlay_AdjacentDirectory) {
+ const char *contents =
+ "{\n"
+ " 'version': 0,\n"
+ " 'roots': [\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path/dir1\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"foo.h\",\n"
+ " 'external-contents': \"/real/foo.h\"\n"
+ " },\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"subdir\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"bar.h\",\n"
+ " 'external-contents': \"/real/bar.h\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ " },\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/path/dir2\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"baz.h\",\n"
+ " 'external-contents': \"/real/baz.h\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ "}\n";
+ TestVFO T(contents);
+ T.map("/path/dir1/foo.h", "/real/foo.h");
+ T.map("/path/dir1/subdir/bar.h", "/real/bar.h");
+ T.map("/path/dir2/baz.h", "/real/baz.h");
+}
+
+TEST(libclang, VirtualFileOverlay_TopLevel) {
+ const char *contents =
+ "{\n"
+ " 'version': 0,\n"
+ " 'roots': [\n"
+ " {\n"
+ " 'type': 'directory',\n"
+ " 'name': \"/\",\n"
+ " 'contents': [\n"
+ " {\n"
+ " 'type': 'file',\n"
+ " 'name': \"foo.h\",\n"
+ " 'external-contents': \"/real/foo.h\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ " ]\n"
+ "}\n";
+ TestVFO T(contents);
+ T.map("/foo.h", "/real/foo.h");
}
TEST(libclang, ModuleMapDescriptor) {