diff --git a/src/libs/qtcreatorcdbext/stringutils.h b/src/libs/qtcreatorcdbext/stringutils.h index d82f99e7172..140c7676946 100644 --- a/src/libs/qtcreatorcdbext/stringutils.h +++ b/src/libs/qtcreatorcdbext/stringutils.h @@ -65,11 +65,11 @@ void split(const std::string &s, char sep, Iterator it) class SubStringPredicate : public std::unary_function { public: - explicit SubStringPredicate(const std::string &needle) : m_needle(needle) {} + explicit SubStringPredicate(const char *needle) : m_needle(needle) {} bool operator()(const std::string &s) { return s.find(m_needle) != std::string::npos; } private: - const std::string &m_needle; + const char *m_needle; }; // Format numbers, etc, as a string. @@ -90,6 +90,25 @@ std::wstring toWString(const Streamable s) return str.str(); } +// Helper for outputting a sequence/container to a ostream as a comma-separated, quoted list +// to be used as "os << DebugSequence(list.begin(), list.end()) << "..." +template +struct DebugSequence : public std::pair +{ + DebugSequence(const Iterator &i1, const Iterator &i2) : std::pair(i1, i2) {} +}; + +template +std::ostream &operator<<(std::ostream &os, const DebugSequence &s) +{ + for (Iterator it = s.first; it != s.second; ++it) { + if (it != s.first) + os << ','; + os << '\'' << *it << '\''; + } + return os; +} + bool endsWith(const std::string &haystack, const char *needle); inline bool endsWith(const std::string &haystack, char needle) { return !haystack.empty() && haystack.at(haystack.size() - 1) == needle; } diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp index 19c5b40e663..3654e42a43c 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp @@ -402,24 +402,38 @@ static inline std::string resolveQtSymbol(const char *symbolC, const char *modulePatternC, const SymbolGroupValueContext &ctx) { + enum { debugResolveQtSymbol = 0 }; typedef std::list StringList; typedef StringList::const_iterator StringListConstIt; + if (debugResolveQtSymbol) + DebugPrint() << ">resolveQtSymbol" << symbolC << " def=" << defaultModuleNameC << " defModName=" + << defaultModuleNameC << " modPattern=" << modulePatternC; // First try a match with the default module name 'QtCored4!qstrdup' for speed reasons std::string defaultPattern = defaultModuleNameC; defaultPattern.push_back('!'); defaultPattern += symbolC; const StringList defaultMatches = SymbolGroupValue::resolveSymbolName(defaultPattern.c_str(), ctx); + if (debugResolveQtSymbol) + DebugPrint() << "resolveQtSymbol: defaultMatches=" << DebugSequence(defaultMatches.begin(), defaultMatches.end()); const SubStringPredicate modulePattern(modulePatternC); const StringListConstIt defaultIt = std::find_if(defaultMatches.begin(), defaultMatches.end(), modulePattern); - if (defaultIt != defaultMatches.end()) + if (defaultIt != defaultMatches.end()) { + if (debugResolveQtSymbol) + DebugPrint() << " " << DebugSequence(allMatches.begin(), allMatches.end()); const StringListConstIt allIt = std::find_if(allMatches.begin(), allMatches.end(), modulePattern); - return allIt != allMatches.end() ? *allIt : std::string(); + const std::string rc = allIt != allMatches.end() ? *allIt : std::string(); + if (debugResolveQtSymbol) + DebugPrint() << "::iterator, which is actually an inner class. + if (endPos > templatePos && type.at(endPos - 1) != '>') + return KT_Unknown; switch (templatePos - qPos) { case 4: if (!type.compare(qPos, 4, "QSet"))