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