Added support for if false.
Hi klimek, djasper,
http://llvm-reviews.chandlerc.com/D855
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D855?vs=2105&id=2109#toc
Files:
lib/Format/UnwrappedLineParser.cpp
lib/Format/UnwrappedLineParser.h
unittests/Format/FormatTest.cpp
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -163,7 +163,7 @@
UnwrappedLineConsumer &Callback)
: Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
CurrentLines(&Lines), StructuralError(false), Style(Style),
- Tokens(NULL), Callback(Callback) {
+ Tokens(NULL), Callback(Callback), InsideIf0(0) {
FormatToken Tok;
do {
Tok = Tokens.getNextToken();
@@ -323,13 +323,73 @@
switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
case tok::pp_define:
parsePPDefine();
+ return;
+ case tok::pp_if:
+ parsePPIf();
+ break;
+ case tok::pp_ifdef:
+ case tok::pp_ifndef:
+ parsePPIfdef();
+ break;
+ case tok::pp_else:
+ parsePPElse();
+ break;
+ case tok::pp_elif:
+ parsePPElIf();
+ break;
+ case tok::pp_endif:
+ parsePPEndIf();
break;
default:
parsePPUnknown();
break;
}
}
+void UnwrappedLineParser::parsePPIf() {
+ nextToken();
+ if ((FormatTok.Tok.isLiteral() &&
+ StringRef(FormatTok.Tok.getLiteralData(), FormatTok.Tok.getLength()) ==
+ "0") ||
+ FormatTok.Tok.is(tok::kw_false)) {
+ PPStack.push_back(PP_If0);
+ ++InsideIf0;
+ } else {
+ PPStack.push_back(PP_If);
+ }
+ parsePPUnknown();
+}
+
+void UnwrappedLineParser::parsePPIfdef() {
+ PPStack.push_back(PP_If);
+ parsePPUnknown();
+}
+
+void UnwrappedLineParser::parsePPElse() {
+ if (!PPStack.empty() && PPStack.back() != PP_Else) {
+ if (PPStack.back() == PP_If0)
+ --InsideIf0;
+ PPStack.pop_back();
+ } // else unmatched pp directives.
+ PPStack.push_back(PP_Else);
+ parsePPUnknown();
+}
+
+void UnwrappedLineParser::parsePPElIf() {
+ parsePPElse();
+ PPStack.pop_back();
+ PPStack.push_back(PP_If);
+}
+
+void UnwrappedLineParser::parsePPEndIf() {
+ if (!PPStack.empty()) {
+ if (PPStack.back() == PP_If0)
+ --InsideIf0;
+ PPStack.pop_back();
+ } // else unmatched pp directives.
+ parsePPUnknown();
+}
+
void UnwrappedLineParser::parsePPDefine() {
nextToken();
@@ -1020,6 +1080,10 @@
flushComments(FormatTok.NewlinesBefore > 0);
parsePPDirective();
}
+
+ if (InsideIf0 && !Line->InPPDirective)
+ continue;
+
if (!FormatTok.Tok.is(tok::comment))
return;
if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {
Index: lib/Format/UnwrappedLineParser.h
===================================================================
--- lib/Format/UnwrappedLineParser.h
+++ lib/Format/UnwrappedLineParser.h
@@ -17,7 +17,6 @@
#define LLVM_CLANG_FORMAT_UNWRAPPED_LINE_PARSER_H
#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceManager.h"
#include "clang/Format/Format.h"
#include "clang/Lex/Lexer.h"
#include <list>
@@ -140,6 +139,11 @@
void parseBlock(bool MustBeDeclaration, unsigned AddLevels = 1);
void parsePPDirective();
void parsePPDefine();
+ void parsePPIf();
+ void parsePPIfdef();
+ void parsePPElIf();
+ void parsePPElse();
+ void parsePPEndIf();
void parsePPUnknown();
void parseStructuralElement();
bool tryToParseBracedList();
@@ -224,6 +228,20 @@
// position of the token in the stream (see \c AllTokens).
SmallVector<LBraceState, 16> LBraces;
+ // Represents preprocessor branch type, so we can find matching
+ // #if/#else/#endif directives.
+ enum PPBranchKind {
+ PP_If, // Any #if, #ifdef, #ifndef, #elif, except for #if 0
+ PP_If0, // #if 0
+ PP_Else // #else
+ };
+
+ // Keeps a stack of currently active preprocessor branching directives.
+ SmallVector<PPBranchKind, 16> PPStack;
+
+ // Holds the number of PP_If0 on PPStack.
+ int InsideIf0;
+
friend class ScopedLineState;
};
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -1008,6 +1008,144 @@
"};");
}
+TEST_F(FormatTest, IgnoresIf0Contents) {
+ EXPECT_EQ("#if 0\n"
+ "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
+ "#endif\n"
+ "void f() {}",
+ format("#if 0\n"
+ "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
+ "#endif\n"
+ "void f( ) { }"));
+ EXPECT_EQ("#if false\n"
+ "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
+ "#endif\n"
+ "void f() {}",
+ format("#if false\n"
+ "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
+ "#endif\n"
+ "void f( ) { }"));
+ EXPECT_EQ("enum E {\n"
+ " One,\n"
+ " Two,\n"
+ "#if 0\n"
+ "Three,\n"
+ " Four,\n"
+ "#endif\n"
+ " Five\n"
+ "};",
+ format("enum E {\n"
+ " One,Two,\n"
+ "#if 0\n"
+ "Three,\n"
+ " Four,\n"
+ "#endif\n"
+ " Five};"));
+ EXPECT_EQ("enum F {\n"
+ " One,\n"
+ "#if 1\n"
+ " Two,\n"
+ "#if 0\n"
+ "Three,\n"
+ " Four,\n"
+ "#endif\n"
+ " Five\n"
+ "#endif\n"
+ "};",
+ format("enum F {\n"
+ "One,\n"
+ "#if 1\n"
+ "Two,\n"
+ "#if 0\n"
+ "Three,\n"
+ " Four,\n"
+ "#endif\n"
+ "Five\n"
+ "#endif\n"
+ "};"));
+ EXPECT_EQ("enum G {\n"
+ " One,\n"
+ "#if 0\n"
+ "Two,\n"
+ "#else\n"
+ " Three,\n"
+ "#endif\n"
+ " Four\n"
+ "};",
+ format("enum G {\n"
+ "One,\n"
+ "#if 0\n"
+ "Two,\n"
+ "#else\n"
+ "Three,\n"
+ "#endif\n"
+ "Four\n"
+ "};"));
+ EXPECT_EQ("enum H {\n"
+ " One,\n"
+ "#if 0\n"
+ "#ifdef Q\n"
+ "Two,\n"
+ "#else\n"
+ "Three,\n"
+ "#endif\n"
+ "#endif\n"
+ " Four\n"
+ "};",
+ format("enum H {\n"
+ "One,\n"
+ "#if 0\n"
+ "#ifdef Q\n"
+ "Two,\n"
+ "#else\n"
+ "Three,\n"
+ "#endif\n"
+ "#endif\n"
+ "Four\n"
+ "};"));
+ EXPECT_EQ("enum I {\n"
+ " One,\n"
+ "#if /* test */ 0 || 1\n"
+ "Two,\n"
+ "Three,\n"
+ "#endif\n"
+ " Four\n"
+ "};",
+ format("enum I {\n"
+ "One,\n"
+ "#if /* test */ 0 || 1\n"
+ "Two,\n"
+ "Three,\n"
+ "#endif\n"
+ "Four\n"
+ "};"));
+ EXPECT_EQ("enum J {\n"
+ " One,\n"
+ "#if 0\n"
+ "#if 0\n"
+ "Two,\n"
+ "#else\n"
+ "Three,\n"
+ "#endif\n"
+ "Four,\n"
+ "#endif\n"
+ " Five\n"
+ "};",
+ format("enum J {\n"
+ "One,\n"
+ "#if 0\n"
+ "#if 0\n"
+ "Two,\n"
+ "#else\n"
+ "Three,\n"
+ "#endif\n"
+ "Four,\n"
+ "#endif\n"
+ "Five\n"
+ "};"));
+
+}
+
//===----------------------------------------------------------------------===//
// Tests for classes, namespaces, etc.
//===----------------------------------------------------------------------===//
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits