- Enhancement: Better support for macros.
This commit is contained in:
parent
d75f550742
commit
bfd00957eb
1
NEWS.md
1
NEWS.md
|
@ -32,6 +32,7 @@ Red Panda C++ Version 2.26
|
||||||
- change: Use qt.conf to use freetype font engine. User can use the windows default font engine by remove this file.
|
- change: Use qt.conf to use freetype font engine. User can use the windows default font engine by remove this file.
|
||||||
- fix: Click on the line begin may toggle breakpoint.
|
- fix: Click on the line begin may toggle breakpoint.
|
||||||
- change: Don't auto add; when completing '{' for lines starting with 'struct/union/enum' and ending with ')'
|
- change: Don't auto add; when completing '{' for lines starting with 'struct/union/enum' and ending with ')'
|
||||||
|
- Enhancement: Better support for macros.
|
||||||
|
|
||||||
Red Panda C++ Version 2.25
|
Red Panda C++ Version 2.25
|
||||||
|
|
||||||
|
|
|
@ -499,6 +499,7 @@ PEvalStatement CppParser::evalExpression(
|
||||||
pos,
|
pos,
|
||||||
currentScope,
|
currentScope,
|
||||||
PEvalStatement(),
|
PEvalStatement(),
|
||||||
|
true,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,7 +538,7 @@ PStatement CppParser::doFindStatementOf(const QString &fileName, const QStringLi
|
||||||
pos,
|
pos,
|
||||||
currentScope,
|
currentScope,
|
||||||
PEvalStatement(),
|
PEvalStatement(),
|
||||||
true);
|
true,false);
|
||||||
if (!ownerEvalStatement) {
|
if (!ownerEvalStatement) {
|
||||||
return PStatement();
|
return PStatement();
|
||||||
}
|
}
|
||||||
|
@ -4126,7 +4127,7 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
|
||||||
pos,
|
pos,
|
||||||
getCurrentScope(),
|
getCurrentScope(),
|
||||||
PEvalStatement(),
|
PEvalStatement(),
|
||||||
true);
|
true,false);
|
||||||
if(aliasStatement && aliasStatement->effectiveTypeStatement) {
|
if(aliasStatement && aliasStatement->effectiveTypeStatement) {
|
||||||
if (STLMaps.contains(aliasStatement->effectiveTypeStatement->fullName)) {
|
if (STLMaps.contains(aliasStatement->effectiveTypeStatement->fullName)) {
|
||||||
addedVar->type = "std::pair"+aliasStatement->templateParams;
|
addedVar->type = "std::pair"+aliasStatement->templateParams;
|
||||||
|
@ -4194,7 +4195,7 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
|
||||||
pos,
|
pos,
|
||||||
getCurrentScope(),
|
getCurrentScope(),
|
||||||
PEvalStatement(),
|
PEvalStatement(),
|
||||||
true);
|
true,false);
|
||||||
if(aliasStatement) {
|
if(aliasStatement) {
|
||||||
if (aliasStatement->effectiveTypeStatement) {
|
if (aliasStatement->effectiveTypeStatement) {
|
||||||
addedVar->type = aliasStatement->effectiveTypeStatement->fullName;
|
addedVar->type = aliasStatement->effectiveTypeStatement->fullName;
|
||||||
|
@ -4294,7 +4295,7 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
|
||||||
pos,
|
pos,
|
||||||
getCurrentScope(),
|
getCurrentScope(),
|
||||||
PEvalStatement(),
|
PEvalStatement(),
|
||||||
true);
|
true,false);
|
||||||
if(aliasStatement && aliasStatement->effectiveTypeStatement) {
|
if(aliasStatement && aliasStatement->effectiveTypeStatement) {
|
||||||
if (aliasStatement->effectiveTypeStatement) {
|
if (aliasStatement->effectiveTypeStatement) {
|
||||||
addedVar->type = aliasStatement->effectiveTypeStatement->fullName;
|
addedVar->type = aliasStatement->effectiveTypeStatement->fullName;
|
||||||
|
@ -4544,8 +4545,7 @@ PStatement CppParser::findMacro(const QString &phrase, const QString &fileName)
|
||||||
PFileIncludes includes = mPreprocessor.findFileIncludes(fileName);
|
PFileIncludes includes = mPreprocessor.findFileIncludes(fileName);
|
||||||
foreach (const PStatement& s, statements) {
|
foreach (const PStatement& s, statements) {
|
||||||
if (s->kind == StatementKind::skPreprocessor) {
|
if (s->kind == StatementKind::skPreprocessor) {
|
||||||
if (includes && !includes->includeFiles.contains(s->fileName)
|
if (includes && fileName != s->fileName && !includes->includeFiles.contains(s->fileName))
|
||||||
&& !includes->includeFiles.contains(s->definitionFileName))
|
|
||||||
continue;
|
continue;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -4687,13 +4687,35 @@ PStatement CppParser::findStatementInNamespace(const QString &name, const QStrin
|
||||||
}
|
}
|
||||||
|
|
||||||
PEvalStatement CppParser::doEvalExpression(const QString& fileName,
|
PEvalStatement CppParser::doEvalExpression(const QString& fileName,
|
||||||
QStringList& phraseExpression,
|
QStringList phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
bool freeScoped) const
|
bool freeScoped,
|
||||||
|
bool expandMacros) const
|
||||||
{
|
{
|
||||||
//dummy function to easy later upgrades
|
if (expandMacros) {
|
||||||
|
QList<QSet<QString>> usedMacros;
|
||||||
|
usedMacros.reserve(phraseExpression.length());
|
||||||
|
for(int i=0;i<phraseExpression.length();i++) {
|
||||||
|
usedMacros.append(QSet<QString>());
|
||||||
|
}
|
||||||
|
int i=pos;
|
||||||
|
while(i<phraseExpression.length()) {
|
||||||
|
QString word = phraseExpression[i];
|
||||||
|
if (isIdentifier(word)) {
|
||||||
|
QSet<QString> used = usedMacros[i];
|
||||||
|
if (!used.contains(word)) {
|
||||||
|
PStatement macro = findMacro(word, fileName);
|
||||||
|
if (macro) {
|
||||||
|
if(!expandMacro(phraseExpression, i, macro, usedMacros))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
return doEvalPointerArithmetic(fileName,
|
return doEvalPointerArithmetic(fileName,
|
||||||
phraseExpression,
|
phraseExpression,
|
||||||
pos,
|
pos,
|
||||||
|
@ -4702,7 +4724,7 @@ PEvalStatement CppParser::doEvalExpression(const QString& fileName,
|
||||||
freeScoped);
|
freeScoped);
|
||||||
}
|
}
|
||||||
|
|
||||||
PEvalStatement CppParser::doEvalPointerArithmetic(const QString &fileName, QStringList &phraseExpression, int &pos, const PStatement &scope, const PEvalStatement &previousResult, bool freeScoped) const
|
PEvalStatement CppParser::doEvalPointerArithmetic(const QString &fileName, const QStringList &phraseExpression, int &pos, const PStatement &scope, const PEvalStatement &previousResult, bool freeScoped) const
|
||||||
{
|
{
|
||||||
if (pos>=phraseExpression.length())
|
if (pos>=phraseExpression.length())
|
||||||
return PEvalStatement();
|
return PEvalStatement();
|
||||||
|
@ -4753,7 +4775,7 @@ PEvalStatement CppParser::doEvalPointerArithmetic(const QString &fileName, QStri
|
||||||
|
|
||||||
PEvalStatement CppParser::doEvalPointerToMembers(
|
PEvalStatement CppParser::doEvalPointerToMembers(
|
||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
QStringList &phraseExpression,
|
const QStringList &phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement &scope,
|
const PStatement &scope,
|
||||||
const PEvalStatement &previousResult,
|
const PEvalStatement &previousResult,
|
||||||
|
@ -4796,7 +4818,7 @@ PEvalStatement CppParser::doEvalPointerToMembers(
|
||||||
}
|
}
|
||||||
|
|
||||||
PEvalStatement CppParser::doEvalCCast(const QString &fileName,
|
PEvalStatement CppParser::doEvalCCast(const QString &fileName,
|
||||||
QStringList &phraseExpression,
|
const QStringList &phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
|
@ -4901,7 +4923,8 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName,
|
||||||
pos,
|
pos,
|
||||||
scope,
|
scope,
|
||||||
PEvalStatement(),
|
PEvalStatement(),
|
||||||
true);
|
true,
|
||||||
|
false);
|
||||||
// qDebug()<<pos;
|
// qDebug()<<pos;
|
||||||
if (pos >= phraseExpression.length() || phraseExpression[pos]!=")") {
|
if (pos >= phraseExpression.length() || phraseExpression[pos]!=")") {
|
||||||
return PEvalStatement();
|
return PEvalStatement();
|
||||||
|
@ -4945,7 +4968,7 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName,
|
||||||
}
|
}
|
||||||
|
|
||||||
PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName,
|
PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName,
|
||||||
QStringList &phraseExpression,
|
const QStringList &phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
|
@ -4979,7 +5002,8 @@ PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName,
|
||||||
pos,
|
pos,
|
||||||
scope,
|
scope,
|
||||||
PEvalStatement(),
|
PEvalStatement(),
|
||||||
true);
|
true,
|
||||||
|
false);
|
||||||
if (newResult)
|
if (newResult)
|
||||||
newResult->assignType(result);
|
newResult->assignType(result);
|
||||||
pos++; // skip ")"
|
pos++; // skip ")"
|
||||||
|
@ -5163,7 +5187,7 @@ PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName,
|
||||||
}
|
}
|
||||||
|
|
||||||
PEvalStatement CppParser::doEvalScopeResolution(const QString &fileName,
|
PEvalStatement CppParser::doEvalScopeResolution(const QString &fileName,
|
||||||
QStringList &phraseExpression,
|
const QStringList &phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
|
@ -5218,7 +5242,7 @@ PEvalStatement CppParser::doEvalScopeResolution(const QString &fileName,
|
||||||
}
|
}
|
||||||
|
|
||||||
PEvalStatement CppParser::doEvalTerm(const QString &fileName,
|
PEvalStatement CppParser::doEvalTerm(const QString &fileName,
|
||||||
QStringList &phraseExpression,
|
const QStringList &phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
|
@ -5235,7 +5259,7 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
|
||||||
// qDebug()<<"eval term"<<phraseExpression[pos];
|
// qDebug()<<"eval term"<<phraseExpression[pos];
|
||||||
if (phraseExpression[pos]=="(") {
|
if (phraseExpression[pos]=="(") {
|
||||||
pos++;
|
pos++;
|
||||||
result = doEvalExpression(fileName,phraseExpression,pos,scope,PEvalStatement(),freeScoped);
|
result = doEvalExpression(fileName,phraseExpression,pos,scope,PEvalStatement(),freeScoped,false);
|
||||||
if (pos >= phraseExpression.length() || phraseExpression[pos]!=")")
|
if (pos >= phraseExpression.length() || phraseExpression[pos]!=")")
|
||||||
return PEvalStatement();
|
return PEvalStatement();
|
||||||
else {
|
else {
|
||||||
|
@ -5329,15 +5353,6 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
|
||||||
result = doCreateEvalFunction(fileName,statement);
|
result = doCreateEvalFunction(fileName,statement);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case StatementKind::skPreprocessor:
|
|
||||||
// qDebug()<<"before"<<phraseExpression;
|
|
||||||
pos--;
|
|
||||||
if (expandMacro(phraseExpression,pos,statement)) {
|
|
||||||
// qDebug()<<"after"<<phraseExpression;
|
|
||||||
result = doEvalExpression(fileName,phraseExpression,pos,scope,previousResult,freeScoped);
|
|
||||||
} else
|
|
||||||
result = PEvalStatement();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
result = PEvalStatement();
|
result = PEvalStatement();
|
||||||
}
|
}
|
||||||
|
@ -5395,12 +5410,14 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppParser::expandMacro(QStringList &phraseExpression, int &pos, const PStatement ¯o) const
|
bool CppParser::expandMacro(QStringList &phraseExpression, int pos, PStatement macro, QList< QSet<QString> > &usedMacros) const
|
||||||
{
|
{
|
||||||
QString s;
|
QString s;
|
||||||
|
QSet<QString> used = usedMacros[pos];
|
||||||
if (macro->args.isEmpty()) {
|
if (macro->args.isEmpty()) {
|
||||||
s=macro->value;
|
s=macro->value;
|
||||||
phraseExpression.removeAt(pos);
|
phraseExpression.removeAt(pos);
|
||||||
|
usedMacros.removeAt(pos);
|
||||||
} else {
|
} else {
|
||||||
QString args=macro->args.mid(1,macro->args.length()-2).trimmed(); // remove '(' ')'
|
QString args=macro->args.mid(1,macro->args.length()-2).trimmed(); // remove '(' ')'
|
||||||
|
|
||||||
|
@ -5480,13 +5497,14 @@ bool CppParser::expandMacro(QStringList &phraseExpression, int &pos, const PStat
|
||||||
}
|
}
|
||||||
for (int j=pos;j<=i;j++) {
|
for (int j=pos;j<=i;j++) {
|
||||||
phraseExpression.removeAt(pos);
|
phraseExpression.removeAt(pos);
|
||||||
|
usedMacros.removeAt(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
used.insert(macro->command);
|
||||||
QSynedit::CppSyntaxer syntaxer;
|
QSynedit::CppSyntaxer syntaxer;
|
||||||
syntaxer.resetState();
|
syntaxer.resetState();
|
||||||
syntaxer.setLine(s,0);
|
syntaxer.setLine(s,0);
|
||||||
int i=0;
|
|
||||||
while (!syntaxer.eol()) {
|
while (!syntaxer.eol()) {
|
||||||
QString token=syntaxer.getToken();
|
QString token=syntaxer.getToken();
|
||||||
QSynedit::PTokenAttribute attr = syntaxer.getTokenAttribute();
|
QSynedit::PTokenAttribute attr = syntaxer.getTokenAttribute();
|
||||||
|
@ -5495,15 +5513,14 @@ bool CppParser::expandMacro(QStringList &phraseExpression, int &pos, const PStat
|
||||||
case QSynedit::TokenType::Comment:
|
case QSynedit::TokenType::Comment:
|
||||||
break;
|
break;
|
||||||
case QSynedit::TokenType::Identifier:
|
case QSynedit::TokenType::Identifier:
|
||||||
if (token!=macro->command)
|
phraseExpression.insert(pos,token);
|
||||||
phraseExpression.insert(pos+i,token);
|
usedMacros.insert(pos,used);
|
||||||
else
|
pos++;
|
||||||
phraseExpression.insert(pos+i,token+"_expanded");
|
|
||||||
i++;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
phraseExpression.insert(pos+i,token);
|
phraseExpression.insert(pos,token);
|
||||||
i++;
|
usedMacros.insert(pos,used);
|
||||||
|
pos++;
|
||||||
}
|
}
|
||||||
syntaxer.next();
|
syntaxer.next();
|
||||||
}
|
}
|
||||||
|
@ -5541,7 +5558,8 @@ PEvalStatement CppParser::doFindAliasedNamespace(const PStatement &namespaceAlia
|
||||||
pos,
|
pos,
|
||||||
namespaceAlias->parentScope.lock(),
|
namespaceAlias->parentScope.lock(),
|
||||||
PEvalStatement(),
|
PEvalStatement(),
|
||||||
true
|
true,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -319,57 +319,58 @@ private:
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
PEvalStatement doEvalExpression(const QString& fileName,
|
PEvalStatement doEvalExpression(const QString& fileName,
|
||||||
QStringList& phraseExpression,
|
QStringList phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
bool freeScoped) const;
|
bool freeScoped,
|
||||||
|
bool expandMacros) const;
|
||||||
|
|
||||||
PEvalStatement doEvalPointerArithmetic(
|
PEvalStatement doEvalPointerArithmetic(
|
||||||
const QString& fileName,
|
const QString& fileName,
|
||||||
QStringList& phraseExpression,
|
const QStringList& phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
bool freeScoped) const;
|
bool freeScoped) const;
|
||||||
PEvalStatement doEvalPointerToMembers(
|
PEvalStatement doEvalPointerToMembers(
|
||||||
const QString& fileName,
|
const QString& fileName,
|
||||||
QStringList& phraseExpression,
|
const QStringList& phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
bool freeScoped) const;
|
bool freeScoped) const;
|
||||||
PEvalStatement doEvalCCast(
|
PEvalStatement doEvalCCast(
|
||||||
const QString& fileName,
|
const QString& fileName,
|
||||||
QStringList& phraseExpression,
|
const QStringList& phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
bool freeScoped) const;
|
bool freeScoped) const;
|
||||||
PEvalStatement doEvalMemberAccess(
|
PEvalStatement doEvalMemberAccess(
|
||||||
const QString& fileName,
|
const QString& fileName,
|
||||||
QStringList& phraseExpression,
|
const QStringList& phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
bool freeScoped) const;
|
bool freeScoped) const;
|
||||||
PEvalStatement doEvalScopeResolution(
|
PEvalStatement doEvalScopeResolution(
|
||||||
const QString& fileName,
|
const QString& fileName,
|
||||||
QStringList& phraseExpression,
|
const QStringList& phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
bool freeScoped) const;
|
bool freeScoped) const;
|
||||||
PEvalStatement doEvalTerm(
|
PEvalStatement doEvalTerm(
|
||||||
const QString& fileName,
|
const QString& fileName,
|
||||||
QStringList& phraseExpression,
|
const QStringList& phraseExpression,
|
||||||
int &pos,
|
int &pos,
|
||||||
const PStatement& scope,
|
const PStatement& scope,
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
bool freeScoped) const;
|
bool freeScoped) const;
|
||||||
|
|
||||||
bool expandMacro(QStringList& phraseExpression,int &pos,
|
bool expandMacro(QStringList& phraseExpression,int pos,
|
||||||
const PStatement& macro) const;
|
PStatement macro, QList< QSet<QString> > &usedMacros) const;
|
||||||
|
|
||||||
PEvalStatement doCreateEvalNamespace(const PStatement& namespaceStatement) const;
|
PEvalStatement doCreateEvalNamespace(const PStatement& namespaceStatement) const;
|
||||||
|
|
||||||
|
|
|
@ -515,11 +515,8 @@ void CppPreprocessor::handleUndefine(const QString &line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CppPreprocessor::expandMacros(const QString &line, int depth)
|
QString CppPreprocessor::expandMacros(const QString &line, QSet<QString> usedMacros)
|
||||||
{
|
{
|
||||||
//prevent infinit recursion
|
|
||||||
if (depth > MAX_DEFINE_EXPAND_DEPTH)
|
|
||||||
return line;
|
|
||||||
QString word;
|
QString word;
|
||||||
QString newLine;
|
QString newLine;
|
||||||
int lenLine = line.length();
|
int lenLine = line.length();
|
||||||
|
@ -530,7 +527,7 @@ QString CppPreprocessor::expandMacros(const QString &line, int depth)
|
||||||
word += ch;
|
word += ch;
|
||||||
} else {
|
} else {
|
||||||
if (!word.isEmpty()) {
|
if (!word.isEmpty()) {
|
||||||
expandMacro(line,newLine,word,i,depth);
|
expandMacro(line,newLine,word,i,usedMacros);
|
||||||
}
|
}
|
||||||
word = "";
|
word = "";
|
||||||
if (i< lenLine) {
|
if (i< lenLine) {
|
||||||
|
@ -540,7 +537,7 @@ QString CppPreprocessor::expandMacros(const QString &line, int depth)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (!word.isEmpty()) {
|
if (!word.isEmpty()) {
|
||||||
expandMacro(line,newLine,word,i,depth);
|
expandMacro(line,newLine,word,i, usedMacros);
|
||||||
}
|
}
|
||||||
return newLine;
|
return newLine;
|
||||||
}
|
}
|
||||||
|
@ -551,6 +548,7 @@ QString CppPreprocessor::expandMacros()
|
||||||
QString word;
|
QString word;
|
||||||
QString newLine;
|
QString newLine;
|
||||||
QString line = mBuffer[mIndex];
|
QString line = mBuffer[mIndex];
|
||||||
|
QSet<QString> usedMacros;
|
||||||
int i=0;
|
int i=0;
|
||||||
while (mIndex < mBuffer.size() && i<line.length()) {
|
while (mIndex < mBuffer.size() && i<line.length()) {
|
||||||
QChar ch=line[i];
|
QChar ch=line[i];
|
||||||
|
@ -558,7 +556,7 @@ QString CppPreprocessor::expandMacros()
|
||||||
word += ch;
|
word += ch;
|
||||||
} else {
|
} else {
|
||||||
if (!word.isEmpty()) {
|
if (!word.isEmpty()) {
|
||||||
expandMacro(newLine,word,i,1);
|
expandMacro(newLine,word,i,usedMacros);
|
||||||
if (mIndex>=mBuffer.length())
|
if (mIndex>=mBuffer.length())
|
||||||
return newLine;
|
return newLine;
|
||||||
line = mBuffer[mIndex];
|
line = mBuffer[mIndex];
|
||||||
|
@ -571,21 +569,23 @@ QString CppPreprocessor::expandMacros()
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (!word.isEmpty()) {
|
if (!word.isEmpty()) {
|
||||||
expandMacro(newLine,word,i,1);
|
expandMacro(newLine,word,i,usedMacros);
|
||||||
}
|
}
|
||||||
return newLine;
|
return newLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString &word, int &i, int depth)
|
void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString &word, int &i, QSet<QString> usedMacros)
|
||||||
{
|
{
|
||||||
|
if (usedMacros.contains(word))
|
||||||
|
return;
|
||||||
int lenLine = line.length();
|
int lenLine = line.length();
|
||||||
PDefine define = getDefine(word);
|
PDefine define = getDefine(word);
|
||||||
if (define && define->args=="" ) {
|
if (define && define->args=="" ) {
|
||||||
if (define->value != word )
|
usedMacros.insert(word);
|
||||||
newLine += expandMacros(define->value,depth+1);
|
if (define->value != word ) {
|
||||||
else
|
newLine += expandMacros(define->value,usedMacros);
|
||||||
|
} else
|
||||||
newLine += word;
|
newLine += word;
|
||||||
|
|
||||||
} else if (define && (define->args!="")) {
|
} else if (define && (define->args!="")) {
|
||||||
while ((i<lenLine) && (line[i] == ' ' || line[i]=='\t'))
|
while ((i<lenLine) && (line[i] == ' ' || line[i]=='\t'))
|
||||||
i++;
|
i++;
|
||||||
|
@ -620,7 +620,8 @@ void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString
|
||||||
argEnd = i-2;
|
argEnd = i-2;
|
||||||
QString args = line.mid(argStart,argEnd-argStart+1).trimmed();
|
QString args = line.mid(argStart,argEnd-argStart+1).trimmed();
|
||||||
QString formattedValue = expandFunction(define,args);
|
QString formattedValue = expandFunction(define,args);
|
||||||
newLine += expandMacros(formattedValue,depth+1);
|
usedMacros.insert(word);
|
||||||
|
newLine += expandMacros(formattedValue,usedMacros);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -629,15 +630,16 @@ void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppPreprocessor::expandMacro(QString &newLine, QString &word, int &i, int depth)
|
void CppPreprocessor::expandMacro(QString &newLine, QString &word, int &i, QSet<QString> usedMacros)
|
||||||
{
|
{
|
||||||
|
if (usedMacros.contains(word))
|
||||||
|
return;
|
||||||
QString line = mBuffer[mIndex];
|
QString line = mBuffer[mIndex];
|
||||||
PDefine define = getDefine(word);
|
PDefine define = getDefine(word);
|
||||||
// if (define && define->name == "DEFHOOKPODX")
|
|
||||||
// qDebug()<<define->args<<define->argList<<define->formatValue;
|
|
||||||
if (define && define->args=="" ) {
|
if (define && define->args=="" ) {
|
||||||
|
usedMacros.insert(word);
|
||||||
if (define->value != word )
|
if (define->value != word )
|
||||||
newLine += expandMacros(define->value,depth+1);
|
newLine += expandMacros(define->value,usedMacros);
|
||||||
else
|
else
|
||||||
newLine += word;
|
newLine += word;
|
||||||
} else if (define && (define->args!="")) {
|
} else if (define && (define->args!="")) {
|
||||||
|
@ -709,13 +711,10 @@ void CppPreprocessor::expandMacro(QString &newLine, QString &word, int &i, int d
|
||||||
args += mBuffer[i];
|
args += mBuffer[i];
|
||||||
}
|
}
|
||||||
args += mBuffer[argLineEnd].left(argEnd);
|
args += mBuffer[argLineEnd].left(argEnd);
|
||||||
// if (define && define->name == "DEFHOOK")
|
|
||||||
// qDebug()<<args;
|
|
||||||
}
|
}
|
||||||
QString formattedValue = expandFunction(define,args);
|
QString formattedValue = expandFunction(define,args);
|
||||||
// if (define && define->name == "DEFHOOKPODX")
|
usedMacros.insert(word);
|
||||||
// qDebug()<<formattedValue;
|
newLine += expandMacros(formattedValue,usedMacros);
|
||||||
newLine += expandMacros(formattedValue,depth+1);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newLine+=word;
|
newLine+=word;
|
||||||
|
|
|
@ -135,10 +135,10 @@ private:
|
||||||
void handleInclude(const QString& line, bool fromNext=false);
|
void handleInclude(const QString& line, bool fromNext=false);
|
||||||
void handlePreprocessor(const QString& value);
|
void handlePreprocessor(const QString& value);
|
||||||
void handleUndefine(const QString& line);
|
void handleUndefine(const QString& line);
|
||||||
QString expandMacros(const QString& line, int depth);
|
QString expandMacros(const QString& line, QSet<QString> usedMacros);
|
||||||
QString expandMacros();
|
QString expandMacros();
|
||||||
void expandMacro(const QString& line, QString& newLine, QString& word, int& i, int depth);
|
void expandMacro(const QString& line, QString& newLine, QString& word, int& i, QSet<QString> usedMacros);
|
||||||
void expandMacro(QString& newLine, QString& word, int& i, int depth);
|
void expandMacro(QString& newLine, QString& word, int& i, QSet<QString> usedMacros);
|
||||||
QString removeGCCAttributes(const QString& line);
|
QString removeGCCAttributes(const QString& line);
|
||||||
void removeGCCAttribute(const QString&line, QString& newLine, int &i, const QString& word);
|
void removeGCCAttribute(const QString&line, QString& newLine, int &i, const QString& word);
|
||||||
PDefine getDefine(const QString& name) const{
|
PDefine getDefine(const QString& name) const{
|
||||||
|
|
Loading…
Reference in New Issue