Nice work, thanks for adding this!<br><br><div class="gmail_quote">On Wed, May 8, 2013 at 2:44 PM, Reid Kleckner <span dir="ltr"><<a href="mailto:reid@kleckner.net" target="_blank">reid@kleckner.net</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Wed May  8 08:44:39 2013<br>
New Revision: 181426<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=181426&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=181426&view=rev</a><br>
Log:<br>
Forward #pragma comment(lib/linker) through as flags metadata<br>
<br>
Summary:<br>
Most of this change is wiring the pragma all the way through from the<br>
lexer, parser, and sema to codegen.  I considered adding a Decl AST node<br>
for this, but it seemed too heavyweight.<br>
<br>
Mach-O already uses a metadata flag called "Linker Options" to do this<br>
kind of auto-linking.  This change follows that pattern.<br>
<br>
LLVM knows how to forward the "Linker Options" metadata into the COFF<br>
.drectve section where these flags belong.  ELF support is not<br>
implemented, but possible.<br>
<br>
This is related to auto-linking, which is <a href="http://llvm.org/PR13016" target="_blank">http://llvm.org/PR13016</a>.<br>
<br>
CC: cfe-commits<br>
<br>
Differential Revision: <a href="http://llvm-reviews.chandlerc.com/D723" target="_blank">http://llvm-reviews.chandlerc.com/D723</a><br>
<br>
Modified:<br>
    cfe/trunk/include/clang/AST/ASTConsumer.h<br>
    cfe/trunk/include/clang/Parse/Parser.h<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/CodeGen/CodeGenAction.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
    cfe/trunk/lib/CodeGen/ModuleBuilder.cpp<br>
    cfe/trunk/lib/CodeGen/TargetInfo.cpp<br>
    cfe/trunk/lib/CodeGen/TargetInfo.h<br>
    cfe/trunk/lib/Parse/ParsePragma.cpp<br>
    cfe/trunk/lib/Parse/ParsePragma.h<br>
    cfe/trunk/lib/Parse/Parser.cpp<br>
    cfe/trunk/lib/Sema/SemaAttr.cpp<br>
    cfe/trunk/test/Modules/autolink.m<br>
<br>
Modified: cfe/trunk/include/clang/AST/ASTConsumer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTConsumer.h?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTConsumer.h?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/AST/ASTConsumer.h (original)<br>
+++ cfe/trunk/include/clang/AST/ASTConsumer.h Wed May  8 08:44:39 2013<br>
@@ -14,6 +14,8 @@<br>
 #ifndef LLVM_CLANG_AST_ASTCONSUMER_H<br>
 #define LLVM_CLANG_AST_ASTCONSUMER_H<br>
<br>
+#include "llvm/ADT/StringRef.h"<br>
+<br>
 namespace clang {<br>
   class ASTContext;<br>
   class CXXRecordDecl;<br>
@@ -86,6 +88,15 @@ public:<br>
   /// The default implementation passes it to HandleTopLevelDecl.<br>
   virtual void HandleImplicitImportDecl(ImportDecl *D);<br>
<br>
+  /// \brief Handle a pragma that appends to Linker Options.  Currently this<br>
+  /// only exists to support Microsoft's #pragma comment(linker, "/foo").<br>
+  virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {}<br>
+<br>
+  /// \brief Handle a dependent library created by a pragma in the source.<br>
+  /// Currently this only exists to support Microsoft's<br>
+  /// #pragma comment(lib, "/foo").<br>
+  virtual void HandleDependentLibrary(llvm::StringRef Lib) {}<br>
+<br>
   /// CompleteTentativeDefinition - Callback invoked at the end of a translation<br>
   /// unit to notify the consumer that the given tentative definition should be<br>
   /// completed.<br>
<br>
Modified: cfe/trunk/include/clang/Parse/Parser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Parse/Parser.h (original)<br>
+++ cfe/trunk/include/clang/Parse/Parser.h Wed May  8 08:44:39 2013<br>
@@ -419,6 +419,10 @@ private:<br>
   void HandlePragmaMSStruct();<br>
<br>
   /// \brief Handle the annotation token produced for<br>
+  /// #pragma comment...<br>
+  void HandlePragmaMSComment();<br>
+<br>
+  /// \brief Handle the annotation token produced for<br>
   /// #pragma align...<br>
   void HandlePragmaAlign();<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Wed May  8 08:44:39 2013<br>
@@ -49,6 +49,7 @@<br>
 #include "llvm/MC/MCParser/MCAsmParser.h"<br>
 #include <deque><br>
 #include <string><br>
+#include <vector><br>
<br>
 namespace llvm {<br>
   class APSInt;<br>
@@ -6584,6 +6585,15 @@ public:<br>
     PMSST_ON    // #pragms ms_struct on<br>
   };<br>
<br>
+  enum PragmaMSCommentKind {<br>
+    PCK_Unknown,<br>
+    PCK_Linker,   // #pragma comment(linker, ...)<br>
+    PCK_Lib,      // #pragma comment(lib, ...)<br>
+    PCK_Compiler, // #pragma comment(compiler, ...)<br>
+    PCK_ExeStr,   // #pragma comment(exestr, ...)<br>
+    PCK_User      // #pragma comment(user, ...)<br>
+  };<br>
+<br>
   /// ActOnPragmaPack - Called on well formed \#pragma pack(...).<br>
   void ActOnPragmaPack(PragmaPackKind Kind,<br>
                        IdentifierInfo *Name,<br>
@@ -6595,6 +6605,9 @@ public:<br>
   /// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off].<br>
   void ActOnPragmaMSStruct(PragmaMSStructKind Kind);<br>
<br>
+  /// ActOnPragmaMSStruct - Called on well formed \#pragma comment(kind, "arg").<br>
+  void ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg);<br>
+<br>
   /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'.<br>
   void ActOnPragmaUnused(const Token &Identifier,<br>
                          Scope *curScope,<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Wed May  8 08:44:39 2013<br>
@@ -179,6 +179,14 @@ namespace clang {<br>
       Gen->HandleVTable(RD, DefinitionRequired);<br>
     }<br>
<br>
+    virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {<br>
+      Gen->HandleLinkerOptionPragma(Opts);<br>
+    }<br>
+<br>
+    virtual void HandleDependentLibrary(llvm::StringRef Opts) {<br>
+      Gen->HandleDependentLibrary(Opts);<br>
+    }<br>
+<br>
     static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,<br>
                                      unsigned LocCookie) {<br>
       SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed May  8 08:44:39 2013<br>
@@ -186,7 +186,8 @@ void CodeGenModule::Release() {<br>
   EmitStaticExternCAliases();<br>
   EmitLLVMUsed();<br>
<br>
-  if (CodeGenOpts.Autolink && Context.getLangOpts().Modules) {<br>
+  if (CodeGenOpts.Autolink &&<br>
+      (Context.getLangOpts().Modules || !LinkerOptionsMetadata.empty())) {<br>
     EmitModuleLinkOptions();<br>
   }<br>
<br>
@@ -762,31 +763,41 @@ void CodeGenModule::EmitLLVMUsed() {<br>
   GV->setSection("llvm.metadata");<br>
 }<br>
<br>
+void CodeGenModule::AppendLinkerOptions(StringRef Opts) {<br>
+  llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opts);<br>
+  LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts));<br>
+}<br>
+<br>
+void CodeGenModule::AddDependentLib(StringRef Lib) {<br>
+  llvm::SmallString<24> Opt;<br>
+  getTargetCodeGenInfo().getDependentLibraryOption(Lib, Opt);<br>
+  llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opt);<br>
+  LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts));<br>
+}<br>
+<br>
 /// \brief Add link options implied by the given module, including modules<br>
 /// it depends on, using a postorder walk.<br>
-static void addLinkOptionsPostorder(llvm::LLVMContext &Context,<br>
+static void addLinkOptionsPostorder(CodeGenModule &CGM,<br>
                                     Module *Mod,<br>
                                     SmallVectorImpl<llvm::Value *> &Metadata,<br>
                                     llvm::SmallPtrSet<Module *, 16> &Visited) {<br>
   // Import this module's parent.<br>
   if (Mod->Parent && Visited.insert(Mod->Parent)) {<br>
-    addLinkOptionsPostorder(Context, Mod->Parent, Metadata, Visited);<br>
+    addLinkOptionsPostorder(CGM, Mod->Parent, Metadata, Visited);<br>
   }<br>
<br>
   // Import this module's dependencies.<br>
   for (unsigned I = Mod->Imports.size(); I > 0; --I) {<br>
     if (Visited.insert(Mod->Imports[I-1]))<br>
-      addLinkOptionsPostorder(Context, Mod->Imports[I-1], Metadata, Visited);<br>
+      addLinkOptionsPostorder(CGM, Mod->Imports[I-1], Metadata, Visited);<br>
   }<br>
<br>
   // Add linker options to link against the libraries/frameworks<br>
   // described by this module.<br>
+  llvm::LLVMContext &Context = CGM.getLLVMContext();<br>
   for (unsigned I = Mod->LinkLibraries.size(); I > 0; --I) {<br>
-    // FIXME: -lfoo is Unix-centric and -framework Foo is Darwin-centric.<br>
-    // We need to know more about the linker to know how to encode these<br>
-    // options propertly.<br>
-<br>
-    // Link against a framework.<br>
+    // Link against a framework.  Frameworks are currently Darwin only, so we<br>
+    // don't to ask TargetCodeGenInfo for the spelling of the linker option.<br>
     if (Mod->LinkLibraries[I-1].IsFramework) {<br>
       llvm::Value *Args[2] = {<br>
         llvm::MDString::get(Context, "-framework"),<br>
@@ -798,9 +809,10 @@ static void addLinkOptionsPostorder(llvm<br>
     }<br>
<br>
     // Link against a library.<br>
-    llvm::Value *OptString<br>
-    = llvm::MDString::get(Context,<br>
-                          "-l" + Mod->LinkLibraries[I-1].Library);<br>
+    llvm::SmallString<24> Opt;<br>
+    CGM.getTargetCodeGenInfo().getDependentLibraryOption(<br>
+      Mod->LinkLibraries[I-1].Library, Opt);<br>
+    llvm::Value *OptString = llvm::MDString::get(Context, Opt);<br>
     Metadata.push_back(llvm::MDNode::get(Context, OptString));<br>
   }<br>
 }<br>
@@ -852,20 +864,23 @@ void CodeGenModule::EmitModuleLinkOption<br>
   }<br>
<br>
   // Add link options for all of the imported modules in reverse topological<br>
-  // order.<br>
+  // order.  We don't do anything to try to order import link flags with respect<br>
+  // to linker options inserted by things like #pragma comment().<br>
   SmallVector<llvm::Value *, 16> MetadataArgs;<br>
   Visited.clear();<br>
   for (llvm::SetVector<clang::Module *>::iterator M = LinkModules.begin(),<br>
                                                MEnd = LinkModules.end();<br>
        M != MEnd; ++M) {<br>
     if (Visited.insert(*M))<br>
-      addLinkOptionsPostorder(getLLVMContext(), *M, MetadataArgs, Visited);<br>
+      addLinkOptionsPostorder(*this, *M, MetadataArgs, Visited);<br>
   }<br>
   std::reverse(MetadataArgs.begin(), MetadataArgs.end());<br>
+  LinkerOptionsMetadata.append(MetadataArgs.begin(), MetadataArgs.end());<br>
<br>
   // Add the linker options metadata flag.<br>
   getModule().addModuleFlag(llvm::Module::AppendUnique, "Linker Options",<br>
-                            llvm::MDNode::get(getLLVMContext(), MetadataArgs));<br>
+                            llvm::MDNode::get(getLLVMContext(),<br>
+                                              LinkerOptionsMetadata));<br>
 }<br>
<br>
 void CodeGenModule::EmitDeferred() {<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed May  8 08:44:39 2013<br>
@@ -355,6 +355,9 @@ class CodeGenModule : public CodeGenType<br>
   /// \brief The complete set of modules that has been imported.<br>
   llvm::SetVector<clang::Module *> ImportedModules;<br>
<br>
+  /// \brief A vector of metadata strings.<br>
+  SmallVector<llvm::Value *, 16> LinkerOptionsMetadata;<br>
+<br>
   /// @name Cache for Objective-C runtime types<br>
   /// @{<br>
<br>
@@ -906,6 +909,12 @@ public:<br>
<br>
   void EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired);<br>
<br>
+  /// \brief Appends Opts to the "Linker Options" metadata value.<br>
+  void AppendLinkerOptions(StringRef Opts);<br>
+<br>
+  /// \brief Appends a dependent lib to the "Linker Options" metadata value.<br>
+  void AddDependentLib(StringRef Lib);<br>
+<br>
   llvm::GlobalVariable::LinkageTypes<br>
   getFunctionLinkage(const FunctionDecl *FD);<br>
<br>
<br>
Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Wed May  8 08:44:39 2013<br>
@@ -20,6 +20,7 @@<br>
 #include "clang/Basic/TargetInfo.h"<br>
 #include "clang/Frontend/CodeGenOptions.h"<br>
 #include "llvm/ADT/OwningPtr.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
 #include "llvm/IR/DataLayout.h"<br>
 #include "llvm/IR/LLVMContext.h"<br>
 #include "llvm/IR/Module.h"<br>
@@ -115,6 +116,14 @@ namespace {<br>
<br>
       Builder->EmitVTable(RD, DefinitionRequired);<br>
     }<br>
+<br>
+    virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {<br>
+      Builder->AppendLinkerOptions(Opts);<br>
+    }<br>
+<br>
+    virtual void HandleDependentLibrary(llvm::StringRef Lib) {<br>
+      Builder->AddDependentLib(Lib);<br>
+    }<br>
   };<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed May  8 08:44:39 2013<br>
@@ -143,6 +143,16 @@ bool TargetCodeGenInfo::isNoProtoCallVar<br>
   return false;<br>
 }<br>
<br>
+void<br>
+TargetCodeGenInfo::getDependentLibraryOption(llvm::StringRef Lib,<br>
+                                             llvm::SmallString<24> &Opt) const {<br>
+  // This assumes the user is passing a library name like "rt" instead of a<br>
+  // filename like "librt.a/so", and that they don't care whether it's static or<br>
+  // dynamic.<br>
+  Opt = "-l";<br>
+  Opt += Lib;<br>
+}<br>
+<br>
 static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);<br>
<br>
 /// isEmptyField - Return true iff a the field is "empty", that is it<br>
@@ -1256,6 +1266,18 @@ public:<br>
<br>
 };<br>
<br>
+class WinX86_32TargetCodeGenInfo : public X86_32TargetCodeGenInfo {<br>
+public:<br>
+  WinX86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned RegParms)<br>
+    : X86_32TargetCodeGenInfo(CGT, false, true, true, RegParms) {}<br>
+<br>
+  void getDependentLibraryOption(llvm::StringRef Lib,<br>
+                                 llvm::SmallString<24> &Opt) const {<br>
+    Opt = "/DEFAULTLIB:";<br>
+    Opt += Lib;<br>
+  }<br>
+};<br>
+<br>
 class WinX86_64TargetCodeGenInfo : public TargetCodeGenInfo {<br>
 public:<br>
   WinX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)<br>
@@ -1274,6 +1296,12 @@ public:<br>
     AssignToArrayRange(CGF.Builder, Address, Eight8, 0, 16);<br>
     return false;<br>
   }<br>
+<br>
+  void getDependentLibraryOption(llvm::StringRef Lib,<br>
+                                 llvm::SmallString<24> &Opt) const {<br>
+    Opt = "/DEFAULTLIB:";<br>
+    Opt += Lib;<br>
+  }<br>
 };<br>
<br>
 }<br>
@@ -5173,8 +5201,8 @@ const TargetCodeGenInfo &CodeGenModule::<br>
<br>
     case llvm::Triple::Win32:<br>
       return *(TheTargetCodeGenInfo =<br>
-               new X86_32TargetCodeGenInfo(Types, false, true, true,<br>
-                                           CodeGenOpts.NumRegisterParameters));<br>
+               new WinX86_32TargetCodeGenInfo(Types,<br>
+                                              CodeGenOpts.NumRegisterParameters));<br>
<br>
     default:<br>
       return *(TheTargetCodeGenInfo =<br>
<br>
Modified: cfe/trunk/lib/CodeGen/TargetInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.h?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.h?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/TargetInfo.h (original)<br>
+++ cfe/trunk/lib/CodeGen/TargetInfo.h Wed May  8 08:44:39 2013<br>
@@ -18,6 +18,7 @@<br>
 #include "clang/AST/Type.h"<br>
 #include "clang/Basic/LLVM.h"<br>
 #include "llvm/ADT/StringRef.h"<br>
+#include "llvm/ADT/SmallString.h"<br>
<br>
 namespace llvm {<br>
   class GlobalValue;<br>
@@ -167,6 +168,11 @@ namespace clang {<br>
     /// that unprototyped calls to varargs functions still succeed.<br>
     virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args,<br>
                                        const FunctionNoProtoType *fnType) const;<br>
+<br>
+    /// Gets the linker options necessary to link a dependent library on this<br>
+    /// platform.<br>
+    virtual void getDependentLibraryOption(llvm::StringRef Lib,<br>
+                                           llvm::SmallString<24> &Opt) const;<br>
   };<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/Parse/ParsePragma.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Wed May  8 08:44:39 2013<br>
@@ -821,10 +821,16 @@ void PragmaCommentHandler::HandlePragma(<br>
   }<br>
<br>
   // Verify that this is one of the 5 whitelisted options.<br>
-  // FIXME: warn that 'exestr' is deprecated.<br>
-  const IdentifierInfo *II = Tok.getIdentifierInfo();<br>
-  if (!II->isStr("compiler") && !II->isStr("exestr") && !II->isStr("lib") &&<br>
-      !II->isStr("linker") && !II->isStr("user")) {<br>
+  IdentifierInfo *II = Tok.getIdentifierInfo();<br>
+  Sema::PragmaMSCommentKind Kind =<br>
+    llvm::StringSwitch<Sema::PragmaMSCommentKind>(II->getName())<br>
+    .Case("linker",   Sema::PCK_Linker)<br>
+    .Case("lib",      Sema::PCK_Lib)<br>
+    .Case("compiler", Sema::PCK_Compiler)<br>
+    .Case("exestr",   Sema::PCK_ExeStr)<br>
+    .Case("user",     Sema::PCK_User)<br>
+    .Default(Sema::PCK_Unknown);<br>
+  if (Kind == Sema::PCK_Unknown) {<br>
     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);<br>
     return;<br>
   }<br>
@@ -837,11 +843,12 @@ void PragmaCommentHandler::HandlePragma(<br>
                                                  /*MacroExpansion=*/true))<br>
     return;<br>
<br>
+  // FIXME: warn that 'exestr' is deprecated.<br>
   // FIXME: If the kind is "compiler" warn if the string is present (it is<br>
   // ignored).<br>
-  // FIXME: 'lib' requires a comment string.<br>
-  // FIXME: 'linker' requires a comment string, and has a specific list of<br>
-  // things that are allowable.<br>
+  // The MSDN docs say that "lib" and "linker" require a string and have a short<br>
+  // whitelist of linker options they support, but in practice MSVC doesn't<br>
+  // issue a diagnostic.  Therefore neither does clang.<br>
<br>
   if (Tok.isNot(tok::r_paren)) {<br>
     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);<br>
@@ -857,4 +864,6 @@ void PragmaCommentHandler::HandlePragma(<br>
   // If the pragma is lexically sound, notify any interested PPCallbacks.<br>
   if (PP.getPPCallbacks())<br>
     PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);<br>
+<br>
+  Actions.ActOnPragmaMSComment(Kind, ArgumentString);<br>
 }<br>
<br>
Modified: cfe/trunk/lib/Parse/ParsePragma.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.h?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.h?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Parse/ParsePragma.h (original)<br>
+++ cfe/trunk/lib/Parse/ParsePragma.h Wed May  8 08:44:39 2013<br>
@@ -116,9 +116,12 @@ public:<br>
 /// PragmaCommentHandler - "\#pragma comment ...".<br>
 class PragmaCommentHandler : public PragmaHandler {<br>
 public:<br>
-  PragmaCommentHandler() : PragmaHandler("comment") {}<br>
+  PragmaCommentHandler(Sema &Actions)<br>
+    : PragmaHandler("comment"), Actions(Actions) {}<br>
   virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,<br>
                             Token &FirstToken);<br>
+private:<br>
+  Sema &Actions;<br>
 };<br>
<br>
 }  // end namespace clang<br>
<br>
Modified: cfe/trunk/lib/Parse/Parser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Parse/Parser.cpp (original)<br>
+++ cfe/trunk/lib/Parse/Parser.cpp Wed May  8 08:44:39 2013<br>
@@ -103,7 +103,7 @@ Parser::Parser(Preprocessor &pp, Sema &a<br>
   PP.AddPragmaHandler(OpenMPHandler.get());<br>
<br>
   if (getLangOpts().MicrosoftExt) {<br>
-    MSCommentHandler.reset(new PragmaCommentHandler());<br>
+    MSCommentHandler.reset(new PragmaCommentHandler(actions));<br>
     PP.AddPragmaHandler(MSCommentHandler.get());<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaAttr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Wed May  8 08:44:39 2013<br>
@@ -13,6 +13,7 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "clang/Sema/SemaInternal.h"<br>
+#include "clang/AST/ASTConsumer.h"<br>
 #include "clang/AST/Attr.h"<br>
 #include "clang/AST/Expr.h"<br>
 #include "clang/Basic/TargetInfo.h"<br>
@@ -263,6 +264,26 @@ void Sema::ActOnPragmaMSStruct(PragmaMSS<br>
   MSStructPragmaOn = (Kind == PMSST_ON);<br>
 }<br>
<br>
+void Sema::ActOnPragmaMSComment(PragmaMSCommentKind Kind, llvm::StringRef Arg) {<br>
+  // FIXME: Serialize this.<br>
+  switch (Kind) {<br>
+  case PCK_Unknown:<br>
+    llvm_unreachable("unexpected pragma comment kind");<br>
+  case PCK_Linker:<br>
+    Consumer.HandleLinkerOptionPragma(Arg);<br>
+    return;<br>
+  case PCK_Lib: {<br>
+    Consumer.HandleDependentLibrary(Arg);<br>
+    return;<br>
+  }<br>
+  case PCK_Compiler:<br>
+  case PCK_ExeStr:<br>
+  case PCK_User:<br>
+    return;  // We ignore all of these.<br>
+  }<br>
+  llvm_unreachable("invalid pragma comment kind");<br>
+}<br>
+<br>
 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,<br>
                              SourceLocation PragmaLoc) {<br>
<br>
<br>
Modified: cfe/trunk/test/Modules/autolink.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/autolink.m?rev=181426&r1=181425&r2=181426&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/autolink.m?rev=181426&r1=181425&r2=181426&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/Modules/autolink.m (original)<br>
+++ cfe/trunk/test/Modules/autolink.m Wed May  8 08:44:39 2013<br>
@@ -35,7 +35,7 @@ int use_no_umbrella() {<br>
 // CHECK: !4 = metadata !{i32 6, metadata !"Linker Options", metadata ![[AUTOLINK_OPTIONS:[0-9]+]]}<br>
 // CHECK: ![[AUTOLINK_OPTIONS]] = metadata !{metadata ![[AUTOLINK_FRAMEWORK:[0-9]+]], metadata ![[AUTOLINK:[0-9]+]], metadata ![[DEPENDSONMODULE:[0-9]+]], metadata ![[MODULE:[0-9]+]], metadata ![[NOUMBRELLA:[0-9]+]]}<br>


 // CHECK: ![[AUTOLINK_FRAMEWORK]] = metadata !{metadata !"-framework", metadata !"autolink_framework"}<br>
-// CHECK: ![[AUTOLINK]] = metadata !{metadata !"-lautolink"}<br>
+// CHECK: ![[AUTOLINK]] = metadata !{metadata !"{{(-l|/DEFAULTLIB:)}}autolink"}<br>
 // CHECK: ![[DEPENDSONMODULE]] = metadata !{metadata !"-framework", metadata !"DependsOnModule"}<br>
 // CHECK: ![[MODULE]] = metadata !{metadata !"-framework", metadata !"Module"}<br>
 // CHECK: ![[NOUMBRELLA]] = metadata !{metadata !"-framework", metadata !"NoUmbrella"}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>João Matos