aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format/UnwrappedLineParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Format/UnwrappedLineParser.cpp')
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp159
1 files changed, 129 insertions, 30 deletions
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 28d925858f77..5b9fe267aae6 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -28,9 +28,28 @@ namespace format {
class FormatTokenSource {
public:
virtual ~FormatTokenSource() {}
+
+ // Returns the next token in the token stream.
virtual FormatToken *getNextToken() = 0;
+ // Returns the token precedint the token returned by the last call to
+ // getNextToken() in the token stream, or nullptr if no such token exists.
+ virtual FormatToken *getPreviousToken() = 0;
+
+ // Returns the token that would be returned by the next call to
+ // getNextToken().
+ virtual FormatToken *peekNextToken() = 0;
+
+ // Returns whether we are at the end of the file.
+ // This can be different from whether getNextToken() returned an eof token
+ // when the FormatTokenSource is a view on a part of the token stream.
+ virtual bool isEOF() = 0;
+
+ // Gets the current position in the token stream, to be used by setPosition().
virtual unsigned getPosition() = 0;
+
+ // Resets the token stream to the state it was in when getPosition() returned
+ // Position, and return the token at that position in the stream.
virtual FormatToken *setPosition(unsigned Position) = 0;
};
@@ -108,6 +127,18 @@ public:
return Token;
}
+ FormatToken *getPreviousToken() override {
+ return PreviousTokenSource->getPreviousToken();
+ }
+
+ FormatToken *peekNextToken() override {
+ if (eof())
+ return &FakeEOF;
+ return PreviousTokenSource->peekNextToken();
+ }
+
+ bool isEOF() override { return PreviousTokenSource->isEOF(); }
+
unsigned getPosition() override { return PreviousTokenSource->getPosition(); }
FormatToken *setPosition(unsigned Position) override {
@@ -199,16 +230,45 @@ public:
: Tokens(Tokens), Position(-1) {}
FormatToken *getNextToken() override {
+ if (Position >= 0 && Tokens[Position]->is(tok::eof)) {
+ LLVM_DEBUG({
+ llvm::dbgs() << "Next ";
+ dbgToken(Position);
+ });
+ return Tokens[Position];
+ }
++Position;
+ LLVM_DEBUG({
+ llvm::dbgs() << "Next ";
+ dbgToken(Position);
+ });
return Tokens[Position];
}
+ FormatToken *getPreviousToken() override {
+ assert(Position > 0);
+ return Tokens[Position - 1];
+ }
+
+ FormatToken *peekNextToken() override {
+ int Next = Position + 1;
+ LLVM_DEBUG({
+ llvm::dbgs() << "Peeking ";
+ dbgToken(Next);
+ });
+ return Tokens[Next];
+ }
+
+ bool isEOF() override { return Tokens[Position]->is(tok::eof); }
+
unsigned getPosition() override {
+ LLVM_DEBUG(llvm::dbgs() << "Getting Position: " << Position << "\n");
assert(Position >= 0);
return Position;
}
FormatToken *setPosition(unsigned P) override {
+ LLVM_DEBUG(llvm::dbgs() << "Setting Position: " << P << "\n");
Position = P;
return Tokens[Position];
}
@@ -216,6 +276,13 @@ public:
void reset() { Position = -1; }
private:
+ void dbgToken(int Position, llvm::StringRef Indent = "") {
+ FormatToken *Tok = Tokens[Position];
+ llvm::dbgs() << Indent << "[" << Position
+ << "] Token: " << Tok->Tok.getName() << " / " << Tok->TokenText
+ << ", Macro: " << !!Tok->MacroCtx << "\n";
+ }
+
ArrayRef<FormatToken *> Tokens;
int Position;
};
@@ -399,7 +466,7 @@ void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
FormatToken *Next;
do {
Next = Tokens->getNextToken();
- } while (Next && Next->is(tok::comment));
+ } while (Next->is(tok::comment));
FormatTok = Tokens->setPosition(StoredPosition);
if (Next && Next->isNot(tok::colon)) {
// default not followed by ':' is not a case label; treat it like
@@ -875,10 +942,7 @@ void UnwrappedLineParser::parsePPEndIf() {
parsePPUnknown();
// If the #endif of a potential include guard is the last thing in the file,
// then we found an include guard.
- unsigned TokenPosition = Tokens->getPosition();
- FormatToken *PeekNext = AllTokens[TokenPosition];
- if (IncludeGuard == IG_Defined && PPBranchLevel == -1 &&
- PeekNext->is(tok::eof) &&
+ if (IncludeGuard == IG_Defined && PPBranchLevel == -1 && Tokens->isEOF() &&
Style.IndentPPDirectives != FormatStyle::PPDIS_None)
IncludeGuard = IG_Found;
}
@@ -1050,6 +1114,35 @@ static bool isC78ParameterDecl(const FormatToken *Tok, const FormatToken *Next,
return Tok->Previous && Tok->Previous->isOneOf(tok::l_paren, tok::comma);
}
+void UnwrappedLineParser::parseModuleImport() {
+ nextToken();
+ while (!eof()) {
+ if (FormatTok->is(tok::colon)) {
+ FormatTok->setType(TT_ModulePartitionColon);
+ }
+ // Handle import <foo/bar.h> as we would an include statement.
+ else if (FormatTok->is(tok::less)) {
+ nextToken();
+ while (!FormatTok->isOneOf(tok::semi, tok::greater, tok::eof)) {
+ // Mark tokens up to the trailing line comments as implicit string
+ // literals.
+ if (FormatTok->isNot(tok::comment) &&
+ !FormatTok->TokenText.startswith("//"))
+ FormatTok->setType(TT_ImplicitStringLiteral);
+ nextToken();
+ }
+ }
+ if (FormatTok->is(tok::semi)) {
+ nextToken();
+ break;
+ }
+ nextToken();
+ }
+
+ addUnwrappedLine();
+ return;
+}
+
// readTokenWithJavaScriptASI reads the next token and terminates the current
// line if JavaScript Automatic Semicolon Insertion must
// happen between the current token and the next token.
@@ -1097,7 +1190,6 @@ void UnwrappedLineParser::readTokenWithJavaScriptASI() {
}
void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) {
- assert(!FormatTok->is(tok::l_brace));
if (Style.Language == FormatStyle::LK_TableGen &&
FormatTok->is(tok::pp_include)) {
nextToken();
@@ -1249,6 +1341,10 @@ void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) {
addUnwrappedLine();
return;
}
+ if (Style.isCpp()) {
+ parseModuleImport();
+ return;
+ }
}
if (Style.isCpp() &&
FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,
@@ -1402,9 +1498,7 @@ void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) {
// declaration.
if (!IsTopLevel || !Style.isCpp() || !Previous || FormatTok->is(tok::eof))
break;
- const unsigned Position = Tokens->getPosition() + 1;
- assert(Position < AllTokens.size());
- if (isC78ParameterDecl(FormatTok, AllTokens[Position], Previous)) {
+ if (isC78ParameterDecl(FormatTok, Tokens->peekNextToken(), Previous)) {
addUnwrappedLine();
return;
}
@@ -1488,7 +1582,7 @@ void UnwrappedLineParser::parseStructuralElement(bool IsTopLevel) {
unsigned StoredPosition = Tokens->getPosition();
FormatToken *Next = Tokens->getNextToken();
FormatTok = Tokens->setPosition(StoredPosition);
- if (Next && !mustBeJSIdent(Keywords, Next)) {
+ if (!mustBeJSIdent(Keywords, Next)) {
nextToken();
break;
}
@@ -2099,8 +2193,8 @@ void UnwrappedLineParser::parseIfThenElse() {
parseBlock();
addUnwrappedLine();
} else if (FormatTok->Tok.is(tok::kw_if)) {
- FormatToken *Previous = AllTokens[Tokens->getPosition() - 1];
- bool PrecededByComment = Previous->is(tok::comment);
+ FormatToken *Previous = Tokens->getPreviousToken();
+ bool PrecededByComment = Previous && Previous->is(tok::comment);
if (PrecededByComment) {
addUnwrappedLine();
++Line->Level;
@@ -2305,6 +2399,8 @@ void UnwrappedLineParser::parseForOrWhileLoop() {
if (Style.Language == FormatStyle::LK_JavaScript &&
FormatTok->is(Keywords.kw_await))
nextToken();
+ if (Style.isCpp() && FormatTok->is(tok::kw_co_await))
+ nextToken();
if (FormatTok->Tok.is(tok::l_paren))
parseParens();
if (FormatTok->Tok.is(tok::l_brace)) {
@@ -2653,23 +2749,25 @@ bool UnwrappedLineParser::tryToParseSimpleAttribute() {
ScopedTokenPosition AutoPosition(Tokens);
FormatToken *Tok = Tokens->getNextToken();
// We already read the first [ check for the second.
- if (Tok && !Tok->is(tok::l_square)) {
+ if (!Tok->is(tok::l_square)) {
return false;
}
// Double check that the attribute is just something
// fairly simple.
- while (Tok) {
+ while (Tok->isNot(tok::eof)) {
if (Tok->is(tok::r_square)) {
break;
}
Tok = Tokens->getNextToken();
}
+ if (Tok->is(tok::eof))
+ return false;
Tok = Tokens->getNextToken();
- if (Tok && !Tok->is(tok::r_square)) {
+ if (!Tok->is(tok::r_square)) {
return false;
}
Tok = Tokens->getNextToken();
- if (Tok && Tok->is(tok::semi)) {
+ if (Tok->is(tok::semi)) {
return false;
}
return true;
@@ -2682,7 +2780,7 @@ void UnwrappedLineParser::parseJavaEnumBody() {
unsigned StoredPosition = Tokens->getPosition();
bool IsSimple = true;
FormatToken *Tok = Tokens->getNextToken();
- while (Tok) {
+ while (!Tok->is(tok::eof)) {
if (Tok->is(tok::r_brace))
break;
if (Tok->isOneOf(tok::l_brace, tok::semi)) {
@@ -3292,6 +3390,20 @@ void UnwrappedLineParser::readToken(int LevelDifference) {
do {
FormatTok = Tokens->getNextToken();
assert(FormatTok);
+ while (FormatTok->getType() == TT_ConflictStart ||
+ FormatTok->getType() == TT_ConflictEnd ||
+ FormatTok->getType() == TT_ConflictAlternative) {
+ if (FormatTok->getType() == TT_ConflictStart) {
+ conditionalCompilationStart(/*Unreachable=*/false);
+ } else if (FormatTok->getType() == TT_ConflictAlternative) {
+ conditionalCompilationAlternative();
+ } else if (FormatTok->getType() == TT_ConflictEnd) {
+ conditionalCompilationEnd();
+ }
+ FormatTok = Tokens->getNextToken();
+ FormatTok->MustBreakBefore = true;
+ }
+
while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) &&
(FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) {
distributeComments(Comments, FormatTok);
@@ -3313,19 +3425,6 @@ void UnwrappedLineParser::readToken(int LevelDifference) {
flushComments(isOnNewLine(*FormatTok));
parsePPDirective();
}
- while (FormatTok->getType() == TT_ConflictStart ||
- FormatTok->getType() == TT_ConflictEnd ||
- FormatTok->getType() == TT_ConflictAlternative) {
- if (FormatTok->getType() == TT_ConflictStart) {
- conditionalCompilationStart(/*Unreachable=*/false);
- } else if (FormatTok->getType() == TT_ConflictAlternative) {
- conditionalCompilationAlternative();
- } else if (FormatTok->getType() == TT_ConflictEnd) {
- conditionalCompilationEnd();
- }
- FormatTok = Tokens->getNextToken();
- FormatTok->MustBreakBefore = true;
- }
if (!PPStack.empty() && (PPStack.back().Kind == PP_Unreachable) &&
!Line->InPPDirective) {