summaryrefslogtreecommitdiff
path: root/lib/Parse/Lexer.cpp
diff options
context:
space:
mode:
authorarphaman <arphaman@gmail.com>2013-07-23 11:29:32 +0100
committerarphaman <arphaman@gmail.com>2013-07-23 11:29:32 +0100
commitb601cce438cabe2fd5cee91f05aaee9186e7a6e4 (patch)
tree7f7507f4b7b598c352c6303d9ec3460e8119d9ef /lib/Parse/Lexer.cpp
parentaa50750ec1afc3241124d7b04446f2ab20ab01db (diff)
downloadflang-b601cce438cabe2fd5cee91f05aaee9186e7a6e4.tar.gz
fixed string literal continuation lexing bug
Diffstat (limited to 'lib/Parse/Lexer.cpp')
-rw-r--r--lib/Parse/Lexer.cpp20
1 files changed, 12 insertions, 8 deletions
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index 5995e153a8..a4809b6b53 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -86,7 +86,7 @@ void Lexer::LineOfText::SetState(const State &S) {
/// SkipBlankLinesAndComments - Helper function that skips blank lines and lines
/// with only comments.
bool Lexer::LineOfText::
-SkipBlankLinesAndComments(unsigned &I, const char *&LineBegin) {
+SkipBlankLinesAndComments(unsigned &I, const char *&LineBegin, bool IgnoreContinuationChar) {
// Skip blank lines and lines with only comments.
while (isVerticalWhitespace(*BufPtr) && *BufPtr != '\0')
++BufPtr;
@@ -112,7 +112,7 @@ SkipBlankLinesAndComments(unsigned &I, const char *&LineBegin) {
// had a previous continuation character at the end of the line, then readjust
// the LineBegin.
if (I != 132 && *BufPtr == '&') {
- if (Atoms.empty()) // FIXME: This isn't sufficient.
+ if (Atoms.empty() && !IgnoreContinuationChar)
Diags.Report(SourceLocation::getFromPointer(BufPtr),
diag::err_continuation_out_of_context);
++I, ++BufPtr;
@@ -150,7 +150,7 @@ SkipFixedFormBlankLinesAndComments(unsigned &I, const char *&LineBegin) {
/// GetCharacterLiteral - A character literal has to be treated specially
/// because an ampersand may exist within it.
void Lexer::LineOfText::
-GetCharacterLiteral(unsigned &I, const char *&LineBegin) {
+GetCharacterLiteral(unsigned &I, const char *&LineBegin, bool &PadAtoms) {
// Skip blank lines and lines with only comments.
SkipBlankLinesAndComments(I, LineBegin);
@@ -195,7 +195,7 @@ GetCharacterLiteral(unsigned &I, const char *&LineBegin) {
I++, ++BufPtr;
LineBegin = BufPtr;
I = 0;
- SkipBlankLinesAndComments(I, LineBegin);
+ SkipBlankLinesAndComments(I, LineBegin, true);
char next = *BufPtr;
bool endQuote = true;
if(DoubleQuotes){
@@ -211,6 +211,7 @@ GetCharacterLiteral(unsigned &I, const char *&LineBegin) {
}
I = currentI;BufPtr = CurrentBufPtr; LineBegin = CurrentLineBegin;
if(!endQuote){
+ PadAtoms = false;
skipNextQuoteChar = true;
continue;
}
@@ -267,6 +268,7 @@ void Lexer::LineOfText::GetNextLine() {
unsigned I = 0;
bool BeginsWithAmp = true;
+ bool PadAtoms = true;
const char *AmpersandPos = 0;
if(LanguageOptions.FixedForm) {
@@ -276,8 +278,8 @@ void Lexer::LineOfText::GetNextLine() {
while (I != 72 && !isVerticalWhitespace(*BufPtr) && *BufPtr != '\0') {
++I, ++BufPtr;
}
- if(!Atoms.empty())
- Atoms.push_back(StringRef(Padding));
+ //if(!Atoms.empty())
+ // Atoms.push_back(StringRef(Padding));
Atoms.push_back(StringRef(LineBegin, BufPtr - LineBegin));
// Increment the buffer pointer to the start of the next line.
@@ -309,7 +311,7 @@ void Lexer::LineOfText::GetNextLine() {
while (I != 132 && !isVerticalWhitespace(*BufPtr) && *BufPtr != '\0') {
if (*BufPtr == '\'' || *BufPtr == '"') {
// TODO: A BOZ constant doesn't get parsed like a character literal.
- GetCharacterLiteral(I, LineBegin);
+ GetCharacterLiteral(I, LineBegin, PadAtoms);
if (I == 132 || isVerticalWhitespace(*BufPtr))
break;
} else if (*BufPtr == '&') {
@@ -350,7 +352,7 @@ void Lexer::LineOfText::GetNextLine() {
if (AmpersandPos) {
Atoms.push_back(StringRef(LineBegin, AmpersandPos - LineBegin));
} else {
- if (!BeginsWithAmp && !Atoms.empty())
+ if (!BeginsWithAmp && !Atoms.empty() && PadAtoms)
// This is a line that doesn't start with an '&'. The tokens are not
// contiguous. Insert a space to indicate this.
Atoms.push_back(StringRef(Padding));
@@ -1078,6 +1080,8 @@ void Lexer::LexCharacterLiteralConstant(Token &Result,
}
} else {
if (C == '\'') {
+ auto Next = peekNextChar();
+ llvm::outs() <<"Next:" << int(Next) << "," << Next<<"\n";
if (peekNextChar() != '\'') {
getNextChar();
break;