Ignore contents of #if 0 blocks.

Summary:
Added stack of preprocessor branching directives, and ignore all tokens
inside #if 0 except for preprocessor directives.

Reviewers: klimek, djasper

Reviewed By: klimek

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D855

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182658 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 9ef5d15..aaed97c 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -323,6 +323,22 @@
   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();
@@ -330,6 +346,48 @@
   }
 }
 
+void UnwrappedLineParser::pushPPConditional() {
+  if (!PPStack.empty() && PPStack.back() == PP_Unreachable)
+    PPStack.push_back(PP_Unreachable);
+  else
+    PPStack.push_back(PP_Conditional);
+}
+
+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_Unreachable);
+  } else {
+    pushPPConditional();
+  }
+  parsePPUnknown();
+}
+
+void UnwrappedLineParser::parsePPIfdef() {
+  pushPPConditional();
+  parsePPUnknown();
+}
+
+void UnwrappedLineParser::parsePPElse() {
+  if (!PPStack.empty())
+    PPStack.pop_back();
+  pushPPConditional();
+  parsePPUnknown();
+}
+
+void UnwrappedLineParser::parsePPElIf() {
+  parsePPElse();
+}
+
+void UnwrappedLineParser::parsePPEndIf() {
+  if (!PPStack.empty())
+    PPStack.pop_back();
+  parsePPUnknown();
+}
+
 void UnwrappedLineParser::parsePPDefine() {
   nextToken();
 
@@ -1020,6 +1078,12 @@
       flushComments(FormatTok.NewlinesBefore > 0);
       parsePPDirective();
     }
+
+    if (!PPStack.empty() && (PPStack.back() == PP_Unreachable) &&
+        !Line->InPPDirective) {
+      continue;
+    }
+
     if (!FormatTok.Tok.is(tok::comment))
       return;
     if (FormatTok.NewlinesBefore > 0 || FormatTok.IsFirst) {