I am new to llvm framework and I am starting very basic. What's more basic than a hello world?
I want to iterate over my main function in main.c. It looks like the section
"Iterating over the BasicBlock in a Function" would be a good place to start"
Function &Func = ...
for (BasicBlock &BB : Func)
// Print out the name of the basic block if it has one, and then the
// number of instructions that it contains
errs() << "Basic block (name=" << BB.getName() << ") has "
<< BB.size() << " instructions.\n";
What do I set Function &Func =
to?
I want to look at the main function in my main.c file.
While we're on this topic. What would I set BasicBlock& BB = ... to?
My code.
bool Prereqs::runOnModule(Module &M) {
/* Add your code here */
errs() << "Hi: ";
errs().write_escaped(M.getName()) << '\n';
NumOfFunctions +=10;
outs()<<"get opcode yields: getOpcode()" <<"\n";
Function &Func = main.c;
for (BasicBlock &BB : Func)
// Print out the name of the basic block if it has one, and then the
// // number of instructions that it contains
// errs() << "Basic block (name=" << BB.getName() << ") has "
// << BB.size() << " instructions.\n";
print(M);
return false;
}
documentation
https://releases.llvm.org/8.0.0/docs/ProgrammersManual.html#basic-inspection-and-traversal-routines
You'll probably want to set Func to the return value of Module::getFunction() and if you don't know what a Module is or how to make one, there is a tutorial.
Related
I have a unit test that verifies a function by reading the buffer sent by the function:
template <typename Manifold>
void print_manifold(Manifold const& manifold)
try
{
std::cout << "Manifold has " << manifold.N0() << " vertices and "
<< manifold.N1() << " edges and " << manifold.N2() << " faces and "
<< manifold.N3() << " simplices.\n";
// fmt::print(
// "Manifold has {} vertices and {} edges and {} faces and {}
// simplices.\n", manifold.N0(), manifold.N1(), manifold.N2(),
// manifold.N3());
}
catch (...)
{
std::cerr << "print_manifold() went wrong ...\n";
throw;
} // print_manifold
And:
SCENARIO("Printing results", "[utility]")
{
// redirect std::cout
stringstream buffer;
cout.rdbuf(buffer.rdbuf());
GIVEN("A Manifold3")
{
Manifold3 const manifold(640, 4);
WHEN("We want to print statistics on a manifold.")
{
THEN("Statistics are successfully printed.")
{
print_manifold(manifold);
CHECK_THAT(buffer.str(), Catch::Contains("Manifold has"));
}
}
}
Is there a way to capture the output generated by fmt::print going to stdout?
When I comment out the cout code and uncomment the fmt code, I get the buffer produced by previous instances of cout <<.
This is more of a C stdio than {fmt} question but you can redirect stdout to a pipe and read the output from it as described in the answers to Redirecting stdout to pipe in C. This is not a great unit test though because it depends on the global state but your current test has the same problem.
Backstory
(You can skip. Useful if you want to expand and adopt my approach.)
I am trying to expand a debugging library I created to be able to do unintrusive benchmarking and debugging. So far, it looks something like this, however I am open to revamping. This is just similar to what I was using for doing type flexible debugging:
#define BENCH(FUNC,N)CT::bench(#FUNC,FUNC,N,__FILE__,__LINE__,__PRETTY_FUNCTION__)
// #FUNC is a string of the code for the function placed in the macro
// FUNC is the function. How it should be captured, I am not sure yet.
// N Should be the number of times you wish to run the captured function
// __FILE__, __LINE__, __PRETTY_FUNCTION__ are GCC predefined macros
// Used for easily locating the code that is generating the output.
template <typename First> // Problem: Ensure only functions used as arguments?
static First bench(const QString expression,
First &&type, // This is the type. Needed for the return.
quint64 repeatN, // Negative repeats make no sense.
const QString &_file,
const int &_line,
const QString &_pretty_function)
{
QString typeName = QConsoleToolkit::demangle(typeid(type).name());
int initial(-1); // Time required to execute function first time
int average(-1); // Average execution time.
for (int i=0; i < repeatN; i++) {
// *
// *
// No idea how to do this.
// Please help.
// *
// *
}
QTextStream(stdout)
<< "Benchmark: " << typeName
<< "\t" << expression
<< "\t" << _pretty_function
<< "\t" << _file
<< ":" << _line << endl
<< " Repeat: " << QString::number(repeatN) << endl
<< "Initial: " << QString::number(initial) << endl
<< "Average: " << QString::number(average) << endl;
// Unsure if this will work with void
return std::forward<First>(type);
}
// Returns string for type
QString CT::demangle(const QString &name)
{
int status;
std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name.toLatin1(), NULL, NULL, &status),
std::free
};
return {(status==0) ? QLatin1String(res.get()) : name};
}
Actual Question
Take the following code:
void MyClass::foo()
{
//dostuff
}
QString MyClass::funString()
{
return "The quick brown fox jumps over the lazy dog";
}
void MyClass::bar()
{
BENCH(foo(), 1000);
QString s = BENCH(funString(),2000);
QTextStream(stdout) << s << endl;
}
My goal is to have MyClass::bar() output this: (Random numbers are made up for initial and average)
Benchmark: void foo() void MyClass::bar() /home/akiva/myclass.cpp:31
Repeat: 1000
Initial: 2523
Average: 1234
Benchmark: QString funString() void MyClass::bar() /home/akiva/myclass.cpp:32
Repeat: 2000
Initial: 5003
Average: 4025
The quick brown fox jumps over the lazy dog
Thus, how can I make it so the macro BENCH() can take any type of function, run it N times, benchmarking how long each iteration takes to run, and have it return the first initial value received upon initial run?
It can not be intrusive, thus making this line possible:
QString s = BENCH(funString(),2000);
File:
{
"somestring":{
"a":1,
"b":7,
"c":17,
"d":137,
"e":"Republic"
},
}
how can I read the somestring value by jsoncpp?
Use the getMemberNames() method.
Json::Value root;
root << jsonString;
Json::Value::Members propNames = root.getMemberNames();
std::string firstProp = propNames[0];
std::cout << firstProp << '\n'; // should print somestring
If you want to see all the properties, you can loop through it using an iterator:
for (auto it: propNames) {
cout << "Property: " << *it << " Value: " << root[*it].asString() << "\n";
}
This simple loop will only work for properties whose values are strings. If you want to handle nested objects, like in your example, you'll need to make it recursive, which I'm leaving as an exercise for the reader.
I am working on CLang 3.5. I am trying to fetch info about variables declared in a C++ project.
How can I fetch datatype or qualified class name of a variable in a clang::VarDecl, clang::FieldDecl or clang::ParmVarDecl object? I tried to find a function which can return datatype or class name of the variable in doc for clang::VarDecl provided here.
http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html
I also tried to look into the code of $LLVM/tools/clang/tools/clang-check/ClangCheck.cpp because on passing cmd arg --ast-dump it shows all of the information about every AST node including all of the variables declared. I wonder how to access all of that information.
I am using ASTMatchers to find my variable declarations, those are:
fieldDecl().bind("field")
parmVarDecl().bind("param")
varDecl().bind("var")
Can anybody please tell me how can I get datatype of all of the variables delcared?
Recently, I'm learning Clang and I've wrote some codes after reading this question. It might help you.
Full source code is available in github.com
(see ex04.cc)
DeclarationMatcher FieldDeclMatcher =
clang::ast_matchers::fieldDecl().bind("field_decl");
class LoopPrinter : public MatchFinder::MatchCallback
{
public :
virtual void run(const MatchFinder::MatchResult& result)
{
if (const clang::FieldDecl* fd
= result.Nodes.getNodeAs<clang::FieldDecl>("field_decl"))
{
std::cout << "======== FieldDecl found ======" << std::endl;
const clang::RecordDecl* rd = fd->getParent();
const clang::QualType qt = fd->getType();
const clang::Type* t = qt.getTypePtr();
std::cout << "FieldDecl found '"
<< fd->getQualifiedNameAsString() << " "
<< fd->getName().str() << "' in '"
<< rd->getName().str() << "'. "
<< "is Builtintype = " << t->isBuiltinType() << " "
<< std::endl << std::endl;
}
} // end of run()
};
I have a problem in using the std::map correctly. The class Example is a class with an ID, a label, a vector of keypoints and a descriptor matrix. The class Examples is a map for retrieving an example given its ID. The examples are read from files on disk, stored in the map, then used later.
Even if it is conceptually very simple, I am not able to fill the map properly.
I have the following class:
class Example
{
public:
std::string id;
std::string label;
std::vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;
Example(std::string id_, std::string label_)
: id(id_), label(label_)
{
// ... nothing ...
}
string to_string() const
{
stringstream ss;
ss << "#" << id
<< " (" << label << ")"
<< " - #keypoints " << keypoints.size()
<< ", descr " << descriptors.rows << " x " << descriptors.cols;
return ss.str();
} // to_string
}; // class Example
ostream& operator <<(ostream & out, const Example &ex)
{
out << ex.to_string();
return out;
} // operator <<
And this one:
// OLD: class Examples : public std::map<std::string, Example*> {
class Examples {
// New line after Martini's comment
std::map<std::string, Example*> _map;
[...]
void fill() {
// create an example
Example *example = new Example(id, label);
// inputstream in
// Read all the keypoints
cv::KeyPoint p;
for(int i=0; ... ) {
in.read(reinterpret_cast<char *>(&p), sizeof(cv::KeyPoint));
example->keypoints.push_back(p); // push_back copies p
} // for
// ... misc code
cv::Mat descr(n_keypoints, d_size, cv_type, cv::Scalar(1));
// ... read Mat from inputstream in, then assign it to the example
example->descriptors = descr;
// SEE THE OUTPUT BELOW
std::cout << "INSERT THIS: " << (*example) << std::endl;
_map.insert(std::pair<string,Example*>(id, example));
std::cout << "READ THIS: " << *(get_example(id)) << std::endl;
// ... other code
} // fill
// Code modified after Martini's comment.
Example* get_example(const std::string &id) const {
std::map<std::string, Example*>::const_iterator it = _map.find(id);
if( it == _map.end()) {
// ... manage error
// ... then exit
} // if
return it->second;
} // get_example
} // class Examples
The output from the insert/get lines is:
INSERT THIS: #122225084 (label) - #keypoints 711, descr 711 x 128
READ THIS: #122225084 (label) - #keypoints 0, descr 0 x 0
In the insert I had a pointer to an example with 711 keypoints and a 711x128 descriptor matrix. If I read the example using its ID right after the insert, I get a pointer to an example with 0 keypoints and an empty matrix.
What am I doing wrong?
Looking into your code one possible explanation is that you already have element in the map with the same key. To diagnose that first of all print value of pointer before you add object and after that (something like this):
std::cout << "INSERT THIS: " << (void *)example << " " << (*example) << std::endl;
_map.insert(std::pair<string,Example*>(id, example));
std::cout << "READ THIS: " << (void *)get_example(id) << " " << *(get_example(id)) << std::endl;
Next or another way is to check result of insert:
if( !_map.insert(std::pair<string,Example*>(id, example)).second )
std::cout << "ERROR: example:" << id << " is already there";
If you want to override element unconditionally you can use oprator[]:
_map[ id ] = example;
If there are really duplicates you will get memory leak (you are getting it anyway) so I would strongly recommend to use smart pointer to store data in your map.