[llvm-commits] [llvm] r131592 - /llvm/trunk/include/llvm/Support/StandardPasses.h

Francois Pichet pichet2000 at gmail.com
Wed May 18 20:00:23 PDT 2011


On Wed, May 18, 2011 at 10:02 PM, Eli Friedman <eli.friedman at gmail.com> wrote:
> On Wed, May 18, 2011 at 6:35 PM, Francois Pichet <pichet2000 at gmail.com> wrote:
>> On Wed, May 18, 2011 at 6:46 PM, David Chisnall <csdavec at swan.ac.uk> wrote:
>>> Author: theraven
>>> Date: Wed May 18 17:46:02 2011
>>> New Revision: 131592
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=131592&view=rev
>>> Log:
>>> Some better type safety enforcement in the standard pass list, along with some small tidies and some fixes for bugs that the stricter checking found.
>>>
>>>
>>> Modified:
>>>    llvm/trunk/include/llvm/Support/StandardPasses.h
>>>
>>> Modified: llvm/trunk/include/llvm/Support/StandardPasses.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=131592&r1=131591&r2=131592&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Support/StandardPasses.h (original)
>>> +++ llvm/trunk/include/llvm/Support/StandardPasses.h Wed May 18 17:46:02 2011
>>> @@ -27,6 +27,7 @@
>>>  #include "llvm/Transforms/IPO.h"
>>>
>>>  namespace llvm {
>>> +    //template<Pass*(*X)(void)> static Pass *CreatePassFn(void) { return X(); }
>>>
>>>   /// RegisterStandardPassLists solves a circular dependency problem.  The
>>>   /// default list of passes has to live somewhere.  It can't live in the core
>>> @@ -42,23 +43,36 @@
>>>       StandardPass::CreateVerifierPass = CreateVerifierPass;
>>>     }
>>>     private:
>>> +    /// Define a template function that does the casting for us, so that we can
>>> +    /// perform safe function pointer casts, but catch unsafe ones.
>>> +    template<llvm::ImmutablePass*(*X)(void)> static llvm::Pass*
>>> +      CreatePassFn(void) { return X(); }
>>> +    template<llvm::ModulePass*(*X)(void)> static llvm::Pass*
>>> +      CreatePassFn(void) { return X(); }
>>> +    template<llvm::FunctionPass*(*X)(void)> static llvm::Pass*
>>> +      CreatePassFn(void) { return X(); }
>>> +    template<llvm::Pass*(*X)(void)> static llvm::Pass*
>>> +      CreatePassFn(void) { return X(); }
>>>     static llvm::Pass *CreateVerifierPass() { return createVerifierPass(); }
>>
>>
>> Hi.. this is too much for MSVC 2010. It wont compile:
>>
>> This is a reduction of the problem:
>> ===========================
>> class A {};
>> class B {};
>>
>> template<A*(*X)(void)> static void CreatePassFn(void) {  }
>> template<B*(*X)(void)> static void CreatePassFn(void) {  }
>>
>> B* CreatePassX(void);
>>
>> int main()
>> {
>>   CreatePassFn<CreatePassX>(); // <== error here.
>>   return 1;
>> }
>> ===========================
>>
>> This code will compile fine with clang and gcc 4.5. MSVC 2010 will fail.
>> Seems like MSVC cannot deduce template arguments that are function and
>> that differ only by return type.
>>
>> Anybody have an idea on how to redesign this to make it MSVC friendly?
>
> I suppose we could use something like the following instead:
> PassInfo::NormalCtor_t static
> getPassFn(llvm::ImmutablePass*(*X)(void)) { return
> reinterpret_cast<PassInfo::NormalCtor_t>(X); }
> PassInfo::NormalCtor_t static getPassFn(llvm::ModulePass*(*X)(void)) {
> return reinterpret_cast<PassInfo::NormalCtor_t>(X); }
> PassInfo::NormalCtor_t static getPassFn(llvm::FunctionPass*(*X)(void))
> { return reinterpret_cast<PassInfo::NormalCtor_t>(X); }
> PassInfo::NormalCtor_t static getPassFn(llvm::Pass*(*X)(void)) {
> return reinterpret_cast<PassInfo::NormalCtor_t>(X); }
>
> Does that sort of thing work with MSVC?
>

yes see r131624.
Thank you for your solution. It really helped.




More information about the llvm-commits mailing list