From a1753f4be12737f36ce9c6eccccddd3be1ec514b Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Fri, 28 Jun 2013 12:51:24 +0000 Subject: [PATCH] Use lexing mode based on FormatStyle.Standard. Summary: Some valid pre-C++11 constructs change meaning when lexed in C++11 mode, e.g. #define x(_a) printf("foo"_a); (example from http://llvm.org/bugs/show_bug.cgi?id=16342). "foo"_a is treated as a user-defined string literal when parsed in C++11 mode. In order to deal with this correctly, we need to set lexing mode according to which standard the code conforms to. We already have a configuration value for this (FormatStyle.Standard), which seems to be appropriate to use in this case as well. Reviewers: klimek CC: cfe-commits, gribozavr Differential Revision: http://llvm-reviews.chandlerc.com/D1028 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185149 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Format/Format.h | 6 +++++- lib/Format/Format.cpp | 7 ++++--- tools/clang-format/ClangFormat.cpp | 7 ++++--- unittests/Format/FormatTest.cpp | 30 ++++++++++++++++++------------ 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index 24eeb76d06..d03b8796fe 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -218,7 +218,11 @@ tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, StringRef FileName = ""); /// \brief Returns the \c LangOpts that the formatter expects you to set. -LangOptions getFormattingLangOpts(); +/// +/// \param Standard determines lexing mode: LC_Cpp11 and LS_Auto turn on C++11 +/// lexing mode, LS_Cpp03 - C++03 mode. +LangOptions getFormattingLangOpts(FormatStyle::LanguageStandard Standard = + FormatStyle::LS_Cpp11); } // end namespace format } // end namespace clang diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 766be71bbd..7d6bc14241 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -1660,7 +1660,8 @@ tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, SourceMgr.overrideFileContents(Entry, Buf); FileID ID = SourceMgr.createFileID(Entry, SourceLocation(), clang::SrcMgr::C_User); - Lexer Lex(ID, SourceMgr.getBuffer(ID), SourceMgr, getFormattingLangOpts()); + Lexer Lex(ID, SourceMgr.getBuffer(ID), SourceMgr, + getFormattingLangOpts(Style.Standard)); SourceLocation StartOfFile = SourceMgr.getLocForStartOfFile(ID); std::vector CharRanges; for (unsigned i = 0, e = Ranges.size(); i != e; ++i) { @@ -1671,10 +1672,10 @@ tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, return reformat(Style, Lex, SourceMgr, CharRanges); } -LangOptions getFormattingLangOpts() { +LangOptions getFormattingLangOpts(FormatStyle::LanguageStandard Standard) { LangOptions LangOpts; LangOpts.CPlusPlus = 1; - LangOpts.CPlusPlus11 = 1; + LangOpts.CPlusPlus11 = Standard == FormatStyle::LS_Cpp03 ? 0 : 1; LangOpts.LineComment = 1; LangOpts.Bool = 1; LangOpts.ObjC1 = 1; diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp index 764200308d..33b7be9f1e 100644 --- a/tools/clang-format/ClangFormat.cpp +++ b/tools/clang-format/ClangFormat.cpp @@ -163,7 +163,6 @@ static bool format(std::string FileName) { return true; } FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files); - Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts()); if (Offsets.empty()) Offsets.push_back(0); if (Offsets.size() != Lengths.size() && @@ -195,8 +194,10 @@ static bool format(std::string FileName) { } Ranges.push_back(CharSourceRange::getCharRange(Start, End)); } - tooling::Replacements Replaces = - reformat(getStyle(Style, FileName), Lex, Sources, Ranges); + FormatStyle FormatStyle = getStyle(Style, FileName); + Lexer Lex(ID, Sources.getBuffer(ID), Sources, + getFormattingLangOpts(FormatStyle.Standard)); + tooling::Replacements Replaces = reformat(FormatStyle, Lex, Sources, Ranges); if (OutputXML) { llvm::outs() << "\n\n"; diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 909932e7c4..682aa52223 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -3097,9 +3097,9 @@ TEST_F(FormatTest, UnderstandsUnaryOperators) { verifyFormat("a-- > b;"); verifyFormat("b ? -a : c;"); verifyFormat("n * sizeof char16;"); - verifyFormat("n * alignof char16;"); + verifyFormat("n * alignof char16;", getGoogleStyle()); verifyFormat("sizeof(char);"); - verifyFormat("alignof(char);"); + verifyFormat("alignof(char);", getGoogleStyle()); verifyFormat("return -1;"); verifyFormat("switch (a) {\n" @@ -3374,7 +3374,7 @@ TEST_F(FormatTest, FormatsCasts) { verifyFormat("void f(int i = (kValue) * kMask) {}"); verifyFormat("void f(int i = (kA * kB) & kMask) {}"); verifyFormat("int a = sizeof(int) * b;"); - verifyFormat("int a = alignof(int) * b;"); + verifyFormat("int a = alignof(int) * b;", getGoogleStyle()); verifyFormat("template <> void f(int i) SOME_ANNOTATION;"); verifyFormat("f(\"%\" SOME_MACRO(ll) \"d\");"); @@ -3383,7 +3383,7 @@ TEST_F(FormatTest, FormatsCasts) { verifyFormat("virtual void foo(char &) const;"); verifyFormat("virtual void foo(int *a, char *) const;"); verifyFormat("int a = sizeof(int *) + b;"); - verifyFormat("int a = alignof(int *) + b;"); + verifyFormat("int a = alignof(int *) + b;", getGoogleStyle()); } TEST_F(FormatTest, FormatsFunctionTypes) { @@ -4250,7 +4250,7 @@ TEST_F(FormatTest, FormatObjCMethodExpr) { verifyFormat("int a = ++[foo bar:baz];"); verifyFormat("int a = --[foo bar:baz];"); verifyFormat("int a = sizeof [foo bar:baz];"); - verifyFormat("int a = alignof [foo bar:baz];"); + verifyFormat("int a = alignof [foo bar:baz];", getGoogleStyle()); verifyFormat("int a = &[foo bar:baz];"); verifyFormat("int a = *[foo bar:baz];"); // FIXME: Make casts work, without breaking f()[4]. @@ -4689,16 +4689,22 @@ TEST_F(FormatTest, BreakStringLiterals) { } TEST_F(FormatTest, SkipsUnknownStringLiterals) { - EXPECT_EQ("u8\"unsupported literal\";", - format("u8\"unsupported literal\";", getLLVMStyleWithColumns(15))); + EXPECT_EQ( + "u8\"unsupported literal\";", + format("u8\"unsupported literal\";", getGoogleStyleWithColumns(15))); EXPECT_EQ("u\"unsupported literal\";", - format("u\"unsupported literal\";", getLLVMStyleWithColumns(15))); + format("u\"unsupported literal\";", getGoogleStyleWithColumns(15))); EXPECT_EQ("U\"unsupported literal\";", - format("U\"unsupported literal\";", getLLVMStyleWithColumns(15))); + format("U\"unsupported literal\";", getGoogleStyleWithColumns(15))); EXPECT_EQ("L\"unsupported literal\";", - format("L\"unsupported literal\";", getLLVMStyleWithColumns(15))); + format("L\"unsupported literal\";", getGoogleStyleWithColumns(15))); EXPECT_EQ("R\"x(raw literal)x\";", - format("R\"x(raw literal)x\";", getLLVMStyleWithColumns(15))); + format("R\"x(raw literal)x\";", getGoogleStyleWithColumns(15))); +} + +TEST_F(FormatTest, DoesNotTryToParseUDLiteralsInPreCpp11Code) { + EXPECT_EQ("#define x(_a) printf(\"foo\" _a);", + format("#define x(_a) printf(\"foo\"_a);", getLLVMStyle())); } TEST_F(FormatTest, BreakStringLiteralsBeforeUnbreakableTokenSequence) { @@ -4780,7 +4786,7 @@ TEST_F(FormatTest, DoNotBreakStringLiteralsInEscapeSequence) { "\"1\"", format("\"test\\000000000001\"", getLLVMStyleWithColumns(10))); EXPECT_EQ("R\"(\\x\\x00)\"\n", - format("R\"(\\x\\x00)\"\n", getLLVMStyleWithColumns(7))); + format("R\"(\\x\\x00)\"\n", getGoogleStyleWithColumns(7))); } TEST_F(FormatTest, DoNotCreateUnreasonableUnwrappedLines) { -- 2.40.0