summaryrefslogtreecommitdiffstats
path: root/clang/lib/Format/UnwrappedLineParser.cpp
diff options
context:
space:
mode:
authorFrancois Ferrand <thetypz@gmail.com>2017-07-28 07:56:14 +0000
committerFrancois Ferrand <thetypz@gmail.com>2017-07-28 07:56:14 +0000
commita98a95cca735b95cca5c904fa5ca875d916effc1 (patch)
tree0f392d9d1dd382895dd7ed0e6a236a8329a0bba8 /clang/lib/Format/UnwrappedLineParser.cpp
parent25271b91b237cde8f897b230aa366d38dd701f6c (diff)
downloadbcm5719-llvm-a98a95cca735b95cca5c904fa5ca875d916effc1.tar.gz
bcm5719-llvm-a98a95cca735b95cca5c904fa5ca875d916effc1.zip
clang-format: fix block OpeningLineIndex around preprocessor
Summary: The current code would return an incorrect value when a preprocessor directive is present immediately after the opening brace: this causes the nanespace end comment fixer to break in some places, for exemple it would not add the comment in this case: namespace a { #define FOO } Fixing the computation is simple enough, but it was breaking a feature, as it would cause comments to be added also when the namespace declaration was dependant on conditional compilation. To fix this, a hash of the current preprocessor stack/branches is computed at the beginning of parseBlock(), so that we explicitely do not store the OpeningLineIndex when the beginning and end of the block are not in the same preprocessor conditions. Tthe hash is computed based on the line, but this could propbably be improved by using the actual condition, so that clang-format would be able to match multiple identical #ifdef blocks. Reviewers: krasimir, djasper Reviewed By: krasimir Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D35483 llvm-svn: 309369
Diffstat (limited to 'clang/lib/Format/UnwrappedLineParser.cpp')
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp54
1 files changed, 42 insertions, 12 deletions
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 9bb9ed19183..bbed83263ce 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -452,6 +452,21 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
FormatTok = Tokens->setPosition(StoredPosition);
}
+template <class T>
+static inline void hash_combine(std::size_t &seed, const T &v) {
+ std::hash<T> hasher;
+ seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+}
+
+size_t UnwrappedLineParser::computePPHash() const {
+ size_t h = 0;
+ for (const auto &i : PPStack) {
+ hash_combine(h, size_t(i.Kind));
+ hash_combine(h, i.Line);
+ }
+ return h;
+}
+
void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel,
bool MunchSemi) {
assert(FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) &&
@@ -459,16 +474,21 @@ void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel,
const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin);
FormatTok->BlockKind = BK_Block;
+ size_t PPStartHash = computePPHash();
+
unsigned InitialLevel = Line->Level;
nextToken(/*LevelDifference=*/AddLevel ? 1 : 0);
if (MacroBlock && FormatTok->is(tok::l_paren))
parseParens();
+ size_t NbPreprocessorDirectives =
+ CurrentLines == &Lines ? PreprocessorDirectives.size() : 0;
addUnwrappedLine();
- size_t OpeningLineIndex = CurrentLines->empty()
- ? (UnwrappedLine::kInvalidIndex)
- : (CurrentLines->size() - 1);
+ size_t OpeningLineIndex =
+ CurrentLines->empty()
+ ? (UnwrappedLine::kInvalidIndex)
+ : (CurrentLines->size() - 1 - NbPreprocessorDirectives);
ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
MustBeDeclaration);
@@ -486,6 +506,8 @@ void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel,
return;
}
+ size_t PPEndHash = computePPHash();
+
// Munch the closing brace.
nextToken(/*LevelDifference=*/AddLevel ? -1 : 0);
@@ -495,11 +517,14 @@ void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel,
if (MunchSemi && FormatTok->Tok.is(tok::semi))
nextToken();
Line->Level = InitialLevel;
- Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
- if (OpeningLineIndex != UnwrappedLine::kInvalidIndex) {
- // Update the opening line to add the forward reference as well
- (*CurrentLines)[OpeningLineIndex].MatchingOpeningBlockLineIndex =
- CurrentLines->size() - 1;
+
+ if (PPStartHash == PPEndHash) {
+ Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
+ if (OpeningLineIndex != UnwrappedLine::kInvalidIndex) {
+ // Update the opening line to add the forward reference as well
+ (*CurrentLines)[OpeningLineIndex].MatchingOpeningBlockLineIndex =
+ CurrentLines->size() - 1;
+ }
}
}
@@ -607,10 +632,15 @@ void UnwrappedLineParser::parsePPDirective() {
}
void UnwrappedLineParser::conditionalCompilationCondition(bool Unreachable) {
- if (Unreachable || (!PPStack.empty() && PPStack.back() == PP_Unreachable))
- PPStack.push_back(PP_Unreachable);
+ size_t Line = CurrentLines->size();
+ if (CurrentLines == &PreprocessorDirectives)
+ Line += Lines.size();
+
+ if (Unreachable ||
+ (!PPStack.empty() && PPStack.back().Kind == PP_Unreachable))
+ PPStack.push_back({PP_Unreachable, Line});
else
- PPStack.push_back(PP_Conditional);
+ PPStack.push_back({PP_Conditional, Line});
}
void UnwrappedLineParser::conditionalCompilationStart(bool Unreachable) {
@@ -2400,7 +2430,7 @@ void UnwrappedLineParser::readToken(int LevelDifference) {
FormatTok->MustBreakBefore = true;
}
- if (!PPStack.empty() && (PPStack.back() == PP_Unreachable) &&
+ if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
!Line->InPPDirective) {
continue;
}
OpenPOWER on IntegriCloud