Analysis group?

Hi,

I am attempting to create a shared object with a few passes that get loaded into opt via -load. I am creating an analysis group and attempting to set the default. When I make the default pass extend CallGraphSCCPass, I get the following assertion from opt:

opt: /llvm-3.7.0/lib/Analysis/IPA/CallGraphSCCPass.cpp:554: virtual void llvm::CallGraphSCCPass::assignPassManager(llvm::PMStack &, llvm::PassManagerType): Assertion `!PMS.empty() && “Unable to handle Call Graph Pass”’ failed.
0 opt 0x000000000125b11d llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 45
1 opt 0x000000000125c5fb
2 libpthread.so.0 0x000000374620f500
3 libc.so.6 0x0000003745a328e5 gsignal + 53
4 libc.so.6 0x0000003745a340c5 abort + 373
5 libc.so.6 0x0000003745a2ba0e
6 libc.so.6 0x0000003745a2bad0 __assert_perror_fail + 0
7 opt 0x0000000000e6d619 llvm::CallGraphSCCPass::assignPassManager(llvm::PMStack&, llvm::PassManagerType) + 489
8 opt 0x00000000011b9cdc llvm::PMTopLevelManager::schedulePass(llvm::Pass*) + 2268
9 opt 0x00000000011c1ef3
10 opt 0x00000000011bcfda llvm::PMDataManager::add(llvm::Pass*, bool) + 906
11 opt 0x00000000011b9cdc llvm::PMTopLevelManager::schedulePass(llvm::Pass*) + 2268
12 opt 0x0000000000533a8c main + 6380
13 libc.so.6 0x0000003745a1ecdd __libc_start_main + 253
14 opt 0x0000000000526799
Stack dump:
0. Program arguments: opt -load Debug.so file.ll -S -user
Aborted (core dumped)

If I change my default pass to extend ModulePass, everything runs fine.

My test case is below. Is this a bug? Have I missed something? Is this unsupported?

Thanks,

Matt

// PassX.h

#ifndef PASSX_H
#define PASSX_H

class PassX {
public:
static char ID;

PassX() {}
virtual ~PassX(){};

virtual bool get(void) const = 0;
};

#endif // PASSX_H

// PassXImpl.cpp
#include
#include “llvm/Analysis/CallGraphSCCPass.h”
#include “PassX.h”
using namespace llvm;

namespace {
struct PassXImpl : public CallGraphSCCPass, public PassX {
static char ID;
PassXImpl() : CallGraphSCCPass(ID) {}
~PassXImpl() {}

virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
if (PI == &PassX::ID)
return (PassX *)this;
return this;
}

virtual void getAnalysisUsage(AnalysisUsage &AU) const {
CallGraphSCCPass::getAnalysisUsage(AU);
}

virtual bool runOnSCC(CallGraphSCC &) { return false; }

virtual bool get(void) const { return true; }
};
}

char PassX::ID = 0;
static RegisterAnalysisGroup G(“PassX”);

char PassXImpl::ID = 0;
static RegisterPass P(“passx”, “Default PassX”);

RegisterAnalysisGroup<PassX, true> Default(P);

// User.cpp

#include
#include “llvm/Pass.h”
#include “PassX.h”
using namespace llvm;

namespace {
struct User : public ModulePass {
static char ID;
User() : ModulePass(ID) {}
~User() {}

virtual void getAnalysisUsage(AnalysisUsage &AU) const {
ModulePass::getAnalysisUsage(AU);
AU.addRequired();
}

virtual bool runOnModule(Module &) {
PassX &P = getAnalysis();
return P.get();
}
};
}

char User::ID = 0;
static RegisterPass P(“user”, “Default User”);