[cfe-commits] r38709 - in /cfe/cfe/trunk: Lex/MacroExpander.cpp include/clang/Basic/DiagnosticKinds.def
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:24:00 PDT 2007
Author: sabre
Date: Wed Jul 11 11:23:59 2007
New Revision: 38709
URL: http://llvm.org/viewvc/llvm-project?rev=38709&view=rev
Log:
Implement stringification.
Modified:
cfe/cfe/trunk/Lex/MacroExpander.cpp
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/Lex/MacroExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/MacroExpander.cpp?rev=38709&r1=38708&r2=38709&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/MacroExpander.cpp (original)
+++ cfe/cfe/trunk/Lex/MacroExpander.cpp Wed Jul 11 11:23:59 2007
@@ -15,6 +15,7 @@
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Diagnostic.h"
using namespace llvm;
using namespace clang;
@@ -33,16 +34,54 @@
ArgTokens.reserve(NumArgs);
}
-/// StringifyArgument - Implement C99 6.10.3.2p2.
+/// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
+/// tokens into the literal string token that should be produced by the C #
+/// preprocessor operator.
+///
static LexerToken StringifyArgument(const std::vector<LexerToken> &Toks,
Preprocessor &PP) {
LexerToken Tok;
Tok.StartToken();
Tok.SetKind(tok::string_literal);
+
+ // Stringify all the tokens.
+ std::string Result = "\"";
+ for (unsigned i = 0, e = Toks.size(); i != e; ++i) {
+ const LexerToken &Tok = Toks[i];
+ // FIXME: Optimize this.
+ if (i != 0 && Tok.hasLeadingSpace())
+ Result += ' ';
+
+ // If this is a string or character constant, escape the token as specified
+ // by 6.10.3.2p2.
+ if (Tok.getKind() == tok::string_literal || // "foo" and L"foo".
+ Tok.getKind() == tok::char_constant) { // 'x' and L'x'.
+ Result += Lexer::Stringify(PP.getSpelling(Tok));
+ } else {
+ // Otherwise, just append the token.
+ Result += PP.getSpelling(Tok);
+ }
+ }
+
+ // If the last character of the string is a \, and if it isn't escaped, this
+ // is an invalid string literal, diagnose it as specified in C99.
+ if (Result[Result.size()-1] == '\\') {
+ // Count the number of consequtive \ characters. If even, then they are
+ // just escaped backslashes, otherwise it's an error.
+ unsigned FirstNonSlash = Result.size()-2;
+ // Guaranteed to find the starting " if nothing else.
+ while (Result[FirstNonSlash] == '\\')
+ --FirstNonSlash;
+ if ((Result.size()-1-FirstNonSlash) & 1) {
+ PP.Diag(Toks.back(), diag::pp_invalid_string_literal);
+ Result.erase(Result.end()-1); // remove one of the \'s.
+ }
+ }
+
+ Result += '"';
- std::string Val = "\"XXYZLAKSDFJAS\"";
- Tok.SetLength(Val.size());
- Tok.SetLocation(PP.CreateString(&Val[0], Val.size()));
+ Tok.SetLength(Result.size());
+ Tok.SetLocation(PP.CreateString(&Result[0], Result.size()));
return Tok;
}
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38709&r1=38708&r2=38709&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:23:59 2007
@@ -98,6 +98,8 @@
"redefining builtin macro")
DIAG(pp_macro_not_used, WARNING, // -Wunused-macros
"macro is not used")
+DIAG(pp_invalid_string_literal, WARNING,
+ "invalid string literal, ignoring final '\'")
DIAG(ext_pp_import_directive, EXTENSION,
"#import is a language extension")
More information about the cfe-commits
mailing list