[cfe-commits] r38712 - in /cfe/cfe/trunk: Lex/MacroExpander.cpp README.txt include/clang/Basic/DiagnosticKinds.def include/clang/Lex/MacroExpander.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:24:01 PDT 2007


Author: sabre
Date: Wed Jul 11 11:24:01 2007
New Revision: 38712

URL: http://llvm.org/viewvc/llvm-project?rev=38712&view=rev
Log:
Implement the microsoft charize extension #@

Modified:
    cfe/cfe/trunk/Lex/MacroExpander.cpp
    cfe/cfe/trunk/README.txt
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Lex/MacroExpander.h

Modified: cfe/cfe/trunk/Lex/MacroExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/MacroExpander.cpp?rev=38712&r1=38711&r2=38712&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/MacroExpander.cpp (original)
+++ cfe/cfe/trunk/Lex/MacroExpander.cpp Wed Jul 11 11:24:01 2007
@@ -39,7 +39,7 @@
 /// preprocessor operator.
 ///
 static LexerToken StringifyArgument(const std::vector<LexerToken> &Toks,
-                                    Preprocessor &PP) {
+                                    Preprocessor &PP, bool Charify = false) {
   LexerToken Tok;
   Tok.StartToken();
   Tok.SetKind(tok::string_literal);
@@ -78,9 +78,32 @@
       Result.erase(Result.end()-1);  // remove one of the \'s.
     }
   }
-  
   Result += '"';
   
+  // If this is the charify operation and the result is not a legal character
+  // constant, diagnose it.
+  if (Charify) {
+    // First step, turn double quotes into single quotes:
+    Result[0] = '\'';
+    Result[Result.size()-1] = '\'';
+    
+    // Check for bogus character.
+    bool isBad = false;
+    if (Result.size() == 2) {
+      Result = "' '";            // #@empty -> ' '.
+    } else if (Result.size() == 3) {
+      isBad = Result[1] == '\'';   // ''' is not legal. '\' already fixed above.
+    } else {
+      isBad = (Result.size() != 4 || Result[1] != '\\');  // Not '\x'
+    }
+    
+    if (isBad) {
+      assert(!Toks.empty() && "No tokens to charize?");
+      PP.Diag(Toks[0], diag::err_invalid_character_to_charify);
+      Result = "' '";
+    }
+  }
+  
   Tok.SetLength(Result.size());
   Tok.SetLocation(PP.CreateString(&Result[0], Result.size()));
   return Tok;
@@ -143,11 +166,17 @@
     // preprocessor already verified that the following token is a macro name
     // when the #define was parsed.
     const LexerToken &CurTok = (*MacroTokens)[i];
-    if (CurTok.getKind() == tok::hash) {
+    if (CurTok.getKind() == tok::hash || CurTok.getKind() == tok::hashat) {
       int ArgNo = Macro.getArgumentNum((*MacroTokens)[i+1].getIdentifierInfo());
       assert(ArgNo != -1 && "Token following # is not an argument?");
       
-      ResultToks.push_back(FormalArgs->getStringifiedArgument(ArgNo, PP));
+      if (CurTok.getKind() == tok::hash)  // Stringify
+        ResultToks.push_back(FormalArgs->getStringifiedArgument(ArgNo, PP));
+      else {
+        // 'charify': don't bother caching these.
+        ResultToks.push_back(StringifyArgument(
+                               FormalArgs->getUnexpArgument(ArgNo), PP, true));
+      }
       
       // FIXME: Should the stringified string leading space flag get set to
       // match the # or the identifier?

Modified: cfe/cfe/trunk/README.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/README.txt?rev=38712&r1=38711&r2=38712&view=diff

==============================================================================
--- cfe/cfe/trunk/README.txt (original)
+++ cfe/cfe/trunk/README.txt Wed Jul 11 11:24:01 2007
@@ -47,8 +47,6 @@
  * Function-style #define & macro expansion
  * #line / #file directives
  * -C output mode in -E mode.
- * MSExtension: #@param 'stringizes' into a character (charize?):
-    #define A(x) #@x   / A(z) -> 'z'
  * MSExtension: "L#param" stringizes to a wide string literal.
 
 Traditional Preprocessor:

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=38712&r1=38711&r2=38712&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:24:01 2007
@@ -73,6 +73,8 @@
      "empty character constant")
 DIAG(err_unterminated_block_comment, ERROR,
      "unterminated /* comment")
+DIAG(err_invalid_character_to_charify, ERROR,
+     "invalid argument to convert to character")
 
 //===----------------------------------------------------------------------===//
 // Preprocessor Diagnostics
@@ -101,7 +103,7 @@
 DIAG(pp_macro_not_used, WARNING,    // -Wunused-macros
      "macro is not used")
 DIAG(pp_invalid_string_literal, WARNING,
-     "invalid string literal, ignoring final '\'")
+     "invalid string literal, ignoring final '\\'")
 
 DIAG(ext_pp_import_directive, EXTENSION,
      "#import is a language extension")

Modified: cfe/cfe/trunk/include/clang/Lex/MacroExpander.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/MacroExpander.h?rev=38712&r1=38711&r2=38712&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/MacroExpander.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/MacroExpander.h Wed Jul 11 11:24:01 2007
@@ -41,6 +41,13 @@
     ArgTokens.back().swap(ArgToks);
   }
   
+  /// getUnexpArgument - Return the unexpanded tokens for the specified formal.
+  ///
+  const std::vector<LexerToken> &getUnexpArgument(unsigned Arg) const {
+    assert(Arg < ArgTokens.size() && "Invalid ArgNo");
+    return ArgTokens[Arg];
+  }
+  
   /// getStringifiedArgument - Compute, cache, and return the specified argument
   /// that has been 'stringified' as required by the # operator.
   const LexerToken &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP);





More information about the cfe-commits mailing list