1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #ifndef SYMBOLGROUPVALUE_H
34 #define SYMBOLGROUPVALUE_H
37 #include "knowntype.h"
43 class AbstractSymbolGroupNode;
44 class SymbolGroupNode;
47 struct SymbolGroupValueContext
49 SymbolGroupValueContext(CIDebugDataSpaces *ds, CIDebugSymbols *s) : dataspaces(ds), symbols(s) {}
50 SymbolGroupValueContext::SymbolGroupValueContext() : dataspaces(0), symbols(0) {}
52 CIDebugDataSpaces *dataspaces;
53 CIDebugSymbols *symbols;
56 class SymbolGroupValue
58 explicit SymbolGroupValue(const std::string &parentError);
61 typedef std::pair<std::string, ULONG64> Symbol;
62 typedef std::list<Symbol> SymbolList;
64 explicit SymbolGroupValue(SymbolGroupNode *node, const SymbolGroupValueContext &c);
67 operator bool() const { return isValid(); }
70 // Access children by name or index (0-based)
71 SymbolGroupValue operator[](const char *name) const;
72 SymbolGroupValue operator[](unsigned) const;
73 // take address and cast to desired (pointer) type
74 SymbolGroupValue typeCast(const char *type) const;
75 // take pointer value and cast to desired (pointer) type
76 SymbolGroupValue pointerTypeCast(const char *type) const;
78 std::string name() const;
79 std::string type() const;
80 std::vector<std::string> innerTypes() const { return innerTypesOf(type()); }
81 std::wstring value() const;
82 unsigned size() const;
84 SymbolGroupNode *node() const { return m_node; }
85 SymbolGroupValueContext context() const { return m_context; }
87 int intValue(int defaultValue = -1) const;
88 double floatValue(double defaultValue = -999) const;
89 ULONG64 pointerValue(ULONG64 defaultValue = 0) const;
90 ULONG64 address() const;
91 std::string module() const;
93 // Return allocated array of data pointed to
94 unsigned char *pointerData(unsigned length) const;
95 // Return data pointed to as wchar_t/std::wstring (UTF16)
96 std::wstring wcharPointerData(unsigned charCount, unsigned maxCharCount = 512) const;
98 std::string error() const;
100 // Some helpers for manipulating types.
101 static unsigned sizeOf(const char *type);
102 // Offset of structure field: "!moduleQMapNode<K,T>", "value".
103 static unsigned fieldOffset(const char *type, const char *field);
104 static std::string stripPointerType(const std::string &);
105 // Strip "class ", "struct "
106 static std::string stripClassPrefixes(const std::string &);
107 // Strip " const" from "char const*", (map key), "QString const", etc.
108 // which otherwise causes GetTypeSize to fail.
109 static std::string stripConst(const std::string &type);
110 static std::string addPointerType(const std::string &);
111 static std::string stripArrayType(const std::string &);
112 static std::string stripModuleFromType(const std::string &type);
113 static std::string moduleOfType(const std::string &type);
114 // pointer type, return number of characters to strip
115 static unsigned isPointerType(const std::string &);
116 // add pointer type 'Foo' -> 'Foo *', 'Foo *' -> 'Foo **'
117 static std::string pointerType(const std::string &type);
118 // Symbol Name/(Expression) of a pointed-to instance ('Foo' at 0x10') ==> '*(Foo *)0x10'
119 static std::string pointedToSymbolName(ULONG64 address, const std::string &type);
120 // Resolve a type, that is, obtain its module name ('QString'->'QtCored4!QString')
121 // Some operations on types (like adding symbols may fail non-deterministically
122 // or be slow when the module specification is omitted).
123 // If a current SymbolGroup is passed on, its module will be used for templates.
124 static std::string resolveType(const std::string &type,
125 const SymbolGroupValueContext &ctx,
126 const std::string ¤tModule = std::string());
128 static std::list<std::string> resolveSymbolName(const char *pattern,
129 const SymbolGroupValueContext &c,
130 std::string *errorMessage = 0);
131 static SymbolList resolveSymbol(const char *pattern,
132 const SymbolGroupValueContext &c,
133 std::string *errorMessage = 0);
135 static unsigned pointerSize();
136 static unsigned intSize();
138 // get the inner types: "QMap<int, double>" -> "int", "double"
139 static std::vector<std::string> innerTypesOf(const std::string &t);
141 static unsigned verbose;
144 bool ensureExpanded() const;
145 SymbolGroupValue typeCastedValue(ULONG64 address, const char *type) const;
147 SymbolGroupNode *m_node;
148 SymbolGroupValueContext m_context;
149 mutable std::string m_errorMessage;
152 // For debugging purposes
153 std::ostream &operator<<(std::ostream &, const SymbolGroupValue &v);
157 static const QtInfo &get(const SymbolGroupValueContext &ctx);
159 // Prepend core module and Qt namespace. To be able to work with some
160 // 'complicated' types like QMapNode, specifying the module helps
161 std::string prependQtCoreModule(const std::string &type) const
162 { return QtInfo::prependModuleAndNameSpace(type, coreModule, nameSpace); }
163 std::string prependQtGuiModule(const std::string &type) const
164 { return QtInfo::prependModuleAndNameSpace(type, guiModule, nameSpace); }
165 // Prepend module and namespace if missing with some smartness
166 // ('Foo' or -> 'nsp::Foo') => 'QtCored4!nsp::Foo'
167 static std::string prependModuleAndNameSpace(const std::string &type,
168 const std::string &module,
169 const std::string &nameSpace);
171 std::string nameSpace;
172 std::string coreModule;
173 std::string guiModule;
174 // Fully qualified types with module and namespace
175 std::string qObjectType;
176 std::string qObjectPrivateType;
177 std::string qWidgetPrivateType;
180 std::ostream &operator<<(std::ostream &os, const QtInfo &);
182 /* Helpers for detecting types reported from IDebugSymbolGroup
183 * 1) Class prefix==true is applicable to outer types obtained from
184 * from IDebugSymbolGroup: 'class foo' or 'struct foo'.
185 * 2) Class prefix==false is for inner types of templates, etc, doing
186 * a more expensive check: 'foo' */
189 KnownTypeHasClassPrefix = 0x1, // Strip "class Foo" -> "Foo"
190 KnownTypeAutoStripPointer = 0x2 // Strip "class Foo *" -> "Foo" for conveniently
191 // handling the pointer/value duality of symbol group entries
194 KnownType knownType(const std::string &type, unsigned flags);
197 void formatKnownTypeFlags(std::ostream &os, KnownType kt);
199 // Dump builtin simple types using SymbolGroupValue expressions,
200 // returning SymbolGroupNode dumper flags. Might return special info
201 // (for example, a cached additional node) for some types to be used in
203 unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx,
206 int *containerSizeIn = 0,
207 void **specialInfoIn = 0);
209 // Non-container complex dumpers (QObjects/QVariants).
210 std::vector<AbstractSymbolGroupNode *>
211 dumpComplexType(SymbolGroupNode *node, int type, void *specialInfo,
212 const SymbolGroupValueContext &ctx);
214 #endif // SYMBOLGROUPVALUE_H