[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