Avoid traversing included system libraries - llvm

I'm working with LLVM + Clang now. I use the ASTUnit to build-up the tree and I use the RecursiveASTVisitor to traverse the tree.
clang::ASTUnit* AST;
clang::DiagnosticOptions diagOpts;
llvm::IntrusiveRefCntPtr<clang::Diagnostic> diags = clang::CompilerInstance::createDiagnostics(diagOpts, 0, 0);
const char** ptr = new const char*[1];
ptr[0] = argv[1];
clang::CompilerInvocation *ci = new clang::CompilerInvocation();
clang::CompilerInvocation::CreateFromArgs(*ci, ptr, ptr+1, *diags);
ci->setLangDefaults(clang::IK_CXX, clang::LangStandard::lang_cxx98);
ci->getPreprocessorOutputOpts().ShowComments = 1;
ci->getPreprocessorOutputOpts().ShowLineMarkers = 1;
AST = clang::ASTUnit::LoadFromCompilerInvocation(ci, diags);
...
...
MyRecursiveASTVisitor myvis(AST->getASTContext());
myvis.TraverseDecl(AST->getASTContext().getTranslationUnitDecl());
I would like to avoid visiting the included system libaries. Is it possible?

I think I found some kind of solution, but not the final one!
In the inherited ASTVisitor class:
class MyRecursiveASTVisitor : public clang::RecursiveASTVisitor<MyRecursiveASTVisitor>
You can override function TraverseDecl. In this function you can traverse the declarations. If you don't call this function recursive, when the declaration is not from the main file, you can avoid traverse the declarations from other files.
bool TraverseDecl ( clang::Decl *D )
{
bool rval;
if (!D) return true;
if (sm.isFromMainFile(D->getLocation()) || std::string(D->getDeclKindName()) == "TranslationUnit")
{
bool rval = clang::RecursiveASTVisitor<MyRecursiveASTVisitor>::TraverseDecl(D);
}
else
rval = true;
return rval;
}
In this context the sm is the clang::SourceManager of class MyRecursiveASTVisitor. You van avoid traversing statements from other files, the same way, in overridden TraverseStmt function.
Now I only how to get to know whether the statement or declaration is from a system library, or a user defined library.

Related

implement field access with functions

I want to replace object field access with functions to make it easy for a program analyzer I am building. Is there a simple way to do this? I came up with the following hack with my own set and get functions:
struct Foo
{
int f1;
int f2;
};
// convert v = t->f1 to v = (int)get(t, "f1")
void * get (struct Foo * t, char * name)
{
if (!strcmp(name, "f1")) return t->f1;
else if (!strcmp(name, "f2")) return t->f2;
else assert(0);
}
// convert t->f1 = v; to set(t, "f1", v)
void set (struct Foo * t, char * name, void * v)
{
if (!strcmp(name, "f1")) t->f1 = (int)v;
else if (!strcmp(name, "f2")) t->f2 = (int)v;
else assert(0);
}
Edit: C or C++ hacks would work.
So, as far as I understand you are looking for some reflection library for c/c++?
In this case, there is quite a big difference between c and c++.
For C++, you can use boost describe.
For C there are several libraries, bottom line all solution come down to defining your structs with macros, something like:
MY_STRUCT(s,
MY_MEMBER(int, y),
MY_MEMBER(float, z))
You can see a few examples here.

Extending Eigen Library to Include Sorting

I would like to extend the C++ Eigen library to include a command v.sort(); I'm using the EIGEN_MATRIXBASE_PLUGIN based approach outlined here.
The code below (in my "MatrixBaseAddons.h") does not work, because the "result" object does not get loaded with a copy of "this"---in the debugger, "result.rows()" is an uninitialized value not equal to derived()->rows(). How do I actually make a copy of "this" and put it in "result"?
// DOES NOT WORK
MatrixBase<Derived> sort(bool ascending = true) const {
MatrixBase<Derived> result = derived();
result.sortInPlace(ascending);
return result;
}
// WORKS!
void sortInPlace(bool ascending = true) {
std::sort(derived().data(), derived().data() + derived().size());
if (!ascending)
this->reverseInPlace();
}
MatrixBase is an abstract class. You need to return a Matrix<> object with appropriate scalar type and sizes. You can directly use the typedef PlainObject for that:
PlainObject sort(bool ascending = true) const {
PlainObject res = derived();
...
return res;
}

creating a new handle to class through a function in c++

I am not sure if my title makes any sense. I am trying to implement a queue class in c++. Below is my q.cpp class so far
#include "q.h"
q::q()
{
for(int i = 0; i < q::QUEUE_SIZE; i++)
{
q::data[i] = '0';
}
q::front = q::rear = -1;
printf(" YEA QUEUE HAS BEEN CREATED ");
}
q* q::createQueue()
{
return new q;
}
Now in my output class (main.cpp), I want to be able to create new queues through the createQueue() function call and returning a handle to the current queue class object
Something like this
q* firstQueue = createQueue();
q* secondQueue = createQueue();
I was thinking my main constructor q() needs to be private and createQueue should act like a factory so my q.h file should be something like below?
#ifndef Q_H
#define Q_H
#include <stdio.h>
class q
{
public:
void destroy_queue(q* currentQueue);
void enque_byte(q* currentQueue,unsigned char b);
unsigned char deque_byte(q* currentQueue);
static q* createQueue();
private:
static const int QUEUE_SIZE = 2048;
unsigned char data[QUEUE_SIZE];
int front, rear;
q();
};
#endif // Q_H
And then how would I be able to do enqueue, dequeue operations by calling
And then do enqueue and dequeue operations on any number of queues like
enqueue(firstQueue,5);
dequeue(firstQueue);
enqueue(secondQueue,10);
..
..
And not use objects to call them like
firstQueue->enqueue(...)
I am slightly confused with the organization of my code. Hope someone could provide an insight on how can I achieve such a structure?
You can just write simple wrappers like
void enqueue(q* obj, int x) {
obj->enqueue(x);
}
All this doesn't make much sense, however; the C++ idiom is to use objects and methods and, unless you are in a case where this idiom doesn't work that well (e.g. multimethods), following it is much easier than fighting against it.

Is there a way to disallow pointer comparison in C++?

I have a (working) code base where I want to add something like an is_equivalent member to a class hierarchy. Scattered throughout the code base there are comparisons like
if (foo == bar) ...
where foo and bar are ordinary pointers to objects in the class hierarchy. I would like to introduce usage like the following (as a virtual function in the base class):
if (foo->is_equivalent(bar)) ...
so that the notion of "equality" is relaxed. A concrete geometric example might be a shape hierarchy, where a Circle should be considered equivalent to an Ellipse with equal major and minor axes (not a perfect analogy).
What I would like to do is have the compiler help me find all the instances where I have done direct pointer comparison. One thought I had was to provide something like an operator==(const Shape *, const Shape *) but that isn't even allowed by C++.
Some pointer comparisons might need to stay pointer comparison, but some will need to be changed into a virtual method call. I'll need to look at each one. What approaches are there to identify all these kinds of comparisons? Temporarily breaking either the build or execution is fine. There is pretty good test coverage.
I have read the question C++ Trick to avoid pointer comparison which is similar, but more limited because the accepted answer assumes the existence of a factory class.
You could write a custom code analysis tool. Here's a minimal (and rather trivial) example I've built using libclang. This filters out every binary operator in the source. By the means of refining this, you could gather all pointer equality comparisons from the AST.
#include <clang-c/Index.h>
#include <stdio.h>
static void printBinOp(CXCursor cursor)
{
CXSourceRange range = clang_getCursorExtent(cursor);
CXSourceLocation begin = clang_getRangeStart(range);
CXSourceLocation end = clang_getRangeEnd(range);
CXFile file;
unsigned begin_offset, end_offset, length;
// retrieve physical location of AST node
clang_getSpellingLocation(begin, &file, NULL, NULL, &begin_offset);
clang_getSpellingLocation(end, NULL, NULL, NULL, &end_offset);
length = end_offset - begin_offset;
// Open the file, error checking omitted for clarity
CXString xfname = clang_getFileName(file);
const char *fname = clang_getCString(xfname);
FILE *fhndl = fopen(fname, "r");
clang_disposeString(xfname);
// Read the source
char buf[length + 1];
fseek(fhndl, begin_offset, SEEK_SET);
fread(buf, length, 1, fhndl);
buf[length] = 0;
fclose(fhndl);
// and print it
printf("Comparison: %s\n", buf);
}
static enum CXChildVisitResult ptrCompVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
{
if (clang_getCursorKind(cursor) == CXCursor_BinaryOperator) {
printBinOp(cursor);
}
return CXChildVisit_Recurse;
}
int main()
{
CXIndex index = clang_createIndex(0, 0);
CXTranslationUnit tu = clang_parseTranslationUnit(index, "foo.cpp", NULL, 0, NULL, 0, CXTranslationUnit_None);
clang_visitChildren(clang_getTranslationUnitCursor(tu), ptrCompVisitor, NULL);
clang_disposeTranslationUnit(tu);
clang_disposeIndex(index);
return 0;
}
The example file I've used was this imaginary C++ source file (named foo.cpp):
class Foo {
int foo;
};
class Bar {
int bar;
}
int main()
{
void *f = new Foo();
void *b = new Bar();
bool alwaystrue_1 = f == f;
bool alwaystrue_2 = b == b;
return f == b;
}
For which my tool printed this:
Comparison: f == f
Comparison: b == b
Comparison: f == b

error: ANSI C++ forbids implicit conversion from `void *' in assignment

I get this error message, and I don't seem to understand it.
What does it mean by ANSI C++ forbids implicit conversion from `void *' in assignment? . And the Fork function only takes the function name and a number
Thread::Fork(VoidFunctionPtr func, int arg)
Error message:
../threads/threadtest.cc: In function `void ServerThread(int)':
../threads/threadtest.cc:72: ANSI C++ forbids implicit conversion from `void *' in assignment
../threads/threadtest.cc:78: implicit declaration of function `int WorkerThread(...)'
REGION:
72 - 78:
nextReq = list -> Remove();
//check till the end
while (nextReq != NULL)
{
WorkerThread(&nextReq);
code:
#include "copyright.h"
#include "system.h"
#include <stdio.h>
#include "request.h"
extern void serve(char *url);
//GLOBAL VARIABLE LIST
List *list;
//----------------------------------------------------------------------
// ThreadTest
// read file and serve urls
//----------------------------------------------------------------------
void
ClientThread(int request)
{
const int sz = 50;
char url[sz];
FILE *fp = fopen("url.txt", "r");
if (!fp)
printf(" Cannot open file url.txt!\n");
else {
int pos = 0;
char c = getc(fp);
while (c != EOF || pos == sz - 1) {
if (c == '\n') {
url[pos] = '\0';
serve(url);
pos = 0;
//Store necessary information in a Request object for each request.
Request req(url, request, 1);
Request *reqq = &req; //req points to the object
list->Append(reqq);
}
else {
url[pos++] = c;
}
c = getc(fp);
}
fclose(fp);
}
}
//----------------------------------------------------------------------
void
ServerThread(int which)
{
Request *nextReq;
//gets the first node off the list
nextReq = list -> Remove();
//check till the end
while (nextReq != NULL)
{
WorkerThread(nextReq);
}
}
//----------------------------------------------------------------------
void
WorkerThread (Request req)
{
serve(req.url);
currentThread -> Yield();
}
//----------------------------------------------------------------------
void
ThreadTest()
{
DEBUG('t', "Entering SimpleTest");
printf("THREAD TEST");
//Thread *c = new Thread("client thread");
Thread *s = new Thread("server thread");
s->Fork(ServerThread, 1);
ClientThread(0);
}
This appears to be one of the offending lines:
nextReq = list -> Remove();
It appears that list->Remove() returns a void *. C++ requires a cast to turn this into another pointer (C does not). So change this to:
nextReq = static_cast<Request *>(list -> Remove());
(Alternatively, consider making List a template class so you can avoid these kinds of unsafe casts. Based on your code, the STL class std::queue<Request> should fulfill your needs here.)
The second offending line is your call to WorkerThread() before it is defined. You need to add a prototype for the function prior to your definition of ServerThread(). Otherwise the compiler does not know what its prototype is, and it should complain once it reaches the real definition of ServerThread() that it does not match the prototype that it deduced earlier.
void WorkerThread(Request);
void
ServerThread(int which)
{
// ...
(Or, since WorkerThread() does not call ServerThread(), you could just swap the order of the definitions of the two functions to resolve the problem.)
Further, note that this code is bad:
Request req(url, request, 1);
Request *reqq = &req; //req points to the object
list->Append(reqq);
You construct an object and then push a pointer to the stack-allocated object onto a list. When ClientThread() returns, this object will be destroyed and you are left with a pointer to an object that no longer exists. Using this pointer will trigger undefined behavior. Consider instead allocating a new Request on the heap by using Request *reqq = new Request(url, request, 1); (but don't forget to delete the object after you process it).
Or, better yet, use std::queue<Request> as I suggested earlier -- then you can just queue.emplace(url, request, 1);. But note that you do need a way to synchronize access to the queue from multiple threads.