diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:47:56 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:47:56 +0000 |
commit | 5e20cdd81c44a443562a09007668ffdf76c455af (patch) | |
tree | dbbd4047878da71c1a706e26ce05b4e7791b14cc /unittests | |
parent | d5f23b0b7528b5c3caed1ba14f897cc4aaa9e3c3 (diff) | |
download | src-5e20cdd81c44a443562a09007668ffdf76c455af.tar.gz src-5e20cdd81c44a443562a09007668ffdf76c455af.zip |
Notes
Diffstat (limited to 'unittests')
38 files changed, 1973 insertions, 582 deletions
diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp index 9f179c4a3f2d..070b4daabb8f 100644 --- a/unittests/AST/DeclPrinterTest.cpp +++ b/unittests/AST/DeclPrinterTest.cpp @@ -44,7 +44,7 @@ class PrintMatch : public MatchFinder::MatchCallback { public: PrintMatch() : NumFoundDecls(0) {} - virtual void run(const MatchFinder::MatchResult &Result) { + void run(const MatchFinder::MatchResult &Result) override { const Decl *D = Result.Nodes.getDeclAs<Decl>("id"); if (!D || D->isImplicit()) return; diff --git a/unittests/AST/ExternalASTSourceTest.cpp b/unittests/AST/ExternalASTSourceTest.cpp index 0cfde74cccce..4f42dcf10336 100644 --- a/unittests/AST/ExternalASTSourceTest.cpp +++ b/unittests/AST/ExternalASTSourceTest.cpp @@ -28,15 +28,15 @@ public: TestFrontendAction(ExternalASTSource *Source) : Source(Source) {} private: - virtual void ExecuteAction() { + void ExecuteAction() override { getCompilerInstance().getASTContext().setExternalSource(Source); getCompilerInstance().getASTContext().getTranslationUnitDecl() ->setHasExternalVisibleStorage(); return ASTFrontendAction::ExecuteAction(); } - virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override { return llvm::make_unique<ASTConsumer>(); } @@ -67,8 +67,8 @@ TEST(ExternalASTSourceTest, FailedLookupOccursOnce) { struct TestSource : ExternalASTSource { TestSource(unsigned &Calls) : Calls(Calls) {} - bool FindExternalVisibleDeclsByName(const DeclContext*, - DeclarationName Name) { + bool FindExternalVisibleDeclsByName(const DeclContext *, + DeclarationName Name) override { if (Name.getAsString() == "j") ++Calls; return false; diff --git a/unittests/AST/MatchVerifier.h b/unittests/AST/MatchVerifier.h index e6593913b700..31932479ef8d 100644 --- a/unittests/AST/MatchVerifier.h +++ b/unittests/AST/MatchVerifier.h @@ -63,7 +63,7 @@ public: Language L); protected: - virtual void run(const MatchFinder::MatchResult &Result); + void run(const MatchFinder::MatchResult &Result) override; virtual void verify(const MatchFinder::MatchResult &Result, const NodeType &Node) {} @@ -166,7 +166,8 @@ public: } protected: - void verify(const MatchFinder::MatchResult &Result, const NodeType &Node) { + void verify(const MatchFinder::MatchResult &Result, + const NodeType &Node) override { SourceLocation Loc = getLocation(Node); unsigned Line = Result.SourceManager->getSpellingLineNumber(Loc); unsigned Column = Result.SourceManager->getSpellingColumnNumber(Loc); @@ -205,7 +206,8 @@ public: } protected: - void verify(const MatchFinder::MatchResult &Result, const NodeType &Node) { + void verify(const MatchFinder::MatchResult &Result, + const NodeType &Node) override { SourceRange R = getRange(Node); SourceLocation Begin = R.getBegin(); SourceLocation End = R.getEnd(); @@ -244,7 +246,7 @@ public: protected: void verify(const MatchFinder::MatchResult &Result, - const ast_type_traits::DynTypedNode &Node) { + const ast_type_traits::DynTypedNode &Node) override { std::string DumpStr; llvm::raw_string_ostream Dump(DumpStr); Node.dump(Dump, *Result.SourceManager); @@ -271,7 +273,7 @@ public: protected: void verify(const MatchFinder::MatchResult &Result, - const ast_type_traits::DynTypedNode &Node) { + const ast_type_traits::DynTypedNode &Node) override { std::string PrintStr; llvm::raw_string_ostream Print(PrintStr); Node.print(Print, Result.Context->getPrintingPolicy()); diff --git a/unittests/AST/NamedDeclPrinterTest.cpp b/unittests/AST/NamedDeclPrinterTest.cpp index f8fb98454bd7..cf97a0abf6c8 100644 --- a/unittests/AST/NamedDeclPrinterTest.cpp +++ b/unittests/AST/NamedDeclPrinterTest.cpp @@ -37,7 +37,7 @@ public: explicit PrintMatch(bool suppressUnwrittenScope) : NumFoundDecls(0), SuppressUnwrittenScope(suppressUnwrittenScope) {} - virtual void run(const MatchFinder::MatchResult &Result) { + void run(const MatchFinder::MatchResult &Result) override { const NamedDecl *ND = Result.Nodes.getNodeAs<NamedDecl>("id"); if (!ND) return; diff --git a/unittests/AST/SourceLocationTest.cpp b/unittests/AST/SourceLocationTest.cpp index ca5a8892a586..b0a8f85f0e40 100644 --- a/unittests/AST/SourceLocationTest.cpp +++ b/unittests/AST/SourceLocationTest.cpp @@ -60,7 +60,7 @@ TEST(RangeVerifier, WrongRange) { class LabelDeclRangeVerifier : public RangeVerifier<LabelStmt> { protected: - virtual SourceRange getRange(const LabelStmt &Node) { + SourceRange getRange(const LabelStmt &Node) override { return Node.getDecl()->getSourceRange(); } }; @@ -109,6 +109,38 @@ TEST(MemberExpr, ImplicitMemberRange) { memberExpr())); } +class MemberExprArrowLocVerifier : public RangeVerifier<MemberExpr> { +protected: + SourceRange getRange(const MemberExpr &Node) override { + return Node.getOperatorLoc(); + } +}; + +TEST(MemberExpr, ArrowRange) { + MemberExprArrowLocVerifier Verifier; + Verifier.expectRange(2, 19, 2, 19); + EXPECT_TRUE(Verifier.match("struct S { int x; };\n" + "void foo(S *s) { s->x = 0; }", + memberExpr())); +} + +TEST(MemberExpr, MacroArrowRange) { + MemberExprArrowLocVerifier Verifier; + Verifier.expectRange(1, 24, 1, 24); + EXPECT_TRUE(Verifier.match("#define MEMBER(a, b) (a->b)\n" + "struct S { int x; };\n" + "void foo(S *s) { MEMBER(s, x) = 0; }", + memberExpr())); +} + +TEST(MemberExpr, ImplicitArrowRange) { + MemberExprArrowLocVerifier Verifier; + Verifier.expectRange(0, 0, 0, 0); + EXPECT_TRUE(Verifier.match("struct S { int x; void Test(); };\n" + "void S::Test() { x = 1; }", + memberExpr())); +} + TEST(VarDecl, VMTypeFixedVarDeclRange) { RangeVerifier<VarDecl> Verifier; Verifier.expectRange(1, 1, 1, 23); @@ -122,6 +154,18 @@ TEST(CXXConstructorDecl, NoRetFunTypeLocRange) { EXPECT_TRUE(Verifier.match("class C { C(); };", functionDecl())); } +TEST(CXXConstructorDecl, DefaultedCtorLocRange) { + RangeVerifier<CXXConstructorDecl> Verifier; + Verifier.expectRange(1, 11, 1, 23); + EXPECT_TRUE(Verifier.match("class C { C() = default; };", functionDecl())); +} + +TEST(CXXConstructorDecl, DeletedCtorLocRange) { + RangeVerifier<CXXConstructorDecl> Verifier; + Verifier.expectRange(1, 11, 1, 22); + EXPECT_TRUE(Verifier.match("class C { C() = delete; };", functionDecl())); +} + TEST(CompoundLiteralExpr, CompoundVectorLiteralRange) { RangeVerifier<CompoundLiteralExpr> Verifier; Verifier.expectRange(2, 11, 2, 22); @@ -157,7 +201,7 @@ TEST(InitListExpr, VectorLiteralInitListParens) { class TemplateAngleBracketLocRangeVerifier : public RangeVerifier<TypeLoc> { protected: - virtual SourceRange getRange(const TypeLoc &Node) { + SourceRange getRange(const TypeLoc &Node) override { TemplateSpecializationTypeLoc T = Node.getUnqualifiedLoc().castAs<TemplateSpecializationTypeLoc>(); assert(!T.isNull()); @@ -182,7 +226,7 @@ TEST(CXXNewExpr, TypeParenRange) { class UnaryTransformTypeLocParensRangeVerifier : public RangeVerifier<TypeLoc> { protected: - virtual SourceRange getRange(const TypeLoc &Node) { + SourceRange getRange(const TypeLoc &Node) override { UnaryTransformTypeLoc T = Node.getUnqualifiedLoc().castAs<UnaryTransformTypeLoc>(); assert(!T.isNull()); diff --git a/unittests/AST/StmtPrinterTest.cpp b/unittests/AST/StmtPrinterTest.cpp index 541fb3df1d90..b1fd2c1eb42c 100644 --- a/unittests/AST/StmtPrinterTest.cpp +++ b/unittests/AST/StmtPrinterTest.cpp @@ -44,7 +44,7 @@ class PrintMatch : public MatchFinder::MatchCallback { public: PrintMatch() : NumFoundStmts(0) {} - virtual void run(const MatchFinder::MatchResult &Result) { + void run(const MatchFinder::MatchResult &Result) override { const Stmt *S = Result.Nodes.getStmtAs<Stmt>("id"); if (!S) return; diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index d2e9ee19b2cf..ae363e974b5d 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -379,6 +379,21 @@ TEST(DeclarationMatcher, hasDeclContext) { EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl())))); } +TEST(DeclarationMatcher, translationUnitDecl) { + const std::string Code = "int MyVar1;\n" + "namespace NameSpace {\n" + "int MyVar2;\n" + "} // namespace NameSpace\n"; + EXPECT_TRUE(matches( + Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl())))); + EXPECT_FALSE(matches( + Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl())))); + EXPECT_TRUE(matches( + Code, + varDecl(hasName("MyVar2"), + hasDeclContext(decl(hasDeclContext(translationUnitDecl())))))); +} + TEST(DeclarationMatcher, LinkageSpecification) { EXPECT_TRUE(matches("extern \"C\" { void foo() {}; }", linkageSpecDecl())); EXPECT_TRUE(notMatches("void foo() {};", linkageSpecDecl())); @@ -732,12 +747,12 @@ public: Name.clear(); } - ~VerifyIdIsBoundTo() { + ~VerifyIdIsBoundTo() override { EXPECT_EQ(0, Count); EXPECT_EQ("", Name); } - virtual bool run(const BoundNodes *Nodes) override { + bool run(const BoundNodes *Nodes) override { const BoundNodes::IDToNodeMap &M = Nodes->getMap(); if (Nodes->getNodeAs<T>(Id)) { ++Count; @@ -759,7 +774,7 @@ public: return false; } - virtual bool run(const BoundNodes *Nodes, ASTContext *Context) override { + bool run(const BoundNodes *Nodes, ASTContext *Context) override { return run(Nodes); } @@ -1383,6 +1398,12 @@ TEST(Callee, MatchesDeclarations) { EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX)); EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX)); + + CallMethodX = callExpr(callee(conversionDecl())); + EXPECT_TRUE( + matches("struct Y { operator int() const; }; int i = Y();", CallMethodX)); + EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();", + CallMethodX)); } TEST(Callee, MatchesMemberExpressions) { @@ -1574,6 +1595,13 @@ TEST(IsDeleted, MatchesDeletedFunctionDeclarations) { functionDecl(hasName("Func"), isDeleted()))); } +TEST(isConstexpr, MatchesConstexprDeclarations) { + EXPECT_TRUE(matches("constexpr int foo = 42;", + varDecl(hasName("foo"), isConstexpr()))); + EXPECT_TRUE(matches("constexpr int bar();", + functionDecl(hasName("bar"), isConstexpr()))); +} + TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) { EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };", methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); @@ -1775,6 +1803,9 @@ TEST(Matcher, MatchesOverridingMethod) { methodDecl(isOverride()))); EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ", methodDecl(isOverride()))); + EXPECT_TRUE( + matches("template <typename Base> struct Y : Base { void f() override;};", + methodDecl(isOverride(), hasName("::Y::f")))); } TEST(Matcher, ConstructorCall) { @@ -2104,14 +2135,26 @@ TEST(Matcher, FloatLiterals) { EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral)); EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral)); EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral)); + EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0)))); + EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f)))); + EXPECT_TRUE( + matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0))))); EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral)); + EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0)))); + EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f)))); + EXPECT_TRUE( + notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0))))); } TEST(Matcher, NullPtrLiteral) { EXPECT_TRUE(matches("int* i = nullptr;", nullPtrLiteralExpr())); } +TEST(Matcher, GNUNullExpr) { + EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr())); +} + TEST(Matcher, AsmStatement) { EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt())); } @@ -2515,10 +2558,9 @@ TEST(AstMatcherPMacro, Works) { HasClassB, new VerifyIdIsBoundTo<Decl>("b"))); } -AST_POLYMORPHIC_MATCHER_P( - polymorphicHas, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(Decl, Stmt), - internal::Matcher<Decl>, AMatcher) { +AST_POLYMORPHIC_MATCHER_P(polymorphicHas, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt), + internal::Matcher<Decl>, AMatcher) { return Finder->matchesChildOf( Node, AMatcher, Builder, ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, @@ -3136,6 +3178,12 @@ TEST(InitListExpression, MatchesInitListExpression) { initListExpr(hasType(asString("int [2]"))))); EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };", initListExpr(hasType(recordDecl(hasName("B")))))); + EXPECT_TRUE(matches("struct S { S(void (*a)()); };" + "void f();" + "S s[1] = { &f };", + declRefExpr(to(functionDecl(hasName("f")))))); + EXPECT_TRUE( + matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42)))); } TEST(UsingDeclaration, MatchesUsingDeclarations) { @@ -4348,9 +4396,9 @@ public: : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) { } - virtual bool run(const BoundNodes *Nodes) { return false; } + bool run(const BoundNodes *Nodes) override { return false; } - virtual bool run(const BoundNodes *Nodes, ASTContext *Context) { + bool run(const BoundNodes *Nodes, ASTContext *Context) override { const T *Node = Nodes->getNodeAs<T>(Id); return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) != nullptr; @@ -4399,9 +4447,9 @@ TEST(MatchFinder, CanMatchSingleNodesRecursively) { template <typename T> class VerifyAncestorHasChildIsEqual : public BoundNodesCallback { public: - virtual bool run(const BoundNodes *Nodes) { return false; } + bool run(const BoundNodes *Nodes) override { return false; } - virtual bool run(const BoundNodes *Nodes, ASTContext *Context) { + bool run(const BoundNodes *Nodes, ASTContext *Context) override { const T *Node = Nodes->getNodeAs<T>(""); return verify(*Nodes, *Context, Node); } @@ -4457,12 +4505,10 @@ TEST(MatchFinder, CheckProfiling) { class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback { public: VerifyStartOfTranslationUnit() : Called(false) {} - virtual void run(const MatchFinder::MatchResult &Result) { + void run(const MatchFinder::MatchResult &Result) override { EXPECT_TRUE(Called); } - virtual void onStartOfTranslationUnit() { - Called = true; - } + void onStartOfTranslationUnit() override { Called = true; } bool Called; }; @@ -4485,12 +4531,10 @@ TEST(MatchFinder, InterceptsStartOfTranslationUnit) { class VerifyEndOfTranslationUnit : public MatchFinder::MatchCallback { public: VerifyEndOfTranslationUnit() : Called(false) {} - virtual void run(const MatchFinder::MatchResult &Result) { + void run(const MatchFinder::MatchResult &Result) override { EXPECT_FALSE(Called); } - virtual void onEndOfTranslationUnit() { - Called = true; - } + void onEndOfTranslationUnit() override { Called = true; } bool Called; }; @@ -4683,5 +4727,50 @@ TEST(Matcher, IsExpansionInFileMatching) { #endif // LLVM_ON_WIN32 + +TEST(ObjCMessageExprMatcher, SimpleExprs) { + // don't find ObjCMessageExpr where none are present + EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything()))); + + std::string Objc1String = + "@interface Str " + " - (Str *)uppercaseString:(Str *)str;" + "@end " + "@interface foo " + "- (void)meth:(Str *)text;" + "@end " + " " + "@implementation foo " + "- (void) meth:(Str *)text { " + " [self contents];" + " Str *up = [text uppercaseString];" + "} " + "@end "; + EXPECT_TRUE(matchesObjC( + Objc1String, + objcMessageExpr(anything()))); + EXPECT_TRUE(matchesObjC( + Objc1String, + objcMessageExpr(hasSelector("contents")))); + EXPECT_TRUE(matchesObjC( + Objc1String, + objcMessageExpr(matchesSelector("cont*")))); + EXPECT_FALSE(matchesObjC( + Objc1String, + objcMessageExpr(matchesSelector("?cont*")))); + EXPECT_TRUE(notMatchesObjC( + Objc1String, + objcMessageExpr(hasSelector("contents"), hasNullSelector()))); + EXPECT_TRUE(matchesObjC( + Objc1String, + objcMessageExpr(hasSelector("contents"), hasUnarySelector()))); + EXPECT_TRUE(matchesObjC( + Objc1String, + objcMessageExpr(matchesSelector("uppercase*"), + argumentCountIs(0) + ))); + +} + } // end namespace ast_matchers } // end namespace clang diff --git a/unittests/ASTMatchers/ASTMatchersTest.h b/unittests/ASTMatchers/ASTMatchersTest.h index a2ab9feee2a2..e555e6318d58 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.h +++ b/unittests/ASTMatchers/ASTMatchersTest.h @@ -40,7 +40,7 @@ public: VerifyMatch(BoundNodesCallback *FindResultVerifier, bool *Verified) : Verified(Verified), FindResultReviewer(FindResultVerifier) {} - virtual void run(const MatchFinder::MatchResult &Result) override { + void run(const MatchFinder::MatchResult &Result) override { if (FindResultReviewer != nullptr) { *Verified |= FindResultReviewer->run(&Result.Nodes, Result.Context); } else { @@ -62,7 +62,8 @@ template <typename T> testing::AssertionResult matchesConditionally( const std::string &Code, const T &AMatcher, bool ExpectMatch, llvm::StringRef CompileArg, - const FileContentMappings &VirtualMappedFiles = FileContentMappings()) { + const FileContentMappings &VirtualMappedFiles = FileContentMappings(), + const std::string &Filename = "input.cc") { bool Found = false, DynamicFound = false; MatchFinder Finder; VerifyMatch VerifyFound(nullptr, &Found); @@ -73,8 +74,12 @@ testing::AssertionResult matchesConditionally( std::unique_ptr<FrontendActionFactory> Factory( newFrontendActionFactory(&Finder)); // Some tests use typeof, which is a gnu extension. - std::vector<std::string> Args(1, CompileArg); - if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, "input.cc", + std::vector<std::string> Args; + Args.push_back(CompileArg); + // Some tests need rtti/exceptions on + Args.push_back("-frtti"); + Args.push_back("-fexceptions"); + if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, Filename, VirtualMappedFiles)) { return testing::AssertionFailure() << "Parsing error in \"" << Code << "\""; } @@ -105,6 +110,23 @@ testing::AssertionResult notMatches(const std::string &Code, return matchesConditionally(Code, AMatcher, false, "-std=c++11"); } +template <typename T> +testing::AssertionResult matchesObjC(const std::string &Code, + const T &AMatcher) { + return matchesConditionally( + Code, AMatcher, true, + "", FileContentMappings(), "input.m"); +} + +template <typename T> +testing::AssertionResult notMatchesObjC(const std::string &Code, + const T &AMatcher) { + return matchesConditionally( + Code, AMatcher, false, + "", FileContentMappings(), "input.m"); +} + + // Function based on matchesConditionally with "-x cuda" argument added and // small CUDA header prepended to the code string. template <typename T> diff --git a/unittests/ASTMatchers/Dynamic/CMakeLists.txt b/unittests/ASTMatchers/Dynamic/CMakeLists.txt index 8b95a7be6e5f..506a65549e4f 100644 --- a/unittests/ASTMatchers/Dynamic/CMakeLists.txt +++ b/unittests/ASTMatchers/Dynamic/CMakeLists.txt @@ -10,6 +10,7 @@ add_clang_unittest(DynamicASTMatchersTests target_link_libraries(DynamicASTMatchersTests clangAST clangASTMatchers + clangBasic clangDynamicASTMatchers clangFrontend clangTooling diff --git a/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/unittests/ASTMatchers/Dynamic/ParserTest.cpp index 2a9a61b543d4..5e6cadd19624 100644 --- a/unittests/ASTMatchers/Dynamic/ParserTest.cpp +++ b/unittests/ASTMatchers/Dynamic/ParserTest.cpp @@ -23,7 +23,7 @@ namespace { class MockSema : public Parser::Sema { public: - virtual ~MockSema() {} + ~MockSema() override {} uint64_t expectMatcher(StringRef MatcherName) { // Optimizations on the matcher framework make simple matchers like @@ -42,7 +42,8 @@ public: Errors.push_back(Error.toStringFull()); } - llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName) { + llvm::Optional<MatcherCtor> + lookupMatcherCtor(StringRef MatcherName) override { const ExpectedMatchersTy::value_type *Matcher = &*ExpectedMatchers.find(MatcherName); return reinterpret_cast<MatcherCtor>(Matcher); @@ -52,7 +53,7 @@ public: const SourceRange &NameRange, StringRef BindID, ArrayRef<ParserValue> Args, - Diagnostics *Error) { + Diagnostics *Error) override { const ExpectedMatchersTy::value_type *Matcher = reinterpret_cast<const ExpectedMatchersTy::value_type *>(Ctor); MatcherInfo ToStore = { Matcher->first, NameRange, Args, BindID }; diff --git a/unittests/Basic/FileManagerTest.cpp b/unittests/Basic/FileManagerTest.cpp index dd8cf2410ad1..d8d85dd76c38 100644 --- a/unittests/Basic/FileManagerTest.cpp +++ b/unittests/Basic/FileManagerTest.cpp @@ -10,6 +10,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemOptions.h" #include "clang/Basic/FileSystemStatCache.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Config/llvm-config.h" #include "gtest/gtest.h" diff --git a/unittests/Basic/SourceManagerTest.cpp b/unittests/Basic/SourceManagerTest.cpp index 1dda54dff14d..494c27a2f1cd 100644 --- a/unittests/Basic/SourceManagerTest.cpp +++ b/unittests/Basic/SourceManagerTest.cpp @@ -61,8 +61,7 @@ class VoidModuleLoader : public ModuleLoader { void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, - SourceLocation ImportLoc, - bool Complain) override { } + SourceLocation ImportLoc) override { } GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override { return nullptr; } @@ -257,15 +256,15 @@ class MacroTracker : public PPCallbacks { public: explicit MacroTracker(std::vector<MacroAction> &Macros) : Macros(Macros) { } - - virtual void MacroDefined(const Token &MacroNameTok, - const MacroDirective *MD) { + + void MacroDefined(const Token &MacroNameTok, + const MacroDirective *MD) override { Macros.push_back(MacroAction(MD->getLocation(), MacroNameTok.getIdentifierInfo()->getName(), true)); } - virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, - SourceRange Range, const MacroArgs *Args) { + void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, + SourceRange Range, const MacroArgs *Args) override { Macros.push_back(MacroAction(MacroNameTok.getLocation(), MacroNameTok.getIdentifierInfo()->getName(), false)); diff --git a/unittests/Basic/VirtualFileSystemTest.cpp b/unittests/Basic/VirtualFileSystemTest.cpp index 67beb923d976..71d2d2b60c04 100644 --- a/unittests/Basic/VirtualFileSystemTest.cpp +++ b/unittests/Basic/VirtualFileSystemTest.cpp @@ -521,9 +521,7 @@ class VFSFromYAMLTest : public ::testing::Test { public: int NumDiagnostics; - void SetUp() { - NumDiagnostics = 0; - } + void SetUp() override { NumDiagnostics = 0; } static void CountingDiagHandler(const SMDiagnostic &, void *Context) { VFSFromYAMLTest *Test = static_cast<VFSFromYAMLTest *>(Context); diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index d0e2860e07f0..0e67ec71537e 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -13,12 +13,14 @@ add_subdirectory(Basic) add_subdirectory(Lex) add_subdirectory(Driver) if(CLANG_ENABLE_STATIC_ANALYZER) + add_subdirectory(StaticAnalyzer) add_subdirectory(Frontend) endif() add_subdirectory(ASTMatchers) add_subdirectory(AST) add_subdirectory(Tooling) add_subdirectory(Format) +add_subdirectory(Rewrite) add_subdirectory(Sema) add_subdirectory(CodeGen) # FIXME: Why are the libclang unit tests disabled on Windows? diff --git a/unittests/CodeGen/BufferSourceTest.cpp b/unittests/CodeGen/BufferSourceTest.cpp index 8169a6d0c9e5..b2a8ba580844 100644 --- a/unittests/CodeGen/BufferSourceTest.cpp +++ b/unittests/CodeGen/BufferSourceTest.cpp @@ -63,7 +63,6 @@ TEST(BufferSourceTest, EmitCXXGlobalInitFunc) { compiler.getDiagnostics(), "EmitCXXGlobalInitFuncTest", compiler.getCodeGenOpts(), - compiler.getTargetOpts(), llvm::getGlobalContext()))); compiler.createSema(clang::TU_Prefix,NULL); diff --git a/unittests/Driver/MultilibTest.cpp b/unittests/Driver/MultilibTest.cpp index dceace536f0f..c5e8e0970de0 100644 --- a/unittests/Driver/MultilibTest.cpp +++ b/unittests/Driver/MultilibTest.cpp @@ -254,12 +254,6 @@ TEST(MultilibTest, SetRegexFilter) { } TEST(MultilibTest, SetFilterObject) { - // Filter object - struct StartsWithP : public MultilibSet::FilterCallback { - bool operator()(const Multilib &M) const override { - return StringRef(M.gccSuffix()).startswith("/p"); - } - }; MultilibSet MS; MS.Maybe(Multilib("orange")); MS.Maybe(Multilib("pear")); @@ -273,7 +267,9 @@ TEST(MultilibTest, SetFilterObject) { 1 /* orange/plum */ + 1 /* orange/pear/plum */ ) << "Size before filter was incorrect. Contents:\n" << MS; - MS.FilterOut(StartsWithP()); + MS.FilterOut([](const Multilib &M) { + return StringRef(M.gccSuffix()).startswith("/p"); + }); ASSERT_EQ((int)MS.size(), 1 /* Default */ + 1 /* orange */ + 1 /* orange/pear */ + diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 8e770c2e9cd5..1c100c3b9b06 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -17,18 +17,29 @@ namespace clang { namespace format { -FormatStyle getGoogleStyle() { - return getGoogleStyle(FormatStyle::LK_Cpp); -} +FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); } class FormatTest : public ::testing::Test { protected: + enum IncompleteCheck { + IC_ExpectComplete, + IC_ExpectIncomplete, + IC_DoNotCheck + }; + std::string format(llvm::StringRef Code, unsigned Offset, unsigned Length, - const FormatStyle &Style) { + const FormatStyle &Style, + IncompleteCheck CheckIncomplete = IC_ExpectComplete) { DEBUG(llvm::errs() << "---\n"); DEBUG(llvm::errs() << Code << "\n\n"); std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); - tooling::Replacements Replaces = reformat(Style, Code, Ranges); + bool IncompleteFormat = false; + tooling::Replacements Replaces = + reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat); + if (CheckIncomplete != IC_DoNotCheck) { + bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete; + EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n"; + } ReplacementCount = Replaces.size(); std::string Result = applyAllReplacements(Code, Replaces); EXPECT_NE("", Result); @@ -36,9 +47,10 @@ protected: return Result; } - std::string - format(llvm::StringRef Code, const FormatStyle &Style = getLLVMStyle()) { - return format(Code, 0, Code.size(), Style); + std::string format(llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle(), + IncompleteCheck CheckIncomplete = IC_ExpectComplete) { + return format(Code, 0, Code.size(), Style, CheckIncomplete); } FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { @@ -58,6 +70,12 @@ protected: EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); } + void verifyIncompleteFormat(llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle()) { + EXPECT_EQ(Code.str(), + format(test::messUp(Code), Style, IC_ExpectIncomplete)); + } + void verifyGoogleFormat(llvm::StringRef Code) { verifyFormat(Code, getGoogleStyle()); } @@ -67,6 +85,12 @@ protected: verifyFormat(llvm::Twine("void f() { " + text + " }").str()); } + /// \brief Verify that clang-format does not crash on the given input. + void verifyNoCrash(llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle()) { + format(Code, Style, IC_DoNotCheck); + } + int ReplacementCount; }; @@ -167,8 +191,7 @@ TEST_F(FormatTest, FormatLineWhenInvokedOnTrailingNewline) { // This might not strictly be correct, but is likely good in all practical // cases. - EXPECT_EQ("int b;\nint a;", - format("int b;int a;", 7, 0, getLLVMStyle())); + EXPECT_EQ("int b;\nint a;", format("int b;int a;", 7, 0, getLLVMStyle())); } TEST_F(FormatTest, RemovesWhitespaceWhenTriggeredOnEmptyLine) { @@ -307,14 +330,14 @@ TEST_F(FormatTest, ReformatsMovedLines) { } 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);"); + 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);"); } //===----------------------------------------------------------------------===// @@ -413,6 +436,12 @@ TEST_F(FormatTest, FormatShortBracedStatements) { " f();\n" "}", AllowSimpleBracedStatements); + verifyFormat("if (true) {\n" + " f();\n" + "} else {\n" + " f();\n" + "}", + AllowSimpleBracedStatements); verifyFormat("template <int> struct A2 {\n" " struct B {};\n" @@ -424,6 +453,12 @@ TEST_F(FormatTest, FormatShortBracedStatements) { " f();\n" "}", AllowSimpleBracedStatements); + verifyFormat("if (true) {\n" + " f();\n" + "} else {\n" + " f();\n" + "}", + AllowSimpleBracedStatements); AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false; verifyFormat("while (true) {\n" @@ -487,6 +522,11 @@ TEST_F(FormatTest, ElseIf) { "} else if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaa)) {\n" "}"); + verifyFormat("if (a) {\n" + "} else if (\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" + "}", + getLLVMStyleWithColumns(62)); } TEST_F(FormatTest, FormatsForLoop) { @@ -517,14 +557,21 @@ TEST_F(FormatTest, FormatsForLoop) { " I = FD->getDeclsInPrototypeScope().begin(),\n" " E = FD->getDeclsInPrototypeScope().end();\n" " I != E; ++I) {\n}"); + verifyFormat("for (SmallVectorImpl<TemplateIdAnnotationn *>::iterator\n" + " I = Container.begin(),\n" + " E = Container.end();\n" + " I != E; ++I) {\n}", + getLLVMStyleWithColumns(76)); - // FIXME: Not sure whether we want extra identation in line 3 here: verifyFormat( "for (aaaaaaaaaaaaaaaaa aaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa !=\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n" " ++aaaaaaaaaaa) {\n}"); + verifyFormat("for (int i = 0; i < aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" + " bbbbbbbbbbbbbbbbbbbb < ccccccccccccccc;\n" + " ++i) {\n}"); verifyFormat("for (int aaaaaaaaaaa = 1; aaaaaaaaaaa <= bbbbbbbbbbbbbbb;\n" " aaaaaaaaaaa++, bbbbbbbbbbbbbbbbb++) {\n" "}"); @@ -664,11 +711,17 @@ TEST_F(FormatTest, FormatsSwitchStatement) { " switch (x) { \\\n" " case a: \\\n" " foo = b; \\\n" - " }", getLLVMStyleWithColumns(20)); + " }", + getLLVMStyleWithColumns(20)); verifyFormat("#define OPERATION_CASE(name) \\\n" " case OP_name: \\\n" " return operations::Operation##name\n", getLLVMStyleWithColumns(40)); + verifyFormat("switch (x) {\n" + "case 1:;\n" + "default:;\n" + " int i;\n" + "}"); verifyGoogleFormat("switch (x) {\n" " case 1:\n" @@ -799,9 +852,16 @@ TEST_F(FormatTest, FormatsLabels) { " some_more_code();\n" " }\n" "}"); - verifyFormat("some_code();\n" + verifyFormat("{\n" + " some_code();\n" "test_label:\n" - "some_other_code();"); + " some_other_code();\n" + "}"); + verifyFormat("{\n" + " some_code();\n" + "test_label:;\n" + " int i = 0;\n" + "}"); } //===----------------------------------------------------------------------===// @@ -1007,11 +1067,10 @@ TEST_F(FormatTest, UnderstandsSingleLineComments) { " // at start\n" "}")); - verifyFormat( - "#define A \\\n" - " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n" - " int jjjjjjjjjjjjjjjjjjjjjjjj; /* */", - getLLVMStyleWithColumns(60)); + verifyFormat("#define A \\\n" + " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n" + " int jjjjjjjjjjjjjjjjjjjjjjjj; /* */", + getLLVMStyleWithColumns(60)); verifyFormat( "#define A \\\n" " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n" @@ -1029,6 +1088,11 @@ TEST_F(FormatTest, UnderstandsSingleLineComments) { " // spanning two lines\n" " x + 3) {\n" "}")); + + verifyNoCrash("/\\\n/"); + verifyNoCrash("/\\\n* */"); + // The 0-character somehow makes the lexer return a proper comment. + verifyNoCrash(StringRef("/*\\\0\n/", 6)); } TEST_F(FormatTest, KeepsParameterWithTrailingCommentsOnTheirOwnLine) { @@ -1043,7 +1107,7 @@ TEST_F(FormatTest, KeepsParameterWithTrailingCommentsOnTheirOwnLine) { " c);", format("SomeFunction(a,\n" " b,\n" - " // comment\n" + " // comment\n" " c);")); EXPECT_EQ("SomeFunction(a, b, // comment (unclear relation)\n" " c);", @@ -1276,13 +1340,12 @@ TEST_F(FormatTest, SplitsLongCxxComments) { EXPECT_EQ("// a b c d\n" "// e f g\n" "// h i j k", - format("// a b c d e f g h i j k", - getLLVMStyleWithColumns(10))); - EXPECT_EQ("// a b c d\n" - "// e f g\n" - "// h i j k", - format("\\\n// a b c d e f g h i j k", - getLLVMStyleWithColumns(10))); + format("// a b c d e f g h i j k", getLLVMStyleWithColumns(10))); + EXPECT_EQ( + "// a b c d\n" + "// e f g\n" + "// h i j k", + format("\\\n// a b c d e f g h i j k", getLLVMStyleWithColumns(10))); EXPECT_EQ("if (true) // A comment that\n" " // doesn't fit on\n" " // one line", @@ -1461,18 +1524,18 @@ TEST_F(FormatTest, SplitsLongLinesInComments) { "doesn't " "fit on one line. */", getLLVMStyleWithColumns(20))); - EXPECT_EQ("/* a b c d\n" - " * e f g\n" - " * h i j k\n" - " */", - format("/* a b c d e f g h i j k */", - getLLVMStyleWithColumns(10))); - EXPECT_EQ("/* a b c d\n" - " * e f g\n" - " * h i j k\n" - " */", - format("\\\n/* a b c d e f g h i j k */", - getLLVMStyleWithColumns(10))); + EXPECT_EQ( + "/* a b c d\n" + " * e f g\n" + " * h i j k\n" + " */", + format("/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10))); + EXPECT_EQ( + "/* a b c d\n" + " * e f g\n" + " * h i j k\n" + " */", + format("\\\n/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10))); EXPECT_EQ("/*\n" "This is a long\n" "comment that doesn't\n" @@ -1482,7 +1545,8 @@ TEST_F(FormatTest, SplitsLongLinesInComments) { "This is a long " "comment that doesn't " "fit on one line. \n" - "*/", getLLVMStyleWithColumns(20))); + "*/", + getLLVMStyleWithColumns(20))); EXPECT_EQ("/*\n" " * This is a long\n" " * comment that\n" @@ -1494,7 +1558,8 @@ TEST_F(FormatTest, SplitsLongLinesInComments) { " comment that " " doesn't fit on " " one line. \n" - " */", getLLVMStyleWithColumns(20))); + " */", + getLLVMStyleWithColumns(20))); EXPECT_EQ("/*\n" " * This_is_a_comment_with_words_that_dont_fit_on_one_line\n" " * so_it_should_be_broken\n" @@ -1528,7 +1593,8 @@ TEST_F(FormatTest, SplitsLongLinesInComments) { " doesn't fit on one" " line 1234567890\n" "*/\n" - "}", getLLVMStyleWithColumns(20))); + "}", + getLLVMStyleWithColumns(20))); EXPECT_EQ("{\n" " /*\n" " * This i s\n" @@ -1546,7 +1612,8 @@ TEST_F(FormatTest, SplitsLongLinesInComments) { " fit on one l i" " n e\n" " */\n" - "}", getLLVMStyleWithColumns(20))); + "}", + getLLVMStyleWithColumns(20))); EXPECT_EQ("/*\n" " * This is a long\n" " * comment that\n" @@ -1555,7 +1622,8 @@ TEST_F(FormatTest, SplitsLongLinesInComments) { " */", format(" /*\n" " * This is a long comment that doesn't fit on one line\n" - " */", getLLVMStyleWithColumns(20))); + " */", + getLLVMStyleWithColumns(20))); EXPECT_EQ("{\n" " if (something) /* This is a\n" " long\n" @@ -1590,6 +1658,17 @@ TEST_F(FormatTest, SplitsLongLinesInComments) { " */", getLLVMStyleWithColumns(20))); + EXPECT_EQ("/**\n" + " * multiline block\n" + " * comment\n" + " *\n" + " */", + format("/**\n" + " * multiline block comment\n" + " *\n" + " */", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/*\n" "\n" "\n" @@ -1849,7 +1928,6 @@ TEST_F(FormatTest, IgnoresIf0Contents) { "#endif\n" "Five\n" "};")); - } //===----------------------------------------------------------------------===// @@ -1879,7 +1957,16 @@ TEST_F(FormatTest, UnderstandsAccessSpecifiers) { " void f() {}\n" "public Q_SLOTS:\n" " void f() {}\n" + "signals:\n" + " void g();\n" "};"); + + // Don't interpret 'signals' the wrong way. + verifyFormat("signals.set();"); + verifyFormat("for (Signals signals : f()) {\n}"); + verifyFormat("{\n" + " signals.set(); // This needs indentation.\n" + "}"); } TEST_F(FormatTest, SeparatesLogicalBlocks) { @@ -1914,6 +2001,30 @@ TEST_F(FormatTest, SeparatesLogicalBlocks) { "\n" " void f();\n" "};")); + + // Even ensure proper spacing inside macros. + EXPECT_EQ("#define B \\\n" + " class A { \\\n" + " protected: \\\n" + " public: \\\n" + " void f(); \\\n" + " };", + format("#define B \\\n" + " class A { \\\n" + " protected: \\\n" + " \\\n" + " public: \\\n" + " \\\n" + " void f(); \\\n" + " };", + getGoogleStyle())); + // But don't remove empty lines after macros ending in access specifiers. + EXPECT_EQ("#define A private:\n" + "\n" + "int i;", + format("#define A private:\n" + "\n" + "int i;")); } TEST_F(FormatTest, FormatsClasses) { @@ -2103,6 +2214,12 @@ TEST_F(FormatTest, FormatsBitfields) { " int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa : 1,\n" " bbbbbbbbbbbbbbbbbbbbbbbbb;\n" "};"); + verifyFormat("struct MyStruct {\n" + " uchar data;\n" + " uchar : 8;\n" + " uchar : 8;\n" + " uchar other;\n" + "};"); } TEST_F(FormatTest, FormatsNamespaces) { @@ -2204,10 +2321,24 @@ TEST_F(FormatTest, FormatsInlineASM) { " call [edx][eax*4] // stdcall\n" " }\n" "}")); + EXPECT_EQ("_asm {\n" + " xor eax, eax;\n" + " cpuid;\n" + "}", + format("_asm {\n" + " xor eax, eax;\n" + " cpuid;\n" + "}")); verifyFormat("void function() {\n" " // comment\n" " asm(\"\");\n" "}"); + EXPECT_EQ("__asm {\n" + "}\n" + "int i;", + format("__asm {\n" + "}\n" + "int i;")); } TEST_F(FormatTest, FormatTryCatch) { @@ -2230,6 +2361,29 @@ TEST_F(FormatTest, FormatTryCatch) { " throw;\n" " }\n" "};\n"); + + // Incomplete try-catch blocks. + verifyIncompleteFormat("try {} catch ("); +} + +TEST_F(FormatTest, FormatSEHTryCatch) { + verifyFormat("__try {\n" + " int a = b * c;\n" + "} __except (EXCEPTION_EXECUTE_HANDLER) {\n" + " // Do nothing.\n" + "}"); + + verifyFormat("__try {\n" + " int a = b * c;\n" + "} __finally {\n" + " // Do nothing.\n" + "}"); + + verifyFormat("DEBUG({\n" + " __try {\n" + " } __finally {\n" + " }\n" + "});\n"); } TEST_F(FormatTest, IncompleteTryCatchBlocks) { @@ -2264,6 +2418,20 @@ TEST_F(FormatTest, FormatTryCatchBraceStyles) { " // something\n" "}", Style); + verifyFormat("__try {\n" + " // something\n" + "}\n" + "__finally {\n" + " // something\n" + "}", + Style); + verifyFormat("@try {\n" + " // something\n" + "}\n" + "@finally {\n" + " // something\n" + "}", + Style); Style.BreakBeforeBraces = FormatStyle::BS_Allman; verifyFormat("try\n" "{\n" @@ -2289,21 +2457,24 @@ TEST_F(FormatTest, FormatTryCatchBraceStyles) { TEST_F(FormatTest, FormatObjCTryCatch) { verifyFormat("@try {\n" " f();\n" - "}\n" - "@catch (NSException e) {\n" + "} @catch (NSException e) {\n" " @throw;\n" - "}\n" - "@finally {\n" + "} @finally {\n" " exit(42);\n" "}"); + verifyFormat("DEBUG({\n" + " @try {\n" + " } @finally {\n" + " }\n" + "});\n"); } TEST_F(FormatTest, StaticInitializers) { verifyFormat("static SomeClass SC = {1, 'a'};"); - verifyFormat( - "static SomeClass WithALoooooooooooooooooooongName = {\n" - " 100000000, \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"};"); + verifyFormat("static SomeClass WithALoooooooooooooooooooongName = {\n" + " 100000000, " + "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"};"); // Here, everything other than the "}" would fit on a line. verifyFormat("static int LooooooooooooooooooooooooongVariable[1] = {\n" @@ -2357,9 +2528,9 @@ TEST_F(FormatTest, NestedStaticInitializers) { " {kGlobalRef, OK_CODE, NULL, NULL, NULL},\n" " {kGlobalRef, CANCELLED_CODE, NULL, NULL, NULL},\n" " {kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL}};"); - verifyFormat( - "CGRect cg_rect = {{rect.fLeft, rect.fTop},\n" - " {rect.fRight - rect.fLeft, rect.fBottom - rect.fTop}};"); + verifyFormat("CGRect cg_rect = {{rect.fLeft, rect.fTop},\n" + " {rect.fRight - rect.fLeft, rect.fBottom - " + "rect.fTop}};"); verifyFormat( "SomeArrayOfSomeType a = {\n" @@ -2378,24 +2549,22 @@ TEST_F(FormatTest, NestedStaticInitializers) { " {{1, 2, 3}},\n" " {{1, 2, 3}}};"); - verifyFormat( - "struct {\n" - " unsigned bit;\n" - " const char *const name;\n" - "} kBitsToOs[] = {{kOsMac, \"Mac\"},\n" - " {kOsWin, \"Windows\"},\n" - " {kOsLinux, \"Linux\"},\n" - " {kOsCrOS, \"Chrome OS\"}};"); - verifyFormat( - "struct {\n" - " unsigned bit;\n" - " const char *const name;\n" - "} kBitsToOs[] = {\n" - " {kOsMac, \"Mac\"},\n" - " {kOsWin, \"Windows\"},\n" - " {kOsLinux, \"Linux\"},\n" - " {kOsCrOS, \"Chrome OS\"},\n" - "};"); + verifyFormat("struct {\n" + " unsigned bit;\n" + " const char *const name;\n" + "} kBitsToOs[] = {{kOsMac, \"Mac\"},\n" + " {kOsWin, \"Windows\"},\n" + " {kOsLinux, \"Linux\"},\n" + " {kOsCrOS, \"Chrome OS\"}};"); + verifyFormat("struct {\n" + " unsigned bit;\n" + " const char *const name;\n" + "} kBitsToOs[] = {\n" + " {kOsMac, \"Mac\"},\n" + " {kOsWin, \"Windows\"},\n" + " {kOsLinux, \"Linux\"},\n" + " {kOsCrOS, \"Chrome OS\"},\n" + "};"); } TEST_F(FormatTest, FormatsSmallMacroDefinitionsInSingleLine) { @@ -2407,6 +2576,14 @@ TEST_F(FormatTest, FormatsSmallMacroDefinitionsInSingleLine) { TEST_F(FormatTest, DoesNotBreakPureVirtualFunctionDefinition) { verifyFormat("virtual void write(ELFWriter *writerrr,\n" " OwningPtr<FileOutputBuffer> &buffer) = 0;"); + + // Do break defaulted and deleted functions. + verifyFormat("virtual void ~Deeeeeeeestructor() =\n" + " default;", + getLLVMStyleWithColumns(40)); + verifyFormat("virtual void ~Deeeeeeeestructor() =\n" + " delete;", + getLLVMStyleWithColumns(40)); } TEST_F(FormatTest, BreaksStringLiteralsOnlyInDefine) { @@ -2456,6 +2633,10 @@ TEST_F(FormatTest, DoesntRemoveUnknownTokens) { "\\na : b);", format("const char * c = STRINGIFY(\n" "\\na : b);")); + + verifyFormat("a\r\\"); + verifyFormat("a\v\\"); + verifyFormat("a\f\\"); } TEST_F(FormatTest, IndentsPPDirectiveInReducedSpace) { @@ -2585,17 +2766,35 @@ TEST_F(FormatTest, EmptyLinesInMacroDefinitions) { } TEST_F(FormatTest, MacroDefinitionsWithIncompleteCode) { - verifyFormat("#define A :"); + verifyIncompleteFormat("#define A :"); verifyFormat("#define SOMECASES \\\n" " case 1: \\\n" " case 2\n", getLLVMStyleWithColumns(20)); verifyFormat("#define A template <typename T>"); - verifyFormat("#define STR(x) #x\n" - "f(STR(this_is_a_string_literal{));"); + verifyIncompleteFormat("#define STR(x) #x\n" + "f(STR(this_is_a_string_literal{));"); verifyFormat("#pragma omp threadprivate( \\\n" " y)), // expected-warning", getLLVMStyleWithColumns(28)); + verifyFormat("#d, = };"); + verifyFormat("#if \"a"); + verifyIncompleteFormat("({\n" + "#define b \\\n" + " } \\\n" + " a\n" + "a", getLLVMStyleWithColumns(15)); + verifyFormat("#define A \\\n" + " { \\\n" + " {\n" + "#define B \\\n" + " } \\\n" + " }", + getLLVMStyleWithColumns(15)); + verifyNoCrash("#if a\na(\n#else\n#endif\n{a"); + verifyNoCrash("a={0,1\n#if a\n#else\n;\n#endif\n}"); + verifyNoCrash("#if a\na(\n#else\n#endif\n) a {a,b,c,d,f,g};"); + verifyNoCrash("#ifdef A\n a(\n #else\n #endif\n) = []() { \n)}"); } TEST_F(FormatTest, MacrosWithoutTrailingSemicolon) { @@ -2610,6 +2809,10 @@ TEST_F(FormatTest, MacrosWithoutTrailingSemicolon) { "\n" " A() {\n}\n" "} ;")); + EXPECT_EQ("MACRO\n" + "/*static*/ int i;", + format("MACRO\n" + " /*static*/ int i;")); EXPECT_EQ("SOME_MACRO\n" "namespace {\n" "void f();\n" @@ -2619,10 +2822,8 @@ TEST_F(FormatTest, MacrosWithoutTrailingSemicolon) { "void f( );\n" "}")); // Only if the identifier contains at least 5 characters. - EXPECT_EQ("HTTP f();", - format("HTTP\nf();")); - EXPECT_EQ("MACRO\nf();", - format("MACRO\nf();")); + EXPECT_EQ("HTTP f();", format("HTTP\nf();")); + EXPECT_EQ("MACRO\nf();", format("MACRO\nf();")); // Only if everything is upper case. EXPECT_EQ("class A : public QObject {\n" " Q_Object A() {}\n" @@ -2638,7 +2839,8 @@ TEST_F(FormatTest, MacrosWithoutTrailingSemicolon) { "<< SomeThing;")); verifyFormat("VISIT_GL_CALL(GenBuffers, void, (GLsizei n, GLuint* buffers), " - "(n, buffers))\n", getChromiumStyle(FormatStyle::LK_Cpp)); + "(n, buffers))\n", + getChromiumStyle(FormatStyle::LK_Cpp)); } TEST_F(FormatTest, MacroCallsWithoutTrailingSemicolon) { @@ -2760,34 +2962,34 @@ TEST_F(FormatTest, MacroCallsWithoutTrailingSemicolon) { " A(X x)\n" " try : t(0) {} catch (...) {}\n" "};")); - EXPECT_EQ( - "class SomeClass {\n" - "public:\n" - " SomeClass() EXCLUSIVE_LOCK_FUNCTION(mu_);\n" - "};", - format("class SomeClass {\n" - "public:\n" - " SomeClass()\n" - " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" - "};")); - EXPECT_EQ( - "class SomeClass {\n" - "public:\n" - " SomeClass()\n" - " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" - "};", - format("class SomeClass {\n" - "public:\n" - " SomeClass()\n" - " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" - "};", getLLVMStyleWithColumns(40))); + EXPECT_EQ("class SomeClass {\n" + "public:\n" + " SomeClass() EXCLUSIVE_LOCK_FUNCTION(mu_);\n" + "};", + format("class SomeClass {\n" + "public:\n" + " SomeClass()\n" + " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" + "};")); + EXPECT_EQ("class SomeClass {\n" + "public:\n" + " SomeClass()\n" + " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" + "};", + format("class SomeClass {\n" + "public:\n" + " SomeClass()\n" + " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" + "};", + getLLVMStyleWithColumns(40))); } TEST_F(FormatTest, LayoutMacroDefinitionsStatementsSpanningBlocks) { verifyFormat("#define A \\\n" " f({ \\\n" " g(); \\\n" - " });", getLLVMStyleWithColumns(11)); + " });", + getLLVMStyleWithColumns(11)); } TEST_F(FormatTest, IndentPreprocessorDirectivesAtZero) { @@ -2805,15 +3007,15 @@ TEST_F(FormatTest, FormatUnbalancedStructuralElements) { format("#define A } }\nint i;", getLLVMStyleWithColumns(11))); } -TEST_F(FormatTest, EscapedNewlineAtStartOfToken) { +TEST_F(FormatTest, EscapedNewlines) { EXPECT_EQ( "#define A \\\n int i; \\\n int j;", format("#define A \\\nint i;\\\n int j;", getLLVMStyleWithColumns(11))); + EXPECT_EQ( + "#define A\n\nint i;", format("#define A \\\n\n int i;")); EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();")); -} - -TEST_F(FormatTest, NoEscapedNewlineHandlingInBlockComments) { EXPECT_EQ("/* \\ \\ \\\n*/", format("\\\n/* \\ \\ \\\n*/")); + EXPECT_EQ("<a\n\\\\\n>", format("<a\n\\\\\n>")); } TEST_F(FormatTest, DontCrashOnBlockComments) { @@ -2906,12 +3108,11 @@ TEST_F(FormatTest, LayoutStatementsAroundPreprocessorDirectives) { getLLVMStyleWithColumns(28)); verifyFormat("#if 1\n" "int i;"); - verifyFormat( - "#if 1\n" - "#endif\n" - "#if 1\n" - "#else\n" - "#endif\n"); + verifyFormat("#if 1\n" + "#endif\n" + "#if 1\n" + "#else\n" + "#endif\n"); verifyFormat("DEBUG({\n" " return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;\n" @@ -2919,6 +3120,12 @@ TEST_F(FormatTest, LayoutStatementsAroundPreprocessorDirectives) { "#if a\n" "#else\n" "#endif"); + + verifyIncompleteFormat("void f(\n" + "#if A\n" + " );\n" + "#else\n" + "#endif"); } TEST_F(FormatTest, GraciouslyHandleIncorrectPreprocessorConditions) { @@ -2929,48 +3136,50 @@ TEST_F(FormatTest, GraciouslyHandleIncorrectPreprocessorConditions) { TEST_F(FormatTest, FormatsJoinedLinesOnSubsequentRuns) { FormatStyle SingleLine = getLLVMStyle(); SingleLine.AllowShortIfStatementsOnASingleLine = true; - verifyFormat( - "#if 0\n" - "#elif 1\n" - "#endif\n" - "void foo() {\n" - " if (test) foo2();\n" - "}", - SingleLine); + verifyFormat("#if 0\n" + "#elif 1\n" + "#endif\n" + "void foo() {\n" + " if (test) foo2();\n" + "}", + SingleLine); } TEST_F(FormatTest, LayoutBlockInsideParens) { - EXPECT_EQ("functionCall({ int i; });", format(" functionCall ( {int i;} );")); - EXPECT_EQ("functionCall({\n" - " int i;\n" - " int j;\n" - "});", - format(" functionCall ( {int i;int j;} );")); - EXPECT_EQ("functionCall({\n" - " int i;\n" - " int j;\n" - "}, aaaa, bbbb, cccc);", - format(" functionCall ( {int i;int j;}, aaaa, bbbb, cccc);")); - EXPECT_EQ("functionCall(\n" - " {\n" - " int i;\n" - " int j;\n" - " },\n" - " aaaa, bbbb, // comment\n" - " cccc);", - format(" functionCall ( {int i;int j;}, aaaa, bbbb, // comment\n" - "cccc);")); - EXPECT_EQ("functionCall(aaaa, bbbb, { int i; });", - format(" functionCall (aaaa, bbbb, {int i;});")); - EXPECT_EQ("functionCall(aaaa, bbbb, {\n" - " int i;\n" - " int j;\n" - "});", - format(" functionCall (aaaa, bbbb, {int i;int j;});")); - EXPECT_EQ("functionCall(aaaa, bbbb, { int i; });", - format(" functionCall (aaaa, bbbb, {int i;});")); + verifyFormat("functionCall({ int i; });"); + verifyFormat("functionCall({\n" + " int i;\n" + " int j;\n" + "});"); + verifyFormat("functionCall({\n" + " int i;\n" + " int j;\n" + "}, aaaa, bbbb, cccc);"); + verifyFormat("functionA(functionB({\n" + " int i;\n" + " int j;\n" + " }),\n" + " aaaa, bbbb, cccc);"); + verifyFormat("functionCall(\n" + " {\n" + " int i;\n" + " int j;\n" + " },\n" + " aaaa, bbbb, // comment\n" + " cccc);"); + verifyFormat("functionA(functionB({\n" + " int i;\n" + " int j;\n" + " }),\n" + " aaaa, bbbb, // comment\n" + " cccc);"); + verifyFormat("functionCall(aaaa, bbbb, { int i; });"); + verifyFormat("functionCall(aaaa, bbbb, {\n" + " int i;\n" + " int j;\n" + "});"); verifyFormat( - "Aaa(\n" // FIXME: There shouldn't be a linebreak here. + "Aaa(\n" // FIXME: There shouldn't be a linebreak here. " {\n" " int i; // break\n" " },\n" @@ -2980,6 +3189,30 @@ TEST_F(FormatTest, LayoutBlockInsideParens) { " if (a)\n" " f();\n" "});"); + EXPECT_EQ("int longlongname; // comment\n" + "int x = f({\n" + " int x; // comment\n" + " int y; // comment\n" + "});", + format("int longlongname; // comment\n" + "int x = f({\n" + " int x; // comment\n" + " int y; // comment\n" + "});", + 65, 0, getLLVMStyle())); + EXPECT_EQ("int s = f({\n" + " class X {\n" + " public:\n" + " void f();\n" + " };\n" + "});", + format("int s = f({\n" + " class X {\n" + " public:\n" + " void f();\n" + " };\n" + "});", + 0, 0, getLLVMStyle())); } TEST_F(FormatTest, LayoutBlockInsideStatement) { @@ -3056,6 +3289,29 @@ TEST_F(FormatTest, LayoutNestedBlocks) { " if (aaaaaaaaaaaaaaaaaaaaaaaa) return;\n" "}, a);", Style); + + verifyNoCrash("^{v^{a}}"); +} + +TEST_F(FormatTest, FormatNestedBlocksInMacros) { + EXPECT_EQ("#define MACRO() \\\n" + " Debug(aaa, /* force line break */ \\\n" + " { \\\n" + " int i; \\\n" + " int j; \\\n" + " })", + format("#define MACRO() Debug(aaa, /* force line break */ \\\n" + " { int i; int j; })", + getGoogleStyle())); + + EXPECT_EQ("#define A \\\n" + " [] { \\\n" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); \\\n" + " }", + format("#define A [] { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); }", + getGoogleStyle())); } TEST_F(FormatTest, IndividualStatementsOfNestedBlocks) { @@ -3127,6 +3383,19 @@ TEST_F(FormatTest, IndividualStatementsOfNestedBlocks) { " int a; //\n" "});", 0, 0, getLLVMStyle())); + EXPECT_EQ("someFunction(\n" + " [] {\n" + " // Only with this comment.\n" + " int i; // invoke formatting here.\n" + " }, // force line break\n" + " aaa);", + format("someFunction(\n" + " [] {\n" + " // Only with this comment.\n" + " int i; // invoke formatting here.\n" + " }, // force line break\n" + " aaa);", + 63, 1, getLLVMStyle())); } TEST_F(FormatTest, PutEmptyBlocksIntoOneLine) { @@ -3221,10 +3490,9 @@ TEST_F(FormatTest, LineBreakingInBinaryExpressions) { "}"); // Even explicit parentheses stress the precedence enough to make the // additional break unnecessary. - verifyFormat( - "if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" - "}"); + verifyFormat("if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" + "}"); // This cases is borderline, but with the indentation it is still readable. verifyFormat( "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" @@ -3235,11 +3503,10 @@ TEST_F(FormatTest, LineBreakingInBinaryExpressions) { // If the LHS is a binary expression, we should still use the additional break // as otherwise the formatting hides the operator precedence. - verifyFormat( - "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" - " 5) {\n" - "}"); + verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" + " 5) {\n" + "}"); FormatStyle OnePerLine = getLLVMStyle(); OnePerLine.BinPackParameters = false; @@ -3330,9 +3597,14 @@ TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) { " // comment\n" " + b;", Style); - verifyFormat("int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" - " + cc;", + verifyFormat( + "int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " + cc;", + Style); + + verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " = aaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaa;", Style); // Forced by comments. @@ -3358,17 +3630,16 @@ TEST_F(FormatTest, NoOperandAlignment) { FormatStyle Style = getLLVMStyle(); Style.AlignOperands = false; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; - verifyFormat( - "bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" - " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" - " && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " > ccccccccccccccccccccccccccccccccccccccccc;", - Style); + verifyFormat("bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " > ccccccccccccccccccccccccccccccccccccccccc;", + Style); verifyFormat("int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" @@ -3580,10 +3851,9 @@ TEST_F(FormatTest, BreaksFunctionDeclarations) { // 1) break amongst arguments. verifyFormat("Aaaaaaaaaaaaaa bbbbbbbbbbbbbb(Cccccccccccccc cccccccccccccc,\n" " Cccccccccccccc cccccccccccccc);"); - verifyFormat( - "template <class TemplateIt>\n" - "SomeReturnType SomeFunction(TemplateIt begin, TemplateIt end,\n" - " TemplateIt *stop) {}"); + verifyFormat("template <class TemplateIt>\n" + "SomeReturnType SomeFunction(TemplateIt begin, TemplateIt end,\n" + " TemplateIt *stop) {}"); // 2) break after return type. verifyFormat( @@ -3664,6 +3934,15 @@ TEST_F(FormatTest, BreaksFunctionDeclarations) { "typename aaaaaaaaaa<aaaaaa>::aaaaaaaaaaa\n" "aaaaaaaaaa<aaaaaa>::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " bool *aaaaaaaaaaaaaaaaaa, bool *aa) {}"); + + FormatStyle Style = getLLVMStyle(); + Style.PointerAlignment = FormatStyle::PAS_Left; + verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa* const aaaaaaaaaaaa) {}", + Style); + verifyFormat("void aaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", + Style); } TEST_F(FormatTest, TrailingReturnType) { @@ -3770,6 +4049,23 @@ TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) { verifyGoogleFormat( "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa GUARDED_BY(aaaaaaaaaaaa) =\n" " aaaaaaaa::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); + verifyGoogleFormat( + "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa GUARDED_BY(aaaaaaaaaaaa) =\n" + " aaaaaaaaaaaaaaaaaaaaaaaaa;"); +} + +TEST_F(FormatTest, FunctionAnnotations) { + verifyFormat("DEPRECATED(\"Use NewClass::NewFunction instead.\")\n" + "string OldFunction(const string ¶meter) {}"); + verifyFormat("template <typename T>\n" + "DEPRECATED(\"Use NewClass::NewFunction instead.\")\n" + "string OldFunction(const string ¶meter) {}"); + + // Not function annotations. + verifyFormat("ASSERT(\"aaaaa\") << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " << bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); + verifyFormat("TEST_F(ThisIsATestFixtureeeeeeeeeeeee,\n" + " ThisIsATestWithAReallyReallyReallyReallyLongName) {}"); } TEST_F(FormatTest, BreaksDesireably) { @@ -3808,10 +4104,9 @@ TEST_F(FormatTest, BreaksDesireably) { verifyFormat( "aaaaaa(aaa, new Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa));"); - verifyFormat( - "aaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat("aaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); // Indent consistently independent of call expression. verifyFormat("aaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccc(\n" @@ -3952,20 +4247,19 @@ TEST_F(FormatTest, AdaptiveOnePerLineFormatting) { } TEST_F(FormatTest, FormatsBuilderPattern) { - verifyFormat( - "return llvm::StringSwitch<Reference::Kind>(name)\n" - " .StartsWith(\".eh_frame_hdr\", ORDER_EH_FRAMEHDR)\n" - " .StartsWith(\".eh_frame\", ORDER_EH_FRAME)\n" - " .StartsWith(\".init\", ORDER_INIT)\n" - " .StartsWith(\".fini\", ORDER_FINI)\n" - " .StartsWith(\".hash\", ORDER_HASH)\n" - " .Default(ORDER_TEXT);\n"); + verifyFormat("return llvm::StringSwitch<Reference::Kind>(name)\n" + " .StartsWith(\".eh_frame_hdr\", ORDER_EH_FRAMEHDR)\n" + " .StartsWith(\".eh_frame\", ORDER_EH_FRAME)\n" + " .StartsWith(\".init\", ORDER_INIT)\n" + " .StartsWith(\".fini\", ORDER_FINI)\n" + " .StartsWith(\".hash\", ORDER_HASH)\n" + " .Default(ORDER_TEXT);\n"); verifyFormat("return aaaaaaaaaaaaaaaaa->aaaaa().aaaaaaaaaaaaa().aaaaaa() <\n" " aaaaaaaaaaaaaaa->aaaaa().aaaaaaaaaaaaa().aaaaaa();"); verifyFormat( "aaaaaaa->aaaaaaa->aaaaaaaaaaaaaaaa(\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" " ->aaaaaaaa(aaaaaaaaaaaaaaa);"); verifyFormat( "aaaaaaaaaaaaaaaaaaa()->aaaaaa(bbbbb)->aaaaaaaaaaaaaaaaaaa( // break\n" @@ -3974,7 +4268,7 @@ TEST_F(FormatTest, FormatsBuilderPattern) { "aaaaaaaaaaaaaaaaaaaaaaa *aaaaaaaaa =\n" " aaaaaa->aaaaaaaaaaaa()\n" " ->aaaaaaaaaaaaaaaa(\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" " ->aaaaaaaaaaaaaaaaa();"); verifyGoogleFormat( "void f() {\n" @@ -4009,6 +4303,18 @@ TEST_F(FormatTest, FormatsBuilderPattern) { " ->aaaaaaaaaaaaaae(0)\n" " ->aaaaaaaaaaaaaaa();"); + // Don't linewrap after very short segments. + verifyFormat("a().aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" + " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" + " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); + verifyFormat("aa().aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" + " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" + " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); + verifyFormat("aaa()\n" + " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" + " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" + " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); + verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaa()\n" " .aaaaaaaaaaaaaaaaaaaaaaaaaa()\n" " .has<bbbbbbbbbbbbbbbbbbbbb>();"); @@ -4135,18 +4441,15 @@ TEST_F(FormatTest, AlignsAfterOpenBracket) { " aaaaaaaaaaaaaaaaaaaaa));"); FormatStyle Style = getLLVMStyle(); Style.AlignAfterOpenBracket = false; - verifyFormat( - "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" - " aaaaaaaaaaa aaaaaaaa, aaaaaaaaa aaaaaaa) {}", - Style); - verifyFormat( - "SomeLongVariableName->someVeryLongFunctionName(\n" - " aaaaaaaaaaa aaaaaaaaa, aaaaaaaaaaa aaaaaaaaa);", - Style); - verifyFormat( - "SomeLongVariableName->someFunction(\n" - " foooooooo(aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaa));", - Style); + verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaa aaaaaaaa, aaaaaaaaa aaaaaaa) {}", + Style); + verifyFormat("SomeLongVariableName->someVeryLongFunctionName(\n" + " aaaaaaaaaaa aaaaaaaaa, aaaaaaaaaaa aaaaaaaaa);", + Style); + verifyFormat("SomeLongVariableName->someFunction(\n" + " foooooooo(aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaa));", + Style); verifyFormat( "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaa aaaaaaaa,\n" " aaaaaaaaa aaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", @@ -4239,13 +4542,12 @@ TEST_F(FormatTest, BreaksConditionalExpressions) { " // comment\n" " ? aaaa\n" " : bbbb;"); - verifyFormat( - "unsigned Indent =\n" - " format(TheLine.First, IndentForLevel[TheLine.Level] >= 0\n" - " ? IndentForLevel[TheLine.Level]\n" - " : TheLine * 2,\n" - " TheLine.InPPDirective, PreviousEndOfLineColumn);", - getLLVMStyleWithColumns(70)); + verifyFormat("unsigned Indent =\n" + " format(TheLine.First, IndentForLevel[TheLine.Level] >= 0\n" + " ? IndentForLevel[TheLine.Level]\n" + " : TheLine * 2,\n" + " TheLine.InPPDirective, PreviousEndOfLineColumn);", + getLLVMStyleWithColumns(70)); verifyFormat("bool aaaaaa = aaaaaaaaaaaaa //\n" " ? aaaaaaaaaaaaaaa\n" " : bbbbbbbbbbbbbbb //\n" @@ -4422,17 +4724,17 @@ TEST_F(FormatTest, DeclarationsOfMultipleVariables) { " *c = ccccccccccccccccccc, *d = ddddddddddddddddddd;"); verifyFormat("aaaaaaaaa ***a = aaaaaaaaaaaaaaaaaaa, ***b = bbbbbbbbbbbbbbb,\n" " ***c = ccccccccccccccccccc, ***d = ddddddddddddddd;"); - // FIXME: If multiple variables are defined, the "*" needs to move to the new - // line. Also fix indent for breaking after the type, this looks bad. - verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaa,\n" - " * b = bbbbbbbbbbbbbbbbbbb;", - getGoogleStyle()); - // Not ideal, but pointer-with-type does not allow much here. - verifyGoogleFormat( - "aaaaaaaaa* a = aaaaaaaaaaaaaaaaaaa, * b = bbbbbbbbbbbbbbbbbbb,\n" - " * b = bbbbbbbbbbbbbbbbbbb, * d = ddddddddddddddddddd;"); + FormatStyle Style = getGoogleStyle(); + Style.PointerAlignment = FormatStyle::PAS_Left; + Style.DerivePointerAlignment = false; + verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " *aaaaaaaaaaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaa,\n" + " *b = bbbbbbbbbbbbbbbbbbb;", + Style); + verifyFormat("aaaaaaaaa *a = aaaaaaaaaaaaaaaaaaa, *b = bbbbbbbbbbbbbbbbbbb,\n" + " *b = bbbbbbbbbbbbbbbbbbb, *d = ddddddddddddddddddd;", + Style); } TEST_F(FormatTest, ConditionalExpressionsInBrackets) { @@ -4485,44 +4787,53 @@ TEST_F(FormatTest, AlignsStringLiterals) { " \"jkl\");"); verifyFormat("f(L\"a\"\n" - " L\"b\")"); + " L\"b\");"); verifyFormat("#define A(X) \\\n" " L\"aaaaa\" #X L\"bbbbbb\" \\\n" " L\"ccccc\"", getLLVMStyleWithColumns(25)); + + verifyFormat("f(@\"a\"\n" + " @\"b\");"); + verifyFormat("NSString s = @\"a\"\n" + " @\"b\"\n" + " @\"c\";"); + verifyFormat("NSString s = @\"a\"\n" + " \"b\"\n" + " \"c\";"); } TEST_F(FormatTest, AlwaysBreakAfterDefinitionReturnType) { FormatStyle AfterType = getLLVMStyle(); AfterType.AlwaysBreakAfterDefinitionReturnType = true; verifyFormat("const char *\n" - "f(void) {\n" // Break here. + "f(void) {\n" // Break here. " return \"\";\n" "}\n" - "const char *bar(void);\n", // No break here. + "const char *bar(void);\n", // No break here. AfterType); verifyFormat("template <class T>\n" "T *\n" - "f(T &c) {\n" // Break here. + "f(T &c) {\n" // Break here. " return NULL;\n" "}\n" - "template <class T> T *f(T &c);\n", // No break here. + "template <class T> T *f(T &c);\n", // No break here. AfterType); AfterType.BreakBeforeBraces = FormatStyle::BS_Stroustrup; verifyFormat("const char *\n" - "f(void)\n" // Break here. + "f(void)\n" // Break here. "{\n" " return \"\";\n" "}\n" - "const char *bar(void);\n", // No break here. + "const char *bar(void);\n", // No break here. AfterType); verifyFormat("template <class T>\n" - "T *\n" // Problem here: no line break - "f(T &c)\n" // Break here. + "T *\n" // Problem here: no line break + "f(T &c)\n" // Break here. "{\n" " return NULL;\n" "}\n" - "template <class T> T *f(T &c);\n", // No break here. + "template <class T> T *f(T &c);\n", // No break here. AfterType); } @@ -4587,10 +4898,13 @@ TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { // Exempt ObjC strings for now. EXPECT_EQ("NSString *const kString = @\"aaaa\"\n" - " \"bbbb\";", + " @\"bbbb\";", format("NSString *const kString = @\"aaaa\"\n" - "\"bbbb\";", + "@\"bbbb\";", Break)); + + Break.ColumnLimit = 0; + verifyFormat("const char *hello = \"hello llvm\";", Break); } TEST_F(FormatTest, AlignsPipes) { @@ -4612,15 +4926,12 @@ TEST_F(FormatTest, AlignsPipes) { "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() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " << bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;"); + verifyFormat("llvm::errs() << \"aaaaaaaaaaaaaaaaaaaaaaa: \"\n" + " << aaaaaaaaaaaaaaaaa(aaaaaaaa, aaaaaaaaaaa);"); verifyFormat( "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); @@ -4650,6 +4961,10 @@ TEST_F(FormatTest, AlignsPipes) { "}"); verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \"\n" " << aaaaaaaa.aaaaaaaaaaaa(aaa)->aaaaaaaaaaaaaa();"); + verifyFormat("llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaa)\n" + " << aaaaaaaaaaaaaaaaaaaaaaaaaa;"); // Breaking before the first "<<" is generally not desirable. verifyFormat( @@ -4691,8 +5006,9 @@ TEST_F(FormatTest, AlignsPipes) { "}"); // Handle 'endl'. - verifyFormat("llvm::errs() << aaaa << endl\n" - " << bbbb << endl;"); + verifyFormat("llvm::errs() << aaaaaaaaaaaaaaaaaaaaaa << endl\n" + " << bbbbbbbbbbbbbbbbbbbbbb << endl;"); + verifyFormat("llvm::errs() << endl << bbbbbbbbbbbbbbbbbbbbbb << endl;"); } TEST_F(FormatTest, UnderstandsEquals) { @@ -4746,18 +5062,18 @@ TEST_F(FormatTest, WrapsAtFunctionCallsIfNecessary) { verifyFormat("SomeMap[std::pair(aaaaaaaaaaaa, bbbbbbbbbbbbbbb)].insert(\n" " ccccccccccccccccccccccc);"); verifyFormat("aaaaa(aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa).aaaaa(aaaaa),\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " .aaaaa(aaaaa),\n" " aaaaaaaaaaaaaaaaaaaaa);"); verifyFormat("void f() {\n" " aaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa)->aaaaaaaaa());\n" "}"); - verifyFormat( - "aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" - " .aaaaaaaaaaaaaaa(aa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaa));"); + verifyFormat("aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " .aaaaaaaaaaaaaaa(aa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaa));"); verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" @@ -4780,9 +5096,9 @@ TEST_F(FormatTest, WrapsAtFunctionCallsIfNecessary) { verifyFormat("a->aaaaaa()->aaaaaaaaaaa(aaaaaaaa()->aaaaaa()->aaaaa() ||\n" " aaaaaaaaa()->aaaaaa()->aaaaa());"); - // FIXME: Should we break before .a()? verifyFormat("aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa).a();"); + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " .a();"); FormatStyle NoBinPacking = getLLVMStyle(); NoBinPacking.BinPackParameters = false; @@ -4959,6 +5275,9 @@ TEST_F(FormatTest, UnderstandsTemplateParameters) { verifyFormat("f<int>();"); verifyFormat("template <typename T> void f() {}"); verifyFormat("struct A<std::enable_if<sizeof(T2) < sizeof(int32)>::type>;"); + verifyFormat("struct A<std::enable_if<sizeof(T2) ? sizeof(int32) : " + "sizeof(char)>::type>;"); + verifyFormat("template <class T> struct S<std::is_arithmetic<T>{}> {};"); // Not template parameters. verifyFormat("return a < b && c > d;"); @@ -4974,6 +5293,7 @@ TEST_F(FormatTest, UnderstandsTemplateParameters) { getLLVMStyleWithColumns(60)); verifyFormat("static_assert(is_convertible<A &&, B>::value, \"AAA\");"); verifyFormat("Constructor(A... a) : a_(X<A>{std::forward<A>(a)}...) {}"); + verifyFormat("< < < < < < < < < < < < < < < < < < < < < < < < < < < < < <"); } TEST_F(FormatTest, UnderstandsBinaryOperators) { @@ -5092,17 +5412,42 @@ TEST_F(FormatTest, UnderstandsOverloadedOperators) { verifyFormat("using A::operator+;"); - verifyFormat("Deleted &operator=(const Deleted &)& = default;"); - verifyFormat("Deleted &operator=(const Deleted &)&& = delete;"); - verifyGoogleFormat("Deleted& operator=(const Deleted&)& = default;"); - verifyGoogleFormat("Deleted& operator=(const Deleted&)&& = delete;"); - verifyFormat("string // break\n" "operator()() & {}"); verifyFormat("string // break\n" "operator()() && {}"); } +TEST_F(FormatTest, UnderstandsFunctionRefQualification) { + verifyFormat("Deleted &operator=(const Deleted &)& = default;"); + verifyFormat("Deleted &operator=(const Deleted &)&& = delete;"); + verifyFormat("SomeType MemberFunction(const Deleted &)& = delete;"); + verifyFormat("SomeType MemberFunction(const Deleted &)&& = delete;"); + verifyFormat("Deleted &operator=(const Deleted &)&;"); + verifyFormat("Deleted &operator=(const Deleted &)&&;"); + verifyFormat("SomeType MemberFunction(const Deleted &)&;"); + verifyFormat("SomeType MemberFunction(const Deleted &)&&;"); + + verifyGoogleFormat("Deleted& operator=(const Deleted&)& = default;"); + verifyGoogleFormat("SomeType MemberFunction(const Deleted&)& = delete;"); + verifyGoogleFormat("Deleted& operator=(const Deleted&)&;"); + verifyGoogleFormat("SomeType MemberFunction(const Deleted&)&;"); + + FormatStyle Spaces = getLLVMStyle(); + Spaces.SpacesInCStyleCastParentheses = true; + verifyFormat("Deleted &operator=(const Deleted &)& = default;", Spaces); + verifyFormat("SomeType MemberFunction(const Deleted &)& = delete;", Spaces); + verifyFormat("Deleted &operator=(const Deleted &)&;", Spaces); + verifyFormat("SomeType MemberFunction(const Deleted &)&;", Spaces); + + Spaces.SpacesInCStyleCastParentheses = false; + Spaces.SpacesInParentheses = true; + verifyFormat("Deleted &operator=( const Deleted & )& = default;", Spaces); + verifyFormat("SomeType MemberFunction( const Deleted & )& = delete;", Spaces); + verifyFormat("Deleted &operator=( const Deleted & )&;", Spaces); + verifyFormat("SomeType MemberFunction( const Deleted & )&;", Spaces); +} + TEST_F(FormatTest, UnderstandsNewAndDelete) { verifyFormat("void f() {\n" " A *a = new A;\n" @@ -5134,6 +5479,8 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyIndependentOfContext("int a = *b;"); verifyIndependentOfContext("int a = *b * c;"); verifyIndependentOfContext("int a = b * *c;"); + verifyIndependentOfContext("int a = b * (10);"); + verifyIndependentOfContext("S << b * (10);"); verifyIndependentOfContext("return 10 * b;"); verifyIndependentOfContext("return *b * *c;"); verifyIndependentOfContext("return a & ~b;"); @@ -5166,13 +5513,16 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyFormat("auto PointerBinding = [](const char *S) {};"); verifyFormat("typedef typeof(int(int, int)) *MyFunc;"); verifyFormat("[](const decltype(*a) &value) {}"); + verifyFormat("#define MACRO() [](A *a) { return 1; }"); verifyIndependentOfContext("typedef void (*f)(int *a);"); verifyIndependentOfContext("int i{a * b};"); verifyIndependentOfContext("aaa && aaa->f();"); verifyIndependentOfContext("int x = ~*p;"); verifyFormat("Constructor() : a(a), area(width * height) {}"); verifyFormat("Constructor() : a(a), area(a, width * height) {}"); + verifyGoogleFormat("MACRO Constructor(const int& i) : a(a), b(b) {}"); verifyFormat("void f() { f(a, c * d); }"); + verifyFormat("void f() { f(new a(), c * d); }"); verifyIndependentOfContext("InvalidRegions[*R] = 0;"); @@ -5193,6 +5543,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { " aaaaaaaaaaaaaaaaaaaaaaaaaaaa, *aaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); verifyGoogleFormat("**outparam = 1;"); + verifyGoogleFormat("*outparam = a * b;"); verifyGoogleFormat("int main(int argc, char** argv) {}"); verifyGoogleFormat("A<int*> a;"); verifyGoogleFormat("A<int**> a;"); @@ -5237,6 +5588,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyIndependentOfContext("if (int *a = (&b))"); verifyIndependentOfContext("while (int *a = &b)"); verifyIndependentOfContext("size = sizeof *a;"); + verifyIndependentOfContext("if (a && (b = c))"); verifyFormat("void f() {\n" " for (const int &v : Values) {\n" " }\n" @@ -5255,8 +5607,8 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyIndependentOfContext("A = new SomeType *[Length]();"); verifyIndependentOfContext("T **t = new T *;"); verifyIndependentOfContext("T **t = new T *();"); - verifyGoogleFormat("A = new SomeType* [Length]();"); - verifyGoogleFormat("A = new SomeType* [Length];"); + verifyGoogleFormat("A = new SomeType*[Length]();"); + verifyGoogleFormat("A = new SomeType*[Length];"); verifyGoogleFormat("T** t = new T*;"); verifyGoogleFormat("T** t = new T*();"); @@ -5324,8 +5676,8 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyFormat("A<int **> a;", PointerMiddle); verifyFormat("A<int *, int *> a;", PointerMiddle); verifyFormat("A<int * []> a;", PointerMiddle); - verifyFormat("A = new SomeType * [Length]();", PointerMiddle); - verifyFormat("A = new SomeType * [Length];", PointerMiddle); + verifyFormat("A = new SomeType *[Length]();", PointerMiddle); + verifyFormat("A = new SomeType *[Length];", PointerMiddle); verifyFormat("T ** t = new T *;", PointerMiddle); } @@ -5431,6 +5783,7 @@ TEST_F(FormatTest, FormatsCasts) { verifyFormat("my_int a = (const my_int)-1;"); verifyFormat("my_int a = (const my_int *)-1;"); verifyFormat("my_int a = (my_int)(my_int)-1;"); + verifyFormat("my_int a = (ns::my_int)-2;"); // FIXME: single value wrapped with paren will be treated as cast. verifyFormat("void f(int i = (kValue)*kMask) {}"); @@ -5503,11 +5856,18 @@ TEST_F(FormatTest, FormatsFunctionTypes) { verifyFormat("void f() { function(*some_pointer_var)[0] = 10; }"); } +TEST_F(FormatTest, FormatsPointersToArrayTypes) { + verifyFormat("A (*foo_)[6];"); + verifyFormat("vector<int> (*foo_)[6];"); +} + TEST_F(FormatTest, BreaksLongVariableDeclarations) { verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" " LoooooooooooooooooooooooooooooooooooooooongVariable;"); verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType const\n" " LoooooooooooooooooooooooooooooooooooooooongVariable;"); + verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" + " *LoooooooooooooooooooooooooooooooooooooooongVariable;"); // Different ways of ()-initializiation. verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" @@ -5516,6 +5876,8 @@ TEST_F(FormatTest, BreaksLongVariableDeclarations) { " LoooooooooooooooooooooooooooooooooooooooongVariable(a);"); verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" " LoooooooooooooooooooooooooooooooooooooooongVariable({});"); + verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" + " LoooooooooooooooooooooooooooooooooooooongVariable([A a]);"); } TEST_F(FormatTest, BreaksLongDeclarations) { @@ -5525,6 +5887,8 @@ TEST_F(FormatTest, BreaksLongDeclarations) { " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" "LoooooooooooooooooooooooooooooooongFunctionDeclaration();"); + verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType *\n" + "LoooooooooooooooooooooooooooooooongFunctionDeclaration();"); verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType MACRO\n" @@ -5563,12 +5927,12 @@ TEST_F(FormatTest, BreaksLongDeclarations) { " SourceLocation L, IdentifierIn *II,\n" " Type *T) {}"); verifyFormat("ReallyLongReturnType<TemplateParam1, TemplateParam2>\n" - "ReallyReallyLongFunctionName(\n" + "ReallyReaaallyLongFunctionName(\n" " const std::string &SomeParameter,\n" - " const SomeType<string, SomeOtherTemplateParameter> &\n" - " ReallyReallyLongParameterName,\n" - " const SomeType<string, SomeOtherTemplateParameter> &\n" - " AnotherLongParameterName) {}"); + " const SomeType<string, SomeOtherTemplateParameter>\n" + " &ReallyReallyLongParameterName,\n" + " const SomeType<string, SomeOtherTemplateParameter>\n" + " &AnotherLongParameterName) {}"); verifyFormat("template <typename A>\n" "SomeLoooooooooooooooooooooongType<\n" " typename some_namespace::SomeOtherType<A>::Type>\n" @@ -5592,8 +5956,15 @@ TEST_F(FormatTest, BreaksLongDeclarations) { " int aaaaaaaaaaaaaaaaaaaaaaa);"); verifyFormat("typedef size_t (*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)(\n" - " const aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + " const aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " *aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " vector<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>\n" + " aaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " vector<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>>\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); } TEST_F(FormatTest, FormatsArrays) { @@ -5617,6 +5988,8 @@ TEST_F(FormatTest, FormatsArrays) { "aaaaaaaaaaa aaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaa->aaaaaaaaa[0]\n" " .aaaaaaa[0]\n" " .aaaaaaaaaaaaaaaaaaaaaa();"); + + verifyNoCrash("a[,Y?)]", getLLVMStyleWithColumns(10)); } TEST_F(FormatTest, LineStartsWithSpecialCharacter) { @@ -5632,6 +6005,7 @@ TEST_F(FormatTest, HandlesIncludeDirectives) { "#include \"string.h\"\n" "#include <a-a>\n" "#include < path with space >\n" + "#include_next <test.h>" "#include \"abc.h\" // this is included for ABC\n" "#include \"some long include\" // with a comment\n" "#include \"some very long include paaaaaaaaaaaaaaaaaaaaaaath\"", @@ -5744,6 +6118,7 @@ TEST_F(FormatTest, IncorrectAccessSpecifier) { TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) { verifyFormat("{"); verifyFormat("#})"); + verifyNoCrash("(/**/[:!] ?[)."); } TEST_F(FormatTest, IncorrectCodeDoNoWhile) { @@ -5760,16 +6135,16 @@ TEST_F(FormatTest, IncorrectCodeDoNoWhile) { TEST_F(FormatTest, IncorrectCodeMissingParens) { verifyFormat("if {\n foo;\n foo();\n}"); verifyFormat("switch {\n foo;\n foo();\n}"); - verifyFormat("for {\n foo;\n foo();\n}"); + verifyIncompleteFormat("for {\n foo;\n foo();\n}"); verifyFormat("while {\n foo;\n foo();\n}"); verifyFormat("do {\n foo;\n foo();\n} while;"); } TEST_F(FormatTest, DoesNotTouchUnwrappedLinesWithErrors) { - verifyFormat("namespace {\n" - "class Foo { Foo (\n" - "};\n" - "} // comment"); + verifyIncompleteFormat("namespace {\n" + "class Foo { Foo (\n" + "};\n" + "} // comment"); } TEST_F(FormatTest, IncorrectCodeErrorDetection) { @@ -5832,10 +6207,23 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) { verifyFormat("std::vector<int> v = {1, 0 /* comment */};"); verifyFormat("Node n{1, Node{1000}, //\n" " 2};"); + verifyFormat("Aaaa aaaaaaa{\n" + " {\n" + " aaaa,\n" + " },\n" + "};"); + verifyFormat("class C : public D {\n" + " SomeClass SC{2};\n" + "};"); + verifyFormat("class C : public A {\n" + " class D : public B {\n" + " void f() { int i{2}; }\n" + " };\n" + "};"); - // In combination with BinPackParameters = false. + // In combination with BinPackArguments = false. FormatStyle NoBinPacking = getLLVMStyle(); - NoBinPacking.BinPackParameters = false; + NoBinPacking.BinPackArguments = false; verifyFormat("const Aaaaaa aaaaa = {aaaaa,\n" " bbbbb,\n" " ccccc,\n" @@ -5949,9 +6337,18 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) { ExtraSpaces); verifyFormat( "std::vector<MyValues> aaaaaaaaaaaaaaaaaaa{\n" - " aaaaaaa, aaaaaaaaaa, aaaaa, aaaaaaaaaaaaaaa, aaa, aaaaaaaaaa, a,\n" - " aaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaa, aaaaaaa, a};"); + " aaaaaaa,\n" + " aaaaaaaaaa,\n" + " aaaaa,\n" + " aaaaaaaaaaaaaaa,\n" + " aaa,\n" + " aaaaaaaaaa,\n" + " a,\n" + " aaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaa,\n" + " a};"); verifyFormat("vector<int> foo = { ::SomeGlobalFunction() };", ExtraSpaces); } @@ -5962,11 +6359,9 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" " 1, 22, 333, 4444, 55555, 666666, 7777777};"); - verifyFormat("vector<int> x = {1, 22, 333, 4444, 55555, 666666, 7777777,\n" - " // line comment\n" + verifyFormat("vector<int> x = {1, 22, 333, 4444, 55555, 666666, 7777777, //\n" " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" - " 1, 22, 333, 4444, 55555,\n" - " // line comment\n" + " 1, 22, 333, 4444, 55555, //\n" " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" " 1, 22, 333, 4444, 55555, 666666, 7777777};"); verifyFormat( @@ -5980,6 +6375,14 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { verifyFormat("static const uint16_t CallerSavedRegs64Bittttt[] = {\n" " X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI,\n" " X86::R8, X86::R9, X86::R10, X86::R11, 0};"); + verifyFormat("static const uint16_t CallerSavedRegs64Bittttt[] = {\n" + " X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI,\n" + " // Separating comment.\n" + " X86::R8, X86::R9, X86::R10, X86::R11, 0};"); + verifyFormat("static const uint16_t CallerSavedRegs64Bittttt[] = {\n" + " // Leading comment\n" + " X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI,\n" + " X86::R8, X86::R9, X86::R10, X86::R11, 0};"); verifyFormat("vector<int> x = {1, 1, 1, 1,\n" " 1, 1, 1, 1};", getLLVMStyleWithColumns(39)); @@ -5989,6 +6392,24 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { verifyFormat("vector<int> aaaaaaaaaaaaaaaaaaaaaa = {\n" " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};", getLLVMStyleWithColumns(43)); + verifyFormat( + "static unsigned SomeValues[10][3] = {\n" + " {1, 4, 0}, {4, 9, 0}, {4, 5, 9}, {8, 5, 4}, {1, 8, 4},\n" + " {10, 1, 6}, {11, 0, 9}, {2, 11, 9}, {5, 2, 9}, {11, 2, 7}};"); + verifyFormat("static auto fields = new vector<string>{\n" + " \"aaaaaaaaaaaaa\",\n" + " \"aaaaaaaaaaaaa\",\n" + " \"aaaaaaaaaaaa\",\n" + " \"aaaaaaaaaaaaaa\",\n" + " \"aaaaaaaaaaaaaaaaaaaaaaaaa\",\n" + " \"aaaaaaaaaaaa\",\n" + " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n" + "};"); + verifyFormat("vector<int> x = {1, 2, 3, 4, aaaaaaaaaaaaaaaaa, 6};"); + verifyFormat("vector<int> x = {1, aaaaaaaaaaaaaaaaaaaaaa,\n" + " 2, bbbbbbbbbbbbbbbbbbbbbb,\n" + " 3, cccccccccccccccccccccc};", + getLLVMStyleWithColumns(60)); // Trailing commas. verifyFormat("vector<int> x = {\n" @@ -6003,15 +6424,21 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { " 1, 1, 1, 1,\n" " /**/ /**/};", getLLVMStyleWithColumns(39)); + + // Trailing comment in the first line. + verifyFormat("vector<int> iiiiiiiiiiiiiii = { //\n" + " 1111111111, 2222222222, 33333333333, 4444444444, //\n" + " 111111111, 222222222, 3333333333, 444444444, //\n" + " 11111111, 22222222, 333333333, 44444444};"); + + // With nested lists, we should either format one item per line or all nested + // lists one on line. + // FIXME: For some nested lists, we can do better. verifyFormat("return {{aaaaaaaaaaaaaaaaaaaaa},\n" " {aaaaaaaaaaaaaaaaaaa},\n" " {aaaaaaaaaaaaaaaaaaaaa},\n" " {aaaaaaaaaaaaaaaaa}};", getLLVMStyleWithColumns(60)); - - // With nested lists, we should either format one item per line or all nested - // lists one one line. - // FIXME: For some nested lists, we can do better. verifyFormat( "SomeStruct my_struct_array = {\n" " {aaaaaa, aaaaaaaa, aaaaaaaaaa, aaaaaaaaa, aaaaaaaaa, aaaaaaaaaa,\n" @@ -6025,6 +6452,8 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { // No column layout should be used here. verifyFormat("aaaaaaaaaaaaaaa = {aaaaaaaaaaaaaaaaaaaaaaaaaaa, 0, 0,\n" " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb};"); + + verifyNoCrash("a<,"); } TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { @@ -6079,7 +6508,8 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { EXPECT_EQ("A() : b(0) {}", format("A():b(0){}", NoColumnLimit)); EXPECT_EQ("class C {\n" " A() : b(0) {}\n" - "};", format("class C{A():b(0){}};", NoColumnLimit)); + "};", + format("class C{A():b(0){}};", NoColumnLimit)); EXPECT_EQ("A()\n" " : b(0) {\n" "}", @@ -6157,6 +6587,8 @@ TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { verifyFormat("class __declspec(X) Z {\n} n;"); verifyFormat("class A##B##C {\n} n;"); verifyFormat("class alignas(16) Z {\n} n;"); + verifyFormat("class MACRO(X) alignas(16) Z {\n} n;"); + verifyFormat("class MACROA MACRO(X) Z {\n} n;"); // Redefinition from nested context: verifyFormat("class A::B::C {\n} n;"); @@ -6298,7 +6730,7 @@ TEST_F(FormatTest, BlockComments) { EXPECT_EQ("/*\n" "*\n" " * aaaaaa\n" - "*aaaaaa\n" + " * aaaaaa\n" "*/", format("/*\n" "*\n" @@ -6467,12 +6899,14 @@ TEST_F(FormatTest, FormatForObjectiveCMethodDecls) { format("-(NSInteger)Method5:(id)anObject:(id)AnotherObject;")); EXPECT_EQ("- (id)Method6:(id)A:(id)B:(id)C:(id)D;", format("- (id)Method6:(id)A:(id)B:(id)C:(id)D;")); - EXPECT_EQ( - "- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;", - format( - "- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;")); + EXPECT_EQ("- (void)sendAction:(SEL)aSelector to:(id)anObject " + "forAllCells:(BOOL)flag;", + format("- (void)sendAction:(SEL)aSelector to:(id)anObject " + "forAllCells:(BOOL)flag;")); // Very long objectiveC method declaration. + verifyFormat("- (void)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n" + " (SoooooooooooooooooooooomeType *)bbbbbbbbbb;"); verifyFormat("- (NSUInteger)indexOfObject:(id)anObject\n" " inRange:(NSRange)range\n" " outRange:(NSRange)out_range\n" @@ -6486,11 +6920,26 @@ TEST_F(FormatTest, FormatForObjectiveCMethodDecls) { " outRange8:(NSRange)out_range8\n" " outRange9:(NSRange)out_range9;"); + // When the function name has to be wrapped. + FormatStyle Style = getLLVMStyle(); + Style.IndentWrappedFunctionNames = false; + verifyFormat("- (SomeLooooooooooooooooooooongType *)\n" + "veryLooooooooooongName:(NSString)aaaaaaaaaaaaaa\n" + " anotherName:(NSString)bbbbbbbbbbbbbb {\n" + "}", + Style); + Style.IndentWrappedFunctionNames = true; + verifyFormat("- (SomeLooooooooooooooooooooongType *)\n" + " veryLooooooooooongName:(NSString)aaaaaaaaaaaaaa\n" + " anotherName:(NSString)bbbbbbbbbbbbbb {\n" + "}", + Style); + verifyFormat("- (int)sum:(vector<int>)numbers;"); verifyGoogleFormat("- (void)setDelegate:(id<Protocol>)delegate;"); // FIXME: In LLVM style, there should be a space in front of a '<' for ObjC // protocol lists (but not for template classes): - //verifyFormat("- (void)setDelegate:(id <Protocol>)delegate;"); + // verifyFormat("- (void)setDelegate:(id <Protocol>)delegate;"); verifyFormat("- (int (*)())foo:(int (*)())f;"); verifyGoogleFormat("- (int (*)())foo:(int (*)())foo;"); @@ -6564,7 +7013,7 @@ TEST_F(FormatTest, FormatObjCInterface) { "+ (id)init;\n" "@end"); - verifyGoogleFormat("@interface Foo (HackStuff) <MyProtocol>\n" + verifyGoogleFormat("@interface Foo (HackStuff)<MyProtocol>\n" "+ (id)init;\n" "@end"); @@ -6606,7 +7055,7 @@ TEST_F(FormatTest, FormatObjCInterface) { FormatStyle OnePerLine = getGoogleStyle(); OnePerLine.BinPackParameters = false; - verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa () <\n" + verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ()<\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" @@ -6770,9 +7219,9 @@ TEST_F(FormatTest, FormatObjCMethodExpr) { verifyFormat("int a = &[foo bar:baz];"); verifyFormat("int a = *[foo bar:baz];"); // FIXME: Make casts work, without breaking f()[4]. - //verifyFormat("int a = (int)[foo bar:baz];"); - //verifyFormat("return (int)[foo bar:baz];"); - //verifyFormat("(void)[foo bar:baz];"); + // verifyFormat("int a = (int)[foo bar:baz];"); + // verifyFormat("return (int)[foo bar:baz];"); + // verifyFormat("(void)[foo bar:baz];"); verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];"); // Binary operators. @@ -6811,9 +7260,16 @@ TEST_F(FormatTest, FormatObjCMethodExpr) { verifyFormat("return in[42];"); verifyFormat("for (auto v : in[1]) {\n}"); + verifyFormat("for (int i = 0; i < in[a]; ++i) {\n}"); + verifyFormat("for (int i = 0; in[a] < i; ++i) {\n}"); + verifyFormat("for (int i = 0; i < n; ++i, ++in[a]) {\n}"); + verifyFormat("for (int i = 0; i < n; ++i, in[a]++) {\n}"); + verifyFormat("for (int i = 0; i < f(in[a]); ++i, in[a]++) {\n}"); verifyFormat("for (id foo in [self getStuffFor:bla]) {\n" "}"); verifyFormat("[self aaaaa:MACRO(a, b:, c:)];"); + verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];"); + verifyFormat("[self aaaaa:(Type)a bbbbb:3];"); verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];"); verifyFormat("[self stuffWithInt:a ? b : c float:4.5];"); @@ -6898,6 +7354,15 @@ TEST_F(FormatTest, FormatObjCMethodExpr) { " fraction:1.0\n" " respectFlipped:NO\n" " hints:nil];"); + verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];"); + verifyFormat("[aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];"); + verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa[aaaaaaaaaaaaaaaaaaaaa]\n" + " aaaaaaaaaaaaaaaaaaaaaa];"); + verifyFormat("[call aaaaaaaa.aaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa\n" + " .aaaaaaaa];", // FIXME: Indentation seems off. + getLLVMStyleWithColumns(60)); verifyFormat( "scoped_nsobject<NSTextField> message(\n" @@ -6914,6 +7379,13 @@ TEST_F(FormatTest, FormatObjCMethodExpr) { " aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n" " aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa];"); + // FIXME: This violates the column limit. + verifyFormat( + "[aaaaaaaaaaaaaaaaaaaaaaaaa\n" + " aaaaaaaaaaaaaaaaa:aaaaaaaa\n" + " aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];", + getLLVMStyleWithColumns(60)); + // Variadic parameters. verifyFormat( "NSArray *myStrings = [NSArray stringarray:@\"a\", @\"b\", nil];"); @@ -7026,20 +7498,19 @@ TEST_F(FormatTest, ObjCDictLiterals) { "}"); verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}"); - verifyFormat("[self setDict:@{}"); - verifyFormat("[self setDict:@{@1 : @2}"); + verifyIncompleteFormat("[self setDict:@{}"); + verifyIncompleteFormat("[self setDict:@{@1 : @2}"); verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);"); verifyFormat( "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};"); verifyFormat( "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};"); - verifyFormat( - "NSDictionary *d = @{\n" - " @\"nam\" : NSUserNam(),\n" - " @\"dte\" : [NSDate date],\n" - " @\"processInfo\" : [NSProcessInfo processInfo]\n" - "};"); + verifyFormat("NSDictionary *d = @{\n" + " @\"nam\" : NSUserNam(),\n" + " @\"dte\" : [NSDate date],\n" + " @\"processInfo\" : [NSProcessInfo processInfo]\n" + "};"); verifyFormat( "@{\n" " NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : " @@ -7057,12 +7528,11 @@ TEST_F(FormatTest, ObjCDictLiterals) { "};"); // We should try to be robust in case someone forgets the "@". - verifyFormat( - "NSDictionary *d = {\n" - " @\"nam\" : NSUserNam(),\n" - " @\"dte\" : [NSDate date],\n" - " @\"processInfo\" : [NSProcessInfo processInfo]\n" - "};"); + verifyFormat("NSDictionary *d = {\n" + " @\"nam\" : NSUserNam(),\n" + " @\"dte\" : [NSDate date],\n" + " @\"processInfo\" : [NSProcessInfo processInfo]\n" + "};"); verifyFormat("NSMutableDictionary *dictionary =\n" " [NSMutableDictionary dictionaryWithDictionary:@{\n" " aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n" @@ -7072,7 +7542,7 @@ TEST_F(FormatTest, ObjCDictLiterals) { } TEST_F(FormatTest, ObjCArrayLiterals) { - verifyFormat("@["); + verifyIncompleteFormat("@["); verifyFormat("@[]"); verifyFormat( "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];"); @@ -7098,6 +7568,10 @@ TEST_F(FormatTest, ObjCArrayLiterals) { " @\"aaaaaaaaaaaaaaaaa\",\n" " @\"aaaaaaaaaaaaaaaaa\"\n" "];"); + verifyFormat("NSArray *array = @[\n" + " @\"a\",\n" + " @\"a\",\n" // Trailing comma -> one per line. + "];"); // We should try to be robust in case someone forgets the "@". verifyFormat("NSArray *some_variable = [\n" @@ -7282,11 +7756,11 @@ TEST_F(FormatTest, BreaksStringLiterals) { "loooooooooooooooooooong);", getLLVMStyleWithColumns(20))); - EXPECT_EQ("f(g(\"long string \"\n" - " \"literal\"),\n" - " b);", - format("f(g(\"long string literal\"), b);", - getLLVMStyleWithColumns(20))); + EXPECT_EQ( + "f(g(\"long string \"\n" + " \"literal\"),\n" + " b);", + format("f(g(\"long string literal\"), b);", getLLVMStyleWithColumns(20))); EXPECT_EQ("f(g(\"long string \"\n" " \"literal\",\n" " a),\n" @@ -7315,23 +7789,20 @@ TEST_F(FormatTest, BreaksStringLiterals) { " aaaaaaaaaaaaaaaaaaaa,\n" " aaaaaa(\"aaa aaaaa aaa aaa aaaaa aaa aaaaa aaa aaa aaaaaa\"));"); - EXPECT_EQ( - "\"splitmea\"\n" - "\"trandomp\"\n" - "\"oint\"", - format("\"splitmeatrandompoint\"", getLLVMStyleWithColumns(10))); + EXPECT_EQ("\"splitmea\"\n" + "\"trandomp\"\n" + "\"oint\"", + format("\"splitmeatrandompoint\"", getLLVMStyleWithColumns(10))); - EXPECT_EQ( - "\"split/\"\n" - "\"pathat/\"\n" - "\"slashes\"", - format("\"split/pathat/slashes\"", getLLVMStyleWithColumns(10))); + EXPECT_EQ("\"split/\"\n" + "\"pathat/\"\n" + "\"slashes\"", + format("\"split/pathat/slashes\"", getLLVMStyleWithColumns(10))); - EXPECT_EQ( - "\"split/\"\n" - "\"pathat/\"\n" - "\"slashes\"", - format("\"split/pathat/slashes\"", getLLVMStyleWithColumns(10))); + EXPECT_EQ("\"split/\"\n" + "\"pathat/\"\n" + "\"slashes\"", + format("\"split/pathat/slashes\"", getLLVMStyleWithColumns(10))); EXPECT_EQ("\"split at \"\n" "\"spaces/at/\"\n" "\"slashes.at.any$\"\n" @@ -7376,12 +7847,11 @@ TEST_F(FormatTest, BreaksStringLiterals) { FormatStyle AlignLeft = getLLVMStyleWithColumns(12); AlignLeft.AlignEscapedNewlinesLeft = true; - EXPECT_EQ( - "#define A \\\n" - " \"some \" \\\n" - " \"text \" \\\n" - " \"other\";", - format("#define A \"some text other\";", AlignLeft)); + EXPECT_EQ("#define A \\\n" + " \"some \" \\\n" + " \"text \" \\\n" + " \"other\";", + format("#define A \"some text other\";", AlignLeft)); } TEST_F(FormatTest, BreaksStringLiteralsWithTabs) { @@ -7413,6 +7883,12 @@ TEST_F(FormatTest, BreaksWideAndNSStringLiterals) { EXPECT_EQ("@\"NSString \"\n" "@\"literal\";", format("@\"NSString literal\";", getGoogleStyleWithColumns(19))); + + // This input makes clang-format try to split the incomplete unicode escape + // sequence, which used to lead to a crasher. + verifyNoCrash( + "aaaaaaaaaaaaaaaaaaaa = L\"\\udff\"'; // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + getLLVMStyleWithColumns(60)); } TEST_F(FormatTest, DoesNotBreakRawStringLiterals) { @@ -7447,6 +7923,22 @@ TEST_F(FormatTest, BreaksStringLiteralsWithin_TMacro) { EXPECT_EQ( "_T ( \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" )", format(" _T ( \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" )", Style)); + EXPECT_EQ("f(\n" + "#if !TEST\n" + " _T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\")\n" + "#endif\n" + " );", + format("f(\n" + "#if !TEST\n" + "_T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\")\n" + "#endif\n" + ");")); + EXPECT_EQ("f(\n" + "\n" + " _T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\"));", + format("f(\n" + "\n" + "_T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\"));")); } TEST_F(FormatTest, DontSplitStringLiteralsWithEscapedNewlines) { @@ -7523,9 +8015,7 @@ TEST_F(FormatTest, DoesNotTryToParseUDLiteralsInPreCpp11Code) { format("#define x(_a) printf(\"foo\"_a);", Style)); } -TEST_F(FormatTest, UnderstandsCpp1y) { - verifyFormat("int bi{1'000'000};"); -} +TEST_F(FormatTest, UnderstandsCpp1y) { verifyFormat("int bi{1'000'000};"); } TEST_F(FormatTest, BreakStringLiteralsBeforeUnbreakableTokenSequence) { EXPECT_EQ("someFunction(\"aaabbbcccd\"\n" @@ -7576,10 +8066,8 @@ TEST_F(FormatTest, BreakStringLiteralsBeforeUnbreakableTokenSequence) { } TEST_F(FormatTest, DoNotBreakStringLiteralsInEscapeSequence) { - EXPECT_EQ("\"\\a\"", - format("\"\\a\"", getLLVMStyleWithColumns(3))); - EXPECT_EQ("\"\\\"", - format("\"\\\"", getLLVMStyleWithColumns(2))); + EXPECT_EQ("\"\\a\"", format("\"\\a\"", getLLVMStyleWithColumns(3))); + EXPECT_EQ("\"\\\"", format("\"\\\"", getLLVMStyleWithColumns(2))); EXPECT_EQ("\"test\"\n" "\"\\n\"", format("\"test\\n\"", getLLVMStyleWithColumns(7))); @@ -7589,8 +8077,7 @@ TEST_F(FormatTest, DoNotBreakStringLiteralsInEscapeSequence) { EXPECT_EQ("\"\\\\\\\\\"\n" "\"\\n\"", format("\"\\\\\\\\\\n\"", getLLVMStyleWithColumns(7))); - EXPECT_EQ("\"\\uff01\"", - format("\"\\uff01\"", getLLVMStyleWithColumns(7))); + EXPECT_EQ("\"\\uff01\"", format("\"\\uff01\"", getLLVMStyleWithColumns(7))); EXPECT_EQ("\"\\uff01\"\n" "\"test\"", format("\"\\uff01test\"", getLLVMStyleWithColumns(8))); @@ -7880,25 +8367,25 @@ TEST_F(FormatTest, ConfigurableUseOfTab) { Tab)); EXPECT_EQ("/* some\n" " comment */", - format(" \t \t /* some\n" - " \t \t comment */", - Tab)); + format(" \t \t /* some\n" + " \t \t comment */", + Tab)); EXPECT_EQ("int a; /* some\n" " comment */", - format(" \t \t int a; /* some\n" - " \t \t comment */", - Tab)); + format(" \t \t int a; /* some\n" + " \t \t comment */", + Tab)); EXPECT_EQ("int a; /* some\n" "comment */", - format(" \t \t int\ta; /* some\n" - " \t \t comment */", - Tab)); + format(" \t \t int\ta; /* some\n" + " \t \t comment */", + Tab)); EXPECT_EQ("f(\"\t\t\"); /* some\n" " comment */", - format(" \t \t f(\"\t\t\"); /* some\n" - " \t \t comment */", - Tab)); + format(" \t \t f(\"\t\t\"); /* some\n" + " \t \t comment */", + Tab)); EXPECT_EQ("{\n" " /*\n" " * Comment\n" @@ -7951,20 +8438,25 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { NoSpace.SpaceBeforeParens = FormatStyle::SBPO_Never; verifyFormat("while(true)\n" - " continue;", NoSpace); + " continue;", + NoSpace); verifyFormat("for(;;)\n" - " continue;", NoSpace); + " continue;", + NoSpace); verifyFormat("if(true)\n" " f();\n" "else if(true)\n" - " f();", NoSpace); + " f();", + NoSpace); verifyFormat("do {\n" " do_something();\n" - "} while(something());", NoSpace); + "} while(something());", + NoSpace); verifyFormat("switch(x) {\n" "default:\n" " break;\n" - "}", NoSpace); + "}", + NoSpace); verifyFormat("auto i = std::make_unique<int>(5);", NoSpace); verifyFormat("size_t x = sizeof(x);", NoSpace); verifyFormat("auto f(int x) -> decltype(x);", NoSpace); @@ -7973,6 +8465,7 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { verifyFormat("size_t x = alignof(MyType);", NoSpace); verifyFormat("static_assert(sizeof(char) == 1, \"Impossible!\");", NoSpace); verifyFormat("int f() throw(Deprecated);", NoSpace); + verifyFormat("typedef void (*cb)(int);", NoSpace); FormatStyle Space = getLLVMStyle(); Space.SpaceBeforeParens = FormatStyle::SBPO_Always; @@ -8017,6 +8510,7 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { verifyFormat("size_t x = alignof (MyType);", Space); verifyFormat("static_assert (sizeof (char) == 1, \"Impossible!\");", Space); verifyFormat("int f () throw (Deprecated);", Space); + verifyFormat("typedef void (*cb) (int);", Space); } TEST_F(FormatTest, ConfigurableSpacesInParentheses) { @@ -8024,21 +8518,28 @@ TEST_F(FormatTest, ConfigurableSpacesInParentheses) { Spaces.SpacesInParentheses = true; verifyFormat("call( x, y, z );", Spaces); + verifyFormat("call();", Spaces); + verifyFormat("std::function<void( int, int )> callback;", Spaces); verifyFormat("while ( (bool)1 )\n" - " continue;", Spaces); + " continue;", + Spaces); verifyFormat("for ( ;; )\n" - " continue;", Spaces); + " continue;", + Spaces); verifyFormat("if ( true )\n" " f();\n" "else if ( true )\n" - " f();", Spaces); + " f();", + Spaces); verifyFormat("do {\n" " do_something( (int)i );\n" - "} while ( something() );", Spaces); + "} while ( something() );", + Spaces); verifyFormat("switch ( x ) {\n" "default:\n" " break;\n" - "}", Spaces); + "}", + Spaces); Spaces.SpacesInParentheses = false; Spaces.SpacesInCStyleCastParentheses = true; @@ -8050,37 +8551,38 @@ TEST_F(FormatTest, ConfigurableSpacesInParentheses) { verifyFormat("my_int a = ( my_int )sizeof(int);", Spaces); verifyFormat("#define x (( int )-1)", Spaces); - Spaces.SpacesInParentheses = false; - Spaces.SpaceInEmptyParentheses = true; - verifyFormat("call(x, y, z);", Spaces); - verifyFormat("call( )", Spaces); - - // Run the first set of tests again with - // Spaces.SpacesInParentheses = false, - // Spaces.SpaceInEmptyParentheses = true and - // Spaces.SpacesInCStyleCastParentheses = true - Spaces.SpacesInParentheses = false, - Spaces.SpaceInEmptyParentheses = true; + // Run the first set of tests again with: + Spaces.SpacesInParentheses = false, Spaces.SpaceInEmptyParentheses = true; Spaces.SpacesInCStyleCastParentheses = true; verifyFormat("call(x, y, z);", Spaces); + verifyFormat("call( );", Spaces); + verifyFormat("std::function<void(int, int)> callback;", Spaces); verifyFormat("while (( bool )1)\n" - " continue;", Spaces); + " continue;", + Spaces); verifyFormat("for (;;)\n" - " continue;", Spaces); + " continue;", + Spaces); verifyFormat("if (true)\n" " f( );\n" "else if (true)\n" - " f( );", Spaces); + " f( );", + Spaces); verifyFormat("do {\n" " do_something(( int )i);\n" - "} while (something( ));", Spaces); + "} while (something( ));", + Spaces); verifyFormat("switch (x) {\n" "default:\n" " break;\n" - "}", Spaces); + "}", + Spaces); + // Run the first set of tests again with: Spaces.SpaceAfterCStyleCast = true; verifyFormat("call(x, y, z);", Spaces); + verifyFormat("call( );", Spaces); + verifyFormat("std::function<void(int, int)> callback;", Spaces); verifyFormat("while (( bool ) 1)\n" " continue;", Spaces); @@ -8101,6 +8603,8 @@ TEST_F(FormatTest, ConfigurableSpacesInParentheses) { " break;\n" "}", Spaces); + + // Run subset of tests again with: Spaces.SpacesInCStyleCastParentheses = false; Spaces.SpaceAfterCStyleCast = true; verifyFormat("while ((bool) 1)\n" @@ -8146,6 +8650,152 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeAssignmentOperators) { verifyFormat("a or_eq 8;", Spaces); } +TEST_F(FormatTest, AlignConsecutiveAssignments) { + FormatStyle Alignment = getLLVMStyle(); + Alignment.AlignConsecutiveAssignments = false; + verifyFormat("int a = 5;\n" + "int oneTwoThree = 123;", + Alignment); + verifyFormat("int a = 5;\n" + "int oneTwoThree = 123;", + Alignment); + + Alignment.AlignConsecutiveAssignments = true; + verifyFormat("int a = 5;\n" + "int oneTwoThree = 123;", + Alignment); + verifyFormat("int a = method();\n" + "int oneTwoThree = 133;", + Alignment); + verifyFormat("a &= 5;\n" + "bcd *= 5;\n" + "ghtyf += 5;\n" + "dvfvdb -= 5;\n" + "a /= 5;\n" + "vdsvsv %= 5;\n" + "sfdbddfbdfbb ^= 5;\n" + "dvsdsv |= 5;\n" + "int dsvvdvsdvvv = 123;", + Alignment); + verifyFormat("int i = 1, j = 10;\n" + "something = 2000;", + Alignment); + verifyFormat("something = 2000;\n" + "int i = 1, j = 10;\n", + Alignment); + verifyFormat("something = 2000;\n" + "another = 911;\n" + "int i = 1, j = 10;\n" + "oneMore = 1;\n" + "i = 2;", + Alignment); + verifyFormat("int a = 5;\n" + "int one = 1;\n" + "method();\n" + "int oneTwoThree = 123;\n" + "int oneTwo = 12;", + Alignment); + verifyFormat("int oneTwoThree = 123; // comment\n" + "int oneTwo = 12; // comment", + Alignment); + EXPECT_EQ("int a = 5;\n" + "\n" + "int oneTwoThree = 123;", + format("int a = 5;\n" + "\n" + "int oneTwoThree= 123;", + Alignment)); + EXPECT_EQ("int a = 5;\n" + "int one = 1;\n" + "\n" + "int oneTwoThree = 123;", + format("int a = 5;\n" + "int one = 1;\n" + "\n" + "int oneTwoThree = 123;", + Alignment)); + EXPECT_EQ("int a = 5;\n" + "int one = 1;\n" + "\n" + "int oneTwoThree = 123;\n" + "int oneTwo = 12;", + format("int a = 5;\n" + "int one = 1;\n" + "\n" + "int oneTwoThree = 123;\n" + "int oneTwo = 12;", + Alignment)); + Alignment.AlignEscapedNewlinesLeft = true; + verifyFormat("#define A \\\n" + " int aaaa = 12; \\\n" + " int b = 23; \\\n" + " int ccc = 234; \\\n" + " int dddddddddd = 2345;", + Alignment); + Alignment.AlignEscapedNewlinesLeft = false; + verifyFormat("#define A " + " \\\n" + " int aaaa = 12; " + " \\\n" + " int b = 23; " + " \\\n" + " int ccc = 234; " + " \\\n" + " int dddddddddd = 2345;", + Alignment); + verifyFormat("void SomeFunction(int parameter = 1, int i = 2, int j = 3, int " + "k = 4, int l = 5,\n" + " int m = 6) {\n" + " int j = 10;\n" + " otherThing = 1;\n" + "}", + Alignment); + verifyFormat("void SomeFunction(int parameter = 0) {\n" + " int i = 1;\n" + " int j = 2;\n" + " int big = 10000;\n" + "}", + Alignment); + verifyFormat("class C {\n" + "public:\n" + " int i = 1;\n" + " virtual void f() = 0;\n" + "};", + Alignment); + verifyFormat("int i = 1;\n" + "if (SomeType t = getSomething()) {\n" + "}\n" + "int j = 2;\n" + "int big = 10000;", + Alignment); + verifyFormat("int j = 7;\n" + "for (int k = 0; k < N; ++k) {\n" + "}\n" + "int j = 2;\n" + "int big = 10000;\n" + "}", + Alignment); + Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_All; + verifyFormat("int i = 1;\n" + "LooooooooooongType loooooooooooooooooooooongVariable\n" + " = someLooooooooooooooooongFunction();\n" + "int j = 2;", + Alignment); + Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_None; + verifyFormat("int i = 1;\n" + "LooooooooooongType loooooooooooooooooooooongVariable =\n" + " someLooooooooooooooooongFunction();\n" + "int j = 2;", + Alignment); + // FIXME: Should align all three assignments + verifyFormat( + "int i = 1;\n" + "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n" + " loooooooooooooooooooooongParameterB);\n" + "int j = 2;", + Alignment); +} + TEST_F(FormatTest, LinuxBraceBreaking) { FormatStyle LinuxBraceStyle = getLLVMStyle(); LinuxBraceStyle.BreakBeforeBraces = FormatStyle::BS_Linux; @@ -8575,11 +9225,16 @@ TEST_F(FormatTest, UnderstandsPragmas) { "(including parentheses).")); } +TEST_F(FormatTest, UnderstandPragmaOption) { + verifyFormat("#pragma option -C -A"); + + EXPECT_EQ("#pragma option -C -A", format("#pragma option -C -A")); +} + #define EXPECT_ALL_STYLES_EQUAL(Styles) \ for (size_t i = 1; i < Styles.size(); ++i) \ - EXPECT_EQ(Styles[0], Styles[i]) << "Style #" << i << " of " \ - << Styles.size() \ - << " differs from Style #0" + EXPECT_EQ(Styles[0], Styles[i]) << "Style #" << i << " of " << Styles.size() \ + << " differs from Style #0" TEST_F(FormatTest, GetsPredefinedStyleByName) { SmallVector<FormatStyle, 3> Styles; @@ -8685,6 +9340,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft); CHECK_PARSE_BOOL(AlignOperands); CHECK_PARSE_BOOL(AlignTrailingComments); + CHECK_PARSE_BOOL(AlignConsecutiveAssignments); CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine); CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine); CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine); @@ -8953,11 +9609,12 @@ TEST_F(FormatTest, UsesLanguageForBasedOnStyle) { Style.BreakBeforeTernaryOperators = true; EXPECT_EQ(0, parseConfiguration("---\n" - "BasedOnStyle: Google\n" - "---\n" - "Language: JavaScript\n" - "IndentWidth: 76\n" - "...\n", &Style).value()); + "BasedOnStyle: Google\n" + "---\n" + "Language: JavaScript\n" + "IndentWidth: 76\n" + "...\n", + &Style).value()); EXPECT_FALSE(Style.BreakBeforeTernaryOperators); EXPECT_EQ(76u, Style.IndentWidth); EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language); @@ -9001,8 +9658,7 @@ TEST_F(FormatTest, CountsUTF8CharactersProperly) { getLLVMStyleWithColumns(31)); verifyFormat("// Однажды в студёную зимнюю пору...", getLLVMStyleWithColumns(36)); - verifyFormat("// 一 二 三 四 五 六 七 八 九 十", - getLLVMStyleWithColumns(32)); + verifyFormat("// 一 二 三 四 五 六 七 八 九 十", getLLVMStyleWithColumns(32)); verifyFormat("/* Однажды в студёную зимнюю пору... */", getLLVMStyleWithColumns(39)); verifyFormat("/* 一 二 三 四 五 六 七 八 九 十 */", @@ -9020,19 +9676,18 @@ TEST_F(FormatTest, SplitsUTF8Strings) { EXPECT_EQ("\"aaaaaaaÄ\"\n" "\"\xc2\x8d\";", format("\"aaaaaaaÄ\xc2\x8d\";", getLLVMStyleWithColumns(10))); + EXPECT_EQ("\"Однажды, в \"\n" + "\"студёную \"\n" + "\"зимнюю \"\n" + "\"пору,\"", + format("\"Однажды, в студёную зимнюю пору,\"", + getLLVMStyleWithColumns(13))); EXPECT_EQ( - "\"Однажды, в \"\n" - "\"студёную \"\n" - "\"зимнюю \"\n" - "\"пору,\"", - format("\"Однажды, в студёную зимнюю пору,\"", - getLLVMStyleWithColumns(13))); - EXPECT_EQ("\"一 二 三 \"\n" - "\"四 五六 \"\n" - "\"七 八 九 \"\n" - "\"十\"", - format("\"一 二 三 四 五六 七 八 九 十\"", - getLLVMStyleWithColumns(11))); + "\"一 二 三 \"\n" + "\"四 五六 \"\n" + "\"七 八 九 \"\n" + "\"十\"", + format("\"一 二 三 四 五六 七 八 九 十\"", getLLVMStyleWithColumns(11))); EXPECT_EQ("\"一\t二 \"\n" "\"\t三 \"\n" "\"四 五\t六 \"\n" @@ -9042,7 +9697,6 @@ TEST_F(FormatTest, SplitsUTF8Strings) { getLLVMStyleWithColumns(11))); } - TEST_F(FormatTest, HandlesDoubleWidthCharsInMultiLineStrings) { EXPECT_EQ("const char *sssss =\n" " \"一二三四五六七八\\\n" @@ -9225,22 +9879,20 @@ TEST_F(FormatTest, FormatsWithWebKitStyle) { Style); // Wrap before binary operators. - EXPECT_EQ( - "void f()\n" - "{\n" - " if (aaaaaaaaaaaaaaaa\n" - " && bbbbbbbbbbbbbbbbbbbbbbbb\n" - " && (cccccccccccccccccccccccccc || dddddddddddddddddddd))\n" - " return;\n" - "}", - format( - "void f() {\n" - "if (aaaaaaaaaaaaaaaa\n" - "&& bbbbbbbbbbbbbbbbbbbbbbbb\n" - "&& (cccccccccccccccccccccccccc || dddddddddddddddddddd))\n" - "return;\n" - "}", - Style)); + EXPECT_EQ("void f()\n" + "{\n" + " if (aaaaaaaaaaaaaaaa\n" + " && bbbbbbbbbbbbbbbbbbbbbbbb\n" + " && (cccccccccccccccccccccccccc || dddddddddddddddddddd))\n" + " return;\n" + "}", + format("void f() {\n" + "if (aaaaaaaaaaaaaaaa\n" + "&& bbbbbbbbbbbbbbbbbbbbbbbb\n" + "&& (cccccccccccccccccccccccccc || dddddddddddddddddddd))\n" + "return;\n" + "}", + Style)); // Allow functions on a single line. verifyFormat("void f() { return; }", Style); @@ -9270,7 +9922,8 @@ TEST_F(FormatTest, FormatsWithWebKitStyle) { " , b(b)\n" " , c(c)\n" "{\n" - "}", Style); + "}", + Style); verifyFormat("SomeClass::Constructor()\n" " : a(a)\n" "{\n" @@ -9395,6 +10048,17 @@ TEST_F(FormatTest, FormatsLambdas) { " : Field([] { // comment\n" " int i;\n" " }) {}"); + verifyFormat("auto my_lambda = [](const string &some_parameter) {\n" + " return some_parameter.size();\n" + "};"); + verifyFormat("int i = aaaaaa ? 1 //\n" + " : [] {\n" + " return 2; //\n" + " }();"); + verifyFormat("llvm::errs() << \"number of twos is \"\n" + " << std::count_if(v.begin(), v.end(), [](int x) {\n" + " return x == 2; // force break\n" + " });"); // Lambdas with return types. verifyFormat("int c = []() -> int { return 2; }();\n"); @@ -9408,6 +10072,12 @@ TEST_F(FormatTest, FormatsLambdas) { " int j) -> int {\n" " return ffffffffffffffffffffffffffffffffffffffffffff(i * j);\n" "};"); + verifyFormat( + "aaaaaaaaaaaaaaaaaaaaaa(\n" + " [](aaaaaaaaaaaaaaaaaaaaaaaaaaa &aaa) -> aaaaaaaaaaaaaaaa {\n" + " return aaaaaaaaaaaaaaaaa;\n" + " });", + getLLVMStyleWithColumns(70)); // Multiple lambdas in the same parentheses change indentation rules. verifyFormat("SomeFunction(\n" @@ -9447,6 +10117,13 @@ TEST_F(FormatTest, FormatsLambdas) { " doo_dah();\n" " })) {\n" "}"); + verifyFormat("auto lambda = []() {\n" + " int a = 2\n" + "#if A\n" + " + 2\n" + "#endif\n" + " ;\n" + "};"); } TEST_F(FormatTest, FormatsBlocks) { @@ -9550,6 +10227,74 @@ TEST_F(FormatTest, FormatsBlocks) { FourIndent); } +TEST_F(FormatTest, FormatsBlocksWithZeroColumnWidth) { + FormatStyle ZeroColumn = getLLVMStyle(); + ZeroColumn.ColumnLimit = 0; + + verifyFormat("[[SessionService sharedService] " + "loadWindowWithCompletionBlock:^(SessionWindow *window) {\n" + " if (window) {\n" + " [self windowDidLoad:window];\n" + " } else {\n" + " [self errorLoadingWindow];\n" + " }\n" + "}];", + ZeroColumn); + EXPECT_EQ("[[SessionService sharedService]\n" + " loadWindowWithCompletionBlock:^(SessionWindow *window) {\n" + " if (window) {\n" + " [self windowDidLoad:window];\n" + " } else {\n" + " [self errorLoadingWindow];\n" + " }\n" + " }];", + format("[[SessionService sharedService]\n" + "loadWindowWithCompletionBlock:^(SessionWindow *window) {\n" + " if (window) {\n" + " [self windowDidLoad:window];\n" + " } else {\n" + " [self errorLoadingWindow];\n" + " }\n" + "}];", + ZeroColumn)); + verifyFormat("[myObject doSomethingWith:arg1\n" + " firstBlock:^(Foo *a) {\n" + " // ...\n" + " int i;\n" + " }\n" + " secondBlock:^(Bar *b) {\n" + " // ...\n" + " int i;\n" + " }\n" + " thirdBlock:^Foo(Bar *b) {\n" + " // ...\n" + " int i;\n" + " }];", + ZeroColumn); + verifyFormat("f(^{\n" + " @autoreleasepool {\n" + " if (a) {\n" + " g();\n" + " }\n" + " }\n" + "});", + ZeroColumn); + verifyFormat("void (^largeBlock)(void) = ^{\n" + " // ...\n" + "};", + ZeroColumn); + + ZeroColumn.AllowShortBlocksOnASingleLine = true; + EXPECT_EQ("void (^largeBlock)(void) = ^{ int i; };", + format("void (^largeBlock)(void) = ^{ int i; };", + ZeroColumn)); + ZeroColumn.AllowShortBlocksOnASingleLine = false; + EXPECT_EQ("void (^largeBlock)(void) = ^{\n" + " int i;\n" + "};", + format("void (^largeBlock)(void) = ^{ int i; };", ZeroColumn)); +} + TEST_F(FormatTest, SupportsCRLF) { EXPECT_EQ("int a;\r\n" "int b;\r\n" @@ -9646,6 +10391,27 @@ TEST_F(FormatTest, SpacesInAngles) { verifyFormat("A<A<int>>();", Spaces); } +TEST_F(FormatTest, TripleAngleBrackets) { + verifyFormat("f<<<1, 1>>>();"); + verifyFormat("f<<<1, 1, 1, s>>>();"); + verifyFormat("f<<<a, b, c, d>>>();"); + EXPECT_EQ("f<<<1, 1>>>();", format("f <<< 1, 1 >>> ();")); + verifyFormat("f<param><<<1, 1>>>();"); + verifyFormat("f<1><<<1, 1>>>();"); + EXPECT_EQ("f<param><<<1, 1>>>();", format("f< param > <<< 1, 1 >>> ();")); + verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaa<<<\n 1, 1>>>();"); +} + +TEST_F(FormatTest, MergeLessLessAtEnd) { + verifyFormat("<<"); + EXPECT_EQ("< < <", format("\\\n<<<")); + verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaallvm::outs() <<"); + verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaallvm::outs()\n <<"); +} + TEST_F(FormatTest, HandleUnbalancedImplicitBracesAcrossPPBranches) { std::string code = "#if A\n" "#if B\n" @@ -9775,9 +10541,7 @@ TEST_F(FormatTest, DisableRegions) { " int k;")); } -TEST_F(FormatTest, DoNotCrashOnInvalidInput) { - format("? ) ="); -} +TEST_F(FormatTest, DoNotCrashOnInvalidInput) { format("? ) ="); } } // end namespace tooling } // end namespace clang diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index 780b02f746e9..a06daac24ecf 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -82,6 +82,10 @@ TEST_F(FormatTestJS, UnderstandsJavaScriptOperators) { verifyFormat("var b = a.map((x) => x + 1);"); verifyFormat("return ('aaa') in bbbb;"); + + // ES6 spread operator. + verifyFormat("someFunction(...a);"); + verifyFormat("var x = [1, ...a, 2];"); } TEST_F(FormatTestJS, UnderstandsAmpAmp) { @@ -94,13 +98,11 @@ TEST_F(FormatTestJS, LiteralOperatorsCanBeKeywords) { TEST_F(FormatTestJS, ES6DestructuringAssignment) { verifyFormat("var [a, b, c] = [1, 2, 3];"); - verifyFormat("var {a, b} = {\n" - " a: 1,\n" - " b: 2\n" - "};"); + verifyFormat("var {a, b} = {a: 1, b: 2};"); } TEST_F(FormatTestJS, ContainerLiterals) { + verifyFormat("var x = {y: function(a) { return a; }};"); verifyFormat("return {\n" " link: function() {\n" " f(); //\n" @@ -139,6 +141,45 @@ TEST_F(FormatTestJS, ContainerLiterals) { " return x.zIsTooLongForOneLineWithTheDeclarationLine();\n" " }\n" "};"); + // Simple object literal, as opposed to enum style below. + verifyFormat("var obj = {a: 123};"); + // Enum style top level assignment. + verifyFormat("X = {\n a: 123\n};"); + verifyFormat("X.Y = {\n a: 123\n};"); + verifyFormat("x = foo && {a: 123};"); + + // Arrow functions in object literals. + verifyFormat("var x = {y: (a) => { return a; }};"); + verifyFormat("var x = {y: (a) => a};"); +} + +TEST_F(FormatTestJS, MethodsInObjectLiterals) { + verifyFormat("var o = {\n" + " value: 'test',\n" + " get value() { // getter\n" + " return this.value;\n" + " }\n" + "};"); + verifyFormat("var o = {\n" + " value: 'test',\n" + " set value(val) { // setter\n" + " this.value = val;\n" + " }\n" + "};"); + verifyFormat("var o = {\n" + " value: 'test',\n" + " someMethod(val) { // method\n" + " doSomething(this.value + val);\n" + " }\n" + "};"); + verifyFormat("var o = {\n" + " someMethod(val) { // method\n" + " doSomething(this.value + val);\n" + " },\n" + " someOtherMethod(val) { // method\n" + " doSomething(this.value + val);\n" + " }\n" + "};"); } TEST_F(FormatTestJS, SpacesInContainerLiterals) { @@ -164,6 +205,11 @@ TEST_F(FormatTestJS, GoogScopes) { "var x = a.b;\n" "var y = c.d;\n" "}); // goog.scope"); + verifyFormat("goog.scope(function() {\n" + "// test\n" + "var x = 0;\n" + "// test\n" + "});"); } TEST_F(FormatTestJS, GoogModules) { @@ -239,6 +285,12 @@ TEST_F(FormatTestJS, FunctionLiterals) { " return x.zIsTooLongForOneLineWithTheDeclarationLine();\n" " };\n" "}"); + verifyFormat("someLooooooooongFunction(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " function(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" + " // code\n" + " });"); verifyFormat("f({a: function() { return 1; }});", getGoogleJSStyleWithColumns(33)); @@ -371,10 +423,24 @@ TEST_F(FormatTestJS, MultipleFunctionLiterals) { " body();\n" " });"); - // FIXME: This is bad, but it used to be formatted correctly by accident. - verifyFormat("getSomeLongPromise().then(function(value) {\n" - " body();\n" - "}).thenCatch(function(error) { body(); });"); + verifyFormat("getSomeLongPromise()\n" + " .then(function(value) { body(); })\n" + " .thenCatch(function(error) { body(); });"); +} + +TEST_F(FormatTestJS, ArrowFunctions) { + verifyFormat("var x = (a) => {\n" + " return a;\n" + "};"); + verifyFormat("var x = (a) => {\n" + " function y() { return 42; }\n" + " return a;\n" + "};"); + verifyFormat("var x = (a: type): {some: type} => {\n" + " return a;\n" + "};"); + verifyFormat("var x = (a) => a;"); + verifyFormat("var x = (a) => a;"); } TEST_F(FormatTestJS, ReturnStatements) { @@ -383,7 +449,7 @@ TEST_F(FormatTestJS, ReturnStatements) { "}"); } -TEST_F(FormatTestJS, ClosureStyleComments) { +TEST_F(FormatTestJS, ClosureStyleCasts) { verifyFormat("var x = /** @type {foo} */ (bar);"); } @@ -427,6 +493,7 @@ TEST_F(FormatTestJS, RegexLiteralClassification) { } TEST_F(FormatTestJS, RegexLiteralSpecialCharacters) { + verifyFormat("var regex = /=/;"); verifyFormat("var regex = /a*/;"); verifyFormat("var regex = /a+/;"); verifyFormat("var regex = /a?/;"); @@ -490,5 +557,214 @@ TEST_F(FormatTestJS, RegexLiteralExamples) { verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);"); } +TEST_F(FormatTestJS, TypeAnnotations) { + verifyFormat("var x: string;"); + verifyFormat("function x(): string {\n return 'x';\n}"); + verifyFormat("function x(): {x: string} {\n return {x: 'x'};\n}"); + verifyFormat("function x(y: string): string {\n return 'x';\n}"); + verifyFormat("for (var y: string in x) {\n x();\n}"); + verifyFormat("((a: string, b: number): string => a + b);"); + verifyFormat("var x: (y: number) => string;"); + verifyFormat("var x: P<string, (a: number) => string>;"); + verifyFormat("var x = {y: function(): z { return 1; }};"); + verifyFormat("var x = {y: function(): {a: number} { return 1; }};"); +} + +TEST_F(FormatTestJS, ClassDeclarations) { + verifyFormat("class C {\n x: string = 12;\n}"); + verifyFormat("class C {\n x(): string => 12;\n}"); + verifyFormat("class C {\n ['x' + 2]: string = 12;\n}"); + verifyFormat("class C {\n private x: string = 12;\n}"); + verifyFormat("class C {\n private static x: string = 12;\n}"); + verifyFormat("class C {\n static x(): string { return 'asd'; }\n}"); + verifyFormat("class C extends P implements I {}"); + verifyFormat("class C extends p.P implements i.I {}"); +} + +TEST_F(FormatTestJS, InterfaceDeclarations) { + verifyFormat("interface I {\n" + " x: string;\n" + "}"); +} + +TEST_F(FormatTestJS, MetadataAnnotations) { + verifyFormat("@A\nclass C {\n}"); + verifyFormat("@A({arg: 'value'})\nclass C {\n}"); + verifyFormat("@A\n@B\nclass C {\n}"); + verifyFormat("class C {\n @A x: string;\n}"); + verifyFormat("class C {\n" + " @A\n" + " private x(): string {\n" + " return 'y';\n" + " }\n" + "}"); + verifyFormat("class X {}\n" + "class Y {}"); +} + +TEST_F(FormatTestJS, Modules) { + verifyFormat("import SomeThing from 'some/module.js';"); + verifyFormat("import {X, Y} from 'some/module.js';"); + verifyFormat("import {\n" + " VeryLongImportsAreAnnoying,\n" + " VeryLongImportsAreAnnoying,\n" + " VeryLongImportsAreAnnoying,\n" + " VeryLongImportsAreAnnoying\n" + "} from 'some/module.js';"); + verifyFormat("import {\n" + " X,\n" + " Y,\n" + "} from 'some/module.js';"); + verifyFormat("import {\n" + " X,\n" + " Y,\n" + "} from 'some/long/module.js';", + getGoogleJSStyleWithColumns(20)); + verifyFormat("import {X as myLocalX, Y as myLocalY} from 'some/module.js';"); + verifyFormat("import * as lib from 'some/module.js';"); + verifyFormat("var x = {import: 1};\nx.import = 2;"); + + verifyFormat("export function fn() {\n" + " return 'fn';\n" + "}"); + verifyFormat("export function A() {\n" + "}\n" + "export default function B() {\n" + "}\n" + "export function C() {\n" + "}"); + verifyFormat("export const x = 12;"); + verifyFormat("export default class X {}"); + verifyFormat("export {X, Y} from 'some/module.js';"); + verifyFormat("export {\n" + " X,\n" + " Y,\n" + "} from 'some/module.js';"); + verifyFormat("export class C {\n" + " x: number;\n" + " y: string;\n" + "}"); + verifyFormat("export class X { y: number; }"); + verifyFormat("export default class X { y: number }"); + verifyFormat("export default function() {\n return 1;\n}"); + verifyFormat("export var x = 12;"); + verifyFormat("export var x: number = 12;"); + verifyFormat("export const y = {\n" + " a: 1,\n" + " b: 2\n" + "};"); +} + +TEST_F(FormatTestJS, TemplateStrings) { + // Keeps any whitespace/indentation within the template string. + EXPECT_EQ("var x = `hello\n" + " ${ name }\n" + " !`;", + format("var x = `hello\n" + " ${ name }\n" + " !`;")); + + // FIXME: +1 / -1 offsets are to work around clang-format miscalculating + // widths for unknown tokens that are not whitespace (e.g. '`'). Remove when + // the code is corrected. + + verifyFormat("var x =\n" + " `hello ${world}` >= some();", + getGoogleJSStyleWithColumns(34)); // Barely doesn't fit. + verifyFormat("var x = `hello ${world}` >= some();", + getGoogleJSStyleWithColumns(35 + 1)); // Barely fits. + EXPECT_EQ("var x = `hello\n" + " ${world}` >=\n" + " some();", + format("var x =\n" + " `hello\n" + " ${world}` >= some();", + getGoogleJSStyleWithColumns(21))); // Barely doesn't fit. + EXPECT_EQ("var x = `hello\n" + " ${world}` >= some();", + format("var x =\n" + " `hello\n" + " ${world}` >= some();", + getGoogleJSStyleWithColumns(22))); // Barely fits. + + verifyFormat("var x =\n `h`;", getGoogleJSStyleWithColumns(13 - 1)); + EXPECT_EQ( + "var x =\n `multi\n line`;", + format("var x = `multi\n line`;", getGoogleJSStyleWithColumns(14 - 1))); + + // Make sure template strings get a proper ColumnWidth assigned, even if they + // are first token in line. + verifyFormat( + "var a = aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" + " `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`;"); + + // Two template strings. + verifyFormat("var x = `hello` == `hello`;"); + + // Comments in template strings. + EXPECT_EQ("var x = `//a`;\n" + "var y;", + format("var x =\n `//a`;\n" + "var y ;")); + EXPECT_EQ("var x = `/*a`;\n" + "var y;", + format("var x =\n `/*a`;\n" + "var y;")); + // Backticks in a comment - not a template string. + EXPECT_EQ("var x = 1 // `/*a`;\n" + " ;", + format("var x =\n 1 // `/*a`;\n" + " ;")); + EXPECT_EQ("/* ` */ var x = 1; /* ` */", + format("/* ` */ var x\n= 1; /* ` */")); + // Comment spans multiple template strings. + EXPECT_EQ("var x = `/*a`;\n" + "var y = ` */ `;", + format("var x =\n `/*a`;\n" + "var y =\n ` */ `;")); + // Escaped backtick. + EXPECT_EQ("var x = ` \\` a`;\n" + "var y;", + format("var x = ` \\` a`;\n" + "var y;")); +} + +TEST_F(FormatTestJS, CastSyntax) { + verifyFormat("var x = <type>foo;"); +} + +TEST_F(FormatTestJS, TypeArguments) { + verifyFormat("class X<Y> {}"); + verifyFormat("new X<Y>();"); + verifyFormat("foo<Y>(a);"); + verifyFormat("var x: X<Y>[];"); + verifyFormat("class C extends D<E> implements F<G>, H<I> {}"); + verifyFormat("function f(a: List<any> = null) {\n}"); + verifyFormat("function f(): List<any> {\n}"); +} + +TEST_F(FormatTestJS, OptionalTypes) { + verifyFormat("function x(a?: b, c?, d?) {\n}"); + verifyFormat("class X {\n" + " y?: z;\n" + " z?;\n" + "}"); + verifyFormat("interface X {\n" + " y?(): z;\n" + "}"); + verifyFormat("x ? 1 : 2;"); + verifyFormat("constructor({aa}: {\n" + " aa?: string,\n" + " aaaaaaaa?: string,\n" + " aaaaaaaaaaaaaaa?: boolean,\n" + " aaaaaa?: List<string>\n" + "}) {\n" + "}"); +} + +TEST_F(FormatTestJS, IndexSignature) { + verifyFormat("var x: {[k: string]: v};"); +} + } // end namespace tooling } // end namespace clang diff --git a/unittests/Format/FormatTestJava.cpp b/unittests/Format/FormatTestJava.cpp index 8d6daa62a599..631a3dca27e7 100644 --- a/unittests/Format/FormatTestJava.cpp +++ b/unittests/Format/FormatTestJava.cpp @@ -153,6 +153,19 @@ TEST_F(FormatTestJava, ClassDeclarations) { "}"); } +TEST_F(FormatTestJava, AnonymousClasses) { + verifyFormat("return new A() {\n" + " public String toString() {\n" + " return \"NotReallyA\";\n" + " }\n" + "};"); + verifyFormat("A a = new A() {\n" + " public String toString() {\n" + " return \"NotReallyA\";\n" + " }\n" + "};"); +} + TEST_F(FormatTestJava, EnumDeclarations) { verifyFormat("enum SomeThing { ABC, CDE }"); verifyFormat("enum SomeThing {\n" @@ -420,7 +433,7 @@ TEST_F(FormatTestJava, NeverAlignAfterReturn) { getStyleWithColumns(40)); verifyFormat("return aaaaaaaaaaaaaaaaaaa()\n" " .bbbbbbbbbbbbbbbbbbb(\n" - " ccccccccccccccc)\n" + " ccccccccccccccc)\n" " .ccccccccccccccccccc();", getStyleWithColumns(40)); } diff --git a/unittests/Format/FormatTestProto.cpp b/unittests/Format/FormatTestProto.cpp index 3a2f97e875d1..ac8fcbdda4fc 100644 --- a/unittests/Format/FormatTestProto.cpp +++ b/unittests/Format/FormatTestProto.cpp @@ -94,12 +94,25 @@ TEST_F(FormatTestProto, MessageFieldAttributes) { " bbbbbbbbbbbbbbbb: BBBBBBBBBB\n" "}];"); verifyFormat("repeated double value = 1 [(aaaaaaa.aaaaaaaaa) = {\n" + " type: \"AAAAAAAAAA\"\n" + " is: \"AAAAAAAAAA\"\n" + " or: \"BBBBBBBBBB\"\n" + "}];"); + verifyFormat("repeated double value = 1 [(aaaaaaa.aaaaaaaaa) = {\n" " aaaaaaaaaaaaaaaa: AAAAAAAAAA,\n" " bbbbbbb: BBBB,\n" " bbbb: BBB\n" "}];"); } +TEST_F(FormatTestProto, DoesntWrapFileOptions) { + EXPECT_EQ( + "option java_package = " + "\"some.really.long.package.that.exceeds.the.column.limit\";", + format("option java_package = " + "\"some.really.long.package.that.exceeds.the.column.limit\";")); +} + TEST_F(FormatTestProto, FormatsOptions) { verifyFormat("option (MyProto.options) = {\n" " field_a: OK\n" diff --git a/unittests/Frontend/FrontendActionTest.cpp b/unittests/Frontend/FrontendActionTest.cpp index 5581c4487ecc..90afd774f1ad 100644 --- a/unittests/Frontend/FrontendActionTest.cpp +++ b/unittests/Frontend/FrontendActionTest.cpp @@ -35,15 +35,16 @@ public: bool ActOnEndOfTranslationUnit; std::vector<std::string> decl_names; - virtual bool BeginSourceFileAction(CompilerInstance &ci, StringRef filename) { + bool BeginSourceFileAction(CompilerInstance &ci, + StringRef filename) override { if (EnableIncrementalProcessing) ci.getPreprocessor().enableIncrementalProcessing(); return ASTFrontendAction::BeginSourceFileAction(ci, filename); } - virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override { return llvm::make_unique<Visitor>(CI, ActOnEndOfTranslationUnit, decl_names); } @@ -56,7 +57,7 @@ private: CI(CI), ActOnEndOfTranslationUnit(ActOnEndOfTranslationUnit), decl_names_(decl_names) {} - virtual void HandleTranslationUnit(ASTContext &context) { + void HandleTranslationUnit(ASTContext &context) override { if (ActOnEndOfTranslationUnit) { CI.getSema().ActOnEndOfTranslationUnit(); } diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp index 85987bf00161..b5a39b303d00 100644 --- a/unittests/Lex/LexerTest.cpp +++ b/unittests/Lex/LexerTest.cpp @@ -37,8 +37,7 @@ class VoidModuleLoader : public ModuleLoader { void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, - SourceLocation ImportLoc, - bool Complain) override { } + SourceLocation ImportLoc) override { } GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override { return nullptr; } diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp index bb27bac6ed66..94812fc93de9 100644 --- a/unittests/Lex/PPCallbacksTest.cpp +++ b/unittests/Lex/PPCallbacksTest.cpp @@ -42,8 +42,7 @@ class VoidModuleLoader : public ModuleLoader { void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, - SourceLocation ImportLoc, - bool Complain) override { } + SourceLocation ImportLoc) override { } GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override { return nullptr; } @@ -54,15 +53,11 @@ class VoidModuleLoader : public ModuleLoader { // Stub to collect data from InclusionDirective callbacks. class InclusionDirectiveCallbacks : public PPCallbacks { public: - void InclusionDirective(SourceLocation HashLoc, - const Token &IncludeTok, - StringRef FileName, - bool IsAngled, - CharSourceRange FilenameRange, - const FileEntry *File, - StringRef SearchPath, - StringRef RelativePath, - const Module *Imported) { + void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, + StringRef FileName, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, + StringRef SearchPath, StringRef RelativePath, + const Module *Imported) override { this->HashLoc = HashLoc; this->IncludeTok = IncludeTok; this->FileName = FileName.str(); @@ -95,9 +90,10 @@ public: PragmaOpenCLExtensionCallbacks() : Name("Not called."), State(99) {}; - void PragmaOpenCLExtension( - clang::SourceLocation NameLoc, const clang::IdentifierInfo *Name, - clang::SourceLocation StateLoc, unsigned State) { + void PragmaOpenCLExtension(clang::SourceLocation NameLoc, + const clang::IdentifierInfo *Name, + clang::SourceLocation StateLoc, + unsigned State) override { this->NameLoc = NameLoc; this->Name = Name->getName(); this->StateLoc = StateLoc; diff --git a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp index 946cb88b9810..d2e364050105 100644 --- a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp +++ b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp @@ -61,8 +61,7 @@ class VoidModuleLoader : public ModuleLoader { void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, - SourceLocation ImportLoc, - bool Complain) override { } + SourceLocation ImportLoc) override { } GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override { return nullptr; } diff --git a/unittests/Makefile b/unittests/Makefile index 1e6a50835b05..2a0b5bc9dd40 100644 --- a/unittests/Makefile +++ b/unittests/Makefile @@ -15,12 +15,12 @@ ifndef CLANG_LEVEL IS_UNITTEST_LEVEL := 1 CLANG_LEVEL := .. PARALLEL_DIRS = CodeGen Basic Lex Driver Format ASTMatchers AST Tooling \ - Sema + Rewrite Sema include $(CLANG_LEVEL)/../..//Makefile.config ifeq ($(ENABLE_CLANG_ARCMT),1) -PARALLEL_DIRS += Frontend libclang +PARALLEL_DIRS += Frontend libclang StaticAnalyzer endif endif # CLANG_LEVEL diff --git a/unittests/Rewrite/CMakeLists.txt b/unittests/Rewrite/CMakeLists.txt new file mode 100644 index 000000000000..bee7ff6d5541 --- /dev/null +++ b/unittests/Rewrite/CMakeLists.txt @@ -0,0 +1,10 @@ +set(LLVM_LINK_COMPONENTS + Support + ) + +add_clang_unittest(RewriteTests + RewriteBufferTest.cpp + ) +target_link_libraries(RewriteTests + clangRewrite + ) diff --git a/unittests/Rewrite/Makefile b/unittests/Rewrite/Makefile new file mode 100644 index 000000000000..43538d560750 --- /dev/null +++ b/unittests/Rewrite/Makefile @@ -0,0 +1,16 @@ +##===- unittests/Rewrite/Makefile --------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +CLANG_LEVEL = ../.. +TESTNAME = Rewrite +include $(CLANG_LEVEL)/../../Makefile.config +LINK_COMPONENTS := $(TARGETS_TO_BUILD) support +USEDLIBS = clangRewrite.a clangLex.a clangBasic.a + +include $(CLANG_LEVEL)/unittests/Makefile diff --git a/unittests/Rewrite/RewriteBufferTest.cpp b/unittests/Rewrite/RewriteBufferTest.cpp new file mode 100644 index 000000000000..e3b7d1fb8897 --- /dev/null +++ b/unittests/Rewrite/RewriteBufferTest.cpp @@ -0,0 +1,51 @@ +//===- unittests/Rewrite/RewriteBufferTest.cpp - RewriteBuffer tests ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Rewrite/Core/RewriteBuffer.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace clang; + +namespace { + +static void tagRange(unsigned Offset, unsigned Len, StringRef tagName, + RewriteBuffer &Buf) { + std::string BeginTag; + raw_string_ostream(BeginTag) << '<' << tagName << '>'; + std::string EndTag; + raw_string_ostream(EndTag) << "</" << tagName << '>'; + + Buf.InsertTextAfter(Offset, BeginTag); + Buf.InsertTextBefore(Offset+Len, EndTag); +} + +TEST(RewriteBuffer, TagRanges) { + StringRef Input = "hello world"; + const char *Output = "<outer><inner>hello</inner></outer> "; + + RewriteBuffer Buf; + Buf.Initialize(Input); + StringRef RemoveStr = "world"; + size_t Pos = Input.find(RemoveStr); + Buf.RemoveText(Pos, RemoveStr.size()); + + StringRef TagStr = "hello"; + Pos = Input.find(TagStr); + tagRange(Pos, TagStr.size(), "outer", Buf); + tagRange(Pos, TagStr.size(), "inner", Buf); + + std::string Result; + raw_string_ostream OS(Result); + Buf.write(OS); + OS.flush(); + EXPECT_EQ(Output, Result); +} + +} // anonymous namespace diff --git a/unittests/Sema/ExternalSemaSourceTest.cpp b/unittests/Sema/ExternalSemaSourceTest.cpp index 3a93fc77fb19..703e97b4ac95 100644 --- a/unittests/Sema/ExternalSemaSourceTest.cpp +++ b/unittests/Sema/ExternalSemaSourceTest.cpp @@ -30,7 +30,7 @@ class CompleteTypeDiagnoser : public clang::ExternalSemaSource { public: CompleteTypeDiagnoser(bool MockResult) : CallCount(0), Result(MockResult) {} - virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation L, QualType T) { + bool MaybeDiagnoseMissingCompleteType(SourceLocation L, QualType T) override { ++CallCount; return Result; } @@ -54,8 +54,8 @@ public: ToNS.append("'"); } - virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, - const Diagnostic &Info) { + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) override { if (Chained) Chained->HandleDiagnostic(DiagLevel, Info); if (Info.getID() - 1 == diag::err_using_directive_member_suggest) { @@ -66,13 +66,13 @@ public: } } - virtual void clear() { + void clear() override { DiagnosticConsumer::clear(); if (Chained) Chained->clear(); } - virtual bool IncludeInDiagnosticCounts() const { + bool IncludeInDiagnosticCounts() const override { if (Chained) return Chained->IncludeInDiagnosticCounts(); return false; @@ -97,16 +97,15 @@ public: NamespaceTypoProvider(StringRef From, StringRef To) : CorrectFrom(From), CorrectTo(To), CurrentSema(nullptr), CallCount(0) {} - virtual void InitializeSema(Sema &S) { CurrentSema = &S; } + void InitializeSema(Sema &S) override { CurrentSema = &S; } - virtual void ForgetSema() { CurrentSema = nullptr; } + void ForgetSema() override { CurrentSema = nullptr; } - virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, - int LookupKind, Scope *S, CXXScopeSpec *SS, - CorrectionCandidateCallback &CCC, - DeclContext *MemberContext, - bool EnteringContext, - const ObjCObjectPointerType *OPT) { + TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, int LookupKind, + Scope *S, CXXScopeSpec *SS, + CorrectionCandidateCallback &CCC, + DeclContext *MemberContext, bool EnteringContext, + const ObjCObjectPointerType *OPT) override { ++CallCount; if (CurrentSema && Typo.getName().getAsString() == CorrectFrom) { DeclContext *DestContext = nullptr; @@ -140,13 +139,13 @@ class ExternalSemaSourceInstaller : public clang::ASTFrontendAction { std::unique_ptr<DiagnosticConsumer> OwnedClient; protected: - virtual std::unique_ptr<clang::ASTConsumer> + std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &Compiler, - llvm::StringRef /* dummy */) { + llvm::StringRef /* dummy */) override { return llvm::make_unique<clang::ASTConsumer>(); } - virtual void ExecuteAction() { + void ExecuteAction() override { CompilerInstance &CI = getCompilerInstance(); ASSERT_FALSE(CI.hasSema()); CI.createSema(getTranslationUnitKind(), nullptr); diff --git a/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp b/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp new file mode 100644 index 000000000000..33f1740bea8a --- /dev/null +++ b/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp @@ -0,0 +1,74 @@ +//===- unittest/Analysis/AnalyzerOptionsTest.cpp - SA Options test --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "gtest/gtest.h" + +namespace clang { +namespace ento { + +TEST(StaticAnalyzerOptions, SearchInParentPackageTests) { + AnalyzerOptions Opts; + Opts.Config["Outer.Inner.CheckerOne:Option"] = "true"; + Opts.Config["Outer.Inner:Option"] = "false"; + Opts.Config["Outer.Inner:Option2"] = "true"; + Opts.Config["Outer:Option2"] = "false"; + + struct CheckerOneMock : CheckerBase { + StringRef getTagDescription() const override { + return "Outer.Inner.CheckerOne"; + } + }; + struct CheckerTwoMock : CheckerBase { + StringRef getTagDescription() const override { + return "Outer.Inner.CheckerTwo"; + } + }; + + // Checker one has Option specified as true. It should read true regardless of + // search mode. + CheckerOneMock CheckerOne; + EXPECT_TRUE(Opts.getBooleanOption("Option", false, &CheckerOne)); + // The package option is overriden with a checker option. + EXPECT_TRUE(Opts.getBooleanOption("Option", false, &CheckerOne, true)); + // The Outer package option is overriden by the Inner package option. No + // package option is specified. + EXPECT_TRUE(Opts.getBooleanOption("Option2", false, &CheckerOne, true)); + // No package option is specified and search in packages is turned off. The + // default value should be returned. + EXPECT_FALSE(Opts.getBooleanOption("Option2", false, &CheckerOne)); + EXPECT_TRUE(Opts.getBooleanOption("Option2", true, &CheckerOne)); + + // Checker true has no option specified. It should get the default value when + // search in parents turned off and false when search in parents turned on. + CheckerTwoMock CheckerTwo; + EXPECT_FALSE(Opts.getBooleanOption("Option", false, &CheckerTwo)); + EXPECT_TRUE(Opts.getBooleanOption("Option", true, &CheckerTwo)); + EXPECT_FALSE(Opts.getBooleanOption("Option", true, &CheckerTwo, true)); +} + +TEST(StaticAnalyzerOptions, StringOptions) { + AnalyzerOptions Opts; + Opts.Config["Outer.Inner.CheckerOne:Option"] = "StringValue"; + + struct CheckerOneMock : CheckerBase { + StringRef getTagDescription() const override { + return "Outer.Inner.CheckerOne"; + } + }; + + CheckerOneMock CheckerOne; + EXPECT_TRUE("StringValue" == + Opts.getOptionAsString("Option", "DefaultValue", &CheckerOne)); + EXPECT_TRUE("DefaultValue" == + Opts.getOptionAsString("Option2", "DefaultValue", &CheckerOne)); +} +} // end namespace ento +} // end namespace clang diff --git a/unittests/StaticAnalyzer/CMakeLists.txt b/unittests/StaticAnalyzer/CMakeLists.txt new file mode 100644 index 000000000000..4aa5efba77a2 --- /dev/null +++ b/unittests/StaticAnalyzer/CMakeLists.txt @@ -0,0 +1,13 @@ +set(LLVM_LINK_COMPONENTS + Support + ) + +add_clang_unittest(StaticAnalysisTests + AnalyzerOptionsTest.cpp + ) + +target_link_libraries(StaticAnalysisTests + clangBasic + clangAnalysis + clangStaticAnalyzerCore + ) diff --git a/unittests/StaticAnalyzer/Makefile b/unittests/StaticAnalyzer/Makefile new file mode 100644 index 000000000000..af85b711e5b3 --- /dev/null +++ b/unittests/StaticAnalyzer/Makefile @@ -0,0 +1,15 @@ +##===- unittests/Basic/Makefile ----------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +CLANG_LEVEL = ../.. +TESTNAME = StaticAnalysis +LINK_COMPONENTS := support mc +USEDLIBS = clangBasic.a clangAnalysis.a clangStaticAnalyzerCore.a + +include $(CLANG_LEVEL)/unittests/Makefile diff --git a/unittests/Tooling/CommentHandlerTest.cpp b/unittests/Tooling/CommentHandlerTest.cpp index 117dfc36febe..da5604524cda 100644 --- a/unittests/Tooling/CommentHandlerTest.cpp +++ b/unittests/Tooling/CommentHandlerTest.cpp @@ -30,11 +30,11 @@ class CommentHandlerVisitor : public TestVisitor<CommentHandlerVisitor>, public: CommentHandlerVisitor() : base(), PP(nullptr), Verified(false) {} - ~CommentHandlerVisitor() { + ~CommentHandlerVisitor() override { EXPECT_TRUE(Verified) << "CommentVerifier not accessed"; } - virtual bool HandleComment(Preprocessor &PP, SourceRange Loc) { + bool HandleComment(Preprocessor &PP, SourceRange Loc) override { assert(&PP == this->PP && "Preprocessor changed!"); SourceLocation Start = Loc.getBegin(); @@ -56,7 +56,7 @@ public: CommentVerifier GetVerifier(); protected: - virtual ASTFrontendAction* CreateTestAction() { + ASTFrontendAction *CreateTestAction() override { return new CommentHandlerAction(this); } @@ -70,8 +70,8 @@ private: CommentHandlerAction(CommentHandlerVisitor *Visitor) : TestAction(Visitor) { } - virtual bool BeginSourceFileAction(CompilerInstance &CI, - StringRef FileName) { + bool BeginSourceFileAction(CompilerInstance &CI, + StringRef FileName) override { CommentHandlerVisitor *V = static_cast<CommentHandlerVisitor*>(this->Visitor); V->PP = &CI.getPreprocessor(); @@ -79,7 +79,7 @@ private: return true; } - virtual void EndSourceFileAction() { + void EndSourceFileAction() override { CommentHandlerVisitor *V = static_cast<CommentHandlerVisitor*>(this->Visitor); V->PP->removeCommentHandler(V); diff --git a/unittests/Tooling/CompilationDatabaseTest.cpp b/unittests/Tooling/CompilationDatabaseTest.cpp index 8866e751fcfe..3e5a589caf17 100644 --- a/unittests/Tooling/CompilationDatabaseTest.cpp +++ b/unittests/Tooling/CompilationDatabaseTest.cpp @@ -127,8 +127,8 @@ static CompileCommand findCompileArgsInJsonDatabase(StringRef FileName, } struct FakeComparator : public PathComparator { - virtual ~FakeComparator() {} - virtual bool equivalent(StringRef FileA, StringRef FileB) const { + ~FakeComparator() override {} + bool equivalent(StringRef FileA, StringRef FileB) const override { return FileA.equals_lower(FileB); } }; diff --git a/unittests/Tooling/RefactoringTest.cpp b/unittests/Tooling/RefactoringTest.cpp index a026a942610b..7e643fa66d9b 100644 --- a/unittests/Tooling/RefactoringTest.cpp +++ b/unittests/Tooling/RefactoringTest.cpp @@ -213,7 +213,7 @@ class FlushRewrittenFilesTest : public ::testing::Test { public: FlushRewrittenFilesTest() {} - ~FlushRewrittenFilesTest() { + ~FlushRewrittenFilesTest() override { for (llvm::StringMap<std::string>::iterator I = TemporaryFiles.begin(), E = TemporaryFiles.end(); I != E; ++I) { @@ -287,7 +287,7 @@ private: public: FindConsumer(TestVisitor *Visitor) : Visitor(Visitor) {} - virtual void HandleTranslationUnit(clang::ASTContext &Context) { + void HandleTranslationUnit(clang::ASTContext &Context) override { Visitor->TraverseDecl(Context.getTranslationUnitDecl()); } @@ -299,9 +299,9 @@ private: public: TestAction(TestVisitor *Visitor) : Visitor(Visitor) {} - virtual std::unique_ptr<clang::ASTConsumer> + std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &compiler, - llvm::StringRef dummy) { + llvm::StringRef dummy) override { Visitor->SM = &compiler.getSourceManager(); /// TestConsumer will be deleted by the framework calling us. return llvm::make_unique<FindConsumer>(Visitor); diff --git a/unittests/Tooling/TestVisitor.h b/unittests/Tooling/TestVisitor.h index d4416950f226..f4a00394487b 100644 --- a/unittests/Tooling/TestVisitor.h +++ b/unittests/Tooling/TestVisitor.h @@ -82,7 +82,7 @@ protected: public: FindConsumer(TestVisitor *Visitor) : Visitor(Visitor) {} - virtual void HandleTranslationUnit(clang::ASTContext &Context) { + void HandleTranslationUnit(clang::ASTContext &Context) override { Visitor->Context = &Context; Visitor->TraverseDecl(Context.getTranslationUnitDecl()); } @@ -95,8 +95,8 @@ protected: public: TestAction(TestVisitor *Visitor) : Visitor(Visitor) {} - virtual std::unique_ptr<clang::ASTConsumer> - CreateASTConsumer(CompilerInstance &, llvm::StringRef dummy) { + std::unique_ptr<clang::ASTConsumer> + CreateASTConsumer(CompilerInstance &, llvm::StringRef dummy) override { /// TestConsumer will be deleted by the framework calling us. return llvm::make_unique<FindConsumer>(Visitor); } @@ -133,7 +133,7 @@ public: } /// \brief Checks that all expected matches have been found. - virtual ~ExpectedLocationVisitor() { + ~ExpectedLocationVisitor() override { for (typename std::vector<ExpectedMatch>::const_iterator It = ExpectedMatches.begin(), End = ExpectedMatches.end(); It != End; ++It) { diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp index 5a93e38c80c2..4b14ebb2c300 100644 --- a/unittests/Tooling/ToolingTest.cpp +++ b/unittests/Tooling/ToolingTest.cpp @@ -35,8 +35,9 @@ public: : TestConsumer(std::move(TestConsumer)) {} protected: - virtual std::unique_ptr<clang::ASTConsumer> - CreateASTConsumer(clang::CompilerInstance &compiler, StringRef dummy) { + std::unique_ptr<clang::ASTConsumer> + CreateASTConsumer(clang::CompilerInstance &compiler, + StringRef dummy) override { /// TestConsumer will be deleted by the framework calling us. return std::move(TestConsumer); } @@ -49,7 +50,7 @@ class FindTopLevelDeclConsumer : public clang::ASTConsumer { public: explicit FindTopLevelDeclConsumer(bool *FoundTopLevelDecl) : FoundTopLevelDecl(FoundTopLevelDecl) {} - virtual bool HandleTopLevelDecl(clang::DeclGroupRef DeclGroup) { + bool HandleTopLevelDecl(clang::DeclGroupRef DeclGroup) override { *FoundTopLevelDecl = true; return true; } @@ -72,7 +73,7 @@ class FindClassDeclXConsumer : public clang::ASTConsumer { public: FindClassDeclXConsumer(bool *FoundClassDeclX) : FoundClassDeclX(FoundClassDeclX) {} - virtual bool HandleTopLevelDecl(clang::DeclGroupRef GroupRef) { + bool HandleTopLevelDecl(clang::DeclGroupRef GroupRef) override { if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>( *GroupRef.begin())) { if (Record->getName() == "X") { @@ -184,14 +185,11 @@ TEST(ToolInvocation, TestVirtualModulesCompilation) { struct VerifyEndCallback : public SourceFileCallbacks { VerifyEndCallback() : BeginCalled(0), EndCalled(0), Matched(false) {} - virtual bool handleBeginSource(CompilerInstance &CI, - StringRef Filename) override { + bool handleBeginSource(CompilerInstance &CI, StringRef Filename) override { ++BeginCalled; return true; } - virtual void handleEndSource() override { - ++EndCalled; - } + void handleEndSource() override { ++EndCalled; } std::unique_ptr<ASTConsumer> newASTConsumer() { return llvm::make_unique<FindTopLevelDeclConsumer>(&Matched); } @@ -225,15 +223,15 @@ TEST(newFrontendActionFactory, InjectsSourceFileCallbacks) { struct SkipBodyConsumer : public clang::ASTConsumer { /// Skip the 'skipMe' function. - virtual bool shouldSkipFunctionBody(Decl *D) { + bool shouldSkipFunctionBody(Decl *D) override { FunctionDecl *F = dyn_cast<FunctionDecl>(D); return F && F->getNameAsString() == "skipMe"; } }; struct SkipBodyAction : public clang::ASTFrontendAction { - virtual std::unique_ptr<ASTConsumer> - CreateASTConsumer(CompilerInstance &Compiler, StringRef) { + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler, + StringRef) override { Compiler.getFrontendOpts().SkipFunctionBodies = true; return llvm::make_unique<SkipBodyConsumer>(); } @@ -312,8 +310,8 @@ TEST(ClangToolTest, BuildASTs) { struct TestDiagnosticConsumer : public DiagnosticConsumer { TestDiagnosticConsumer() : NumDiagnosticsSeen(0) {} - virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, - const Diagnostic &Info) { + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) override { ++NumDiagnosticsSeen; } unsigned NumDiagnosticsSeen; diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp index a21881429e62..e827ebc0da86 100644 --- a/unittests/libclang/LibclangTest.cpp +++ b/unittests/libclang/LibclangTest.cpp @@ -357,7 +357,7 @@ public: CXTranslationUnit ClangTU; unsigned TUFlags; - void SetUp() { + void SetUp() override { llvm::SmallString<256> Dir; ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("libclang-test", Dir)); TestDir = Dir.str(); @@ -365,7 +365,7 @@ public: clang_defaultEditingTranslationUnitOptions(); Index = clang_createIndex(0, 0); } - void TearDown() { + void TearDown() override { clang_disposeTranslationUnit(ClangTU); clang_disposeIndex(Index); for (const std::string &Path : Files) |