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

Eli Friedman eli.friedman at gmail.com
Wed May 18 19:02:08 PDT 2011


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?

-Eli




More information about the llvm-commits mailing list