diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.cpp | 64 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.h | 17 |
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; }; |