forked from qt-creator/qt-creator
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:
@@ -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"))
|
||||
|
||||
Reference in New Issue
Block a user