How can I fix an undefined symbol when using "LoopInfo::getLoopFor"? - llvm

I'm trying to write a pass that go through each basic block, and I want to identify whether each basic block is in a loop or not.
I added LoopInfo as a required analysis:
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addRequired<LoopInfo>();
AU.addPreserved<LoopInfo>();
}
And then called getLoopFor:
virtual bool runOnFunction(Function &Func) {
OptimizeBB(bb);
return false;
}
virtual void OptimizeBB(BasicBlock &bb){
LoopInfo &LI = getAnalysis<LoopInfo>();
errs()<<" \nDebug Here\n ";
Loop* innerloop=LI.getLoopFor(&bb);
if(innerloop==NULL){ errs()<<" \n(not loop)\n ";}
else { errs()<<" \n(loop)\n ";}
}
But I'm getting the following error:
/home/mypass/llvm/Debug+Asserts/bin/opt: symbol lookup error: /home/mypass/llvm/Debug+Asserts/lib/ReadIR.so: undefined symbol: _ZNK4llvm12LoopInfoBaseINS_10BasicBlockENS_4LoopEE10getLoopForEPKS1_
How can I fix that? Or is there any other method that can identify a loop for a basic block?

I am assuming you have the correct headers included. In the following code, what are you passing as bb ?
virtual bool runOnFunction(Function &Func) {
OptimizeBB(bb);
return false;
}
You need to iterate over Func to get the BBs within Func and then pass them to OptimizeBB().

Try this
virtual bool runOnFunction(Function &Func) {
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
OptimizeBB(bb);
return false;
}

Related

Using EXPECT_CALL for local methods

I know EXPECT_CALL is supposed to be used for mocked classes and their objects/methods. But is it ever possible to use this to expect calls of local methods?
void Sample::Init()
{
// some codes here...
auto enabled = isFeatureEnabled();
//some other things here
}
bool Sample::isFeatureEnabled()
{
return lights_ and sounds_;
}
I want to EXPECT_CALL isFeatureEnabled() - is this at all possible?
You can try this, I find this approach useful:
class template_method_base {
public:
void execute(std::string s1, std::string s2) {
delegate(s1 + s2);
}
private:
virtual void delegate(std::string s) = 0;
};
class template_method_testable : public template_method_base {
public:
MOCK_METHOD1(delegate, void(std::string s));
};
TEST(TestingTemplateMethod, shouldDelegateCallFromExecute) {
template_method_testable testable_obj{};
EXPECT_CALL(testable_obj, delegate("AB"));
testable_obj.execute("A", "B");
}

Omitting parameter with default value in a subclass function override

I am writing an interface for several I/O classes.
There is a function that looks for information in different kinds of files (sometimes html, sdb, txt, ...):
bool Search(std::string file, std::string field)
However, one of these requires an additional parameter to complement the SQL query. In this case the sdb needs to specify in what table the field is located.
I am trying something like the following (it does not compile, I am aware):
class fileIO{
public:
virtual ~FileIO(){};
virtual bool Search(std::string file, std::string field,
std::string additional = 0 /* for sdb only */) = 0;
}
class readHTML : fileIO{
public:
bool Search(std::string file, std::string field); //does NOT override virtual method
Is there anything that can give me the behavior I am looking for?
Is such strategy according to C++ standards?
What else could I add to replace such enforcement on the interface?
I am sorry if the title is misleading, I am looking for an alternative with that behavior. I could not find it so far.
You don't need it, I'd say.
At the caller site, there is only two possibilities: you know your specific fileIO instance is a sdbIO or you don't. If you do, you can call an overloaded version of Search defined in sdbIO which takes this additional info. If you don't, you don't and sdbIO::Search should be defined in terms of its overloaded version.
struct fileIO
{
virtual bool Search(std::string file, std::string field) = 0;
}
struct sdbIO : fileIO
{
bool Search(std::string file, std::string field, std::string additional);
bool Search(std::string file, std::string field) override
{
Search(file, field, "");
}
};
At the caller site:
void f(fileIO& io)
{
// I know this is a sdb:
dynamic_cast<sdbIO&>(io).Search("/file", "text", "WHERE answer=42");
// I don't
io.Search("/file", "text");
}
notes: do you really need a copy of those strings?
You can hide the virtual function in the non-public interface and make the public interface (with the default argument) non-virtual.
struct Interface
{
...
// public interface calls the abstract members.
bool Search(string const&a, string const&b, string const&c = "")
{
if(c.empty() && need_third_string())
throw runtime_error("search requires an additional string argument");
return search(a,b,c);
}
protected:
virtual bool need_third_string() const = 0;
virtual bool search(string const&, string const&, string const&) const=0;
};
with obvious derivations:
struct A : Interface
{
protected:
bool need_third_string() const override
{ return false; }
bool search(string const&a, string const&b, string const&) const override
{ /* search ignoring third argument */ }
};
struct B : Interface
{
protected:
bool need_third_string() const override
{ return true; }
bool search(string const&a, string const&b, string const&c) const override
{ /* search ignoring using all 3 arguments */ }
};
I don't see any problem with above two way to handle things. Still, I have just one more.
#include<bits/stdc++.h>
#include <stdexcept>
using namespace std;
typedef struct
{
std::string arg1;
std::string arg2;
std::string arg3;
} Param;
class FileIO{
public:
virtual ~FileIO(){};
virtual void Search(Param param) = 0;
};
class ReadHTML : public FileIO{
public:
void Search(Param param)
{
if(param.arg3.length() > 0) // Some logic to handle things here.
search3(param.arg1, param.arg2, param.arg3);
else
throw std::runtime_error("Bad call with param");
}
private:
void search3(std::string arg1, std::string arg2, std::string arg3)
{
std::cout << " I am called with Html::Search3" << std::endl;
}
};
class ReadTxt : public FileIO{
public:
void Search(Param param)
{
if(param.arg1.length() && param.arg2.length()) // Some logic to handle things here.
search2(param.arg1, param.arg2);
else
throw std::runtime_error("Bad call with param");
}
private:
void search2(std::string arg1, std::string arg2)
{
std::cout << " I am called with Txt::Search2" << std::endl;
}
};
// Driver program to test above function
int main()
{
FileIO *io = new ReadHTML();
Param paramHtml = {"a", "b", "c"};
io->Search(paramHtml); // Put some try .. catch
Param paramTxt = {"a", "b"};
io = new ReadTxt(); // Put some try...catch
io->Search(paramTxt);
return 0;
}

Pointer to function-member

I have a FreeRTOS function xTaskCreate. Simplified declaration looks like
typedef void (*TaskFunction_t)( void* );
unsigned xTaskCreate( TaskFunction_t pxTaskCode, void*params );
And there are two classes:
class Super {
virtual void task(void*params) = 0;
};
class Derived1 : public Super {
virtual void task(void*params){ while(1){ blinkLed(1); delay_ms(333); } }
};
class Derived2 : public Super { ... ;}
In function init() I select one of derived classes and create its instance. Then want to create task
void init(){
Super *obj = condition ? new Derived1 : new Derived2;
xTaskCreate( obj->task ); // WRONG.
}
Upd. Add missed void*params in Simplified declaration of xTaskCreate.
TaskFunction_t is just a pointer to a function - so it can't take a pointer to a member function. Only a pointer to normal function. Or a static member function. Or a lambda with no capture. It's that last one that we'll take advantage of.
One of the arguments you removed from your simplified declaration is the context:
BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
const char * const pcName,
unsigned short usStackDepth,
void *pvParameters, // <== this one!
UBaseType_t uxPriority,
TaskHandle_t *pxCreatedTask
);
You provide the Super* in the parameters and provide a lambda that knows what to do with it. Altogether:
void init(){
Super *obj = condition ? new Derived1 : new Derived2;
xTaskCreate([](void* o){ static_cast<Super*>(o)->task(); },
..., // other args here
obj,
... // more args
);
}
Note that task() should take no arguments. The void*is the context that we're converting to a Super*.
After several experiements of my own with answers here I prefered this simpler method giving Object oriented function calls to RTOS tasks.
//These are not full declaration of class IModule which is fully abstarct so //object that are IModule* are always inherited.
protected:
virtual int InitModule() = 0;
virtual bool PreLoop() = 0;
virtual bool DoLoop() = 0;
virtual bool PostLoop() = 0;
virtual bool DoShutdown() = 0;
//Return if this module implementation requires an RTOS task looping.
virtual bool isFreeRTOSTaskRequired() = 0;
private:
TaskHandle_t *moduleLoopTaskHandle;
bool CreateRTOSTask();
static void TaskStart(void* taskStartParameters);
void TaskLoop();
//END OF PARTIAL decleration
bool IModule::CreateRTOSTask()
{
xTaskCreate(IModule::TaskStart, "NAME", 2048, this, tskNO_AFFINITY, moduleLoopTaskHandle);
return true;
}
void IModule::TaskStart(void *taskStartParameters)
{
IModule *moduleObject = (IModule *)taskStartParameters;
moduleObject->TaskLoop();
}
void IModule::TaskLoop()
{
//TODO Buraya ölçüm koyalım ve bir değişkene yazalım
while (true)
{
ESP_LOGD("IModule::TaskLoop", "%s", "I am alive!");
if (!PreLoop())
{
}
if (!DoLoop())
{
}
if (!PostLoop())
{
}
}
vTaskDelete(NULL);
}
UPDATED: See below.
As explained better than I can here, you might get away with this. Hard to tell from your question if it will cover all of your requirements.
typedef void (Super::*TaskFunction_t)( void* );
Further Reading
UPDATE:
I fleshed out your example, and the results and code are below:
XXXXX:~/scratch/member_function_pointer$ bin/provemeright
Condition false
virtual void Derived2::task(void*)
XXXXX:~/scratch/member_function_pointer$ bin/provemeright foo
Condition true because of argument foo
virtual void Derived1::task(void*)
code (all one cpp file, bad form, but proves syntax):
#include <iostream>
class Super;
typedef void (Super::*TaskFunction_t)(void*);
unsigned xTaskCreate( TaskFunction_t pxTaskCode, void* params);
bool condition = false;
class Super {
public: virtual void task(void* params) = 0;
};
class Derived1 : public Super {
public: virtual void task(void* params) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
if(params) // Necessary to prevent unused parameter warning
std::cout << "Not Null" << std::endl;
};
};
class Derived2 : public Super {
public: virtual void task(void* params) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
if(params) // Necessary to prevent unused parameter warning
std::cout << "Not Null" << std::endl;
};
};
void init(){
Super *obj = condition ? (Super*)new Derived1 : (Super*)new Derived2;
xTaskCreate( &Super::task , obj);
}
int main(int argc, char **argv)
{
if(argc > 1)
{
std::cout << "Condition true because of argument " << argv[1] << std::endl;
condition = true;
} else {
std::cout << "Condition false" << std::endl;
}
init();
return 0;
}
unsigned xTaskCreate( TaskFunction_t pxTaskCode, void* params)
{
Super *obj = (Super*) params;
(obj->*pxTaskCode)(NULL);
return 0;
}
If you're concerned that the syntax is &Super::task instead of &obj->task, then you're misunderstanding how virtual functions work. (It turns out that the &obj->task syntax forbidden by ISO C++, but gcc says it's permissive, so you shouldn't but could force it to compile, and get exactly the same result)
The information about which virtual version of a function to call 'lives' in the object, not the type system. (Could probably phrase that better, open to suggestions, but I think it gets the general point across) It is impossible to call a member function without an object, so in order to make use of the function pointer, you'll have to have an object to 'call it on'. It is the type of that object which will determine which virtual function gets called. So the code above should achieve whatever you're going for, unless of course, this is a round-about way to determine the type of the object pointed to by obj, in which case, it's an awfully convoluted way of going about it.
Further Reading specifically in "Kerrek SB"s answer.

Preventing assignment by subscript operator by not returning references causes runtime crash

I'm doing this:
template<typename T> class var_accessor {
public:
std::set<std::shared_ptr<T>> varset;
std::map<std::string,std::shared_ptr<T>> vars_by_name;
std::map<uint32,std::shared_ptr<T>> vars_by_id;
std::shared_ptr<T> operator[](const uint32& index) { return vars_by_id[index]; }
std::shared_ptr<T> operator[](const std::string& index) { return vars_by_name[index]; }
bool is_in_set(std::shared_ptr<T> what) { auto it = varset.find(what); if (it == varset.end()) return false; return true; }
bool is_in_set(uint32 what) { auto it = vars_by_id.find(what); if (it == vars_by_id.end()) return false; return true; }
bool is_in_set(std::string& what) { auto it = vars_by_name.find(what); if (it == vars_by_name.end()) return false; return true; }
bool place(std::shared_ptr<T> what, const uint32 whatid, const std::string& whatstring) {
if (is_in_set(what)) return false;
varset.emplace(what);
vars_by_name.emplace(whatstring,what);
vars_by_id.emplace(whatid,what);
return true;
}
};
Then...
class whatever {
std::string name;
std::function<int32()> exec;
};
And:
class foo {
public:
var_accessor<whatever> stuff;
};
This works:
std::shared_ptr<whatever> thing(new whatever);
thing->name = "Anne";
thing->exec = []() { return 1; }
foo person;
person.stuff.emplace(thing, 1, thing->name);
Getting the name crashes it:
std::cout << person.stuff[1]->name;
But if I change the operator[]'s to return references, it works fine.
I don't want to be able to accidentally add new elements without adding to all 3 structures, so that's why I made
std::shared_ptr<T> operator[]
instead of
std::shared_ptr<T>& operator[]
Is there any way to prevent assignment by subscript but keep the subscript operator working?
To be clear I want to be able to keep doing
std::cout << person.stuff[4];
But NOT be able to do
std::shared_ptr<whatever> bob(new whatever);
bob->name = "bob";
person.stuff[2] = bob;
The error is a EXC_BAD_ACCESS inside the std::string class madness
Everything I read says simply "don't return references if you want to prevent assignment" but it also prevents using it for me.
Yes I know some things should be made private but I just want to get it working first.
Using Clang/LLVM in XCode 5.1
Thanks!
You should return a const reference. See this question
A const reference means the caller is not allowed to change the value, only look at it. So assignment will be a compile-time error. But using it will work (and be efficient).

pure virtual method called error

I have the following definitions:
class PartitioningMethod {
public:
virtual void addConstraints(ConstraintManager& cm) = 0;
virtual bool hasMoreConstraints() = 0;
virtual void setQuery(const Query& q) = 0;
virtual ~PartitioningMethod(){ }
};
class Random : public PartitioningMethod {
private:
vector< ref<Expr> > constraints;
vector< ref<Expr> >::iterator it;
vector< ref<Expr> >::iterator end;
int numConstraints;
RNG theRNG;
public:
void setQuery(const Query& q) {
constraints.clear();
//Set random number
//srand ( unsigned ( time (NULL) ) * theRNG.getInt32() );
srand ( theRNG.getInt32() );
//Copy constraints
copy(q.constraints.begin(),q.constraints.end(),std::back_inserter(constraints));
//Shuffle Randomly
std::random_shuffle(constraints.begin(),constraints.end(), p_myrandom);
it = constraints.begin();
end = constraints.end();
numConstraints = constraints.size();
}
void addConstraints(ConstraintManager& cm) {
int step = rand() % numConstraints + 1;
while(step != 0) {
cm.addConstraint(*it);
++it;
--step;
--numConstraints;
}
}
bool hasMoreConstraints() {
return it != end;
}
};
bool PartitioningSolver::computeInitialValues(const Query& query,
const std::vector<const Array*> &objects,
std::vector< std::vector<unsigned char> > &values,
bool &hasSolution) {
fprintf(stderr,"INIT\n");
// If there are no constraints in the query
if(query.constraints.size() == 0 || query.constraints.size() == 1)
return solver->impl->computeInitialValues(query, objects, values, hasSolution);
// If the number constraints in the query are > 0
method->setQuery(query);
ConstraintManager cm;
ref<Expr> expr = query.expr;
fprintf(stderr,"Begin partitioning\n");
fprintf(stderr,"---------------------\n");
while(method->hasMoreConstraints()){
fprintf(stderr, "HERE");
//Add Constraints
method->addConstraints(cm);
//Construct a query
Query temp_query(cm,expr);
ExprPPrinter::printQuery(std::cerr,temp_query.constraints,temp_query.expr);
fprintf(stderr,"---------------------\n");
//Query STP to check if satisfiable
values.clear();
if(!solver->impl->computeInitialValues(temp_query, objects, values, hasSolution))
return false;
//If not, return immediately (a win!)
if(!hasSolution)
return true;
//If a solution is returned, check if the solution satisfies the entire set of constraints
vector<const Array*> obj = objects;
Assignment solution(obj, values);
bool satisfiesAll = checkSolution(solution, query.constraints);
// fprintf(stderr,"Satisfies all: %i\n", satisfiesAll);
// If it is successful, return the solution (a win again!),
if(satisfiesAll)
return true;
// If not add more constraints (if there is more) and repeat
}
return true;
}
A Partial definition for the Partitioning solver class:
class PartitioningSolver : public SolverImpl {
private:
Solver* solver;
PartitioningMethod* method;
bool checkSolution(Assignment& solution, const ConstraintManager& constraints);
public:
PartitioningSolver(Solver *s, PartitioningMethod* pm) : solver(s), method(pm) { }
~PartitioningSolver() { delete solver; delete method; }
};
Sorry for pasting such a long snippet of code but I have been working on it for hours and keep getting the eror
pure virtual method called
terminate called without an active exception
I am not sure what's wrong. It seems to fail in computeInitialValues function where fprintf(stderr,"Begin partitioning\n"); is located. I tried adding print statements as a last resort but even they don't print anything.. Any ideas is appreciated.
EDIT:
Ok so I changed the name Random to Ran and it started to work. I was creating this class instance on the fly as an argument with new Random() I guess it was mixing up with another constructor or something else I dont know..
There's another type of bug, which can cause this error message to be printed.
You deleted the object, and later you're trying to make a call on it. It's undefined behaviour, and on some compilers, if you're lucky, that's what you'll see. Try to run your code with valgrind.
http://tombarta.wordpress.com/2008/07/10/gcc-pure-virtual-method-called/
You're calling a pure virtual function from a constructor in some code that you haven't included for us to see.
When my base class's constructor calls a virtual function on its this object, why doesn't my derived class's override of that virtual function get invoked?