work save
This commit is contained in:
parent
ebfb631452
commit
ca59fd7d70
|
@ -1797,78 +1797,6 @@ bool CppParser::checkForUsing(KeywordType keywordType)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppParser::checkForVar()
|
|
||||||
{
|
|
||||||
int indexBackup=mIndex;
|
|
||||||
// Be pessimistic
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
// Store old index
|
|
||||||
KeywordType keywordType;
|
|
||||||
|
|
||||||
// Use mIndex so we can reuse checking functions
|
|
||||||
if (mIndex + 1 < mTokenizer.tokenCount()) {
|
|
||||||
// Check the current and the next token
|
|
||||||
for (int i = 0; i<=1; i++) {
|
|
||||||
if (checkForKeyword(keywordType)
|
|
||||||
|| isInvalidVarPrefixChar(mTokenizer[mIndex]->text.front())
|
|
||||||
|| (mTokenizer[mIndex]->text.back() == '.')
|
|
||||||
|| (
|
|
||||||
(mTokenizer[mIndex]->text.length() > 1) &&
|
|
||||||
(mTokenizer[mIndex]->text[mTokenizer[mIndex]->text.length() - 2] == '-') &&
|
|
||||||
(mTokenizer[mIndex]->text[mTokenizer[mIndex]->text.length() - 1] == '>'))
|
|
||||||
) {
|
|
||||||
// Reset index and fail
|
|
||||||
mIndex = indexBackup;
|
|
||||||
return false;
|
|
||||||
} // Could be a function pointer?
|
|
||||||
else if (mTokenizer[mIndex]->text == '(') {
|
|
||||||
int nextIndex = mTokenizer[mIndex]->matchIndex+1;
|
|
||||||
if ( (nextIndex >= mTokenizer.tokenCount())
|
|
||||||
|| (mTokenizer[nextIndex]->text != '(')
|
|
||||||
|| !mTokenizer[mIndex+1]->text.startsWith('*')) {
|
|
||||||
// Reset index and fail
|
|
||||||
mIndex = indexBackup;
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
nextIndex = mTokenizer[nextIndex]->matchIndex+1;
|
|
||||||
if (mTokenizer[mIndex]->text!=';') {
|
|
||||||
mIndex = indexBackup;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
isFunctionPointer=true;
|
|
||||||
mIndex = indexBackup;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fail if we do not find a comma or a semicolon or a ( (inline constructor)
|
|
||||||
while (mIndex < mTokenizer.tokenCount()) {
|
|
||||||
if (mTokenizer[mIndex]->text.front() == '#'
|
|
||||||
|| mTokenizer[mIndex]->text == '}'
|
|
||||||
|| checkForKeyword(keywordType)) {
|
|
||||||
break; // fail
|
|
||||||
} else if (mTokenizer[mIndex]->text.front() == ','
|
|
||||||
|| mTokenizer[mIndex]->text.front() == ';'
|
|
||||||
|| mTokenizer[mIndex]->text.front() == '{') {
|
|
||||||
result = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//skip '(' ')'
|
|
||||||
if (mTokenizer[mIndex]->text=='(' || mTokenizer[mIndex]->text=='[')
|
|
||||||
mIndex=mTokenizer[mIndex]->matchIndex;
|
|
||||||
else
|
|
||||||
mIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Revert to the point we started at
|
|
||||||
mIndex = indexBackup;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CppParser::getCurrentBlockEndSkip()
|
int CppParser::getCurrentBlockEndSkip()
|
||||||
{
|
{
|
||||||
if (mBlockEndSkips.isEmpty())
|
if (mBlockEndSkips.isEmpty())
|
||||||
|
@ -2826,8 +2754,8 @@ bool CppParser::handleStatement()
|
||||||
handleStructs(false);
|
handleStructs(false);
|
||||||
} else if (checkForMethod(funcType, funcName, argStart,argEnd, isStatic, isFriend)) {
|
} else if (checkForMethod(funcType, funcName, argStart,argEnd, isStatic, isFriend)) {
|
||||||
handleMethod(funcType, funcName, argStart, argEnd, isStatic, isFriend); // don't recalculate parts
|
handleMethod(funcType, funcName, argStart, argEnd, isStatic, isFriend); // don't recalculate parts
|
||||||
} else if (checkForVar()) {
|
} else if (tryHandleVar()) {
|
||||||
handleVar();
|
//do nothing
|
||||||
} else
|
} else
|
||||||
mIndex++;
|
mIndex++;
|
||||||
|
|
||||||
|
@ -3199,81 +3127,78 @@ void CppParser::handleUsing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppParser::handleVar()
|
bool CppParser::tryHandleVar()
|
||||||
{
|
{
|
||||||
int indexBackup=mIndex;
|
int indexBackup=mIndex;
|
||||||
// Keep going and stop on top of the variable name
|
KeywordType keywordType;
|
||||||
QString lastType = "";
|
QString varType=mTokenizer[mIndex]->text;
|
||||||
bool isExtern = false;
|
bool isExtern = false;
|
||||||
bool isStatic = false;
|
bool isStatic = false;
|
||||||
bool varAdded = false;
|
QString lastType;
|
||||||
|
if (isInvalidVarPrefixChar(mTokenizer[mIndex]->text.front())
|
||||||
|
|| (mTokenizer[mIndex]->text.back() == '.')
|
||||||
|
|| (mTokenizer[mIndex]->text.back() == '>'))
|
||||||
|
//failed to handle
|
||||||
|
return false;
|
||||||
|
if (varType=="extern") {
|
||||||
|
lastType=varType;
|
||||||
|
isExtern=true;
|
||||||
|
} else if (varType=="static") {
|
||||||
|
lastType=varType;
|
||||||
|
isStatic=true;
|
||||||
|
}
|
||||||
|
mIndex++;
|
||||||
|
|
||||||
if (checkForKeyword(keywordType)
|
//we only check the first token to reduce calculations
|
||||||
|
if (mIndex>=mTokenizer.tokenCount()
|
||||||
|
|| checkForKeyword(keywordType)
|
||||||
|| isInvalidVarPrefixChar(mTokenizer[mIndex]->text.front())
|
|| isInvalidVarPrefixChar(mTokenizer[mIndex]->text.front())
|
||||||
|| (mTokenizer[mIndex]->text.back() == '.')
|
|| (mTokenizer[mIndex]->text.back() == '.')
|
||||||
|| (
|
|| (mTokenizer[mIndex]->text.back() == '>')) {
|
||||||
(mTokenizer[mIndex]->text.length() > 1) &&
|
//failed to handle
|
||||||
(mTokenizer[mIndex]->text[mTokenizer[mIndex]->text.length() - 2] == '-') &&
|
mIndex=indexBackup;
|
||||||
(mTokenizer[mIndex]->text[mTokenizer[mIndex]->text.length() - 1] == '>'))
|
return false;
|
||||||
) {
|
|
||||||
// Reset index and fail
|
|
||||||
mIndex = indexBackup;
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!isFunctionPointer) {
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if ((mIndex + 1 < mTokenizer.tokenCount())
|
|
||||||
&& (mTokenizer[mIndex + 1]->text=='('
|
|
||||||
|| mTokenizer[mIndex + 1]->text==','
|
|
||||||
|| mTokenizer[mIndex + 1]->text==';'
|
|
||||||
|| mTokenizer[mIndex + 1]->text.front()==':'
|
|
||||||
|| mTokenizer[mIndex + 1]->text=='}'
|
|
||||||
|| mTokenizer[mIndex + 1]->text.front()=='#'
|
|
||||||
|| mTokenizer[mIndex + 1]->text=='{')) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// struct/class/union is part of the type signature
|
|
||||||
// but we dont store it in the type cache, so must trim it to find the type info
|
|
||||||
if (mTokenizer[mIndex]->text!="struct"
|
|
||||||
&& mTokenizer[mIndex]->text!="class"
|
|
||||||
&& mTokenizer[mIndex]->text!="union") {
|
|
||||||
if (mTokenizer[mIndex]->text == ':') {
|
|
||||||
lastType += ':';
|
|
||||||
} else {
|
|
||||||
QString s=mTokenizer[mIndex]->text;
|
|
||||||
if (s == "extern") {
|
|
||||||
isExtern = true;
|
|
||||||
} else {
|
|
||||||
if (!s.isEmpty())
|
|
||||||
lastType += ' '+s;
|
|
||||||
if (s == "static")
|
|
||||||
isStatic = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mIndex++;
|
|
||||||
if(mIndex >= mTokenizer.tokenCount())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lastType = lastType.trimmed();
|
|
||||||
} else {
|
|
||||||
QString s=mTokenizer[mIndex]->text;
|
|
||||||
if (s == "extern") {
|
|
||||||
isExtern = true;
|
|
||||||
} else if (s=="static") {
|
|
||||||
isStatic = true;
|
|
||||||
} else
|
|
||||||
lastType=s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't bother entering the scanning loop when we have failed
|
while (mIndex+1<mTokenizer.tokenCount()) {
|
||||||
if (mIndex >= mTokenizer.tokenCount())
|
if (mTokenizer[mIndex]->text=='('
|
||||||
return;
|
&& mTokenizer[mIndex]->matchIndex<=mTokenizer.tokenCount()
|
||||||
|
&& mTokenizer[mTokenizer[mIndex]->matchIndex]->text=='(') {
|
||||||
|
//function pointer
|
||||||
|
break;
|
||||||
|
} else if (mTokenizer[mIndex + 1]->text=='('
|
||||||
|
|| mTokenizer[mIndex + 1]->text==','
|
||||||
|
|| mTokenizer[mIndex + 1]->text==';'
|
||||||
|
|| mTokenizer[mIndex + 1]->text.front()==':'
|
||||||
|
|| mTokenizer[mIndex + 1]->text=='}'
|
||||||
|
|| mTokenizer[mIndex + 1]->text.front()=='#'
|
||||||
|
|| mTokenizer[mIndex + 1]->text=='{') {
|
||||||
|
//end of type info
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mTokenizer[mIndex]->text!="struct"
|
||||||
|
&& mTokenizer[mIndex]->text!="class"
|
||||||
|
&& mTokenizer[mIndex]->text!="union") {
|
||||||
|
QString s=mTokenizer[mIndex]->text;
|
||||||
|
if (s == "extern") {
|
||||||
|
isExtern = true;
|
||||||
|
} else if (s == "static") {
|
||||||
|
isStatic = true;
|
||||||
|
} else
|
||||||
|
lastType += ' '+s;
|
||||||
|
}
|
||||||
|
mIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
// Find the variable name
|
if (mIndex+1 >= mTokenizer.tokenCount() || lastType.isEmpty()
|
||||||
while (true) {
|
|| lastType.endsWith(':')) {
|
||||||
|
mIndex=indexBackup;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool varAdded = false;
|
||||||
|
QString tempType;
|
||||||
|
while(true) {
|
||||||
// Skip bit identifiers,
|
// Skip bit identifiers,
|
||||||
// e.g.:
|
// e.g.:
|
||||||
// handle
|
// handle
|
||||||
|
@ -3288,46 +3213,52 @@ void CppParser::handleVar()
|
||||||
))
|
))
|
||||||
mIndex++;
|
mIndex++;
|
||||||
}
|
}
|
||||||
// Skip inline constructors,
|
if (mTokenizer[mIndex]->text=='('
|
||||||
// e.g.:
|
&& mTokenizer[mIndex]->matchIndex+1<mTokenizer.tokenCount()
|
||||||
// handle
|
&& mTokenizer[mTokenizer[mIndex]->matchIndex+1]->text=='(') {
|
||||||
// int a(3)
|
//function pointer
|
||||||
// as
|
QString cmd=mTokenizer[mIndex]->text;
|
||||||
// int a
|
int argStart=mTokenizer[mIndex]->matchIndex+1;
|
||||||
if (!isFunctionPointer &&
|
int argEnd=mTokenizer[argStart]->matchIndex;
|
||||||
mIndex < mTokenizer.tokenCount() &&
|
if (cmd.startsWith('*'))
|
||||||
mTokenizer[mIndex]->text == '(') {
|
cmd=cmd.mid(1);
|
||||||
mIndex=mTokenizer[mIndex]->matchIndex+1;
|
if (!cmd.isEmpty()) {
|
||||||
}
|
addChildStatement(
|
||||||
|
getCurrentScope(),
|
||||||
// Did we stop on top of the variable name?
|
mCurrentFile,
|
||||||
if (mIndex < mTokenizer.tokenCount()) {
|
lastType,
|
||||||
if (mTokenizer[mIndex]->text.front()!=','
|
cmd,
|
||||||
&& mTokenizer[mIndex]->text.front()!=';') {
|
mergeArgs(argStart,argEnd),
|
||||||
QString cmd;
|
"",
|
||||||
|
"",
|
||||||
|
mTokenizer[mIndex]->line,
|
||||||
|
StatementKind::skVariable,
|
||||||
|
getScope(),
|
||||||
|
mClassScope,
|
||||||
|
//True,
|
||||||
|
!isExtern,
|
||||||
|
isStatic); // TODO: not supported to pass list
|
||||||
|
varAdded = true;
|
||||||
|
tempType="";
|
||||||
|
}
|
||||||
|
mIndex=argEnd+1;
|
||||||
|
} else if (isWordChar(mTokenizer[mIndex]->text[0])) {
|
||||||
|
QString cmd=mTokenizer[mIndex]->text;
|
||||||
|
while (cmd.startsWith('*')) {
|
||||||
|
cmd=cmd.mid(1);
|
||||||
|
}
|
||||||
|
if (cmd=="const") {
|
||||||
|
tempType=mTokenizer[mIndex]->text;
|
||||||
|
} else {
|
||||||
|
QString suffix;
|
||||||
QString args;
|
QString args;
|
||||||
if (isFunctionPointer) {
|
cmd=mTokenizer[mIndex]->text;
|
||||||
QString s = mTokenizer[mIndex+1]->text;
|
parseCommandTypeAndArgs(cmd,suffix,args);
|
||||||
cmd = s.mid(1); // (*foo) -> foo
|
if (!cmd.isEmpty()) {
|
||||||
//TODO: parse args
|
|
||||||
args = mTokenizer[mIndex + 1]->text; // (int a,int b)
|
|
||||||
lastType += "(*)" + args; // void(int a,int b)
|
|
||||||
mIndex++;
|
|
||||||
} else if (mTokenizer[mIndex]->text.back() == ']') { //array; break args
|
|
||||||
int pos = mTokenizer[mIndex]->text.indexOf('[');
|
|
||||||
cmd = mTokenizer[mIndex]->text.mid(0,pos);
|
|
||||||
args = mTokenizer[mIndex]->text.mid(pos);
|
|
||||||
} else {
|
|
||||||
cmd = mTokenizer[mIndex]->text;
|
|
||||||
args = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a statement for every struct we are in
|
|
||||||
if (!lastType.isEmpty()) {
|
|
||||||
addChildStatement(
|
addChildStatement(
|
||||||
getCurrentScope(),
|
getCurrentScope(),
|
||||||
mCurrentFile,
|
mCurrentFile,
|
||||||
lastType,
|
(lastType+' '+tempType+suffix).trimmed(),
|
||||||
cmd,
|
cmd,
|
||||||
args,
|
args,
|
||||||
"",
|
"",
|
||||||
|
@ -3340,32 +3271,25 @@ void CppParser::handleVar()
|
||||||
!isExtern,
|
!isExtern,
|
||||||
isStatic); // TODO: not supported to pass list
|
isStatic); // TODO: not supported to pass list
|
||||||
varAdded = true;
|
varAdded = true;
|
||||||
|
tempType="";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mIndex++;
|
||||||
// Step over the variable name
|
} else if (mTokenizer[mIndex]->text==';') {
|
||||||
if (isblockChar(mTokenizer[mIndex]->text.front())) {
|
break;
|
||||||
break;
|
} else if (mTokenizer[mIndex]->text=='(') {
|
||||||
}
|
mIndex=mTokenizer[mIndex]->matchIndex+1;
|
||||||
|
} else if (mTokenizer[mIndex]->text=='{') {
|
||||||
|
mIndex=mTokenizer[mIndex]->matchIndex+1;
|
||||||
|
} else {
|
||||||
|
tempType="";
|
||||||
mIndex++;
|
mIndex++;
|
||||||
}
|
}
|
||||||
if (mIndex >= mTokenizer.tokenCount())
|
|
||||||
break;
|
|
||||||
if (isblockChar(mTokenizer[mIndex]->text.front()))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (varAdded && (mIndex < mTokenizer.tokenCount())
|
// Skip ;
|
||||||
&& (mTokenizer[mIndex]->text == '{')) {
|
mIndex++;
|
||||||
// skip { } like A x {new A};
|
|
||||||
int i=indexOfMatchingBrace(mIndex);
|
return true;
|
||||||
if (i!=mIndex)
|
|
||||||
mIndex = i+1;
|
|
||||||
}
|
|
||||||
// Skip ; and ,
|
|
||||||
if ( (mIndex < mTokenizer.tokenCount()) &&
|
|
||||||
(mTokenizer[mIndex]->text.front() == ';'
|
|
||||||
|| mTokenizer[mIndex]->text.front() == ','))
|
|
||||||
mIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppParser::internalParse(const QString &fileName)
|
void CppParser::internalParse(const QString &fileName)
|
||||||
|
@ -4436,236 +4360,39 @@ int CppParser::calcKeyLenForStruct(const QString &word)
|
||||||
|
|
||||||
void CppParser::scanMethodArgs(const PStatement& functionStatement, int argStart, int argEnd)
|
void CppParser::scanMethodArgs(const PStatement& functionStatement, int argStart, int argEnd)
|
||||||
{
|
{
|
||||||
// Split up argument string by ,
|
int paramStart = argStart+1;
|
||||||
int i = argStart+1; // assume it starts with ( and ends with )
|
int i = paramStart ; // assume it starts with ( and ends with )
|
||||||
int paramStart = i;
|
|
||||||
// Keep going and stop on top of the variable name
|
// Keep going and stop on top of the variable name
|
||||||
QString lastType = "";
|
QString varType = "";
|
||||||
bool isFunctionPointer = false;
|
|
||||||
bool varAdded = false;
|
|
||||||
while (i < argEnd) {
|
while (i < argEnd) {
|
||||||
if ((argStr[i] == ',') ||
|
if (mTokenizer[i]->text=='('
|
||||||
((i == argStr.length()-1) && (argStr[i] == ')'))) {
|
&& mTokenizer[i]->matchIndex+1<argEnd
|
||||||
// We've found "int* a" for example
|
&& mTokenizer[mTokenizer[i]->matchIndex+1]->text=='(') {
|
||||||
QString s = argStr.mid(paramStart,i-paramStart);
|
//function pointer
|
||||||
|
int argStart=mTokenizer[i]->matchIndex+1;
|
||||||
|
int argEnd=mTokenizer[argStart]->matchIndex;
|
||||||
|
i=
|
||||||
|
} else if (mTokenizer[i]->text=='{') {
|
||||||
|
i=mTokenizer[i]->matchIndex+1;
|
||||||
|
} else if (mTokenizer[i]->text=='(') {
|
||||||
|
i=mTokenizer[i]->matchIndex+1;
|
||||||
|
} else if (isWordChar(mTokenizer[i]->text[0])) {
|
||||||
|
if (varType.isEmpty()) {
|
||||||
|
|
||||||
//remove default value
|
} else if
|
||||||
int assignPos = s.indexOf('=');
|
QString cmd=mTokenizer[i]->text;
|
||||||
if (assignPos >= 0) {
|
if () {
|
||||||
s.truncate(assignPos);
|
QString args,suffix;
|
||||||
s = s.trimmed();
|
parseCommandTypeAndArgs(cmd,suffix,args);
|
||||||
}
|
if (!cmd.isEmpty()) {
|
||||||
//todo: we don't support function pointer parameters now, till we can tokenize function parameters
|
PStatement statement=findStatementOf(mCurrentFile,cmd,functionStatement,true);
|
||||||
|
if (!statement || !isTypeStatement(statement->kind)) {
|
||||||
//skip []
|
}
|
||||||
int varEndPos = s.length()-1;
|
|
||||||
int bracketLevel = 0;
|
|
||||||
while (varEndPos>=0) {
|
|
||||||
switch(s[varEndPos].unicode()) {
|
|
||||||
case ']':
|
|
||||||
bracketLevel++;
|
|
||||||
break;
|
|
||||||
case '[':
|
|
||||||
bracketLevel--;
|
|
||||||
varEndPos--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (bracketLevel==0)
|
|
||||||
break;
|
|
||||||
varEndPos--;
|
|
||||||
}
|
|
||||||
int varStartPos = varEndPos;
|
|
||||||
if (varEndPos>=0) {
|
|
||||||
while (varStartPos-1>=0) {
|
|
||||||
if (!mTokenizer.isIdentChar(s[varStartPos-1]))
|
|
||||||
break;
|
|
||||||
varStartPos--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (varStartPos>=0) {
|
|
||||||
if (varEndPos+1<s.length())
|
|
||||||
args=s.mid(varEndPos+1);
|
|
||||||
addStatement(
|
|
||||||
functionStatement,
|
|
||||||
mCurrentFile,
|
|
||||||
s.mid(0,varStartPos), // 'int*'
|
|
||||||
s.mid(varStartPos,varEndPos-varStartPos+1), // a
|
|
||||||
args,
|
|
||||||
"",
|
|
||||||
functionStatement->definitionLine,
|
|
||||||
StatementKind::skParameter,
|
|
||||||
StatementScope::Local,
|
|
||||||
StatementClassScope::None,
|
|
||||||
true,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
if (varStartPos<s.length()) {
|
|
||||||
args = "";
|
|
||||||
int bracketPos = s.indexOf('[');
|
|
||||||
if (bracketPos >= 0) {
|
|
||||||
args = s.mid(bracketPos);
|
|
||||||
s.truncate(bracketPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
paramStart = i + 1; // step over ,
|
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if ((mIndex + 2 < mTokenizer.tokenCount())
|
|
||||||
&& (mTokenizer[mIndex + 1]->text.front() == '(')
|
|
||||||
&& (mTokenizer[mIndex + 2]->text.front() == '(')) {
|
|
||||||
isFunctionPointer = mTokenizer[mIndex + 1]->text.indexOf('*') >= 0;
|
|
||||||
if (!isFunctionPointer)
|
|
||||||
break; // inline constructor
|
|
||||||
} else if ((mIndex + 1 < mTokenizer.tokenCount())
|
|
||||||
&& (mTokenizer[mIndex + 1]->text.front()=='('
|
|
||||||
|| mTokenizer[mIndex + 1]->text.front()==','
|
|
||||||
|| mTokenizer[mIndex + 1]->text.front()==';'
|
|
||||||
|| mTokenizer[mIndex + 1]->text.front()==':'
|
|
||||||
|| mTokenizer[mIndex + 1]->text.front()=='}'
|
|
||||||
|| mTokenizer[mIndex + 1]->text.front()=='#'
|
|
||||||
|| mTokenizer[mIndex + 1]->text.front()=='{')) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// we've made a mistake, this is a typedef , not a variable definition.
|
|
||||||
if (mTokenizer[mIndex]->text == "typedef")
|
|
||||||
return;
|
|
||||||
|
|
||||||
// struct/class/union is part of the type signature
|
|
||||||
// but we dont store it in the type cache, so must trim it to find the type info
|
|
||||||
if (mTokenizer[mIndex]->text!="struct"
|
|
||||||
&& mTokenizer[mIndex]->text!="class"
|
|
||||||
&& mTokenizer[mIndex]->text!="union") {
|
|
||||||
if (mTokenizer[mIndex]->text == ':') {
|
|
||||||
lastType += ':';
|
|
||||||
} else {
|
|
||||||
QString s=mTokenizer[mIndex]->text;
|
|
||||||
if (s == "extern") {
|
|
||||||
isExtern = true;
|
|
||||||
} else {
|
|
||||||
if (!s.isEmpty())
|
|
||||||
lastType += ' '+s;
|
|
||||||
if (s == "static")
|
|
||||||
isStatic = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mIndex++;
|
|
||||||
if(mIndex >= mTokenizer.tokenCount())
|
|
||||||
break;
|
|
||||||
if (isFunctionPointer)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lastType = lastType.trimmed();
|
|
||||||
|
|
||||||
// Don't bother entering the scanning loop when we have failed
|
|
||||||
if (mIndex >= mTokenizer.tokenCount())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Find the variable name
|
|
||||||
while (true) {
|
|
||||||
|
|
||||||
// Skip bit identifiers,
|
|
||||||
// e.g.:
|
|
||||||
// handle
|
|
||||||
// unsigned short bAppReturnCode:8,reserved:6,fBusy:1,fAck:1
|
|
||||||
// as
|
|
||||||
// unsigned short bAppReturnCode,reserved,fBusy,fAck
|
|
||||||
if ( (mIndex < mTokenizer.tokenCount()) && (mTokenizer[mIndex]->text.front() == ':')) {
|
|
||||||
while ( (mIndex < mTokenizer.tokenCount())
|
|
||||||
&& !(
|
|
||||||
mTokenizer[mIndex]->text.front() == ','
|
|
||||||
|| isblockChar(';')
|
|
||||||
))
|
|
||||||
mIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip inline constructors,
|
|
||||||
// e.g.:
|
|
||||||
// handle
|
|
||||||
// int a(3)
|
|
||||||
// as
|
|
||||||
// int a
|
|
||||||
if (!isFunctionPointer &&
|
|
||||||
mIndex < mTokenizer.tokenCount() &&
|
|
||||||
mTokenizer[mIndex]->text.front() == '(') {
|
|
||||||
while ((mIndex < mTokenizer.tokenCount())
|
|
||||||
&& !(
|
|
||||||
mTokenizer[mIndex]->text.front() == ','
|
|
||||||
|| isblockChar(mTokenizer[mIndex]->text.front())
|
|
||||||
))
|
|
||||||
mIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Did we stop on top of the variable name?
|
|
||||||
if (mIndex < mTokenizer.tokenCount()) {
|
|
||||||
if (mTokenizer[mIndex]->text.front()!=','
|
|
||||||
&& mTokenizer[mIndex]->text.front()!=';') {
|
|
||||||
QString cmd;
|
|
||||||
QString args;
|
|
||||||
if (isFunctionPointer && (mIndex + 1 < mTokenizer.tokenCount())) {
|
|
||||||
QString s = mTokenizer[mIndex]->text;
|
|
||||||
cmd = s.mid(2,s.length()-3).trimmed(); // (*foo) -> foo
|
|
||||||
args = mTokenizer[mIndex + 1]->text; // (int a,int b)
|
|
||||||
lastType += "(*)" + args; // void(int a,int b)
|
|
||||||
mIndex++;
|
|
||||||
} else if (mTokenizer[mIndex]->text.back() == ']') { //array; break args
|
|
||||||
int pos = mTokenizer[mIndex]->text.indexOf('[');
|
|
||||||
cmd = mTokenizer[mIndex]->text.mid(0,pos);
|
|
||||||
args = mTokenizer[mIndex]->text.mid(pos);
|
|
||||||
} else {
|
|
||||||
cmd = mTokenizer[mIndex]->text;
|
|
||||||
args = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a statement for every struct we are in
|
|
||||||
if (!lastType.isEmpty()) {
|
|
||||||
addChildStatement(
|
|
||||||
getCurrentScope(),
|
|
||||||
mCurrentFile,
|
|
||||||
lastType,
|
|
||||||
cmd,
|
|
||||||
args,
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
mTokenizer[mIndex]->line,
|
|
||||||
StatementKind::skVariable,
|
|
||||||
getScope(),
|
|
||||||
mClassScope,
|
|
||||||
//True,
|
|
||||||
!isExtern,
|
|
||||||
isStatic); // TODO: not supported to pass list
|
|
||||||
varAdded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step over the variable name
|
|
||||||
if (isblockChar(mTokenizer[mIndex]->text.front())) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mIndex++;
|
|
||||||
}
|
|
||||||
if (mIndex >= mTokenizer.tokenCount())
|
|
||||||
break;
|
|
||||||
if (isblockChar(mTokenizer[mIndex]->text.front()))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (varAdded && (mIndex < mTokenizer.tokenCount())
|
|
||||||
&& (mTokenizer[mIndex]->text == '{')) {
|
|
||||||
// skip { } like A x {new A};
|
|
||||||
int i=indexOfMatchingBrace(mIndex);
|
|
||||||
if (i!=mIndex)
|
|
||||||
mIndex = i+1;
|
|
||||||
}
|
|
||||||
// Skip ; and ,
|
|
||||||
if ( (mIndex < mTokenizer.tokenCount()) &&
|
|
||||||
(mTokenizer[mIndex]->text.front() == ';'
|
|
||||||
|| mTokenizer[mIndex]->text.front() == ','))
|
|
||||||
mIndex++;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,6 @@ private:
|
||||||
bool checkForTypedefEnum();
|
bool checkForTypedefEnum();
|
||||||
bool checkForTypedefStruct();
|
bool checkForTypedefStruct();
|
||||||
bool checkForUsing(KeywordType keywordType);
|
bool checkForUsing(KeywordType keywordType);
|
||||||
bool checkForVar();
|
|
||||||
|
|
||||||
void fillListOfFunctions(const QString& fileName, int line,
|
void fillListOfFunctions(const QString& fileName, int line,
|
||||||
const PStatement& statement,
|
const PStatement& statement,
|
||||||
|
@ -414,7 +413,7 @@ private:
|
||||||
bool handleStatement();
|
bool handleStatement();
|
||||||
void handleStructs(bool isTypedef = false);
|
void handleStructs(bool isTypedef = false);
|
||||||
void handleUsing();
|
void handleUsing();
|
||||||
void handleVar();
|
bool tryHandleVar();
|
||||||
void internalParse(const QString& fileName);
|
void internalParse(const QString& fileName);
|
||||||
// function FindMacroDefine(const Command: AnsiString): PStatement;
|
// function FindMacroDefine(const Command: AnsiString): PStatement;
|
||||||
void inheritClassStatement(
|
void inheritClassStatement(
|
||||||
|
|
Loading…
Reference in New Issue