How to print a line on Terminal Using Clang Libtooling? - c++

I am relatively new to CLang and Libtooling. I want to display a Line from the source code on the terminal. I have a *VisitFunctionDecl(FunctionDecl func) in the RecursiveASTVisitor. For every function I get the SourceRange and from that the SourceLocation. But I dont understand how to display that. I has something to do

You need the FullSourceLoc:
FullSourceLoc functionDeclFullLocation = Context->getFullLoc(func.getLocStart());
if (functionDeclFullLocation.isValid())
llvm::outs() << "Found FunctionDecl at "
<< functionDeclFullLocation.getManager().getFilename(functionDeclFullLocation) << ":"
<< functionDeclFullLocation.getSpellingLineNumber() << ":"
<< functionDeclFullLocation.getSpellingColumnNumber() << "\n";

Related

filesystem::* strange results in windows filesystem paths with extended chars

Code doesn't do anything useful. It's just try & error code to figure out what's going on:
fs::path path("e:\\Σtest");
cout<<path << " exsits="<< fs::exists(path) << " is dir=" << fs::is_directory(path) << std::endl;
fs::path pathL(L"e:\\Σtest");
cout<<pathL << " exsits="<< fs::exists(pathL) << " is dir=" << fs::is_directory(pathL) << std::endl;
fs::path pathu(u"e:\\Σtest");
cout<<pathu << " exsits="<< fs::exists(pathu) << " is dir=" << fs::is_directory(pathu) << std::endl;
Output:
e:\Σtest exsits=0 is dir=0
e:\Σtest exsits=0 is dir=0
e:\Σtest exsits=0 is dir=0
I sure that folder Σtest exists. I guess there is encoding involve somehow. I can't figure out what sophisticated problem we have encounter here, someone can explain output?
EDIT:
Following #cpplearner advice to pass /utf-8 to compiler output changes (also code page for console was changed to utf-8 by chcp 65001):
e:\Σtest exsits=0 is dir=0
e:\?test exsits=1 is dir=1
e:\?test exsits=1 is dir=1
Question remain the same, what magic happen here?

clang format shift << "\n" to separate line

When I have some c++ stringstream code that is like this
node_struct << filename << nodeID << "\n";
node_struct << "end" << "\n";
clang format will always format the line break to the next line even when the columnlimit is not hit.
node_struct << filename << nodeID
<< "\n";
node_struct << "end"
<< "\n";
How do I prevent such unwanted behavior?
The rule you are asking about could be BreakBeforeBinaryOperators.
See https://clang.llvm.org/docs/ClangFormatStyleOptions.html
You can use this rule in your .clang-format configuration like this:
BreakBeforeBinaryOperators: None

C++ substr method - "invalid use of ‘this’ in non-member function"

I tried to compile the following code
std::string key = "DISTRIB_DESCRIPTION=";
std::cout << "last five characters: " << key.substr(this.end()-5) << '\n';
And the compiler says
error: invalid use of ‘this’ in non-member function
std::cout << "last five characters: " << key.substr(this.end()-5) << '\n';
^
substr is a "public member function" of std::string, why can't I use this?
I know I could just reference key again instead of this, but my original code was
std::cout << "Description: " << line.substr(found+key.length()+1).substr(this.begin(),this.length()-1) << '\n';
In the second use of substr, the string does not have a name, so the only way to refer to it would be this. I fixed it with
std::cout << "Description: " << line.substr(found+key.length()+1,line.length()-found-key.length()-2) << '\n';
But I am now curious to why this won't work.
this is only available when you are writing code as part of a non-static method of a class. In your particular case, it seems obvious to you that this should refer to key, but the compiler sees no reason for that.
Also, string.substr() takes an integer indicating the beginning position. string.end() returns an iterator, which will not work. What you likely want to do here is call string.length().
Simply replace the first piece of code with:
std::cout << "last five characters: " << key.substr(key.length()-5) << '\n';
And you should be okay.

std::cout gives different output from qDebug

I am using Qt, and I have an unsigned char *bytePointer and want to print out a number-value of the current byte. Below is my code, which is meant to give the int-value and the hex-value of the continuous bytes that I receive from a machine attached to the computer:
int byteHex=0;
byteHex = (int)*bytePointer;
qDebug << "\n int: " //this is the main issue here.
<< *bytePointer;
std::cout << " (hex: "
<< std::hex
<< byteHex
<< ")\n";
}
This gives perfect results, and I get actual numbers, however this code is going into an API and I don't want to use Qt-only functions, such as qDebug. So when I try this:
int byteHex=0;
byteHex = (int)*bytePointer;
std::cout << "\n int: " //I changed qDebug to std::cout
<< *bytePointer;
std::cout << " (hex: "
<< std::hex
<< byteHex
<< ")\n";
}
The output does give the hex-values perfectly, however the int-values return symbols (like ☺, └, §, to list a few).
My question is: How do I get std::cout to give the same output as qDebug?
EDIT: for some reason the symbols only occur with a certain Qt setting. I have no idea why it happened but it's fixed now.
As others pointed out in comment, you change the outputting to hex, but you do not actually set it back here:
std::cout << " (hex: "
<< std::hex
<< byteHex
<< ")\n";
You will need to apply this afterwards:
std::cout << std::dec;
Standard output streams will output any character type as a character, not a numeric value. To output the numeric value, convert to a non-character integer type:
std::cout << int(*bytePointer);

String will not write to output correctly

I am trying to write to a file and am having trouble with the string not writing.
From what I have been able to figure out, my string will only print if I place a '\n' after it. The problem is I am trying to write it to a file and it has to be all in line with other information.
Sample of what I am trying to make my file look like:
1111 Last, First 10 20 $30.00
What it actually writes:
1111 10 20 $30.00
This is what i have tried and it will only print the last 3 items. If I place a '\n' after getName() then it prints everything fine:
ofstream outputFile("somefile.txt");
outputFile << std::setw(10) << getAccount()
<< std::setw(10) << getName() // returns a string
<< std::setw(10) << getNum1()
<< std::setw(10) << getNum2()
<< std::setw(10) << getTotal() << endl;
I have tried calling flush after getName() but it did not work
outputFile.flush()
I am supposed to store the last and first name separately.
string getName() const
{
string full = last + ", " + first;
return full;
}
I'm assuming you actually specify a name for the output file, e.g.
std::ofstream outputFile("some-file.txt");
Assuming this is sorted, have a look at std::setw(n) from <iomanip> and make sure your outputs are somehow separated. For example, you might want to use
outputFile << std::setw(8) << getAccount() << ' '
<< std::setw(20) << getName() << ' '
<< std::setw(6) << getNum1() << ' '
<< std::setw(6) << getNum2() << ' '
<< getTotal() << '\n';
... and if you really want to make sure the output is immediately written to the file rather than buffered:
outputFile << std::flush;
(which is equivalent to std::outputFile.flush(); but using cuter syntax).
Based on comments mentioned above, I would guess you ended up with names containing a '\r' right at the end: this way, it looks as if there is nothing but actually the characters are just overwritten by characters coming later. You can remove the carriage return characters using
str.erase(std::remove(str.begin(), str.end(), '\r'), str.end());