summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-03-19 22:09:55 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-03-19 22:09:55 +0000
commit91e150d54c8c442469ecb2aa4d4de09214ec1337 (patch)
treee2f5c533a00ece1a2e5ded062b66c46eb386467e /clang/lib/Lex
parentd674d96bc56c0f377879d01c9d8dfdaaa7859cdb (diff)
downloadbcm5719-llvm-91e150d54c8c442469ecb2aa4d4de09214ec1337.tar.gz
bcm5719-llvm-91e150d54c8c442469ecb2aa4d4de09214ec1337.zip
Replace tok::angle_string_literal with new tok::header_name.
Use the new kind for both angled header-name tokens and for double-quoted header-name tokens. This is in preparation for C++20's context-sensitive header-name token formation rules. llvm-svn: 356530
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r--clang/lib/Lex/Lexer.cpp6
-rw-r--r--clang/lib/Lex/PPDirectives.cpp10
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp4
-rw-r--r--clang/lib/Lex/Pragma.cpp8
-rw-r--r--clang/lib/Lex/Preprocessor.cpp30
5 files changed, 42 insertions, 16 deletions
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 41003baced6..40c63874661 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -2072,7 +2072,7 @@ bool Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) {
// Update the location of token as well as BufferPtr.
const char *TokStart = BufferPtr;
- FormTokenWithChars(Result, CurPtr, tok::angle_string_literal);
+ FormTokenWithChars(Result, CurPtr, tok::header_name);
Result.setLiteralData(TokStart);
return true;
}
@@ -3465,7 +3465,9 @@ LexNextToken:
case '"':
// Notify MIOpt that we read a non-whitespace/non-comment token.
MIOpt.ReadToken();
- return LexStringLiteral(Result, CurPtr, tok::string_literal);
+ return LexStringLiteral(Result, CurPtr,
+ ParsingFilename ? tok::header_name
+ : tok::string_literal);
// C99 6.4.6: Punctuators.
case '?':
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 40eb3af2573..8d4b9f06569 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -1446,6 +1446,14 @@ bool Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc,
// Get the text form of the filename.
assert(!Buffer.empty() && "Can't have tokens with empty spellings!");
+ // FIXME: Consider warning on some of the cases described in C11 6.4.7/3 and
+ // C++20 [lex.header]/2:
+ //
+ // If `"`, `'`, `\`, `/*`, or `//` appears in a header-name, then
+ // in C: behavior is undefined
+ // in C++: program is conditionally-supported with implementation-defined
+ // semantics
+
// Make sure the filename is <x> or "x".
bool isAngled;
if (Buffer[0] == '<') {
@@ -1613,7 +1621,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
if (LexHeaderName(FilenameTok))
return;
- if (!FilenameTok.isOneOf(tok::angle_string_literal, tok::string_literal)) {
+ if (FilenameTok.isNot(tok::header_name)) {
Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
if (FilenameTok.isNot(tok::eod))
DiscardUntilEndOfDirective();
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 751f99950de..d698f0e6578 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1166,7 +1166,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
PP.Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;
// 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))
+ if (Tok.isNot(tok::header_name))
return false;
} else {
// Save '(' location for possible missing ')' message.
@@ -1175,7 +1175,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
return false;
}
- if (!Tok.isOneOf(tok::angle_string_literal, tok::string_literal)) {
+ if (Tok.isNot(tok::header_name)) {
PP.Diag(Tok.getLocation(), diag::err_pp_expects_filename);
return false;
}
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
index 369fd92dd61..286b863b354 100644
--- a/clang/lib/Lex/Pragma.cpp
+++ b/clang/lib/Lex/Pragma.cpp
@@ -486,7 +486,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
return;
// If the next token wasn't a header-name, diagnose the error.
- if (!FilenameTok.isOneOf(tok::angle_string_literal, tok::string_literal)) {
+ if (FilenameTok.isNot(tok::header_name)) {
Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
return;
}
@@ -670,8 +670,7 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
StringRef SourceFileName;
SmallString<128> FileNameBuffer;
- if (SourceFilenameTok.is(tok::string_literal) ||
- SourceFilenameTok.is(tok::angle_string_literal)) {
+ if (SourceFilenameTok.is(tok::header_name)) {
SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
} else {
Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
@@ -691,8 +690,7 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
return;
StringRef ReplaceFileName;
- if (ReplaceFilenameTok.is(tok::string_literal) ||
- ReplaceFilenameTok.is(tok::angle_string_literal)) {
+ if (ReplaceFilenameTok.is(tok::header_name)) {
ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
} else {
Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index ebe3797717c..832a70620e8 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -901,11 +901,12 @@ void Preprocessor::Lex(Token &Result) {
/// \param FilenameTok Filled in with the next token. On success, this will
/// be either an angle_header_name or a string_literal token. On
/// failure, it will be whatever other token was found instead.
-/// \param AllowConcatenation If \c true, allow a < token, followed by other
-/// tokens and finally a > token, to form a single header-name token.
+/// \param AllowMacroExpansion If \c true, allow the header name to be formed
+/// by macro expansion (concatenating tokens as necessary if the first
+/// token is a '<').
/// \return \c true if we reached EOD or EOF while looking for a > token in
/// a concatenated header name and diagnosed it. \c false otherwise.
-bool Preprocessor::LexHeaderName(Token &FilenameTok, bool AllowConcatenation) {
+bool Preprocessor::LexHeaderName(Token &FilenameTok, bool AllowMacroExpansion) {
// Lex using header-name tokenization rules if tokens are being lexed from
// a file. Just grab a token normally if we're in a macro expansion.
if (CurPPLexer)
@@ -915,13 +916,16 @@ bool Preprocessor::LexHeaderName(Token &FilenameTok, bool AllowConcatenation) {
// This could be a <foo/bar.h> file coming from a macro expansion. In this
// case, glue the tokens together into an angle_string_literal token.
- if (FilenameTok.is(tok::less) && AllowConcatenation) {
- SmallString<128> FilenameBuffer;
+ SmallString<128> FilenameBuffer;
+ if (FilenameTok.is(tok::less) && AllowMacroExpansion) {
SourceLocation Start = FilenameTok.getLocation();
SourceLocation End;
FilenameBuffer.push_back('<');
// Consume tokens until we find a '>'.
+ // FIXME: A header-name could be formed starting or ending with an
+ // alternative token. It's not clear whether that's ill-formed in all
+ // cases.
while (FilenameTok.isNot(tok::greater)) {
Lex(FilenameTok);
if (FilenameTok.isOneOf(tok::eod, tok::eof)) {
@@ -962,8 +966,22 @@ bool Preprocessor::LexHeaderName(Token &FilenameTok, bool AllowConcatenation) {
}
FilenameTok.startToken();
- FilenameTok.setKind(tok::angle_string_literal);
+ FilenameTok.setKind(tok::header_name);
CreateString(FilenameBuffer, FilenameTok, Start, End);
+ } else if (FilenameTok.is(tok::string_literal) && AllowMacroExpansion) {
+ // Convert a string-literal token of the form " h-char-sequence "
+ // (produced by macro expansion) into a header-name token.
+ //
+ // The rules for header-names don't quite match the rules for
+ // string-literals, but all the places where they differ result in
+ // undefined behavior, so we can and do treat them the same.
+ //
+ // A string-literal with a prefix or suffix is not translated into a
+ // header-name. This could theoretically be observable via the C++20
+ // context-sensitive header-name formation rules.
+ StringRef Str = getSpelling(FilenameTok, FilenameBuffer);
+ if (Str.size() >= 2 && Str.front() == '"' && Str.back() == '"')
+ FilenameTok.setKind(tok::header_name);
}
return false;
OpenPOWER on IntegriCloud