forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/2.8'
Conflicts: src/plugins/coreplugin/documentmanager.cpp Change-Id: I6dc025bc0f31eb694c8d9e2dd4ea5cc888ee8a94
This commit is contained in:
@@ -341,15 +341,15 @@ QStringList Document::includedFiles() const
|
||||
{
|
||||
QStringList files;
|
||||
foreach (const Include &i, _includes)
|
||||
files.append(i.fileName());
|
||||
files.append(i.resolvedFileName());
|
||||
files.removeDuplicates();
|
||||
return files;
|
||||
}
|
||||
|
||||
// This assumes to be called with a QDir::cleanPath cleaned fileName.
|
||||
void Document::addIncludeFile(const QString &fileName, unsigned line)
|
||||
void Document::addIncludeFile(const Document::Include &include)
|
||||
{
|
||||
_includes.append(Include(fileName, line));
|
||||
_includes.append(include);
|
||||
}
|
||||
|
||||
void Document::appendMacro(const Macro ¯o)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "Macro.h"
|
||||
|
||||
#include <cplusplus/CPlusPlusForwardDeclarations.h>
|
||||
#include <cplusplus/PreprocessorClient.h>
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QDateTime>
|
||||
@@ -75,9 +76,6 @@ public:
|
||||
|
||||
QString fileName() const;
|
||||
|
||||
QStringList includedFiles() const;
|
||||
void addIncludeFile(const QString &fileName, unsigned line);
|
||||
|
||||
void appendMacro(const Macro ¯o);
|
||||
void addMacroUse(const Macro ¯o, unsigned offset, unsigned length,
|
||||
unsigned beginLine,
|
||||
@@ -233,22 +231,31 @@ public:
|
||||
};
|
||||
|
||||
class Include {
|
||||
QString _fileName;
|
||||
QString _resolvedFileName;
|
||||
QString _unresolvedFileName;
|
||||
unsigned _line;
|
||||
Client::IncludeType _type;
|
||||
|
||||
public:
|
||||
Include(const QString &fileName, unsigned line)
|
||||
: _fileName(fileName), _line(line)
|
||||
Include(const QString &unresolvedFileName, const QString &resolvedFileName, unsigned line,
|
||||
Client::IncludeType type)
|
||||
: _resolvedFileName(resolvedFileName)
|
||||
, _unresolvedFileName(unresolvedFileName)
|
||||
, _line(line)
|
||||
, _type(type)
|
||||
{ }
|
||||
|
||||
QString fileName() const
|
||||
{ return _fileName; }
|
||||
QString resolvedFileName() const
|
||||
{ return _resolvedFileName; }
|
||||
|
||||
QString unresolvedFileName() const
|
||||
{ return _unresolvedFileName; }
|
||||
|
||||
unsigned line() const
|
||||
{ return _line; }
|
||||
|
||||
bool resolved() const
|
||||
{ return QFileInfo(_fileName).isAbsolute(); }
|
||||
Client::IncludeType type() const
|
||||
{ return _type; }
|
||||
};
|
||||
|
||||
class MacroUse: public Block {
|
||||
@@ -302,6 +309,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
QStringList includedFiles() const;
|
||||
void addIncludeFile(const Include &include);
|
||||
|
||||
QList<Include> includes() const
|
||||
{ return _includes; }
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc, const QString &source)
|
||||
|
||||
mergeEnvironment(Preprocessor::configurationFileName);
|
||||
foreach (const Document::Include &i, doc->includes())
|
||||
mergeEnvironment(i.fileName());
|
||||
mergeEnvironment(i.resolvedFileName());
|
||||
}
|
||||
|
||||
const QByteArray preprocessed = _preproc.run(fileName, source);
|
||||
@@ -62,13 +62,13 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc, const QString &source)
|
||||
return preprocessed;
|
||||
}
|
||||
|
||||
void FastPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType)
|
||||
void FastPreprocessor::sourceNeeded(unsigned line, const QString &fileName,
|
||||
IncludeType mode)
|
||||
{
|
||||
Q_ASSERT(_currentDoc);
|
||||
// CHECKME: Is that cleanName needed?
|
||||
QString cleanName = QDir::cleanPath(fileName);
|
||||
_currentDoc->addIncludeFile(cleanName, line);
|
||||
|
||||
_currentDoc->addIncludeFile(Document::Include(fileName, cleanName, line, mode));
|
||||
mergeEnvironment(fileName);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ void FastPreprocessor::mergeEnvironment(const QString &fileName)
|
||||
|
||||
if (Document::Ptr doc = _snapshot.document(fileName)) {
|
||||
foreach (const Document::Include &i, doc->includes())
|
||||
mergeEnvironment(i.fileName());
|
||||
mergeEnvironment(i.resolvedFileName());
|
||||
|
||||
_env.addMacros(doc->definedMacros());
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
QByteArray run(Document::Ptr newDoc, const QString &source);
|
||||
|
||||
// CPlusPlus::Client
|
||||
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType);
|
||||
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType mode);
|
||||
|
||||
virtual void macroAdded(const Macro &);
|
||||
|
||||
|
||||
@@ -305,7 +305,8 @@ ClassOrNamespace *LookupContext::globalNamespace() const
|
||||
}
|
||||
|
||||
ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope,
|
||||
ClassOrNamespace* enclosingTemplateInstantiation) const
|
||||
ClassOrNamespace* enclosingTemplateInstantiation,
|
||||
QSet<const Declaration *> typedefsBeingResolved) const
|
||||
{
|
||||
if (! scope) {
|
||||
return 0;
|
||||
@@ -324,8 +325,14 @@ ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope,
|
||||
Overview oo;
|
||||
qDebug() << "Looks like" << oo(name) << "is a typedef for" << oo(d->type());
|
||||
#endif // DEBUG_LOOKUP
|
||||
if (const NamedType *namedTy = d->type()->asNamedType())
|
||||
return lookupType(namedTy->name(), scope);
|
||||
if (const NamedType *namedTy = d->type()->asNamedType()) {
|
||||
// Stop on recursive typedef declarations
|
||||
if (typedefsBeingResolved.contains(d))
|
||||
return 0;
|
||||
return lookupType(namedTy->name(), scope, 0,
|
||||
QSet<const Declaration *>(typedefsBeingResolved)
|
||||
<< d);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (UsingDeclaration *ud = m->asUsingDeclaration()) {
|
||||
@@ -1364,7 +1371,7 @@ void CreateBindings::process(Document::Ptr doc)
|
||||
_processed.insert(globalNamespace);
|
||||
|
||||
foreach (const Document::Include &i, doc->includes()) {
|
||||
if (Document::Ptr incl = _snapshot.document(i.fileName()))
|
||||
if (Document::Ptr incl = _snapshot.document(i.resolvedFileName()))
|
||||
process(incl);
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +289,9 @@ public:
|
||||
|
||||
QList<LookupItem> lookup(const Name *name, Scope *scope) const;
|
||||
ClassOrNamespace *lookupType(const Name *name, Scope *scope,
|
||||
ClassOrNamespace* enclosingTemplateInstantiation = 0) const;
|
||||
ClassOrNamespace* enclosingTemplateInstantiation = 0,
|
||||
QSet<const Declaration *> typedefsBeingResolved
|
||||
= QSet<const Declaration *>()) const;
|
||||
ClassOrNamespace *lookupType(Symbol *symbol,
|
||||
ClassOrNamespace* enclosingTemplateInstantiation = 0) const;
|
||||
ClassOrNamespace *lookupParent(Symbol *symbol) const;
|
||||
|
||||
@@ -77,11 +77,13 @@ static QList<_Tp> removeDuplicates(const QList<_Tp> &results)
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// ResolveExpression
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
ResolveExpression::ResolveExpression(const LookupContext &context)
|
||||
ResolveExpression::ResolveExpression(const LookupContext &context,
|
||||
const QSet<const Declaration *> &autoDeclarationsBeingResolved)
|
||||
: ASTVisitor(context.expressionDocument()->translationUnit()),
|
||||
_scope(0),
|
||||
_context(context),
|
||||
bind(context.expressionDocument()->translationUnit()),
|
||||
_autoDeclarationsBeingResolved(autoDeclarationsBeingResolved),
|
||||
_reference(false)
|
||||
{ }
|
||||
|
||||
@@ -521,6 +523,10 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
|
||||
if (!decl)
|
||||
continue;
|
||||
|
||||
// Stop on recursive auto declarations
|
||||
if (_autoDeclarationsBeingResolved.contains(decl))
|
||||
continue;
|
||||
|
||||
const StringLiteral *initializationString = decl->getInitializer();
|
||||
if (initializationString == 0)
|
||||
continue;
|
||||
@@ -535,7 +541,8 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
|
||||
|
||||
TypeOfExpression exprTyper;
|
||||
Document::Ptr doc = _context.snapshot().document(QString::fromLocal8Bit(decl->fileName()));
|
||||
exprTyper.init(doc, _context.snapshot(), _context.bindings());
|
||||
exprTyper.init(doc, _context.snapshot(), _context.bindings(),
|
||||
QSet<const Declaration* >(_autoDeclarationsBeingResolved) << decl);
|
||||
|
||||
Document::Ptr exprDoc =
|
||||
documentForExpression(exprTyper.preprocessedExpression(initializer));
|
||||
@@ -545,8 +552,8 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
|
||||
if (deduceAuto._block)
|
||||
continue;
|
||||
|
||||
const QList<LookupItem> &typeItems =
|
||||
exprTyper(extractExpressionAST(exprDoc), exprDoc, decl->enclosingScope());
|
||||
const QList<LookupItem> &typeItems = exprTyper(extractExpressionAST(exprDoc), exprDoc,
|
||||
decl->enclosingScope());
|
||||
if (typeItems.empty())
|
||||
continue;
|
||||
|
||||
|
||||
@@ -43,7 +43,9 @@ namespace CPlusPlus {
|
||||
class CPLUSPLUS_EXPORT ResolveExpression: protected ASTVisitor
|
||||
{
|
||||
public:
|
||||
ResolveExpression(const LookupContext &context);
|
||||
ResolveExpression(const LookupContext &context,
|
||||
const QSet<const Declaration *> &autoDeclarationsBeingResolved
|
||||
= QSet<const Declaration *>());
|
||||
virtual ~ResolveExpression();
|
||||
|
||||
QList<LookupItem> operator()(ExpressionAST *ast, Scope *scope);
|
||||
@@ -126,6 +128,7 @@ private:
|
||||
const LookupContext& _context;
|
||||
Bind bind;
|
||||
QList<LookupItem> _results;
|
||||
QSet<const Declaration *> _autoDeclarationsBeingResolved;
|
||||
bool _reference;
|
||||
};
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ void SnapshotSymbolVisitor::accept(Document::Ptr doc, QSet<QString> *processed)
|
||||
processed->insert(doc->fileName());
|
||||
|
||||
foreach (const Document::Include &i, doc->includes()) {
|
||||
if (Document::Ptr incl = _snapshot.document(i.fileName()))
|
||||
if (Document::Ptr incl = _snapshot.document(i.resolvedFileName()))
|
||||
accept(incl, processed);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,8 @@ void TypeOfExpression::reset()
|
||||
}
|
||||
|
||||
void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot,
|
||||
QSharedPointer<CreateBindings> bindings)
|
||||
QSharedPointer<CreateBindings> bindings,
|
||||
const QSet<const Declaration *> &autoDeclarationsBeingResolved)
|
||||
{
|
||||
m_thisDocument = thisDocument;
|
||||
m_snapshot = snapshot;
|
||||
@@ -69,6 +70,7 @@ void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot
|
||||
m_lookupContext = LookupContext();
|
||||
m_bindings = bindings;
|
||||
m_environment.clear();
|
||||
m_autoDeclarationsBeingResolved = autoDeclarationsBeingResolved;
|
||||
}
|
||||
|
||||
QList<LookupItem> TypeOfExpression::operator()(const QByteArray &utf8code,
|
||||
@@ -113,7 +115,7 @@ QList<LookupItem> TypeOfExpression::operator()(ExpressionAST *expression,
|
||||
m_lookupContext.setBindings(m_bindings);
|
||||
m_lookupContext.setExpandTemplates(m_expandTemplates);
|
||||
|
||||
ResolveExpression resolve(m_lookupContext);
|
||||
ResolveExpression resolve(m_lookupContext, m_autoDeclarationsBeingResolved);
|
||||
const QList<LookupItem> items = resolve(m_ast, scope);
|
||||
|
||||
if (! m_bindings)
|
||||
@@ -135,7 +137,7 @@ QList<LookupItem> TypeOfExpression::reference(ExpressionAST *expression,
|
||||
m_lookupContext.setBindings(m_bindings);
|
||||
m_lookupContext.setExpandTemplates(m_expandTemplates);
|
||||
|
||||
ResolveExpression resolve(m_lookupContext);
|
||||
ResolveExpression resolve(m_lookupContext, m_autoDeclarationsBeingResolved);
|
||||
const QList<LookupItem> items = resolve.reference(m_ast, scope);
|
||||
|
||||
if (! m_bindings)
|
||||
@@ -176,7 +178,7 @@ void TypeOfExpression::processEnvironment(Document::Ptr doc, Environment *env,
|
||||
processed->insert(doc->fileName());
|
||||
|
||||
foreach (const Document::Include &incl, doc->includes())
|
||||
processEnvironment(m_snapshot.document(incl.fileName()), env, processed);
|
||||
processEnvironment(m_snapshot.document(incl.resolvedFileName()), env, processed);
|
||||
|
||||
foreach (const Macro ¯o, doc->definedMacros())
|
||||
env->bind(macro);
|
||||
|
||||
@@ -59,8 +59,11 @@ public:
|
||||
* Also clears the lookup context, so can be used to make sure references
|
||||
* to the documents previously used are removed.
|
||||
*/
|
||||
void init(Document::Ptr thisDocument, const Snapshot &snapshot,
|
||||
QSharedPointer<CreateBindings> bindings = QSharedPointer<CreateBindings>());
|
||||
void init(Document::Ptr thisDocument,
|
||||
const Snapshot &snapshot,
|
||||
QSharedPointer<CreateBindings> bindings = QSharedPointer<CreateBindings>(),
|
||||
const QSet<const Declaration *> &autoDeclarationsBeingResolved
|
||||
= QSet<const Declaration *>());
|
||||
|
||||
void reset();
|
||||
|
||||
@@ -152,6 +155,8 @@ private:
|
||||
// Keep the expression documents and thus all the symbols and
|
||||
// their types alive until they are not needed any more.
|
||||
QList<Document::Ptr> m_documents;
|
||||
|
||||
QSet<const Declaration *> m_autoDeclarationsBeingResolved;
|
||||
};
|
||||
|
||||
ExpressionAST CPLUSPLUS_EXPORT *extractExpressionAST(Document::Ptr doc);
|
||||
|
||||
@@ -14,6 +14,7 @@ QtcLibrary {
|
||||
Depends { name: "Qt.widgets" }
|
||||
|
||||
Group {
|
||||
name: "ThirdPartyCPlusPlus"
|
||||
prefix: "../3rdparty/cplusplus/"
|
||||
files: [
|
||||
"AST.cpp",
|
||||
|
||||
@@ -1048,7 +1048,7 @@ bool Preprocessor::handleIdentifier(PPToken *tk)
|
||||
argRefs);
|
||||
}
|
||||
|
||||
if (!handleFunctionLikeMacro(tk, macro, body, allArgTks, baseLine)) {
|
||||
if (!handleFunctionLikeMacro(macro, body, allArgTks, baseLine)) {
|
||||
if (m_client && !idTk.expanded())
|
||||
m_client->stopExpandingMacro(idTk.offset, *macro);
|
||||
return false;
|
||||
@@ -1119,8 +1119,7 @@ bool Preprocessor::handleIdentifier(PPToken *tk)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Preprocessor::handleFunctionLikeMacro(PPToken *tk,
|
||||
const Macro *macro,
|
||||
bool Preprocessor::handleFunctionLikeMacro(const Macro *macro,
|
||||
QVector<PPToken> &body,
|
||||
const QVector<QVector<PPToken> > &actuals,
|
||||
unsigned baseLine)
|
||||
@@ -1220,9 +1219,6 @@ bool Preprocessor::handleFunctionLikeMacro(PPToken *tk,
|
||||
body = expanded;
|
||||
body.squeeze();
|
||||
|
||||
// Next token to be lexed after the expansion.
|
||||
pushToken(tk);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1479,9 +1475,9 @@ bool Preprocessor::collectActualArguments(PPToken *tk, QVector<QVector<PPToken>
|
||||
actuals->append(tokens);
|
||||
}
|
||||
|
||||
if (tk->is(T_RPAREN))
|
||||
lex(tk);
|
||||
//###TODO: else error message
|
||||
if (!tk->is(T_RPAREN)) {
|
||||
//###TODO: else error message
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -205,8 +205,7 @@ private:
|
||||
void lex(PPToken *tk);
|
||||
void skipPreprocesorDirective(PPToken *tk);
|
||||
bool handleIdentifier(PPToken *tk);
|
||||
bool handleFunctionLikeMacro(PPToken *tk,
|
||||
const Macro *macro,
|
||||
bool handleFunctionLikeMacro(const Macro *macro,
|
||||
QVector<PPToken> &body,
|
||||
const QVector<QVector<PPToken> > &actuals,
|
||||
unsigned lineRef);
|
||||
|
||||
Reference in New Issue
Block a user