summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp64
-rw-r--r--clang/lib/Format/UnwrappedLineParser.h17
2 files changed, 80 insertions, 1 deletions
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 9ef5d1514d9..aaed97c3020 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -323,6 +323,22 @@ void UnwrappedLineParser::parsePPDirective() {
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::parsePPDirective() {
}
}
+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 @@ void UnwrappedLineParser::readToken() {
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) {
diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h
index 4746951dcd7..bf3db1ea03b 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/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 @@ private:
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();
@@ -167,6 +171,7 @@ private:
void flushComments(bool NewlineBeforeNext);
void pushToken(const FormatToken &Tok);
void calculateBraceTypes();
+ void pushPPConditional();
// Represents what type of block a left brace opens.
enum LBraceState {
@@ -224,6 +229,16 @@ private:
// 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_Conditional, // Any #if, #ifdef, #ifndef, #elif, block outside #if 0
+ PP_Unreachable // #if 0 or a conditional preprocessor block inside #if 0
+ };
+
+ // Keeps a stack of currently active preprocessor branching directives.
+ SmallVector<PPBranchKind, 16> PPStack;
+
friend class ScopedLineState;
};
OpenPOWER on IntegriCloud