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).
This commit is contained in:
Friedemann Kleint
2011-01-19 11:40:50 +01:00
parent 3a87fdd5f1
commit 20046e3ab3
2 changed files with 40 additions and 4 deletions

View File

@@ -65,11 +65,11 @@ void split(const std::string &s, char sep, Iterator it)
class SubStringPredicate : public std::unary_function<const std::string &, bool> class SubStringPredicate : public std::unary_function<const std::string &, bool>
{ {
public: 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; } bool operator()(const std::string &s) { return s.find(m_needle) != std::string::npos; }
private: private:
const std::string &m_needle; const char *m_needle;
}; };
// Format numbers, etc, as a string. // Format numbers, etc, as a string.
@@ -90,6 +90,25 @@ std::wstring toWString(const Streamable s)
return str.str(); 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); bool endsWith(const std::string &haystack, const char *needle);
inline bool endsWith(const std::string &haystack, char needle) inline bool endsWith(const std::string &haystack, char needle)
{ return !haystack.empty() && haystack.at(haystack.size() - 1) == needle; } { return !haystack.empty() && haystack.at(haystack.size() - 1) == needle; }

View File

@@ -402,24 +402,38 @@ static inline std::string resolveQtSymbol(const char *symbolC,
const char *modulePatternC, const char *modulePatternC,
const SymbolGroupValueContext &ctx) const SymbolGroupValueContext &ctx)
{ {
enum { debugResolveQtSymbol = 0 };
typedef std::list<std::string> StringList; typedef std::list<std::string> StringList;
typedef StringList::const_iterator StringListConstIt; 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 // First try a match with the default module name 'QtCored4!qstrdup' for speed reasons
std::string defaultPattern = defaultModuleNameC; std::string defaultPattern = defaultModuleNameC;
defaultPattern.push_back('!'); defaultPattern.push_back('!');
defaultPattern += symbolC; defaultPattern += symbolC;
const StringList defaultMatches = SymbolGroupValue::resolveSymbolName(defaultPattern.c_str(), ctx); 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 SubStringPredicate modulePattern(modulePatternC);
const StringListConstIt defaultIt = std::find_if(defaultMatches.begin(), defaultMatches.end(), modulePattern); 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; return *defaultIt;
}
// Fail, now try a search with '*qstrdup' in all modules. This might return several matches // Fail, now try a search with '*qstrdup' in all modules. This might return several matches
// like 'QtCored4!qstrdup', 'QGuid4!qstrdup' // like 'QtCored4!qstrdup', 'QGuid4!qstrdup'
const std::string wildCardPattern = std::string(1, '*') + symbolC; const std::string wildCardPattern = std::string(1, '*') + symbolC;
const StringList allMatches = SymbolGroupValue::resolveSymbolName(wildCardPattern.c_str(), ctx); 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); 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) const QtInfo &QtInfo::get(const SymbolGroupValueContext &ctx)
@@ -844,6 +858,9 @@ static KnownType knownClassTypeHelper(const std::string &type,
return KT_Unknown; return KT_Unknown;
// Qt types (templates) // Qt types (templates)
if (templatePos != std::string::npos) { 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) { switch (templatePos - qPos) {
case 4: case 4:
if (!type.compare(qPos, 4, "QSet")) if (!type.compare(qPos, 4, "QSet"))