[cfe-commits] r62333 - in /cfe/trunk: include/clang/Lex/PPCallbacks.h lib/Lex/Pragma.cpp

Chris Lattner sabre at nondot.org
Fri Jan 16 10:59:24 PST 2009


Author: lattner
Date: Fri Jan 16 12:59:23 2009
New Revision: 62333

URL: http://llvm.org/viewvc/llvm-project?rev=62333&view=rev
Log:
Improve #pragma comment support by building the string argument and
notifying PPCallbacks about it.


Modified:
    cfe/trunk/include/clang/Lex/PPCallbacks.h
    cfe/trunk/lib/Lex/Pragma.cpp

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

==============================================================================
--- cfe/trunk/include/clang/Lex/PPCallbacks.h (original)
+++ cfe/trunk/include/clang/Lex/PPCallbacks.h Fri Jan 16 12:59:23 2009
@@ -20,6 +20,7 @@
 
 namespace clang {
   class SourceLocation;
+  class IdentifierInfo;
     
 /// PPCallbacks - This interface provides a way to observe the actions of the
 /// preprocessor as it does its thing.  Clients can define their hooks here to
@@ -46,6 +47,13 @@
   virtual void Ident(SourceLocation Loc, const std::string &str) {
   }
   
+  /// PragmaComment - This callback is invoked when a #pragma comment directive
+  /// is read.
+  ///
+  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, 
+                             const std::string &Str) {
+  }
+  
 };
 
 }  // end namespace clang

Modified: cfe/trunk/lib/Lex/Pragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Pragma.cpp?rev=62333&r1=62332&r2=62333&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/Pragma.cpp (original)
+++ cfe/trunk/lib/Lex/Pragma.cpp Fri Jan 16 12:59:23 2009
@@ -14,6 +14,7 @@
 
 #include "clang/Lex/Pragma.h"
 #include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/LiteralSupport.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
@@ -125,7 +126,11 @@
     return;
   }
   
-  // The _Pragma is lexically sound.  Destringize according to C99 6.10.9.1.
+  // The _Pragma is lexically sound.  Destringize according to C99 6.10.9.1:
+  // "The string literal is destringized by deleting the L prefix, if present,
+  // deleting the leading and trailing double-quotes, replacing each escape
+  // sequence \" by a double-quote, and replacing each escape sequence \\ by a
+  // single backslash."
   if (StrVal[0] == 'L')  // Remove L prefix.
     StrVal.erase(StrVal.begin());
   assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
@@ -342,16 +347,11 @@
     return;
   }
   
-  // Check for optional string.
-  // FIXME: If the kind is "compiler" warn if the string is present (it is
-  // ignored).
-  // FIXME: 'lib' requires a comment string.
-  // FIXME: 'linker' requires a comment string, and has a specific list of
-  // things that are allowable.
+  // Read the optional string if present.
   Lex(Tok);
+  std::string ArgumentString;
   if (Tok.is(tok::comma)) {
-    // FIXME: for now, we parse but ignore the string.
-    Lex(Tok);
+    Lex(Tok); // eat the comma.
 
     // We need at least one string.
     if (Tok.getKind() != tok::string_literal) {
@@ -362,20 +362,45 @@
     // String concatenation allows multiple strings, which can even come from
     // macro expansion.
     // "foo " "bar" "Baz"
-    while (Tok.getKind() == tok::string_literal)
+    llvm::SmallVector<Token, 4> StrToks;
+    while (Tok.getKind() == tok::string_literal) {
+      StrToks.push_back(Tok);
       Lex(Tok);
+    }
+
+    // Concatenate and parse the strings.
+    StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this);
+    assert(!Literal.AnyWide && "Didn't allow wide strings in");
+    if (Literal.hadError)
+      return;
+    if (Literal.Pascal) {
+      Diag(StrToks[0].getLocation(), diag::err_pragma_comment_malformed);
+      return;
+    }
+
+    ArgumentString = std::string(Literal.GetString(),
+                                 Literal.GetString()+Literal.GetStringLength());
   }
   
+  // FIXME: If the kind is "compiler" warn if the string is present (it is
+  // ignored).
+  // FIXME: 'lib' requires a comment string.
+  // FIXME: 'linker' requires a comment string, and has a specific list of
+  // things that are allowable.
+  
   if (Tok.isNot(tok::r_paren)) {
     Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
     return;
   }
-  Lex(Tok);
+  Lex(Tok);  // eat the r_paren.
 
   if (Tok.isNot(tok::eom)) {
     Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
     return;
   }
+  
+  // If the pragma is lexically sound, notify any interested PPCallbacks.
+  Callbacks->PragmaComment(CommentLoc, II, ArgumentString);
 }
 
 





More information about the cfe-commits mailing list