forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/2.7'
Conflicts: src/plugins/qnx/blackberrydeployconfiguration.cpp Change-Id: I16d1c7717f4bc25ba7e8dbdd5be6580fafe3f33d
This commit is contained in:
@@ -651,11 +651,6 @@ bool Snapshot::isEmpty() const
|
||||
return _documents.isEmpty();
|
||||
}
|
||||
|
||||
Document::Ptr Snapshot::operator[](const QString &fileName) const
|
||||
{
|
||||
return _documents.value(fileName, Document::Ptr());
|
||||
}
|
||||
|
||||
Snapshot::const_iterator Snapshot::find(const QString &fileName) const
|
||||
{
|
||||
return _documents.find(fileName);
|
||||
|
||||
@@ -146,8 +146,8 @@ public:
|
||||
const QString &text,
|
||||
unsigned length = 0)
|
||||
: _level(level),
|
||||
_fileName(fileName),
|
||||
_line(line),
|
||||
_fileName(fileName),
|
||||
_column(column),
|
||||
_length(length),
|
||||
_text(text)
|
||||
@@ -185,8 +185,8 @@ public:
|
||||
|
||||
private:
|
||||
int _level;
|
||||
QString _fileName;
|
||||
unsigned _line;
|
||||
QString _fileName;
|
||||
unsigned _column;
|
||||
unsigned _length;
|
||||
QString _text;
|
||||
@@ -377,7 +377,6 @@ public:
|
||||
|
||||
bool contains(const QString &fileName) const;
|
||||
Document::Ptr document(const QString &fileName) const;
|
||||
Document::Ptr operator[](const QString &fileName) const;
|
||||
|
||||
const_iterator find(const QString &fileName) const;
|
||||
|
||||
|
||||
@@ -41,37 +41,6 @@
|
||||
|
||||
using namespace CPlusPlus;
|
||||
|
||||
namespace {
|
||||
|
||||
QString fetchLine(const QByteArray &bytes, const int line)
|
||||
{
|
||||
int current = 0;
|
||||
const char *s = bytes.constData();
|
||||
|
||||
if (line) {
|
||||
while (*s) {
|
||||
if (*s == '\n') {
|
||||
++current;
|
||||
if (line == current) {
|
||||
++s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
if (current == line) {
|
||||
const char *e = s;
|
||||
while (*e && *e != '\n')
|
||||
++e;
|
||||
return QString::fromUtf8(s, e - s);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
} // Anonymous
|
||||
|
||||
FindUsages::FindUsages(const QByteArray &originalSource, Document::Ptr doc, const Snapshot &snapshot)
|
||||
: ASTVisitor(doc->translationUnit()),
|
||||
_id(0),
|
||||
@@ -85,6 +54,8 @@ FindUsages::FindUsages(const QByteArray &originalSource, Document::Ptr doc, cons
|
||||
{
|
||||
_snapshot.insert(_doc);
|
||||
typeofExpression.init(_doc, _snapshot, _context.bindings());
|
||||
|
||||
prepareLines(_originalSource);
|
||||
}
|
||||
|
||||
FindUsages::FindUsages(const LookupContext &context)
|
||||
@@ -99,6 +70,8 @@ FindUsages::FindUsages(const LookupContext &context)
|
||||
_currentScope(0)
|
||||
{
|
||||
typeofExpression.init(_doc, _snapshot, _context.bindings());
|
||||
|
||||
prepareLines(_originalSource);
|
||||
}
|
||||
|
||||
QList<Usage> FindUsages::usages() const
|
||||
@@ -178,8 +151,7 @@ QString FindUsages::matchingLine(const Token &tk) const
|
||||
break;
|
||||
}
|
||||
|
||||
const QString matchingLine = QString::fromUtf8(cp, lineEnd - cp);
|
||||
return matchingLine;
|
||||
return QString::fromUtf8(cp, lineEnd - cp);
|
||||
}
|
||||
|
||||
void FindUsages::reportResult(unsigned tokenIndex)
|
||||
@@ -195,9 +167,8 @@ void FindUsages::reportResult(unsigned tokenIndex)
|
||||
unsigned line, col;
|
||||
getTokenStartPosition(tokenIndex, &line, &col);
|
||||
QString lineText;
|
||||
const int lines = _originalSource.count('\n') + 1;
|
||||
if (((int) line - 1) < lines)
|
||||
lineText = fetchLine(_originalSource, line - 1);
|
||||
if (line < _sourceLineEnds.size())
|
||||
lineText = fetchLine(line);
|
||||
else
|
||||
lineText = matchingLine(tk);
|
||||
|
||||
@@ -2167,3 +2138,28 @@ bool FindUsages::visit(ArrayDeclaratorAST *ast)
|
||||
// unsigned rbracket_token = ast->rbracket_token;
|
||||
return false;
|
||||
}
|
||||
|
||||
void FindUsages::prepareLines(const QByteArray &bytes)
|
||||
{
|
||||
_sourceLineEnds.reserve(1000);
|
||||
const char *s = bytes.constData();
|
||||
_sourceLineEnds.push_back(s - 1); // we start counting at line 1, so line 0 is always empty.
|
||||
|
||||
for (; *s; ++s)
|
||||
if (*s == '\n')
|
||||
_sourceLineEnds.push_back(s);
|
||||
if (s != _sourceLineEnds.back() + 1) // no newline at the end of the file
|
||||
_sourceLineEnds.push_back(s);
|
||||
}
|
||||
|
||||
QString FindUsages::fetchLine(unsigned lineNr) const
|
||||
{
|
||||
Q_ASSERT(lineNr < _sourceLineEnds.size());
|
||||
if (lineNr == 0)
|
||||
return QString();
|
||||
|
||||
const char *start = _sourceLineEnds.at(lineNr - 1) + 1;
|
||||
const char *end = _sourceLineEnds.at(lineNr);
|
||||
return QString::fromUtf8(start, end - start);
|
||||
}
|
||||
|
||||
|
||||
@@ -283,6 +283,10 @@ protected:
|
||||
virtual bool visit(FunctionDeclaratorAST *ast);
|
||||
virtual bool visit(ArrayDeclaratorAST *ast);
|
||||
|
||||
private:
|
||||
void prepareLines(const QByteArray &bytes);
|
||||
QString fetchLine(unsigned lineNr) const;
|
||||
|
||||
private:
|
||||
const Identifier *_id;
|
||||
Symbol *_declSymbol;
|
||||
@@ -290,7 +294,8 @@ private:
|
||||
Document::Ptr _doc;
|
||||
Snapshot _snapshot;
|
||||
LookupContext _context;
|
||||
QByteArray _originalSource;
|
||||
const QByteArray _originalSource;
|
||||
std::vector<const char *> _sourceLineEnds;
|
||||
QByteArray _source;
|
||||
QList<int> _references;
|
||||
QList<Usage> _usages;
|
||||
|
||||
@@ -703,6 +703,40 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ClassOrNamespace *ClassOrNamespace::findSpecializationWithPointer(const TemplateNameId *templId,
|
||||
const TemplateNameIdTable &specializations)
|
||||
{
|
||||
// we go through all specialization and try to find that one with template argument as pointer
|
||||
for (TemplateNameIdTable::const_iterator cit = specializations.begin();
|
||||
cit != specializations.end(); ++cit) {
|
||||
const TemplateNameId *specializationNameId = cit->first;
|
||||
const unsigned specializationTemplateArgumentCount
|
||||
= specializationNameId->templateArgumentCount();
|
||||
const unsigned initializationTemplateArgumentCount
|
||||
= templId->templateArgumentCount();
|
||||
// for now it works only when we have the same number of arguments in specialization
|
||||
// and initialization(in future it should be more clever)
|
||||
if (specializationTemplateArgumentCount == initializationTemplateArgumentCount) {
|
||||
for (unsigned i = 0; i < initializationTemplateArgumentCount; ++i) {
|
||||
const FullySpecifiedType &specializationTemplateArgument
|
||||
= specializationNameId->templateArgumentAt(i);
|
||||
const FullySpecifiedType &initializationTemplateArgument
|
||||
= templId->templateArgumentAt(i);
|
||||
PointerType *specPointer
|
||||
= specializationTemplateArgument.type()->asPointerType();
|
||||
// specialization and initialization argument have to be a pointer
|
||||
// additionally type of pointer argument of specialization has to be namedType
|
||||
if (specPointer && initializationTemplateArgument.type()->isPointerType()
|
||||
&& specPointer->elementType().type()->isNamedType()) {
|
||||
return cit->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespace *origin)
|
||||
{
|
||||
Q_ASSERT(name != 0);
|
||||
@@ -715,16 +749,24 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
|
||||
return 0;
|
||||
|
||||
ClassOrNamespace *reference = it->second;
|
||||
ClassOrNamespace *baseTemplateClassReference = reference;
|
||||
|
||||
const TemplateNameId *templId = name->asTemplateNameId();
|
||||
if (templId) {
|
||||
// for "using" we should use the real one ClassOrNamespace(it should be the first
|
||||
// one item from usings list)
|
||||
// we indicate that it is a 'using' by checking number of symbols(it should be 0)
|
||||
if (reference->symbols().count() == 0 && reference->usings().count() != 0)
|
||||
reference = reference->_usings[0];
|
||||
|
||||
// if it is a TemplateNameId it could be a specialization(full or partial) or
|
||||
// instantiation of one of the specialization(reference->_specialization) or
|
||||
// base class(reference)
|
||||
if (templId->isSpecialization()) {
|
||||
// if it is a specialization we try to find or create new one and
|
||||
// add to base class(reference)
|
||||
TemplateNameIdTable::const_iterator cit = reference->_specializations.find(templId);
|
||||
TemplateNameIdTable::const_iterator cit
|
||||
= reference->_specializations.find(templId);
|
||||
if (cit != reference->_specializations.end()) {
|
||||
return cit->second;
|
||||
} else {
|
||||
@@ -736,15 +778,24 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
|
||||
return newSpecialization;
|
||||
}
|
||||
} else {
|
||||
QMap<const TemplateNameId *, ClassOrNamespace *>::const_iterator citInstantiation
|
||||
= reference->_instantiations.find(templId);
|
||||
if (citInstantiation != reference->_instantiations.end())
|
||||
return citInstantiation.value();
|
||||
TemplateNameId *nonConstTemplId = const_cast<TemplateNameId *>(templId);
|
||||
// make this instantiation looks like specialization which help to find
|
||||
// full specialization for this instantiation
|
||||
nonConstTemplId->setIsSpecialization(true);
|
||||
TemplateNameIdTable::const_iterator cit = reference->_specializations.find(templId);
|
||||
if (cit != reference->_specializations.end()) {
|
||||
const TemplateNameIdTable &specializations = reference->_specializations;
|
||||
TemplateNameIdTable::const_iterator cit = specializations.find(templId);
|
||||
if (cit != specializations.end()) {
|
||||
// we found full specialization
|
||||
reference = cit->second;
|
||||
} else {
|
||||
ClassOrNamespace *specializationWithPointer
|
||||
= findSpecializationWithPointer(templId, specializations);
|
||||
if (specializationWithPointer)
|
||||
reference = specializationWithPointer;
|
||||
// TODO: find the best specialization(probably partial) for this instantiation
|
||||
}
|
||||
// let's instantiation be instantiation
|
||||
@@ -788,7 +839,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
|
||||
// construct all instantiation data.
|
||||
if (templId) {
|
||||
_alreadyConsideredTemplates.insert(templId);
|
||||
ClassOrNamespace *instantiation = _factory->allocClassOrNamespace(reference);
|
||||
ClassOrNamespace *instantiation = _factory->allocClassOrNamespace(baseTemplateClassReference);
|
||||
#ifdef DEBUG_LOOKUP
|
||||
instantiation->_name = templId;
|
||||
#endif // DEBUG_LOOKUP
|
||||
@@ -833,6 +884,17 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
|
||||
oo.showReturnTypes = true;
|
||||
oo.showTemplateParameters = true;
|
||||
qDebug()<<"cloned"<<oo(clone->type());
|
||||
if (Class *klass = s->asClass()) {
|
||||
const unsigned klassMemberCount = klass->memberCount();
|
||||
for (unsigned i = 0; i < klassMemberCount; ++i){
|
||||
Symbol *klassMemberAsSymbol = klass->memberAt(i);
|
||||
if (klassMemberAsSymbol->isTypedef()) {
|
||||
if (Declaration *declaration = klassMemberAsSymbol->asDeclaration()) {
|
||||
qDebug() << "Member: " << oo(declaration->type(), declaration->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOOKUP
|
||||
}
|
||||
instantiateNestedClasses(reference, cloner, subst, instantiation);
|
||||
@@ -904,6 +966,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
|
||||
}
|
||||
|
||||
_alreadyConsideredTemplates.clear(templId);
|
||||
baseTemplateClassReference->_instantiations[templId] = instantiation;
|
||||
return instantiation;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@ public:
|
||||
ClassOrNamespace *findType(const Name *name);
|
||||
|
||||
private:
|
||||
typedef std::map<const Name *, ClassOrNamespace *, Name::Compare> Table;
|
||||
typedef std::map<const TemplateNameId *, ClassOrNamespace *, TemplateNameId::Compare> TemplateNameIdTable;
|
||||
|
||||
/// \internal
|
||||
void flush();
|
||||
|
||||
@@ -98,10 +101,8 @@ private:
|
||||
Subst &subst,
|
||||
ClassOrNamespace *enclosingTemplateClassInstantiation);
|
||||
bool isInstantiateNestedClassNeeded(const QList<Symbol *>& symbols, const Subst &subst) const;
|
||||
|
||||
private:
|
||||
typedef std::map<const Name *, ClassOrNamespace *, Name::Compare> Table;
|
||||
typedef std::map<const TemplateNameId *, ClassOrNamespace *, TemplateNameId::Compare> TemplateNameIdTable;
|
||||
ClassOrNamespace *findSpecializationWithPointer(const TemplateNameId *templId,
|
||||
const TemplateNameIdTable &specializations);
|
||||
|
||||
CreateBindings *_factory;
|
||||
ClassOrNamespace *_parent;
|
||||
@@ -112,6 +113,7 @@ private:
|
||||
QList<Symbol *> _todo;
|
||||
QSharedPointer<Control> _control;
|
||||
TemplateNameIdTable _specializations;
|
||||
QMap<const TemplateNameId *, ClassOrNamespace *> _instantiations;
|
||||
|
||||
// it's an instantiation.
|
||||
const TemplateNameId *_templateId;
|
||||
|
||||
@@ -143,9 +143,7 @@ public:
|
||||
private:
|
||||
friend class Environment;
|
||||
Macro *_next;
|
||||
unsigned _hashcode;
|
||||
|
||||
private:
|
||||
QString decoratedName() const;
|
||||
|
||||
struct Flags
|
||||
@@ -160,6 +158,7 @@ private:
|
||||
QVector<PPToken> _definitionTokens;
|
||||
QVector<QByteArray> _formals;
|
||||
QString _fileName;
|
||||
unsigned _hashcode;
|
||||
unsigned _fileRevision;
|
||||
unsigned _line;
|
||||
unsigned _offset;
|
||||
|
||||
@@ -835,8 +835,9 @@ public:
|
||||
void resolve(FullySpecifiedType *type, Scope **scope, ClassOrNamespace *binding)
|
||||
{
|
||||
QSet<Symbol *> visited;
|
||||
_binding = binding;
|
||||
while (NamedType *namedTy = getNamedType(*type)) {
|
||||
QList<LookupItem> namedTypeItems = getNamedTypeItems(namedTy->name(), *scope, binding);
|
||||
QList<LookupItem> namedTypeItems = getNamedTypeItems(namedTy->name(), *scope, _binding);
|
||||
|
||||
#ifdef DEBUG_LOOKUP
|
||||
qDebug() << "-- we have" << namedTypeItems.size() << "candidates";
|
||||
@@ -908,7 +909,7 @@ private:
|
||||
}
|
||||
|
||||
bool findTypedef(const QList<LookupItem>& namedTypeItems, FullySpecifiedType *type,
|
||||
Scope **scope, QSet<Symbol *>& visited) const
|
||||
Scope **scope, QSet<Symbol *>& visited)
|
||||
{
|
||||
bool foundTypedef = false;
|
||||
foreach (const LookupItem &it, namedTypeItems) {
|
||||
@@ -921,6 +922,7 @@ private:
|
||||
// continue working with the typedefed type and scope
|
||||
*type = declaration->type();
|
||||
*scope = it.scope();
|
||||
_binding = it.binding();
|
||||
foundTypedef = true;
|
||||
break;
|
||||
}
|
||||
@@ -930,6 +932,8 @@ private:
|
||||
}
|
||||
|
||||
const LookupContext &_context;
|
||||
// binding has to be remembered in case of resolving typedefs for templates
|
||||
ClassOrNamespace *_binding;
|
||||
};
|
||||
|
||||
ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &baseResults,
|
||||
|
||||
@@ -547,14 +547,14 @@ Preprocessor::State::State()
|
||||
, m_skipping(MAX_LEVEL)
|
||||
, m_trueTest(MAX_LEVEL)
|
||||
, m_ifLevel(0)
|
||||
, m_tokenBuffer(0)
|
||||
, m_tokenBufferDepth(0)
|
||||
, m_tokenBuffer(0)
|
||||
, m_inPreprocessorDirective(false)
|
||||
, m_result(0)
|
||||
, m_markExpandedTokens(true)
|
||||
, m_noLines(false)
|
||||
, m_inCondition(false)
|
||||
, m_offsetRef(0)
|
||||
, m_result(0)
|
||||
, m_lineRef(1)
|
||||
, m_expansionStatus(NotExpanding)
|
||||
, m_includeGuardState(IncludeGuardState_BeforeIfndef)
|
||||
|
||||
@@ -118,17 +118,17 @@ private:
|
||||
QBitArray m_skipping;
|
||||
QBitArray m_trueTest;
|
||||
int m_ifLevel;
|
||||
Internal::TokenBuffer *m_tokenBuffer;
|
||||
unsigned m_tokenBufferDepth;
|
||||
Internal::TokenBuffer *m_tokenBuffer;
|
||||
bool m_inPreprocessorDirective;
|
||||
|
||||
QByteArray *m_result;
|
||||
bool m_markExpandedTokens;
|
||||
|
||||
bool m_noLines;
|
||||
bool m_inCondition;
|
||||
|
||||
unsigned m_offsetRef;
|
||||
QByteArray *m_result;
|
||||
unsigned m_lineRef;
|
||||
|
||||
ExpansionStatus m_expansionStatus;
|
||||
|
||||
Reference in New Issue
Block a user