diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 3959671fda..06b39d3fa7 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -925,22 +925,30 @@ static bool HasAttribute(const IdentifierInfo *II) { static bool EvaluateHasIncludeCommon(Token &Tok, IdentifierInfo *II, Preprocessor &PP, const DirectoryLookup *LookupFrom) { - SourceLocation LParenLoc; + // Save the location of the current token. If a '(' is later found, use + // that location. If no, use the end of this location instead. + SourceLocation LParenLoc = Tok.getLocation(); // Get '('. PP.LexNonComment(Tok); // Ensure we have a '('. if (Tok.isNot(tok::l_paren)) { - PP.Diag(Tok.getLocation(), diag::err_pp_missing_lparen) << II->getName(); - return false; - } - - // Save '(' location for possible missing ')' message. - LParenLoc = Tok.getLocation(); + // No '(', use end of last token. + LParenLoc = PP.getLocForEndOfToken(LParenLoc); + PP.Diag(LParenLoc, diag::err_pp_missing_lparen) << II->getName(); + // If the next token looks like a filename or the start of one, + // assume it is and process it as such. + if (!Tok.is(tok::angle_string_literal) && !Tok.is(tok::string_literal) && + !Tok.is(tok::less)) + return false; + } else { + // Save '(' location for possible missing ')' message. + LParenLoc = Tok.getLocation(); - // Get the file name. - PP.getCurrentLexer()->LexIncludeFilename(Tok); + // Get the file name. + PP.getCurrentLexer()->LexIncludeFilename(Tok); + } // Reserve a buffer to get the spelling. SmallString<128> FilenameBuffer; @@ -965,8 +973,11 @@ static bool EvaluateHasIncludeCommon(Token &Tok, // This could be a <foo/bar.h> file coming from a macro expansion. In this // case, glue the tokens together into FilenameBuffer and interpret those. FilenameBuffer.push_back('<'); - if (PP.ConcatenateIncludeName(FilenameBuffer, EndLoc)) + if (PP.ConcatenateIncludeName(FilenameBuffer, EndLoc)) { + // Let the caller know a <eod> was found by changing the Token kind. + Tok.setKind(tok::eod); return false; // Found <eod> but no ">"? Diagnostic already emitted. + } Filename = FilenameBuffer.str(); break; default: @@ -974,12 +985,15 @@ static bool EvaluateHasIncludeCommon(Token &Tok, return false; } + SourceLocation FilenameLoc = Tok.getLocation(); + // Get ')'. PP.LexNonComment(Tok); // Ensure we have a trailing ). if (Tok.isNot(tok::r_paren)) { - PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName(); + PP.Diag(PP.getLocForEndOfToken(FilenameLoc), diag::err_pp_missing_rparen) + << II->getName(); PP.Diag(LParenLoc, diag::note_matching) << "("; return false; } @@ -1252,7 +1266,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { else Value = EvaluateHasIncludeNext(Tok, II, *this); OS << (int)Value; - Tok.setKind(tok::numeric_constant); + if (Tok.is(tok::r_paren)) + Tok.setKind(tok::numeric_constant); } else if (II == Ident__has_warning) { // The argument should be a parenthesized string literal. // The argument to these builtins should be a parenthesized identifier. |