[cfe-commits] r62317 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def include/clang/Lex/Preprocessor.h lib/Lex/Pragma.cpp test/Preprocessor/pragma_microsoft.c

Chris Lattner sabre at nondot.org
Fri Jan 16 00:21:25 PST 2009


Author: lattner
Date: Fri Jan 16 02:21:25 2009
New Revision: 62317

URL: http://llvm.org/viewvc/llvm-project?rev=62317&view=rev
Log:
Implement basic support for parsing #pragma comment, a microsoft extension
documented here:
http://msdn.microsoft.com/en-us/library/7f0aews7(VS.80).aspx

This is according to my understanding reading the docs, I don't know if it
really agrees fully with what VC++ allows.

Added:
    cfe/trunk/test/Preprocessor/pragma_microsoft.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Lex/Pragma.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=62317&r1=62316&r2=62317&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Jan 16 02:21:25 2009
@@ -241,6 +241,10 @@
      "attempt to use a poisoned identifier")
 DIAG(err__Pragma_malformed, ERROR,
      "_Pragma takes a parenthesized string literal")
+DIAG(err_pragma_comment_malformed, ERROR,
+     "pragma comment requires parenthesized identifier and optional string")
+DIAG(err_pragma_comment_unknown_kind, ERROR,
+     "unknown kind of pragma comment")
 DIAG(err_defined_macro_name, ERROR,
      "'defined' cannot be used as a macro name")
 DIAG(err_paste_at_start, ERROR,

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

==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Jan 16 02:21:25 2009
@@ -726,6 +726,7 @@
   void HandlePragmaPoison(Token &PoisonTok);
   void HandlePragmaSystemHeader(Token &SysHeaderTok);
   void HandlePragmaDependency(Token &DependencyTok);
+  void HandlePragmaComment(Token &CommentTok);
 };
 
 /// PreprocessorFactory - A generic factory interface for lazily creating

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

==============================================================================
--- cfe/trunk/lib/Lex/Pragma.cpp (original)
+++ cfe/trunk/lib/Lex/Pragma.cpp Fri Jan 16 02:21:25 2009
@@ -312,6 +312,74 @@
   }
 }
 
+/// HandlePragmaComment - Handle the microsoft #pragma comment extension.  The
+/// syntax is:
+///   #pragma comment(linker, "foo")
+/// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
+/// "foo" is a string, which is fully macro expanded, and permits string
+/// concatenation, embeded escape characters etc.  See MSDN for more details.
+void Preprocessor::HandlePragmaComment(Token &Tok) {
+  SourceLocation CommentLoc = Tok.getLocation();
+  Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(CommentLoc, diag::err_pragma_comment_malformed);
+    return;
+  }
+  
+  // Read the identifier.
+  Lex(Tok);
+  if (Tok.isNot(tok::identifier)) {
+    Diag(CommentLoc, diag::err_pragma_comment_malformed);
+    return;
+  }
+  
+  // Verify that this is one of the 5 whitelisted options.
+  // FIXME: warn that 'exestr' is deprecated.
+  const IdentifierInfo *II = Tok.getIdentifierInfo();
+  if (!II->isStr("compiler") && !II->isStr("exestr") && !II->isStr("lib") && 
+      !II->isStr("linker") && !II->isStr("user")) {
+    Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
+    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.
+  Lex(Tok);
+  if (Tok.is(tok::comma)) {
+    // FIXME: for now, we parse but ignore the string.
+    Lex(Tok);
+
+    // We need at least one string.
+    if (Tok.getKind() != tok::string_literal) {
+      Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
+      return;
+    }
+
+    // String concatenation allows multiple strings, which can even come from
+    // macro expansion.
+    // "foo " "bar" "Baz"
+    while (Tok.getKind() == tok::string_literal)
+      Lex(Tok);
+  }
+  
+  if (Tok.isNot(tok::r_paren)) {
+    Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
+    return;
+  }
+  Lex(Tok);
+
+  if (Tok.isNot(tok::eom)) {
+    Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
+    return;
+  }
+}
+
+
+
 
 /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
 /// If 'Namespace' is non-null, then it is a token required to exist on the
@@ -413,6 +481,14 @@
     PP.HandlePragmaDependency(DepToken);
   }
 };
+  
+/// PragmaCommentHandler - "#pragma comment ...".
+struct PragmaCommentHandler : public PragmaHandler {
+  PragmaCommentHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
+  virtual void HandlePragma(Preprocessor &PP, Token &CommentTok) {
+    PP.HandlePragmaComment(CommentTok);
+  }
+};
 }  // end anonymous namespace
 
 
@@ -426,4 +502,8 @@
                                           getIdentifierInfo("system_header")));
   AddPragmaHandler("GCC", new PragmaDependencyHandler(
                                           getIdentifierInfo("dependency")));
+  
+  // MS extensions.
+  if (Features.Microsoft)
+    AddPragmaHandler(0, new PragmaCommentHandler(getIdentifierInfo("comment")));
 }

Added: cfe/trunk/test/Preprocessor/pragma_microsoft.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/pragma_microsoft.c?rev=62317&view=auto

==============================================================================
--- cfe/trunk/test/Preprocessor/pragma_microsoft.c (added)
+++ cfe/trunk/test/Preprocessor/pragma_microsoft.c Fri Jan 16 02:21:25 2009
@@ -0,0 +1,18 @@
+// RUN: clang %s -fsyntax-only -verify -fms-extensions
+
+// rdar://6495941
+
+#define FOO 1
+#define BAR "2"
+
+#pragma comment(linker,"foo=" FOO) // expected-error {{pragma comment requires parenthesized identifier and optional string}}
+#pragma comment(linker," bar=" BAR)
+
+#pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ ) 
+
+#pragma comment(foo)    // expected-error {{unknown kind of pragma comment}}
+#pragma comment(compiler,)     // expected-error {{pragma comment requires}}
+#define foo compiler
+#pragma comment(foo)   // macro expand kind?
+#pragma comment(foo) x // expected-error {{pragma comment requires}}
+





More information about the cfe-commits mailing list