New PassManager: PassPluginLibraryInfo How can I capture my variable or modify which and wether passes shall be added based on variables?

what does not work:

        [&myarg](PassBuilder &PB) {
            PB.registerPipelineParsingCallback(
                [](StringRef Name, FunctionPassManager &FPM,ArrayRef<PassBuilder::PipelineElement>) {
                    if(Name == "hello-new-pm-pass"){
                         FPM.addPass(getHelloNewPMPass(myarg));
                        return true;
                    }
                    return false;
                   }
            );

could not convert ‘{1, "HelloNewPMPass", "v0.1", <lambda closure object>llvmGetPassPluginInfo()::<lambda(llvm::PassBuilder&)>{arginfo}}’ from ‘<brace-enclosed initializer list>’ to ‘llvm::PassPluginLibraryInfo’

What works:

        [](PassBuilder &PB) {
            PB.registerPipelineParsingCallback(
                [](StringRef Name, FunctionPassManager &FPM,ArrayRef<PassBuilder::PipelineElement>) {
                    if(Name == "hello-new-pm-pass"){
                         FPM.addPass(getHelloNewPMPass("VERY CONST"));
                        return true;
                    }
                    return false;
                   }
            );

So how can I capture my variable or modify which and wether passes shall be added based on variables?

Looks like you use 2 lambdas

[&myarg](PassBuilder &PB)

and

[](StringRef Name, FunctionPassManager &FPM,ArrayRef<PassBuilder::PipelineElement>) {

You capture myarg only in the outer lambda but try to use it in the inner lambda.

Regards,
Kai

I left the second lambda, because the error is not the not captured variable but that capturing in the outer lambda already breaks the compilation.
Obviously the problem is, that a function pointer is expected but a capturing lambda does not return one? But how to make variables available?

Maybe the real problem is in code that you left out. With a definition like

struct HelloPass : PassInfoMixin<HelloPass> {
  HelloPass();
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};

HelloPass getHelloNewPMPass(const char *Str) {
  return HelloPass();
}

the following compiles fine for me:

  const char *myarg = "VERY CONST";
  auto x = [&myarg](PassBuilder &PB) {
              PB.registerPipelineParsingCallback(
                  [&myarg](StringRef Name, FunctionPassManager &FPM,ArrayRef<PassBuilder::PipelineElement>) {
                      if(Name == "hello-new-pm-pass"){
                           FPM.addPass(getHelloNewPMPass(myarg));
                          return true;
                      }
                      return false;
                     }
              );
  };

If I leave out the inner capture, then I get the error message:

error: variable 'myarg' cannot be implicitly captured in a lambda with no capture-default specified

Therefore I guess the problem is not the lambda but the way it is used.

Regards,
Kai

Sorry, took a long time but finally I understand your question. The definition of the last field in PassPluginLibraryInfo is

  void (*RegisterPassBuilderCallbacks)(PassBuilder &);

This is a pointer to a function, which is not compatible with a lambda capturing local variables.
Since this is all embedded in function llvmGetPassPluginInfo(), is there a reason that you can’t use a static variable (at file level) or a function returning the value?

Regards,
Kai

thats indeed a viable option. thanks