Skip to content

Commit

Permalink
Stringizing raw string literals containing newline
Browse files Browse the repository at this point in the history
Summary: This patch implements 4.3 of http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4220.pdf. If a raw string contains a newline character, replace each newline character with the \n escape code. Without this patch, included test case (macro_raw_string.cpp) results compilation failure.

Reviewers: rsmith, doug.gregor, jkorous-apple

Reviewed By: jkorous-apple

Subscribers: jkorous-apple, vsapsai, cfe-commits

Differential Revision: https://reviews.llvm.org/D39279

llvm-svn: 319904
  • Loading branch information
taewookoh committed Dec 6, 2017
1 parent ddf4ef3 commit cebac48
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 71 deletions.
27 changes: 13 additions & 14 deletions clang/include/clang/Lex/Lexer.h
Expand Up @@ -70,7 +70,7 @@ class Lexer : public PreprocessorLexer {
SourceLocation FileLoc; // Location for start of file.
LangOptions LangOpts; // LangOpts enabled by this language (cache).
bool Is_PragmaLexer; // True if lexer for _Pragma handling.

//===--------------------------------------------------------------------===//
// Context-specific lexing flags set by the preprocessor.
//
Expand Down Expand Up @@ -241,17 +241,16 @@ class Lexer : public PreprocessorLexer {

/// \brief Return the current location in the buffer.
const char *getBufferLocation() const { return BufferPtr; }
/// Stringify - Convert the specified string into a C string by escaping '\'
/// and " characters. This does not add surrounding ""'s to the string.

/// Stringify - Convert the specified string into a C string by i) escaping
/// '\\' and " characters and ii) replacing newline character(s) with "\\n".
/// If Charify is true, this escapes the ' character instead of ".
static std::string Stringify(StringRef Str, bool Charify = false);

/// Stringify - Convert the specified string into a C string by escaping '\'
/// and " characters. This does not add surrounding ""'s to the string.
/// Stringify - Convert the specified string into a C string by i) escaping
/// '\\' and " characters and ii) replacing newline character(s) with "\\n".
static void Stringify(SmallVectorImpl<char> &Str);


/// getSpelling - This method is used to get the spelling of a token into a
/// preallocated buffer, instead of as an std::string. The caller is required
/// to allocate enough space for the token, which is guaranteed to be at least
Expand All @@ -262,19 +261,19 @@ class Lexer : public PreprocessorLexer {
/// to point to a constant buffer with the data already in it (avoiding a
/// copy). The caller is not allowed to modify the returned buffer pointer
/// if an internal buffer is returned.
static unsigned getSpelling(const Token &Tok, const char *&Buffer,
static unsigned getSpelling(const Token &Tok, const char *&Buffer,
const SourceManager &SourceMgr,
const LangOptions &LangOpts,
bool *Invalid = nullptr);

/// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
/// token is the characters used to represent the token in the source file
/// after trigraph expansion and escaped-newline folding. In particular, this
/// wants to get the true, uncanonicalized, spelling of things like digraphs
/// UCNs, etc.
static std::string getSpelling(const Token &Tok,
const SourceManager &SourceMgr,
const LangOptions &LangOpts,
const LangOptions &LangOpts,
bool *Invalid = nullptr);

/// getSpelling - This method is used to get the spelling of the
Expand All @@ -290,7 +289,7 @@ class Lexer : public PreprocessorLexer {
const SourceManager &SourceMgr,
const LangOptions &LangOpts,
bool *invalid = nullptr);

/// MeasureTokenLength - Relex the token at the specified location and return
/// its length in bytes in the input file. If the token needs cleaning (e.g.
/// includes a trigraph or an escaped newline) then this count includes bytes
Expand All @@ -312,15 +311,15 @@ class Lexer : public PreprocessorLexer {
static SourceLocation GetBeginningOfToken(SourceLocation Loc,
const SourceManager &SM,
const LangOptions &LangOpts);

/// AdvanceToTokenCharacter - If the current SourceLocation specifies a
/// location at the start of a token, return a new location that specifies a
/// character within the token. This handles trigraphs and escaped newlines.
static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
unsigned Character,
const SourceManager &SM,
const LangOptions &LangOpts);

/// \brief Computes the source location just past the end of the
/// token at this source location.
///
Expand Down Expand Up @@ -667,7 +666,7 @@ class Lexer : public PreprocessorLexer {
bool SkipBlockComment (Token &Result, const char *CurPtr,
bool &TokAtPhysicalStartOfLine);
bool SaveLineComment (Token &Result, const char *CurPtr);

bool IsStartOfConflictMarker(const char *CurPtr);
bool HandleEndOfConflictMarker(const char *CurPtr);

Expand Down

0 comments on commit cebac48

Please sign in to comment.