Commit 20046e3a authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Debugger[CDB]: Fixes for namespaced Qt.

Fix broken substringpredicate (temporary string reference),
fix Qt container template detection not to fall for
QMap<>::iterator (real inner class).
parent 3a87fdd5
......@@ -65,11 +65,11 @@ void split(const std::string &s, char sep, Iterator it)
class SubStringPredicate : public std::unary_function<const std::string &, bool>
{
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<Iterator>(list.begin(), list.end()) << "..."
template <class Iterator>
struct DebugSequence : public std::pair<Iterator, Iterator>
{
DebugSequence(const Iterator &i1, const Iterator &i2) : std::pair<Iterator, Iterator>(i1, i2) {}
};
template <class Iterator>
std::ostream &operator<<(std::ostream &os, const DebugSequence<Iterator> &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; }
......
......@@ -402,24 +402,38 @@ static inline std::string resolveQtSymbol(const char *symbolC,
const char *modulePatternC,
const SymbolGroupValueContext &ctx)
{
enum { debugResolveQtSymbol = 0 };
typedef std::list<std::string> 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<StringListConstIt>(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() << "<resolveQtSymbol return1 " << *defaultIt;
return *defaultIt;
}
// Fail, now try a search with '*qstrdup' in all modules. This might return several matches
// like 'QtCored4!qstrdup', 'QGuid4!qstrdup'
const std::string wildCardPattern = std::string(1, '*') + symbolC;
const StringList allMatches = SymbolGroupValue::resolveSymbolName(wildCardPattern.c_str(), ctx);
if (debugResolveQtSymbol)
DebugPrint() << "resolveQtSymbol: allMatches= (" << wildCardPattern << ") -> " << DebugSequence<StringListConstIt>(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() << "<resolveQtSymbol return2 " << rc;
return rc;
}
const QtInfo &QtInfo::get(const SymbolGroupValueContext &ctx)
......@@ -844,6 +858,9 @@ static KnownType knownClassTypeHelper(const std::string &type,
return KT_Unknown;
// Qt types (templates)
if (templatePos != std::string::npos) {
// Do not fall for QMap<K,T>::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"))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment