File: | lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp |
Warning: | line 6734, column 23 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- TypeSystemClang.cpp -----------------------------------------------===// | ||||||
2 | // | ||||||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||
4 | // See https://llvm.org/LICENSE.txt for license information. | ||||||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||
6 | // | ||||||
7 | //===----------------------------------------------------------------------===// | ||||||
8 | |||||||
9 | #include "TypeSystemClang.h" | ||||||
10 | |||||||
11 | #include "llvm/Support/FormatAdapters.h" | ||||||
12 | #include "llvm/Support/FormatVariadic.h" | ||||||
13 | |||||||
14 | #include <mutex> | ||||||
15 | #include <string> | ||||||
16 | #include <vector> | ||||||
17 | |||||||
18 | #include "clang/AST/ASTContext.h" | ||||||
19 | #include "clang/AST/ASTImporter.h" | ||||||
20 | #include "clang/AST/Attr.h" | ||||||
21 | #include "clang/AST/CXXInheritance.h" | ||||||
22 | #include "clang/AST/DeclObjC.h" | ||||||
23 | #include "clang/AST/DeclTemplate.h" | ||||||
24 | #include "clang/AST/Mangle.h" | ||||||
25 | #include "clang/AST/RecordLayout.h" | ||||||
26 | #include "clang/AST/Type.h" | ||||||
27 | #include "clang/AST/VTableBuilder.h" | ||||||
28 | #include "clang/Basic/Builtins.h" | ||||||
29 | #include "clang/Basic/Diagnostic.h" | ||||||
30 | #include "clang/Basic/FileManager.h" | ||||||
31 | #include "clang/Basic/FileSystemOptions.h" | ||||||
32 | #include "clang/Basic/LangStandard.h" | ||||||
33 | #include "clang/Basic/SourceManager.h" | ||||||
34 | #include "clang/Basic/TargetInfo.h" | ||||||
35 | #include "clang/Basic/TargetOptions.h" | ||||||
36 | #include "clang/Frontend/FrontendOptions.h" | ||||||
37 | #include "clang/Lex/HeaderSearch.h" | ||||||
38 | #include "clang/Lex/HeaderSearchOptions.h" | ||||||
39 | #include "clang/Lex/ModuleMap.h" | ||||||
40 | #include "clang/Sema/Sema.h" | ||||||
41 | |||||||
42 | #include "llvm/Support/Signals.h" | ||||||
43 | #include "llvm/Support/Threading.h" | ||||||
44 | |||||||
45 | #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" | ||||||
46 | #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" | ||||||
47 | #include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h" | ||||||
48 | #include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h" | ||||||
49 | #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" | ||||||
50 | #include "Plugins/ExpressionParser/Clang/ClangUserExpression.h" | ||||||
51 | #include "Plugins/ExpressionParser/Clang/ClangUtil.h" | ||||||
52 | #include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h" | ||||||
53 | #include "lldb/Utility/ArchSpec.h" | ||||||
54 | #include "lldb/Utility/Flags.h" | ||||||
55 | |||||||
56 | #include "lldb/Core/DumpDataExtractor.h" | ||||||
57 | #include "lldb/Core/Module.h" | ||||||
58 | #include "lldb/Core/PluginManager.h" | ||||||
59 | #include "lldb/Core/StreamFile.h" | ||||||
60 | #include "lldb/Core/ThreadSafeDenseMap.h" | ||||||
61 | #include "lldb/Core/UniqueCStringMap.h" | ||||||
62 | #include "lldb/Symbol/ObjectFile.h" | ||||||
63 | #include "lldb/Symbol/SymbolFile.h" | ||||||
64 | #include "lldb/Target/ExecutionContext.h" | ||||||
65 | #include "lldb/Target/Language.h" | ||||||
66 | #include "lldb/Target/Process.h" | ||||||
67 | #include "lldb/Target/Target.h" | ||||||
68 | #include "lldb/Utility/DataExtractor.h" | ||||||
69 | #include "lldb/Utility/LLDBAssert.h" | ||||||
70 | #include "lldb/Utility/Log.h" | ||||||
71 | #include "lldb/Utility/RegularExpression.h" | ||||||
72 | #include "lldb/Utility/Scalar.h" | ||||||
73 | |||||||
74 | #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" | ||||||
75 | #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" | ||||||
76 | #include "Plugins/SymbolFile/PDB/PDBASTParser.h" | ||||||
77 | |||||||
78 | #include <cstdio> | ||||||
79 | |||||||
80 | #include <mutex> | ||||||
81 | |||||||
82 | using namespace lldb; | ||||||
83 | using namespace lldb_private; | ||||||
84 | using namespace clang; | ||||||
85 | using llvm::StringSwitch; | ||||||
86 | |||||||
87 | LLDB_PLUGIN_DEFINE(TypeSystemClang)namespace lldb_private { void lldb_initialize_TypeSystemClang () { TypeSystemClang::Initialize(); } void lldb_terminate_TypeSystemClang () { TypeSystemClang::Terminate(); } } | ||||||
88 | |||||||
89 | namespace { | ||||||
90 | static void VerifyDecl(clang::Decl *decl) { | ||||||
91 | assert(decl && "VerifyDecl called with nullptr?")(static_cast <bool> (decl && "VerifyDecl called with nullptr?" ) ? void (0) : __assert_fail ("decl && \"VerifyDecl called with nullptr?\"" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 91, __extension__ __PRETTY_FUNCTION__)); | ||||||
92 | #ifndef NDEBUG | ||||||
93 | // We don't care about the actual access value here but only want to trigger | ||||||
94 | // that Clang calls its internal Decl::AccessDeclContextCheck validation. | ||||||
95 | decl->getAccess(); | ||||||
96 | #endif | ||||||
97 | } | ||||||
98 | |||||||
99 | static inline bool | ||||||
100 | TypeSystemClangSupportsLanguage(lldb::LanguageType language) { | ||||||
101 | return language == eLanguageTypeUnknown || // Clang is the default type system | ||||||
102 | lldb_private::Language::LanguageIsC(language) || | ||||||
103 | lldb_private::Language::LanguageIsCPlusPlus(language) || | ||||||
104 | lldb_private::Language::LanguageIsObjC(language) || | ||||||
105 | lldb_private::Language::LanguageIsPascal(language) || | ||||||
106 | // Use Clang for Rust until there is a proper language plugin for it | ||||||
107 | language == eLanguageTypeRust || | ||||||
108 | language == eLanguageTypeExtRenderScript || | ||||||
109 | // Use Clang for D until there is a proper language plugin for it | ||||||
110 | language == eLanguageTypeD || | ||||||
111 | // Open Dylan compiler debug info is designed to be Clang-compatible | ||||||
112 | language == eLanguageTypeDylan; | ||||||
113 | } | ||||||
114 | |||||||
115 | // Checks whether m1 is an overload of m2 (as opposed to an override). This is | ||||||
116 | // called by addOverridesForMethod to distinguish overrides (which share a | ||||||
117 | // vtable entry) from overloads (which require distinct entries). | ||||||
118 | bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) { | ||||||
119 | // FIXME: This should detect covariant return types, but currently doesn't. | ||||||
120 | lldbassert(&m1->getASTContext() == &m2->getASTContext() &&lldb_private::lldb_assert(static_cast<bool>(&m1-> getASTContext() == &m2->getASTContext() && "Methods should have the same AST context" ), "&m1->getASTContext() == &m2->getASTContext() && \"Methods should have the same AST context\"" , __FUNCTION__, "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 121) | ||||||
121 | "Methods should have the same AST context")lldb_private::lldb_assert(static_cast<bool>(&m1-> getASTContext() == &m2->getASTContext() && "Methods should have the same AST context" ), "&m1->getASTContext() == &m2->getASTContext() && \"Methods should have the same AST context\"" , __FUNCTION__, "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 121); | ||||||
122 | clang::ASTContext &context = m1->getASTContext(); | ||||||
123 | |||||||
124 | const auto *m1Type = llvm::cast<clang::FunctionProtoType>( | ||||||
125 | context.getCanonicalType(m1->getType())); | ||||||
126 | |||||||
127 | const auto *m2Type = llvm::cast<clang::FunctionProtoType>( | ||||||
128 | context.getCanonicalType(m2->getType())); | ||||||
129 | |||||||
130 | auto compareArgTypes = [&context](const clang::QualType &m1p, | ||||||
131 | const clang::QualType &m2p) { | ||||||
132 | return context.hasSameType(m1p.getUnqualifiedType(), | ||||||
133 | m2p.getUnqualifiedType()); | ||||||
134 | }; | ||||||
135 | |||||||
136 | // FIXME: In C++14 and later, we can just pass m2Type->param_type_end() | ||||||
137 | // as a fourth parameter to std::equal(). | ||||||
138 | return (m1->getNumParams() != m2->getNumParams()) || | ||||||
139 | !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(), | ||||||
140 | m2Type->param_type_begin(), compareArgTypes); | ||||||
141 | } | ||||||
142 | |||||||
143 | // If decl is a virtual method, walk the base classes looking for methods that | ||||||
144 | // decl overrides. This table of overridden methods is used by IRGen to | ||||||
145 | // determine the vtable layout for decl's parent class. | ||||||
146 | void addOverridesForMethod(clang::CXXMethodDecl *decl) { | ||||||
147 | if (!decl->isVirtual()) | ||||||
148 | return; | ||||||
149 | |||||||
150 | clang::CXXBasePaths paths; | ||||||
151 | llvm::SmallVector<clang::NamedDecl *, 4> decls; | ||||||
152 | |||||||
153 | auto find_overridden_methods = | ||||||
154 | [&decls, decl](const clang::CXXBaseSpecifier *specifier, | ||||||
155 | clang::CXXBasePath &path) { | ||||||
156 | if (auto *base_record = llvm::dyn_cast<clang::CXXRecordDecl>( | ||||||
157 | specifier->getType()->getAs<clang::RecordType>()->getDecl())) { | ||||||
158 | |||||||
159 | clang::DeclarationName name = decl->getDeclName(); | ||||||
160 | |||||||
161 | // If this is a destructor, check whether the base class destructor is | ||||||
162 | // virtual. | ||||||
163 | if (name.getNameKind() == clang::DeclarationName::CXXDestructorName) | ||||||
164 | if (auto *baseDtorDecl = base_record->getDestructor()) { | ||||||
165 | if (baseDtorDecl->isVirtual()) { | ||||||
166 | decls.push_back(baseDtorDecl); | ||||||
167 | return true; | ||||||
168 | } else | ||||||
169 | return false; | ||||||
170 | } | ||||||
171 | |||||||
172 | // Otherwise, search for name in the base class. | ||||||
173 | for (path.Decls = base_record->lookup(name).begin(); | ||||||
174 | path.Decls != path.Decls.end(); ++path.Decls) { | ||||||
175 | if (auto *method_decl = | ||||||
176 | llvm::dyn_cast<clang::CXXMethodDecl>(*path.Decls)) | ||||||
177 | if (method_decl->isVirtual() && !isOverload(decl, method_decl)) { | ||||||
178 | decls.push_back(method_decl); | ||||||
179 | return true; | ||||||
180 | } | ||||||
181 | } | ||||||
182 | } | ||||||
183 | |||||||
184 | return false; | ||||||
185 | }; | ||||||
186 | |||||||
187 | if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) { | ||||||
188 | for (auto *overridden_decl : decls) | ||||||
189 | decl->addOverriddenMethod( | ||||||
190 | llvm::cast<clang::CXXMethodDecl>(overridden_decl)); | ||||||
191 | } | ||||||
192 | } | ||||||
193 | } | ||||||
194 | |||||||
195 | static lldb::addr_t GetVTableAddress(Process &process, | ||||||
196 | VTableContextBase &vtable_ctx, | ||||||
197 | ValueObject &valobj, | ||||||
198 | const ASTRecordLayout &record_layout) { | ||||||
199 | // Retrieve type info | ||||||
200 | CompilerType pointee_type; | ||||||
201 | CompilerType this_type(valobj.GetCompilerType()); | ||||||
202 | uint32_t type_info = this_type.GetTypeInfo(&pointee_type); | ||||||
203 | if (!type_info) | ||||||
204 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | ||||||
205 | |||||||
206 | // Check if it's a pointer or reference | ||||||
207 | bool ptr_or_ref = false; | ||||||
208 | if (type_info & (eTypeIsPointer | eTypeIsReference)) { | ||||||
209 | ptr_or_ref = true; | ||||||
210 | type_info = pointee_type.GetTypeInfo(); | ||||||
211 | } | ||||||
212 | |||||||
213 | // We process only C++ classes | ||||||
214 | const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus; | ||||||
215 | if ((type_info & cpp_class) != cpp_class) | ||||||
216 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | ||||||
217 | |||||||
218 | // Calculate offset to VTable pointer | ||||||
219 | lldb::offset_t vbtable_ptr_offset = | ||||||
220 | vtable_ctx.isMicrosoft() ? record_layout.getVBPtrOffset().getQuantity() | ||||||
221 | : 0; | ||||||
222 | |||||||
223 | if (ptr_or_ref) { | ||||||
224 | // We have a pointer / ref to object, so read | ||||||
225 | // VTable pointer from process memory | ||||||
226 | |||||||
227 | if (valobj.GetAddressTypeOfChildren() != eAddressTypeLoad) | ||||||
228 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | ||||||
229 | |||||||
230 | auto vbtable_ptr_addr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS(18446744073709551615UL)); | ||||||
231 | if (vbtable_ptr_addr == LLDB_INVALID_ADDRESS(18446744073709551615UL)) | ||||||
232 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | ||||||
233 | |||||||
234 | vbtable_ptr_addr += vbtable_ptr_offset; | ||||||
235 | |||||||
236 | Status err; | ||||||
237 | return process.ReadPointerFromMemory(vbtable_ptr_addr, err); | ||||||
238 | } | ||||||
239 | |||||||
240 | // We have an object already read from process memory, | ||||||
241 | // so just extract VTable pointer from it | ||||||
242 | |||||||
243 | DataExtractor data; | ||||||
244 | Status err; | ||||||
245 | auto size = valobj.GetData(data, err); | ||||||
246 | if (err.Fail() || vbtable_ptr_offset + data.GetAddressByteSize() > size) | ||||||
247 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); | ||||||
248 | |||||||
249 | return data.GetAddress(&vbtable_ptr_offset); | ||||||
250 | } | ||||||
251 | |||||||
252 | static int64_t ReadVBaseOffsetFromVTable(Process &process, | ||||||
253 | VTableContextBase &vtable_ctx, | ||||||
254 | lldb::addr_t vtable_ptr, | ||||||
255 | const CXXRecordDecl *cxx_record_decl, | ||||||
256 | const CXXRecordDecl *base_class_decl) { | ||||||
257 | if (vtable_ctx.isMicrosoft()) { | ||||||
258 | clang::MicrosoftVTableContext &msoft_vtable_ctx = | ||||||
259 | static_cast<clang::MicrosoftVTableContext &>(vtable_ctx); | ||||||
260 | |||||||
261 | // Get the index into the virtual base table. The | ||||||
262 | // index is the index in uint32_t from vbtable_ptr | ||||||
263 | const unsigned vbtable_index = | ||||||
264 | msoft_vtable_ctx.getVBTableIndex(cxx_record_decl, base_class_decl); | ||||||
265 | const lldb::addr_t base_offset_addr = vtable_ptr + vbtable_index * 4; | ||||||
266 | Status err; | ||||||
267 | return process.ReadSignedIntegerFromMemory(base_offset_addr, 4, INT64_MAX(9223372036854775807L), | ||||||
268 | err); | ||||||
269 | } | ||||||
270 | |||||||
271 | clang::ItaniumVTableContext &itanium_vtable_ctx = | ||||||
272 | static_cast<clang::ItaniumVTableContext &>(vtable_ctx); | ||||||
273 | |||||||
274 | clang::CharUnits base_offset_offset = | ||||||
275 | itanium_vtable_ctx.getVirtualBaseOffsetOffset(cxx_record_decl, | ||||||
276 | base_class_decl); | ||||||
277 | const lldb::addr_t base_offset_addr = | ||||||
278 | vtable_ptr + base_offset_offset.getQuantity(); | ||||||
279 | const uint32_t base_offset_size = process.GetAddressByteSize(); | ||||||
280 | Status err; | ||||||
281 | return process.ReadSignedIntegerFromMemory(base_offset_addr, base_offset_size, | ||||||
282 | INT64_MAX(9223372036854775807L), err); | ||||||
283 | } | ||||||
284 | |||||||
285 | static bool GetVBaseBitOffset(VTableContextBase &vtable_ctx, | ||||||
286 | ValueObject &valobj, | ||||||
287 | const ASTRecordLayout &record_layout, | ||||||
288 | const CXXRecordDecl *cxx_record_decl, | ||||||
289 | const CXXRecordDecl *base_class_decl, | ||||||
290 | int32_t &bit_offset) { | ||||||
291 | ExecutionContext exe_ctx(valobj.GetExecutionContextRef()); | ||||||
292 | Process *process = exe_ctx.GetProcessPtr(); | ||||||
293 | if (!process) | ||||||
294 | return false; | ||||||
295 | |||||||
296 | lldb::addr_t vtable_ptr = | ||||||
297 | GetVTableAddress(*process, vtable_ctx, valobj, record_layout); | ||||||
298 | if (vtable_ptr == LLDB_INVALID_ADDRESS(18446744073709551615UL)) | ||||||
299 | return false; | ||||||
300 | |||||||
301 | auto base_offset = ReadVBaseOffsetFromVTable( | ||||||
302 | *process, vtable_ctx, vtable_ptr, cxx_record_decl, base_class_decl); | ||||||
303 | if (base_offset == INT64_MAX(9223372036854775807L)) | ||||||
304 | return false; | ||||||
305 | |||||||
306 | bit_offset = base_offset * 8; | ||||||
307 | |||||||
308 | return true; | ||||||
309 | } | ||||||
310 | |||||||
311 | typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, TypeSystemClang *> | ||||||
312 | ClangASTMap; | ||||||
313 | |||||||
314 | static ClangASTMap &GetASTMap() { | ||||||
315 | static ClangASTMap *g_map_ptr = nullptr; | ||||||
316 | static llvm::once_flag g_once_flag; | ||||||
317 | llvm::call_once(g_once_flag, []() { | ||||||
318 | g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins | ||||||
319 | }); | ||||||
320 | return *g_map_ptr; | ||||||
321 | } | ||||||
322 | |||||||
323 | TypePayloadClang::TypePayloadClang(OptionalClangModuleID owning_module, | ||||||
324 | bool is_complete_objc_class) | ||||||
325 | : m_payload(owning_module.GetValue()) { | ||||||
326 | SetIsCompleteObjCClass(is_complete_objc_class); | ||||||
327 | } | ||||||
328 | |||||||
329 | void TypePayloadClang::SetOwningModule(OptionalClangModuleID id) { | ||||||
330 | assert(id.GetValue() < ObjCClassBit)(static_cast <bool> (id.GetValue() < ObjCClassBit) ? void (0) : __assert_fail ("id.GetValue() < ObjCClassBit", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 330 , __extension__ __PRETTY_FUNCTION__)); | ||||||
331 | bool is_complete = IsCompleteObjCClass(); | ||||||
332 | m_payload = id.GetValue(); | ||||||
333 | SetIsCompleteObjCClass(is_complete); | ||||||
334 | } | ||||||
335 | |||||||
336 | static void SetMemberOwningModule(clang::Decl *member, | ||||||
337 | const clang::Decl *parent) { | ||||||
338 | if (!member || !parent) | ||||||
339 | return; | ||||||
340 | |||||||
341 | OptionalClangModuleID id(parent->getOwningModuleID()); | ||||||
342 | if (!id.HasValue()) | ||||||
343 | return; | ||||||
344 | |||||||
345 | member->setFromASTFile(); | ||||||
346 | member->setOwningModuleID(id.GetValue()); | ||||||
347 | member->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible); | ||||||
348 | if (llvm::isa<clang::NamedDecl>(member)) | ||||||
349 | if (auto *dc = llvm::dyn_cast<clang::DeclContext>(parent)) { | ||||||
350 | dc->setHasExternalVisibleStorage(true); | ||||||
351 | // This triggers ExternalASTSource::FindExternalVisibleDeclsByName() to be | ||||||
352 | // called when searching for members. | ||||||
353 | dc->setHasExternalLexicalStorage(true); | ||||||
354 | } | ||||||
355 | } | ||||||
356 | |||||||
357 | char TypeSystemClang::ID; | ||||||
358 | |||||||
359 | bool TypeSystemClang::IsOperator(llvm::StringRef name, | ||||||
360 | clang::OverloadedOperatorKind &op_kind) { | ||||||
361 | // All operators have to start with "operator". | ||||||
362 | if (!name.consume_front("operator")) | ||||||
363 | return false; | ||||||
364 | |||||||
365 | // Remember if there was a space after "operator". This is necessary to | ||||||
366 | // check for collisions with strangely named functions like "operatorint()". | ||||||
367 | bool space_after_operator = name.consume_front(" "); | ||||||
368 | |||||||
369 | op_kind = StringSwitch<clang::OverloadedOperatorKind>(name) | ||||||
370 | .Case("+", clang::OO_Plus) | ||||||
371 | .Case("+=", clang::OO_PlusEqual) | ||||||
372 | .Case("++", clang::OO_PlusPlus) | ||||||
373 | .Case("-", clang::OO_Minus) | ||||||
374 | .Case("-=", clang::OO_MinusEqual) | ||||||
375 | .Case("--", clang::OO_MinusMinus) | ||||||
376 | .Case("->", clang::OO_Arrow) | ||||||
377 | .Case("->*", clang::OO_ArrowStar) | ||||||
378 | .Case("*", clang::OO_Star) | ||||||
379 | .Case("*=", clang::OO_StarEqual) | ||||||
380 | .Case("/", clang::OO_Slash) | ||||||
381 | .Case("/=", clang::OO_SlashEqual) | ||||||
382 | .Case("%", clang::OO_Percent) | ||||||
383 | .Case("%=", clang::OO_PercentEqual) | ||||||
384 | .Case("^", clang::OO_Caret) | ||||||
385 | .Case("^=", clang::OO_CaretEqual) | ||||||
386 | .Case("&", clang::OO_Amp) | ||||||
387 | .Case("&=", clang::OO_AmpEqual) | ||||||
388 | .Case("&&", clang::OO_AmpAmp) | ||||||
389 | .Case("|", clang::OO_Pipe) | ||||||
390 | .Case("|=", clang::OO_PipeEqual) | ||||||
391 | .Case("||", clang::OO_PipePipe) | ||||||
392 | .Case("~", clang::OO_Tilde) | ||||||
393 | .Case("!", clang::OO_Exclaim) | ||||||
394 | .Case("!=", clang::OO_ExclaimEqual) | ||||||
395 | .Case("=", clang::OO_Equal) | ||||||
396 | .Case("==", clang::OO_EqualEqual) | ||||||
397 | .Case("<", clang::OO_Less) | ||||||
398 | .Case("<<", clang::OO_LessLess) | ||||||
399 | .Case("<<=", clang::OO_LessLessEqual) | ||||||
400 | .Case("<=", clang::OO_LessEqual) | ||||||
401 | .Case(">", clang::OO_Greater) | ||||||
402 | .Case(">>", clang::OO_GreaterGreater) | ||||||
403 | .Case(">>=", clang::OO_GreaterGreaterEqual) | ||||||
404 | .Case(">=", clang::OO_GreaterEqual) | ||||||
405 | .Case("()", clang::OO_Call) | ||||||
406 | .Case("[]", clang::OO_Subscript) | ||||||
407 | .Case(",", clang::OO_Comma) | ||||||
408 | .Default(clang::NUM_OVERLOADED_OPERATORS); | ||||||
409 | |||||||
410 | // We found a fitting operator, so we can exit now. | ||||||
411 | if (op_kind != clang::NUM_OVERLOADED_OPERATORS) | ||||||
412 | return true; | ||||||
413 | |||||||
414 | // After the "operator " or "operator" part is something unknown. This means | ||||||
415 | // it's either one of the named operators (new/delete), a conversion operator | ||||||
416 | // (e.g. operator bool) or a function which name starts with "operator" | ||||||
417 | // (e.g. void operatorbool). | ||||||
418 | |||||||
419 | // If it's a function that starts with operator it can't have a space after | ||||||
420 | // "operator" because identifiers can't contain spaces. | ||||||
421 | // E.g. "operator int" (conversion operator) | ||||||
422 | // vs. "operatorint" (function with colliding name). | ||||||
423 | if (!space_after_operator) | ||||||
424 | return false; // not an operator. | ||||||
425 | |||||||
426 | // Now the operator is either one of the named operators or a conversion | ||||||
427 | // operator. | ||||||
428 | op_kind = StringSwitch<clang::OverloadedOperatorKind>(name) | ||||||
429 | .Case("new", clang::OO_New) | ||||||
430 | .Case("new[]", clang::OO_Array_New) | ||||||
431 | .Case("delete", clang::OO_Delete) | ||||||
432 | .Case("delete[]", clang::OO_Array_Delete) | ||||||
433 | // conversion operators hit this case. | ||||||
434 | .Default(clang::NUM_OVERLOADED_OPERATORS); | ||||||
435 | |||||||
436 | return true; | ||||||
437 | } | ||||||
438 | |||||||
439 | clang::AccessSpecifier | ||||||
440 | TypeSystemClang::ConvertAccessTypeToAccessSpecifier(AccessType access) { | ||||||
441 | switch (access) { | ||||||
442 | default: | ||||||
443 | break; | ||||||
444 | case eAccessNone: | ||||||
445 | return AS_none; | ||||||
446 | case eAccessPublic: | ||||||
447 | return AS_public; | ||||||
448 | case eAccessPrivate: | ||||||
449 | return AS_private; | ||||||
450 | case eAccessProtected: | ||||||
451 | return AS_protected; | ||||||
452 | } | ||||||
453 | return AS_none; | ||||||
454 | } | ||||||
455 | |||||||
456 | static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { | ||||||
457 | // FIXME: Cleanup per-file based stuff. | ||||||
458 | |||||||
459 | // Set some properties which depend solely on the input kind; it would be | ||||||
460 | // nice to move these to the language standard, and have the driver resolve | ||||||
461 | // the input kind + language standard. | ||||||
462 | if (IK.getLanguage() == clang::Language::Asm) { | ||||||
463 | Opts.AsmPreprocessor = 1; | ||||||
464 | } else if (IK.isObjectiveC()) { | ||||||
465 | Opts.ObjC = 1; | ||||||
466 | } | ||||||
467 | |||||||
468 | LangStandard::Kind LangStd = LangStandard::lang_unspecified; | ||||||
469 | |||||||
470 | if (LangStd == LangStandard::lang_unspecified) { | ||||||
471 | // Based on the base language, pick one. | ||||||
472 | switch (IK.getLanguage()) { | ||||||
473 | case clang::Language::Unknown: | ||||||
474 | case clang::Language::LLVM_IR: | ||||||
475 | case clang::Language::RenderScript: | ||||||
476 | llvm_unreachable("Invalid input kind!")::llvm::llvm_unreachable_internal("Invalid input kind!", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 476); | ||||||
477 | case clang::Language::OpenCL: | ||||||
478 | LangStd = LangStandard::lang_opencl10; | ||||||
479 | break; | ||||||
480 | case clang::Language::OpenCLCXX: | ||||||
481 | LangStd = LangStandard::lang_openclcpp10; | ||||||
482 | break; | ||||||
483 | case clang::Language::CUDA: | ||||||
484 | LangStd = LangStandard::lang_cuda; | ||||||
485 | break; | ||||||
486 | case clang::Language::Asm: | ||||||
487 | case clang::Language::C: | ||||||
488 | case clang::Language::ObjC: | ||||||
489 | LangStd = LangStandard::lang_gnu99; | ||||||
490 | break; | ||||||
491 | case clang::Language::CXX: | ||||||
492 | case clang::Language::ObjCXX: | ||||||
493 | LangStd = LangStandard::lang_gnucxx98; | ||||||
494 | break; | ||||||
495 | case clang::Language::HIP: | ||||||
496 | LangStd = LangStandard::lang_hip; | ||||||
497 | break; | ||||||
498 | } | ||||||
499 | } | ||||||
500 | |||||||
501 | const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); | ||||||
502 | Opts.LineComment = Std.hasLineComments(); | ||||||
503 | Opts.C99 = Std.isC99(); | ||||||
504 | Opts.CPlusPlus = Std.isCPlusPlus(); | ||||||
505 | Opts.CPlusPlus11 = Std.isCPlusPlus11(); | ||||||
506 | Opts.Digraphs = Std.hasDigraphs(); | ||||||
507 | Opts.GNUMode = Std.isGNUMode(); | ||||||
508 | Opts.GNUInline = !Std.isC99(); | ||||||
509 | Opts.HexFloats = Std.hasHexFloats(); | ||||||
510 | Opts.ImplicitInt = Std.hasImplicitInt(); | ||||||
511 | |||||||
512 | Opts.WChar = true; | ||||||
513 | |||||||
514 | // OpenCL has some additional defaults. | ||||||
515 | if (LangStd == LangStandard::lang_opencl10) { | ||||||
516 | Opts.OpenCL = 1; | ||||||
517 | Opts.AltiVec = 1; | ||||||
518 | Opts.CXXOperatorNames = 1; | ||||||
519 | Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::All); | ||||||
520 | } | ||||||
521 | |||||||
522 | // OpenCL and C++ both have bool, true, false keywords. | ||||||
523 | Opts.Bool = Opts.OpenCL || Opts.CPlusPlus; | ||||||
524 | |||||||
525 | Opts.setValueVisibilityMode(DefaultVisibility); | ||||||
526 | |||||||
527 | // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs is | ||||||
528 | // specified, or -std is set to a conforming mode. | ||||||
529 | Opts.Trigraphs = !Opts.GNUMode; | ||||||
530 | Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault(); | ||||||
531 | Opts.OptimizeSize = 0; | ||||||
532 | |||||||
533 | // FIXME: Eliminate this dependency. | ||||||
534 | // unsigned Opt = | ||||||
535 | // Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags); | ||||||
536 | // Opts.Optimize = Opt != 0; | ||||||
537 | unsigned Opt = 0; | ||||||
538 | |||||||
539 | // This is the __NO_INLINE__ define, which just depends on things like the | ||||||
540 | // optimization level and -fno-inline, not actually whether the backend has | ||||||
541 | // inlining enabled. | ||||||
542 | // | ||||||
543 | // FIXME: This is affected by other options (-fno-inline). | ||||||
544 | Opts.NoInlineDefine = !Opt; | ||||||
545 | |||||||
546 | // This is needed to allocate the extra space for the owning module | ||||||
547 | // on each decl. | ||||||
548 | Opts.ModulesLocalVisibility = 1; | ||||||
549 | } | ||||||
550 | |||||||
551 | TypeSystemClang::TypeSystemClang(llvm::StringRef name, | ||||||
552 | llvm::Triple target_triple) { | ||||||
553 | m_display_name = name.str(); | ||||||
554 | if (!target_triple.str().empty()) | ||||||
555 | SetTargetTriple(target_triple.str()); | ||||||
556 | // The caller didn't pass an ASTContext so create a new one for this | ||||||
557 | // TypeSystemClang. | ||||||
558 | CreateASTContext(); | ||||||
559 | } | ||||||
560 | |||||||
561 | TypeSystemClang::TypeSystemClang(llvm::StringRef name, | ||||||
562 | ASTContext &existing_ctxt) { | ||||||
563 | m_display_name = name.str(); | ||||||
564 | SetTargetTriple(existing_ctxt.getTargetInfo().getTriple().str()); | ||||||
565 | |||||||
566 | m_ast_up.reset(&existing_ctxt); | ||||||
567 | GetASTMap().Insert(&existing_ctxt, this); | ||||||
568 | } | ||||||
569 | |||||||
570 | // Destructor | ||||||
571 | TypeSystemClang::~TypeSystemClang() { Finalize(); } | ||||||
572 | |||||||
573 | lldb::TypeSystemSP TypeSystemClang::CreateInstance(lldb::LanguageType language, | ||||||
574 | lldb_private::Module *module, | ||||||
575 | Target *target) { | ||||||
576 | if (!TypeSystemClangSupportsLanguage(language)) | ||||||
577 | return lldb::TypeSystemSP(); | ||||||
578 | ArchSpec arch; | ||||||
579 | if (module) | ||||||
580 | arch = module->GetArchitecture(); | ||||||
581 | else if (target) | ||||||
582 | arch = target->GetArchitecture(); | ||||||
583 | |||||||
584 | if (!arch.IsValid()) | ||||||
585 | return lldb::TypeSystemSP(); | ||||||
586 | |||||||
587 | llvm::Triple triple = arch.GetTriple(); | ||||||
588 | // LLVM wants this to be set to iOS or MacOSX; if we're working on | ||||||
589 | // a bare-boards type image, change the triple for llvm's benefit. | ||||||
590 | if (triple.getVendor() == llvm::Triple::Apple && | ||||||
591 | triple.getOS() == llvm::Triple::UnknownOS) { | ||||||
592 | if (triple.getArch() == llvm::Triple::arm || | ||||||
593 | triple.getArch() == llvm::Triple::aarch64 || | ||||||
594 | triple.getArch() == llvm::Triple::aarch64_32 || | ||||||
595 | triple.getArch() == llvm::Triple::thumb) { | ||||||
596 | triple.setOS(llvm::Triple::IOS); | ||||||
597 | } else { | ||||||
598 | triple.setOS(llvm::Triple::MacOSX); | ||||||
599 | } | ||||||
600 | } | ||||||
601 | |||||||
602 | if (module) { | ||||||
603 | std::string ast_name = | ||||||
604 | "ASTContext for '" + module->GetFileSpec().GetPath() + "'"; | ||||||
605 | return std::make_shared<TypeSystemClang>(ast_name, triple); | ||||||
606 | } else if (target && target->IsValid()) | ||||||
607 | return std::make_shared<ScratchTypeSystemClang>(*target, triple); | ||||||
608 | return lldb::TypeSystemSP(); | ||||||
609 | } | ||||||
610 | |||||||
611 | LanguageSet TypeSystemClang::GetSupportedLanguagesForTypes() { | ||||||
612 | LanguageSet languages; | ||||||
613 | languages.Insert(lldb::eLanguageTypeC89); | ||||||
614 | languages.Insert(lldb::eLanguageTypeC); | ||||||
615 | languages.Insert(lldb::eLanguageTypeC11); | ||||||
616 | languages.Insert(lldb::eLanguageTypeC_plus_plus); | ||||||
617 | languages.Insert(lldb::eLanguageTypeC99); | ||||||
618 | languages.Insert(lldb::eLanguageTypeObjC); | ||||||
619 | languages.Insert(lldb::eLanguageTypeObjC_plus_plus); | ||||||
620 | languages.Insert(lldb::eLanguageTypeC_plus_plus_03); | ||||||
621 | languages.Insert(lldb::eLanguageTypeC_plus_plus_11); | ||||||
622 | languages.Insert(lldb::eLanguageTypeC11); | ||||||
623 | languages.Insert(lldb::eLanguageTypeC_plus_plus_14); | ||||||
624 | return languages; | ||||||
625 | } | ||||||
626 | |||||||
627 | LanguageSet TypeSystemClang::GetSupportedLanguagesForExpressions() { | ||||||
628 | LanguageSet languages; | ||||||
629 | languages.Insert(lldb::eLanguageTypeC_plus_plus); | ||||||
630 | languages.Insert(lldb::eLanguageTypeObjC_plus_plus); | ||||||
631 | languages.Insert(lldb::eLanguageTypeC_plus_plus_03); | ||||||
632 | languages.Insert(lldb::eLanguageTypeC_plus_plus_11); | ||||||
633 | languages.Insert(lldb::eLanguageTypeC_plus_plus_14); | ||||||
634 | return languages; | ||||||
635 | } | ||||||
636 | |||||||
637 | void TypeSystemClang::Initialize() { | ||||||
638 | PluginManager::RegisterPlugin( | ||||||
639 | GetPluginNameStatic(), "clang base AST context plug-in", CreateInstance, | ||||||
640 | GetSupportedLanguagesForTypes(), GetSupportedLanguagesForExpressions()); | ||||||
641 | } | ||||||
642 | |||||||
643 | void TypeSystemClang::Terminate() { | ||||||
644 | PluginManager::UnregisterPlugin(CreateInstance); | ||||||
645 | } | ||||||
646 | |||||||
647 | void TypeSystemClang::Finalize() { | ||||||
648 | assert(m_ast_up)(static_cast <bool> (m_ast_up) ? void (0) : __assert_fail ("m_ast_up", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 648, __extension__ __PRETTY_FUNCTION__)); | ||||||
649 | GetASTMap().Erase(m_ast_up.get()); | ||||||
650 | if (!m_ast_owned) | ||||||
651 | m_ast_up.release(); | ||||||
652 | |||||||
653 | m_builtins_up.reset(); | ||||||
654 | m_selector_table_up.reset(); | ||||||
655 | m_identifier_table_up.reset(); | ||||||
656 | m_target_info_up.reset(); | ||||||
657 | m_target_options_rp.reset(); | ||||||
658 | m_diagnostics_engine_up.reset(); | ||||||
659 | m_source_manager_up.reset(); | ||||||
660 | m_language_options_up.reset(); | ||||||
661 | } | ||||||
662 | |||||||
663 | void TypeSystemClang::setSema(Sema *s) { | ||||||
664 | // Ensure that the new sema actually belongs to our ASTContext. | ||||||
665 | assert(s == nullptr || &s->getASTContext() == m_ast_up.get())(static_cast <bool> (s == nullptr || &s->getASTContext () == m_ast_up.get()) ? void (0) : __assert_fail ("s == nullptr || &s->getASTContext() == m_ast_up.get()" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 665, __extension__ __PRETTY_FUNCTION__)); | ||||||
666 | m_sema = s; | ||||||
667 | } | ||||||
668 | |||||||
669 | const char *TypeSystemClang::GetTargetTriple() { | ||||||
670 | return m_target_triple.c_str(); | ||||||
671 | } | ||||||
672 | |||||||
673 | void TypeSystemClang::SetTargetTriple(llvm::StringRef target_triple) { | ||||||
674 | m_target_triple = target_triple.str(); | ||||||
675 | } | ||||||
676 | |||||||
677 | void TypeSystemClang::SetExternalSource( | ||||||
678 | llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) { | ||||||
679 | ASTContext &ast = getASTContext(); | ||||||
680 | ast.getTranslationUnitDecl()->setHasExternalLexicalStorage(true); | ||||||
681 | ast.setExternalSource(ast_source_up); | ||||||
682 | } | ||||||
683 | |||||||
684 | ASTContext &TypeSystemClang::getASTContext() { | ||||||
685 | assert(m_ast_up)(static_cast <bool> (m_ast_up) ? void (0) : __assert_fail ("m_ast_up", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 685, __extension__ __PRETTY_FUNCTION__)); | ||||||
686 | return *m_ast_up; | ||||||
687 | } | ||||||
688 | |||||||
689 | class NullDiagnosticConsumer : public DiagnosticConsumer { | ||||||
690 | public: | ||||||
691 | NullDiagnosticConsumer() { | ||||||
692 | m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS::lldb_private::LLDBLog::Expressions); | ||||||
693 | } | ||||||
694 | |||||||
695 | void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, | ||||||
696 | const clang::Diagnostic &info) override { | ||||||
697 | if (m_log) { | ||||||
698 | llvm::SmallVector<char, 32> diag_str(10); | ||||||
699 | info.FormatDiagnostic(diag_str); | ||||||
700 | diag_str.push_back('\0'); | ||||||
701 | LLDB_LOGF(m_log, "Compiler diagnostic: %s\n", diag_str.data())do { ::lldb_private::Log *log_private = (m_log); if (log_private ) log_private->Printf("Compiler diagnostic: %s\n", diag_str .data()); } while (0); | ||||||
702 | } | ||||||
703 | } | ||||||
704 | |||||||
705 | DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { | ||||||
706 | return new NullDiagnosticConsumer(); | ||||||
707 | } | ||||||
708 | |||||||
709 | private: | ||||||
710 | Log *m_log; | ||||||
711 | }; | ||||||
712 | |||||||
713 | void TypeSystemClang::CreateASTContext() { | ||||||
714 | assert(!m_ast_up)(static_cast <bool> (!m_ast_up) ? void (0) : __assert_fail ("!m_ast_up", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 714, __extension__ __PRETTY_FUNCTION__)); | ||||||
715 | m_ast_owned = true; | ||||||
716 | |||||||
717 | m_language_options_up = std::make_unique<LangOptions>(); | ||||||
718 | ParseLangArgs(*m_language_options_up, clang::Language::ObjCXX, | ||||||
719 | GetTargetTriple()); | ||||||
720 | |||||||
721 | m_identifier_table_up = | ||||||
722 | std::make_unique<IdentifierTable>(*m_language_options_up, nullptr); | ||||||
723 | m_builtins_up = std::make_unique<Builtin::Context>(); | ||||||
724 | |||||||
725 | m_selector_table_up = std::make_unique<SelectorTable>(); | ||||||
726 | |||||||
727 | clang::FileSystemOptions file_system_options; | ||||||
728 | m_file_manager_up = std::make_unique<clang::FileManager>( | ||||||
729 | file_system_options, FileSystem::Instance().GetVirtualFileSystem()); | ||||||
730 | |||||||
731 | llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs()); | ||||||
732 | m_diagnostics_engine_up = | ||||||
733 | std::make_unique<DiagnosticsEngine>(diag_id_sp, new DiagnosticOptions()); | ||||||
734 | |||||||
735 | m_source_manager_up = std::make_unique<clang::SourceManager>( | ||||||
736 | *m_diagnostics_engine_up, *m_file_manager_up); | ||||||
737 | m_ast_up = std::make_unique<ASTContext>( | ||||||
738 | *m_language_options_up, *m_source_manager_up, *m_identifier_table_up, | ||||||
739 | *m_selector_table_up, *m_builtins_up, TU_Complete); | ||||||
740 | |||||||
741 | m_diagnostic_consumer_up = std::make_unique<NullDiagnosticConsumer>(); | ||||||
742 | m_ast_up->getDiagnostics().setClient(m_diagnostic_consumer_up.get(), false); | ||||||
743 | |||||||
744 | // This can be NULL if we don't know anything about the architecture or if | ||||||
745 | // the target for an architecture isn't enabled in the llvm/clang that we | ||||||
746 | // built | ||||||
747 | TargetInfo *target_info = getTargetInfo(); | ||||||
748 | if (target_info) | ||||||
749 | m_ast_up->InitBuiltinTypes(*target_info); | ||||||
750 | |||||||
751 | GetASTMap().Insert(m_ast_up.get(), this); | ||||||
752 | |||||||
753 | llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_up( | ||||||
754 | new ClangExternalASTSourceCallbacks(*this)); | ||||||
755 | SetExternalSource(ast_source_up); | ||||||
756 | } | ||||||
757 | |||||||
758 | TypeSystemClang *TypeSystemClang::GetASTContext(clang::ASTContext *ast) { | ||||||
759 | TypeSystemClang *clang_ast = GetASTMap().Lookup(ast); | ||||||
760 | return clang_ast; | ||||||
761 | } | ||||||
762 | |||||||
763 | clang::MangleContext *TypeSystemClang::getMangleContext() { | ||||||
764 | if (m_mangle_ctx_up == nullptr) | ||||||
765 | m_mangle_ctx_up.reset(getASTContext().createMangleContext()); | ||||||
766 | return m_mangle_ctx_up.get(); | ||||||
767 | } | ||||||
768 | |||||||
769 | std::shared_ptr<clang::TargetOptions> &TypeSystemClang::getTargetOptions() { | ||||||
770 | if (m_target_options_rp == nullptr && !m_target_triple.empty()) { | ||||||
771 | m_target_options_rp = std::make_shared<clang::TargetOptions>(); | ||||||
772 | if (m_target_options_rp != nullptr) | ||||||
773 | m_target_options_rp->Triple = m_target_triple; | ||||||
774 | } | ||||||
775 | return m_target_options_rp; | ||||||
776 | } | ||||||
777 | |||||||
778 | TargetInfo *TypeSystemClang::getTargetInfo() { | ||||||
779 | // target_triple should be something like "x86_64-apple-macosx" | ||||||
780 | if (m_target_info_up == nullptr && !m_target_triple.empty()) | ||||||
781 | m_target_info_up.reset(TargetInfo::CreateTargetInfo( | ||||||
782 | getASTContext().getDiagnostics(), getTargetOptions())); | ||||||
783 | return m_target_info_up.get(); | ||||||
784 | } | ||||||
785 | |||||||
786 | #pragma mark Basic Types | ||||||
787 | |||||||
788 | static inline bool QualTypeMatchesBitSize(const uint64_t bit_size, | ||||||
789 | ASTContext &ast, QualType qual_type) { | ||||||
790 | uint64_t qual_type_bit_size = ast.getTypeSize(qual_type); | ||||||
791 | return qual_type_bit_size == bit_size; | ||||||
792 | } | ||||||
793 | |||||||
794 | CompilerType | ||||||
795 | TypeSystemClang::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding, | ||||||
796 | size_t bit_size) { | ||||||
797 | ASTContext &ast = getASTContext(); | ||||||
798 | switch (encoding) { | ||||||
799 | case eEncodingInvalid: | ||||||
800 | if (QualTypeMatchesBitSize(bit_size, ast, ast.VoidPtrTy)) | ||||||
801 | return GetType(ast.VoidPtrTy); | ||||||
802 | break; | ||||||
803 | |||||||
804 | case eEncodingUint: | ||||||
805 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) | ||||||
806 | return GetType(ast.UnsignedCharTy); | ||||||
807 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) | ||||||
808 | return GetType(ast.UnsignedShortTy); | ||||||
809 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) | ||||||
810 | return GetType(ast.UnsignedIntTy); | ||||||
811 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy)) | ||||||
812 | return GetType(ast.UnsignedLongTy); | ||||||
813 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy)) | ||||||
814 | return GetType(ast.UnsignedLongLongTy); | ||||||
815 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty)) | ||||||
816 | return GetType(ast.UnsignedInt128Ty); | ||||||
817 | break; | ||||||
818 | |||||||
819 | case eEncodingSint: | ||||||
820 | if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy)) | ||||||
821 | return GetType(ast.SignedCharTy); | ||||||
822 | if (QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy)) | ||||||
823 | return GetType(ast.ShortTy); | ||||||
824 | if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy)) | ||||||
825 | return GetType(ast.IntTy); | ||||||
826 | if (QualTypeMatchesBitSize(bit_size, ast, ast.LongTy)) | ||||||
827 | return GetType(ast.LongTy); | ||||||
828 | if (QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy)) | ||||||
829 | return GetType(ast.LongLongTy); | ||||||
830 | if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty)) | ||||||
831 | return GetType(ast.Int128Ty); | ||||||
832 | break; | ||||||
833 | |||||||
834 | case eEncodingIEEE754: | ||||||
835 | if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy)) | ||||||
836 | return GetType(ast.FloatTy); | ||||||
837 | if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy)) | ||||||
838 | return GetType(ast.DoubleTy); | ||||||
839 | if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy)) | ||||||
840 | return GetType(ast.LongDoubleTy); | ||||||
841 | if (QualTypeMatchesBitSize(bit_size, ast, ast.HalfTy)) | ||||||
842 | return GetType(ast.HalfTy); | ||||||
843 | break; | ||||||
844 | |||||||
845 | case eEncodingVector: | ||||||
846 | // Sanity check that bit_size is a multiple of 8's. | ||||||
847 | if (bit_size && !(bit_size & 0x7u)) | ||||||
848 | return GetType(ast.getExtVectorType(ast.UnsignedCharTy, bit_size / 8)); | ||||||
849 | break; | ||||||
850 | } | ||||||
851 | |||||||
852 | return CompilerType(); | ||||||
853 | } | ||||||
854 | |||||||
855 | lldb::BasicType | ||||||
856 | TypeSystemClang::GetBasicTypeEnumeration(ConstString name) { | ||||||
857 | if (name) { | ||||||
858 | typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap; | ||||||
859 | static TypeNameToBasicTypeMap g_type_map; | ||||||
860 | static llvm::once_flag g_once_flag; | ||||||
861 | llvm::call_once(g_once_flag, []() { | ||||||
862 | // "void" | ||||||
863 | g_type_map.Append(ConstString("void"), eBasicTypeVoid); | ||||||
864 | |||||||
865 | // "char" | ||||||
866 | g_type_map.Append(ConstString("char"), eBasicTypeChar); | ||||||
867 | g_type_map.Append(ConstString("signed char"), eBasicTypeSignedChar); | ||||||
868 | g_type_map.Append(ConstString("unsigned char"), eBasicTypeUnsignedChar); | ||||||
869 | g_type_map.Append(ConstString("wchar_t"), eBasicTypeWChar); | ||||||
870 | g_type_map.Append(ConstString("signed wchar_t"), eBasicTypeSignedWChar); | ||||||
871 | g_type_map.Append(ConstString("unsigned wchar_t"), | ||||||
872 | eBasicTypeUnsignedWChar); | ||||||
873 | // "short" | ||||||
874 | g_type_map.Append(ConstString("short"), eBasicTypeShort); | ||||||
875 | g_type_map.Append(ConstString("short int"), eBasicTypeShort); | ||||||
876 | g_type_map.Append(ConstString("unsigned short"), eBasicTypeUnsignedShort); | ||||||
877 | g_type_map.Append(ConstString("unsigned short int"), | ||||||
878 | eBasicTypeUnsignedShort); | ||||||
879 | |||||||
880 | // "int" | ||||||
881 | g_type_map.Append(ConstString("int"), eBasicTypeInt); | ||||||
882 | g_type_map.Append(ConstString("signed int"), eBasicTypeInt); | ||||||
883 | g_type_map.Append(ConstString("unsigned int"), eBasicTypeUnsignedInt); | ||||||
884 | g_type_map.Append(ConstString("unsigned"), eBasicTypeUnsignedInt); | ||||||
885 | |||||||
886 | // "long" | ||||||
887 | g_type_map.Append(ConstString("long"), eBasicTypeLong); | ||||||
888 | g_type_map.Append(ConstString("long int"), eBasicTypeLong); | ||||||
889 | g_type_map.Append(ConstString("unsigned long"), eBasicTypeUnsignedLong); | ||||||
890 | g_type_map.Append(ConstString("unsigned long int"), | ||||||
891 | eBasicTypeUnsignedLong); | ||||||
892 | |||||||
893 | // "long long" | ||||||
894 | g_type_map.Append(ConstString("long long"), eBasicTypeLongLong); | ||||||
895 | g_type_map.Append(ConstString("long long int"), eBasicTypeLongLong); | ||||||
896 | g_type_map.Append(ConstString("unsigned long long"), | ||||||
897 | eBasicTypeUnsignedLongLong); | ||||||
898 | g_type_map.Append(ConstString("unsigned long long int"), | ||||||
899 | eBasicTypeUnsignedLongLong); | ||||||
900 | |||||||
901 | // "int128" | ||||||
902 | g_type_map.Append(ConstString("__int128_t"), eBasicTypeInt128); | ||||||
903 | g_type_map.Append(ConstString("__uint128_t"), eBasicTypeUnsignedInt128); | ||||||
904 | |||||||
905 | // Miscellaneous | ||||||
906 | g_type_map.Append(ConstString("bool"), eBasicTypeBool); | ||||||
907 | g_type_map.Append(ConstString("float"), eBasicTypeFloat); | ||||||
908 | g_type_map.Append(ConstString("double"), eBasicTypeDouble); | ||||||
909 | g_type_map.Append(ConstString("long double"), eBasicTypeLongDouble); | ||||||
910 | g_type_map.Append(ConstString("id"), eBasicTypeObjCID); | ||||||
911 | g_type_map.Append(ConstString("SEL"), eBasicTypeObjCSel); | ||||||
912 | g_type_map.Append(ConstString("nullptr"), eBasicTypeNullPtr); | ||||||
913 | g_type_map.Sort(); | ||||||
914 | }); | ||||||
915 | |||||||
916 | return g_type_map.Find(name, eBasicTypeInvalid); | ||||||
917 | } | ||||||
918 | return eBasicTypeInvalid; | ||||||
919 | } | ||||||
920 | |||||||
921 | uint32_t TypeSystemClang::GetPointerByteSize() { | ||||||
922 | if (m_pointer_byte_size == 0) | ||||||
923 | if (auto size = GetBasicType(lldb::eBasicTypeVoid) | ||||||
924 | .GetPointerType() | ||||||
925 | .GetByteSize(nullptr)) | ||||||
926 | m_pointer_byte_size = *size; | ||||||
927 | return m_pointer_byte_size; | ||||||
928 | } | ||||||
929 | |||||||
930 | CompilerType TypeSystemClang::GetBasicType(lldb::BasicType basic_type) { | ||||||
931 | clang::ASTContext &ast = getASTContext(); | ||||||
932 | |||||||
933 | lldb::opaque_compiler_type_t clang_type = | ||||||
934 | GetOpaqueCompilerType(&ast, basic_type); | ||||||
935 | |||||||
936 | if (clang_type) | ||||||
937 | return CompilerType(this, clang_type); | ||||||
938 | return CompilerType(); | ||||||
939 | } | ||||||
940 | |||||||
941 | CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize( | ||||||
942 | llvm::StringRef type_name, uint32_t dw_ate, uint32_t bit_size) { | ||||||
943 | ASTContext &ast = getASTContext(); | ||||||
944 | |||||||
945 | switch (dw_ate) { | ||||||
946 | default: | ||||||
947 | break; | ||||||
948 | |||||||
949 | case DW_ATE_address: | ||||||
950 | if (QualTypeMatchesBitSize(bit_size, ast, ast.VoidPtrTy)) | ||||||
951 | return GetType(ast.VoidPtrTy); | ||||||
952 | break; | ||||||
953 | |||||||
954 | case DW_ATE_boolean: | ||||||
955 | if (QualTypeMatchesBitSize(bit_size, ast, ast.BoolTy)) | ||||||
956 | return GetType(ast.BoolTy); | ||||||
957 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) | ||||||
958 | return GetType(ast.UnsignedCharTy); | ||||||
959 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) | ||||||
960 | return GetType(ast.UnsignedShortTy); | ||||||
961 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) | ||||||
962 | return GetType(ast.UnsignedIntTy); | ||||||
963 | break; | ||||||
964 | |||||||
965 | case DW_ATE_lo_user: | ||||||
966 | // This has been seen to mean DW_AT_complex_integer | ||||||
967 | if (type_name.contains("complex")) { | ||||||
968 | CompilerType complex_int_clang_type = | ||||||
969 | GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed, | ||||||
970 | bit_size / 2); | ||||||
971 | return GetType( | ||||||
972 | ast.getComplexType(ClangUtil::GetQualType(complex_int_clang_type))); | ||||||
973 | } | ||||||
974 | break; | ||||||
975 | |||||||
976 | case DW_ATE_complex_float: { | ||||||
977 | CanQualType FloatComplexTy = ast.getComplexType(ast.FloatTy); | ||||||
978 | if (QualTypeMatchesBitSize(bit_size, ast, FloatComplexTy)) | ||||||
979 | return GetType(FloatComplexTy); | ||||||
980 | |||||||
981 | CanQualType DoubleComplexTy = ast.getComplexType(ast.DoubleTy); | ||||||
982 | if (QualTypeMatchesBitSize(bit_size, ast, DoubleComplexTy)) | ||||||
983 | return GetType(DoubleComplexTy); | ||||||
984 | |||||||
985 | CanQualType LongDoubleComplexTy = ast.getComplexType(ast.LongDoubleTy); | ||||||
986 | if (QualTypeMatchesBitSize(bit_size, ast, LongDoubleComplexTy)) | ||||||
987 | return GetType(LongDoubleComplexTy); | ||||||
988 | |||||||
989 | CompilerType complex_float_clang_type = | ||||||
990 | GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float, | ||||||
991 | bit_size / 2); | ||||||
992 | return GetType( | ||||||
993 | ast.getComplexType(ClangUtil::GetQualType(complex_float_clang_type))); | ||||||
994 | } | ||||||
995 | |||||||
996 | case DW_ATE_float: | ||||||
997 | if (type_name == "float" && | ||||||
998 | QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy)) | ||||||
999 | return GetType(ast.FloatTy); | ||||||
1000 | if (type_name == "double" && | ||||||
1001 | QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy)) | ||||||
1002 | return GetType(ast.DoubleTy); | ||||||
1003 | if (type_name == "long double" && | ||||||
1004 | QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy)) | ||||||
1005 | return GetType(ast.LongDoubleTy); | ||||||
1006 | // Fall back to not requiring a name match | ||||||
1007 | if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy)) | ||||||
1008 | return GetType(ast.FloatTy); | ||||||
1009 | if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleTy)) | ||||||
1010 | return GetType(ast.DoubleTy); | ||||||
1011 | if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy)) | ||||||
1012 | return GetType(ast.LongDoubleTy); | ||||||
1013 | if (QualTypeMatchesBitSize(bit_size, ast, ast.HalfTy)) | ||||||
1014 | return GetType(ast.HalfTy); | ||||||
1015 | break; | ||||||
1016 | |||||||
1017 | case DW_ATE_signed: | ||||||
1018 | if (!type_name.empty()) { | ||||||
1019 | if (type_name == "wchar_t" && | ||||||
1020 | QualTypeMatchesBitSize(bit_size, ast, ast.WCharTy) && | ||||||
1021 | (getTargetInfo() && | ||||||
1022 | TargetInfo::isTypeSigned(getTargetInfo()->getWCharType()))) | ||||||
1023 | return GetType(ast.WCharTy); | ||||||
1024 | if (type_name == "void" && | ||||||
1025 | QualTypeMatchesBitSize(bit_size, ast, ast.VoidTy)) | ||||||
1026 | return GetType(ast.VoidTy); | ||||||
1027 | if (type_name.contains("long long") && | ||||||
1028 | QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy)) | ||||||
1029 | return GetType(ast.LongLongTy); | ||||||
1030 | if (type_name.contains("long") && | ||||||
1031 | QualTypeMatchesBitSize(bit_size, ast, ast.LongTy)) | ||||||
1032 | return GetType(ast.LongTy); | ||||||
1033 | if (type_name.contains("short") && | ||||||
1034 | QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy)) | ||||||
1035 | return GetType(ast.ShortTy); | ||||||
1036 | if (type_name.contains("char")) { | ||||||
1037 | if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) | ||||||
1038 | return GetType(ast.CharTy); | ||||||
1039 | if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy)) | ||||||
1040 | return GetType(ast.SignedCharTy); | ||||||
1041 | } | ||||||
1042 | if (type_name.contains("int")) { | ||||||
1043 | if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy)) | ||||||
1044 | return GetType(ast.IntTy); | ||||||
1045 | if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty)) | ||||||
1046 | return GetType(ast.Int128Ty); | ||||||
1047 | } | ||||||
1048 | } | ||||||
1049 | // We weren't able to match up a type name, just search by size | ||||||
1050 | if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) | ||||||
1051 | return GetType(ast.CharTy); | ||||||
1052 | if (QualTypeMatchesBitSize(bit_size, ast, ast.ShortTy)) | ||||||
1053 | return GetType(ast.ShortTy); | ||||||
1054 | if (QualTypeMatchesBitSize(bit_size, ast, ast.IntTy)) | ||||||
1055 | return GetType(ast.IntTy); | ||||||
1056 | if (QualTypeMatchesBitSize(bit_size, ast, ast.LongTy)) | ||||||
1057 | return GetType(ast.LongTy); | ||||||
1058 | if (QualTypeMatchesBitSize(bit_size, ast, ast.LongLongTy)) | ||||||
1059 | return GetType(ast.LongLongTy); | ||||||
1060 | if (QualTypeMatchesBitSize(bit_size, ast, ast.Int128Ty)) | ||||||
1061 | return GetType(ast.Int128Ty); | ||||||
1062 | break; | ||||||
1063 | |||||||
1064 | case DW_ATE_signed_char: | ||||||
1065 | if (ast.getLangOpts().CharIsSigned && type_name == "char") { | ||||||
1066 | if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) | ||||||
1067 | return GetType(ast.CharTy); | ||||||
1068 | } | ||||||
1069 | if (QualTypeMatchesBitSize(bit_size, ast, ast.SignedCharTy)) | ||||||
1070 | return GetType(ast.SignedCharTy); | ||||||
1071 | break; | ||||||
1072 | |||||||
1073 | case DW_ATE_unsigned: | ||||||
1074 | if (!type_name.empty()) { | ||||||
1075 | if (type_name == "wchar_t") { | ||||||
1076 | if (QualTypeMatchesBitSize(bit_size, ast, ast.WCharTy)) { | ||||||
1077 | if (!(getTargetInfo() && | ||||||
1078 | TargetInfo::isTypeSigned(getTargetInfo()->getWCharType()))) | ||||||
1079 | return GetType(ast.WCharTy); | ||||||
1080 | } | ||||||
1081 | } | ||||||
1082 | if (type_name.contains("long long")) { | ||||||
1083 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy)) | ||||||
1084 | return GetType(ast.UnsignedLongLongTy); | ||||||
1085 | } else if (type_name.contains("long")) { | ||||||
1086 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy)) | ||||||
1087 | return GetType(ast.UnsignedLongTy); | ||||||
1088 | } else if (type_name.contains("short")) { | ||||||
1089 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) | ||||||
1090 | return GetType(ast.UnsignedShortTy); | ||||||
1091 | } else if (type_name.contains("char")) { | ||||||
1092 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) | ||||||
1093 | return GetType(ast.UnsignedCharTy); | ||||||
1094 | } else if (type_name.contains("int")) { | ||||||
1095 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) | ||||||
1096 | return GetType(ast.UnsignedIntTy); | ||||||
1097 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty)) | ||||||
1098 | return GetType(ast.UnsignedInt128Ty); | ||||||
1099 | } | ||||||
1100 | } | ||||||
1101 | // We weren't able to match up a type name, just search by size | ||||||
1102 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) | ||||||
1103 | return GetType(ast.UnsignedCharTy); | ||||||
1104 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) | ||||||
1105 | return GetType(ast.UnsignedShortTy); | ||||||
1106 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedIntTy)) | ||||||
1107 | return GetType(ast.UnsignedIntTy); | ||||||
1108 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongTy)) | ||||||
1109 | return GetType(ast.UnsignedLongTy); | ||||||
1110 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedLongLongTy)) | ||||||
1111 | return GetType(ast.UnsignedLongLongTy); | ||||||
1112 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedInt128Ty)) | ||||||
1113 | return GetType(ast.UnsignedInt128Ty); | ||||||
1114 | break; | ||||||
1115 | |||||||
1116 | case DW_ATE_unsigned_char: | ||||||
1117 | if (!ast.getLangOpts().CharIsSigned && type_name == "char") { | ||||||
1118 | if (QualTypeMatchesBitSize(bit_size, ast, ast.CharTy)) | ||||||
1119 | return GetType(ast.CharTy); | ||||||
1120 | } | ||||||
1121 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedCharTy)) | ||||||
1122 | return GetType(ast.UnsignedCharTy); | ||||||
1123 | if (QualTypeMatchesBitSize(bit_size, ast, ast.UnsignedShortTy)) | ||||||
1124 | return GetType(ast.UnsignedShortTy); | ||||||
1125 | break; | ||||||
1126 | |||||||
1127 | case DW_ATE_imaginary_float: | ||||||
1128 | break; | ||||||
1129 | |||||||
1130 | case DW_ATE_UTF: | ||||||
1131 | switch (bit_size) { | ||||||
1132 | case 8: | ||||||
1133 | return GetType(ast.Char8Ty); | ||||||
1134 | case 16: | ||||||
1135 | return GetType(ast.Char16Ty); | ||||||
1136 | case 32: | ||||||
1137 | return GetType(ast.Char32Ty); | ||||||
1138 | default: | ||||||
1139 | if (!type_name.empty()) { | ||||||
1140 | if (type_name == "char16_t") | ||||||
1141 | return GetType(ast.Char16Ty); | ||||||
1142 | if (type_name == "char32_t") | ||||||
1143 | return GetType(ast.Char32Ty); | ||||||
1144 | if (type_name == "char8_t") | ||||||
1145 | return GetType(ast.Char8Ty); | ||||||
1146 | } | ||||||
1147 | } | ||||||
1148 | break; | ||||||
1149 | } | ||||||
1150 | |||||||
1151 | Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES::lldb_private::LLDBLog::Types); | ||||||
1152 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , __func__, "error: need to add support for DW_TAG_base_type '{0}' " "encoded with DW_ATE = {1:x}, bit_size = {2}", type_name, dw_ate , bit_size); } while (0) | ||||||
1153 | "error: need to add support for DW_TAG_base_type '{0}' "do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , __func__, "error: need to add support for DW_TAG_base_type '{0}' " "encoded with DW_ATE = {1:x}, bit_size = {2}", type_name, dw_ate , bit_size); } while (0) | ||||||
1154 | "encoded with DW_ATE = {1:x}, bit_size = {2}",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , __func__, "error: need to add support for DW_TAG_base_type '{0}' " "encoded with DW_ATE = {1:x}, bit_size = {2}", type_name, dw_ate , bit_size); } while (0) | ||||||
1155 | type_name, dw_ate, bit_size)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , __func__, "error: need to add support for DW_TAG_base_type '{0}' " "encoded with DW_ATE = {1:x}, bit_size = {2}", type_name, dw_ate , bit_size); } while (0); | ||||||
1156 | return CompilerType(); | ||||||
1157 | } | ||||||
1158 | |||||||
1159 | CompilerType TypeSystemClang::GetCStringType(bool is_const) { | ||||||
1160 | ASTContext &ast = getASTContext(); | ||||||
1161 | QualType char_type(ast.CharTy); | ||||||
1162 | |||||||
1163 | if (is_const) | ||||||
1164 | char_type.addConst(); | ||||||
1165 | |||||||
1166 | return GetType(ast.getPointerType(char_type)); | ||||||
1167 | } | ||||||
1168 | |||||||
1169 | bool TypeSystemClang::AreTypesSame(CompilerType type1, CompilerType type2, | ||||||
1170 | bool ignore_qualifiers) { | ||||||
1171 | TypeSystemClang *ast = | ||||||
1172 | llvm::dyn_cast_or_null<TypeSystemClang>(type1.GetTypeSystem()); | ||||||
1173 | if (!ast || ast != type2.GetTypeSystem()) | ||||||
1174 | return false; | ||||||
1175 | |||||||
1176 | if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType()) | ||||||
1177 | return true; | ||||||
1178 | |||||||
1179 | QualType type1_qual = ClangUtil::GetQualType(type1); | ||||||
1180 | QualType type2_qual = ClangUtil::GetQualType(type2); | ||||||
1181 | |||||||
1182 | if (ignore_qualifiers) { | ||||||
1183 | type1_qual = type1_qual.getUnqualifiedType(); | ||||||
1184 | type2_qual = type2_qual.getUnqualifiedType(); | ||||||
1185 | } | ||||||
1186 | |||||||
1187 | return ast->getASTContext().hasSameType(type1_qual, type2_qual); | ||||||
1188 | } | ||||||
1189 | |||||||
1190 | CompilerType TypeSystemClang::GetTypeForDecl(void *opaque_decl) { | ||||||
1191 | if (!opaque_decl) | ||||||
1192 | return CompilerType(); | ||||||
1193 | |||||||
1194 | clang::Decl *decl = static_cast<clang::Decl *>(opaque_decl); | ||||||
1195 | if (auto *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl)) | ||||||
1196 | return GetTypeForDecl(named_decl); | ||||||
1197 | return CompilerType(); | ||||||
1198 | } | ||||||
1199 | |||||||
1200 | CompilerDeclContext TypeSystemClang::CreateDeclContext(DeclContext *ctx) { | ||||||
1201 | // Check that the DeclContext actually belongs to this ASTContext. | ||||||
1202 | assert(&ctx->getParentASTContext() == &getASTContext())(static_cast <bool> (&ctx->getParentASTContext() == &getASTContext()) ? void (0) : __assert_fail ("&ctx->getParentASTContext() == &getASTContext()" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 1202, __extension__ __PRETTY_FUNCTION__)); | ||||||
1203 | return CompilerDeclContext(this, ctx); | ||||||
1204 | } | ||||||
1205 | |||||||
1206 | CompilerType TypeSystemClang::GetTypeForDecl(clang::NamedDecl *decl) { | ||||||
1207 | if (clang::ObjCInterfaceDecl *interface_decl = | ||||||
1208 | llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) | ||||||
1209 | return GetTypeForDecl(interface_decl); | ||||||
1210 | if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) | ||||||
1211 | return GetTypeForDecl(tag_decl); | ||||||
1212 | return CompilerType(); | ||||||
1213 | } | ||||||
1214 | |||||||
1215 | CompilerType TypeSystemClang::GetTypeForDecl(TagDecl *decl) { | ||||||
1216 | return GetType(getASTContext().getTagDeclType(decl)); | ||||||
1217 | } | ||||||
1218 | |||||||
1219 | CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) { | ||||||
1220 | return GetType(getASTContext().getObjCInterfaceType(decl)); | ||||||
1221 | } | ||||||
1222 | |||||||
1223 | #pragma mark Structure, Unions, Classes | ||||||
1224 | |||||||
1225 | void TypeSystemClang::SetOwningModule(clang::Decl *decl, | ||||||
1226 | OptionalClangModuleID owning_module) { | ||||||
1227 | if (!decl || !owning_module.HasValue()) | ||||||
1228 | return; | ||||||
1229 | |||||||
1230 | decl->setFromASTFile(); | ||||||
1231 | decl->setOwningModuleID(owning_module.GetValue()); | ||||||
1232 | decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible); | ||||||
1233 | } | ||||||
1234 | |||||||
1235 | OptionalClangModuleID | ||||||
1236 | TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name, | ||||||
1237 | OptionalClangModuleID parent, | ||||||
1238 | bool is_framework, bool is_explicit) { | ||||||
1239 | // Get the external AST source which holds the modules. | ||||||
1240 | auto *ast_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>( | ||||||
1241 | getASTContext().getExternalSource()); | ||||||
1242 | assert(ast_source && "external ast source was lost")(static_cast <bool> (ast_source && "external ast source was lost" ) ? void (0) : __assert_fail ("ast_source && \"external ast source was lost\"" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 1242, __extension__ __PRETTY_FUNCTION__)); | ||||||
1243 | if (!ast_source) | ||||||
1244 | return {}; | ||||||
1245 | |||||||
1246 | // Lazily initialize the module map. | ||||||
1247 | if (!m_header_search_up) { | ||||||
1248 | auto HSOpts = std::make_shared<clang::HeaderSearchOptions>(); | ||||||
1249 | m_header_search_up = std::make_unique<clang::HeaderSearch>( | ||||||
1250 | HSOpts, *m_source_manager_up, *m_diagnostics_engine_up, | ||||||
1251 | *m_language_options_up, m_target_info_up.get()); | ||||||
1252 | m_module_map_up = std::make_unique<clang::ModuleMap>( | ||||||
1253 | *m_source_manager_up, *m_diagnostics_engine_up, *m_language_options_up, | ||||||
1254 | m_target_info_up.get(), *m_header_search_up); | ||||||
1255 | } | ||||||
1256 | |||||||
1257 | // Get or create the module context. | ||||||
1258 | bool created; | ||||||
1259 | clang::Module *module; | ||||||
1260 | auto parent_desc = ast_source->getSourceDescriptor(parent.GetValue()); | ||||||
1261 | std::tie(module, created) = m_module_map_up->findOrCreateModule( | ||||||
1262 | name, parent_desc ? parent_desc->getModuleOrNull() : nullptr, | ||||||
1263 | is_framework, is_explicit); | ||||||
1264 | if (!created) | ||||||
1265 | return ast_source->GetIDForModule(module); | ||||||
1266 | |||||||
1267 | return ast_source->RegisterModule(module); | ||||||
1268 | } | ||||||
1269 | |||||||
1270 | CompilerType TypeSystemClang::CreateRecordType( | ||||||
1271 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, | ||||||
1272 | AccessType access_type, llvm::StringRef name, int kind, | ||||||
1273 | LanguageType language, ClangASTMetadata *metadata, bool exports_symbols) { | ||||||
1274 | ASTContext &ast = getASTContext(); | ||||||
1275 | |||||||
1276 | if (decl_ctx == nullptr) | ||||||
1277 | decl_ctx = ast.getTranslationUnitDecl(); | ||||||
1278 | |||||||
1279 | if (language == eLanguageTypeObjC || | ||||||
1280 | language == eLanguageTypeObjC_plus_plus) { | ||||||
1281 | bool isForwardDecl = true; | ||||||
1282 | bool isInternal = false; | ||||||
1283 | return CreateObjCClass(name, decl_ctx, owning_module, isForwardDecl, | ||||||
1284 | isInternal, metadata); | ||||||
1285 | } | ||||||
1286 | |||||||
1287 | // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and | ||||||
1288 | // we will need to update this code. I was told to currently always use the | ||||||
1289 | // CXXRecordDecl class since we often don't know from debug information if | ||||||
1290 | // something is struct or a class, so we default to always use the more | ||||||
1291 | // complete definition just in case. | ||||||
1292 | |||||||
1293 | bool has_name = !name.empty(); | ||||||
1294 | CXXRecordDecl *decl = CXXRecordDecl::CreateDeserialized(ast, 0); | ||||||
1295 | decl->setTagKind(static_cast<TagDecl::TagKind>(kind)); | ||||||
1296 | decl->setDeclContext(decl_ctx); | ||||||
1297 | if (has_name) | ||||||
1298 | decl->setDeclName(&ast.Idents.get(name)); | ||||||
1299 | SetOwningModule(decl, owning_module); | ||||||
1300 | |||||||
1301 | if (!has_name) { | ||||||
1302 | // In C++ a lambda is also represented as an unnamed class. This is | ||||||
1303 | // different from an *anonymous class* that the user wrote: | ||||||
1304 | // | ||||||
1305 | // struct A { | ||||||
1306 | // // anonymous class (GNU/MSVC extension) | ||||||
1307 | // struct { | ||||||
1308 | // int x; | ||||||
1309 | // }; | ||||||
1310 | // // unnamed class within a class | ||||||
1311 | // struct { | ||||||
1312 | // int y; | ||||||
1313 | // } B; | ||||||
1314 | // }; | ||||||
1315 | // | ||||||
1316 | // void f() { | ||||||
1317 | // // unammed class outside of a class | ||||||
1318 | // struct { | ||||||
1319 | // int z; | ||||||
1320 | // } C; | ||||||
1321 | // } | ||||||
1322 | // | ||||||
1323 | // Anonymous classes is a GNU/MSVC extension that clang supports. It | ||||||
1324 | // requires the anonymous class be embedded within a class. So the new | ||||||
1325 | // heuristic verifies this condition. | ||||||
1326 | if (isa<CXXRecordDecl>(decl_ctx) && exports_symbols) | ||||||
1327 | decl->setAnonymousStructOrUnion(true); | ||||||
1328 | } | ||||||
1329 | |||||||
1330 | if (metadata) | ||||||
1331 | SetMetadata(decl, *metadata); | ||||||
1332 | |||||||
1333 | if (access_type != eAccessNone) | ||||||
1334 | decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type)); | ||||||
1335 | |||||||
1336 | if (decl_ctx) | ||||||
1337 | decl_ctx->addDecl(decl); | ||||||
1338 | |||||||
1339 | return GetType(ast.getTagDeclType(decl)); | ||||||
1340 | } | ||||||
1341 | |||||||
1342 | namespace { | ||||||
1343 | /// Returns true iff the given TemplateArgument should be represented as an | ||||||
1344 | /// NonTypeTemplateParmDecl in the AST. | ||||||
1345 | bool IsValueParam(const clang::TemplateArgument &argument) { | ||||||
1346 | return argument.getKind() == TemplateArgument::Integral; | ||||||
1347 | } | ||||||
1348 | |||||||
1349 | void AddAccessSpecifierDecl(clang::CXXRecordDecl *cxx_record_decl, | ||||||
1350 | ASTContext &ct, | ||||||
1351 | clang::AccessSpecifier previous_access, | ||||||
1352 | clang::AccessSpecifier access_specifier) { | ||||||
1353 | if (!cxx_record_decl->isClass() && !cxx_record_decl->isStruct()) | ||||||
1354 | return; | ||||||
1355 | if (previous_access != access_specifier) { | ||||||
1356 | // For struct, don't add AS_public if it's the first AccessSpecDecl. | ||||||
1357 | // For class, don't add AS_private if it's the first AccessSpecDecl. | ||||||
1358 | if ((cxx_record_decl->isStruct() && | ||||||
1359 | previous_access == clang::AccessSpecifier::AS_none && | ||||||
1360 | access_specifier == clang::AccessSpecifier::AS_public) || | ||||||
1361 | (cxx_record_decl->isClass() && | ||||||
1362 | previous_access == clang::AccessSpecifier::AS_none && | ||||||
1363 | access_specifier == clang::AccessSpecifier::AS_private)) { | ||||||
1364 | return; | ||||||
1365 | } | ||||||
1366 | cxx_record_decl->addDecl( | ||||||
1367 | AccessSpecDecl::Create(ct, access_specifier, cxx_record_decl, | ||||||
1368 | SourceLocation(), SourceLocation())); | ||||||
1369 | } | ||||||
1370 | } | ||||||
1371 | } // namespace | ||||||
1372 | |||||||
1373 | static TemplateParameterList *CreateTemplateParameterList( | ||||||
1374 | ASTContext &ast, | ||||||
1375 | const TypeSystemClang::TemplateParameterInfos &template_param_infos, | ||||||
1376 | llvm::SmallVector<NamedDecl *, 8> &template_param_decls) { | ||||||
1377 | const bool parameter_pack = false; | ||||||
1378 | const bool is_typename = false; | ||||||
1379 | const unsigned depth = 0; | ||||||
1380 | const size_t num_template_params = template_param_infos.args.size(); | ||||||
1381 | DeclContext *const decl_context = | ||||||
1382 | ast.getTranslationUnitDecl(); // Is this the right decl context?, | ||||||
1383 | for (size_t i = 0; i < num_template_params; ++i) { | ||||||
1384 | const char *name = template_param_infos.names[i]; | ||||||
1385 | |||||||
1386 | IdentifierInfo *identifier_info = nullptr; | ||||||
1387 | if (name && name[0]) | ||||||
1388 | identifier_info = &ast.Idents.get(name); | ||||||
1389 | if (IsValueParam(template_param_infos.args[i])) { | ||||||
1390 | QualType template_param_type = | ||||||
1391 | template_param_infos.args[i].getIntegralType(); | ||||||
1392 | template_param_decls.push_back(NonTypeTemplateParmDecl::Create( | ||||||
1393 | ast, decl_context, SourceLocation(), SourceLocation(), depth, i, | ||||||
1394 | identifier_info, template_param_type, parameter_pack, | ||||||
1395 | ast.getTrivialTypeSourceInfo(template_param_type))); | ||||||
1396 | } else { | ||||||
1397 | template_param_decls.push_back(TemplateTypeParmDecl::Create( | ||||||
1398 | ast, decl_context, SourceLocation(), SourceLocation(), depth, i, | ||||||
1399 | identifier_info, is_typename, parameter_pack)); | ||||||
1400 | } | ||||||
1401 | } | ||||||
1402 | |||||||
1403 | if (template_param_infos.packed_args) { | ||||||
1404 | IdentifierInfo *identifier_info = nullptr; | ||||||
1405 | if (template_param_infos.pack_name && template_param_infos.pack_name[0]) | ||||||
1406 | identifier_info = &ast.Idents.get(template_param_infos.pack_name); | ||||||
1407 | const bool parameter_pack_true = true; | ||||||
1408 | |||||||
1409 | if (!template_param_infos.packed_args->args.empty() && | ||||||
1410 | IsValueParam(template_param_infos.packed_args->args[0])) { | ||||||
1411 | QualType template_param_type = | ||||||
1412 | template_param_infos.packed_args->args[0].getIntegralType(); | ||||||
1413 | template_param_decls.push_back(NonTypeTemplateParmDecl::Create( | ||||||
1414 | ast, decl_context, SourceLocation(), SourceLocation(), depth, | ||||||
1415 | num_template_params, identifier_info, template_param_type, | ||||||
1416 | parameter_pack_true, | ||||||
1417 | ast.getTrivialTypeSourceInfo(template_param_type))); | ||||||
1418 | } else { | ||||||
1419 | template_param_decls.push_back(TemplateTypeParmDecl::Create( | ||||||
1420 | ast, decl_context, SourceLocation(), SourceLocation(), depth, | ||||||
1421 | num_template_params, identifier_info, is_typename, | ||||||
1422 | parameter_pack_true)); | ||||||
1423 | } | ||||||
1424 | } | ||||||
1425 | clang::Expr *const requires_clause = nullptr; // TODO: Concepts | ||||||
1426 | TemplateParameterList *template_param_list = TemplateParameterList::Create( | ||||||
1427 | ast, SourceLocation(), SourceLocation(), template_param_decls, | ||||||
1428 | SourceLocation(), requires_clause); | ||||||
1429 | return template_param_list; | ||||||
1430 | } | ||||||
1431 | |||||||
1432 | clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( | ||||||
1433 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, | ||||||
1434 | clang::FunctionDecl *func_decl, | ||||||
1435 | const TemplateParameterInfos &template_param_infos) { | ||||||
1436 | // /// Create a function template node. | ||||||
1437 | ASTContext &ast = getASTContext(); | ||||||
1438 | |||||||
1439 | llvm::SmallVector<NamedDecl *, 8> template_param_decls; | ||||||
1440 | TemplateParameterList *template_param_list = CreateTemplateParameterList( | ||||||
1441 | ast, template_param_infos, template_param_decls); | ||||||
1442 | FunctionTemplateDecl *func_tmpl_decl = | ||||||
1443 | FunctionTemplateDecl::CreateDeserialized(ast, 0); | ||||||
1444 | func_tmpl_decl->setDeclContext(decl_ctx); | ||||||
1445 | func_tmpl_decl->setLocation(func_decl->getLocation()); | ||||||
1446 | func_tmpl_decl->setDeclName(func_decl->getDeclName()); | ||||||
1447 | func_tmpl_decl->init(func_decl, template_param_list); | ||||||
1448 | SetOwningModule(func_tmpl_decl, owning_module); | ||||||
1449 | |||||||
1450 | for (size_t i = 0, template_param_decl_count = template_param_decls.size(); | ||||||
1451 | i < template_param_decl_count; ++i) { | ||||||
1452 | // TODO: verify which decl context we should put template_param_decls into.. | ||||||
1453 | template_param_decls[i]->setDeclContext(func_decl); | ||||||
1454 | } | ||||||
1455 | // Function templates inside a record need to have an access specifier. | ||||||
1456 | // It doesn't matter what access specifier we give the template as LLDB | ||||||
1457 | // anyway allows accessing everything inside a record. | ||||||
1458 | if (decl_ctx->isRecord()) | ||||||
1459 | func_tmpl_decl->setAccess(clang::AccessSpecifier::AS_public); | ||||||
1460 | |||||||
1461 | return func_tmpl_decl; | ||||||
1462 | } | ||||||
1463 | |||||||
1464 | void TypeSystemClang::CreateFunctionTemplateSpecializationInfo( | ||||||
1465 | FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl, | ||||||
1466 | const TemplateParameterInfos &infos) { | ||||||
1467 | TemplateArgumentList *template_args_ptr = | ||||||
1468 | TemplateArgumentList::CreateCopy(func_decl->getASTContext(), infos.args); | ||||||
1469 | |||||||
1470 | func_decl->setFunctionTemplateSpecialization(func_tmpl_decl, | ||||||
1471 | template_args_ptr, nullptr); | ||||||
1472 | } | ||||||
1473 | |||||||
1474 | /// Returns true if the given template parameter can represent the given value. | ||||||
1475 | /// For example, `typename T` can represent `int` but not integral values such | ||||||
1476 | /// as `int I = 3`. | ||||||
1477 | static bool TemplateParameterAllowsValue(NamedDecl *param, | ||||||
1478 | const TemplateArgument &value) { | ||||||
1479 | if (llvm::isa<TemplateTypeParmDecl>(param)) { | ||||||
1480 | // Compare the argument kind, i.e. ensure that <typename> != <int>. | ||||||
1481 | if (value.getKind() != TemplateArgument::Type) | ||||||
1482 | return false; | ||||||
1483 | } else if (auto *type_param = | ||||||
1484 | llvm::dyn_cast<NonTypeTemplateParmDecl>(param)) { | ||||||
1485 | // Compare the argument kind, i.e. ensure that <typename> != <int>. | ||||||
1486 | if (!IsValueParam(value)) | ||||||
1487 | return false; | ||||||
1488 | // Compare the integral type, i.e. ensure that <int> != <char>. | ||||||
1489 | if (type_param->getType() != value.getIntegralType()) | ||||||
1490 | return false; | ||||||
1491 | } else { | ||||||
1492 | // There is no way to create other parameter decls at the moment, so we | ||||||
1493 | // can't reach this case during normal LLDB usage. Log that this happened | ||||||
1494 | // and assert. | ||||||
1495 | Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS::lldb_private::LLDBLog::Expressions); | ||||||
1496 | LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , __func__, "Don't know how to compare template parameter to passed" " value. Decl kind of parameter is: {0}", param->getDeclKindName ()); } while (0) | ||||||
1497 | "Don't know how to compare template parameter to passed"do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , __func__, "Don't know how to compare template parameter to passed" " value. Decl kind of parameter is: {0}", param->getDeclKindName ()); } while (0) | ||||||
1498 | " value. Decl kind of parameter is: {0}",do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , __func__, "Don't know how to compare template parameter to passed" " value. Decl kind of parameter is: {0}", param->getDeclKindName ()); } while (0) | ||||||
1499 | param->getDeclKindName())do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Format("lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , __func__, "Don't know how to compare template parameter to passed" " value. Decl kind of parameter is: {0}", param->getDeclKindName ()); } while (0); | ||||||
1500 | lldbassert(false && "Can't compare this TemplateParmDecl subclass")lldb_private::lldb_assert(static_cast<bool>(false && "Can't compare this TemplateParmDecl subclass"), "false && \"Can't compare this TemplateParmDecl subclass\"" , __FUNCTION__, "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 1500); | ||||||
1501 | // In release builds just fall back to marking the parameter as not | ||||||
1502 | // accepting the value so that we don't try to fit an instantiation to a | ||||||
1503 | // template that doesn't fit. E.g., avoid that `S<1>` is being connected to | ||||||
1504 | // `template<typename T> struct S;`. | ||||||
1505 | return false; | ||||||
1506 | } | ||||||
1507 | return true; | ||||||
1508 | } | ||||||
1509 | |||||||
1510 | /// Returns true if the given class template declaration could produce an | ||||||
1511 | /// instantiation with the specified values. | ||||||
1512 | /// For example, `<typename T>` allows the arguments `float`, but not for | ||||||
1513 | /// example `bool, float` or `3` (as an integer parameter value). | ||||||
1514 | static bool ClassTemplateAllowsToInstantiationArgs( | ||||||
1515 | ClassTemplateDecl *class_template_decl, | ||||||
1516 | const TypeSystemClang::TemplateParameterInfos &instantiation_values) { | ||||||
1517 | |||||||
1518 | TemplateParameterList ¶ms = *class_template_decl->getTemplateParameters(); | ||||||
1519 | |||||||
1520 | // Save some work by iterating only once over the found parameters and | ||||||
1521 | // calculate the information related to parameter packs. | ||||||
1522 | |||||||
1523 | // Contains the first pack parameter (or non if there are none). | ||||||
1524 | llvm::Optional<NamedDecl *> pack_parameter; | ||||||
1525 | // Contains the number of non-pack parameters. | ||||||
1526 | size_t non_pack_params = params.size(); | ||||||
1527 | for (size_t i = 0; i < params.size(); ++i) { | ||||||
1528 | NamedDecl *param = params.getParam(i); | ||||||
1529 | if (param->isParameterPack()) { | ||||||
1530 | pack_parameter = param; | ||||||
1531 | non_pack_params = i; | ||||||
1532 | break; | ||||||
1533 | } | ||||||
1534 | } | ||||||
1535 | |||||||
1536 | // The found template needs to have compatible non-pack template arguments. | ||||||
1537 | // E.g., ensure that <typename, typename> != <typename>. | ||||||
1538 | // The pack parameters are compared later. | ||||||
1539 | if (non_pack_params != instantiation_values.args.size()) | ||||||
1540 | return false; | ||||||
1541 | |||||||
1542 | // Ensure that <typename...> != <typename>. | ||||||
1543 | if (pack_parameter.hasValue() != instantiation_values.hasParameterPack()) | ||||||
1544 | return false; | ||||||
1545 | |||||||
1546 | // Compare the first pack parameter that was found with the first pack | ||||||
1547 | // parameter value. The special case of having an empty parameter pack value | ||||||
1548 | // always fits to a pack parameter. | ||||||
1549 | // E.g., ensure that <int...> != <typename...>. | ||||||
1550 | if (pack_parameter && !instantiation_values.packed_args->args.empty() && | ||||||
1551 | !TemplateParameterAllowsValue( | ||||||
1552 | *pack_parameter, instantiation_values.packed_args->args.front())) | ||||||
1553 | return false; | ||||||
1554 | |||||||
1555 | // Compare all the non-pack parameters now. | ||||||
1556 | // E.g., ensure that <int> != <long>. | ||||||
1557 | for (const auto pair : llvm::zip_first(instantiation_values.args, params)) { | ||||||
1558 | const TemplateArgument &passed_arg = std::get<0>(pair); | ||||||
1559 | NamedDecl *found_param = std::get<1>(pair); | ||||||
1560 | if (!TemplateParameterAllowsValue(found_param, passed_arg)) | ||||||
1561 | return false; | ||||||
1562 | } | ||||||
1563 | |||||||
1564 | return class_template_decl; | ||||||
1565 | } | ||||||
1566 | |||||||
1567 | ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( | ||||||
1568 | DeclContext *decl_ctx, OptionalClangModuleID owning_module, | ||||||
1569 | lldb::AccessType access_type, llvm::StringRef class_name, int kind, | ||||||
1570 | const TemplateParameterInfos &template_param_infos) { | ||||||
1571 | ASTContext &ast = getASTContext(); | ||||||
1572 | |||||||
1573 | ClassTemplateDecl *class_template_decl = nullptr; | ||||||
1574 | if (decl_ctx == nullptr) | ||||||
1575 | decl_ctx = ast.getTranslationUnitDecl(); | ||||||
1576 | |||||||
1577 | IdentifierInfo &identifier_info = ast.Idents.get(class_name); | ||||||
1578 | DeclarationName decl_name(&identifier_info); | ||||||
1579 | |||||||
1580 | // Search the AST for an existing ClassTemplateDecl that could be reused. | ||||||
1581 | clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); | ||||||
1582 | for (NamedDecl *decl : result) { | ||||||
1583 | class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl); | ||||||
1584 | if (!class_template_decl) | ||||||
1585 | continue; | ||||||
1586 | // The class template has to be able to represents the instantiation | ||||||
1587 | // values we received. Without this we might end up putting an instantiation | ||||||
1588 | // with arguments such as <int, int> to a template such as: | ||||||
1589 | // template<typename T> struct S; | ||||||
1590 | // Connecting the instantiation to an incompatible template could cause | ||||||
1591 | // problems later on. | ||||||
1592 | if (!ClassTemplateAllowsToInstantiationArgs(class_template_decl, | ||||||
1593 | template_param_infos)) | ||||||
1594 | continue; | ||||||
1595 | return class_template_decl; | ||||||
1596 | } | ||||||
1597 | |||||||
1598 | llvm::SmallVector<NamedDecl *, 8> template_param_decls; | ||||||
1599 | |||||||
1600 | TemplateParameterList *template_param_list = CreateTemplateParameterList( | ||||||
1601 | ast, template_param_infos, template_param_decls); | ||||||
1602 | |||||||
1603 | CXXRecordDecl *template_cxx_decl = CXXRecordDecl::CreateDeserialized(ast, 0); | ||||||
1604 | template_cxx_decl->setTagKind(static_cast<TagDecl::TagKind>(kind)); | ||||||
1605 | // What decl context do we use here? TU? The actual decl context? | ||||||
1606 | template_cxx_decl->setDeclContext(decl_ctx); | ||||||
1607 | template_cxx_decl->setDeclName(decl_name); | ||||||
1608 | SetOwningModule(template_cxx_decl, owning_module); | ||||||
1609 | |||||||
1610 | for (size_t i = 0, template_param_decl_count = template_param_decls.size(); | ||||||
1611 | i < template_param_decl_count; ++i) { | ||||||
1612 | template_param_decls[i]->setDeclContext(template_cxx_decl); | ||||||
1613 | } | ||||||
1614 | |||||||
1615 | // With templated classes, we say that a class is templated with | ||||||
1616 | // specializations, but that the bare class has no functions. | ||||||
1617 | // template_cxx_decl->startDefinition(); | ||||||
1618 | // template_cxx_decl->completeDefinition(); | ||||||
1619 | |||||||
1620 | class_template_decl = ClassTemplateDecl::CreateDeserialized(ast, 0); | ||||||
1621 | // What decl context do we use here? TU? The actual decl context? | ||||||
1622 | class_template_decl->setDeclContext(decl_ctx); | ||||||
1623 | class_template_decl->setDeclName(decl_name); | ||||||
1624 | class_template_decl->init(template_cxx_decl, template_param_list); | ||||||
1625 | template_cxx_decl->setDescribedClassTemplate(class_template_decl); | ||||||
1626 | SetOwningModule(class_template_decl, owning_module); | ||||||
1627 | |||||||
1628 | if (access_type != eAccessNone) | ||||||
1629 | class_template_decl->setAccess( | ||||||
1630 | ConvertAccessTypeToAccessSpecifier(access_type)); | ||||||
1631 | |||||||
1632 | decl_ctx->addDecl(class_template_decl); | ||||||
1633 | |||||||
1634 | VerifyDecl(class_template_decl); | ||||||
1635 | |||||||
1636 | return class_template_decl; | ||||||
1637 | } | ||||||
1638 | |||||||
1639 | TemplateTemplateParmDecl * | ||||||
1640 | TypeSystemClang::CreateTemplateTemplateParmDecl(const char *template_name) { | ||||||
1641 | ASTContext &ast = getASTContext(); | ||||||
1642 | |||||||
1643 | auto *decl_ctx = ast.getTranslationUnitDecl(); | ||||||
1644 | |||||||
1645 | IdentifierInfo &identifier_info = ast.Idents.get(template_name); | ||||||
1646 | llvm::SmallVector<NamedDecl *, 8> template_param_decls; | ||||||
1647 | |||||||
1648 | TypeSystemClang::TemplateParameterInfos template_param_infos; | ||||||
1649 | TemplateParameterList *template_param_list = CreateTemplateParameterList( | ||||||
1650 | ast, template_param_infos, template_param_decls); | ||||||
1651 | |||||||
1652 | // LLDB needs to create those decls only to be able to display a | ||||||
1653 | // type that includes a template template argument. Only the name matters for | ||||||
1654 | // this purpose, so we use dummy values for the other characteristics of the | ||||||
1655 | // type. | ||||||
1656 | return TemplateTemplateParmDecl::Create( | ||||||
1657 | ast, decl_ctx, SourceLocation(), | ||||||
1658 | /*Depth*/ 0, /*Position*/ 0, | ||||||
1659 | /*IsParameterPack*/ false, &identifier_info, template_param_list); | ||||||
1660 | } | ||||||
1661 | |||||||
1662 | ClassTemplateSpecializationDecl * | ||||||
1663 | TypeSystemClang::CreateClassTemplateSpecializationDecl( | ||||||
1664 | DeclContext *decl_ctx, OptionalClangModuleID owning_module, | ||||||
1665 | ClassTemplateDecl *class_template_decl, int kind, | ||||||
1666 | const TemplateParameterInfos &template_param_infos) { | ||||||
1667 | ASTContext &ast = getASTContext(); | ||||||
1668 | llvm::SmallVector<clang::TemplateArgument, 2> args( | ||||||
1669 | template_param_infos.args.size() + | ||||||
1670 | (template_param_infos.packed_args ? 1 : 0)); | ||||||
1671 | std::copy(template_param_infos.args.begin(), template_param_infos.args.end(), | ||||||
1672 | args.begin()); | ||||||
1673 | if (template_param_infos.packed_args) { | ||||||
1674 | args[args.size() - 1] = TemplateArgument::CreatePackCopy( | ||||||
1675 | ast, template_param_infos.packed_args->args); | ||||||
1676 | } | ||||||
1677 | ClassTemplateSpecializationDecl *class_template_specialization_decl = | ||||||
1678 | ClassTemplateSpecializationDecl::CreateDeserialized(ast, 0); | ||||||
1679 | class_template_specialization_decl->setTagKind( | ||||||
1680 | static_cast<TagDecl::TagKind>(kind)); | ||||||
1681 | class_template_specialization_decl->setDeclContext(decl_ctx); | ||||||
1682 | class_template_specialization_decl->setInstantiationOf(class_template_decl); | ||||||
1683 | class_template_specialization_decl->setTemplateArgs( | ||||||
1684 | TemplateArgumentList::CreateCopy(ast, args)); | ||||||
1685 | ast.getTypeDeclType(class_template_specialization_decl, nullptr); | ||||||
1686 | class_template_specialization_decl->setDeclName( | ||||||
1687 | class_template_decl->getDeclName()); | ||||||
1688 | SetOwningModule(class_template_specialization_decl, owning_module); | ||||||
1689 | decl_ctx->addDecl(class_template_specialization_decl); | ||||||
1690 | |||||||
1691 | class_template_specialization_decl->setSpecializationKind( | ||||||
1692 | TSK_ExplicitSpecialization); | ||||||
1693 | |||||||
1694 | return class_template_specialization_decl; | ||||||
1695 | } | ||||||
1696 | |||||||
1697 | CompilerType TypeSystemClang::CreateClassTemplateSpecializationType( | ||||||
1698 | ClassTemplateSpecializationDecl *class_template_specialization_decl) { | ||||||
1699 | if (class_template_specialization_decl) { | ||||||
1700 | ASTContext &ast = getASTContext(); | ||||||
1701 | return GetType(ast.getTagDeclType(class_template_specialization_decl)); | ||||||
1702 | } | ||||||
1703 | return CompilerType(); | ||||||
1704 | } | ||||||
1705 | |||||||
1706 | static inline bool check_op_param(bool is_method, | ||||||
1707 | clang::OverloadedOperatorKind op_kind, | ||||||
1708 | bool unary, bool binary, | ||||||
1709 | uint32_t num_params) { | ||||||
1710 | // Special-case call since it can take any number of operands | ||||||
1711 | if (op_kind == OO_Call) | ||||||
1712 | return true; | ||||||
1713 | |||||||
1714 | // The parameter count doesn't include "this" | ||||||
1715 | if (is_method) | ||||||
1716 | ++num_params; | ||||||
1717 | if (num_params == 1) | ||||||
1718 | return unary; | ||||||
1719 | if (num_params == 2) | ||||||
1720 | return binary; | ||||||
1721 | else | ||||||
1722 | return false; | ||||||
1723 | } | ||||||
1724 | |||||||
1725 | bool TypeSystemClang::CheckOverloadedOperatorKindParameterCount( | ||||||
1726 | bool is_method, clang::OverloadedOperatorKind op_kind, | ||||||
1727 | uint32_t num_params) { | ||||||
1728 | switch (op_kind) { | ||||||
1729 | default: | ||||||
1730 | break; | ||||||
1731 | // C++ standard allows any number of arguments to new/delete | ||||||
1732 | case OO_New: | ||||||
1733 | case OO_Array_New: | ||||||
1734 | case OO_Delete: | ||||||
1735 | case OO_Array_Delete: | ||||||
1736 | return true; | ||||||
1737 | } | ||||||
1738 | |||||||
1739 | #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ | ||||||
1740 | case OO_##Name: \ | ||||||
1741 | return check_op_param(is_method, op_kind, Unary, Binary, num_params); | ||||||
1742 | switch (op_kind) { | ||||||
1743 | #include "clang/Basic/OperatorKinds.def" | ||||||
1744 | default: | ||||||
1745 | break; | ||||||
1746 | } | ||||||
1747 | return false; | ||||||
1748 | } | ||||||
1749 | |||||||
1750 | clang::AccessSpecifier | ||||||
1751 | TypeSystemClang::UnifyAccessSpecifiers(clang::AccessSpecifier lhs, | ||||||
1752 | clang::AccessSpecifier rhs) { | ||||||
1753 | // Make the access equal to the stricter of the field and the nested field's | ||||||
1754 | // access | ||||||
1755 | if (lhs == AS_none || rhs == AS_none) | ||||||
1756 | return AS_none; | ||||||
1757 | if (lhs == AS_private || rhs == AS_private) | ||||||
1758 | return AS_private; | ||||||
1759 | if (lhs == AS_protected || rhs == AS_protected) | ||||||
1760 | return AS_protected; | ||||||
1761 | return AS_public; | ||||||
1762 | } | ||||||
1763 | |||||||
1764 | bool TypeSystemClang::FieldIsBitfield(FieldDecl *field, | ||||||
1765 | uint32_t &bitfield_bit_size) { | ||||||
1766 | ASTContext &ast = getASTContext(); | ||||||
1767 | if (field == nullptr) | ||||||
1768 | return false; | ||||||
1769 | |||||||
1770 | if (field->isBitField()) { | ||||||
1771 | Expr *bit_width_expr = field->getBitWidth(); | ||||||
1772 | if (bit_width_expr) { | ||||||
1773 | if (Optional<llvm::APSInt> bit_width_apsint = | ||||||
1774 | bit_width_expr->getIntegerConstantExpr(ast)) { | ||||||
1775 | bitfield_bit_size = bit_width_apsint->getLimitedValue(UINT32_MAX(4294967295U)); | ||||||
1776 | return true; | ||||||
1777 | } | ||||||
1778 | } | ||||||
1779 | } | ||||||
1780 | return false; | ||||||
1781 | } | ||||||
1782 | |||||||
1783 | bool TypeSystemClang::RecordHasFields(const RecordDecl *record_decl) { | ||||||
1784 | if (record_decl == nullptr) | ||||||
1785 | return false; | ||||||
1786 | |||||||
1787 | if (!record_decl->field_empty()) | ||||||
1788 | return true; | ||||||
1789 | |||||||
1790 | // No fields, lets check this is a CXX record and check the base classes | ||||||
1791 | const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); | ||||||
1792 | if (cxx_record_decl) { | ||||||
1793 | CXXRecordDecl::base_class_const_iterator base_class, base_class_end; | ||||||
1794 | for (base_class = cxx_record_decl->bases_begin(), | ||||||
1795 | base_class_end = cxx_record_decl->bases_end(); | ||||||
1796 | base_class != base_class_end; ++base_class) { | ||||||
1797 | const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>( | ||||||
1798 | base_class->getType()->getAs<RecordType>()->getDecl()); | ||||||
1799 | if (RecordHasFields(base_class_decl)) | ||||||
1800 | return true; | ||||||
1801 | } | ||||||
1802 | } | ||||||
1803 | return false; | ||||||
1804 | } | ||||||
1805 | |||||||
1806 | #pragma mark Objective-C Classes | ||||||
1807 | |||||||
1808 | CompilerType TypeSystemClang::CreateObjCClass( | ||||||
1809 | llvm::StringRef name, clang::DeclContext *decl_ctx, | ||||||
1810 | OptionalClangModuleID owning_module, bool isForwardDecl, bool isInternal, | ||||||
1811 | ClangASTMetadata *metadata) { | ||||||
1812 | ASTContext &ast = getASTContext(); | ||||||
1813 | assert(!name.empty())(static_cast <bool> (!name.empty()) ? void (0) : __assert_fail ("!name.empty()", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 1813, __extension__ __PRETTY_FUNCTION__)); | ||||||
1814 | if (!decl_ctx) | ||||||
1815 | decl_ctx = ast.getTranslationUnitDecl(); | ||||||
1816 | |||||||
1817 | ObjCInterfaceDecl *decl = ObjCInterfaceDecl::CreateDeserialized(ast, 0); | ||||||
1818 | decl->setDeclContext(decl_ctx); | ||||||
1819 | decl->setDeclName(&ast.Idents.get(name)); | ||||||
1820 | /*isForwardDecl,*/ | ||||||
1821 | decl->setImplicit(isInternal); | ||||||
1822 | SetOwningModule(decl, owning_module); | ||||||
1823 | |||||||
1824 | if (metadata) | ||||||
1825 | SetMetadata(decl, *metadata); | ||||||
1826 | |||||||
1827 | return GetType(ast.getObjCInterfaceType(decl)); | ||||||
1828 | } | ||||||
1829 | |||||||
1830 | static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) { | ||||||
1831 | return !TypeSystemClang::RecordHasFields(b->getType()->getAsCXXRecordDecl()); | ||||||
1832 | } | ||||||
1833 | |||||||
1834 | uint32_t | ||||||
1835 | TypeSystemClang::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl, | ||||||
1836 | bool omit_empty_base_classes) { | ||||||
1837 | uint32_t num_bases = 0; | ||||||
1838 | if (cxx_record_decl) { | ||||||
1839 | if (omit_empty_base_classes) { | ||||||
1840 | CXXRecordDecl::base_class_const_iterator base_class, base_class_end; | ||||||
1841 | for (base_class = cxx_record_decl->bases_begin(), | ||||||
1842 | base_class_end = cxx_record_decl->bases_end(); | ||||||
1843 | base_class != base_class_end; ++base_class) { | ||||||
1844 | // Skip empty base classes | ||||||
1845 | if (BaseSpecifierIsEmpty(base_class)) | ||||||
1846 | continue; | ||||||
1847 | ++num_bases; | ||||||
1848 | } | ||||||
1849 | } else | ||||||
1850 | num_bases = cxx_record_decl->getNumBases(); | ||||||
1851 | } | ||||||
1852 | return num_bases; | ||||||
1853 | } | ||||||
1854 | |||||||
1855 | #pragma mark Namespace Declarations | ||||||
1856 | |||||||
1857 | NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration( | ||||||
1858 | const char *name, clang::DeclContext *decl_ctx, | ||||||
1859 | OptionalClangModuleID owning_module, bool is_inline) { | ||||||
1860 | NamespaceDecl *namespace_decl = nullptr; | ||||||
1861 | ASTContext &ast = getASTContext(); | ||||||
1862 | TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl(); | ||||||
1863 | if (!decl_ctx) | ||||||
1864 | decl_ctx = translation_unit_decl; | ||||||
1865 | |||||||
1866 | if (name) { | ||||||
1867 | IdentifierInfo &identifier_info = ast.Idents.get(name); | ||||||
1868 | DeclarationName decl_name(&identifier_info); | ||||||
1869 | clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); | ||||||
1870 | for (NamedDecl *decl : result) { | ||||||
1871 | namespace_decl = dyn_cast<clang::NamespaceDecl>(decl); | ||||||
1872 | if (namespace_decl) | ||||||
1873 | return namespace_decl; | ||||||
1874 | } | ||||||
1875 | |||||||
1876 | namespace_decl = | ||||||
1877 | NamespaceDecl::Create(ast, decl_ctx, is_inline, SourceLocation(), | ||||||
1878 | SourceLocation(), &identifier_info, nullptr); | ||||||
1879 | |||||||
1880 | decl_ctx->addDecl(namespace_decl); | ||||||
1881 | } else { | ||||||
1882 | if (decl_ctx == translation_unit_decl) { | ||||||
1883 | namespace_decl = translation_unit_decl->getAnonymousNamespace(); | ||||||
1884 | if (namespace_decl) | ||||||
1885 | return namespace_decl; | ||||||
1886 | |||||||
1887 | namespace_decl = | ||||||
1888 | NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(), | ||||||
1889 | SourceLocation(), nullptr, nullptr); | ||||||
1890 | translation_unit_decl->setAnonymousNamespace(namespace_decl); | ||||||
1891 | translation_unit_decl->addDecl(namespace_decl); | ||||||
1892 | assert(namespace_decl == translation_unit_decl->getAnonymousNamespace())(static_cast <bool> (namespace_decl == translation_unit_decl ->getAnonymousNamespace()) ? void (0) : __assert_fail ("namespace_decl == translation_unit_decl->getAnonymousNamespace()" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 1892, __extension__ __PRETTY_FUNCTION__)); | ||||||
1893 | } else { | ||||||
1894 | NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx); | ||||||
1895 | if (parent_namespace_decl) { | ||||||
1896 | namespace_decl = parent_namespace_decl->getAnonymousNamespace(); | ||||||
1897 | if (namespace_decl) | ||||||
1898 | return namespace_decl; | ||||||
1899 | namespace_decl = | ||||||
1900 | NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(), | ||||||
1901 | SourceLocation(), nullptr, nullptr); | ||||||
1902 | parent_namespace_decl->setAnonymousNamespace(namespace_decl); | ||||||
1903 | parent_namespace_decl->addDecl(namespace_decl); | ||||||
1904 | assert(namespace_decl ==(static_cast <bool> (namespace_decl == parent_namespace_decl ->getAnonymousNamespace()) ? void (0) : __assert_fail ("namespace_decl == parent_namespace_decl->getAnonymousNamespace()" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 1905, __extension__ __PRETTY_FUNCTION__)) | ||||||
1905 | parent_namespace_decl->getAnonymousNamespace())(static_cast <bool> (namespace_decl == parent_namespace_decl ->getAnonymousNamespace()) ? void (0) : __assert_fail ("namespace_decl == parent_namespace_decl->getAnonymousNamespace()" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 1905, __extension__ __PRETTY_FUNCTION__)); | ||||||
1906 | } else { | ||||||
1907 | assert(false && "GetUniqueNamespaceDeclaration called with no name and "(static_cast <bool> (false && "GetUniqueNamespaceDeclaration called with no name and " "no namespace as decl_ctx") ? void (0) : __assert_fail ("false && \"GetUniqueNamespaceDeclaration called with no name and \" \"no namespace as decl_ctx\"" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 1908, __extension__ __PRETTY_FUNCTION__)) | ||||||
1908 | "no namespace as decl_ctx")(static_cast <bool> (false && "GetUniqueNamespaceDeclaration called with no name and " "no namespace as decl_ctx") ? void (0) : __assert_fail ("false && \"GetUniqueNamespaceDeclaration called with no name and \" \"no namespace as decl_ctx\"" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 1908, __extension__ __PRETTY_FUNCTION__)); | ||||||
1909 | } | ||||||
1910 | } | ||||||
1911 | } | ||||||
1912 | // Note: namespaces can span multiple modules, so perhaps this isn't a good | ||||||
1913 | // idea. | ||||||
1914 | SetOwningModule(namespace_decl, owning_module); | ||||||
1915 | |||||||
1916 | VerifyDecl(namespace_decl); | ||||||
1917 | return namespace_decl; | ||||||
1918 | } | ||||||
1919 | |||||||
1920 | clang::BlockDecl * | ||||||
1921 | TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx, | ||||||
1922 | OptionalClangModuleID owning_module) { | ||||||
1923 | if (ctx) { | ||||||
1924 | clang::BlockDecl *decl = | ||||||
1925 | clang::BlockDecl::CreateDeserialized(getASTContext(), 0); | ||||||
1926 | decl->setDeclContext(ctx); | ||||||
1927 | ctx->addDecl(decl); | ||||||
1928 | SetOwningModule(decl, owning_module); | ||||||
1929 | return decl; | ||||||
1930 | } | ||||||
1931 | return nullptr; | ||||||
1932 | } | ||||||
1933 | |||||||
1934 | clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left, | ||||||
1935 | clang::DeclContext *right, | ||||||
1936 | clang::DeclContext *root) { | ||||||
1937 | if (root == nullptr) | ||||||
1938 | return nullptr; | ||||||
1939 | |||||||
1940 | std::set<clang::DeclContext *> path_left; | ||||||
1941 | for (clang::DeclContext *d = left; d != nullptr; d = d->getParent()) | ||||||
1942 | path_left.insert(d); | ||||||
1943 | |||||||
1944 | for (clang::DeclContext *d = right; d != nullptr; d = d->getParent()) | ||||||
1945 | if (path_left.find(d) != path_left.end()) | ||||||
1946 | return d; | ||||||
1947 | |||||||
1948 | return nullptr; | ||||||
1949 | } | ||||||
1950 | |||||||
1951 | clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration( | ||||||
1952 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, | ||||||
1953 | clang::NamespaceDecl *ns_decl) { | ||||||
1954 | if (decl_ctx && ns_decl) { | ||||||
1955 | auto *translation_unit = getASTContext().getTranslationUnitDecl(); | ||||||
1956 | clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create( | ||||||
1957 | getASTContext(), decl_ctx, clang::SourceLocation(), | ||||||
1958 | clang::SourceLocation(), clang::NestedNameSpecifierLoc(), | ||||||
1959 | clang::SourceLocation(), ns_decl, | ||||||
1960 | FindLCABetweenDecls(decl_ctx, ns_decl, | ||||||
1961 | translation_unit)); | ||||||
1962 | decl_ctx->addDecl(using_decl); | ||||||
1963 | SetOwningModule(using_decl, owning_module); | ||||||
1964 | return using_decl; | ||||||
1965 | } | ||||||
1966 | return nullptr; | ||||||
1967 | } | ||||||
1968 | |||||||
1969 | clang::UsingDecl * | ||||||
1970 | TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, | ||||||
1971 | OptionalClangModuleID owning_module, | ||||||
1972 | clang::NamedDecl *target) { | ||||||
1973 | if (current_decl_ctx && target) { | ||||||
1974 | clang::UsingDecl *using_decl = clang::UsingDecl::Create( | ||||||
1975 | getASTContext(), current_decl_ctx, clang::SourceLocation(), | ||||||
1976 | clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false); | ||||||
1977 | SetOwningModule(using_decl, owning_module); | ||||||
1978 | clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create( | ||||||
1979 | getASTContext(), current_decl_ctx, clang::SourceLocation(), | ||||||
1980 | target->getDeclName(), using_decl, target); | ||||||
1981 | SetOwningModule(shadow_decl, owning_module); | ||||||
1982 | using_decl->addShadowDecl(shadow_decl); | ||||||
1983 | current_decl_ctx->addDecl(using_decl); | ||||||
1984 | return using_decl; | ||||||
1985 | } | ||||||
1986 | return nullptr; | ||||||
1987 | } | ||||||
1988 | |||||||
1989 | clang::VarDecl *TypeSystemClang::CreateVariableDeclaration( | ||||||
1990 | clang::DeclContext *decl_context, OptionalClangModuleID owning_module, | ||||||
1991 | const char *name, clang::QualType type) { | ||||||
1992 | if (decl_context) { | ||||||
1993 | clang::VarDecl *var_decl = | ||||||
1994 | clang::VarDecl::CreateDeserialized(getASTContext(), 0); | ||||||
1995 | var_decl->setDeclContext(decl_context); | ||||||
1996 | if (name && name[0]) | ||||||
1997 | var_decl->setDeclName(&getASTContext().Idents.getOwn(name)); | ||||||
1998 | var_decl->setType(type); | ||||||
1999 | SetOwningModule(var_decl, owning_module); | ||||||
2000 | var_decl->setAccess(clang::AS_public); | ||||||
2001 | decl_context->addDecl(var_decl); | ||||||
2002 | return var_decl; | ||||||
2003 | } | ||||||
2004 | return nullptr; | ||||||
2005 | } | ||||||
2006 | |||||||
2007 | lldb::opaque_compiler_type_t | ||||||
2008 | TypeSystemClang::GetOpaqueCompilerType(clang::ASTContext *ast, | ||||||
2009 | lldb::BasicType basic_type) { | ||||||
2010 | switch (basic_type) { | ||||||
2011 | case eBasicTypeVoid: | ||||||
2012 | return ast->VoidTy.getAsOpaquePtr(); | ||||||
2013 | case eBasicTypeChar: | ||||||
2014 | return ast->CharTy.getAsOpaquePtr(); | ||||||
2015 | case eBasicTypeSignedChar: | ||||||
2016 | return ast->SignedCharTy.getAsOpaquePtr(); | ||||||
2017 | case eBasicTypeUnsignedChar: | ||||||
2018 | return ast->UnsignedCharTy.getAsOpaquePtr(); | ||||||
2019 | case eBasicTypeWChar: | ||||||
2020 | return ast->getWCharType().getAsOpaquePtr(); | ||||||
2021 | case eBasicTypeSignedWChar: | ||||||
2022 | return ast->getSignedWCharType().getAsOpaquePtr(); | ||||||
2023 | case eBasicTypeUnsignedWChar: | ||||||
2024 | return ast->getUnsignedWCharType().getAsOpaquePtr(); | ||||||
2025 | case eBasicTypeChar16: | ||||||
2026 | return ast->Char16Ty.getAsOpaquePtr(); | ||||||
2027 | case eBasicTypeChar32: | ||||||
2028 | return ast->Char32Ty.getAsOpaquePtr(); | ||||||
2029 | case eBasicTypeShort: | ||||||
2030 | return ast->ShortTy.getAsOpaquePtr(); | ||||||
2031 | case eBasicTypeUnsignedShort: | ||||||
2032 | return ast->UnsignedShortTy.getAsOpaquePtr(); | ||||||
2033 | case eBasicTypeInt: | ||||||
2034 | return ast->IntTy.getAsOpaquePtr(); | ||||||
2035 | case eBasicTypeUnsignedInt: | ||||||
2036 | return ast->UnsignedIntTy.getAsOpaquePtr(); | ||||||
2037 | case eBasicTypeLong: | ||||||
2038 | return ast->LongTy.getAsOpaquePtr(); | ||||||
2039 | case eBasicTypeUnsignedLong: | ||||||
2040 | return ast->UnsignedLongTy.getAsOpaquePtr(); | ||||||
2041 | case eBasicTypeLongLong: | ||||||
2042 | return ast->LongLongTy.getAsOpaquePtr(); | ||||||
2043 | case eBasicTypeUnsignedLongLong: | ||||||
2044 | return ast->UnsignedLongLongTy.getAsOpaquePtr(); | ||||||
2045 | case eBasicTypeInt128: | ||||||
2046 | return ast->Int128Ty.getAsOpaquePtr(); | ||||||
2047 | case eBasicTypeUnsignedInt128: | ||||||
2048 | return ast->UnsignedInt128Ty.getAsOpaquePtr(); | ||||||
2049 | case eBasicTypeBool: | ||||||
2050 | return ast->BoolTy.getAsOpaquePtr(); | ||||||
2051 | case eBasicTypeHalf: | ||||||
2052 | return ast->HalfTy.getAsOpaquePtr(); | ||||||
2053 | case eBasicTypeFloat: | ||||||
2054 | return ast->FloatTy.getAsOpaquePtr(); | ||||||
2055 | case eBasicTypeDouble: | ||||||
2056 | return ast->DoubleTy.getAsOpaquePtr(); | ||||||
2057 | case eBasicTypeLongDouble: | ||||||
2058 | return ast->LongDoubleTy.getAsOpaquePtr(); | ||||||
2059 | case eBasicTypeFloatComplex: | ||||||
2060 | return ast->getComplexType(ast->FloatTy).getAsOpaquePtr(); | ||||||
2061 | case eBasicTypeDoubleComplex: | ||||||
2062 | return ast->getComplexType(ast->DoubleTy).getAsOpaquePtr(); | ||||||
2063 | case eBasicTypeLongDoubleComplex: | ||||||
2064 | return ast->getComplexType(ast->LongDoubleTy).getAsOpaquePtr(); | ||||||
2065 | case eBasicTypeObjCID: | ||||||
2066 | return ast->getObjCIdType().getAsOpaquePtr(); | ||||||
2067 | case eBasicTypeObjCClass: | ||||||
2068 | return ast->getObjCClassType().getAsOpaquePtr(); | ||||||
2069 | case eBasicTypeObjCSel: | ||||||
2070 | return ast->getObjCSelType().getAsOpaquePtr(); | ||||||
2071 | case eBasicTypeNullPtr: | ||||||
2072 | return ast->NullPtrTy.getAsOpaquePtr(); | ||||||
2073 | default: | ||||||
2074 | return nullptr; | ||||||
2075 | } | ||||||
2076 | } | ||||||
2077 | |||||||
2078 | #pragma mark Function Types | ||||||
2079 | |||||||
2080 | clang::DeclarationName | ||||||
2081 | TypeSystemClang::GetDeclarationName(llvm::StringRef name, | ||||||
2082 | const CompilerType &function_clang_type) { | ||||||
2083 | clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS; | ||||||
2084 | if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS) | ||||||
2085 | return DeclarationName(&getASTContext().Idents.get( | ||||||
2086 | name)); // Not operator, but a regular function. | ||||||
2087 | |||||||
2088 | // Check the number of operator parameters. Sometimes we have seen bad DWARF | ||||||
2089 | // that doesn't correctly describe operators and if we try to create a method | ||||||
2090 | // and add it to the class, clang will assert and crash, so we need to make | ||||||
2091 | // sure things are acceptable. | ||||||
2092 | clang::QualType method_qual_type(ClangUtil::GetQualType(function_clang_type)); | ||||||
2093 | const clang::FunctionProtoType *function_type = | ||||||
2094 | llvm::dyn_cast<clang::FunctionProtoType>(method_qual_type.getTypePtr()); | ||||||
2095 | if (function_type == nullptr) | ||||||
2096 | return clang::DeclarationName(); | ||||||
2097 | |||||||
2098 | const bool is_method = false; | ||||||
2099 | const unsigned int num_params = function_type->getNumParams(); | ||||||
2100 | if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount( | ||||||
2101 | is_method, op_kind, num_params)) | ||||||
2102 | return clang::DeclarationName(); | ||||||
2103 | |||||||
2104 | return getASTContext().DeclarationNames.getCXXOperatorName(op_kind); | ||||||
2105 | } | ||||||
2106 | |||||||
2107 | PrintingPolicy TypeSystemClang::GetTypePrintingPolicy() { | ||||||
2108 | clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy()); | ||||||
2109 | printing_policy.SuppressTagKeyword = true; | ||||||
2110 | // Inline namespaces are important for some type formatters (e.g., libc++ | ||||||
2111 | // and libstdc++ are differentiated by their inline namespaces). | ||||||
2112 | printing_policy.SuppressInlineNamespace = false; | ||||||
2113 | printing_policy.SuppressUnwrittenScope = false; | ||||||
2114 | // Default arguments are also always important for type formatters. Otherwise | ||||||
2115 | // we would need to always specify two type names for the setups where we do | ||||||
2116 | // know the default arguments and where we don't know default arguments. | ||||||
2117 | // | ||||||
2118 | // For example, without this we would need to have formatters for both: | ||||||
2119 | // std::basic_string<char> | ||||||
2120 | // and | ||||||
2121 | // std::basic_string<char, std::char_traits<char>, std::allocator<char> > | ||||||
2122 | // to support setups where LLDB was able to reconstruct default arguments | ||||||
2123 | // (and we then would have suppressed them from the type name) and also setups | ||||||
2124 | // where LLDB wasn't able to reconstruct the default arguments. | ||||||
2125 | printing_policy.SuppressDefaultTemplateArgs = false; | ||||||
2126 | return printing_policy; | ||||||
2127 | } | ||||||
2128 | |||||||
2129 | std::string TypeSystemClang::GetTypeNameForDecl(const NamedDecl *named_decl) { | ||||||
2130 | clang::PrintingPolicy printing_policy = GetTypePrintingPolicy(); | ||||||
2131 | std::string result; | ||||||
2132 | llvm::raw_string_ostream os(result); | ||||||
2133 | named_decl->printQualifiedName(os, printing_policy); | ||||||
2134 | return result; | ||||||
2135 | } | ||||||
2136 | |||||||
2137 | FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( | ||||||
2138 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, | ||||||
2139 | llvm::StringRef name, const CompilerType &function_clang_type, | ||||||
2140 | clang::StorageClass storage, bool is_inline) { | ||||||
2141 | FunctionDecl *func_decl = nullptr; | ||||||
2142 | ASTContext &ast = getASTContext(); | ||||||
2143 | if (!decl_ctx) | ||||||
2144 | decl_ctx = ast.getTranslationUnitDecl(); | ||||||
2145 | |||||||
2146 | const bool hasWrittenPrototype = true; | ||||||
2147 | const bool isConstexprSpecified = false; | ||||||
2148 | |||||||
2149 | clang::DeclarationName declarationName = | ||||||
2150 | GetDeclarationName(name, function_clang_type); | ||||||
2151 | func_decl = FunctionDecl::CreateDeserialized(ast, 0); | ||||||
2152 | func_decl->setDeclContext(decl_ctx); | ||||||
2153 | func_decl->setDeclName(declarationName); | ||||||
2154 | func_decl->setType(ClangUtil::GetQualType(function_clang_type)); | ||||||
2155 | func_decl->setStorageClass(storage); | ||||||
2156 | func_decl->setInlineSpecified(is_inline); | ||||||
2157 | func_decl->setHasWrittenPrototype(hasWrittenPrototype); | ||||||
2158 | func_decl->setConstexprKind(isConstexprSpecified | ||||||
2159 | ? ConstexprSpecKind::Constexpr | ||||||
2160 | : ConstexprSpecKind::Unspecified); | ||||||
2161 | SetOwningModule(func_decl, owning_module); | ||||||
2162 | decl_ctx->addDecl(func_decl); | ||||||
2163 | |||||||
2164 | VerifyDecl(func_decl); | ||||||
2165 | |||||||
2166 | return func_decl; | ||||||
2167 | } | ||||||
2168 | |||||||
2169 | CompilerType | ||||||
2170 | TypeSystemClang::CreateFunctionType(const CompilerType &result_type, | ||||||
2171 | const CompilerType *args, unsigned num_args, | ||||||
2172 | bool is_variadic, unsigned type_quals, | ||||||
2173 | clang::CallingConv cc) { | ||||||
2174 | if (!result_type || !ClangUtil::IsClangType(result_type)) | ||||||
2175 | return CompilerType(); // invalid return type | ||||||
2176 | |||||||
2177 | std::vector<QualType> qual_type_args; | ||||||
2178 | if (num_args > 0 && args == nullptr) | ||||||
2179 | return CompilerType(); // invalid argument array passed in | ||||||
2180 | |||||||
2181 | // Verify that all arguments are valid and the right type | ||||||
2182 | for (unsigned i = 0; i < num_args; ++i) { | ||||||
2183 | if (args[i]) { | ||||||
2184 | // Make sure we have a clang type in args[i] and not a type from another | ||||||
2185 | // language whose name might match | ||||||
2186 | const bool is_clang_type = ClangUtil::IsClangType(args[i]); | ||||||
2187 | lldbassert(is_clang_type)lldb_private::lldb_assert(static_cast<bool>(is_clang_type ), "is_clang_type", __FUNCTION__, "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 2187); | ||||||
2188 | if (is_clang_type) | ||||||
2189 | qual_type_args.push_back(ClangUtil::GetQualType(args[i])); | ||||||
2190 | else | ||||||
2191 | return CompilerType(); // invalid argument type (must be a clang type) | ||||||
2192 | } else | ||||||
2193 | return CompilerType(); // invalid argument type (empty) | ||||||
2194 | } | ||||||
2195 | |||||||
2196 | // TODO: Detect calling convention in DWARF? | ||||||
2197 | FunctionProtoType::ExtProtoInfo proto_info; | ||||||
2198 | proto_info.ExtInfo = cc; | ||||||
2199 | proto_info.Variadic = is_variadic; | ||||||
2200 | proto_info.ExceptionSpec = EST_None; | ||||||
2201 | proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals); | ||||||
2202 | proto_info.RefQualifier = RQ_None; | ||||||
2203 | |||||||
2204 | return GetType(getASTContext().getFunctionType( | ||||||
2205 | ClangUtil::GetQualType(result_type), qual_type_args, proto_info)); | ||||||
2206 | } | ||||||
2207 | |||||||
2208 | ParmVarDecl *TypeSystemClang::CreateParameterDeclaration( | ||||||
2209 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, | ||||||
2210 | const char *name, const CompilerType ¶m_type, int storage, | ||||||
2211 | bool add_decl) { | ||||||
2212 | ASTContext &ast = getASTContext(); | ||||||
2213 | auto *decl = ParmVarDecl::CreateDeserialized(ast, 0); | ||||||
2214 | decl->setDeclContext(decl_ctx); | ||||||
2215 | if (name && name[0]) | ||||||
2216 | decl->setDeclName(&ast.Idents.get(name)); | ||||||
2217 | decl->setType(ClangUtil::GetQualType(param_type)); | ||||||
2218 | decl->setStorageClass(static_cast<clang::StorageClass>(storage)); | ||||||
2219 | SetOwningModule(decl, owning_module); | ||||||
2220 | if (add_decl) | ||||||
2221 | decl_ctx->addDecl(decl); | ||||||
2222 | |||||||
2223 | return decl; | ||||||
2224 | } | ||||||
2225 | |||||||
2226 | void TypeSystemClang::SetFunctionParameters( | ||||||
2227 | FunctionDecl *function_decl, llvm::ArrayRef<ParmVarDecl *> params) { | ||||||
2228 | if (function_decl) | ||||||
2229 | function_decl->setParams(params); | ||||||
2230 | } | ||||||
2231 | |||||||
2232 | CompilerType | ||||||
2233 | TypeSystemClang::CreateBlockPointerType(const CompilerType &function_type) { | ||||||
2234 | QualType block_type = m_ast_up->getBlockPointerType( | ||||||
2235 | clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType())); | ||||||
2236 | |||||||
2237 | return GetType(block_type); | ||||||
2238 | } | ||||||
2239 | |||||||
2240 | #pragma mark Array Types | ||||||
2241 | |||||||
2242 | CompilerType TypeSystemClang::CreateArrayType(const CompilerType &element_type, | ||||||
2243 | size_t element_count, | ||||||
2244 | bool is_vector) { | ||||||
2245 | if (element_type.IsValid()) { | ||||||
2246 | ASTContext &ast = getASTContext(); | ||||||
2247 | |||||||
2248 | if (is_vector) { | ||||||
2249 | return GetType(ast.getExtVectorType(ClangUtil::GetQualType(element_type), | ||||||
2250 | element_count)); | ||||||
2251 | } else { | ||||||
2252 | |||||||
2253 | llvm::APInt ap_element_count(64, element_count); | ||||||
2254 | if (element_count == 0) { | ||||||
2255 | return GetType(ast.getIncompleteArrayType( | ||||||
2256 | ClangUtil::GetQualType(element_type), clang::ArrayType::Normal, 0)); | ||||||
2257 | } else { | ||||||
2258 | return GetType(ast.getConstantArrayType( | ||||||
2259 | ClangUtil::GetQualType(element_type), ap_element_count, nullptr, | ||||||
2260 | clang::ArrayType::Normal, 0)); | ||||||
2261 | } | ||||||
2262 | } | ||||||
2263 | } | ||||||
2264 | return CompilerType(); | ||||||
2265 | } | ||||||
2266 | |||||||
2267 | CompilerType TypeSystemClang::CreateStructForIdentifier( | ||||||
2268 | ConstString type_name, | ||||||
2269 | const std::initializer_list<std::pair<const char *, CompilerType>> | ||||||
2270 | &type_fields, | ||||||
2271 | bool packed) { | ||||||
2272 | CompilerType type; | ||||||
2273 | if (!type_name.IsEmpty() && | ||||||
2274 | (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)) | ||||||
2275 | .IsValid()) { | ||||||
2276 | lldbassert(0 && "Trying to create a type for an existing name")lldb_private::lldb_assert(static_cast<bool>(0 && "Trying to create a type for an existing name"), "0 && \"Trying to create a type for an existing name\"" , __FUNCTION__, "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 2276); | ||||||
2277 | return type; | ||||||
2278 | } | ||||||
2279 | |||||||
2280 | type = CreateRecordType(nullptr, OptionalClangModuleID(), lldb::eAccessPublic, | ||||||
2281 | type_name.GetCString(), clang::TTK_Struct, | ||||||
2282 | lldb::eLanguageTypeC); | ||||||
2283 | StartTagDeclarationDefinition(type); | ||||||
2284 | for (const auto &field : type_fields) | ||||||
2285 | AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic, | ||||||
2286 | 0); | ||||||
2287 | if (packed) | ||||||
2288 | SetIsPacked(type); | ||||||
2289 | CompleteTagDeclarationDefinition(type); | ||||||
2290 | return type; | ||||||
2291 | } | ||||||
2292 | |||||||
2293 | CompilerType TypeSystemClang::GetOrCreateStructForIdentifier( | ||||||
2294 | ConstString type_name, | ||||||
2295 | const std::initializer_list<std::pair<const char *, CompilerType>> | ||||||
2296 | &type_fields, | ||||||
2297 | bool packed) { | ||||||
2298 | CompilerType type; | ||||||
2299 | if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid()) | ||||||
2300 | return type; | ||||||
2301 | |||||||
2302 | return CreateStructForIdentifier(type_name, type_fields, packed); | ||||||
2303 | } | ||||||
2304 | |||||||
2305 | #pragma mark Enumeration Types | ||||||
2306 | |||||||
2307 | CompilerType TypeSystemClang::CreateEnumerationType( | ||||||
2308 | llvm::StringRef name, clang::DeclContext *decl_ctx, | ||||||
2309 | OptionalClangModuleID owning_module, const Declaration &decl, | ||||||
2310 | const CompilerType &integer_clang_type, bool is_scoped) { | ||||||
2311 | // TODO: Do something intelligent with the Declaration object passed in | ||||||
2312 | // like maybe filling in the SourceLocation with it... | ||||||
2313 | ASTContext &ast = getASTContext(); | ||||||
2314 | |||||||
2315 | // TODO: ask about these... | ||||||
2316 | // const bool IsFixed = false; | ||||||
2317 | EnumDecl *enum_decl = EnumDecl::CreateDeserialized(ast, 0); | ||||||
2318 | enum_decl->setDeclContext(decl_ctx); | ||||||
2319 | if (!name.empty()) | ||||||
2320 | enum_decl->setDeclName(&ast.Idents.get(name)); | ||||||
2321 | enum_decl->setScoped(is_scoped); | ||||||
2322 | enum_decl->setScopedUsingClassTag(is_scoped); | ||||||
2323 | enum_decl->setFixed(false); | ||||||
2324 | SetOwningModule(enum_decl, owning_module); | ||||||
2325 | if (decl_ctx) | ||||||
2326 | decl_ctx->addDecl(enum_decl); | ||||||
2327 | |||||||
2328 | // TODO: check if we should be setting the promotion type too? | ||||||
2329 | enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type)); | ||||||
2330 | |||||||
2331 | enum_decl->setAccess(AS_public); // TODO respect what's in the debug info | ||||||
2332 | |||||||
2333 | return GetType(ast.getTagDeclType(enum_decl)); | ||||||
2334 | } | ||||||
2335 | |||||||
2336 | CompilerType TypeSystemClang::GetIntTypeFromBitSize(size_t bit_size, | ||||||
2337 | bool is_signed) { | ||||||
2338 | clang::ASTContext &ast = getASTContext(); | ||||||
2339 | |||||||
2340 | if (is_signed) { | ||||||
2341 | if (bit_size == ast.getTypeSize(ast.SignedCharTy)) | ||||||
2342 | return GetType(ast.SignedCharTy); | ||||||
2343 | |||||||
2344 | if (bit_size == ast.getTypeSize(ast.ShortTy)) | ||||||
2345 | return GetType(ast.ShortTy); | ||||||
2346 | |||||||
2347 | if (bit_size == ast.getTypeSize(ast.IntTy)) | ||||||
2348 | return GetType(ast.IntTy); | ||||||
2349 | |||||||
2350 | if (bit_size == ast.getTypeSize(ast.LongTy)) | ||||||
2351 | return GetType(ast.LongTy); | ||||||
2352 | |||||||
2353 | if (bit_size == ast.getTypeSize(ast.LongLongTy)) | ||||||
2354 | return GetType(ast.LongLongTy); | ||||||
2355 | |||||||
2356 | if (bit_size == ast.getTypeSize(ast.Int128Ty)) | ||||||
2357 | return GetType(ast.Int128Ty); | ||||||
2358 | } else { | ||||||
2359 | if (bit_size == ast.getTypeSize(ast.UnsignedCharTy)) | ||||||
2360 | return GetType(ast.UnsignedCharTy); | ||||||
2361 | |||||||
2362 | if (bit_size == ast.getTypeSize(ast.UnsignedShortTy)) | ||||||
2363 | return GetType(ast.UnsignedShortTy); | ||||||
2364 | |||||||
2365 | if (bit_size == ast.getTypeSize(ast.UnsignedIntTy)) | ||||||
2366 | return GetType(ast.UnsignedIntTy); | ||||||
2367 | |||||||
2368 | if (bit_size == ast.getTypeSize(ast.UnsignedLongTy)) | ||||||
2369 | return GetType(ast.UnsignedLongTy); | ||||||
2370 | |||||||
2371 | if (bit_size == ast.getTypeSize(ast.UnsignedLongLongTy)) | ||||||
2372 | return GetType(ast.UnsignedLongLongTy); | ||||||
2373 | |||||||
2374 | if (bit_size == ast.getTypeSize(ast.UnsignedInt128Ty)) | ||||||
2375 | return GetType(ast.UnsignedInt128Ty); | ||||||
2376 | } | ||||||
2377 | return CompilerType(); | ||||||
2378 | } | ||||||
2379 | |||||||
2380 | CompilerType TypeSystemClang::GetPointerSizedIntType(bool is_signed) { | ||||||
2381 | return GetIntTypeFromBitSize( | ||||||
2382 | getASTContext().getTypeSize(getASTContext().VoidPtrTy), is_signed); | ||||||
2383 | } | ||||||
2384 | |||||||
2385 | void TypeSystemClang::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) { | ||||||
2386 | if (decl_ctx) { | ||||||
2387 | DumpDeclContextHiearchy(decl_ctx->getParent()); | ||||||
2388 | |||||||
2389 | clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl_ctx); | ||||||
2390 | if (named_decl) { | ||||||
2391 | printf("%20s: %s\n", decl_ctx->getDeclKindName(), | ||||||
2392 | named_decl->getDeclName().getAsString().c_str()); | ||||||
2393 | } else { | ||||||
2394 | printf("%20s\n", decl_ctx->getDeclKindName()); | ||||||
2395 | } | ||||||
2396 | } | ||||||
2397 | } | ||||||
2398 | |||||||
2399 | void TypeSystemClang::DumpDeclHiearchy(clang::Decl *decl) { | ||||||
2400 | if (decl == nullptr) | ||||||
2401 | return; | ||||||
2402 | DumpDeclContextHiearchy(decl->getDeclContext()); | ||||||
2403 | |||||||
2404 | clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl); | ||||||
2405 | if (record_decl) { | ||||||
2406 | printf("%20s: %s%s\n", decl->getDeclKindName(), | ||||||
2407 | record_decl->getDeclName().getAsString().c_str(), | ||||||
2408 | record_decl->isInjectedClassName() ? " (injected class name)" : ""); | ||||||
2409 | |||||||
2410 | } else { | ||||||
2411 | clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl); | ||||||
2412 | if (named_decl) { | ||||||
2413 | printf("%20s: %s\n", decl->getDeclKindName(), | ||||||
2414 | named_decl->getDeclName().getAsString().c_str()); | ||||||
2415 | } else { | ||||||
2416 | printf("%20s\n", decl->getDeclKindName()); | ||||||
2417 | } | ||||||
2418 | } | ||||||
2419 | } | ||||||
2420 | |||||||
2421 | bool TypeSystemClang::DeclsAreEquivalent(clang::Decl *lhs_decl, | ||||||
2422 | clang::Decl *rhs_decl) { | ||||||
2423 | if (lhs_decl && rhs_decl) { | ||||||
2424 | // Make sure the decl kinds match first | ||||||
2425 | const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind(); | ||||||
2426 | const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind(); | ||||||
2427 | |||||||
2428 | if (lhs_decl_kind == rhs_decl_kind) { | ||||||
2429 | // Now check that the decl contexts kinds are all equivalent before we | ||||||
2430 | // have to check any names of the decl contexts... | ||||||
2431 | clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext(); | ||||||
2432 | clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext(); | ||||||
2433 | if (lhs_decl_ctx && rhs_decl_ctx) { | ||||||
2434 | while (true) { | ||||||
2435 | if (lhs_decl_ctx && rhs_decl_ctx) { | ||||||
2436 | const clang::Decl::Kind lhs_decl_ctx_kind = | ||||||
2437 | lhs_decl_ctx->getDeclKind(); | ||||||
2438 | const clang::Decl::Kind rhs_decl_ctx_kind = | ||||||
2439 | rhs_decl_ctx->getDeclKind(); | ||||||
2440 | if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) { | ||||||
2441 | lhs_decl_ctx = lhs_decl_ctx->getParent(); | ||||||
2442 | rhs_decl_ctx = rhs_decl_ctx->getParent(); | ||||||
2443 | |||||||
2444 | if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr) | ||||||
2445 | break; | ||||||
2446 | } else | ||||||
2447 | return false; | ||||||
2448 | } else | ||||||
2449 | return false; | ||||||
2450 | } | ||||||
2451 | |||||||
2452 | // Now make sure the name of the decls match | ||||||
2453 | clang::NamedDecl *lhs_named_decl = | ||||||
2454 | llvm::dyn_cast<clang::NamedDecl>(lhs_decl); | ||||||
2455 | clang::NamedDecl *rhs_named_decl = | ||||||
2456 | llvm::dyn_cast<clang::NamedDecl>(rhs_decl); | ||||||
2457 | if (lhs_named_decl && rhs_named_decl) { | ||||||
2458 | clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName(); | ||||||
2459 | clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName(); | ||||||
2460 | if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) { | ||||||
2461 | if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString()) | ||||||
2462 | return false; | ||||||
2463 | } else | ||||||
2464 | return false; | ||||||
2465 | } else | ||||||
2466 | return false; | ||||||
2467 | |||||||
2468 | // We know that the decl context kinds all match, so now we need to | ||||||
2469 | // make sure the names match as well | ||||||
2470 | lhs_decl_ctx = lhs_decl->getDeclContext(); | ||||||
2471 | rhs_decl_ctx = rhs_decl->getDeclContext(); | ||||||
2472 | while (true) { | ||||||
2473 | switch (lhs_decl_ctx->getDeclKind()) { | ||||||
2474 | case clang::Decl::TranslationUnit: | ||||||
2475 | // We don't care about the translation unit names | ||||||
2476 | return true; | ||||||
2477 | default: { | ||||||
2478 | clang::NamedDecl *lhs_named_decl = | ||||||
2479 | llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx); | ||||||
2480 | clang::NamedDecl *rhs_named_decl = | ||||||
2481 | llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx); | ||||||
2482 | if (lhs_named_decl && rhs_named_decl) { | ||||||
2483 | clang::DeclarationName lhs_decl_name = | ||||||
2484 | lhs_named_decl->getDeclName(); | ||||||
2485 | clang::DeclarationName rhs_decl_name = | ||||||
2486 | rhs_named_decl->getDeclName(); | ||||||
2487 | if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) { | ||||||
2488 | if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString()) | ||||||
2489 | return false; | ||||||
2490 | } else | ||||||
2491 | return false; | ||||||
2492 | } else | ||||||
2493 | return false; | ||||||
2494 | } break; | ||||||
2495 | } | ||||||
2496 | lhs_decl_ctx = lhs_decl_ctx->getParent(); | ||||||
2497 | rhs_decl_ctx = rhs_decl_ctx->getParent(); | ||||||
2498 | } | ||||||
2499 | } | ||||||
2500 | } | ||||||
2501 | } | ||||||
2502 | return false; | ||||||
2503 | } | ||||||
2504 | bool TypeSystemClang::GetCompleteDecl(clang::ASTContext *ast, | ||||||
2505 | clang::Decl *decl) { | ||||||
2506 | if (!decl) | ||||||
2507 | return false; | ||||||
2508 | |||||||
2509 | ExternalASTSource *ast_source = ast->getExternalSource(); | ||||||
2510 | |||||||
2511 | if (!ast_source) | ||||||
2512 | return false; | ||||||
2513 | |||||||
2514 | if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) { | ||||||
2515 | if (tag_decl->isCompleteDefinition()) | ||||||
2516 | return true; | ||||||
2517 | |||||||
2518 | if (!tag_decl->hasExternalLexicalStorage()) | ||||||
2519 | return false; | ||||||
2520 | |||||||
2521 | ast_source->CompleteType(tag_decl); | ||||||
2522 | |||||||
2523 | return !tag_decl->getTypeForDecl()->isIncompleteType(); | ||||||
2524 | } else if (clang::ObjCInterfaceDecl *objc_interface_decl = | ||||||
2525 | llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) { | ||||||
2526 | if (objc_interface_decl->getDefinition()) | ||||||
2527 | return true; | ||||||
2528 | |||||||
2529 | if (!objc_interface_decl->hasExternalLexicalStorage()) | ||||||
2530 | return false; | ||||||
2531 | |||||||
2532 | ast_source->CompleteType(objc_interface_decl); | ||||||
2533 | |||||||
2534 | return !objc_interface_decl->getTypeForDecl()->isIncompleteType(); | ||||||
2535 | } else { | ||||||
2536 | return false; | ||||||
2537 | } | ||||||
2538 | } | ||||||
2539 | |||||||
2540 | void TypeSystemClang::SetMetadataAsUserID(const clang::Decl *decl, | ||||||
2541 | user_id_t user_id) { | ||||||
2542 | ClangASTMetadata meta_data; | ||||||
2543 | meta_data.SetUserID(user_id); | ||||||
2544 | SetMetadata(decl, meta_data); | ||||||
2545 | } | ||||||
2546 | |||||||
2547 | void TypeSystemClang::SetMetadataAsUserID(const clang::Type *type, | ||||||
2548 | user_id_t user_id) { | ||||||
2549 | ClangASTMetadata meta_data; | ||||||
2550 | meta_data.SetUserID(user_id); | ||||||
2551 | SetMetadata(type, meta_data); | ||||||
2552 | } | ||||||
2553 | |||||||
2554 | void TypeSystemClang::SetMetadata(const clang::Decl *object, | ||||||
2555 | ClangASTMetadata &metadata) { | ||||||
2556 | m_decl_metadata[object] = metadata; | ||||||
2557 | } | ||||||
2558 | |||||||
2559 | void TypeSystemClang::SetMetadata(const clang::Type *object, | ||||||
2560 | ClangASTMetadata &metadata) { | ||||||
2561 | m_type_metadata[object] = metadata; | ||||||
2562 | } | ||||||
2563 | |||||||
2564 | ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Decl *object) { | ||||||
2565 | auto It = m_decl_metadata.find(object); | ||||||
2566 | if (It != m_decl_metadata.end()) | ||||||
2567 | return &It->second; | ||||||
2568 | return nullptr; | ||||||
2569 | } | ||||||
2570 | |||||||
2571 | ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Type *object) { | ||||||
2572 | auto It = m_type_metadata.find(object); | ||||||
2573 | if (It != m_type_metadata.end()) | ||||||
2574 | return &It->second; | ||||||
2575 | return nullptr; | ||||||
2576 | } | ||||||
2577 | |||||||
2578 | void TypeSystemClang::SetCXXRecordDeclAccess(const clang::CXXRecordDecl *object, | ||||||
2579 | clang::AccessSpecifier access) { | ||||||
2580 | if (access == clang::AccessSpecifier::AS_none) | ||||||
2581 | m_cxx_record_decl_access.erase(object); | ||||||
2582 | else | ||||||
2583 | m_cxx_record_decl_access[object] = access; | ||||||
2584 | } | ||||||
2585 | |||||||
2586 | clang::AccessSpecifier | ||||||
2587 | TypeSystemClang::GetCXXRecordDeclAccess(const clang::CXXRecordDecl *object) { | ||||||
2588 | auto It = m_cxx_record_decl_access.find(object); | ||||||
2589 | if (It != m_cxx_record_decl_access.end()) | ||||||
2590 | return It->second; | ||||||
2591 | return clang::AccessSpecifier::AS_none; | ||||||
2592 | } | ||||||
2593 | |||||||
2594 | clang::DeclContext * | ||||||
2595 | TypeSystemClang::GetDeclContextForType(const CompilerType &type) { | ||||||
2596 | return GetDeclContextForType(ClangUtil::GetQualType(type)); | ||||||
2597 | } | ||||||
2598 | |||||||
2599 | /// Aggressively desugar the provided type, skipping past various kinds of | ||||||
2600 | /// syntactic sugar and other constructs one typically wants to ignore. | ||||||
2601 | /// The \p mask argument allows one to skip certain kinds of simplifications, | ||||||
2602 | /// when one wishes to handle a certain kind of type directly. | ||||||
2603 | static QualType | ||||||
2604 | RemoveWrappingTypes(QualType type, ArrayRef<clang::Type::TypeClass> mask = {}) { | ||||||
2605 | while (true) { | ||||||
2606 | if (find(mask, type->getTypeClass()) != mask.end()) | ||||||
2607 | return type; | ||||||
2608 | switch (type->getTypeClass()) { | ||||||
2609 | // This is not fully correct as _Atomic is more than sugar, but it is | ||||||
2610 | // sufficient for the purposes we care about. | ||||||
2611 | case clang::Type::Atomic: | ||||||
2612 | type = cast<clang::AtomicType>(type)->getValueType(); | ||||||
2613 | break; | ||||||
2614 | case clang::Type::Auto: | ||||||
2615 | case clang::Type::Decltype: | ||||||
2616 | case clang::Type::Elaborated: | ||||||
2617 | case clang::Type::Paren: | ||||||
2618 | case clang::Type::SubstTemplateTypeParm: | ||||||
2619 | case clang::Type::TemplateSpecialization: | ||||||
2620 | case clang::Type::Typedef: | ||||||
2621 | case clang::Type::TypeOf: | ||||||
2622 | case clang::Type::TypeOfExpr: | ||||||
2623 | case clang::Type::Using: | ||||||
2624 | type = type->getLocallyUnqualifiedSingleStepDesugaredType(); | ||||||
2625 | break; | ||||||
2626 | default: | ||||||
2627 | return type; | ||||||
2628 | } | ||||||
2629 | } | ||||||
2630 | } | ||||||
2631 | |||||||
2632 | clang::DeclContext * | ||||||
2633 | TypeSystemClang::GetDeclContextForType(clang::QualType type) { | ||||||
2634 | if (type.isNull()) | ||||||
2635 | return nullptr; | ||||||
2636 | |||||||
2637 | clang::QualType qual_type = RemoveWrappingTypes(type.getCanonicalType()); | ||||||
2638 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
2639 | switch (type_class) { | ||||||
2640 | case clang::Type::ObjCInterface: | ||||||
2641 | return llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr()) | ||||||
2642 | ->getInterface(); | ||||||
2643 | case clang::Type::ObjCObjectPointer: | ||||||
2644 | return GetDeclContextForType( | ||||||
2645 | llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr()) | ||||||
2646 | ->getPointeeType()); | ||||||
2647 | case clang::Type::Record: | ||||||
2648 | return llvm::cast<clang::RecordType>(qual_type)->getDecl(); | ||||||
2649 | case clang::Type::Enum: | ||||||
2650 | return llvm::cast<clang::EnumType>(qual_type)->getDecl(); | ||||||
2651 | default: | ||||||
2652 | break; | ||||||
2653 | } | ||||||
2654 | // No DeclContext in this type... | ||||||
2655 | return nullptr; | ||||||
2656 | } | ||||||
2657 | |||||||
2658 | static bool GetCompleteQualType(clang::ASTContext *ast, | ||||||
2659 | clang::QualType qual_type, | ||||||
2660 | bool allow_completion = true) { | ||||||
2661 | qual_type = RemoveWrappingTypes(qual_type); | ||||||
2662 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
2663 | switch (type_class) { | ||||||
2664 | case clang::Type::ConstantArray: | ||||||
2665 | case clang::Type::IncompleteArray: | ||||||
2666 | case clang::Type::VariableArray: { | ||||||
2667 | const clang::ArrayType *array_type = | ||||||
2668 | llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr()); | ||||||
2669 | |||||||
2670 | if (array_type) | ||||||
2671 | return GetCompleteQualType(ast, array_type->getElementType(), | ||||||
2672 | allow_completion); | ||||||
2673 | } break; | ||||||
2674 | case clang::Type::Record: { | ||||||
2675 | clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); | ||||||
2676 | if (cxx_record_decl) { | ||||||
2677 | if (cxx_record_decl->hasExternalLexicalStorage()) { | ||||||
2678 | const bool is_complete = cxx_record_decl->isCompleteDefinition(); | ||||||
2679 | const bool fields_loaded = | ||||||
2680 | cxx_record_decl->hasLoadedFieldsFromExternalStorage(); | ||||||
2681 | if (is_complete && fields_loaded) | ||||||
2682 | return true; | ||||||
2683 | |||||||
2684 | if (!allow_completion) | ||||||
2685 | return false; | ||||||
2686 | |||||||
2687 | // Call the field_begin() accessor to for it to use the external source | ||||||
2688 | // to load the fields... | ||||||
2689 | clang::ExternalASTSource *external_ast_source = | ||||||
2690 | ast->getExternalSource(); | ||||||
2691 | if (external_ast_source) { | ||||||
2692 | external_ast_source->CompleteType(cxx_record_decl); | ||||||
2693 | if (cxx_record_decl->isCompleteDefinition()) { | ||||||
2694 | cxx_record_decl->field_begin(); | ||||||
2695 | cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); | ||||||
2696 | } | ||||||
2697 | } | ||||||
2698 | } | ||||||
2699 | } | ||||||
2700 | const clang::TagType *tag_type = | ||||||
2701 | llvm::cast<clang::TagType>(qual_type.getTypePtr()); | ||||||
2702 | return !tag_type->isIncompleteType(); | ||||||
2703 | } break; | ||||||
2704 | |||||||
2705 | case clang::Type::Enum: { | ||||||
2706 | const clang::TagType *tag_type = | ||||||
2707 | llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()); | ||||||
2708 | if (tag_type) { | ||||||
2709 | clang::TagDecl *tag_decl = tag_type->getDecl(); | ||||||
2710 | if (tag_decl) { | ||||||
2711 | if (tag_decl->getDefinition()) | ||||||
2712 | return true; | ||||||
2713 | |||||||
2714 | if (!allow_completion) | ||||||
2715 | return false; | ||||||
2716 | |||||||
2717 | if (tag_decl->hasExternalLexicalStorage()) { | ||||||
2718 | if (ast) { | ||||||
2719 | clang::ExternalASTSource *external_ast_source = | ||||||
2720 | ast->getExternalSource(); | ||||||
2721 | if (external_ast_source) { | ||||||
2722 | external_ast_source->CompleteType(tag_decl); | ||||||
2723 | return !tag_type->isIncompleteType(); | ||||||
2724 | } | ||||||
2725 | } | ||||||
2726 | } | ||||||
2727 | return false; | ||||||
2728 | } | ||||||
2729 | } | ||||||
2730 | |||||||
2731 | } break; | ||||||
2732 | case clang::Type::ObjCObject: | ||||||
2733 | case clang::Type::ObjCInterface: { | ||||||
2734 | const clang::ObjCObjectType *objc_class_type = | ||||||
2735 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type); | ||||||
2736 | if (objc_class_type) { | ||||||
2737 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
2738 | objc_class_type->getInterface(); | ||||||
2739 | // We currently can't complete objective C types through the newly added | ||||||
2740 | // ASTContext because it only supports TagDecl objects right now... | ||||||
2741 | if (class_interface_decl) { | ||||||
2742 | if (class_interface_decl->getDefinition()) | ||||||
2743 | return true; | ||||||
2744 | |||||||
2745 | if (!allow_completion) | ||||||
2746 | return false; | ||||||
2747 | |||||||
2748 | if (class_interface_decl->hasExternalLexicalStorage()) { | ||||||
2749 | if (ast) { | ||||||
2750 | clang::ExternalASTSource *external_ast_source = | ||||||
2751 | ast->getExternalSource(); | ||||||
2752 | if (external_ast_source) { | ||||||
2753 | external_ast_source->CompleteType(class_interface_decl); | ||||||
2754 | return !objc_class_type->isIncompleteType(); | ||||||
2755 | } | ||||||
2756 | } | ||||||
2757 | } | ||||||
2758 | return false; | ||||||
2759 | } | ||||||
2760 | } | ||||||
2761 | } break; | ||||||
2762 | |||||||
2763 | case clang::Type::Attributed: | ||||||
2764 | return GetCompleteQualType( | ||||||
2765 | ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(), | ||||||
2766 | allow_completion); | ||||||
2767 | |||||||
2768 | default: | ||||||
2769 | break; | ||||||
2770 | } | ||||||
2771 | |||||||
2772 | return true; | ||||||
2773 | } | ||||||
2774 | |||||||
2775 | static clang::ObjCIvarDecl::AccessControl | ||||||
2776 | ConvertAccessTypeToObjCIvarAccessControl(AccessType access) { | ||||||
2777 | switch (access) { | ||||||
2778 | case eAccessNone: | ||||||
2779 | return clang::ObjCIvarDecl::None; | ||||||
2780 | case eAccessPublic: | ||||||
2781 | return clang::ObjCIvarDecl::Public; | ||||||
2782 | case eAccessPrivate: | ||||||
2783 | return clang::ObjCIvarDecl::Private; | ||||||
2784 | case eAccessProtected: | ||||||
2785 | return clang::ObjCIvarDecl::Protected; | ||||||
2786 | case eAccessPackage: | ||||||
2787 | return clang::ObjCIvarDecl::Package; | ||||||
2788 | } | ||||||
2789 | return clang::ObjCIvarDecl::None; | ||||||
2790 | } | ||||||
2791 | |||||||
2792 | // Tests | ||||||
2793 | |||||||
2794 | #ifndef NDEBUG | ||||||
2795 | bool TypeSystemClang::Verify(lldb::opaque_compiler_type_t type) { | ||||||
2796 | return !type || llvm::isa<clang::Type>(GetQualType(type).getTypePtr()); | ||||||
2797 | } | ||||||
2798 | #endif | ||||||
2799 | |||||||
2800 | bool TypeSystemClang::IsAggregateType(lldb::opaque_compiler_type_t type) { | ||||||
2801 | clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); | ||||||
2802 | |||||||
2803 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
2804 | switch (type_class) { | ||||||
2805 | case clang::Type::IncompleteArray: | ||||||
2806 | case clang::Type::VariableArray: | ||||||
2807 | case clang::Type::ConstantArray: | ||||||
2808 | case clang::Type::ExtVector: | ||||||
2809 | case clang::Type::Vector: | ||||||
2810 | case clang::Type::Record: | ||||||
2811 | case clang::Type::ObjCObject: | ||||||
2812 | case clang::Type::ObjCInterface: | ||||||
2813 | return true; | ||||||
2814 | default: | ||||||
2815 | break; | ||||||
2816 | } | ||||||
2817 | // The clang type does have a value | ||||||
2818 | return false; | ||||||
2819 | } | ||||||
2820 | |||||||
2821 | bool TypeSystemClang::IsAnonymousType(lldb::opaque_compiler_type_t type) { | ||||||
2822 | clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); | ||||||
2823 | |||||||
2824 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
2825 | switch (type_class) { | ||||||
2826 | case clang::Type::Record: { | ||||||
2827 | if (const clang::RecordType *record_type = | ||||||
2828 | llvm::dyn_cast_or_null<clang::RecordType>( | ||||||
2829 | qual_type.getTypePtrOrNull())) { | ||||||
2830 | if (const clang::RecordDecl *record_decl = record_type->getDecl()) { | ||||||
2831 | return record_decl->isAnonymousStructOrUnion(); | ||||||
2832 | } | ||||||
2833 | } | ||||||
2834 | break; | ||||||
2835 | } | ||||||
2836 | default: | ||||||
2837 | break; | ||||||
2838 | } | ||||||
2839 | // The clang type does have a value | ||||||
2840 | return false; | ||||||
2841 | } | ||||||
2842 | |||||||
2843 | bool TypeSystemClang::IsArrayType(lldb::opaque_compiler_type_t type, | ||||||
2844 | CompilerType *element_type_ptr, | ||||||
2845 | uint64_t *size, bool *is_incomplete) { | ||||||
2846 | clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); | ||||||
2847 | |||||||
2848 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
2849 | switch (type_class) { | ||||||
2850 | default: | ||||||
2851 | break; | ||||||
2852 | |||||||
2853 | case clang::Type::ConstantArray: | ||||||
2854 | if (element_type_ptr) | ||||||
2855 | element_type_ptr->SetCompilerType( | ||||||
2856 | this, llvm::cast<clang::ConstantArrayType>(qual_type) | ||||||
2857 | ->getElementType() | ||||||
2858 | .getAsOpaquePtr()); | ||||||
2859 | if (size) | ||||||
2860 | *size = llvm::cast<clang::ConstantArrayType>(qual_type) | ||||||
2861 | ->getSize() | ||||||
2862 | .getLimitedValue(ULLONG_MAX(9223372036854775807LL*2ULL+1ULL)); | ||||||
2863 | if (is_incomplete) | ||||||
2864 | *is_incomplete = false; | ||||||
2865 | return true; | ||||||
2866 | |||||||
2867 | case clang::Type::IncompleteArray: | ||||||
2868 | if (element_type_ptr) | ||||||
2869 | element_type_ptr->SetCompilerType( | ||||||
2870 | this, llvm::cast<clang::IncompleteArrayType>(qual_type) | ||||||
2871 | ->getElementType() | ||||||
2872 | .getAsOpaquePtr()); | ||||||
2873 | if (size) | ||||||
2874 | *size = 0; | ||||||
2875 | if (is_incomplete) | ||||||
2876 | *is_incomplete = true; | ||||||
2877 | return true; | ||||||
2878 | |||||||
2879 | case clang::Type::VariableArray: | ||||||
2880 | if (element_type_ptr) | ||||||
2881 | element_type_ptr->SetCompilerType( | ||||||
2882 | this, llvm::cast<clang::VariableArrayType>(qual_type) | ||||||
2883 | ->getElementType() | ||||||
2884 | .getAsOpaquePtr()); | ||||||
2885 | if (size) | ||||||
2886 | *size = 0; | ||||||
2887 | if (is_incomplete) | ||||||
2888 | *is_incomplete = false; | ||||||
2889 | return true; | ||||||
2890 | |||||||
2891 | case clang::Type::DependentSizedArray: | ||||||
2892 | if (element_type_ptr) | ||||||
2893 | element_type_ptr->SetCompilerType( | ||||||
2894 | this, llvm::cast<clang::DependentSizedArrayType>(qual_type) | ||||||
2895 | ->getElementType() | ||||||
2896 | .getAsOpaquePtr()); | ||||||
2897 | if (size) | ||||||
2898 | *size = 0; | ||||||
2899 | if (is_incomplete) | ||||||
2900 | *is_incomplete = false; | ||||||
2901 | return true; | ||||||
2902 | } | ||||||
2903 | if (element_type_ptr) | ||||||
2904 | element_type_ptr->Clear(); | ||||||
2905 | if (size) | ||||||
2906 | *size = 0; | ||||||
2907 | if (is_incomplete) | ||||||
2908 | *is_incomplete = false; | ||||||
2909 | return false; | ||||||
2910 | } | ||||||
2911 | |||||||
2912 | bool TypeSystemClang::IsVectorType(lldb::opaque_compiler_type_t type, | ||||||
2913 | CompilerType *element_type, uint64_t *size) { | ||||||
2914 | clang::QualType qual_type(GetCanonicalQualType(type)); | ||||||
2915 | |||||||
2916 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
2917 | switch (type_class) { | ||||||
2918 | case clang::Type::Vector: { | ||||||
2919 | const clang::VectorType *vector_type = | ||||||
2920 | qual_type->getAs<clang::VectorType>(); | ||||||
2921 | if (vector_type) { | ||||||
2922 | if (size) | ||||||
2923 | *size = vector_type->getNumElements(); | ||||||
2924 | if (element_type) | ||||||
2925 | *element_type = GetType(vector_type->getElementType()); | ||||||
2926 | } | ||||||
2927 | return true; | ||||||
2928 | } break; | ||||||
2929 | case clang::Type::ExtVector: { | ||||||
2930 | const clang::ExtVectorType *ext_vector_type = | ||||||
2931 | qual_type->getAs<clang::ExtVectorType>(); | ||||||
2932 | if (ext_vector_type) { | ||||||
2933 | if (size) | ||||||
2934 | *size = ext_vector_type->getNumElements(); | ||||||
2935 | if (element_type) | ||||||
2936 | *element_type = | ||||||
2937 | CompilerType(this, ext_vector_type->getElementType().getAsOpaquePtr()); | ||||||
2938 | } | ||||||
2939 | return true; | ||||||
2940 | } | ||||||
2941 | default: | ||||||
2942 | break; | ||||||
2943 | } | ||||||
2944 | return false; | ||||||
2945 | } | ||||||
2946 | |||||||
2947 | bool TypeSystemClang::IsRuntimeGeneratedType( | ||||||
2948 | lldb::opaque_compiler_type_t type) { | ||||||
2949 | clang::DeclContext *decl_ctx = GetDeclContextForType(GetQualType(type)); | ||||||
2950 | if (!decl_ctx) | ||||||
2951 | return false; | ||||||
2952 | |||||||
2953 | if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx)) | ||||||
2954 | return false; | ||||||
2955 | |||||||
2956 | clang::ObjCInterfaceDecl *result_iface_decl = | ||||||
2957 | llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx); | ||||||
2958 | |||||||
2959 | ClangASTMetadata *ast_metadata = GetMetadata(result_iface_decl); | ||||||
2960 | if (!ast_metadata) | ||||||
2961 | return false; | ||||||
2962 | return (ast_metadata->GetISAPtr() != 0); | ||||||
2963 | } | ||||||
2964 | |||||||
2965 | bool TypeSystemClang::IsCharType(lldb::opaque_compiler_type_t type) { | ||||||
2966 | return GetQualType(type).getUnqualifiedType()->isCharType(); | ||||||
2967 | } | ||||||
2968 | |||||||
2969 | bool TypeSystemClang::IsCompleteType(lldb::opaque_compiler_type_t type) { | ||||||
2970 | // If the type hasn't been lazily completed yet, complete it now so that we | ||||||
2971 | // can give the caller an accurate answer whether the type actually has a | ||||||
2972 | // definition. Without completing the type now we would just tell the user | ||||||
2973 | // the current (internal) completeness state of the type and most users don't | ||||||
2974 | // care (or even know) about this behavior. | ||||||
2975 | const bool allow_completion = true; | ||||||
2976 | return GetCompleteQualType(&getASTContext(), GetQualType(type), | ||||||
2977 | allow_completion); | ||||||
2978 | } | ||||||
2979 | |||||||
2980 | bool TypeSystemClang::IsConst(lldb::opaque_compiler_type_t type) { | ||||||
2981 | return GetQualType(type).isConstQualified(); | ||||||
2982 | } | ||||||
2983 | |||||||
2984 | bool TypeSystemClang::IsCStringType(lldb::opaque_compiler_type_t type, | ||||||
2985 | uint32_t &length) { | ||||||
2986 | CompilerType pointee_or_element_clang_type; | ||||||
2987 | length = 0; | ||||||
2988 | Flags type_flags(GetTypeInfo(type, &pointee_or_element_clang_type)); | ||||||
2989 | |||||||
2990 | if (!pointee_or_element_clang_type.IsValid()) | ||||||
2991 | return false; | ||||||
2992 | |||||||
2993 | if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer)) { | ||||||
2994 | if (pointee_or_element_clang_type.IsCharType()) { | ||||||
2995 | if (type_flags.Test(eTypeIsArray)) { | ||||||
2996 | // We know the size of the array and it could be a C string since it is | ||||||
2997 | // an array of characters | ||||||
2998 | length = llvm::cast<clang::ConstantArrayType>( | ||||||
2999 | GetCanonicalQualType(type).getTypePtr()) | ||||||
3000 | ->getSize() | ||||||
3001 | .getLimitedValue(); | ||||||
3002 | } | ||||||
3003 | return true; | ||||||
3004 | } | ||||||
3005 | } | ||||||
3006 | return false; | ||||||
3007 | } | ||||||
3008 | |||||||
3009 | bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type) { | ||||||
3010 | if (type) { | ||||||
3011 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
3012 | |||||||
3013 | if (qual_type->isFunctionType()) { | ||||||
3014 | return true; | ||||||
3015 | } | ||||||
3016 | |||||||
3017 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3018 | switch (type_class) { | ||||||
3019 | default: | ||||||
3020 | break; | ||||||
3021 | case clang::Type::LValueReference: | ||||||
3022 | case clang::Type::RValueReference: { | ||||||
3023 | const clang::ReferenceType *reference_type = | ||||||
3024 | llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); | ||||||
3025 | if (reference_type) | ||||||
3026 | return IsFunctionType( | ||||||
3027 | reference_type->getPointeeType().getAsOpaquePtr()); | ||||||
3028 | } break; | ||||||
3029 | } | ||||||
3030 | } | ||||||
3031 | return false; | ||||||
3032 | } | ||||||
3033 | |||||||
3034 | // Used to detect "Homogeneous Floating-point Aggregates" | ||||||
3035 | uint32_t | ||||||
3036 | TypeSystemClang::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, | ||||||
3037 | CompilerType *base_type_ptr) { | ||||||
3038 | if (!type) | ||||||
3039 | return 0; | ||||||
3040 | |||||||
3041 | clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); | ||||||
3042 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3043 | switch (type_class) { | ||||||
3044 | case clang::Type::Record: | ||||||
3045 | if (GetCompleteType(type)) { | ||||||
3046 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
3047 | qual_type->getAsCXXRecordDecl(); | ||||||
3048 | if (cxx_record_decl) { | ||||||
3049 | if (cxx_record_decl->getNumBases() || cxx_record_decl->isDynamicClass()) | ||||||
3050 | return 0; | ||||||
3051 | } | ||||||
3052 | const clang::RecordType *record_type = | ||||||
3053 | llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
3054 | if (record_type) { | ||||||
3055 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
3056 | if (record_decl) { | ||||||
3057 | // We are looking for a structure that contains only floating point | ||||||
3058 | // types | ||||||
3059 | clang::RecordDecl::field_iterator field_pos, | ||||||
3060 | field_end = record_decl->field_end(); | ||||||
3061 | uint32_t num_fields = 0; | ||||||
3062 | bool is_hva = false; | ||||||
3063 | bool is_hfa = false; | ||||||
3064 | clang::QualType base_qual_type; | ||||||
3065 | uint64_t base_bitwidth = 0; | ||||||
3066 | for (field_pos = record_decl->field_begin(); field_pos != field_end; | ||||||
3067 | ++field_pos) { | ||||||
3068 | clang::QualType field_qual_type = field_pos->getType(); | ||||||
3069 | uint64_t field_bitwidth = getASTContext().getTypeSize(qual_type); | ||||||
3070 | if (field_qual_type->isFloatingType()) { | ||||||
3071 | if (field_qual_type->isComplexType()) | ||||||
3072 | return 0; | ||||||
3073 | else { | ||||||
3074 | if (num_fields == 0) | ||||||
3075 | base_qual_type = field_qual_type; | ||||||
3076 | else { | ||||||
3077 | if (is_hva) | ||||||
3078 | return 0; | ||||||
3079 | is_hfa = true; | ||||||
3080 | if (field_qual_type.getTypePtr() != | ||||||
3081 | base_qual_type.getTypePtr()) | ||||||
3082 | return 0; | ||||||
3083 | } | ||||||
3084 | } | ||||||
3085 | } else if (field_qual_type->isVectorType() || | ||||||
3086 | field_qual_type->isExtVectorType()) { | ||||||
3087 | if (num_fields == 0) { | ||||||
3088 | base_qual_type = field_qual_type; | ||||||
3089 | base_bitwidth = field_bitwidth; | ||||||
3090 | } else { | ||||||
3091 | if (is_hfa) | ||||||
3092 | return 0; | ||||||
3093 | is_hva = true; | ||||||
3094 | if (base_bitwidth != field_bitwidth) | ||||||
3095 | return 0; | ||||||
3096 | if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr()) | ||||||
3097 | return 0; | ||||||
3098 | } | ||||||
3099 | } else | ||||||
3100 | return 0; | ||||||
3101 | ++num_fields; | ||||||
3102 | } | ||||||
3103 | if (base_type_ptr) | ||||||
3104 | *base_type_ptr = CompilerType(this, base_qual_type.getAsOpaquePtr()); | ||||||
3105 | return num_fields; | ||||||
3106 | } | ||||||
3107 | } | ||||||
3108 | } | ||||||
3109 | break; | ||||||
3110 | |||||||
3111 | default: | ||||||
3112 | break; | ||||||
3113 | } | ||||||
3114 | return 0; | ||||||
3115 | } | ||||||
3116 | |||||||
3117 | size_t TypeSystemClang::GetNumberOfFunctionArguments( | ||||||
3118 | lldb::opaque_compiler_type_t type) { | ||||||
3119 | if (type) { | ||||||
3120 | clang::QualType qual_type(GetCanonicalQualType(type)); | ||||||
3121 | const clang::FunctionProtoType *func = | ||||||
3122 | llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr()); | ||||||
3123 | if (func) | ||||||
3124 | return func->getNumParams(); | ||||||
3125 | } | ||||||
3126 | return 0; | ||||||
3127 | } | ||||||
3128 | |||||||
3129 | CompilerType | ||||||
3130 | TypeSystemClang::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, | ||||||
3131 | const size_t index) { | ||||||
3132 | if (type) { | ||||||
3133 | clang::QualType qual_type(GetQualType(type)); | ||||||
3134 | const clang::FunctionProtoType *func = | ||||||
3135 | llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr()); | ||||||
3136 | if (func) { | ||||||
3137 | if (index < func->getNumParams()) | ||||||
3138 | return CompilerType(this, func->getParamType(index).getAsOpaquePtr()); | ||||||
3139 | } | ||||||
3140 | } | ||||||
3141 | return CompilerType(); | ||||||
3142 | } | ||||||
3143 | |||||||
3144 | bool TypeSystemClang::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { | ||||||
3145 | if (type) { | ||||||
3146 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
3147 | |||||||
3148 | if (qual_type->isFunctionPointerType()) | ||||||
3149 | return true; | ||||||
3150 | |||||||
3151 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3152 | switch (type_class) { | ||||||
3153 | default: | ||||||
3154 | break; | ||||||
3155 | |||||||
3156 | case clang::Type::LValueReference: | ||||||
3157 | case clang::Type::RValueReference: { | ||||||
3158 | const clang::ReferenceType *reference_type = | ||||||
3159 | llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); | ||||||
3160 | if (reference_type) | ||||||
3161 | return IsFunctionPointerType( | ||||||
3162 | reference_type->getPointeeType().getAsOpaquePtr()); | ||||||
3163 | } break; | ||||||
3164 | } | ||||||
3165 | } | ||||||
3166 | return false; | ||||||
3167 | } | ||||||
3168 | |||||||
3169 | bool TypeSystemClang::IsBlockPointerType( | ||||||
3170 | lldb::opaque_compiler_type_t type, | ||||||
3171 | CompilerType *function_pointer_type_ptr) { | ||||||
3172 | if (type) { | ||||||
3173 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
3174 | |||||||
3175 | if (qual_type->isBlockPointerType()) { | ||||||
3176 | if (function_pointer_type_ptr) { | ||||||
3177 | const clang::BlockPointerType *block_pointer_type = | ||||||
3178 | qual_type->getAs<clang::BlockPointerType>(); | ||||||
3179 | QualType pointee_type = block_pointer_type->getPointeeType(); | ||||||
3180 | QualType function_pointer_type = m_ast_up->getPointerType(pointee_type); | ||||||
3181 | *function_pointer_type_ptr = | ||||||
3182 | CompilerType(this, function_pointer_type.getAsOpaquePtr()); | ||||||
3183 | } | ||||||
3184 | return true; | ||||||
3185 | } | ||||||
3186 | |||||||
3187 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3188 | switch (type_class) { | ||||||
3189 | default: | ||||||
3190 | break; | ||||||
3191 | |||||||
3192 | case clang::Type::LValueReference: | ||||||
3193 | case clang::Type::RValueReference: { | ||||||
3194 | const clang::ReferenceType *reference_type = | ||||||
3195 | llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); | ||||||
3196 | if (reference_type) | ||||||
3197 | return IsBlockPointerType( | ||||||
3198 | reference_type->getPointeeType().getAsOpaquePtr(), | ||||||
3199 | function_pointer_type_ptr); | ||||||
3200 | } break; | ||||||
3201 | } | ||||||
3202 | } | ||||||
3203 | return false; | ||||||
3204 | } | ||||||
3205 | |||||||
3206 | bool TypeSystemClang::IsIntegerType(lldb::opaque_compiler_type_t type, | ||||||
3207 | bool &is_signed) { | ||||||
3208 | if (!type) | ||||||
3209 | return false; | ||||||
3210 | |||||||
3211 | clang::QualType qual_type(GetCanonicalQualType(type)); | ||||||
3212 | const clang::BuiltinType *builtin_type = | ||||||
3213 | llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal()); | ||||||
3214 | |||||||
3215 | if (builtin_type) { | ||||||
3216 | if (builtin_type->isInteger()) { | ||||||
3217 | is_signed = builtin_type->isSignedInteger(); | ||||||
3218 | return true; | ||||||
3219 | } | ||||||
3220 | } | ||||||
3221 | |||||||
3222 | return false; | ||||||
3223 | } | ||||||
3224 | |||||||
3225 | bool TypeSystemClang::IsEnumerationType(lldb::opaque_compiler_type_t type, | ||||||
3226 | bool &is_signed) { | ||||||
3227 | if (type) { | ||||||
3228 | const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>( | ||||||
3229 | GetCanonicalQualType(type)->getCanonicalTypeInternal()); | ||||||
3230 | |||||||
3231 | if (enum_type) { | ||||||
3232 | IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(), | ||||||
3233 | is_signed); | ||||||
3234 | return true; | ||||||
3235 | } | ||||||
3236 | } | ||||||
3237 | |||||||
3238 | return false; | ||||||
3239 | } | ||||||
3240 | |||||||
3241 | bool TypeSystemClang::IsScopedEnumerationType( | ||||||
3242 | lldb::opaque_compiler_type_t type) { | ||||||
3243 | if (type) { | ||||||
3244 | const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>( | ||||||
3245 | GetCanonicalQualType(type)->getCanonicalTypeInternal()); | ||||||
3246 | |||||||
3247 | if (enum_type) { | ||||||
3248 | return enum_type->isScopedEnumeralType(); | ||||||
3249 | } | ||||||
3250 | } | ||||||
3251 | |||||||
3252 | return false; | ||||||
3253 | } | ||||||
3254 | |||||||
3255 | bool TypeSystemClang::IsPointerType(lldb::opaque_compiler_type_t type, | ||||||
3256 | CompilerType *pointee_type) { | ||||||
3257 | if (type) { | ||||||
3258 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
3259 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3260 | switch (type_class) { | ||||||
3261 | case clang::Type::Builtin: | ||||||
3262 | switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) { | ||||||
3263 | default: | ||||||
3264 | break; | ||||||
3265 | case clang::BuiltinType::ObjCId: | ||||||
3266 | case clang::BuiltinType::ObjCClass: | ||||||
3267 | return true; | ||||||
3268 | } | ||||||
3269 | return false; | ||||||
3270 | case clang::Type::ObjCObjectPointer: | ||||||
3271 | if (pointee_type) | ||||||
3272 | pointee_type->SetCompilerType( | ||||||
3273 | this, llvm::cast<clang::ObjCObjectPointerType>(qual_type) | ||||||
3274 | ->getPointeeType() | ||||||
3275 | .getAsOpaquePtr()); | ||||||
3276 | return true; | ||||||
3277 | case clang::Type::BlockPointer: | ||||||
3278 | if (pointee_type) | ||||||
3279 | pointee_type->SetCompilerType( | ||||||
3280 | this, llvm::cast<clang::BlockPointerType>(qual_type) | ||||||
3281 | ->getPointeeType() | ||||||
3282 | .getAsOpaquePtr()); | ||||||
3283 | return true; | ||||||
3284 | case clang::Type::Pointer: | ||||||
3285 | if (pointee_type) | ||||||
3286 | pointee_type->SetCompilerType(this, | ||||||
3287 | llvm::cast<clang::PointerType>(qual_type) | ||||||
3288 | ->getPointeeType() | ||||||
3289 | .getAsOpaquePtr()); | ||||||
3290 | return true; | ||||||
3291 | case clang::Type::MemberPointer: | ||||||
3292 | if (pointee_type) | ||||||
3293 | pointee_type->SetCompilerType( | ||||||
3294 | this, llvm::cast<clang::MemberPointerType>(qual_type) | ||||||
3295 | ->getPointeeType() | ||||||
3296 | .getAsOpaquePtr()); | ||||||
3297 | return true; | ||||||
3298 | default: | ||||||
3299 | break; | ||||||
3300 | } | ||||||
3301 | } | ||||||
3302 | if (pointee_type) | ||||||
3303 | pointee_type->Clear(); | ||||||
3304 | return false; | ||||||
3305 | } | ||||||
3306 | |||||||
3307 | bool TypeSystemClang::IsPointerOrReferenceType( | ||||||
3308 | lldb::opaque_compiler_type_t type, CompilerType *pointee_type) { | ||||||
3309 | if (type) { | ||||||
3310 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
3311 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3312 | switch (type_class) { | ||||||
3313 | case clang::Type::Builtin: | ||||||
3314 | switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) { | ||||||
3315 | default: | ||||||
3316 | break; | ||||||
3317 | case clang::BuiltinType::ObjCId: | ||||||
3318 | case clang::BuiltinType::ObjCClass: | ||||||
3319 | return true; | ||||||
3320 | } | ||||||
3321 | return false; | ||||||
3322 | case clang::Type::ObjCObjectPointer: | ||||||
3323 | if (pointee_type) | ||||||
3324 | pointee_type->SetCompilerType( | ||||||
3325 | this, llvm::cast<clang::ObjCObjectPointerType>(qual_type) | ||||||
3326 | ->getPointeeType().getAsOpaquePtr()); | ||||||
3327 | return true; | ||||||
3328 | case clang::Type::BlockPointer: | ||||||
3329 | if (pointee_type) | ||||||
3330 | pointee_type->SetCompilerType( | ||||||
3331 | this, llvm::cast<clang::BlockPointerType>(qual_type) | ||||||
3332 | ->getPointeeType() | ||||||
3333 | .getAsOpaquePtr()); | ||||||
3334 | return true; | ||||||
3335 | case clang::Type::Pointer: | ||||||
3336 | if (pointee_type) | ||||||
3337 | pointee_type->SetCompilerType(this, | ||||||
3338 | llvm::cast<clang::PointerType>(qual_type) | ||||||
3339 | ->getPointeeType() | ||||||
3340 | .getAsOpaquePtr()); | ||||||
3341 | return true; | ||||||
3342 | case clang::Type::MemberPointer: | ||||||
3343 | if (pointee_type) | ||||||
3344 | pointee_type->SetCompilerType( | ||||||
3345 | this, llvm::cast<clang::MemberPointerType>(qual_type) | ||||||
3346 | ->getPointeeType() | ||||||
3347 | .getAsOpaquePtr()); | ||||||
3348 | return true; | ||||||
3349 | case clang::Type::LValueReference: | ||||||
3350 | if (pointee_type) | ||||||
3351 | pointee_type->SetCompilerType( | ||||||
3352 | this, llvm::cast<clang::LValueReferenceType>(qual_type) | ||||||
3353 | ->desugar() | ||||||
3354 | .getAsOpaquePtr()); | ||||||
3355 | return true; | ||||||
3356 | case clang::Type::RValueReference: | ||||||
3357 | if (pointee_type) | ||||||
3358 | pointee_type->SetCompilerType( | ||||||
3359 | this, llvm::cast<clang::RValueReferenceType>(qual_type) | ||||||
3360 | ->desugar() | ||||||
3361 | .getAsOpaquePtr()); | ||||||
3362 | return true; | ||||||
3363 | default: | ||||||
3364 | break; | ||||||
3365 | } | ||||||
3366 | } | ||||||
3367 | if (pointee_type) | ||||||
3368 | pointee_type->Clear(); | ||||||
3369 | return false; | ||||||
3370 | } | ||||||
3371 | |||||||
3372 | bool TypeSystemClang::IsReferenceType(lldb::opaque_compiler_type_t type, | ||||||
3373 | CompilerType *pointee_type, | ||||||
3374 | bool *is_rvalue) { | ||||||
3375 | if (type) { | ||||||
3376 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
3377 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3378 | |||||||
3379 | switch (type_class) { | ||||||
3380 | case clang::Type::LValueReference: | ||||||
3381 | if (pointee_type) | ||||||
3382 | pointee_type->SetCompilerType( | ||||||
3383 | this, llvm::cast<clang::LValueReferenceType>(qual_type) | ||||||
3384 | ->desugar() | ||||||
3385 | .getAsOpaquePtr()); | ||||||
3386 | if (is_rvalue) | ||||||
3387 | *is_rvalue = false; | ||||||
3388 | return true; | ||||||
3389 | case clang::Type::RValueReference: | ||||||
3390 | if (pointee_type) | ||||||
3391 | pointee_type->SetCompilerType( | ||||||
3392 | this, llvm::cast<clang::RValueReferenceType>(qual_type) | ||||||
3393 | ->desugar() | ||||||
3394 | .getAsOpaquePtr()); | ||||||
3395 | if (is_rvalue) | ||||||
3396 | *is_rvalue = true; | ||||||
3397 | return true; | ||||||
3398 | |||||||
3399 | default: | ||||||
3400 | break; | ||||||
3401 | } | ||||||
3402 | } | ||||||
3403 | if (pointee_type) | ||||||
3404 | pointee_type->Clear(); | ||||||
3405 | return false; | ||||||
3406 | } | ||||||
3407 | |||||||
3408 | bool TypeSystemClang::IsFloatingPointType(lldb::opaque_compiler_type_t type, | ||||||
3409 | uint32_t &count, bool &is_complex) { | ||||||
3410 | if (type) { | ||||||
3411 | clang::QualType qual_type(GetCanonicalQualType(type)); | ||||||
3412 | |||||||
3413 | if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>( | ||||||
3414 | qual_type->getCanonicalTypeInternal())) { | ||||||
3415 | clang::BuiltinType::Kind kind = BT->getKind(); | ||||||
3416 | if (kind >= clang::BuiltinType::Float && | ||||||
3417 | kind <= clang::BuiltinType::LongDouble) { | ||||||
3418 | count = 1; | ||||||
3419 | is_complex = false; | ||||||
3420 | return true; | ||||||
3421 | } | ||||||
3422 | } else if (const clang::ComplexType *CT = | ||||||
3423 | llvm::dyn_cast<clang::ComplexType>( | ||||||
3424 | qual_type->getCanonicalTypeInternal())) { | ||||||
3425 | if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, | ||||||
3426 | is_complex)) { | ||||||
3427 | count = 2; | ||||||
3428 | is_complex = true; | ||||||
3429 | return true; | ||||||
3430 | } | ||||||
3431 | } else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>( | ||||||
3432 | qual_type->getCanonicalTypeInternal())) { | ||||||
3433 | if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, | ||||||
3434 | is_complex)) { | ||||||
3435 | count = VT->getNumElements(); | ||||||
3436 | is_complex = false; | ||||||
3437 | return true; | ||||||
3438 | } | ||||||
3439 | } | ||||||
3440 | } | ||||||
3441 | count = 0; | ||||||
3442 | is_complex = false; | ||||||
3443 | return false; | ||||||
3444 | } | ||||||
3445 | |||||||
3446 | bool TypeSystemClang::IsDefined(lldb::opaque_compiler_type_t type) { | ||||||
3447 | if (!type) | ||||||
3448 | return false; | ||||||
3449 | |||||||
3450 | clang::QualType qual_type(GetQualType(type)); | ||||||
3451 | const clang::TagType *tag_type = | ||||||
3452 | llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()); | ||||||
3453 | if (tag_type) { | ||||||
3454 | clang::TagDecl *tag_decl = tag_type->getDecl(); | ||||||
3455 | if (tag_decl) | ||||||
3456 | return tag_decl->isCompleteDefinition(); | ||||||
3457 | return false; | ||||||
3458 | } else { | ||||||
3459 | const clang::ObjCObjectType *objc_class_type = | ||||||
3460 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type); | ||||||
3461 | if (objc_class_type) { | ||||||
3462 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
3463 | objc_class_type->getInterface(); | ||||||
3464 | if (class_interface_decl) | ||||||
3465 | return class_interface_decl->getDefinition() != nullptr; | ||||||
3466 | return false; | ||||||
3467 | } | ||||||
3468 | } | ||||||
3469 | return true; | ||||||
3470 | } | ||||||
3471 | |||||||
3472 | bool TypeSystemClang::IsObjCClassType(const CompilerType &type) { | ||||||
3473 | if (ClangUtil::IsClangType(type)) { | ||||||
3474 | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); | ||||||
3475 | |||||||
3476 | const clang::ObjCObjectPointerType *obj_pointer_type = | ||||||
3477 | llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type); | ||||||
3478 | |||||||
3479 | if (obj_pointer_type) | ||||||
3480 | return obj_pointer_type->isObjCClassType(); | ||||||
3481 | } | ||||||
3482 | return false; | ||||||
3483 | } | ||||||
3484 | |||||||
3485 | bool TypeSystemClang::IsObjCObjectOrInterfaceType(const CompilerType &type) { | ||||||
3486 | if (ClangUtil::IsClangType(type)) | ||||||
3487 | return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType(); | ||||||
3488 | return false; | ||||||
3489 | } | ||||||
3490 | |||||||
3491 | bool TypeSystemClang::IsClassType(lldb::opaque_compiler_type_t type) { | ||||||
3492 | if (!type) | ||||||
3493 | return false; | ||||||
3494 | clang::QualType qual_type(GetCanonicalQualType(type)); | ||||||
3495 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3496 | return (type_class == clang::Type::Record); | ||||||
3497 | } | ||||||
3498 | |||||||
3499 | bool TypeSystemClang::IsEnumType(lldb::opaque_compiler_type_t type) { | ||||||
3500 | if (!type) | ||||||
3501 | return false; | ||||||
3502 | clang::QualType qual_type(GetCanonicalQualType(type)); | ||||||
3503 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3504 | return (type_class == clang::Type::Enum); | ||||||
3505 | } | ||||||
3506 | |||||||
3507 | bool TypeSystemClang::IsPolymorphicClass(lldb::opaque_compiler_type_t type) { | ||||||
3508 | if (type) { | ||||||
3509 | clang::QualType qual_type(GetCanonicalQualType(type)); | ||||||
3510 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3511 | switch (type_class) { | ||||||
3512 | case clang::Type::Record: | ||||||
3513 | if (GetCompleteType(type)) { | ||||||
3514 | const clang::RecordType *record_type = | ||||||
3515 | llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
3516 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
3517 | if (record_decl) { | ||||||
3518 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
3519 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); | ||||||
3520 | if (cxx_record_decl) | ||||||
3521 | return cxx_record_decl->isPolymorphic(); | ||||||
3522 | } | ||||||
3523 | } | ||||||
3524 | break; | ||||||
3525 | |||||||
3526 | default: | ||||||
3527 | break; | ||||||
3528 | } | ||||||
3529 | } | ||||||
3530 | return false; | ||||||
3531 | } | ||||||
3532 | |||||||
3533 | bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type, | ||||||
3534 | CompilerType *dynamic_pointee_type, | ||||||
3535 | bool check_cplusplus, | ||||||
3536 | bool check_objc) { | ||||||
3537 | clang::QualType pointee_qual_type; | ||||||
3538 | if (type) { | ||||||
3539 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
3540 | bool success = false; | ||||||
3541 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3542 | switch (type_class) { | ||||||
3543 | case clang::Type::Builtin: | ||||||
3544 | if (check_objc && | ||||||
3545 | llvm::cast<clang::BuiltinType>(qual_type)->getKind() == | ||||||
3546 | clang::BuiltinType::ObjCId) { | ||||||
3547 | if (dynamic_pointee_type) | ||||||
3548 | dynamic_pointee_type->SetCompilerType(this, type); | ||||||
3549 | return true; | ||||||
3550 | } | ||||||
3551 | break; | ||||||
3552 | |||||||
3553 | case clang::Type::ObjCObjectPointer: | ||||||
3554 | if (check_objc) { | ||||||
3555 | if (const auto *objc_pointee_type = | ||||||
3556 | qual_type->getPointeeType().getTypePtrOrNull()) { | ||||||
3557 | if (const auto *objc_object_type = | ||||||
3558 | llvm::dyn_cast_or_null<clang::ObjCObjectType>( | ||||||
3559 | objc_pointee_type)) { | ||||||
3560 | if (objc_object_type->isObjCClass()) | ||||||
3561 | return false; | ||||||
3562 | } | ||||||
3563 | } | ||||||
3564 | if (dynamic_pointee_type) | ||||||
3565 | dynamic_pointee_type->SetCompilerType( | ||||||
3566 | this, llvm::cast<clang::ObjCObjectPointerType>(qual_type) | ||||||
3567 | ->getPointeeType() | ||||||
3568 | .getAsOpaquePtr()); | ||||||
3569 | return true; | ||||||
3570 | } | ||||||
3571 | break; | ||||||
3572 | |||||||
3573 | case clang::Type::Pointer: | ||||||
3574 | pointee_qual_type = | ||||||
3575 | llvm::cast<clang::PointerType>(qual_type)->getPointeeType(); | ||||||
3576 | success = true; | ||||||
3577 | break; | ||||||
3578 | |||||||
3579 | case clang::Type::LValueReference: | ||||||
3580 | case clang::Type::RValueReference: | ||||||
3581 | pointee_qual_type = | ||||||
3582 | llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType(); | ||||||
3583 | success = true; | ||||||
3584 | break; | ||||||
3585 | |||||||
3586 | default: | ||||||
3587 | break; | ||||||
3588 | } | ||||||
3589 | |||||||
3590 | if (success) { | ||||||
3591 | // Check to make sure what we are pointing too is a possible dynamic C++ | ||||||
3592 | // type We currently accept any "void *" (in case we have a class that | ||||||
3593 | // has been watered down to an opaque pointer) and virtual C++ classes. | ||||||
3594 | const clang::Type::TypeClass pointee_type_class = | ||||||
3595 | pointee_qual_type.getCanonicalType()->getTypeClass(); | ||||||
3596 | switch (pointee_type_class) { | ||||||
3597 | case clang::Type::Builtin: | ||||||
3598 | switch (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind()) { | ||||||
3599 | case clang::BuiltinType::UnknownAny: | ||||||
3600 | case clang::BuiltinType::Void: | ||||||
3601 | if (dynamic_pointee_type) | ||||||
3602 | dynamic_pointee_type->SetCompilerType( | ||||||
3603 | this, pointee_qual_type.getAsOpaquePtr()); | ||||||
3604 | return true; | ||||||
3605 | default: | ||||||
3606 | break; | ||||||
3607 | } | ||||||
3608 | break; | ||||||
3609 | |||||||
3610 | case clang::Type::Record: | ||||||
3611 | if (check_cplusplus) { | ||||||
3612 | clang::CXXRecordDecl *cxx_record_decl = | ||||||
3613 | pointee_qual_type->getAsCXXRecordDecl(); | ||||||
3614 | if (cxx_record_decl) { | ||||||
3615 | bool is_complete = cxx_record_decl->isCompleteDefinition(); | ||||||
3616 | |||||||
3617 | if (is_complete) | ||||||
3618 | success = cxx_record_decl->isDynamicClass(); | ||||||
3619 | else { | ||||||
3620 | ClangASTMetadata *metadata = GetMetadata(cxx_record_decl); | ||||||
3621 | if (metadata) | ||||||
3622 | success = metadata->GetIsDynamicCXXType(); | ||||||
3623 | else { | ||||||
3624 | is_complete = GetType(pointee_qual_type).GetCompleteType(); | ||||||
3625 | if (is_complete) | ||||||
3626 | success = cxx_record_decl->isDynamicClass(); | ||||||
3627 | else | ||||||
3628 | success = false; | ||||||
3629 | } | ||||||
3630 | } | ||||||
3631 | |||||||
3632 | if (success) { | ||||||
3633 | if (dynamic_pointee_type) | ||||||
3634 | dynamic_pointee_type->SetCompilerType( | ||||||
3635 | this, pointee_qual_type.getAsOpaquePtr()); | ||||||
3636 | return true; | ||||||
3637 | } | ||||||
3638 | } | ||||||
3639 | } | ||||||
3640 | break; | ||||||
3641 | |||||||
3642 | case clang::Type::ObjCObject: | ||||||
3643 | case clang::Type::ObjCInterface: | ||||||
3644 | if (check_objc) { | ||||||
3645 | if (dynamic_pointee_type) | ||||||
3646 | dynamic_pointee_type->SetCompilerType( | ||||||
3647 | this, pointee_qual_type.getAsOpaquePtr()); | ||||||
3648 | return true; | ||||||
3649 | } | ||||||
3650 | break; | ||||||
3651 | |||||||
3652 | default: | ||||||
3653 | break; | ||||||
3654 | } | ||||||
3655 | } | ||||||
3656 | } | ||||||
3657 | if (dynamic_pointee_type) | ||||||
3658 | dynamic_pointee_type->Clear(); | ||||||
3659 | return false; | ||||||
3660 | } | ||||||
3661 | |||||||
3662 | bool TypeSystemClang::IsScalarType(lldb::opaque_compiler_type_t type) { | ||||||
3663 | if (!type) | ||||||
3664 | return false; | ||||||
3665 | |||||||
3666 | return (GetTypeInfo(type, nullptr) & eTypeIsScalar) != 0; | ||||||
3667 | } | ||||||
3668 | |||||||
3669 | bool TypeSystemClang::IsTypedefType(lldb::opaque_compiler_type_t type) { | ||||||
3670 | if (!type) | ||||||
3671 | return false; | ||||||
3672 | return RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}) | ||||||
3673 | ->getTypeClass() == clang::Type::Typedef; | ||||||
3674 | } | ||||||
3675 | |||||||
3676 | bool TypeSystemClang::IsVoidType(lldb::opaque_compiler_type_t type) { | ||||||
3677 | if (!type) | ||||||
3678 | return false; | ||||||
3679 | return GetCanonicalQualType(type)->isVoidType(); | ||||||
3680 | } | ||||||
3681 | |||||||
3682 | bool TypeSystemClang::CanPassInRegisters(const CompilerType &type) { | ||||||
3683 | if (auto *record_decl = | ||||||
3684 | TypeSystemClang::GetAsRecordDecl(type)) { | ||||||
3685 | return record_decl->canPassInRegisters(); | ||||||
3686 | } | ||||||
3687 | return false; | ||||||
3688 | } | ||||||
3689 | |||||||
3690 | bool TypeSystemClang::SupportsLanguage(lldb::LanguageType language) { | ||||||
3691 | return TypeSystemClangSupportsLanguage(language); | ||||||
3692 | } | ||||||
3693 | |||||||
3694 | Optional<std::string> | ||||||
3695 | TypeSystemClang::GetCXXClassName(const CompilerType &type) { | ||||||
3696 | if (!type) | ||||||
3697 | return llvm::None; | ||||||
3698 | |||||||
3699 | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); | ||||||
3700 | if (qual_type.isNull()) | ||||||
3701 | return llvm::None; | ||||||
3702 | |||||||
3703 | clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); | ||||||
3704 | if (!cxx_record_decl) | ||||||
3705 | return llvm::None; | ||||||
3706 | |||||||
3707 | return std::string(cxx_record_decl->getIdentifier()->getNameStart()); | ||||||
3708 | } | ||||||
3709 | |||||||
3710 | bool TypeSystemClang::IsCXXClassType(const CompilerType &type) { | ||||||
3711 | if (!type) | ||||||
3712 | return false; | ||||||
3713 | |||||||
3714 | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); | ||||||
3715 | return !qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr; | ||||||
3716 | } | ||||||
3717 | |||||||
3718 | bool TypeSystemClang::IsBeingDefined(lldb::opaque_compiler_type_t type) { | ||||||
3719 | if (!type) | ||||||
3720 | return false; | ||||||
3721 | clang::QualType qual_type(GetCanonicalQualType(type)); | ||||||
3722 | const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type); | ||||||
3723 | if (tag_type) | ||||||
3724 | return tag_type->isBeingDefined(); | ||||||
3725 | return false; | ||||||
3726 | } | ||||||
3727 | |||||||
3728 | bool TypeSystemClang::IsObjCObjectPointerType(const CompilerType &type, | ||||||
3729 | CompilerType *class_type_ptr) { | ||||||
3730 | if (!ClangUtil::IsClangType(type)) | ||||||
3731 | return false; | ||||||
3732 | |||||||
3733 | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); | ||||||
3734 | |||||||
3735 | if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) { | ||||||
3736 | if (class_type_ptr) { | ||||||
3737 | if (!qual_type->isObjCClassType() && !qual_type->isObjCIdType()) { | ||||||
3738 | const clang::ObjCObjectPointerType *obj_pointer_type = | ||||||
3739 | llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type); | ||||||
3740 | if (obj_pointer_type == nullptr) | ||||||
3741 | class_type_ptr->Clear(); | ||||||
3742 | else | ||||||
3743 | class_type_ptr->SetCompilerType( | ||||||
3744 | type.GetTypeSystem(), | ||||||
3745 | clang::QualType(obj_pointer_type->getInterfaceType(), 0) | ||||||
3746 | .getAsOpaquePtr()); | ||||||
3747 | } | ||||||
3748 | } | ||||||
3749 | return true; | ||||||
3750 | } | ||||||
3751 | if (class_type_ptr) | ||||||
3752 | class_type_ptr->Clear(); | ||||||
3753 | return false; | ||||||
3754 | } | ||||||
3755 | |||||||
3756 | // Type Completion | ||||||
3757 | |||||||
3758 | bool TypeSystemClang::GetCompleteType(lldb::opaque_compiler_type_t type) { | ||||||
3759 | if (!type) | ||||||
3760 | return false; | ||||||
3761 | const bool allow_completion = true; | ||||||
3762 | return GetCompleteQualType(&getASTContext(), GetQualType(type), | ||||||
3763 | allow_completion); | ||||||
3764 | } | ||||||
3765 | |||||||
3766 | ConstString TypeSystemClang::GetTypeName(lldb::opaque_compiler_type_t type) { | ||||||
3767 | if (!type) | ||||||
3768 | return ConstString(); | ||||||
3769 | |||||||
3770 | clang::QualType qual_type(GetQualType(type)); | ||||||
3771 | |||||||
3772 | // Remove certain type sugar from the name. Sugar such as elaborated types | ||||||
3773 | // or template types which only serve to improve diagnostics shouldn't | ||||||
3774 | // act as their own types from the user's perspective (e.g., formatter | ||||||
3775 | // shouldn't format a variable differently depending on how the ser has | ||||||
3776 | // specified the type. '::Type' and 'Type' should behave the same). | ||||||
3777 | // Typedefs and atomic derived types are not removed as they are actually | ||||||
3778 | // useful for identifiying specific types. | ||||||
3779 | qual_type = RemoveWrappingTypes(qual_type, | ||||||
3780 | {clang::Type::Typedef, clang::Type::Atomic}); | ||||||
3781 | |||||||
3782 | // For a typedef just return the qualified name. | ||||||
3783 | if (const auto *typedef_type = qual_type->getAs<clang::TypedefType>()) { | ||||||
3784 | const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); | ||||||
3785 | return ConstString(GetTypeNameForDecl(typedef_decl)); | ||||||
3786 | } | ||||||
3787 | |||||||
3788 | return ConstString(qual_type.getAsString(GetTypePrintingPolicy())); | ||||||
3789 | } | ||||||
3790 | |||||||
3791 | ConstString | ||||||
3792 | TypeSystemClang::GetDisplayTypeName(lldb::opaque_compiler_type_t type) { | ||||||
3793 | if (!type) | ||||||
3794 | return ConstString(); | ||||||
3795 | |||||||
3796 | clang::QualType qual_type(GetQualType(type)); | ||||||
3797 | clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy()); | ||||||
3798 | printing_policy.SuppressTagKeyword = true; | ||||||
3799 | printing_policy.SuppressScope = false; | ||||||
3800 | printing_policy.SuppressUnwrittenScope = true; | ||||||
3801 | printing_policy.SuppressInlineNamespace = true; | ||||||
3802 | return ConstString(qual_type.getAsString(printing_policy)); | ||||||
3803 | } | ||||||
3804 | |||||||
3805 | uint32_t | ||||||
3806 | TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type, | ||||||
3807 | CompilerType *pointee_or_element_clang_type) { | ||||||
3808 | if (!type) | ||||||
3809 | return 0; | ||||||
3810 | |||||||
3811 | if (pointee_or_element_clang_type) | ||||||
3812 | pointee_or_element_clang_type->Clear(); | ||||||
3813 | |||||||
3814 | clang::QualType qual_type = | ||||||
3815 | RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}); | ||||||
3816 | |||||||
3817 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
3818 | switch (type_class) { | ||||||
3819 | case clang::Type::Attributed: | ||||||
3820 | return GetTypeInfo( | ||||||
3821 | qual_type->getAs<clang::AttributedType>() | ||||||
3822 | ->getModifiedType().getAsOpaquePtr(), | ||||||
3823 | pointee_or_element_clang_type); | ||||||
3824 | case clang::Type::Builtin: { | ||||||
3825 | const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>( | ||||||
3826 | qual_type->getCanonicalTypeInternal()); | ||||||
3827 | |||||||
3828 | uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue; | ||||||
3829 | switch (builtin_type->getKind()) { | ||||||
3830 | case clang::BuiltinType::ObjCId: | ||||||
3831 | case clang::BuiltinType::ObjCClass: | ||||||
3832 | if (pointee_or_element_clang_type) | ||||||
3833 | pointee_or_element_clang_type->SetCompilerType( | ||||||
3834 | this, getASTContext().ObjCBuiltinClassTy.getAsOpaquePtr()); | ||||||
3835 | builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; | ||||||
3836 | break; | ||||||
3837 | |||||||
3838 | case clang::BuiltinType::ObjCSel: | ||||||
3839 | if (pointee_or_element_clang_type) | ||||||
3840 | pointee_or_element_clang_type->SetCompilerType( | ||||||
3841 | this, getASTContext().CharTy.getAsOpaquePtr()); | ||||||
3842 | builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; | ||||||
3843 | break; | ||||||
3844 | |||||||
3845 | case clang::BuiltinType::Bool: | ||||||
3846 | case clang::BuiltinType::Char_U: | ||||||
3847 | case clang::BuiltinType::UChar: | ||||||
3848 | case clang::BuiltinType::WChar_U: | ||||||
3849 | case clang::BuiltinType::Char16: | ||||||
3850 | case clang::BuiltinType::Char32: | ||||||
3851 | case clang::BuiltinType::UShort: | ||||||
3852 | case clang::BuiltinType::UInt: | ||||||
3853 | case clang::BuiltinType::ULong: | ||||||
3854 | case clang::BuiltinType::ULongLong: | ||||||
3855 | case clang::BuiltinType::UInt128: | ||||||
3856 | case clang::BuiltinType::Char_S: | ||||||
3857 | case clang::BuiltinType::SChar: | ||||||
3858 | case clang::BuiltinType::WChar_S: | ||||||
3859 | case clang::BuiltinType::Short: | ||||||
3860 | case clang::BuiltinType::Int: | ||||||
3861 | case clang::BuiltinType::Long: | ||||||
3862 | case clang::BuiltinType::LongLong: | ||||||
3863 | case clang::BuiltinType::Int128: | ||||||
3864 | case clang::BuiltinType::Float: | ||||||
3865 | case clang::BuiltinType::Double: | ||||||
3866 | case clang::BuiltinType::LongDouble: | ||||||
3867 | builtin_type_flags |= eTypeIsScalar; | ||||||
3868 | if (builtin_type->isInteger()) { | ||||||
3869 | builtin_type_flags |= eTypeIsInteger; | ||||||
3870 | if (builtin_type->isSignedInteger()) | ||||||
3871 | builtin_type_flags |= eTypeIsSigned; | ||||||
3872 | } else if (builtin_type->isFloatingPoint()) | ||||||
3873 | builtin_type_flags |= eTypeIsFloat; | ||||||
3874 | break; | ||||||
3875 | default: | ||||||
3876 | break; | ||||||
3877 | } | ||||||
3878 | return builtin_type_flags; | ||||||
3879 | } | ||||||
3880 | |||||||
3881 | case clang::Type::BlockPointer: | ||||||
3882 | if (pointee_or_element_clang_type) | ||||||
3883 | pointee_or_element_clang_type->SetCompilerType( | ||||||
3884 | this, qual_type->getPointeeType().getAsOpaquePtr()); | ||||||
3885 | return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock; | ||||||
3886 | |||||||
3887 | case clang::Type::Complex: { | ||||||
3888 | uint32_t complex_type_flags = | ||||||
3889 | eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex; | ||||||
3890 | const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>( | ||||||
3891 | qual_type->getCanonicalTypeInternal()); | ||||||
3892 | if (complex_type) { | ||||||
3893 | clang::QualType complex_element_type(complex_type->getElementType()); | ||||||
3894 | if (complex_element_type->isIntegerType()) | ||||||
3895 | complex_type_flags |= eTypeIsFloat; | ||||||
3896 | else if (complex_element_type->isFloatingType()) | ||||||
3897 | complex_type_flags |= eTypeIsInteger; | ||||||
3898 | } | ||||||
3899 | return complex_type_flags; | ||||||
3900 | } break; | ||||||
3901 | |||||||
3902 | case clang::Type::ConstantArray: | ||||||
3903 | case clang::Type::DependentSizedArray: | ||||||
3904 | case clang::Type::IncompleteArray: | ||||||
3905 | case clang::Type::VariableArray: | ||||||
3906 | if (pointee_or_element_clang_type) | ||||||
3907 | pointee_or_element_clang_type->SetCompilerType( | ||||||
3908 | this, llvm::cast<clang::ArrayType>(qual_type.getTypePtr()) | ||||||
3909 | ->getElementType() | ||||||
3910 | .getAsOpaquePtr()); | ||||||
3911 | return eTypeHasChildren | eTypeIsArray; | ||||||
3912 | |||||||
3913 | case clang::Type::DependentName: | ||||||
3914 | return 0; | ||||||
3915 | case clang::Type::DependentSizedExtVector: | ||||||
3916 | return eTypeHasChildren | eTypeIsVector; | ||||||
3917 | case clang::Type::DependentTemplateSpecialization: | ||||||
3918 | return eTypeIsTemplate; | ||||||
3919 | |||||||
3920 | case clang::Type::Enum: | ||||||
3921 | if (pointee_or_element_clang_type) | ||||||
3922 | pointee_or_element_clang_type->SetCompilerType( | ||||||
3923 | this, llvm::cast<clang::EnumType>(qual_type) | ||||||
3924 | ->getDecl() | ||||||
3925 | ->getIntegerType() | ||||||
3926 | .getAsOpaquePtr()); | ||||||
3927 | return eTypeIsEnumeration | eTypeHasValue; | ||||||
3928 | |||||||
3929 | case clang::Type::FunctionProto: | ||||||
3930 | return eTypeIsFuncPrototype | eTypeHasValue; | ||||||
3931 | case clang::Type::FunctionNoProto: | ||||||
3932 | return eTypeIsFuncPrototype | eTypeHasValue; | ||||||
3933 | case clang::Type::InjectedClassName: | ||||||
3934 | return 0; | ||||||
3935 | |||||||
3936 | case clang::Type::LValueReference: | ||||||
3937 | case clang::Type::RValueReference: | ||||||
3938 | if (pointee_or_element_clang_type) | ||||||
3939 | pointee_or_element_clang_type->SetCompilerType( | ||||||
3940 | this, llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()) | ||||||
3941 | ->getPointeeType() | ||||||
3942 | .getAsOpaquePtr()); | ||||||
3943 | return eTypeHasChildren | eTypeIsReference | eTypeHasValue; | ||||||
3944 | |||||||
3945 | case clang::Type::MemberPointer: | ||||||
3946 | return eTypeIsPointer | eTypeIsMember | eTypeHasValue; | ||||||
3947 | |||||||
3948 | case clang::Type::ObjCObjectPointer: | ||||||
3949 | if (pointee_or_element_clang_type) | ||||||
3950 | pointee_or_element_clang_type->SetCompilerType( | ||||||
3951 | this, qual_type->getPointeeType().getAsOpaquePtr()); | ||||||
3952 | return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | | ||||||
3953 | eTypeHasValue; | ||||||
3954 | |||||||
3955 | case clang::Type::ObjCObject: | ||||||
3956 | return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; | ||||||
3957 | case clang::Type::ObjCInterface: | ||||||
3958 | return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; | ||||||
3959 | |||||||
3960 | case clang::Type::Pointer: | ||||||
3961 | if (pointee_or_element_clang_type) | ||||||
3962 | pointee_or_element_clang_type->SetCompilerType( | ||||||
3963 | this, qual_type->getPointeeType().getAsOpaquePtr()); | ||||||
3964 | return eTypeHasChildren | eTypeIsPointer | eTypeHasValue; | ||||||
3965 | |||||||
3966 | case clang::Type::Record: | ||||||
3967 | if (qual_type->getAsCXXRecordDecl()) | ||||||
3968 | return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus; | ||||||
3969 | else | ||||||
3970 | return eTypeHasChildren | eTypeIsStructUnion; | ||||||
3971 | break; | ||||||
3972 | case clang::Type::SubstTemplateTypeParm: | ||||||
3973 | return eTypeIsTemplate; | ||||||
3974 | case clang::Type::TemplateTypeParm: | ||||||
3975 | return eTypeIsTemplate; | ||||||
3976 | case clang::Type::TemplateSpecialization: | ||||||
3977 | return eTypeIsTemplate; | ||||||
3978 | |||||||
3979 | case clang::Type::Typedef: | ||||||
3980 | return eTypeIsTypedef | GetType(llvm::cast<clang::TypedefType>(qual_type) | ||||||
3981 | ->getDecl() | ||||||
3982 | ->getUnderlyingType()) | ||||||
3983 | .GetTypeInfo(pointee_or_element_clang_type); | ||||||
3984 | case clang::Type::UnresolvedUsing: | ||||||
3985 | return 0; | ||||||
3986 | |||||||
3987 | case clang::Type::ExtVector: | ||||||
3988 | case clang::Type::Vector: { | ||||||
3989 | uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector; | ||||||
3990 | const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>( | ||||||
3991 | qual_type->getCanonicalTypeInternal()); | ||||||
3992 | if (vector_type) { | ||||||
3993 | if (vector_type->isIntegerType()) | ||||||
3994 | vector_type_flags |= eTypeIsFloat; | ||||||
3995 | else if (vector_type->isFloatingType()) | ||||||
3996 | vector_type_flags |= eTypeIsInteger; | ||||||
3997 | } | ||||||
3998 | return vector_type_flags; | ||||||
3999 | } | ||||||
4000 | default: | ||||||
4001 | return 0; | ||||||
4002 | } | ||||||
4003 | return 0; | ||||||
4004 | } | ||||||
4005 | |||||||
4006 | lldb::LanguageType | ||||||
4007 | TypeSystemClang::GetMinimumLanguage(lldb::opaque_compiler_type_t type) { | ||||||
4008 | if (!type) | ||||||
4009 | return lldb::eLanguageTypeC; | ||||||
4010 | |||||||
4011 | // If the type is a reference, then resolve it to what it refers to first: | ||||||
4012 | clang::QualType qual_type(GetCanonicalQualType(type).getNonReferenceType()); | ||||||
4013 | if (qual_type->isAnyPointerType()) { | ||||||
4014 | if (qual_type->isObjCObjectPointerType()) | ||||||
4015 | return lldb::eLanguageTypeObjC; | ||||||
4016 | if (qual_type->getPointeeCXXRecordDecl()) | ||||||
4017 | return lldb::eLanguageTypeC_plus_plus; | ||||||
4018 | |||||||
4019 | clang::QualType pointee_type(qual_type->getPointeeType()); | ||||||
4020 | if (pointee_type->getPointeeCXXRecordDecl()) | ||||||
4021 | return lldb::eLanguageTypeC_plus_plus; | ||||||
4022 | if (pointee_type->isObjCObjectOrInterfaceType()) | ||||||
4023 | return lldb::eLanguageTypeObjC; | ||||||
4024 | if (pointee_type->isObjCClassType()) | ||||||
4025 | return lldb::eLanguageTypeObjC; | ||||||
4026 | if (pointee_type.getTypePtr() == | ||||||
4027 | getASTContext().ObjCBuiltinIdTy.getTypePtr()) | ||||||
4028 | return lldb::eLanguageTypeObjC; | ||||||
4029 | } else { | ||||||
4030 | if (qual_type->isObjCObjectOrInterfaceType()) | ||||||
4031 | return lldb::eLanguageTypeObjC; | ||||||
4032 | if (qual_type->getAsCXXRecordDecl()) | ||||||
4033 | return lldb::eLanguageTypeC_plus_plus; | ||||||
4034 | switch (qual_type->getTypeClass()) { | ||||||
4035 | default: | ||||||
4036 | break; | ||||||
4037 | case clang::Type::Builtin: | ||||||
4038 | switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) { | ||||||
4039 | default: | ||||||
4040 | case clang::BuiltinType::Void: | ||||||
4041 | case clang::BuiltinType::Bool: | ||||||
4042 | case clang::BuiltinType::Char_U: | ||||||
4043 | case clang::BuiltinType::UChar: | ||||||
4044 | case clang::BuiltinType::WChar_U: | ||||||
4045 | case clang::BuiltinType::Char16: | ||||||
4046 | case clang::BuiltinType::Char32: | ||||||
4047 | case clang::BuiltinType::UShort: | ||||||
4048 | case clang::BuiltinType::UInt: | ||||||
4049 | case clang::BuiltinType::ULong: | ||||||
4050 | case clang::BuiltinType::ULongLong: | ||||||
4051 | case clang::BuiltinType::UInt128: | ||||||
4052 | case clang::BuiltinType::Char_S: | ||||||
4053 | case clang::BuiltinType::SChar: | ||||||
4054 | case clang::BuiltinType::WChar_S: | ||||||
4055 | case clang::BuiltinType::Short: | ||||||
4056 | case clang::BuiltinType::Int: | ||||||
4057 | case clang::BuiltinType::Long: | ||||||
4058 | case clang::BuiltinType::LongLong: | ||||||
4059 | case clang::BuiltinType::Int128: | ||||||
4060 | case clang::BuiltinType::Float: | ||||||
4061 | case clang::BuiltinType::Double: | ||||||
4062 | case clang::BuiltinType::LongDouble: | ||||||
4063 | break; | ||||||
4064 | |||||||
4065 | case clang::BuiltinType::NullPtr: | ||||||
4066 | return eLanguageTypeC_plus_plus; | ||||||
4067 | |||||||
4068 | case clang::BuiltinType::ObjCId: | ||||||
4069 | case clang::BuiltinType::ObjCClass: | ||||||
4070 | case clang::BuiltinType::ObjCSel: | ||||||
4071 | return eLanguageTypeObjC; | ||||||
4072 | |||||||
4073 | case clang::BuiltinType::Dependent: | ||||||
4074 | case clang::BuiltinType::Overload: | ||||||
4075 | case clang::BuiltinType::BoundMember: | ||||||
4076 | case clang::BuiltinType::UnknownAny: | ||||||
4077 | break; | ||||||
4078 | } | ||||||
4079 | break; | ||||||
4080 | case clang::Type::Typedef: | ||||||
4081 | return GetType(llvm::cast<clang::TypedefType>(qual_type) | ||||||
4082 | ->getDecl() | ||||||
4083 | ->getUnderlyingType()) | ||||||
4084 | .GetMinimumLanguage(); | ||||||
4085 | } | ||||||
4086 | } | ||||||
4087 | return lldb::eLanguageTypeC; | ||||||
4088 | } | ||||||
4089 | |||||||
4090 | lldb::TypeClass | ||||||
4091 | TypeSystemClang::GetTypeClass(lldb::opaque_compiler_type_t type) { | ||||||
4092 | if (!type) | ||||||
4093 | return lldb::eTypeClassInvalid; | ||||||
4094 | |||||||
4095 | clang::QualType qual_type = | ||||||
4096 | RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}); | ||||||
4097 | |||||||
4098 | switch (qual_type->getTypeClass()) { | ||||||
4099 | case clang::Type::Atomic: | ||||||
4100 | case clang::Type::Auto: | ||||||
4101 | case clang::Type::Decltype: | ||||||
4102 | case clang::Type::Elaborated: | ||||||
4103 | case clang::Type::Paren: | ||||||
4104 | case clang::Type::TypeOf: | ||||||
4105 | case clang::Type::TypeOfExpr: | ||||||
4106 | case clang::Type::Using: | ||||||
4107 | llvm_unreachable("Handled in RemoveWrappingTypes!")::llvm::llvm_unreachable_internal("Handled in RemoveWrappingTypes!" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 4107); | ||||||
4108 | case clang::Type::UnaryTransform: | ||||||
4109 | break; | ||||||
4110 | case clang::Type::FunctionNoProto: | ||||||
4111 | return lldb::eTypeClassFunction; | ||||||
4112 | case clang::Type::FunctionProto: | ||||||
4113 | return lldb::eTypeClassFunction; | ||||||
4114 | case clang::Type::IncompleteArray: | ||||||
4115 | return lldb::eTypeClassArray; | ||||||
4116 | case clang::Type::VariableArray: | ||||||
4117 | return lldb::eTypeClassArray; | ||||||
4118 | case clang::Type::ConstantArray: | ||||||
4119 | return lldb::eTypeClassArray; | ||||||
4120 | case clang::Type::DependentSizedArray: | ||||||
4121 | return lldb::eTypeClassArray; | ||||||
4122 | case clang::Type::DependentSizedExtVector: | ||||||
4123 | return lldb::eTypeClassVector; | ||||||
4124 | case clang::Type::DependentVector: | ||||||
4125 | return lldb::eTypeClassVector; | ||||||
4126 | case clang::Type::ExtVector: | ||||||
4127 | return lldb::eTypeClassVector; | ||||||
4128 | case clang::Type::Vector: | ||||||
4129 | return lldb::eTypeClassVector; | ||||||
4130 | case clang::Type::Builtin: | ||||||
4131 | // Ext-Int is just an integer type. | ||||||
4132 | case clang::Type::BitInt: | ||||||
4133 | case clang::Type::DependentBitInt: | ||||||
4134 | return lldb::eTypeClassBuiltin; | ||||||
4135 | case clang::Type::ObjCObjectPointer: | ||||||
4136 | return lldb::eTypeClassObjCObjectPointer; | ||||||
4137 | case clang::Type::BlockPointer: | ||||||
4138 | return lldb::eTypeClassBlockPointer; | ||||||
4139 | case clang::Type::Pointer: | ||||||
4140 | return lldb::eTypeClassPointer; | ||||||
4141 | case clang::Type::LValueReference: | ||||||
4142 | return lldb::eTypeClassReference; | ||||||
4143 | case clang::Type::RValueReference: | ||||||
4144 | return lldb::eTypeClassReference; | ||||||
4145 | case clang::Type::MemberPointer: | ||||||
4146 | return lldb::eTypeClassMemberPointer; | ||||||
4147 | case clang::Type::Complex: | ||||||
4148 | if (qual_type->isComplexType()) | ||||||
4149 | return lldb::eTypeClassComplexFloat; | ||||||
4150 | else | ||||||
4151 | return lldb::eTypeClassComplexInteger; | ||||||
4152 | case clang::Type::ObjCObject: | ||||||
4153 | return lldb::eTypeClassObjCObject; | ||||||
4154 | case clang::Type::ObjCInterface: | ||||||
4155 | return lldb::eTypeClassObjCInterface; | ||||||
4156 | case clang::Type::Record: { | ||||||
4157 | const clang::RecordType *record_type = | ||||||
4158 | llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
4159 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
4160 | if (record_decl->isUnion()) | ||||||
4161 | return lldb::eTypeClassUnion; | ||||||
4162 | else if (record_decl->isStruct()) | ||||||
4163 | return lldb::eTypeClassStruct; | ||||||
4164 | else | ||||||
4165 | return lldb::eTypeClassClass; | ||||||
4166 | } break; | ||||||
4167 | case clang::Type::Enum: | ||||||
4168 | return lldb::eTypeClassEnumeration; | ||||||
4169 | case clang::Type::Typedef: | ||||||
4170 | return lldb::eTypeClassTypedef; | ||||||
4171 | case clang::Type::UnresolvedUsing: | ||||||
4172 | break; | ||||||
4173 | |||||||
4174 | case clang::Type::Attributed: | ||||||
4175 | break; | ||||||
4176 | case clang::Type::TemplateTypeParm: | ||||||
4177 | break; | ||||||
4178 | case clang::Type::SubstTemplateTypeParm: | ||||||
4179 | break; | ||||||
4180 | case clang::Type::SubstTemplateTypeParmPack: | ||||||
4181 | break; | ||||||
4182 | case clang::Type::InjectedClassName: | ||||||
4183 | break; | ||||||
4184 | case clang::Type::DependentName: | ||||||
4185 | break; | ||||||
4186 | case clang::Type::DependentTemplateSpecialization: | ||||||
4187 | break; | ||||||
4188 | case clang::Type::PackExpansion: | ||||||
4189 | break; | ||||||
4190 | |||||||
4191 | case clang::Type::TemplateSpecialization: | ||||||
4192 | break; | ||||||
4193 | case clang::Type::DeducedTemplateSpecialization: | ||||||
4194 | break; | ||||||
4195 | case clang::Type::Pipe: | ||||||
4196 | break; | ||||||
4197 | |||||||
4198 | // pointer type decayed from an array or function type. | ||||||
4199 | case clang::Type::Decayed: | ||||||
4200 | break; | ||||||
4201 | case clang::Type::Adjusted: | ||||||
4202 | break; | ||||||
4203 | case clang::Type::ObjCTypeParam: | ||||||
4204 | break; | ||||||
4205 | |||||||
4206 | case clang::Type::DependentAddressSpace: | ||||||
4207 | break; | ||||||
4208 | case clang::Type::MacroQualified: | ||||||
4209 | break; | ||||||
4210 | |||||||
4211 | // Matrix types that we're not sure how to display at the moment. | ||||||
4212 | case clang::Type::ConstantMatrix: | ||||||
4213 | case clang::Type::DependentSizedMatrix: | ||||||
4214 | break; | ||||||
4215 | } | ||||||
4216 | // We don't know hot to display this type... | ||||||
4217 | return lldb::eTypeClassOther; | ||||||
4218 | } | ||||||
4219 | |||||||
4220 | unsigned TypeSystemClang::GetTypeQualifiers(lldb::opaque_compiler_type_t type) { | ||||||
4221 | if (type) | ||||||
4222 | return GetQualType(type).getQualifiers().getCVRQualifiers(); | ||||||
4223 | return 0; | ||||||
4224 | } | ||||||
4225 | |||||||
4226 | // Creating related types | ||||||
4227 | |||||||
4228 | CompilerType | ||||||
4229 | TypeSystemClang::GetArrayElementType(lldb::opaque_compiler_type_t type, | ||||||
4230 | ExecutionContextScope *exe_scope) { | ||||||
4231 | if (type) { | ||||||
4232 | clang::QualType qual_type(GetQualType(type)); | ||||||
4233 | |||||||
4234 | const clang::Type *array_eletype = | ||||||
4235 | qual_type.getTypePtr()->getArrayElementTypeNoTypeQual(); | ||||||
4236 | |||||||
4237 | if (!array_eletype) | ||||||
4238 | return CompilerType(); | ||||||
4239 | |||||||
4240 | return GetType(clang::QualType(array_eletype, 0)); | ||||||
4241 | } | ||||||
4242 | return CompilerType(); | ||||||
4243 | } | ||||||
4244 | |||||||
4245 | CompilerType TypeSystemClang::GetArrayType(lldb::opaque_compiler_type_t type, | ||||||
4246 | uint64_t size) { | ||||||
4247 | if (type) { | ||||||
4248 | clang::QualType qual_type(GetCanonicalQualType(type)); | ||||||
4249 | clang::ASTContext &ast_ctx = getASTContext(); | ||||||
4250 | if (size != 0) | ||||||
4251 | return GetType(ast_ctx.getConstantArrayType( | ||||||
4252 | qual_type, llvm::APInt(64, size), nullptr, | ||||||
4253 | clang::ArrayType::ArraySizeModifier::Normal, 0)); | ||||||
4254 | else | ||||||
4255 | return GetType(ast_ctx.getIncompleteArrayType( | ||||||
4256 | qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0)); | ||||||
4257 | } | ||||||
4258 | |||||||
4259 | return CompilerType(); | ||||||
4260 | } | ||||||
4261 | |||||||
4262 | CompilerType | ||||||
4263 | TypeSystemClang::GetCanonicalType(lldb::opaque_compiler_type_t type) { | ||||||
4264 | if (type) | ||||||
4265 | return GetType(GetCanonicalQualType(type)); | ||||||
4266 | return CompilerType(); | ||||||
4267 | } | ||||||
4268 | |||||||
4269 | static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast, | ||||||
4270 | clang::QualType qual_type) { | ||||||
4271 | if (qual_type->isPointerType()) | ||||||
4272 | qual_type = ast->getPointerType( | ||||||
4273 | GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType())); | ||||||
4274 | else if (const ConstantArrayType *arr = | ||||||
4275 | ast->getAsConstantArrayType(qual_type)) { | ||||||
4276 | qual_type = ast->getConstantArrayType( | ||||||
4277 | GetFullyUnqualifiedType_Impl(ast, arr->getElementType()), | ||||||
4278 | arr->getSize(), arr->getSizeExpr(), arr->getSizeModifier(), | ||||||
4279 | arr->getIndexTypeQualifiers().getAsOpaqueValue()); | ||||||
4280 | } else | ||||||
4281 | qual_type = qual_type.getUnqualifiedType(); | ||||||
4282 | qual_type.removeLocalConst(); | ||||||
4283 | qual_type.removeLocalRestrict(); | ||||||
4284 | qual_type.removeLocalVolatile(); | ||||||
4285 | return qual_type; | ||||||
4286 | } | ||||||
4287 | |||||||
4288 | CompilerType | ||||||
4289 | TypeSystemClang::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) { | ||||||
4290 | if (type) | ||||||
4291 | return GetType( | ||||||
4292 | GetFullyUnqualifiedType_Impl(&getASTContext(), GetQualType(type))); | ||||||
4293 | return CompilerType(); | ||||||
4294 | } | ||||||
4295 | |||||||
4296 | CompilerType | ||||||
4297 | TypeSystemClang::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) { | ||||||
4298 | if (type) | ||||||
4299 | return GetEnumerationIntegerType(GetType(GetCanonicalQualType(type))); | ||||||
4300 | return CompilerType(); | ||||||
4301 | } | ||||||
4302 | |||||||
4303 | int TypeSystemClang::GetFunctionArgumentCount( | ||||||
4304 | lldb::opaque_compiler_type_t type) { | ||||||
4305 | if (type) { | ||||||
4306 | const clang::FunctionProtoType *func = | ||||||
4307 | llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType(type)); | ||||||
4308 | if (func) | ||||||
4309 | return func->getNumParams(); | ||||||
4310 | } | ||||||
4311 | return -1; | ||||||
4312 | } | ||||||
4313 | |||||||
4314 | CompilerType TypeSystemClang::GetFunctionArgumentTypeAtIndex( | ||||||
4315 | lldb::opaque_compiler_type_t type, size_t idx) { | ||||||
4316 | if (type) { | ||||||
4317 | const clang::FunctionProtoType *func = | ||||||
4318 | llvm::dyn_cast<clang::FunctionProtoType>(GetQualType(type)); | ||||||
4319 | if (func) { | ||||||
4320 | const uint32_t num_args = func->getNumParams(); | ||||||
4321 | if (idx < num_args) | ||||||
4322 | return GetType(func->getParamType(idx)); | ||||||
4323 | } | ||||||
4324 | } | ||||||
4325 | return CompilerType(); | ||||||
4326 | } | ||||||
4327 | |||||||
4328 | CompilerType | ||||||
4329 | TypeSystemClang::GetFunctionReturnType(lldb::opaque_compiler_type_t type) { | ||||||
4330 | if (type) { | ||||||
4331 | clang::QualType qual_type(GetQualType(type)); | ||||||
4332 | const clang::FunctionProtoType *func = | ||||||
4333 | llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr()); | ||||||
4334 | if (func) | ||||||
4335 | return GetType(func->getReturnType()); | ||||||
4336 | } | ||||||
4337 | return CompilerType(); | ||||||
4338 | } | ||||||
4339 | |||||||
4340 | size_t | ||||||
4341 | TypeSystemClang::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) { | ||||||
4342 | size_t num_functions = 0; | ||||||
4343 | if (type) { | ||||||
4344 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
4345 | switch (qual_type->getTypeClass()) { | ||||||
4346 | case clang::Type::Record: | ||||||
4347 | if (GetCompleteQualType(&getASTContext(), qual_type)) { | ||||||
4348 | const clang::RecordType *record_type = | ||||||
4349 | llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
4350 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
4351 | assert(record_decl)(static_cast <bool> (record_decl) ? void (0) : __assert_fail ("record_decl", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 4351, __extension__ __PRETTY_FUNCTION__)); | ||||||
4352 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
4353 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); | ||||||
4354 | if (cxx_record_decl) | ||||||
4355 | num_functions = std::distance(cxx_record_decl->method_begin(), | ||||||
4356 | cxx_record_decl->method_end()); | ||||||
4357 | } | ||||||
4358 | break; | ||||||
4359 | |||||||
4360 | case clang::Type::ObjCObjectPointer: { | ||||||
4361 | const clang::ObjCObjectPointerType *objc_class_type = | ||||||
4362 | qual_type->getAs<clang::ObjCObjectPointerType>(); | ||||||
4363 | const clang::ObjCInterfaceType *objc_interface_type = | ||||||
4364 | objc_class_type->getInterfaceType(); | ||||||
4365 | if (objc_interface_type && | ||||||
4366 | GetCompleteType(static_cast<lldb::opaque_compiler_type_t>( | ||||||
4367 | const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) { | ||||||
4368 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
4369 | objc_interface_type->getDecl(); | ||||||
4370 | if (class_interface_decl) { | ||||||
4371 | num_functions = std::distance(class_interface_decl->meth_begin(), | ||||||
4372 | class_interface_decl->meth_end()); | ||||||
4373 | } | ||||||
4374 | } | ||||||
4375 | break; | ||||||
4376 | } | ||||||
4377 | |||||||
4378 | case clang::Type::ObjCObject: | ||||||
4379 | case clang::Type::ObjCInterface: | ||||||
4380 | if (GetCompleteType(type)) { | ||||||
4381 | const clang::ObjCObjectType *objc_class_type = | ||||||
4382 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); | ||||||
4383 | if (objc_class_type) { | ||||||
4384 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
4385 | objc_class_type->getInterface(); | ||||||
4386 | if (class_interface_decl) | ||||||
4387 | num_functions = std::distance(class_interface_decl->meth_begin(), | ||||||
4388 | class_interface_decl->meth_end()); | ||||||
4389 | } | ||||||
4390 | } | ||||||
4391 | break; | ||||||
4392 | |||||||
4393 | default: | ||||||
4394 | break; | ||||||
4395 | } | ||||||
4396 | } | ||||||
4397 | return num_functions; | ||||||
4398 | } | ||||||
4399 | |||||||
4400 | TypeMemberFunctionImpl | ||||||
4401 | TypeSystemClang::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, | ||||||
4402 | size_t idx) { | ||||||
4403 | std::string name; | ||||||
4404 | MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown); | ||||||
4405 | CompilerType clang_type; | ||||||
4406 | CompilerDecl clang_decl; | ||||||
4407 | if (type) { | ||||||
4408 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
4409 | switch (qual_type->getTypeClass()) { | ||||||
4410 | case clang::Type::Record: | ||||||
4411 | if (GetCompleteQualType(&getASTContext(), qual_type)) { | ||||||
4412 | const clang::RecordType *record_type = | ||||||
4413 | llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
4414 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
4415 | assert(record_decl)(static_cast <bool> (record_decl) ? void (0) : __assert_fail ("record_decl", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 4415, __extension__ __PRETTY_FUNCTION__)); | ||||||
4416 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
4417 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); | ||||||
4418 | if (cxx_record_decl) { | ||||||
4419 | auto method_iter = cxx_record_decl->method_begin(); | ||||||
4420 | auto method_end = cxx_record_decl->method_end(); | ||||||
4421 | if (idx < | ||||||
4422 | static_cast<size_t>(std::distance(method_iter, method_end))) { | ||||||
4423 | std::advance(method_iter, idx); | ||||||
4424 | clang::CXXMethodDecl *cxx_method_decl = | ||||||
4425 | method_iter->getCanonicalDecl(); | ||||||
4426 | if (cxx_method_decl) { | ||||||
4427 | name = cxx_method_decl->getDeclName().getAsString(); | ||||||
4428 | if (cxx_method_decl->isStatic()) | ||||||
4429 | kind = lldb::eMemberFunctionKindStaticMethod; | ||||||
4430 | else if (llvm::isa<clang::CXXConstructorDecl>(cxx_method_decl)) | ||||||
4431 | kind = lldb::eMemberFunctionKindConstructor; | ||||||
4432 | else if (llvm::isa<clang::CXXDestructorDecl>(cxx_method_decl)) | ||||||
4433 | kind = lldb::eMemberFunctionKindDestructor; | ||||||
4434 | else | ||||||
4435 | kind = lldb::eMemberFunctionKindInstanceMethod; | ||||||
4436 | clang_type = GetType(cxx_method_decl->getType()); | ||||||
4437 | clang_decl = GetCompilerDecl(cxx_method_decl); | ||||||
4438 | } | ||||||
4439 | } | ||||||
4440 | } | ||||||
4441 | } | ||||||
4442 | break; | ||||||
4443 | |||||||
4444 | case clang::Type::ObjCObjectPointer: { | ||||||
4445 | const clang::ObjCObjectPointerType *objc_class_type = | ||||||
4446 | qual_type->getAs<clang::ObjCObjectPointerType>(); | ||||||
4447 | const clang::ObjCInterfaceType *objc_interface_type = | ||||||
4448 | objc_class_type->getInterfaceType(); | ||||||
4449 | if (objc_interface_type && | ||||||
4450 | GetCompleteType(static_cast<lldb::opaque_compiler_type_t>( | ||||||
4451 | const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) { | ||||||
4452 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
4453 | objc_interface_type->getDecl(); | ||||||
4454 | if (class_interface_decl) { | ||||||
4455 | auto method_iter = class_interface_decl->meth_begin(); | ||||||
4456 | auto method_end = class_interface_decl->meth_end(); | ||||||
4457 | if (idx < | ||||||
4458 | static_cast<size_t>(std::distance(method_iter, method_end))) { | ||||||
4459 | std::advance(method_iter, idx); | ||||||
4460 | clang::ObjCMethodDecl *objc_method_decl = | ||||||
4461 | method_iter->getCanonicalDecl(); | ||||||
4462 | if (objc_method_decl) { | ||||||
4463 | clang_decl = GetCompilerDecl(objc_method_decl); | ||||||
4464 | name = objc_method_decl->getSelector().getAsString(); | ||||||
4465 | if (objc_method_decl->isClassMethod()) | ||||||
4466 | kind = lldb::eMemberFunctionKindStaticMethod; | ||||||
4467 | else | ||||||
4468 | kind = lldb::eMemberFunctionKindInstanceMethod; | ||||||
4469 | } | ||||||
4470 | } | ||||||
4471 | } | ||||||
4472 | } | ||||||
4473 | break; | ||||||
4474 | } | ||||||
4475 | |||||||
4476 | case clang::Type::ObjCObject: | ||||||
4477 | case clang::Type::ObjCInterface: | ||||||
4478 | if (GetCompleteType(type)) { | ||||||
4479 | const clang::ObjCObjectType *objc_class_type = | ||||||
4480 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); | ||||||
4481 | if (objc_class_type) { | ||||||
4482 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
4483 | objc_class_type->getInterface(); | ||||||
4484 | if (class_interface_decl) { | ||||||
4485 | auto method_iter = class_interface_decl->meth_begin(); | ||||||
4486 | auto method_end = class_interface_decl->meth_end(); | ||||||
4487 | if (idx < | ||||||
4488 | static_cast<size_t>(std::distance(method_iter, method_end))) { | ||||||
4489 | std::advance(method_iter, idx); | ||||||
4490 | clang::ObjCMethodDecl *objc_method_decl = | ||||||
4491 | method_iter->getCanonicalDecl(); | ||||||
4492 | if (objc_method_decl) { | ||||||
4493 | clang_decl = GetCompilerDecl(objc_method_decl); | ||||||
4494 | name = objc_method_decl->getSelector().getAsString(); | ||||||
4495 | if (objc_method_decl->isClassMethod()) | ||||||
4496 | kind = lldb::eMemberFunctionKindStaticMethod; | ||||||
4497 | else | ||||||
4498 | kind = lldb::eMemberFunctionKindInstanceMethod; | ||||||
4499 | } | ||||||
4500 | } | ||||||
4501 | } | ||||||
4502 | } | ||||||
4503 | } | ||||||
4504 | break; | ||||||
4505 | |||||||
4506 | default: | ||||||
4507 | break; | ||||||
4508 | } | ||||||
4509 | } | ||||||
4510 | |||||||
4511 | if (kind == eMemberFunctionKindUnknown) | ||||||
4512 | return TypeMemberFunctionImpl(); | ||||||
4513 | else | ||||||
4514 | return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind); | ||||||
4515 | } | ||||||
4516 | |||||||
4517 | CompilerType | ||||||
4518 | TypeSystemClang::GetNonReferenceType(lldb::opaque_compiler_type_t type) { | ||||||
4519 | if (type) | ||||||
4520 | return GetType(GetQualType(type).getNonReferenceType()); | ||||||
4521 | return CompilerType(); | ||||||
4522 | } | ||||||
4523 | |||||||
4524 | CompilerType | ||||||
4525 | TypeSystemClang::GetPointeeType(lldb::opaque_compiler_type_t type) { | ||||||
4526 | if (type) { | ||||||
4527 | clang::QualType qual_type(GetQualType(type)); | ||||||
4528 | return GetType(qual_type.getTypePtr()->getPointeeType()); | ||||||
4529 | } | ||||||
4530 | return CompilerType(); | ||||||
4531 | } | ||||||
4532 | |||||||
4533 | CompilerType | ||||||
4534 | TypeSystemClang::GetPointerType(lldb::opaque_compiler_type_t type) { | ||||||
4535 | if (type) { | ||||||
4536 | clang::QualType qual_type(GetQualType(type)); | ||||||
4537 | |||||||
4538 | switch (qual_type.getDesugaredType(getASTContext())->getTypeClass()) { | ||||||
4539 | case clang::Type::ObjCObject: | ||||||
4540 | case clang::Type::ObjCInterface: | ||||||
4541 | return GetType(getASTContext().getObjCObjectPointerType(qual_type)); | ||||||
4542 | |||||||
4543 | default: | ||||||
4544 | return GetType(getASTContext().getPointerType(qual_type)); | ||||||
4545 | } | ||||||
4546 | } | ||||||
4547 | return CompilerType(); | ||||||
4548 | } | ||||||
4549 | |||||||
4550 | CompilerType | ||||||
4551 | TypeSystemClang::GetLValueReferenceType(lldb::opaque_compiler_type_t type) { | ||||||
4552 | if (type) | ||||||
4553 | return GetType(getASTContext().getLValueReferenceType(GetQualType(type))); | ||||||
4554 | else | ||||||
4555 | return CompilerType(); | ||||||
4556 | } | ||||||
4557 | |||||||
4558 | CompilerType | ||||||
4559 | TypeSystemClang::GetRValueReferenceType(lldb::opaque_compiler_type_t type) { | ||||||
4560 | if (type) | ||||||
4561 | return GetType(getASTContext().getRValueReferenceType(GetQualType(type))); | ||||||
4562 | else | ||||||
4563 | return CompilerType(); | ||||||
4564 | } | ||||||
4565 | |||||||
4566 | CompilerType TypeSystemClang::GetAtomicType(lldb::opaque_compiler_type_t type) { | ||||||
4567 | if (!type) | ||||||
4568 | return CompilerType(); | ||||||
4569 | return GetType(getASTContext().getAtomicType(GetQualType(type))); | ||||||
4570 | } | ||||||
4571 | |||||||
4572 | CompilerType | ||||||
4573 | TypeSystemClang::AddConstModifier(lldb::opaque_compiler_type_t type) { | ||||||
4574 | if (type) { | ||||||
4575 | clang::QualType result(GetQualType(type)); | ||||||
4576 | result.addConst(); | ||||||
4577 | return GetType(result); | ||||||
4578 | } | ||||||
4579 | return CompilerType(); | ||||||
4580 | } | ||||||
4581 | |||||||
4582 | CompilerType | ||||||
4583 | TypeSystemClang::AddVolatileModifier(lldb::opaque_compiler_type_t type) { | ||||||
4584 | if (type) { | ||||||
4585 | clang::QualType result(GetQualType(type)); | ||||||
4586 | result.addVolatile(); | ||||||
4587 | return GetType(result); | ||||||
4588 | } | ||||||
4589 | return CompilerType(); | ||||||
4590 | } | ||||||
4591 | |||||||
4592 | CompilerType | ||||||
4593 | TypeSystemClang::AddRestrictModifier(lldb::opaque_compiler_type_t type) { | ||||||
4594 | if (type) { | ||||||
4595 | clang::QualType result(GetQualType(type)); | ||||||
4596 | result.addRestrict(); | ||||||
4597 | return GetType(result); | ||||||
4598 | } | ||||||
4599 | return CompilerType(); | ||||||
4600 | } | ||||||
4601 | |||||||
4602 | CompilerType TypeSystemClang::CreateTypedef( | ||||||
4603 | lldb::opaque_compiler_type_t type, const char *typedef_name, | ||||||
4604 | const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) { | ||||||
4605 | if (type && typedef_name && typedef_name[0]) { | ||||||
4606 | clang::ASTContext &clang_ast = getASTContext(); | ||||||
4607 | clang::QualType qual_type(GetQualType(type)); | ||||||
4608 | |||||||
4609 | clang::DeclContext *decl_ctx = | ||||||
4610 | TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); | ||||||
4611 | if (!decl_ctx) | ||||||
4612 | decl_ctx = getASTContext().getTranslationUnitDecl(); | ||||||
4613 | |||||||
4614 | clang::TypedefDecl *decl = | ||||||
4615 | clang::TypedefDecl::CreateDeserialized(clang_ast, 0); | ||||||
4616 | decl->setDeclContext(decl_ctx); | ||||||
4617 | decl->setDeclName(&clang_ast.Idents.get(typedef_name)); | ||||||
4618 | decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(qual_type)); | ||||||
4619 | decl_ctx->addDecl(decl); | ||||||
4620 | SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule()); | ||||||
4621 | |||||||
4622 | clang::TagDecl *tdecl = nullptr; | ||||||
4623 | if (!qual_type.isNull()) { | ||||||
4624 | if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>()) | ||||||
4625 | tdecl = rt->getDecl(); | ||||||
4626 | if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>()) | ||||||
4627 | tdecl = et->getDecl(); | ||||||
4628 | } | ||||||
4629 | |||||||
4630 | // Check whether this declaration is an anonymous struct, union, or enum, | ||||||
4631 | // hidden behind a typedef. If so, we try to check whether we have a | ||||||
4632 | // typedef tag to attach to the original record declaration | ||||||
4633 | if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl()) | ||||||
4634 | tdecl->setTypedefNameForAnonDecl(decl); | ||||||
4635 | |||||||
4636 | decl->setAccess(clang::AS_public); // TODO respect proper access specifier | ||||||
4637 | |||||||
4638 | // Get a uniqued clang::QualType for the typedef decl type | ||||||
4639 | return GetType(clang_ast.getTypedefType(decl)); | ||||||
4640 | } | ||||||
4641 | return CompilerType(); | ||||||
4642 | } | ||||||
4643 | |||||||
4644 | CompilerType | ||||||
4645 | TypeSystemClang::GetTypedefedType(lldb::opaque_compiler_type_t type) { | ||||||
4646 | if (type) { | ||||||
4647 | const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>( | ||||||
4648 | RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef})); | ||||||
4649 | if (typedef_type) | ||||||
4650 | return GetType(typedef_type->getDecl()->getUnderlyingType()); | ||||||
4651 | } | ||||||
4652 | return CompilerType(); | ||||||
4653 | } | ||||||
4654 | |||||||
4655 | // Create related types using the current type's AST | ||||||
4656 | |||||||
4657 | CompilerType TypeSystemClang::GetBasicTypeFromAST(lldb::BasicType basic_type) { | ||||||
4658 | return TypeSystemClang::GetBasicType(basic_type); | ||||||
4659 | } | ||||||
4660 | // Exploring the type | ||||||
4661 | |||||||
4662 | const llvm::fltSemantics & | ||||||
4663 | TypeSystemClang::GetFloatTypeSemantics(size_t byte_size) { | ||||||
4664 | clang::ASTContext &ast = getASTContext(); | ||||||
4665 | const size_t bit_size = byte_size * 8; | ||||||
4666 | if (bit_size == ast.getTypeSize(ast.FloatTy)) | ||||||
4667 | return ast.getFloatTypeSemantics(ast.FloatTy); | ||||||
4668 | else if (bit_size == ast.getTypeSize(ast.DoubleTy)) | ||||||
4669 | return ast.getFloatTypeSemantics(ast.DoubleTy); | ||||||
4670 | else if (bit_size == ast.getTypeSize(ast.LongDoubleTy)) | ||||||
4671 | return ast.getFloatTypeSemantics(ast.LongDoubleTy); | ||||||
4672 | else if (bit_size == ast.getTypeSize(ast.HalfTy)) | ||||||
4673 | return ast.getFloatTypeSemantics(ast.HalfTy); | ||||||
4674 | return llvm::APFloatBase::Bogus(); | ||||||
4675 | } | ||||||
4676 | |||||||
4677 | Optional<uint64_t> | ||||||
4678 | TypeSystemClang::GetBitSize(lldb::opaque_compiler_type_t type, | ||||||
4679 | ExecutionContextScope *exe_scope) { | ||||||
4680 | if (GetCompleteType(type)) { | ||||||
4681 | clang::QualType qual_type(GetCanonicalQualType(type)); | ||||||
4682 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
4683 | switch (type_class) { | ||||||
4684 | case clang::Type::Record: | ||||||
4685 | if (GetCompleteType(type)) | ||||||
4686 | return getASTContext().getTypeSize(qual_type); | ||||||
4687 | else | ||||||
4688 | return None; | ||||||
4689 | break; | ||||||
4690 | |||||||
4691 | case clang::Type::ObjCInterface: | ||||||
4692 | case clang::Type::ObjCObject: { | ||||||
4693 | ExecutionContext exe_ctx(exe_scope); | ||||||
4694 | Process *process = exe_ctx.GetProcessPtr(); | ||||||
4695 | if (process) { | ||||||
4696 | ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process); | ||||||
4697 | if (objc_runtime) { | ||||||
4698 | uint64_t bit_size = 0; | ||||||
4699 | if (objc_runtime->GetTypeBitSize(GetType(qual_type), bit_size)) | ||||||
4700 | return bit_size; | ||||||
4701 | } | ||||||
4702 | } else { | ||||||
4703 | static bool g_printed = false; | ||||||
4704 | if (!g_printed) { | ||||||
4705 | StreamString s; | ||||||
4706 | DumpTypeDescription(type, &s); | ||||||
4707 | |||||||
4708 | llvm::outs() << "warning: trying to determine the size of type "; | ||||||
4709 | llvm::outs() << s.GetString() << "\n"; | ||||||
4710 | llvm::outs() << "without a valid ExecutionContext. this is not " | ||||||
4711 | "reliable. please file a bug against LLDB.\n"; | ||||||
4712 | llvm::outs() << "backtrace:\n"; | ||||||
4713 | llvm::sys::PrintStackTrace(llvm::outs()); | ||||||
4714 | llvm::outs() << "\n"; | ||||||
4715 | g_printed = true; | ||||||
4716 | } | ||||||
4717 | } | ||||||
4718 | } | ||||||
4719 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||||
4720 | default: | ||||||
4721 | const uint32_t bit_size = getASTContext().getTypeSize(qual_type); | ||||||
4722 | if (bit_size == 0) { | ||||||
4723 | if (qual_type->isIncompleteArrayType()) | ||||||
4724 | return getASTContext().getTypeSize( | ||||||
4725 | qual_type->getArrayElementTypeNoTypeQual() | ||||||
4726 | ->getCanonicalTypeUnqualified()); | ||||||
4727 | } | ||||||
4728 | if (qual_type->isObjCObjectOrInterfaceType()) | ||||||
4729 | return bit_size + | ||||||
4730 | getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy); | ||||||
4731 | // Function types actually have a size of 0, that's not an error. | ||||||
4732 | if (qual_type->isFunctionProtoType()) | ||||||
4733 | return bit_size; | ||||||
4734 | if (bit_size) | ||||||
4735 | return bit_size; | ||||||
4736 | } | ||||||
4737 | } | ||||||
4738 | return None; | ||||||
4739 | } | ||||||
4740 | |||||||
4741 | llvm::Optional<size_t> | ||||||
4742 | TypeSystemClang::GetTypeBitAlign(lldb::opaque_compiler_type_t type, | ||||||
4743 | ExecutionContextScope *exe_scope) { | ||||||
4744 | if (GetCompleteType(type)) | ||||||
4745 | return getASTContext().getTypeAlign(GetQualType(type)); | ||||||
4746 | return {}; | ||||||
4747 | } | ||||||
4748 | |||||||
4749 | lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, | ||||||
4750 | uint64_t &count) { | ||||||
4751 | if (!type) | ||||||
4752 | return lldb::eEncodingInvalid; | ||||||
4753 | |||||||
4754 | count = 1; | ||||||
4755 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
4756 | |||||||
4757 | switch (qual_type->getTypeClass()) { | ||||||
4758 | case clang::Type::Atomic: | ||||||
4759 | case clang::Type::Auto: | ||||||
4760 | case clang::Type::Decltype: | ||||||
4761 | case clang::Type::Elaborated: | ||||||
4762 | case clang::Type::Paren: | ||||||
4763 | case clang::Type::Typedef: | ||||||
4764 | case clang::Type::TypeOf: | ||||||
4765 | case clang::Type::TypeOfExpr: | ||||||
4766 | case clang::Type::Using: | ||||||
4767 | llvm_unreachable("Handled in RemoveWrappingTypes!")::llvm::llvm_unreachable_internal("Handled in RemoveWrappingTypes!" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 4767); | ||||||
4768 | |||||||
4769 | case clang::Type::UnaryTransform: | ||||||
4770 | break; | ||||||
4771 | |||||||
4772 | case clang::Type::FunctionNoProto: | ||||||
4773 | case clang::Type::FunctionProto: | ||||||
4774 | break; | ||||||
4775 | |||||||
4776 | case clang::Type::IncompleteArray: | ||||||
4777 | case clang::Type::VariableArray: | ||||||
4778 | break; | ||||||
4779 | |||||||
4780 | case clang::Type::ConstantArray: | ||||||
4781 | break; | ||||||
4782 | |||||||
4783 | case clang::Type::DependentVector: | ||||||
4784 | case clang::Type::ExtVector: | ||||||
4785 | case clang::Type::Vector: | ||||||
4786 | // TODO: Set this to more than one??? | ||||||
4787 | break; | ||||||
4788 | |||||||
4789 | case clang::Type::BitInt: | ||||||
4790 | case clang::Type::DependentBitInt: | ||||||
4791 | return qual_type->isUnsignedIntegerType() ? lldb::eEncodingUint | ||||||
4792 | : lldb::eEncodingSint; | ||||||
4793 | |||||||
4794 | case clang::Type::Builtin: | ||||||
4795 | switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) { | ||||||
4796 | case clang::BuiltinType::Void: | ||||||
4797 | break; | ||||||
4798 | |||||||
4799 | case clang::BuiltinType::Char_S: | ||||||
4800 | case clang::BuiltinType::SChar: | ||||||
4801 | case clang::BuiltinType::WChar_S: | ||||||
4802 | case clang::BuiltinType::Short: | ||||||
4803 | case clang::BuiltinType::Int: | ||||||
4804 | case clang::BuiltinType::Long: | ||||||
4805 | case clang::BuiltinType::LongLong: | ||||||
4806 | case clang::BuiltinType::Int128: | ||||||
4807 | return lldb::eEncodingSint; | ||||||
4808 | |||||||
4809 | case clang::BuiltinType::Bool: | ||||||
4810 | case clang::BuiltinType::Char_U: | ||||||
4811 | case clang::BuiltinType::UChar: | ||||||
4812 | case clang::BuiltinType::WChar_U: | ||||||
4813 | case clang::BuiltinType::Char8: | ||||||
4814 | case clang::BuiltinType::Char16: | ||||||
4815 | case clang::BuiltinType::Char32: | ||||||
4816 | case clang::BuiltinType::UShort: | ||||||
4817 | case clang::BuiltinType::UInt: | ||||||
4818 | case clang::BuiltinType::ULong: | ||||||
4819 | case clang::BuiltinType::ULongLong: | ||||||
4820 | case clang::BuiltinType::UInt128: | ||||||
4821 | return lldb::eEncodingUint; | ||||||
4822 | |||||||
4823 | // Fixed point types. Note that they are currently ignored. | ||||||
4824 | case clang::BuiltinType::ShortAccum: | ||||||
4825 | case clang::BuiltinType::Accum: | ||||||
4826 | case clang::BuiltinType::LongAccum: | ||||||
4827 | case clang::BuiltinType::UShortAccum: | ||||||
4828 | case clang::BuiltinType::UAccum: | ||||||
4829 | case clang::BuiltinType::ULongAccum: | ||||||
4830 | case clang::BuiltinType::ShortFract: | ||||||
4831 | case clang::BuiltinType::Fract: | ||||||
4832 | case clang::BuiltinType::LongFract: | ||||||
4833 | case clang::BuiltinType::UShortFract: | ||||||
4834 | case clang::BuiltinType::UFract: | ||||||
4835 | case clang::BuiltinType::ULongFract: | ||||||
4836 | case clang::BuiltinType::SatShortAccum: | ||||||
4837 | case clang::BuiltinType::SatAccum: | ||||||
4838 | case clang::BuiltinType::SatLongAccum: | ||||||
4839 | case clang::BuiltinType::SatUShortAccum: | ||||||
4840 | case clang::BuiltinType::SatUAccum: | ||||||
4841 | case clang::BuiltinType::SatULongAccum: | ||||||
4842 | case clang::BuiltinType::SatShortFract: | ||||||
4843 | case clang::BuiltinType::SatFract: | ||||||
4844 | case clang::BuiltinType::SatLongFract: | ||||||
4845 | case clang::BuiltinType::SatUShortFract: | ||||||
4846 | case clang::BuiltinType::SatUFract: | ||||||
4847 | case clang::BuiltinType::SatULongFract: | ||||||
4848 | break; | ||||||
4849 | |||||||
4850 | case clang::BuiltinType::Half: | ||||||
4851 | case clang::BuiltinType::Float: | ||||||
4852 | case clang::BuiltinType::Float16: | ||||||
4853 | case clang::BuiltinType::Float128: | ||||||
4854 | case clang::BuiltinType::Double: | ||||||
4855 | case clang::BuiltinType::LongDouble: | ||||||
4856 | case clang::BuiltinType::BFloat16: | ||||||
4857 | case clang::BuiltinType::Ibm128: | ||||||
4858 | return lldb::eEncodingIEEE754; | ||||||
4859 | |||||||
4860 | case clang::BuiltinType::ObjCClass: | ||||||
4861 | case clang::BuiltinType::ObjCId: | ||||||
4862 | case clang::BuiltinType::ObjCSel: | ||||||
4863 | return lldb::eEncodingUint; | ||||||
4864 | |||||||
4865 | case clang::BuiltinType::NullPtr: | ||||||
4866 | return lldb::eEncodingUint; | ||||||
4867 | |||||||
4868 | case clang::BuiltinType::Kind::ARCUnbridgedCast: | ||||||
4869 | case clang::BuiltinType::Kind::BoundMember: | ||||||
4870 | case clang::BuiltinType::Kind::BuiltinFn: | ||||||
4871 | case clang::BuiltinType::Kind::Dependent: | ||||||
4872 | case clang::BuiltinType::Kind::OCLClkEvent: | ||||||
4873 | case clang::BuiltinType::Kind::OCLEvent: | ||||||
4874 | case clang::BuiltinType::Kind::OCLImage1dRO: | ||||||
4875 | case clang::BuiltinType::Kind::OCLImage1dWO: | ||||||
4876 | case clang::BuiltinType::Kind::OCLImage1dRW: | ||||||
4877 | case clang::BuiltinType::Kind::OCLImage1dArrayRO: | ||||||
4878 | case clang::BuiltinType::Kind::OCLImage1dArrayWO: | ||||||
4879 | case clang::BuiltinType::Kind::OCLImage1dArrayRW: | ||||||
4880 | case clang::BuiltinType::Kind::OCLImage1dBufferRO: | ||||||
4881 | case clang::BuiltinType::Kind::OCLImage1dBufferWO: | ||||||
4882 | case clang::BuiltinType::Kind::OCLImage1dBufferRW: | ||||||
4883 | case clang::BuiltinType::Kind::OCLImage2dRO: | ||||||
4884 | case clang::BuiltinType::Kind::OCLImage2dWO: | ||||||
4885 | case clang::BuiltinType::Kind::OCLImage2dRW: | ||||||
4886 | case clang::BuiltinType::Kind::OCLImage2dArrayRO: | ||||||
4887 | case clang::BuiltinType::Kind::OCLImage2dArrayWO: | ||||||
4888 | case clang::BuiltinType::Kind::OCLImage2dArrayRW: | ||||||
4889 | case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO: | ||||||
4890 | case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO: | ||||||
4891 | case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW: | ||||||
4892 | case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO: | ||||||
4893 | case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO: | ||||||
4894 | case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW: | ||||||
4895 | case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO: | ||||||
4896 | case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO: | ||||||
4897 | case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW: | ||||||
4898 | case clang::BuiltinType::Kind::OCLImage2dDepthRO: | ||||||
4899 | case clang::BuiltinType::Kind::OCLImage2dDepthWO: | ||||||
4900 | case clang::BuiltinType::Kind::OCLImage2dDepthRW: | ||||||
4901 | case clang::BuiltinType::Kind::OCLImage2dMSAARO: | ||||||
4902 | case clang::BuiltinType::Kind::OCLImage2dMSAAWO: | ||||||
4903 | case clang::BuiltinType::Kind::OCLImage2dMSAARW: | ||||||
4904 | case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO: | ||||||
4905 | case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO: | ||||||
4906 | case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW: | ||||||
4907 | case clang::BuiltinType::Kind::OCLImage3dRO: | ||||||
4908 | case clang::BuiltinType::Kind::OCLImage3dWO: | ||||||
4909 | case clang::BuiltinType::Kind::OCLImage3dRW: | ||||||
4910 | case clang::BuiltinType::Kind::OCLQueue: | ||||||
4911 | case clang::BuiltinType::Kind::OCLReserveID: | ||||||
4912 | case clang::BuiltinType::Kind::OCLSampler: | ||||||
4913 | case clang::BuiltinType::Kind::OMPArraySection: | ||||||
4914 | case clang::BuiltinType::Kind::OMPArrayShaping: | ||||||
4915 | case clang::BuiltinType::Kind::OMPIterator: | ||||||
4916 | case clang::BuiltinType::Kind::Overload: | ||||||
4917 | case clang::BuiltinType::Kind::PseudoObject: | ||||||
4918 | case clang::BuiltinType::Kind::UnknownAny: | ||||||
4919 | break; | ||||||
4920 | |||||||
4921 | case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload: | ||||||
4922 | case clang::BuiltinType::OCLIntelSubgroupAVCImePayload: | ||||||
4923 | case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload: | ||||||
4924 | case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload: | ||||||
4925 | case clang::BuiltinType::OCLIntelSubgroupAVCMceResult: | ||||||
4926 | case clang::BuiltinType::OCLIntelSubgroupAVCImeResult: | ||||||
4927 | case clang::BuiltinType::OCLIntelSubgroupAVCRefResult: | ||||||
4928 | case clang::BuiltinType::OCLIntelSubgroupAVCSicResult: | ||||||
4929 | case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout: | ||||||
4930 | case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout: | ||||||
4931 | case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin: | ||||||
4932 | case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin: | ||||||
4933 | break; | ||||||
4934 | |||||||
4935 | // PowerPC -- Matrix Multiply Assist | ||||||
4936 | case clang::BuiltinType::VectorPair: | ||||||
4937 | case clang::BuiltinType::VectorQuad: | ||||||
4938 | break; | ||||||
4939 | |||||||
4940 | // ARM -- Scalable Vector Extension | ||||||
4941 | case clang::BuiltinType::SveBool: | ||||||
4942 | case clang::BuiltinType::SveInt8: | ||||||
4943 | case clang::BuiltinType::SveInt8x2: | ||||||
4944 | case clang::BuiltinType::SveInt8x3: | ||||||
4945 | case clang::BuiltinType::SveInt8x4: | ||||||
4946 | case clang::BuiltinType::SveInt16: | ||||||
4947 | case clang::BuiltinType::SveInt16x2: | ||||||
4948 | case clang::BuiltinType::SveInt16x3: | ||||||
4949 | case clang::BuiltinType::SveInt16x4: | ||||||
4950 | case clang::BuiltinType::SveInt32: | ||||||
4951 | case clang::BuiltinType::SveInt32x2: | ||||||
4952 | case clang::BuiltinType::SveInt32x3: | ||||||
4953 | case clang::BuiltinType::SveInt32x4: | ||||||
4954 | case clang::BuiltinType::SveInt64: | ||||||
4955 | case clang::BuiltinType::SveInt64x2: | ||||||
4956 | case clang::BuiltinType::SveInt64x3: | ||||||
4957 | case clang::BuiltinType::SveInt64x4: | ||||||
4958 | case clang::BuiltinType::SveUint8: | ||||||
4959 | case clang::BuiltinType::SveUint8x2: | ||||||
4960 | case clang::BuiltinType::SveUint8x3: | ||||||
4961 | case clang::BuiltinType::SveUint8x4: | ||||||
4962 | case clang::BuiltinType::SveUint16: | ||||||
4963 | case clang::BuiltinType::SveUint16x2: | ||||||
4964 | case clang::BuiltinType::SveUint16x3: | ||||||
4965 | case clang::BuiltinType::SveUint16x4: | ||||||
4966 | case clang::BuiltinType::SveUint32: | ||||||
4967 | case clang::BuiltinType::SveUint32x2: | ||||||
4968 | case clang::BuiltinType::SveUint32x3: | ||||||
4969 | case clang::BuiltinType::SveUint32x4: | ||||||
4970 | case clang::BuiltinType::SveUint64: | ||||||
4971 | case clang::BuiltinType::SveUint64x2: | ||||||
4972 | case clang::BuiltinType::SveUint64x3: | ||||||
4973 | case clang::BuiltinType::SveUint64x4: | ||||||
4974 | case clang::BuiltinType::SveFloat16: | ||||||
4975 | case clang::BuiltinType::SveBFloat16: | ||||||
4976 | case clang::BuiltinType::SveBFloat16x2: | ||||||
4977 | case clang::BuiltinType::SveBFloat16x3: | ||||||
4978 | case clang::BuiltinType::SveBFloat16x4: | ||||||
4979 | case clang::BuiltinType::SveFloat16x2: | ||||||
4980 | case clang::BuiltinType::SveFloat16x3: | ||||||
4981 | case clang::BuiltinType::SveFloat16x4: | ||||||
4982 | case clang::BuiltinType::SveFloat32: | ||||||
4983 | case clang::BuiltinType::SveFloat32x2: | ||||||
4984 | case clang::BuiltinType::SveFloat32x3: | ||||||
4985 | case clang::BuiltinType::SveFloat32x4: | ||||||
4986 | case clang::BuiltinType::SveFloat64: | ||||||
4987 | case clang::BuiltinType::SveFloat64x2: | ||||||
4988 | case clang::BuiltinType::SveFloat64x3: | ||||||
4989 | case clang::BuiltinType::SveFloat64x4: | ||||||
4990 | break; | ||||||
4991 | |||||||
4992 | // RISC-V V builtin types. | ||||||
4993 | case clang::BuiltinType::RvvInt8mf8: | ||||||
4994 | case clang::BuiltinType::RvvInt8mf4: | ||||||
4995 | case clang::BuiltinType::RvvInt8mf2: | ||||||
4996 | case clang::BuiltinType::RvvInt8m1: | ||||||
4997 | case clang::BuiltinType::RvvInt8m2: | ||||||
4998 | case clang::BuiltinType::RvvInt8m4: | ||||||
4999 | case clang::BuiltinType::RvvInt8m8: | ||||||
5000 | case clang::BuiltinType::RvvUint8mf8: | ||||||
5001 | case clang::BuiltinType::RvvUint8mf4: | ||||||
5002 | case clang::BuiltinType::RvvUint8mf2: | ||||||
5003 | case clang::BuiltinType::RvvUint8m1: | ||||||
5004 | case clang::BuiltinType::RvvUint8m2: | ||||||
5005 | case clang::BuiltinType::RvvUint8m4: | ||||||
5006 | case clang::BuiltinType::RvvUint8m8: | ||||||
5007 | case clang::BuiltinType::RvvInt16mf4: | ||||||
5008 | case clang::BuiltinType::RvvInt16mf2: | ||||||
5009 | case clang::BuiltinType::RvvInt16m1: | ||||||
5010 | case clang::BuiltinType::RvvInt16m2: | ||||||
5011 | case clang::BuiltinType::RvvInt16m4: | ||||||
5012 | case clang::BuiltinType::RvvInt16m8: | ||||||
5013 | case clang::BuiltinType::RvvUint16mf4: | ||||||
5014 | case clang::BuiltinType::RvvUint16mf2: | ||||||
5015 | case clang::BuiltinType::RvvUint16m1: | ||||||
5016 | case clang::BuiltinType::RvvUint16m2: | ||||||
5017 | case clang::BuiltinType::RvvUint16m4: | ||||||
5018 | case clang::BuiltinType::RvvUint16m8: | ||||||
5019 | case clang::BuiltinType::RvvInt32mf2: | ||||||
5020 | case clang::BuiltinType::RvvInt32m1: | ||||||
5021 | case clang::BuiltinType::RvvInt32m2: | ||||||
5022 | case clang::BuiltinType::RvvInt32m4: | ||||||
5023 | case clang::BuiltinType::RvvInt32m8: | ||||||
5024 | case clang::BuiltinType::RvvUint32mf2: | ||||||
5025 | case clang::BuiltinType::RvvUint32m1: | ||||||
5026 | case clang::BuiltinType::RvvUint32m2: | ||||||
5027 | case clang::BuiltinType::RvvUint32m4: | ||||||
5028 | case clang::BuiltinType::RvvUint32m8: | ||||||
5029 | case clang::BuiltinType::RvvInt64m1: | ||||||
5030 | case clang::BuiltinType::RvvInt64m2: | ||||||
5031 | case clang::BuiltinType::RvvInt64m4: | ||||||
5032 | case clang::BuiltinType::RvvInt64m8: | ||||||
5033 | case clang::BuiltinType::RvvUint64m1: | ||||||
5034 | case clang::BuiltinType::RvvUint64m2: | ||||||
5035 | case clang::BuiltinType::RvvUint64m4: | ||||||
5036 | case clang::BuiltinType::RvvUint64m8: | ||||||
5037 | case clang::BuiltinType::RvvFloat16mf4: | ||||||
5038 | case clang::BuiltinType::RvvFloat16mf2: | ||||||
5039 | case clang::BuiltinType::RvvFloat16m1: | ||||||
5040 | case clang::BuiltinType::RvvFloat16m2: | ||||||
5041 | case clang::BuiltinType::RvvFloat16m4: | ||||||
5042 | case clang::BuiltinType::RvvFloat16m8: | ||||||
5043 | case clang::BuiltinType::RvvFloat32mf2: | ||||||
5044 | case clang::BuiltinType::RvvFloat32m1: | ||||||
5045 | case clang::BuiltinType::RvvFloat32m2: | ||||||
5046 | case clang::BuiltinType::RvvFloat32m4: | ||||||
5047 | case clang::BuiltinType::RvvFloat32m8: | ||||||
5048 | case clang::BuiltinType::RvvFloat64m1: | ||||||
5049 | case clang::BuiltinType::RvvFloat64m2: | ||||||
5050 | case clang::BuiltinType::RvvFloat64m4: | ||||||
5051 | case clang::BuiltinType::RvvFloat64m8: | ||||||
5052 | case clang::BuiltinType::RvvBool1: | ||||||
5053 | case clang::BuiltinType::RvvBool2: | ||||||
5054 | case clang::BuiltinType::RvvBool4: | ||||||
5055 | case clang::BuiltinType::RvvBool8: | ||||||
5056 | case clang::BuiltinType::RvvBool16: | ||||||
5057 | case clang::BuiltinType::RvvBool32: | ||||||
5058 | case clang::BuiltinType::RvvBool64: | ||||||
5059 | break; | ||||||
5060 | |||||||
5061 | case clang::BuiltinType::IncompleteMatrixIdx: | ||||||
5062 | break; | ||||||
5063 | } | ||||||
5064 | break; | ||||||
5065 | // All pointer types are represented as unsigned integer encodings. We may | ||||||
5066 | // nee to add a eEncodingPointer if we ever need to know the difference | ||||||
5067 | case clang::Type::ObjCObjectPointer: | ||||||
5068 | case clang::Type::BlockPointer: | ||||||
5069 | case clang::Type::Pointer: | ||||||
5070 | case clang::Type::LValueReference: | ||||||
5071 | case clang::Type::RValueReference: | ||||||
5072 | case clang::Type::MemberPointer: | ||||||
5073 | return lldb::eEncodingUint; | ||||||
5074 | case clang::Type::Complex: { | ||||||
5075 | lldb::Encoding encoding = lldb::eEncodingIEEE754; | ||||||
5076 | if (qual_type->isComplexType()) | ||||||
5077 | encoding = lldb::eEncodingIEEE754; | ||||||
5078 | else { | ||||||
5079 | const clang::ComplexType *complex_type = | ||||||
5080 | qual_type->getAsComplexIntegerType(); | ||||||
5081 | if (complex_type) | ||||||
5082 | encoding = GetType(complex_type->getElementType()).GetEncoding(count); | ||||||
5083 | else | ||||||
5084 | encoding = lldb::eEncodingSint; | ||||||
5085 | } | ||||||
5086 | count = 2; | ||||||
5087 | return encoding; | ||||||
5088 | } | ||||||
5089 | |||||||
5090 | case clang::Type::ObjCInterface: | ||||||
5091 | break; | ||||||
5092 | case clang::Type::Record: | ||||||
5093 | break; | ||||||
5094 | case clang::Type::Enum: | ||||||
5095 | return lldb::eEncodingSint; | ||||||
5096 | case clang::Type::DependentSizedArray: | ||||||
5097 | case clang::Type::DependentSizedExtVector: | ||||||
5098 | case clang::Type::UnresolvedUsing: | ||||||
5099 | case clang::Type::Attributed: | ||||||
5100 | case clang::Type::TemplateTypeParm: | ||||||
5101 | case clang::Type::SubstTemplateTypeParm: | ||||||
5102 | case clang::Type::SubstTemplateTypeParmPack: | ||||||
5103 | case clang::Type::InjectedClassName: | ||||||
5104 | case clang::Type::DependentName: | ||||||
5105 | case clang::Type::DependentTemplateSpecialization: | ||||||
5106 | case clang::Type::PackExpansion: | ||||||
5107 | case clang::Type::ObjCObject: | ||||||
5108 | |||||||
5109 | case clang::Type::TemplateSpecialization: | ||||||
5110 | case clang::Type::DeducedTemplateSpecialization: | ||||||
5111 | case clang::Type::Adjusted: | ||||||
5112 | case clang::Type::Pipe: | ||||||
5113 | break; | ||||||
5114 | |||||||
5115 | // pointer type decayed from an array or function type. | ||||||
5116 | case clang::Type::Decayed: | ||||||
5117 | break; | ||||||
5118 | case clang::Type::ObjCTypeParam: | ||||||
5119 | break; | ||||||
5120 | |||||||
5121 | case clang::Type::DependentAddressSpace: | ||||||
5122 | break; | ||||||
5123 | case clang::Type::MacroQualified: | ||||||
5124 | break; | ||||||
5125 | |||||||
5126 | case clang::Type::ConstantMatrix: | ||||||
5127 | case clang::Type::DependentSizedMatrix: | ||||||
5128 | break; | ||||||
5129 | } | ||||||
5130 | count = 0; | ||||||
5131 | return lldb::eEncodingInvalid; | ||||||
5132 | } | ||||||
5133 | |||||||
5134 | lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) { | ||||||
5135 | if (!type) | ||||||
5136 | return lldb::eFormatDefault; | ||||||
5137 | |||||||
5138 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
5139 | |||||||
5140 | switch (qual_type->getTypeClass()) { | ||||||
5141 | case clang::Type::Atomic: | ||||||
5142 | case clang::Type::Auto: | ||||||
5143 | case clang::Type::Decltype: | ||||||
5144 | case clang::Type::Elaborated: | ||||||
5145 | case clang::Type::Paren: | ||||||
5146 | case clang::Type::Typedef: | ||||||
5147 | case clang::Type::TypeOf: | ||||||
5148 | case clang::Type::TypeOfExpr: | ||||||
5149 | case clang::Type::Using: | ||||||
5150 | llvm_unreachable("Handled in RemoveWrappingTypes!")::llvm::llvm_unreachable_internal("Handled in RemoveWrappingTypes!" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 5150); | ||||||
5151 | case clang::Type::UnaryTransform: | ||||||
5152 | break; | ||||||
5153 | |||||||
5154 | case clang::Type::FunctionNoProto: | ||||||
5155 | case clang::Type::FunctionProto: | ||||||
5156 | break; | ||||||
5157 | |||||||
5158 | case clang::Type::IncompleteArray: | ||||||
5159 | case clang::Type::VariableArray: | ||||||
5160 | break; | ||||||
5161 | |||||||
5162 | case clang::Type::ConstantArray: | ||||||
5163 | return lldb::eFormatVoid; // no value | ||||||
5164 | |||||||
5165 | case clang::Type::DependentVector: | ||||||
5166 | case clang::Type::ExtVector: | ||||||
5167 | case clang::Type::Vector: | ||||||
5168 | break; | ||||||
5169 | |||||||
5170 | case clang::Type::BitInt: | ||||||
5171 | case clang::Type::DependentBitInt: | ||||||
5172 | return qual_type->isUnsignedIntegerType() ? lldb::eFormatUnsigned | ||||||
5173 | : lldb::eFormatDecimal; | ||||||
5174 | |||||||
5175 | case clang::Type::Builtin: | ||||||
5176 | switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) { | ||||||
5177 | case clang::BuiltinType::UnknownAny: | ||||||
5178 | case clang::BuiltinType::Void: | ||||||
5179 | case clang::BuiltinType::BoundMember: | ||||||
5180 | break; | ||||||
5181 | |||||||
5182 | case clang::BuiltinType::Bool: | ||||||
5183 | return lldb::eFormatBoolean; | ||||||
5184 | case clang::BuiltinType::Char_S: | ||||||
5185 | case clang::BuiltinType::SChar: | ||||||
5186 | case clang::BuiltinType::WChar_S: | ||||||
5187 | case clang::BuiltinType::Char_U: | ||||||
5188 | case clang::BuiltinType::UChar: | ||||||
5189 | case clang::BuiltinType::WChar_U: | ||||||
5190 | return lldb::eFormatChar; | ||||||
5191 | case clang::BuiltinType::Char8: | ||||||
5192 | return lldb::eFormatUnicode8; | ||||||
5193 | case clang::BuiltinType::Char16: | ||||||
5194 | return lldb::eFormatUnicode16; | ||||||
5195 | case clang::BuiltinType::Char32: | ||||||
5196 | return lldb::eFormatUnicode32; | ||||||
5197 | case clang::BuiltinType::UShort: | ||||||
5198 | return lldb::eFormatUnsigned; | ||||||
5199 | case clang::BuiltinType::Short: | ||||||
5200 | return lldb::eFormatDecimal; | ||||||
5201 | case clang::BuiltinType::UInt: | ||||||
5202 | return lldb::eFormatUnsigned; | ||||||
5203 | case clang::BuiltinType::Int: | ||||||
5204 | return lldb::eFormatDecimal; | ||||||
5205 | case clang::BuiltinType::ULong: | ||||||
5206 | return lldb::eFormatUnsigned; | ||||||
5207 | case clang::BuiltinType::Long: | ||||||
5208 | return lldb::eFormatDecimal; | ||||||
5209 | case clang::BuiltinType::ULongLong: | ||||||
5210 | return lldb::eFormatUnsigned; | ||||||
5211 | case clang::BuiltinType::LongLong: | ||||||
5212 | return lldb::eFormatDecimal; | ||||||
5213 | case clang::BuiltinType::UInt128: | ||||||
5214 | return lldb::eFormatUnsigned; | ||||||
5215 | case clang::BuiltinType::Int128: | ||||||
5216 | return lldb::eFormatDecimal; | ||||||
5217 | case clang::BuiltinType::Half: | ||||||
5218 | case clang::BuiltinType::Float: | ||||||
5219 | case clang::BuiltinType::Double: | ||||||
5220 | case clang::BuiltinType::LongDouble: | ||||||
5221 | return lldb::eFormatFloat; | ||||||
5222 | default: | ||||||
5223 | return lldb::eFormatHex; | ||||||
5224 | } | ||||||
5225 | break; | ||||||
5226 | case clang::Type::ObjCObjectPointer: | ||||||
5227 | return lldb::eFormatHex; | ||||||
5228 | case clang::Type::BlockPointer: | ||||||
5229 | return lldb::eFormatHex; | ||||||
5230 | case clang::Type::Pointer: | ||||||
5231 | return lldb::eFormatHex; | ||||||
5232 | case clang::Type::LValueReference: | ||||||
5233 | case clang::Type::RValueReference: | ||||||
5234 | return lldb::eFormatHex; | ||||||
5235 | case clang::Type::MemberPointer: | ||||||
5236 | break; | ||||||
5237 | case clang::Type::Complex: { | ||||||
5238 | if (qual_type->isComplexType()) | ||||||
5239 | return lldb::eFormatComplex; | ||||||
5240 | else | ||||||
5241 | return lldb::eFormatComplexInteger; | ||||||
5242 | } | ||||||
5243 | case clang::Type::ObjCInterface: | ||||||
5244 | break; | ||||||
5245 | case clang::Type::Record: | ||||||
5246 | break; | ||||||
5247 | case clang::Type::Enum: | ||||||
5248 | return lldb::eFormatEnum; | ||||||
5249 | case clang::Type::DependentSizedArray: | ||||||
5250 | case clang::Type::DependentSizedExtVector: | ||||||
5251 | case clang::Type::UnresolvedUsing: | ||||||
5252 | case clang::Type::Attributed: | ||||||
5253 | case clang::Type::TemplateTypeParm: | ||||||
5254 | case clang::Type::SubstTemplateTypeParm: | ||||||
5255 | case clang::Type::SubstTemplateTypeParmPack: | ||||||
5256 | case clang::Type::InjectedClassName: | ||||||
5257 | case clang::Type::DependentName: | ||||||
5258 | case clang::Type::DependentTemplateSpecialization: | ||||||
5259 | case clang::Type::PackExpansion: | ||||||
5260 | case clang::Type::ObjCObject: | ||||||
5261 | |||||||
5262 | case clang::Type::TemplateSpecialization: | ||||||
5263 | case clang::Type::DeducedTemplateSpecialization: | ||||||
5264 | case clang::Type::Adjusted: | ||||||
5265 | case clang::Type::Pipe: | ||||||
5266 | break; | ||||||
5267 | |||||||
5268 | // pointer type decayed from an array or function type. | ||||||
5269 | case clang::Type::Decayed: | ||||||
5270 | break; | ||||||
5271 | case clang::Type::ObjCTypeParam: | ||||||
5272 | break; | ||||||
5273 | |||||||
5274 | case clang::Type::DependentAddressSpace: | ||||||
5275 | break; | ||||||
5276 | case clang::Type::MacroQualified: | ||||||
5277 | break; | ||||||
5278 | |||||||
5279 | // Matrix types we're not sure how to display yet. | ||||||
5280 | case clang::Type::ConstantMatrix: | ||||||
5281 | case clang::Type::DependentSizedMatrix: | ||||||
5282 | break; | ||||||
5283 | } | ||||||
5284 | // We don't know hot to display this type... | ||||||
5285 | return lldb::eFormatBytes; | ||||||
5286 | } | ||||||
5287 | |||||||
5288 | static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl, | ||||||
5289 | bool check_superclass) { | ||||||
5290 | while (class_interface_decl) { | ||||||
5291 | if (class_interface_decl->ivar_size() > 0) | ||||||
5292 | return true; | ||||||
5293 | |||||||
5294 | if (check_superclass) | ||||||
5295 | class_interface_decl = class_interface_decl->getSuperClass(); | ||||||
5296 | else | ||||||
5297 | break; | ||||||
5298 | } | ||||||
5299 | return false; | ||||||
5300 | } | ||||||
5301 | |||||||
5302 | static Optional<SymbolFile::ArrayInfo> | ||||||
5303 | GetDynamicArrayInfo(TypeSystemClang &ast, SymbolFile *sym_file, | ||||||
5304 | clang::QualType qual_type, | ||||||
5305 | const ExecutionContext *exe_ctx) { | ||||||
5306 | if (qual_type->isIncompleteArrayType()) | ||||||
5307 | if (auto *metadata = ast.GetMetadata(qual_type.getTypePtr())) | ||||||
5308 | return sym_file->GetDynamicArrayInfoForUID(metadata->GetUserID(), | ||||||
5309 | exe_ctx); | ||||||
5310 | return llvm::None; | ||||||
5311 | } | ||||||
5312 | |||||||
5313 | uint32_t TypeSystemClang::GetNumChildren(lldb::opaque_compiler_type_t type, | ||||||
5314 | bool omit_empty_base_classes, | ||||||
5315 | const ExecutionContext *exe_ctx) { | ||||||
5316 | if (!type) | ||||||
5317 | return 0; | ||||||
5318 | |||||||
5319 | uint32_t num_children = 0; | ||||||
5320 | clang::QualType qual_type(RemoveWrappingTypes(GetQualType(type))); | ||||||
5321 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
5322 | switch (type_class) { | ||||||
5323 | case clang::Type::Builtin: | ||||||
5324 | switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) { | ||||||
5325 | case clang::BuiltinType::ObjCId: // child is Class | ||||||
5326 | case clang::BuiltinType::ObjCClass: // child is Class | ||||||
5327 | num_children = 1; | ||||||
5328 | break; | ||||||
5329 | |||||||
5330 | default: | ||||||
5331 | break; | ||||||
5332 | } | ||||||
5333 | break; | ||||||
5334 | |||||||
5335 | case clang::Type::Complex: | ||||||
5336 | return 0; | ||||||
5337 | case clang::Type::Record: | ||||||
5338 | if (GetCompleteQualType(&getASTContext(), qual_type)) { | ||||||
5339 | const clang::RecordType *record_type = | ||||||
5340 | llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
5341 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
5342 | assert(record_decl)(static_cast <bool> (record_decl) ? void (0) : __assert_fail ("record_decl", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 5342, __extension__ __PRETTY_FUNCTION__)); | ||||||
5343 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
5344 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); | ||||||
5345 | if (cxx_record_decl) { | ||||||
5346 | if (omit_empty_base_classes) { | ||||||
5347 | // Check each base classes to see if it or any of its base classes | ||||||
5348 | // contain any fields. This can help limit the noise in variable | ||||||
5349 | // views by not having to show base classes that contain no members. | ||||||
5350 | clang::CXXRecordDecl::base_class_const_iterator base_class, | ||||||
5351 | base_class_end; | ||||||
5352 | for (base_class = cxx_record_decl->bases_begin(), | ||||||
5353 | base_class_end = cxx_record_decl->bases_end(); | ||||||
5354 | base_class != base_class_end; ++base_class) { | ||||||
5355 | const clang::CXXRecordDecl *base_class_decl = | ||||||
5356 | llvm::cast<clang::CXXRecordDecl>( | ||||||
5357 | base_class->getType() | ||||||
5358 | ->getAs<clang::RecordType>() | ||||||
5359 | ->getDecl()); | ||||||
5360 | |||||||
5361 | // Skip empty base classes | ||||||
5362 | if (!TypeSystemClang::RecordHasFields(base_class_decl)) | ||||||
5363 | continue; | ||||||
5364 | |||||||
5365 | num_children++; | ||||||
5366 | } | ||||||
5367 | } else { | ||||||
5368 | // Include all base classes | ||||||
5369 | num_children += cxx_record_decl->getNumBases(); | ||||||
5370 | } | ||||||
5371 | } | ||||||
5372 | clang::RecordDecl::field_iterator field, field_end; | ||||||
5373 | for (field = record_decl->field_begin(), | ||||||
5374 | field_end = record_decl->field_end(); | ||||||
5375 | field != field_end; ++field) | ||||||
5376 | ++num_children; | ||||||
5377 | } | ||||||
5378 | break; | ||||||
5379 | |||||||
5380 | case clang::Type::ObjCObject: | ||||||
5381 | case clang::Type::ObjCInterface: | ||||||
5382 | if (GetCompleteQualType(&getASTContext(), qual_type)) { | ||||||
5383 | const clang::ObjCObjectType *objc_class_type = | ||||||
5384 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); | ||||||
5385 | assert(objc_class_type)(static_cast <bool> (objc_class_type) ? void (0) : __assert_fail ("objc_class_type", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 5385, __extension__ __PRETTY_FUNCTION__)); | ||||||
5386 | if (objc_class_type) { | ||||||
5387 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
5388 | objc_class_type->getInterface(); | ||||||
5389 | |||||||
5390 | if (class_interface_decl) { | ||||||
5391 | |||||||
5392 | clang::ObjCInterfaceDecl *superclass_interface_decl = | ||||||
5393 | class_interface_decl->getSuperClass(); | ||||||
5394 | if (superclass_interface_decl) { | ||||||
5395 | if (omit_empty_base_classes) { | ||||||
5396 | if (ObjCDeclHasIVars(superclass_interface_decl, true)) | ||||||
5397 | ++num_children; | ||||||
5398 | } else | ||||||
5399 | ++num_children; | ||||||
5400 | } | ||||||
5401 | |||||||
5402 | num_children += class_interface_decl->ivar_size(); | ||||||
5403 | } | ||||||
5404 | } | ||||||
5405 | } | ||||||
5406 | break; | ||||||
5407 | |||||||
5408 | case clang::Type::LValueReference: | ||||||
5409 | case clang::Type::RValueReference: | ||||||
5410 | case clang::Type::ObjCObjectPointer: { | ||||||
5411 | CompilerType pointee_clang_type(GetPointeeType(type)); | ||||||
5412 | |||||||
5413 | uint32_t num_pointee_children = 0; | ||||||
5414 | if (pointee_clang_type.IsAggregateType()) | ||||||
5415 | num_pointee_children = | ||||||
5416 | pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx); | ||||||
5417 | // If this type points to a simple type, then it has 1 child | ||||||
5418 | if (num_pointee_children == 0) | ||||||
5419 | num_children = 1; | ||||||
5420 | else | ||||||
5421 | num_children = num_pointee_children; | ||||||
5422 | } break; | ||||||
5423 | |||||||
5424 | case clang::Type::Vector: | ||||||
5425 | case clang::Type::ExtVector: | ||||||
5426 | num_children = | ||||||
5427 | llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements(); | ||||||
5428 | break; | ||||||
5429 | |||||||
5430 | case clang::Type::ConstantArray: | ||||||
5431 | num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr()) | ||||||
5432 | ->getSize() | ||||||
5433 | .getLimitedValue(); | ||||||
5434 | break; | ||||||
5435 | case clang::Type::IncompleteArray: | ||||||
5436 | if (auto array_info = | ||||||
5437 | GetDynamicArrayInfo(*this, GetSymbolFile(), qual_type, exe_ctx)) | ||||||
5438 | // Only 1-dimensional arrays are supported. | ||||||
5439 | num_children = array_info->element_orders.size() | ||||||
5440 | ? array_info->element_orders.back() | ||||||
5441 | : 0; | ||||||
5442 | break; | ||||||
5443 | |||||||
5444 | case clang::Type::Pointer: { | ||||||
5445 | const clang::PointerType *pointer_type = | ||||||
5446 | llvm::cast<clang::PointerType>(qual_type.getTypePtr()); | ||||||
5447 | clang::QualType pointee_type(pointer_type->getPointeeType()); | ||||||
5448 | CompilerType pointee_clang_type(GetType(pointee_type)); | ||||||
5449 | uint32_t num_pointee_children = 0; | ||||||
5450 | if (pointee_clang_type.IsAggregateType()) | ||||||
5451 | num_pointee_children = | ||||||
5452 | pointee_clang_type.GetNumChildren(omit_empty_base_classes, exe_ctx); | ||||||
5453 | if (num_pointee_children == 0) { | ||||||
5454 | // We have a pointer to a pointee type that claims it has no children. We | ||||||
5455 | // will want to look at | ||||||
5456 | num_children = GetNumPointeeChildren(pointee_type); | ||||||
5457 | } else | ||||||
5458 | num_children = num_pointee_children; | ||||||
5459 | } break; | ||||||
5460 | |||||||
5461 | default: | ||||||
5462 | break; | ||||||
5463 | } | ||||||
5464 | return num_children; | ||||||
5465 | } | ||||||
5466 | |||||||
5467 | CompilerType TypeSystemClang::GetBuiltinTypeByName(ConstString name) { | ||||||
5468 | return GetBasicType(GetBasicTypeEnumeration(name)); | ||||||
5469 | } | ||||||
5470 | |||||||
5471 | lldb::BasicType | ||||||
5472 | TypeSystemClang::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) { | ||||||
5473 | if (type) { | ||||||
5474 | clang::QualType qual_type(GetQualType(type)); | ||||||
5475 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
5476 | if (type_class == clang::Type::Builtin) { | ||||||
5477 | switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) { | ||||||
5478 | case clang::BuiltinType::Void: | ||||||
5479 | return eBasicTypeVoid; | ||||||
5480 | case clang::BuiltinType::Bool: | ||||||
5481 | return eBasicTypeBool; | ||||||
5482 | case clang::BuiltinType::Char_S: | ||||||
5483 | return eBasicTypeSignedChar; | ||||||
5484 | case clang::BuiltinType::Char_U: | ||||||
5485 | return eBasicTypeUnsignedChar; | ||||||
5486 | case clang::BuiltinType::Char16: | ||||||
5487 | return eBasicTypeChar16; | ||||||
5488 | case clang::BuiltinType::Char32: | ||||||
5489 | return eBasicTypeChar32; | ||||||
5490 | case clang::BuiltinType::UChar: | ||||||
5491 | return eBasicTypeUnsignedChar; | ||||||
5492 | case clang::BuiltinType::SChar: | ||||||
5493 | return eBasicTypeSignedChar; | ||||||
5494 | case clang::BuiltinType::WChar_S: | ||||||
5495 | return eBasicTypeSignedWChar; | ||||||
5496 | case clang::BuiltinType::WChar_U: | ||||||
5497 | return eBasicTypeUnsignedWChar; | ||||||
5498 | case clang::BuiltinType::Short: | ||||||
5499 | return eBasicTypeShort; | ||||||
5500 | case clang::BuiltinType::UShort: | ||||||
5501 | return eBasicTypeUnsignedShort; | ||||||
5502 | case clang::BuiltinType::Int: | ||||||
5503 | return eBasicTypeInt; | ||||||
5504 | case clang::BuiltinType::UInt: | ||||||
5505 | return eBasicTypeUnsignedInt; | ||||||
5506 | case clang::BuiltinType::Long: | ||||||
5507 | return eBasicTypeLong; | ||||||
5508 | case clang::BuiltinType::ULong: | ||||||
5509 | return eBasicTypeUnsignedLong; | ||||||
5510 | case clang::BuiltinType::LongLong: | ||||||
5511 | return eBasicTypeLongLong; | ||||||
5512 | case clang::BuiltinType::ULongLong: | ||||||
5513 | return eBasicTypeUnsignedLongLong; | ||||||
5514 | case clang::BuiltinType::Int128: | ||||||
5515 | return eBasicTypeInt128; | ||||||
5516 | case clang::BuiltinType::UInt128: | ||||||
5517 | return eBasicTypeUnsignedInt128; | ||||||
5518 | |||||||
5519 | case clang::BuiltinType::Half: | ||||||
5520 | return eBasicTypeHalf; | ||||||
5521 | case clang::BuiltinType::Float: | ||||||
5522 | return eBasicTypeFloat; | ||||||
5523 | case clang::BuiltinType::Double: | ||||||
5524 | return eBasicTypeDouble; | ||||||
5525 | case clang::BuiltinType::LongDouble: | ||||||
5526 | return eBasicTypeLongDouble; | ||||||
5527 | |||||||
5528 | case clang::BuiltinType::NullPtr: | ||||||
5529 | return eBasicTypeNullPtr; | ||||||
5530 | case clang::BuiltinType::ObjCId: | ||||||
5531 | return eBasicTypeObjCID; | ||||||
5532 | case clang::BuiltinType::ObjCClass: | ||||||
5533 | return eBasicTypeObjCClass; | ||||||
5534 | case clang::BuiltinType::ObjCSel: | ||||||
5535 | return eBasicTypeObjCSel; | ||||||
5536 | default: | ||||||
5537 | return eBasicTypeOther; | ||||||
5538 | } | ||||||
5539 | } | ||||||
5540 | } | ||||||
5541 | return eBasicTypeInvalid; | ||||||
5542 | } | ||||||
5543 | |||||||
5544 | void TypeSystemClang::ForEachEnumerator( | ||||||
5545 | lldb::opaque_compiler_type_t type, | ||||||
5546 | std::function<bool(const CompilerType &integer_type, | ||||||
5547 | ConstString name, | ||||||
5548 | const llvm::APSInt &value)> const &callback) { | ||||||
5549 | const clang::EnumType *enum_type = | ||||||
5550 | llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type)); | ||||||
5551 | if (enum_type) { | ||||||
5552 | const clang::EnumDecl *enum_decl = enum_type->getDecl(); | ||||||
5553 | if (enum_decl) { | ||||||
5554 | CompilerType integer_type = GetType(enum_decl->getIntegerType()); | ||||||
5555 | |||||||
5556 | clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; | ||||||
5557 | for (enum_pos = enum_decl->enumerator_begin(), | ||||||
5558 | enum_end_pos = enum_decl->enumerator_end(); | ||||||
5559 | enum_pos != enum_end_pos; ++enum_pos) { | ||||||
5560 | ConstString name(enum_pos->getNameAsString().c_str()); | ||||||
5561 | if (!callback(integer_type, name, enum_pos->getInitVal())) | ||||||
5562 | break; | ||||||
5563 | } | ||||||
5564 | } | ||||||
5565 | } | ||||||
5566 | } | ||||||
5567 | |||||||
5568 | #pragma mark Aggregate Types | ||||||
5569 | |||||||
5570 | uint32_t TypeSystemClang::GetNumFields(lldb::opaque_compiler_type_t type) { | ||||||
5571 | if (!type) | ||||||
5572 | return 0; | ||||||
5573 | |||||||
5574 | uint32_t count = 0; | ||||||
5575 | clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); | ||||||
5576 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
5577 | switch (type_class) { | ||||||
5578 | case clang::Type::Record: | ||||||
5579 | if (GetCompleteType(type)) { | ||||||
5580 | const clang::RecordType *record_type = | ||||||
5581 | llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
5582 | if (record_type) { | ||||||
5583 | clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
5584 | if (record_decl) { | ||||||
5585 | uint32_t field_idx = 0; | ||||||
5586 | clang::RecordDecl::field_iterator field, field_end; | ||||||
5587 | for (field = record_decl->field_begin(), | ||||||
5588 | field_end = record_decl->field_end(); | ||||||
5589 | field != field_end; ++field) | ||||||
5590 | ++field_idx; | ||||||
5591 | count = field_idx; | ||||||
5592 | } | ||||||
5593 | } | ||||||
5594 | } | ||||||
5595 | break; | ||||||
5596 | |||||||
5597 | case clang::Type::ObjCObjectPointer: { | ||||||
5598 | const clang::ObjCObjectPointerType *objc_class_type = | ||||||
5599 | qual_type->getAs<clang::ObjCObjectPointerType>(); | ||||||
5600 | const clang::ObjCInterfaceType *objc_interface_type = | ||||||
5601 | objc_class_type->getInterfaceType(); | ||||||
5602 | if (objc_interface_type && | ||||||
5603 | GetCompleteType(static_cast<lldb::opaque_compiler_type_t>( | ||||||
5604 | const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) { | ||||||
5605 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
5606 | objc_interface_type->getDecl(); | ||||||
5607 | if (class_interface_decl) { | ||||||
5608 | count = class_interface_decl->ivar_size(); | ||||||
5609 | } | ||||||
5610 | } | ||||||
5611 | break; | ||||||
5612 | } | ||||||
5613 | |||||||
5614 | case clang::Type::ObjCObject: | ||||||
5615 | case clang::Type::ObjCInterface: | ||||||
5616 | if (GetCompleteType(type)) { | ||||||
5617 | const clang::ObjCObjectType *objc_class_type = | ||||||
5618 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); | ||||||
5619 | if (objc_class_type) { | ||||||
5620 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
5621 | objc_class_type->getInterface(); | ||||||
5622 | |||||||
5623 | if (class_interface_decl) | ||||||
5624 | count = class_interface_decl->ivar_size(); | ||||||
5625 | } | ||||||
5626 | } | ||||||
5627 | break; | ||||||
5628 | |||||||
5629 | default: | ||||||
5630 | break; | ||||||
5631 | } | ||||||
5632 | return count; | ||||||
5633 | } | ||||||
5634 | |||||||
5635 | static lldb::opaque_compiler_type_t | ||||||
5636 | GetObjCFieldAtIndex(clang::ASTContext *ast, | ||||||
5637 | clang::ObjCInterfaceDecl *class_interface_decl, size_t idx, | ||||||
5638 | std::string &name, uint64_t *bit_offset_ptr, | ||||||
5639 | uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) { | ||||||
5640 | if (class_interface_decl) { | ||||||
5641 | if (idx < (class_interface_decl->ivar_size())) { | ||||||
5642 | clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, | ||||||
5643 | ivar_end = class_interface_decl->ivar_end(); | ||||||
5644 | uint32_t ivar_idx = 0; | ||||||
5645 | |||||||
5646 | for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; | ||||||
5647 | ++ivar_pos, ++ivar_idx) { | ||||||
5648 | if (ivar_idx == idx) { | ||||||
5649 | const clang::ObjCIvarDecl *ivar_decl = *ivar_pos; | ||||||
5650 | |||||||
5651 | clang::QualType ivar_qual_type(ivar_decl->getType()); | ||||||
5652 | |||||||
5653 | name.assign(ivar_decl->getNameAsString()); | ||||||
5654 | |||||||
5655 | if (bit_offset_ptr) { | ||||||
5656 | const clang::ASTRecordLayout &interface_layout = | ||||||
5657 | ast->getASTObjCInterfaceLayout(class_interface_decl); | ||||||
5658 | *bit_offset_ptr = interface_layout.getFieldOffset(ivar_idx); | ||||||
5659 | } | ||||||
5660 | |||||||
5661 | const bool is_bitfield = ivar_pos->isBitField(); | ||||||
5662 | |||||||
5663 | if (bitfield_bit_size_ptr) { | ||||||
5664 | *bitfield_bit_size_ptr = 0; | ||||||
5665 | |||||||
5666 | if (is_bitfield && ast) { | ||||||
5667 | clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth(); | ||||||
5668 | clang::Expr::EvalResult result; | ||||||
5669 | if (bitfield_bit_size_expr && | ||||||
5670 | bitfield_bit_size_expr->EvaluateAsInt(result, *ast)) { | ||||||
5671 | llvm::APSInt bitfield_apsint = result.Val.getInt(); | ||||||
5672 | *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); | ||||||
5673 | } | ||||||
5674 | } | ||||||
5675 | } | ||||||
5676 | if (is_bitfield_ptr) | ||||||
5677 | *is_bitfield_ptr = is_bitfield; | ||||||
5678 | |||||||
5679 | return ivar_qual_type.getAsOpaquePtr(); | ||||||
5680 | } | ||||||
5681 | } | ||||||
5682 | } | ||||||
5683 | } | ||||||
5684 | return nullptr; | ||||||
5685 | } | ||||||
5686 | |||||||
5687 | CompilerType TypeSystemClang::GetFieldAtIndex(lldb::opaque_compiler_type_t type, | ||||||
5688 | size_t idx, std::string &name, | ||||||
5689 | uint64_t *bit_offset_ptr, | ||||||
5690 | uint32_t *bitfield_bit_size_ptr, | ||||||
5691 | bool *is_bitfield_ptr) { | ||||||
5692 | if (!type) | ||||||
5693 | return CompilerType(); | ||||||
5694 | |||||||
5695 | clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); | ||||||
5696 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
5697 | switch (type_class) { | ||||||
5698 | case clang::Type::Record: | ||||||
5699 | if (GetCompleteType(type)) { | ||||||
5700 | const clang::RecordType *record_type = | ||||||
5701 | llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
5702 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
5703 | uint32_t field_idx = 0; | ||||||
5704 | clang::RecordDecl::field_iterator field, field_end; | ||||||
5705 | for (field = record_decl->field_begin(), | ||||||
5706 | field_end = record_decl->field_end(); | ||||||
5707 | field != field_end; ++field, ++field_idx) { | ||||||
5708 | if (idx == field_idx) { | ||||||
5709 | // Print the member type if requested | ||||||
5710 | // Print the member name and equal sign | ||||||
5711 | name.assign(field->getNameAsString()); | ||||||
5712 | |||||||
5713 | // Figure out the type byte size (field_type_info.first) and | ||||||
5714 | // alignment (field_type_info.second) from the AST context. | ||||||
5715 | if (bit_offset_ptr) { | ||||||
5716 | const clang::ASTRecordLayout &record_layout = | ||||||
5717 | getASTContext().getASTRecordLayout(record_decl); | ||||||
5718 | *bit_offset_ptr = record_layout.getFieldOffset(field_idx); | ||||||
5719 | } | ||||||
5720 | |||||||
5721 | const bool is_bitfield = field->isBitField(); | ||||||
5722 | |||||||
5723 | if (bitfield_bit_size_ptr) { | ||||||
5724 | *bitfield_bit_size_ptr = 0; | ||||||
5725 | |||||||
5726 | if (is_bitfield) { | ||||||
5727 | clang::Expr *bitfield_bit_size_expr = field->getBitWidth(); | ||||||
5728 | clang::Expr::EvalResult result; | ||||||
5729 | if (bitfield_bit_size_expr && | ||||||
5730 | bitfield_bit_size_expr->EvaluateAsInt(result, | ||||||
5731 | getASTContext())) { | ||||||
5732 | llvm::APSInt bitfield_apsint = result.Val.getInt(); | ||||||
5733 | *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); | ||||||
5734 | } | ||||||
5735 | } | ||||||
5736 | } | ||||||
5737 | if (is_bitfield_ptr) | ||||||
5738 | *is_bitfield_ptr = is_bitfield; | ||||||
5739 | |||||||
5740 | return GetType(field->getType()); | ||||||
5741 | } | ||||||
5742 | } | ||||||
5743 | } | ||||||
5744 | break; | ||||||
5745 | |||||||
5746 | case clang::Type::ObjCObjectPointer: { | ||||||
5747 | const clang::ObjCObjectPointerType *objc_class_type = | ||||||
5748 | qual_type->getAs<clang::ObjCObjectPointerType>(); | ||||||
5749 | const clang::ObjCInterfaceType *objc_interface_type = | ||||||
5750 | objc_class_type->getInterfaceType(); | ||||||
5751 | if (objc_interface_type && | ||||||
5752 | GetCompleteType(static_cast<lldb::opaque_compiler_type_t>( | ||||||
5753 | const_cast<clang::ObjCInterfaceType *>(objc_interface_type)))) { | ||||||
5754 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
5755 | objc_interface_type->getDecl(); | ||||||
5756 | if (class_interface_decl) { | ||||||
5757 | return CompilerType( | ||||||
5758 | this, GetObjCFieldAtIndex(&getASTContext(), class_interface_decl, | ||||||
5759 | idx, name, bit_offset_ptr, | ||||||
5760 | bitfield_bit_size_ptr, is_bitfield_ptr)); | ||||||
5761 | } | ||||||
5762 | } | ||||||
5763 | break; | ||||||
5764 | } | ||||||
5765 | |||||||
5766 | case clang::Type::ObjCObject: | ||||||
5767 | case clang::Type::ObjCInterface: | ||||||
5768 | if (GetCompleteType(type)) { | ||||||
5769 | const clang::ObjCObjectType *objc_class_type = | ||||||
5770 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); | ||||||
5771 | assert(objc_class_type)(static_cast <bool> (objc_class_type) ? void (0) : __assert_fail ("objc_class_type", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 5771, __extension__ __PRETTY_FUNCTION__)); | ||||||
5772 | if (objc_class_type) { | ||||||
5773 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
5774 | objc_class_type->getInterface(); | ||||||
5775 | return CompilerType( | ||||||
5776 | this, GetObjCFieldAtIndex(&getASTContext(), class_interface_decl, | ||||||
5777 | idx, name, bit_offset_ptr, | ||||||
5778 | bitfield_bit_size_ptr, is_bitfield_ptr)); | ||||||
5779 | } | ||||||
5780 | } | ||||||
5781 | break; | ||||||
5782 | |||||||
5783 | default: | ||||||
5784 | break; | ||||||
5785 | } | ||||||
5786 | return CompilerType(); | ||||||
5787 | } | ||||||
5788 | |||||||
5789 | uint32_t | ||||||
5790 | TypeSystemClang::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) { | ||||||
5791 | uint32_t count = 0; | ||||||
5792 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
5793 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
5794 | switch (type_class) { | ||||||
5795 | case clang::Type::Record: | ||||||
5796 | if (GetCompleteType(type)) { | ||||||
5797 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
5798 | qual_type->getAsCXXRecordDecl(); | ||||||
5799 | if (cxx_record_decl) | ||||||
5800 | count = cxx_record_decl->getNumBases(); | ||||||
5801 | } | ||||||
5802 | break; | ||||||
5803 | |||||||
5804 | case clang::Type::ObjCObjectPointer: | ||||||
5805 | count = GetPointeeType(type).GetNumDirectBaseClasses(); | ||||||
5806 | break; | ||||||
5807 | |||||||
5808 | case clang::Type::ObjCObject: | ||||||
5809 | if (GetCompleteType(type)) { | ||||||
5810 | const clang::ObjCObjectType *objc_class_type = | ||||||
5811 | qual_type->getAsObjCQualifiedInterfaceType(); | ||||||
5812 | if (objc_class_type) { | ||||||
5813 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
5814 | objc_class_type->getInterface(); | ||||||
5815 | |||||||
5816 | if (class_interface_decl && class_interface_decl->getSuperClass()) | ||||||
5817 | count = 1; | ||||||
5818 | } | ||||||
5819 | } | ||||||
5820 | break; | ||||||
5821 | case clang::Type::ObjCInterface: | ||||||
5822 | if (GetCompleteType(type)) { | ||||||
5823 | const clang::ObjCInterfaceType *objc_interface_type = | ||||||
5824 | qual_type->getAs<clang::ObjCInterfaceType>(); | ||||||
5825 | if (objc_interface_type) { | ||||||
5826 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
5827 | objc_interface_type->getInterface(); | ||||||
5828 | |||||||
5829 | if (class_interface_decl && class_interface_decl->getSuperClass()) | ||||||
5830 | count = 1; | ||||||
5831 | } | ||||||
5832 | } | ||||||
5833 | break; | ||||||
5834 | |||||||
5835 | default: | ||||||
5836 | break; | ||||||
5837 | } | ||||||
5838 | return count; | ||||||
5839 | } | ||||||
5840 | |||||||
5841 | uint32_t | ||||||
5842 | TypeSystemClang::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) { | ||||||
5843 | uint32_t count = 0; | ||||||
5844 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
5845 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
5846 | switch (type_class) { | ||||||
5847 | case clang::Type::Record: | ||||||
5848 | if (GetCompleteType(type)) { | ||||||
5849 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
5850 | qual_type->getAsCXXRecordDecl(); | ||||||
5851 | if (cxx_record_decl) | ||||||
5852 | count = cxx_record_decl->getNumVBases(); | ||||||
5853 | } | ||||||
5854 | break; | ||||||
5855 | |||||||
5856 | default: | ||||||
5857 | break; | ||||||
5858 | } | ||||||
5859 | return count; | ||||||
5860 | } | ||||||
5861 | |||||||
5862 | CompilerType TypeSystemClang::GetDirectBaseClassAtIndex( | ||||||
5863 | lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) { | ||||||
5864 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
5865 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
5866 | switch (type_class) { | ||||||
5867 | case clang::Type::Record: | ||||||
5868 | if (GetCompleteType(type)) { | ||||||
5869 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
5870 | qual_type->getAsCXXRecordDecl(); | ||||||
5871 | if (cxx_record_decl) { | ||||||
5872 | uint32_t curr_idx = 0; | ||||||
5873 | clang::CXXRecordDecl::base_class_const_iterator base_class, | ||||||
5874 | base_class_end; | ||||||
5875 | for (base_class = cxx_record_decl->bases_begin(), | ||||||
5876 | base_class_end = cxx_record_decl->bases_end(); | ||||||
5877 | base_class != base_class_end; ++base_class, ++curr_idx) { | ||||||
5878 | if (curr_idx == idx) { | ||||||
5879 | if (bit_offset_ptr) { | ||||||
5880 | const clang::ASTRecordLayout &record_layout = | ||||||
5881 | getASTContext().getASTRecordLayout(cxx_record_decl); | ||||||
5882 | const clang::CXXRecordDecl *base_class_decl = | ||||||
5883 | llvm::cast<clang::CXXRecordDecl>( | ||||||
5884 | base_class->getType() | ||||||
5885 | ->getAs<clang::RecordType>() | ||||||
5886 | ->getDecl()); | ||||||
5887 | if (base_class->isVirtual()) | ||||||
5888 | *bit_offset_ptr = | ||||||
5889 | record_layout.getVBaseClassOffset(base_class_decl) | ||||||
5890 | .getQuantity() * | ||||||
5891 | 8; | ||||||
5892 | else | ||||||
5893 | *bit_offset_ptr = | ||||||
5894 | record_layout.getBaseClassOffset(base_class_decl) | ||||||
5895 | .getQuantity() * | ||||||
5896 | 8; | ||||||
5897 | } | ||||||
5898 | return GetType(base_class->getType()); | ||||||
5899 | } | ||||||
5900 | } | ||||||
5901 | } | ||||||
5902 | } | ||||||
5903 | break; | ||||||
5904 | |||||||
5905 | case clang::Type::ObjCObjectPointer: | ||||||
5906 | return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr); | ||||||
5907 | |||||||
5908 | case clang::Type::ObjCObject: | ||||||
5909 | if (idx == 0 && GetCompleteType(type)) { | ||||||
5910 | const clang::ObjCObjectType *objc_class_type = | ||||||
5911 | qual_type->getAsObjCQualifiedInterfaceType(); | ||||||
5912 | if (objc_class_type) { | ||||||
5913 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
5914 | objc_class_type->getInterface(); | ||||||
5915 | |||||||
5916 | if (class_interface_decl) { | ||||||
5917 | clang::ObjCInterfaceDecl *superclass_interface_decl = | ||||||
5918 | class_interface_decl->getSuperClass(); | ||||||
5919 | if (superclass_interface_decl) { | ||||||
5920 | if (bit_offset_ptr) | ||||||
5921 | *bit_offset_ptr = 0; | ||||||
5922 | return GetType(getASTContext().getObjCInterfaceType( | ||||||
5923 | superclass_interface_decl)); | ||||||
5924 | } | ||||||
5925 | } | ||||||
5926 | } | ||||||
5927 | } | ||||||
5928 | break; | ||||||
5929 | case clang::Type::ObjCInterface: | ||||||
5930 | if (idx == 0 && GetCompleteType(type)) { | ||||||
5931 | const clang::ObjCObjectType *objc_interface_type = | ||||||
5932 | qual_type->getAs<clang::ObjCInterfaceType>(); | ||||||
5933 | if (objc_interface_type) { | ||||||
5934 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
5935 | objc_interface_type->getInterface(); | ||||||
5936 | |||||||
5937 | if (class_interface_decl) { | ||||||
5938 | clang::ObjCInterfaceDecl *superclass_interface_decl = | ||||||
5939 | class_interface_decl->getSuperClass(); | ||||||
5940 | if (superclass_interface_decl) { | ||||||
5941 | if (bit_offset_ptr) | ||||||
5942 | *bit_offset_ptr = 0; | ||||||
5943 | return GetType(getASTContext().getObjCInterfaceType( | ||||||
5944 | superclass_interface_decl)); | ||||||
5945 | } | ||||||
5946 | } | ||||||
5947 | } | ||||||
5948 | } | ||||||
5949 | break; | ||||||
5950 | |||||||
5951 | default: | ||||||
5952 | break; | ||||||
5953 | } | ||||||
5954 | return CompilerType(); | ||||||
5955 | } | ||||||
5956 | |||||||
5957 | CompilerType TypeSystemClang::GetVirtualBaseClassAtIndex( | ||||||
5958 | lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) { | ||||||
5959 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
5960 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
5961 | switch (type_class) { | ||||||
5962 | case clang::Type::Record: | ||||||
5963 | if (GetCompleteType(type)) { | ||||||
5964 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
5965 | qual_type->getAsCXXRecordDecl(); | ||||||
5966 | if (cxx_record_decl) { | ||||||
5967 | uint32_t curr_idx = 0; | ||||||
5968 | clang::CXXRecordDecl::base_class_const_iterator base_class, | ||||||
5969 | base_class_end; | ||||||
5970 | for (base_class = cxx_record_decl->vbases_begin(), | ||||||
5971 | base_class_end = cxx_record_decl->vbases_end(); | ||||||
5972 | base_class != base_class_end; ++base_class, ++curr_idx) { | ||||||
5973 | if (curr_idx == idx) { | ||||||
5974 | if (bit_offset_ptr) { | ||||||
5975 | const clang::ASTRecordLayout &record_layout = | ||||||
5976 | getASTContext().getASTRecordLayout(cxx_record_decl); | ||||||
5977 | const clang::CXXRecordDecl *base_class_decl = | ||||||
5978 | llvm::cast<clang::CXXRecordDecl>( | ||||||
5979 | base_class->getType() | ||||||
5980 | ->getAs<clang::RecordType>() | ||||||
5981 | ->getDecl()); | ||||||
5982 | *bit_offset_ptr = | ||||||
5983 | record_layout.getVBaseClassOffset(base_class_decl) | ||||||
5984 | .getQuantity() * | ||||||
5985 | 8; | ||||||
5986 | } | ||||||
5987 | return GetType(base_class->getType()); | ||||||
5988 | } | ||||||
5989 | } | ||||||
5990 | } | ||||||
5991 | } | ||||||
5992 | break; | ||||||
5993 | |||||||
5994 | default: | ||||||
5995 | break; | ||||||
5996 | } | ||||||
5997 | return CompilerType(); | ||||||
5998 | } | ||||||
5999 | |||||||
6000 | // If a pointer to a pointee type (the clang_type arg) says that it has no | ||||||
6001 | // children, then we either need to trust it, or override it and return a | ||||||
6002 | // different result. For example, an "int *" has one child that is an integer, | ||||||
6003 | // but a function pointer doesn't have any children. Likewise if a Record type | ||||||
6004 | // claims it has no children, then there really is nothing to show. | ||||||
6005 | uint32_t TypeSystemClang::GetNumPointeeChildren(clang::QualType type) { | ||||||
6006 | if (type.isNull()) | ||||||
6007 | return 0; | ||||||
6008 | |||||||
6009 | clang::QualType qual_type = RemoveWrappingTypes(type.getCanonicalType()); | ||||||
6010 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
6011 | switch (type_class) { | ||||||
6012 | case clang::Type::Builtin: | ||||||
6013 | switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) { | ||||||
6014 | case clang::BuiltinType::UnknownAny: | ||||||
6015 | case clang::BuiltinType::Void: | ||||||
6016 | case clang::BuiltinType::NullPtr: | ||||||
6017 | case clang::BuiltinType::OCLEvent: | ||||||
6018 | case clang::BuiltinType::OCLImage1dRO: | ||||||
6019 | case clang::BuiltinType::OCLImage1dWO: | ||||||
6020 | case clang::BuiltinType::OCLImage1dRW: | ||||||
6021 | case clang::BuiltinType::OCLImage1dArrayRO: | ||||||
6022 | case clang::BuiltinType::OCLImage1dArrayWO: | ||||||
6023 | case clang::BuiltinType::OCLImage1dArrayRW: | ||||||
6024 | case clang::BuiltinType::OCLImage1dBufferRO: | ||||||
6025 | case clang::BuiltinType::OCLImage1dBufferWO: | ||||||
6026 | case clang::BuiltinType::OCLImage1dBufferRW: | ||||||
6027 | case clang::BuiltinType::OCLImage2dRO: | ||||||
6028 | case clang::BuiltinType::OCLImage2dWO: | ||||||
6029 | case clang::BuiltinType::OCLImage2dRW: | ||||||
6030 | case clang::BuiltinType::OCLImage2dArrayRO: | ||||||
6031 | case clang::BuiltinType::OCLImage2dArrayWO: | ||||||
6032 | case clang::BuiltinType::OCLImage2dArrayRW: | ||||||
6033 | case clang::BuiltinType::OCLImage3dRO: | ||||||
6034 | case clang::BuiltinType::OCLImage3dWO: | ||||||
6035 | case clang::BuiltinType::OCLImage3dRW: | ||||||
6036 | case clang::BuiltinType::OCLSampler: | ||||||
6037 | return 0; | ||||||
6038 | case clang::BuiltinType::Bool: | ||||||
6039 | case clang::BuiltinType::Char_U: | ||||||
6040 | case clang::BuiltinType::UChar: | ||||||
6041 | case clang::BuiltinType::WChar_U: | ||||||
6042 | case clang::BuiltinType::Char16: | ||||||
6043 | case clang::BuiltinType::Char32: | ||||||
6044 | case clang::BuiltinType::UShort: | ||||||
6045 | case clang::BuiltinType::UInt: | ||||||
6046 | case clang::BuiltinType::ULong: | ||||||
6047 | case clang::BuiltinType::ULongLong: | ||||||
6048 | case clang::BuiltinType::UInt128: | ||||||
6049 | case clang::BuiltinType::Char_S: | ||||||
6050 | case clang::BuiltinType::SChar: | ||||||
6051 | case clang::BuiltinType::WChar_S: | ||||||
6052 | case clang::BuiltinType::Short: | ||||||
6053 | case clang::BuiltinType::Int: | ||||||
6054 | case clang::BuiltinType::Long: | ||||||
6055 | case clang::BuiltinType::LongLong: | ||||||
6056 | case clang::BuiltinType::Int128: | ||||||
6057 | case clang::BuiltinType::Float: | ||||||
6058 | case clang::BuiltinType::Double: | ||||||
6059 | case clang::BuiltinType::LongDouble: | ||||||
6060 | case clang::BuiltinType::Dependent: | ||||||
6061 | case clang::BuiltinType::Overload: | ||||||
6062 | case clang::BuiltinType::ObjCId: | ||||||
6063 | case clang::BuiltinType::ObjCClass: | ||||||
6064 | case clang::BuiltinType::ObjCSel: | ||||||
6065 | case clang::BuiltinType::BoundMember: | ||||||
6066 | case clang::BuiltinType::Half: | ||||||
6067 | case clang::BuiltinType::ARCUnbridgedCast: | ||||||
6068 | case clang::BuiltinType::PseudoObject: | ||||||
6069 | case clang::BuiltinType::BuiltinFn: | ||||||
6070 | case clang::BuiltinType::OMPArraySection: | ||||||
6071 | return 1; | ||||||
6072 | default: | ||||||
6073 | return 0; | ||||||
6074 | } | ||||||
6075 | break; | ||||||
6076 | |||||||
6077 | case clang::Type::Complex: | ||||||
6078 | return 1; | ||||||
6079 | case clang::Type::Pointer: | ||||||
6080 | return 1; | ||||||
6081 | case clang::Type::BlockPointer: | ||||||
6082 | return 0; // If block pointers don't have debug info, then no children for | ||||||
6083 | // them | ||||||
6084 | case clang::Type::LValueReference: | ||||||
6085 | return 1; | ||||||
6086 | case clang::Type::RValueReference: | ||||||
6087 | return 1; | ||||||
6088 | case clang::Type::MemberPointer: | ||||||
6089 | return 0; | ||||||
6090 | case clang::Type::ConstantArray: | ||||||
6091 | return 0; | ||||||
6092 | case clang::Type::IncompleteArray: | ||||||
6093 | return 0; | ||||||
6094 | case clang::Type::VariableArray: | ||||||
6095 | return 0; | ||||||
6096 | case clang::Type::DependentSizedArray: | ||||||
6097 | return 0; | ||||||
6098 | case clang::Type::DependentSizedExtVector: | ||||||
6099 | return 0; | ||||||
6100 | case clang::Type::Vector: | ||||||
6101 | return 0; | ||||||
6102 | case clang::Type::ExtVector: | ||||||
6103 | return 0; | ||||||
6104 | case clang::Type::FunctionProto: | ||||||
6105 | return 0; // When we function pointers, they have no children... | ||||||
6106 | case clang::Type::FunctionNoProto: | ||||||
6107 | return 0; // When we function pointers, they have no children... | ||||||
6108 | case clang::Type::UnresolvedUsing: | ||||||
6109 | return 0; | ||||||
6110 | case clang::Type::Record: | ||||||
6111 | return 0; | ||||||
6112 | case clang::Type::Enum: | ||||||
6113 | return 1; | ||||||
6114 | case clang::Type::TemplateTypeParm: | ||||||
6115 | return 1; | ||||||
6116 | case clang::Type::SubstTemplateTypeParm: | ||||||
6117 | return 1; | ||||||
6118 | case clang::Type::TemplateSpecialization: | ||||||
6119 | return 1; | ||||||
6120 | case clang::Type::InjectedClassName: | ||||||
6121 | return 0; | ||||||
6122 | case clang::Type::DependentName: | ||||||
6123 | return 1; | ||||||
6124 | case clang::Type::DependentTemplateSpecialization: | ||||||
6125 | return 1; | ||||||
6126 | case clang::Type::ObjCObject: | ||||||
6127 | return 0; | ||||||
6128 | case clang::Type::ObjCInterface: | ||||||
6129 | return 0; | ||||||
6130 | case clang::Type::ObjCObjectPointer: | ||||||
6131 | return 1; | ||||||
6132 | default: | ||||||
6133 | break; | ||||||
6134 | } | ||||||
6135 | return 0; | ||||||
6136 | } | ||||||
6137 | |||||||
6138 | CompilerType TypeSystemClang::GetChildCompilerTypeAtIndex( | ||||||
6139 | lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, | ||||||
6140 | bool transparent_pointers, bool omit_empty_base_classes, | ||||||
6141 | bool ignore_array_bounds, std::string &child_name, | ||||||
6142 | uint32_t &child_byte_size, int32_t &child_byte_offset, | ||||||
6143 | uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, | ||||||
6144 | bool &child_is_base_class, bool &child_is_deref_of_parent, | ||||||
6145 | ValueObject *valobj, uint64_t &language_flags) { | ||||||
6146 | if (!type) | ||||||
6147 | return CompilerType(); | ||||||
6148 | |||||||
6149 | auto get_exe_scope = [&exe_ctx]() { | ||||||
6150 | return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr; | ||||||
6151 | }; | ||||||
6152 | |||||||
6153 | clang::QualType parent_qual_type( | ||||||
6154 | RemoveWrappingTypes(GetCanonicalQualType(type))); | ||||||
6155 | const clang::Type::TypeClass parent_type_class = | ||||||
6156 | parent_qual_type->getTypeClass(); | ||||||
6157 | child_bitfield_bit_size = 0; | ||||||
6158 | child_bitfield_bit_offset = 0; | ||||||
6159 | child_is_base_class = false; | ||||||
6160 | language_flags = 0; | ||||||
6161 | |||||||
6162 | const bool idx_is_valid = | ||||||
6163 | idx < GetNumChildren(type, omit_empty_base_classes, exe_ctx); | ||||||
6164 | int32_t bit_offset; | ||||||
6165 | switch (parent_type_class) { | ||||||
6166 | case clang::Type::Builtin: | ||||||
6167 | if (idx_is_valid) { | ||||||
6168 | switch (llvm::cast<clang::BuiltinType>(parent_qual_type)->getKind()) { | ||||||
6169 | case clang::BuiltinType::ObjCId: | ||||||
6170 | case clang::BuiltinType::ObjCClass: | ||||||
6171 | child_name = "isa"; | ||||||
6172 | child_byte_size = | ||||||
6173 | getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy) / | ||||||
6174 | CHAR_BIT8; | ||||||
6175 | return GetType(getASTContext().ObjCBuiltinClassTy); | ||||||
6176 | |||||||
6177 | default: | ||||||
6178 | break; | ||||||
6179 | } | ||||||
6180 | } | ||||||
6181 | break; | ||||||
6182 | |||||||
6183 | case clang::Type::Record: | ||||||
6184 | if (idx_is_valid && GetCompleteType(type)) { | ||||||
6185 | const clang::RecordType *record_type = | ||||||
6186 | llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr()); | ||||||
6187 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
6188 | assert(record_decl)(static_cast <bool> (record_decl) ? void (0) : __assert_fail ("record_decl", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 6188, __extension__ __PRETTY_FUNCTION__)); | ||||||
6189 | const clang::ASTRecordLayout &record_layout = | ||||||
6190 | getASTContext().getASTRecordLayout(record_decl); | ||||||
6191 | uint32_t child_idx = 0; | ||||||
6192 | |||||||
6193 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
6194 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); | ||||||
6195 | if (cxx_record_decl) { | ||||||
6196 | // We might have base classes to print out first | ||||||
6197 | clang::CXXRecordDecl::base_class_const_iterator base_class, | ||||||
6198 | base_class_end; | ||||||
6199 | for (base_class = cxx_record_decl->bases_begin(), | ||||||
6200 | base_class_end = cxx_record_decl->bases_end(); | ||||||
6201 | base_class != base_class_end; ++base_class) { | ||||||
6202 | const clang::CXXRecordDecl *base_class_decl = nullptr; | ||||||
6203 | |||||||
6204 | // Skip empty base classes | ||||||
6205 | if (omit_empty_base_classes) { | ||||||
6206 | base_class_decl = llvm::cast<clang::CXXRecordDecl>( | ||||||
6207 | base_class->getType()->getAs<clang::RecordType>()->getDecl()); | ||||||
6208 | if (!TypeSystemClang::RecordHasFields(base_class_decl)) | ||||||
6209 | continue; | ||||||
6210 | } | ||||||
6211 | |||||||
6212 | if (idx == child_idx) { | ||||||
6213 | if (base_class_decl == nullptr) | ||||||
6214 | base_class_decl = llvm::cast<clang::CXXRecordDecl>( | ||||||
6215 | base_class->getType()->getAs<clang::RecordType>()->getDecl()); | ||||||
6216 | |||||||
6217 | if (base_class->isVirtual()) { | ||||||
6218 | bool handled = false; | ||||||
6219 | if (valobj) { | ||||||
6220 | clang::VTableContextBase *vtable_ctx = | ||||||
6221 | getASTContext().getVTableContext(); | ||||||
6222 | if (vtable_ctx) | ||||||
6223 | handled = GetVBaseBitOffset(*vtable_ctx, *valobj, | ||||||
6224 | record_layout, cxx_record_decl, | ||||||
6225 | base_class_decl, bit_offset); | ||||||
6226 | } | ||||||
6227 | if (!handled) | ||||||
6228 | bit_offset = record_layout.getVBaseClassOffset(base_class_decl) | ||||||
6229 | .getQuantity() * | ||||||
6230 | 8; | ||||||
6231 | } else | ||||||
6232 | bit_offset = record_layout.getBaseClassOffset(base_class_decl) | ||||||
6233 | .getQuantity() * | ||||||
6234 | 8; | ||||||
6235 | |||||||
6236 | // Base classes should be a multiple of 8 bits in size | ||||||
6237 | child_byte_offset = bit_offset / 8; | ||||||
6238 | CompilerType base_class_clang_type = GetType(base_class->getType()); | ||||||
6239 | child_name = base_class_clang_type.GetTypeName().AsCString(""); | ||||||
6240 | Optional<uint64_t> size = | ||||||
6241 | base_class_clang_type.GetBitSize(get_exe_scope()); | ||||||
6242 | if (!size) | ||||||
6243 | return {}; | ||||||
6244 | uint64_t base_class_clang_type_bit_size = *size; | ||||||
6245 | |||||||
6246 | // Base classes bit sizes should be a multiple of 8 bits in size | ||||||
6247 | assert(base_class_clang_type_bit_size % 8 == 0)(static_cast <bool> (base_class_clang_type_bit_size % 8 == 0) ? void (0) : __assert_fail ("base_class_clang_type_bit_size % 8 == 0" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 6247, __extension__ __PRETTY_FUNCTION__)); | ||||||
6248 | child_byte_size = base_class_clang_type_bit_size / 8; | ||||||
6249 | child_is_base_class = true; | ||||||
6250 | return base_class_clang_type; | ||||||
6251 | } | ||||||
6252 | // We don't increment the child index in the for loop since we might | ||||||
6253 | // be skipping empty base classes | ||||||
6254 | ++child_idx; | ||||||
6255 | } | ||||||
6256 | } | ||||||
6257 | // Make sure index is in range... | ||||||
6258 | uint32_t field_idx = 0; | ||||||
6259 | clang::RecordDecl::field_iterator field, field_end; | ||||||
6260 | for (field = record_decl->field_begin(), | ||||||
6261 | field_end = record_decl->field_end(); | ||||||
6262 | field != field_end; ++field, ++field_idx, ++child_idx) { | ||||||
6263 | if (idx == child_idx) { | ||||||
6264 | // Print the member type if requested | ||||||
6265 | // Print the member name and equal sign | ||||||
6266 | child_name.assign(field->getNameAsString()); | ||||||
6267 | |||||||
6268 | // Figure out the type byte size (field_type_info.first) and | ||||||
6269 | // alignment (field_type_info.second) from the AST context. | ||||||
6270 | CompilerType field_clang_type = GetType(field->getType()); | ||||||
6271 | assert(field_idx < record_layout.getFieldCount())(static_cast <bool> (field_idx < record_layout.getFieldCount ()) ? void (0) : __assert_fail ("field_idx < record_layout.getFieldCount()" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 6271, __extension__ __PRETTY_FUNCTION__)); | ||||||
6272 | Optional<uint64_t> size = | ||||||
6273 | field_clang_type.GetByteSize(get_exe_scope()); | ||||||
6274 | if (!size) | ||||||
6275 | return {}; | ||||||
6276 | child_byte_size = *size; | ||||||
6277 | const uint32_t child_bit_size = child_byte_size * 8; | ||||||
6278 | |||||||
6279 | // Figure out the field offset within the current struct/union/class | ||||||
6280 | // type | ||||||
6281 | bit_offset = record_layout.getFieldOffset(field_idx); | ||||||
6282 | if (FieldIsBitfield(*field, child_bitfield_bit_size)) { | ||||||
6283 | child_bitfield_bit_offset = bit_offset % child_bit_size; | ||||||
6284 | const uint32_t child_bit_offset = | ||||||
6285 | bit_offset - child_bitfield_bit_offset; | ||||||
6286 | child_byte_offset = child_bit_offset / 8; | ||||||
6287 | } else { | ||||||
6288 | child_byte_offset = bit_offset / 8; | ||||||
6289 | } | ||||||
6290 | |||||||
6291 | return field_clang_type; | ||||||
6292 | } | ||||||
6293 | } | ||||||
6294 | } | ||||||
6295 | break; | ||||||
6296 | |||||||
6297 | case clang::Type::ObjCObject: | ||||||
6298 | case clang::Type::ObjCInterface: | ||||||
6299 | if (idx_is_valid && GetCompleteType(type)) { | ||||||
6300 | const clang::ObjCObjectType *objc_class_type = | ||||||
6301 | llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr()); | ||||||
6302 | assert(objc_class_type)(static_cast <bool> (objc_class_type) ? void (0) : __assert_fail ("objc_class_type", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 6302, __extension__ __PRETTY_FUNCTION__)); | ||||||
6303 | if (objc_class_type) { | ||||||
6304 | uint32_t child_idx = 0; | ||||||
6305 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
6306 | objc_class_type->getInterface(); | ||||||
6307 | |||||||
6308 | if (class_interface_decl) { | ||||||
6309 | |||||||
6310 | const clang::ASTRecordLayout &interface_layout = | ||||||
6311 | getASTContext().getASTObjCInterfaceLayout(class_interface_decl); | ||||||
6312 | clang::ObjCInterfaceDecl *superclass_interface_decl = | ||||||
6313 | class_interface_decl->getSuperClass(); | ||||||
6314 | if (superclass_interface_decl) { | ||||||
6315 | if (omit_empty_base_classes) { | ||||||
6316 | CompilerType base_class_clang_type = | ||||||
6317 | GetType(getASTContext().getObjCInterfaceType( | ||||||
6318 | superclass_interface_decl)); | ||||||
6319 | if (base_class_clang_type.GetNumChildren(omit_empty_base_classes, | ||||||
6320 | exe_ctx) > 0) { | ||||||
6321 | if (idx == 0) { | ||||||
6322 | clang::QualType ivar_qual_type( | ||||||
6323 | getASTContext().getObjCInterfaceType( | ||||||
6324 | superclass_interface_decl)); | ||||||
6325 | |||||||
6326 | child_name.assign( | ||||||
6327 | superclass_interface_decl->getNameAsString()); | ||||||
6328 | |||||||
6329 | clang::TypeInfo ivar_type_info = | ||||||
6330 | getASTContext().getTypeInfo(ivar_qual_type.getTypePtr()); | ||||||
6331 | |||||||
6332 | child_byte_size = ivar_type_info.Width / 8; | ||||||
6333 | child_byte_offset = 0; | ||||||
6334 | child_is_base_class = true; | ||||||
6335 | |||||||
6336 | return GetType(ivar_qual_type); | ||||||
6337 | } | ||||||
6338 | |||||||
6339 | ++child_idx; | ||||||
6340 | } | ||||||
6341 | } else | ||||||
6342 | ++child_idx; | ||||||
6343 | } | ||||||
6344 | |||||||
6345 | const uint32_t superclass_idx = child_idx; | ||||||
6346 | |||||||
6347 | if (idx < (child_idx + class_interface_decl->ivar_size())) { | ||||||
6348 | clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, | ||||||
6349 | ivar_end = class_interface_decl->ivar_end(); | ||||||
6350 | |||||||
6351 | for (ivar_pos = class_interface_decl->ivar_begin(); | ||||||
6352 | ivar_pos != ivar_end; ++ivar_pos) { | ||||||
6353 | if (child_idx == idx) { | ||||||
6354 | clang::ObjCIvarDecl *ivar_decl = *ivar_pos; | ||||||
6355 | |||||||
6356 | clang::QualType ivar_qual_type(ivar_decl->getType()); | ||||||
6357 | |||||||
6358 | child_name.assign(ivar_decl->getNameAsString()); | ||||||
6359 | |||||||
6360 | clang::TypeInfo ivar_type_info = | ||||||
6361 | getASTContext().getTypeInfo(ivar_qual_type.getTypePtr()); | ||||||
6362 | |||||||
6363 | child_byte_size = ivar_type_info.Width / 8; | ||||||
6364 | |||||||
6365 | // Figure out the field offset within the current | ||||||
6366 | // struct/union/class type For ObjC objects, we can't trust the | ||||||
6367 | // bit offset we get from the Clang AST, since that doesn't | ||||||
6368 | // account for the space taken up by unbacked properties, or | ||||||
6369 | // from the changing size of base classes that are newer than | ||||||
6370 | // this class. So if we have a process around that we can ask | ||||||
6371 | // about this object, do so. | ||||||
6372 | child_byte_offset = LLDB_INVALID_IVAR_OFFSET(4294967295U); | ||||||
6373 | Process *process = nullptr; | ||||||
6374 | if (exe_ctx) | ||||||
6375 | process = exe_ctx->GetProcessPtr(); | ||||||
6376 | if (process) { | ||||||
6377 | ObjCLanguageRuntime *objc_runtime = | ||||||
6378 | ObjCLanguageRuntime::Get(*process); | ||||||
6379 | if (objc_runtime != nullptr) { | ||||||
6380 | CompilerType parent_ast_type = GetType(parent_qual_type); | ||||||
6381 | child_byte_offset = objc_runtime->GetByteOffsetForIvar( | ||||||
6382 | parent_ast_type, ivar_decl->getNameAsString().c_str()); | ||||||
6383 | } | ||||||
6384 | } | ||||||
6385 | |||||||
6386 | // Setting this to INT32_MAX to make sure we don't compute it | ||||||
6387 | // twice... | ||||||
6388 | bit_offset = INT32_MAX(2147483647); | ||||||
6389 | |||||||
6390 | if (child_byte_offset == | ||||||
6391 | static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET(4294967295U))) { | ||||||
6392 | bit_offset = interface_layout.getFieldOffset(child_idx - | ||||||
6393 | superclass_idx); | ||||||
6394 | child_byte_offset = bit_offset / 8; | ||||||
6395 | } | ||||||
6396 | |||||||
6397 | // Note, the ObjC Ivar Byte offset is just that, it doesn't | ||||||
6398 | // account for the bit offset of a bitfield within its | ||||||
6399 | // containing object. So regardless of where we get the byte | ||||||
6400 | // offset from, we still need to get the bit offset for | ||||||
6401 | // bitfields from the layout. | ||||||
6402 | |||||||
6403 | if (FieldIsBitfield(ivar_decl, child_bitfield_bit_size)) { | ||||||
6404 | if (bit_offset == INT32_MAX(2147483647)) | ||||||
6405 | bit_offset = interface_layout.getFieldOffset( | ||||||
6406 | child_idx - superclass_idx); | ||||||
6407 | |||||||
6408 | child_bitfield_bit_offset = bit_offset % 8; | ||||||
6409 | } | ||||||
6410 | return GetType(ivar_qual_type); | ||||||
6411 | } | ||||||
6412 | ++child_idx; | ||||||
6413 | } | ||||||
6414 | } | ||||||
6415 | } | ||||||
6416 | } | ||||||
6417 | } | ||||||
6418 | break; | ||||||
6419 | |||||||
6420 | case clang::Type::ObjCObjectPointer: | ||||||
6421 | if (idx_is_valid) { | ||||||
6422 | CompilerType pointee_clang_type(GetPointeeType(type)); | ||||||
6423 | |||||||
6424 | if (transparent_pointers && pointee_clang_type.IsAggregateType()) { | ||||||
6425 | child_is_deref_of_parent = false; | ||||||
6426 | bool tmp_child_is_deref_of_parent = false; | ||||||
6427 | return pointee_clang_type.GetChildCompilerTypeAtIndex( | ||||||
6428 | exe_ctx, idx, transparent_pointers, omit_empty_base_classes, | ||||||
6429 | ignore_array_bounds, child_name, child_byte_size, child_byte_offset, | ||||||
6430 | child_bitfield_bit_size, child_bitfield_bit_offset, | ||||||
6431 | child_is_base_class, tmp_child_is_deref_of_parent, valobj, | ||||||
6432 | language_flags); | ||||||
6433 | } else { | ||||||
6434 | child_is_deref_of_parent = true; | ||||||
6435 | const char *parent_name = | ||||||
6436 | valobj ? valobj->GetName().GetCString() : nullptr; | ||||||
6437 | if (parent_name) { | ||||||
6438 | child_name.assign(1, '*'); | ||||||
6439 | child_name += parent_name; | ||||||
6440 | } | ||||||
6441 | |||||||
6442 | // We have a pointer to an simple type | ||||||
6443 | if (idx == 0 && pointee_clang_type.GetCompleteType()) { | ||||||
6444 | if (Optional<uint64_t> size = | ||||||
6445 | pointee_clang_type.GetByteSize(get_exe_scope())) { | ||||||
6446 | child_byte_size = *size; | ||||||
6447 | child_byte_offset = 0; | ||||||
6448 | return pointee_clang_type; | ||||||
6449 | } | ||||||
6450 | } | ||||||
6451 | } | ||||||
6452 | } | ||||||
6453 | break; | ||||||
6454 | |||||||
6455 | case clang::Type::Vector: | ||||||
6456 | case clang::Type::ExtVector: | ||||||
6457 | if (idx_is_valid) { | ||||||
6458 | const clang::VectorType *array = | ||||||
6459 | llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr()); | ||||||
6460 | if (array) { | ||||||
6461 | CompilerType element_type = GetType(array->getElementType()); | ||||||
6462 | if (element_type.GetCompleteType()) { | ||||||
6463 | char element_name[64]; | ||||||
6464 | ::snprintf(element_name, sizeof(element_name), "[%" PRIu64"l" "u" "]", | ||||||
6465 | static_cast<uint64_t>(idx)); | ||||||
6466 | child_name.assign(element_name); | ||||||
6467 | if (Optional<uint64_t> size = | ||||||
6468 | element_type.GetByteSize(get_exe_scope())) { | ||||||
6469 | child_byte_size = *size; | ||||||
6470 | child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; | ||||||
6471 | return element_type; | ||||||
6472 | } | ||||||
6473 | } | ||||||
6474 | } | ||||||
6475 | } | ||||||
6476 | break; | ||||||
6477 | |||||||
6478 | case clang::Type::ConstantArray: | ||||||
6479 | case clang::Type::IncompleteArray: | ||||||
6480 | if (ignore_array_bounds || idx_is_valid) { | ||||||
6481 | const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe(); | ||||||
6482 | if (array) { | ||||||
6483 | CompilerType element_type = GetType(array->getElementType()); | ||||||
6484 | if (element_type.GetCompleteType()) { | ||||||
6485 | child_name = std::string(llvm::formatv("[{0}]", idx)); | ||||||
6486 | if (Optional<uint64_t> size = | ||||||
6487 | element_type.GetByteSize(get_exe_scope())) { | ||||||
6488 | child_byte_size = *size; | ||||||
6489 | child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; | ||||||
6490 | return element_type; | ||||||
6491 | } | ||||||
6492 | } | ||||||
6493 | } | ||||||
6494 | } | ||||||
6495 | break; | ||||||
6496 | |||||||
6497 | case clang::Type::Pointer: { | ||||||
6498 | CompilerType pointee_clang_type(GetPointeeType(type)); | ||||||
6499 | |||||||
6500 | // Don't dereference "void *" pointers | ||||||
6501 | if (pointee_clang_type.IsVoidType()) | ||||||
6502 | return CompilerType(); | ||||||
6503 | |||||||
6504 | if (transparent_pointers && pointee_clang_type.IsAggregateType()) { | ||||||
6505 | child_is_deref_of_parent = false; | ||||||
6506 | bool tmp_child_is_deref_of_parent = false; | ||||||
6507 | return pointee_clang_type.GetChildCompilerTypeAtIndex( | ||||||
6508 | exe_ctx, idx, transparent_pointers, omit_empty_base_classes, | ||||||
6509 | ignore_array_bounds, child_name, child_byte_size, child_byte_offset, | ||||||
6510 | child_bitfield_bit_size, child_bitfield_bit_offset, | ||||||
6511 | child_is_base_class, tmp_child_is_deref_of_parent, valobj, | ||||||
6512 | language_flags); | ||||||
6513 | } else { | ||||||
6514 | child_is_deref_of_parent = true; | ||||||
6515 | |||||||
6516 | const char *parent_name = | ||||||
6517 | valobj ? valobj->GetName().GetCString() : nullptr; | ||||||
6518 | if (parent_name) { | ||||||
6519 | child_name.assign(1, '*'); | ||||||
6520 | child_name += parent_name; | ||||||
6521 | } | ||||||
6522 | |||||||
6523 | // We have a pointer to an simple type | ||||||
6524 | if (idx == 0) { | ||||||
6525 | if (Optional<uint64_t> size = | ||||||
6526 | pointee_clang_type.GetByteSize(get_exe_scope())) { | ||||||
6527 | child_byte_size = *size; | ||||||
6528 | child_byte_offset = 0; | ||||||
6529 | return pointee_clang_type; | ||||||
6530 | } | ||||||
6531 | } | ||||||
6532 | } | ||||||
6533 | break; | ||||||
6534 | } | ||||||
6535 | |||||||
6536 | case clang::Type::LValueReference: | ||||||
6537 | case clang::Type::RValueReference: | ||||||
6538 | if (idx_is_valid) { | ||||||
6539 | const clang::ReferenceType *reference_type = | ||||||
6540 | llvm::cast<clang::ReferenceType>( | ||||||
6541 | RemoveWrappingTypes(GetQualType(type)).getTypePtr()); | ||||||
6542 | CompilerType pointee_clang_type = | ||||||
6543 | GetType(reference_type->getPointeeType()); | ||||||
6544 | if (transparent_pointers && pointee_clang_type.IsAggregateType()) { | ||||||
6545 | child_is_deref_of_parent = false; | ||||||
6546 | bool tmp_child_is_deref_of_parent = false; | ||||||
6547 | return pointee_clang_type.GetChildCompilerTypeAtIndex( | ||||||
6548 | exe_ctx, idx, transparent_pointers, omit_empty_base_classes, | ||||||
6549 | ignore_array_bounds, child_name, child_byte_size, child_byte_offset, | ||||||
6550 | child_bitfield_bit_size, child_bitfield_bit_offset, | ||||||
6551 | child_is_base_class, tmp_child_is_deref_of_parent, valobj, | ||||||
6552 | language_flags); | ||||||
6553 | } else { | ||||||
6554 | const char *parent_name = | ||||||
6555 | valobj ? valobj->GetName().GetCString() : nullptr; | ||||||
6556 | if (parent_name) { | ||||||
6557 | child_name.assign(1, '&'); | ||||||
6558 | child_name += parent_name; | ||||||
6559 | } | ||||||
6560 | |||||||
6561 | // We have a pointer to an simple type | ||||||
6562 | if (idx == 0) { | ||||||
6563 | if (Optional<uint64_t> size = | ||||||
6564 | pointee_clang_type.GetByteSize(get_exe_scope())) { | ||||||
6565 | child_byte_size = *size; | ||||||
6566 | child_byte_offset = 0; | ||||||
6567 | return pointee_clang_type; | ||||||
6568 | } | ||||||
6569 | } | ||||||
6570 | } | ||||||
6571 | } | ||||||
6572 | break; | ||||||
6573 | |||||||
6574 | default: | ||||||
6575 | break; | ||||||
6576 | } | ||||||
6577 | return CompilerType(); | ||||||
6578 | } | ||||||
6579 | |||||||
6580 | static uint32_t GetIndexForRecordBase(const clang::RecordDecl *record_decl, | ||||||
6581 | const clang::CXXBaseSpecifier *base_spec, | ||||||
6582 | bool omit_empty_base_classes) { | ||||||
6583 | uint32_t child_idx = 0; | ||||||
6584 | |||||||
6585 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
6586 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); | ||||||
6587 | |||||||
6588 | if (cxx_record_decl) { | ||||||
6589 | clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end; | ||||||
6590 | for (base_class = cxx_record_decl->bases_begin(), | ||||||
6591 | base_class_end = cxx_record_decl->bases_end(); | ||||||
6592 | base_class != base_class_end; ++base_class) { | ||||||
6593 | if (omit_empty_base_classes) { | ||||||
6594 | if (BaseSpecifierIsEmpty(base_class)) | ||||||
6595 | continue; | ||||||
6596 | } | ||||||
6597 | |||||||
6598 | if (base_class == base_spec) | ||||||
6599 | return child_idx; | ||||||
6600 | ++child_idx; | ||||||
6601 | } | ||||||
6602 | } | ||||||
6603 | |||||||
6604 | return UINT32_MAX(4294967295U); | ||||||
6605 | } | ||||||
6606 | |||||||
6607 | static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl, | ||||||
6608 | clang::NamedDecl *canonical_decl, | ||||||
6609 | bool omit_empty_base_classes) { | ||||||
6610 | uint32_t child_idx = TypeSystemClang::GetNumBaseClasses( | ||||||
6611 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl), | ||||||
6612 | omit_empty_base_classes); | ||||||
6613 | |||||||
6614 | clang::RecordDecl::field_iterator field, field_end; | ||||||
6615 | for (field = record_decl->field_begin(), field_end = record_decl->field_end(); | ||||||
6616 | field != field_end; ++field, ++child_idx) { | ||||||
6617 | if (field->getCanonicalDecl() == canonical_decl) | ||||||
6618 | return child_idx; | ||||||
6619 | } | ||||||
6620 | |||||||
6621 | return UINT32_MAX(4294967295U); | ||||||
6622 | } | ||||||
6623 | |||||||
6624 | // Look for a child member (doesn't include base classes, but it does include | ||||||
6625 | // their members) in the type hierarchy. Returns an index path into | ||||||
6626 | // "clang_type" on how to reach the appropriate member. | ||||||
6627 | // | ||||||
6628 | // class A | ||||||
6629 | // { | ||||||
6630 | // public: | ||||||
6631 | // int m_a; | ||||||
6632 | // int m_b; | ||||||
6633 | // }; | ||||||
6634 | // | ||||||
6635 | // class B | ||||||
6636 | // { | ||||||
6637 | // }; | ||||||
6638 | // | ||||||
6639 | // class C : | ||||||
6640 | // public B, | ||||||
6641 | // public A | ||||||
6642 | // { | ||||||
6643 | // }; | ||||||
6644 | // | ||||||
6645 | // If we have a clang type that describes "class C", and we wanted to looked | ||||||
6646 | // "m_b" in it: | ||||||
6647 | // | ||||||
6648 | // With omit_empty_base_classes == false we would get an integer array back | ||||||
6649 | // with: { 1, 1 } The first index 1 is the child index for "class A" within | ||||||
6650 | // class C The second index 1 is the child index for "m_b" within class A | ||||||
6651 | // | ||||||
6652 | // With omit_empty_base_classes == true we would get an integer array back | ||||||
6653 | // with: { 0, 1 } The first index 0 is the child index for "class A" within | ||||||
6654 | // class C (since class B doesn't have any members it doesn't count) The second | ||||||
6655 | // index 1 is the child index for "m_b" within class A | ||||||
6656 | |||||||
6657 | size_t TypeSystemClang::GetIndexOfChildMemberWithName( | ||||||
6658 | lldb::opaque_compiler_type_t type, const char *name, | ||||||
6659 | bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) { | ||||||
6660 | if (type && name && name[0]) { | ||||||
| |||||||
6661 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
6662 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
6663 | switch (type_class) { | ||||||
6664 | case clang::Type::Record: | ||||||
6665 | if (GetCompleteType(type)) { | ||||||
6666 | const clang::RecordType *record_type = | ||||||
6667 | llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
6668 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
6669 | |||||||
6670 | assert(record_decl)(static_cast <bool> (record_decl) ? void (0) : __assert_fail ("record_decl", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 6670, __extension__ __PRETTY_FUNCTION__)); | ||||||
6671 | uint32_t child_idx = 0; | ||||||
6672 | |||||||
6673 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
6674 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); | ||||||
6675 | |||||||
6676 | // Try and find a field that matches NAME | ||||||
6677 | clang::RecordDecl::field_iterator field, field_end; | ||||||
6678 | llvm::StringRef name_sref(name); | ||||||
6679 | for (field = record_decl->field_begin(), | ||||||
6680 | field_end = record_decl->field_end(); | ||||||
6681 | field != field_end; ++field, ++child_idx) { | ||||||
6682 | llvm::StringRef field_name = field->getName(); | ||||||
6683 | if (field_name.empty()) { | ||||||
6684 | CompilerType field_type = GetType(field->getType()); | ||||||
6685 | child_indexes.push_back(child_idx); | ||||||
6686 | if (field_type.GetIndexOfChildMemberWithName( | ||||||
6687 | name, omit_empty_base_classes, child_indexes)) | ||||||
6688 | return child_indexes.size(); | ||||||
6689 | child_indexes.pop_back(); | ||||||
6690 | |||||||
6691 | } else if (field_name.equals(name_sref)) { | ||||||
6692 | // We have to add on the number of base classes to this index! | ||||||
6693 | child_indexes.push_back( | ||||||
6694 | child_idx + TypeSystemClang::GetNumBaseClasses( | ||||||
6695 | cxx_record_decl, omit_empty_base_classes)); | ||||||
6696 | return child_indexes.size(); | ||||||
6697 | } | ||||||
6698 | } | ||||||
6699 | |||||||
6700 | if (cxx_record_decl
| ||||||
6701 | const clang::RecordDecl *parent_record_decl = cxx_record_decl; | ||||||
6702 | |||||||
6703 | // Didn't find things easily, lets let clang do its thang... | ||||||
6704 | clang::IdentifierInfo &ident_ref = | ||||||
6705 | getASTContext().Idents.get(name_sref); | ||||||
6706 | clang::DeclarationName decl_name(&ident_ref); | ||||||
6707 | |||||||
6708 | clang::CXXBasePaths paths; | ||||||
6709 | if (cxx_record_decl->lookupInBases( | ||||||
6710 | [decl_name](const clang::CXXBaseSpecifier *specifier, | ||||||
6711 | clang::CXXBasePath &path) { | ||||||
6712 | CXXRecordDecl *record = | ||||||
6713 | specifier->getType()->getAsCXXRecordDecl(); | ||||||
6714 | auto r = record->lookup(decl_name); | ||||||
6715 | path.Decls = r.begin(); | ||||||
6716 | return !r.empty(); | ||||||
6717 | }, | ||||||
6718 | paths)) { | ||||||
6719 | clang::CXXBasePaths::const_paths_iterator path, | ||||||
6720 | path_end = paths.end(); | ||||||
6721 | for (path = paths.begin(); path != path_end; ++path) { | ||||||
6722 | const size_t num_path_elements = path->size(); | ||||||
6723 | for (size_t e = 0; e < num_path_elements; ++e) { | ||||||
6724 | clang::CXXBasePathElement elem = (*path)[e]; | ||||||
6725 | |||||||
6726 | child_idx = GetIndexForRecordBase(parent_record_decl, elem.Base, | ||||||
6727 | omit_empty_base_classes); | ||||||
6728 | if (child_idx
| ||||||
6729 | child_indexes.clear(); | ||||||
6730 | return 0; | ||||||
6731 | } else { | ||||||
6732 | child_indexes.push_back(child_idx); | ||||||
6733 | parent_record_decl = llvm::cast<clang::RecordDecl>( | ||||||
6734 | elem.Base->getType() | ||||||
| |||||||
6735 | ->getAs<clang::RecordType>() | ||||||
6736 | ->getDecl()); | ||||||
6737 | } | ||||||
6738 | } | ||||||
6739 | for (clang::DeclContext::lookup_iterator I = path->Decls, E; | ||||||
6740 | I != E; ++I) { | ||||||
6741 | child_idx = GetIndexForRecordChild( | ||||||
6742 | parent_record_decl, *I, omit_empty_base_classes); | ||||||
6743 | if (child_idx == UINT32_MAX(4294967295U)) { | ||||||
6744 | child_indexes.clear(); | ||||||
6745 | return 0; | ||||||
6746 | } else { | ||||||
6747 | child_indexes.push_back(child_idx); | ||||||
6748 | } | ||||||
6749 | } | ||||||
6750 | } | ||||||
6751 | return child_indexes.size(); | ||||||
6752 | } | ||||||
6753 | } | ||||||
6754 | } | ||||||
6755 | break; | ||||||
6756 | |||||||
6757 | case clang::Type::ObjCObject: | ||||||
6758 | case clang::Type::ObjCInterface: | ||||||
6759 | if (GetCompleteType(type)) { | ||||||
6760 | llvm::StringRef name_sref(name); | ||||||
6761 | const clang::ObjCObjectType *objc_class_type = | ||||||
6762 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); | ||||||
6763 | assert(objc_class_type)(static_cast <bool> (objc_class_type) ? void (0) : __assert_fail ("objc_class_type", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 6763, __extension__ __PRETTY_FUNCTION__)); | ||||||
6764 | if (objc_class_type) { | ||||||
6765 | uint32_t child_idx = 0; | ||||||
6766 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
6767 | objc_class_type->getInterface(); | ||||||
6768 | |||||||
6769 | if (class_interface_decl) { | ||||||
6770 | clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, | ||||||
6771 | ivar_end = class_interface_decl->ivar_end(); | ||||||
6772 | clang::ObjCInterfaceDecl *superclass_interface_decl = | ||||||
6773 | class_interface_decl->getSuperClass(); | ||||||
6774 | |||||||
6775 | for (ivar_pos = class_interface_decl->ivar_begin(); | ||||||
6776 | ivar_pos != ivar_end; ++ivar_pos, ++child_idx) { | ||||||
6777 | const clang::ObjCIvarDecl *ivar_decl = *ivar_pos; | ||||||
6778 | |||||||
6779 | if (ivar_decl->getName().equals(name_sref)) { | ||||||
6780 | if ((!omit_empty_base_classes && superclass_interface_decl) || | ||||||
6781 | (omit_empty_base_classes && | ||||||
6782 | ObjCDeclHasIVars(superclass_interface_decl, true))) | ||||||
6783 | ++child_idx; | ||||||
6784 | |||||||
6785 | child_indexes.push_back(child_idx); | ||||||
6786 | return child_indexes.size(); | ||||||
6787 | } | ||||||
6788 | } | ||||||
6789 | |||||||
6790 | if (superclass_interface_decl) { | ||||||
6791 | // The super class index is always zero for ObjC classes, so we | ||||||
6792 | // push it onto the child indexes in case we find an ivar in our | ||||||
6793 | // superclass... | ||||||
6794 | child_indexes.push_back(0); | ||||||
6795 | |||||||
6796 | CompilerType superclass_clang_type = | ||||||
6797 | GetType(getASTContext().getObjCInterfaceType( | ||||||
6798 | superclass_interface_decl)); | ||||||
6799 | if (superclass_clang_type.GetIndexOfChildMemberWithName( | ||||||
6800 | name, omit_empty_base_classes, child_indexes)) { | ||||||
6801 | // We did find an ivar in a superclass so just return the | ||||||
6802 | // results! | ||||||
6803 | return child_indexes.size(); | ||||||
6804 | } | ||||||
6805 | |||||||
6806 | // We didn't find an ivar matching "name" in our superclass, pop | ||||||
6807 | // the superclass zero index that we pushed on above. | ||||||
6808 | child_indexes.pop_back(); | ||||||
6809 | } | ||||||
6810 | } | ||||||
6811 | } | ||||||
6812 | } | ||||||
6813 | break; | ||||||
6814 | |||||||
6815 | case clang::Type::ObjCObjectPointer: { | ||||||
6816 | CompilerType objc_object_clang_type = GetType( | ||||||
6817 | llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr()) | ||||||
6818 | ->getPointeeType()); | ||||||
6819 | return objc_object_clang_type.GetIndexOfChildMemberWithName( | ||||||
6820 | name, omit_empty_base_classes, child_indexes); | ||||||
6821 | } break; | ||||||
6822 | |||||||
6823 | case clang::Type::ConstantArray: { | ||||||
6824 | // const clang::ConstantArrayType *array = | ||||||
6825 | // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr()); | ||||||
6826 | // const uint64_t element_count = | ||||||
6827 | // array->getSize().getLimitedValue(); | ||||||
6828 | // | ||||||
6829 | // if (idx < element_count) | ||||||
6830 | // { | ||||||
6831 | // std::pair<uint64_t, unsigned> field_type_info = | ||||||
6832 | // ast->getTypeInfo(array->getElementType()); | ||||||
6833 | // | ||||||
6834 | // char element_name[32]; | ||||||
6835 | // ::snprintf (element_name, sizeof (element_name), | ||||||
6836 | // "%s[%u]", parent_name ? parent_name : "", idx); | ||||||
6837 | // | ||||||
6838 | // child_name.assign(element_name); | ||||||
6839 | // assert(field_type_info.first % 8 == 0); | ||||||
6840 | // child_byte_size = field_type_info.first / 8; | ||||||
6841 | // child_byte_offset = idx * child_byte_size; | ||||||
6842 | // return array->getElementType().getAsOpaquePtr(); | ||||||
6843 | // } | ||||||
6844 | } break; | ||||||
6845 | |||||||
6846 | // case clang::Type::MemberPointerType: | ||||||
6847 | // { | ||||||
6848 | // MemberPointerType *mem_ptr_type = | ||||||
6849 | // llvm::cast<MemberPointerType>(qual_type.getTypePtr()); | ||||||
6850 | // clang::QualType pointee_type = | ||||||
6851 | // mem_ptr_type->getPointeeType(); | ||||||
6852 | // | ||||||
6853 | // if (TypeSystemClang::IsAggregateType | ||||||
6854 | // (pointee_type.getAsOpaquePtr())) | ||||||
6855 | // { | ||||||
6856 | // return GetIndexOfChildWithName (ast, | ||||||
6857 | // mem_ptr_type->getPointeeType().getAsOpaquePtr(), | ||||||
6858 | // name); | ||||||
6859 | // } | ||||||
6860 | // } | ||||||
6861 | // break; | ||||||
6862 | // | ||||||
6863 | case clang::Type::LValueReference: | ||||||
6864 | case clang::Type::RValueReference: { | ||||||
6865 | const clang::ReferenceType *reference_type = | ||||||
6866 | llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); | ||||||
6867 | clang::QualType pointee_type(reference_type->getPointeeType()); | ||||||
6868 | CompilerType pointee_clang_type = GetType(pointee_type); | ||||||
6869 | |||||||
6870 | if (pointee_clang_type.IsAggregateType()) { | ||||||
6871 | return pointee_clang_type.GetIndexOfChildMemberWithName( | ||||||
6872 | name, omit_empty_base_classes, child_indexes); | ||||||
6873 | } | ||||||
6874 | } break; | ||||||
6875 | |||||||
6876 | case clang::Type::Pointer: { | ||||||
6877 | CompilerType pointee_clang_type(GetPointeeType(type)); | ||||||
6878 | |||||||
6879 | if (pointee_clang_type.IsAggregateType()) { | ||||||
6880 | return pointee_clang_type.GetIndexOfChildMemberWithName( | ||||||
6881 | name, omit_empty_base_classes, child_indexes); | ||||||
6882 | } | ||||||
6883 | } break; | ||||||
6884 | |||||||
6885 | default: | ||||||
6886 | break; | ||||||
6887 | } | ||||||
6888 | } | ||||||
6889 | return 0; | ||||||
6890 | } | ||||||
6891 | |||||||
6892 | // Get the index of the child of "clang_type" whose name matches. This function | ||||||
6893 | // doesn't descend into the children, but only looks one level deep and name | ||||||
6894 | // matches can include base class names. | ||||||
6895 | |||||||
6896 | uint32_t | ||||||
6897 | TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, | ||||||
6898 | const char *name, | ||||||
6899 | bool omit_empty_base_classes) { | ||||||
6900 | if (type && name && name[0]) { | ||||||
6901 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
6902 | |||||||
6903 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
6904 | |||||||
6905 | switch (type_class) { | ||||||
6906 | case clang::Type::Record: | ||||||
6907 | if (GetCompleteType(type)) { | ||||||
6908 | const clang::RecordType *record_type = | ||||||
6909 | llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
6910 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
6911 | |||||||
6912 | assert(record_decl)(static_cast <bool> (record_decl) ? void (0) : __assert_fail ("record_decl", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 6912, __extension__ __PRETTY_FUNCTION__)); | ||||||
6913 | uint32_t child_idx = 0; | ||||||
6914 | |||||||
6915 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
6916 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); | ||||||
6917 | |||||||
6918 | if (cxx_record_decl) { | ||||||
6919 | clang::CXXRecordDecl::base_class_const_iterator base_class, | ||||||
6920 | base_class_end; | ||||||
6921 | for (base_class = cxx_record_decl->bases_begin(), | ||||||
6922 | base_class_end = cxx_record_decl->bases_end(); | ||||||
6923 | base_class != base_class_end; ++base_class) { | ||||||
6924 | // Skip empty base classes | ||||||
6925 | clang::CXXRecordDecl *base_class_decl = | ||||||
6926 | llvm::cast<clang::CXXRecordDecl>( | ||||||
6927 | base_class->getType() | ||||||
6928 | ->getAs<clang::RecordType>() | ||||||
6929 | ->getDecl()); | ||||||
6930 | if (omit_empty_base_classes && | ||||||
6931 | !TypeSystemClang::RecordHasFields(base_class_decl)) | ||||||
6932 | continue; | ||||||
6933 | |||||||
6934 | CompilerType base_class_clang_type = GetType(base_class->getType()); | ||||||
6935 | std::string base_class_type_name( | ||||||
6936 | base_class_clang_type.GetTypeName().AsCString("")); | ||||||
6937 | if (base_class_type_name == name) | ||||||
6938 | return child_idx; | ||||||
6939 | ++child_idx; | ||||||
6940 | } | ||||||
6941 | } | ||||||
6942 | |||||||
6943 | // Try and find a field that matches NAME | ||||||
6944 | clang::RecordDecl::field_iterator field, field_end; | ||||||
6945 | llvm::StringRef name_sref(name); | ||||||
6946 | for (field = record_decl->field_begin(), | ||||||
6947 | field_end = record_decl->field_end(); | ||||||
6948 | field != field_end; ++field, ++child_idx) { | ||||||
6949 | if (field->getName().equals(name_sref)) | ||||||
6950 | return child_idx; | ||||||
6951 | } | ||||||
6952 | } | ||||||
6953 | break; | ||||||
6954 | |||||||
6955 | case clang::Type::ObjCObject: | ||||||
6956 | case clang::Type::ObjCInterface: | ||||||
6957 | if (GetCompleteType(type)) { | ||||||
6958 | llvm::StringRef name_sref(name); | ||||||
6959 | const clang::ObjCObjectType *objc_class_type = | ||||||
6960 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); | ||||||
6961 | assert(objc_class_type)(static_cast <bool> (objc_class_type) ? void (0) : __assert_fail ("objc_class_type", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 6961, __extension__ __PRETTY_FUNCTION__)); | ||||||
6962 | if (objc_class_type) { | ||||||
6963 | uint32_t child_idx = 0; | ||||||
6964 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
6965 | objc_class_type->getInterface(); | ||||||
6966 | |||||||
6967 | if (class_interface_decl) { | ||||||
6968 | clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, | ||||||
6969 | ivar_end = class_interface_decl->ivar_end(); | ||||||
6970 | clang::ObjCInterfaceDecl *superclass_interface_decl = | ||||||
6971 | class_interface_decl->getSuperClass(); | ||||||
6972 | |||||||
6973 | for (ivar_pos = class_interface_decl->ivar_begin(); | ||||||
6974 | ivar_pos != ivar_end; ++ivar_pos, ++child_idx) { | ||||||
6975 | const clang::ObjCIvarDecl *ivar_decl = *ivar_pos; | ||||||
6976 | |||||||
6977 | if (ivar_decl->getName().equals(name_sref)) { | ||||||
6978 | if ((!omit_empty_base_classes && superclass_interface_decl) || | ||||||
6979 | (omit_empty_base_classes && | ||||||
6980 | ObjCDeclHasIVars(superclass_interface_decl, true))) | ||||||
6981 | ++child_idx; | ||||||
6982 | |||||||
6983 | return child_idx; | ||||||
6984 | } | ||||||
6985 | } | ||||||
6986 | |||||||
6987 | if (superclass_interface_decl) { | ||||||
6988 | if (superclass_interface_decl->getName().equals(name_sref)) | ||||||
6989 | return 0; | ||||||
6990 | } | ||||||
6991 | } | ||||||
6992 | } | ||||||
6993 | } | ||||||
6994 | break; | ||||||
6995 | |||||||
6996 | case clang::Type::ObjCObjectPointer: { | ||||||
6997 | CompilerType pointee_clang_type = GetType( | ||||||
6998 | llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr()) | ||||||
6999 | ->getPointeeType()); | ||||||
7000 | return pointee_clang_type.GetIndexOfChildWithName( | ||||||
7001 | name, omit_empty_base_classes); | ||||||
7002 | } break; | ||||||
7003 | |||||||
7004 | case clang::Type::ConstantArray: { | ||||||
7005 | // const clang::ConstantArrayType *array = | ||||||
7006 | // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr()); | ||||||
7007 | // const uint64_t element_count = | ||||||
7008 | // array->getSize().getLimitedValue(); | ||||||
7009 | // | ||||||
7010 | // if (idx < element_count) | ||||||
7011 | // { | ||||||
7012 | // std::pair<uint64_t, unsigned> field_type_info = | ||||||
7013 | // ast->getTypeInfo(array->getElementType()); | ||||||
7014 | // | ||||||
7015 | // char element_name[32]; | ||||||
7016 | // ::snprintf (element_name, sizeof (element_name), | ||||||
7017 | // "%s[%u]", parent_name ? parent_name : "", idx); | ||||||
7018 | // | ||||||
7019 | // child_name.assign(element_name); | ||||||
7020 | // assert(field_type_info.first % 8 == 0); | ||||||
7021 | // child_byte_size = field_type_info.first / 8; | ||||||
7022 | // child_byte_offset = idx * child_byte_size; | ||||||
7023 | // return array->getElementType().getAsOpaquePtr(); | ||||||
7024 | // } | ||||||
7025 | } break; | ||||||
7026 | |||||||
7027 | // case clang::Type::MemberPointerType: | ||||||
7028 | // { | ||||||
7029 | // MemberPointerType *mem_ptr_type = | ||||||
7030 | // llvm::cast<MemberPointerType>(qual_type.getTypePtr()); | ||||||
7031 | // clang::QualType pointee_type = | ||||||
7032 | // mem_ptr_type->getPointeeType(); | ||||||
7033 | // | ||||||
7034 | // if (TypeSystemClang::IsAggregateType | ||||||
7035 | // (pointee_type.getAsOpaquePtr())) | ||||||
7036 | // { | ||||||
7037 | // return GetIndexOfChildWithName (ast, | ||||||
7038 | // mem_ptr_type->getPointeeType().getAsOpaquePtr(), | ||||||
7039 | // name); | ||||||
7040 | // } | ||||||
7041 | // } | ||||||
7042 | // break; | ||||||
7043 | // | ||||||
7044 | case clang::Type::LValueReference: | ||||||
7045 | case clang::Type::RValueReference: { | ||||||
7046 | const clang::ReferenceType *reference_type = | ||||||
7047 | llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); | ||||||
7048 | CompilerType pointee_type = GetType(reference_type->getPointeeType()); | ||||||
7049 | |||||||
7050 | if (pointee_type.IsAggregateType()) { | ||||||
7051 | return pointee_type.GetIndexOfChildWithName(name, | ||||||
7052 | omit_empty_base_classes); | ||||||
7053 | } | ||||||
7054 | } break; | ||||||
7055 | |||||||
7056 | case clang::Type::Pointer: { | ||||||
7057 | const clang::PointerType *pointer_type = | ||||||
7058 | llvm::cast<clang::PointerType>(qual_type.getTypePtr()); | ||||||
7059 | CompilerType pointee_type = GetType(pointer_type->getPointeeType()); | ||||||
7060 | |||||||
7061 | if (pointee_type.IsAggregateType()) { | ||||||
7062 | return pointee_type.GetIndexOfChildWithName(name, | ||||||
7063 | omit_empty_base_classes); | ||||||
7064 | } else { | ||||||
7065 | // if (parent_name) | ||||||
7066 | // { | ||||||
7067 | // child_name.assign(1, '*'); | ||||||
7068 | // child_name += parent_name; | ||||||
7069 | // } | ||||||
7070 | // | ||||||
7071 | // // We have a pointer to an simple type | ||||||
7072 | // if (idx == 0) | ||||||
7073 | // { | ||||||
7074 | // std::pair<uint64_t, unsigned> clang_type_info | ||||||
7075 | // = ast->getTypeInfo(pointee_type); | ||||||
7076 | // assert(clang_type_info.first % 8 == 0); | ||||||
7077 | // child_byte_size = clang_type_info.first / 8; | ||||||
7078 | // child_byte_offset = 0; | ||||||
7079 | // return pointee_type.getAsOpaquePtr(); | ||||||
7080 | // } | ||||||
7081 | } | ||||||
7082 | } break; | ||||||
7083 | |||||||
7084 | default: | ||||||
7085 | break; | ||||||
7086 | } | ||||||
7087 | } | ||||||
7088 | return UINT32_MAX(4294967295U); | ||||||
7089 | } | ||||||
7090 | |||||||
7091 | size_t | ||||||
7092 | TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { | ||||||
7093 | if (!type) | ||||||
7094 | return 0; | ||||||
7095 | |||||||
7096 | clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); | ||||||
7097 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
7098 | switch (type_class) { | ||||||
7099 | case clang::Type::Record: | ||||||
7100 | if (GetCompleteType(type)) { | ||||||
7101 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
7102 | qual_type->getAsCXXRecordDecl(); | ||||||
7103 | if (cxx_record_decl) { | ||||||
7104 | const clang::ClassTemplateSpecializationDecl *template_decl = | ||||||
7105 | llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>( | ||||||
7106 | cxx_record_decl); | ||||||
7107 | if (template_decl) | ||||||
7108 | return template_decl->getTemplateArgs().size(); | ||||||
7109 | } | ||||||
7110 | } | ||||||
7111 | break; | ||||||
7112 | |||||||
7113 | default: | ||||||
7114 | break; | ||||||
7115 | } | ||||||
7116 | |||||||
7117 | return 0; | ||||||
7118 | } | ||||||
7119 | |||||||
7120 | const clang::ClassTemplateSpecializationDecl * | ||||||
7121 | TypeSystemClang::GetAsTemplateSpecialization( | ||||||
7122 | lldb::opaque_compiler_type_t type) { | ||||||
7123 | if (!type) | ||||||
7124 | return nullptr; | ||||||
7125 | |||||||
7126 | clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); | ||||||
7127 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
7128 | switch (type_class) { | ||||||
7129 | case clang::Type::Record: { | ||||||
7130 | if (! GetCompleteType(type)) | ||||||
7131 | return nullptr; | ||||||
7132 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
7133 | qual_type->getAsCXXRecordDecl(); | ||||||
7134 | if (!cxx_record_decl) | ||||||
7135 | return nullptr; | ||||||
7136 | return llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>( | ||||||
7137 | cxx_record_decl); | ||||||
7138 | } | ||||||
7139 | |||||||
7140 | default: | ||||||
7141 | return nullptr; | ||||||
7142 | } | ||||||
7143 | } | ||||||
7144 | |||||||
7145 | lldb::TemplateArgumentKind | ||||||
7146 | TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, | ||||||
7147 | size_t arg_idx) { | ||||||
7148 | const clang::ClassTemplateSpecializationDecl *template_decl = | ||||||
7149 | GetAsTemplateSpecialization(type); | ||||||
7150 | if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size()) | ||||||
7151 | return eTemplateArgumentKindNull; | ||||||
7152 | |||||||
7153 | switch (template_decl->getTemplateArgs()[arg_idx].getKind()) { | ||||||
7154 | case clang::TemplateArgument::Null: | ||||||
7155 | return eTemplateArgumentKindNull; | ||||||
7156 | |||||||
7157 | case clang::TemplateArgument::NullPtr: | ||||||
7158 | return eTemplateArgumentKindNullPtr; | ||||||
7159 | |||||||
7160 | case clang::TemplateArgument::Type: | ||||||
7161 | return eTemplateArgumentKindType; | ||||||
7162 | |||||||
7163 | case clang::TemplateArgument::Declaration: | ||||||
7164 | return eTemplateArgumentKindDeclaration; | ||||||
7165 | |||||||
7166 | case clang::TemplateArgument::Integral: | ||||||
7167 | return eTemplateArgumentKindIntegral; | ||||||
7168 | |||||||
7169 | case clang::TemplateArgument::Template: | ||||||
7170 | return eTemplateArgumentKindTemplate; | ||||||
7171 | |||||||
7172 | case clang::TemplateArgument::TemplateExpansion: | ||||||
7173 | return eTemplateArgumentKindTemplateExpansion; | ||||||
7174 | |||||||
7175 | case clang::TemplateArgument::Expression: | ||||||
7176 | return eTemplateArgumentKindExpression; | ||||||
7177 | |||||||
7178 | case clang::TemplateArgument::Pack: | ||||||
7179 | return eTemplateArgumentKindPack; | ||||||
7180 | } | ||||||
7181 | llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind")::llvm::llvm_unreachable_internal("Unhandled clang::TemplateArgument::ArgKind" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 7181); | ||||||
7182 | } | ||||||
7183 | |||||||
7184 | CompilerType | ||||||
7185 | TypeSystemClang::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, | ||||||
7186 | size_t idx) { | ||||||
7187 | const clang::ClassTemplateSpecializationDecl *template_decl = | ||||||
7188 | GetAsTemplateSpecialization(type); | ||||||
7189 | if (!template_decl || idx >= template_decl->getTemplateArgs().size()) | ||||||
7190 | return CompilerType(); | ||||||
7191 | |||||||
7192 | const clang::TemplateArgument &template_arg = | ||||||
7193 | template_decl->getTemplateArgs()[idx]; | ||||||
7194 | if (template_arg.getKind() != clang::TemplateArgument::Type) | ||||||
7195 | return CompilerType(); | ||||||
7196 | |||||||
7197 | return GetType(template_arg.getAsType()); | ||||||
7198 | } | ||||||
7199 | |||||||
7200 | Optional<CompilerType::IntegralTemplateArgument> | ||||||
7201 | TypeSystemClang::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, | ||||||
7202 | size_t idx) { | ||||||
7203 | const clang::ClassTemplateSpecializationDecl *template_decl = | ||||||
7204 | GetAsTemplateSpecialization(type); | ||||||
7205 | if (! template_decl || idx >= template_decl->getTemplateArgs().size()) | ||||||
7206 | return llvm::None; | ||||||
7207 | |||||||
7208 | const clang::TemplateArgument &template_arg = | ||||||
7209 | template_decl->getTemplateArgs()[idx]; | ||||||
7210 | if (template_arg.getKind() != clang::TemplateArgument::Integral) | ||||||
7211 | return llvm::None; | ||||||
7212 | |||||||
7213 | return { | ||||||
7214 | {template_arg.getAsIntegral(), GetType(template_arg.getIntegralType())}}; | ||||||
7215 | } | ||||||
7216 | |||||||
7217 | CompilerType TypeSystemClang::GetTypeForFormatters(void *type) { | ||||||
7218 | if (type) | ||||||
7219 | return ClangUtil::RemoveFastQualifiers(CompilerType(this, type)); | ||||||
7220 | return CompilerType(); | ||||||
7221 | } | ||||||
7222 | |||||||
7223 | clang::EnumDecl *TypeSystemClang::GetAsEnumDecl(const CompilerType &type) { | ||||||
7224 | const clang::EnumType *enutype = | ||||||
7225 | llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type)); | ||||||
7226 | if (enutype) | ||||||
7227 | return enutype->getDecl(); | ||||||
7228 | return nullptr; | ||||||
7229 | } | ||||||
7230 | |||||||
7231 | clang::RecordDecl *TypeSystemClang::GetAsRecordDecl(const CompilerType &type) { | ||||||
7232 | const clang::RecordType *record_type = | ||||||
7233 | llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type)); | ||||||
7234 | if (record_type) | ||||||
7235 | return record_type->getDecl(); | ||||||
7236 | return nullptr; | ||||||
7237 | } | ||||||
7238 | |||||||
7239 | clang::TagDecl *TypeSystemClang::GetAsTagDecl(const CompilerType &type) { | ||||||
7240 | return ClangUtil::GetAsTagDecl(type); | ||||||
7241 | } | ||||||
7242 | |||||||
7243 | clang::TypedefNameDecl * | ||||||
7244 | TypeSystemClang::GetAsTypedefDecl(const CompilerType &type) { | ||||||
7245 | const clang::TypedefType *typedef_type = | ||||||
7246 | llvm::dyn_cast<clang::TypedefType>(ClangUtil::GetQualType(type)); | ||||||
7247 | if (typedef_type) | ||||||
7248 | return typedef_type->getDecl(); | ||||||
7249 | return nullptr; | ||||||
7250 | } | ||||||
7251 | |||||||
7252 | clang::CXXRecordDecl * | ||||||
7253 | TypeSystemClang::GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type) { | ||||||
7254 | return GetCanonicalQualType(type)->getAsCXXRecordDecl(); | ||||||
7255 | } | ||||||
7256 | |||||||
7257 | clang::ObjCInterfaceDecl * | ||||||
7258 | TypeSystemClang::GetAsObjCInterfaceDecl(const CompilerType &type) { | ||||||
7259 | const clang::ObjCObjectType *objc_class_type = | ||||||
7260 | llvm::dyn_cast<clang::ObjCObjectType>( | ||||||
7261 | ClangUtil::GetCanonicalQualType(type)); | ||||||
7262 | if (objc_class_type) | ||||||
7263 | return objc_class_type->getInterface(); | ||||||
7264 | return nullptr; | ||||||
7265 | } | ||||||
7266 | |||||||
7267 | clang::FieldDecl *TypeSystemClang::AddFieldToRecordType( | ||||||
7268 | const CompilerType &type, llvm::StringRef name, | ||||||
7269 | const CompilerType &field_clang_type, AccessType access, | ||||||
7270 | uint32_t bitfield_bit_size) { | ||||||
7271 | if (!type.IsValid() || !field_clang_type.IsValid()) | ||||||
7272 | return nullptr; | ||||||
7273 | TypeSystemClang *ast = | ||||||
7274 | llvm::dyn_cast_or_null<TypeSystemClang>(type.GetTypeSystem()); | ||||||
7275 | if (!ast) | ||||||
7276 | return nullptr; | ||||||
7277 | clang::ASTContext &clang_ast = ast->getASTContext(); | ||||||
7278 | clang::IdentifierInfo *ident = nullptr; | ||||||
7279 | if (!name.empty()) | ||||||
7280 | ident = &clang_ast.Idents.get(name); | ||||||
7281 | |||||||
7282 | clang::FieldDecl *field = nullptr; | ||||||
7283 | |||||||
7284 | clang::Expr *bit_width = nullptr; | ||||||
7285 | if (bitfield_bit_size != 0) { | ||||||
7286 | llvm::APInt bitfield_bit_size_apint(clang_ast.getTypeSize(clang_ast.IntTy), | ||||||
7287 | bitfield_bit_size); | ||||||
7288 | bit_width = new (clang_ast) | ||||||
7289 | clang::IntegerLiteral(clang_ast, bitfield_bit_size_apint, | ||||||
7290 | clang_ast.IntTy, clang::SourceLocation()); | ||||||
7291 | } | ||||||
7292 | |||||||
7293 | clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type); | ||||||
7294 | if (record_decl) { | ||||||
7295 | field = clang::FieldDecl::CreateDeserialized(clang_ast, 0); | ||||||
7296 | field->setDeclContext(record_decl); | ||||||
7297 | field->setDeclName(ident); | ||||||
7298 | field->setType(ClangUtil::GetQualType(field_clang_type)); | ||||||
7299 | if (bit_width) | ||||||
7300 | field->setBitWidth(bit_width); | ||||||
7301 | SetMemberOwningModule(field, record_decl); | ||||||
7302 | |||||||
7303 | if (name.empty()) { | ||||||
7304 | // Determine whether this field corresponds to an anonymous struct or | ||||||
7305 | // union. | ||||||
7306 | if (const clang::TagType *TagT = | ||||||
7307 | field->getType()->getAs<clang::TagType>()) { | ||||||
7308 | if (clang::RecordDecl *Rec = | ||||||
7309 | llvm::dyn_cast<clang::RecordDecl>(TagT->getDecl())) | ||||||
7310 | if (!Rec->getDeclName()) { | ||||||
7311 | Rec->setAnonymousStructOrUnion(true); | ||||||
7312 | field->setImplicit(); | ||||||
7313 | } | ||||||
7314 | } | ||||||
7315 | } | ||||||
7316 | |||||||
7317 | if (field) { | ||||||
7318 | clang::AccessSpecifier access_specifier = | ||||||
7319 | TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access); | ||||||
7320 | field->setAccess(access_specifier); | ||||||
7321 | |||||||
7322 | if (clang::CXXRecordDecl *cxx_record_decl = | ||||||
7323 | llvm::dyn_cast<CXXRecordDecl>(record_decl)) { | ||||||
7324 | AddAccessSpecifierDecl(cxx_record_decl, ast->getASTContext(), | ||||||
7325 | ast->GetCXXRecordDeclAccess(cxx_record_decl), | ||||||
7326 | access_specifier); | ||||||
7327 | ast->SetCXXRecordDeclAccess(cxx_record_decl, access_specifier); | ||||||
7328 | } | ||||||
7329 | record_decl->addDecl(field); | ||||||
7330 | |||||||
7331 | VerifyDecl(field); | ||||||
7332 | } | ||||||
7333 | } else { | ||||||
7334 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
7335 | ast->GetAsObjCInterfaceDecl(type); | ||||||
7336 | |||||||
7337 | if (class_interface_decl) { | ||||||
7338 | const bool is_synthesized = false; | ||||||
7339 | |||||||
7340 | field_clang_type.GetCompleteType(); | ||||||
7341 | |||||||
7342 | auto *ivar = clang::ObjCIvarDecl::CreateDeserialized(clang_ast, 0); | ||||||
7343 | ivar->setDeclContext(class_interface_decl); | ||||||
7344 | ivar->setDeclName(ident); | ||||||
7345 | ivar->setType(ClangUtil::GetQualType(field_clang_type)); | ||||||
7346 | ivar->setAccessControl(ConvertAccessTypeToObjCIvarAccessControl(access)); | ||||||
7347 | if (bit_width) | ||||||
7348 | ivar->setBitWidth(bit_width); | ||||||
7349 | ivar->setSynthesize(is_synthesized); | ||||||
7350 | field = ivar; | ||||||
7351 | SetMemberOwningModule(field, class_interface_decl); | ||||||
7352 | |||||||
7353 | if (field) { | ||||||
7354 | class_interface_decl->addDecl(field); | ||||||
7355 | |||||||
7356 | VerifyDecl(field); | ||||||
7357 | } | ||||||
7358 | } | ||||||
7359 | } | ||||||
7360 | return field; | ||||||
7361 | } | ||||||
7362 | |||||||
7363 | void TypeSystemClang::BuildIndirectFields(const CompilerType &type) { | ||||||
7364 | if (!type) | ||||||
7365 | return; | ||||||
7366 | |||||||
7367 | TypeSystemClang *ast = llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem()); | ||||||
7368 | if (!ast) | ||||||
7369 | return; | ||||||
7370 | |||||||
7371 | clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type); | ||||||
7372 | |||||||
7373 | if (!record_decl) | ||||||
7374 | return; | ||||||
7375 | |||||||
7376 | typedef llvm::SmallVector<clang::IndirectFieldDecl *, 1> IndirectFieldVector; | ||||||
7377 | |||||||
7378 | IndirectFieldVector indirect_fields; | ||||||
7379 | clang::RecordDecl::field_iterator field_pos; | ||||||
7380 | clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end(); | ||||||
7381 | clang::RecordDecl::field_iterator last_field_pos = field_end_pos; | ||||||
7382 | for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; | ||||||
7383 | last_field_pos = field_pos++) { | ||||||
7384 | if (field_pos->isAnonymousStructOrUnion()) { | ||||||
7385 | clang::QualType field_qual_type = field_pos->getType(); | ||||||
7386 | |||||||
7387 | const clang::RecordType *field_record_type = | ||||||
7388 | field_qual_type->getAs<clang::RecordType>(); | ||||||
7389 | |||||||
7390 | if (!field_record_type) | ||||||
7391 | continue; | ||||||
7392 | |||||||
7393 | clang::RecordDecl *field_record_decl = field_record_type->getDecl(); | ||||||
7394 | |||||||
7395 | if (!field_record_decl) | ||||||
7396 | continue; | ||||||
7397 | |||||||
7398 | for (clang::RecordDecl::decl_iterator | ||||||
7399 | di = field_record_decl->decls_begin(), | ||||||
7400 | de = field_record_decl->decls_end(); | ||||||
7401 | di != de; ++di) { | ||||||
7402 | if (clang::FieldDecl *nested_field_decl = | ||||||
7403 | llvm::dyn_cast<clang::FieldDecl>(*di)) { | ||||||
7404 | clang::NamedDecl **chain = | ||||||
7405 | new (ast->getASTContext()) clang::NamedDecl *[2]; | ||||||
7406 | chain[0] = *field_pos; | ||||||
7407 | chain[1] = nested_field_decl; | ||||||
7408 | clang::IndirectFieldDecl *indirect_field = | ||||||
7409 | clang::IndirectFieldDecl::Create( | ||||||
7410 | ast->getASTContext(), record_decl, clang::SourceLocation(), | ||||||
7411 | nested_field_decl->getIdentifier(), | ||||||
7412 | nested_field_decl->getType(), {chain, 2}); | ||||||
7413 | SetMemberOwningModule(indirect_field, record_decl); | ||||||
7414 | |||||||
7415 | indirect_field->setImplicit(); | ||||||
7416 | |||||||
7417 | indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers( | ||||||
7418 | field_pos->getAccess(), nested_field_decl->getAccess())); | ||||||
7419 | |||||||
7420 | indirect_fields.push_back(indirect_field); | ||||||
7421 | } else if (clang::IndirectFieldDecl *nested_indirect_field_decl = | ||||||
7422 | llvm::dyn_cast<clang::IndirectFieldDecl>(*di)) { | ||||||
7423 | size_t nested_chain_size = | ||||||
7424 | nested_indirect_field_decl->getChainingSize(); | ||||||
7425 | clang::NamedDecl **chain = new (ast->getASTContext()) | ||||||
7426 | clang::NamedDecl *[nested_chain_size + 1]; | ||||||
7427 | chain[0] = *field_pos; | ||||||
7428 | |||||||
7429 | int chain_index = 1; | ||||||
7430 | for (clang::IndirectFieldDecl::chain_iterator | ||||||
7431 | nci = nested_indirect_field_decl->chain_begin(), | ||||||
7432 | nce = nested_indirect_field_decl->chain_end(); | ||||||
7433 | nci < nce; ++nci) { | ||||||
7434 | chain[chain_index] = *nci; | ||||||
7435 | chain_index++; | ||||||
7436 | } | ||||||
7437 | |||||||
7438 | clang::IndirectFieldDecl *indirect_field = | ||||||
7439 | clang::IndirectFieldDecl::Create( | ||||||
7440 | ast->getASTContext(), record_decl, clang::SourceLocation(), | ||||||
7441 | nested_indirect_field_decl->getIdentifier(), | ||||||
7442 | nested_indirect_field_decl->getType(), | ||||||
7443 | {chain, nested_chain_size + 1}); | ||||||
7444 | SetMemberOwningModule(indirect_field, record_decl); | ||||||
7445 | |||||||
7446 | indirect_field->setImplicit(); | ||||||
7447 | |||||||
7448 | indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers( | ||||||
7449 | field_pos->getAccess(), nested_indirect_field_decl->getAccess())); | ||||||
7450 | |||||||
7451 | indirect_fields.push_back(indirect_field); | ||||||
7452 | } | ||||||
7453 | } | ||||||
7454 | } | ||||||
7455 | } | ||||||
7456 | |||||||
7457 | // Check the last field to see if it has an incomplete array type as its last | ||||||
7458 | // member and if it does, the tell the record decl about it | ||||||
7459 | if (last_field_pos != field_end_pos) { | ||||||
7460 | if (last_field_pos->getType()->isIncompleteArrayType()) | ||||||
7461 | record_decl->hasFlexibleArrayMember(); | ||||||
7462 | } | ||||||
7463 | |||||||
7464 | for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), | ||||||
7465 | ife = indirect_fields.end(); | ||||||
7466 | ifi < ife; ++ifi) { | ||||||
7467 | record_decl->addDecl(*ifi); | ||||||
7468 | } | ||||||
7469 | } | ||||||
7470 | |||||||
7471 | void TypeSystemClang::SetIsPacked(const CompilerType &type) { | ||||||
7472 | if (type) { | ||||||
7473 | TypeSystemClang *ast = | ||||||
7474 | llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem()); | ||||||
7475 | if (ast) { | ||||||
7476 | clang::RecordDecl *record_decl = GetAsRecordDecl(type); | ||||||
7477 | |||||||
7478 | if (!record_decl) | ||||||
7479 | return; | ||||||
7480 | |||||||
7481 | record_decl->addAttr( | ||||||
7482 | clang::PackedAttr::CreateImplicit(ast->getASTContext())); | ||||||
7483 | } | ||||||
7484 | } | ||||||
7485 | } | ||||||
7486 | |||||||
7487 | clang::VarDecl *TypeSystemClang::AddVariableToRecordType( | ||||||
7488 | const CompilerType &type, llvm::StringRef name, | ||||||
7489 | const CompilerType &var_type, AccessType access) { | ||||||
7490 | if (!type.IsValid() || !var_type.IsValid()) | ||||||
7491 | return nullptr; | ||||||
7492 | |||||||
7493 | TypeSystemClang *ast = llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem()); | ||||||
7494 | if (!ast) | ||||||
7495 | return nullptr; | ||||||
7496 | |||||||
7497 | clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type); | ||||||
7498 | if (!record_decl) | ||||||
7499 | return nullptr; | ||||||
7500 | |||||||
7501 | clang::VarDecl *var_decl = nullptr; | ||||||
7502 | clang::IdentifierInfo *ident = nullptr; | ||||||
7503 | if (!name.empty()) | ||||||
7504 | ident = &ast->getASTContext().Idents.get(name); | ||||||
7505 | |||||||
7506 | var_decl = clang::VarDecl::CreateDeserialized(ast->getASTContext(), 0); | ||||||
7507 | var_decl->setDeclContext(record_decl); | ||||||
7508 | var_decl->setDeclName(ident); | ||||||
7509 | var_decl->setType(ClangUtil::GetQualType(var_type)); | ||||||
7510 | var_decl->setStorageClass(clang::SC_Static); | ||||||
7511 | SetMemberOwningModule(var_decl, record_decl); | ||||||
7512 | if (!var_decl) | ||||||
7513 | return nullptr; | ||||||
7514 | |||||||
7515 | var_decl->setAccess( | ||||||
7516 | TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access)); | ||||||
7517 | record_decl->addDecl(var_decl); | ||||||
7518 | |||||||
7519 | VerifyDecl(var_decl); | ||||||
7520 | |||||||
7521 | return var_decl; | ||||||
7522 | } | ||||||
7523 | |||||||
7524 | void TypeSystemClang::SetIntegerInitializerForVariable( | ||||||
7525 | VarDecl *var, const llvm::APInt &init_value) { | ||||||
7526 | assert(!var->hasInit() && "variable already initialized")(static_cast <bool> (!var->hasInit() && "variable already initialized" ) ? void (0) : __assert_fail ("!var->hasInit() && \"variable already initialized\"" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 7526, __extension__ __PRETTY_FUNCTION__)); | ||||||
7527 | |||||||
7528 | clang::ASTContext &ast = var->getASTContext(); | ||||||
7529 | QualType qt = var->getType(); | ||||||
7530 | assert(qt->isIntegralOrEnumerationType() &&(static_cast <bool> (qt->isIntegralOrEnumerationType () && "only integer or enum types supported") ? void ( 0) : __assert_fail ("qt->isIntegralOrEnumerationType() && \"only integer or enum types supported\"" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 7531, __extension__ __PRETTY_FUNCTION__)) | ||||||
7531 | "only integer or enum types supported")(static_cast <bool> (qt->isIntegralOrEnumerationType () && "only integer or enum types supported") ? void ( 0) : __assert_fail ("qt->isIntegralOrEnumerationType() && \"only integer or enum types supported\"" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 7531, __extension__ __PRETTY_FUNCTION__)); | ||||||
7532 | // If the variable is an enum type, take the underlying integer type as | ||||||
7533 | // the type of the integer literal. | ||||||
7534 | if (const EnumType *enum_type = llvm::dyn_cast<EnumType>(qt.getTypePtr())) { | ||||||
7535 | const EnumDecl *enum_decl = enum_type->getDecl(); | ||||||
7536 | qt = enum_decl->getIntegerType(); | ||||||
7537 | } | ||||||
7538 | var->setInit(IntegerLiteral::Create(ast, init_value, qt.getUnqualifiedType(), | ||||||
7539 | SourceLocation())); | ||||||
7540 | } | ||||||
7541 | |||||||
7542 | void TypeSystemClang::SetFloatingInitializerForVariable( | ||||||
7543 | clang::VarDecl *var, const llvm::APFloat &init_value) { | ||||||
7544 | assert(!var->hasInit() && "variable already initialized")(static_cast <bool> (!var->hasInit() && "variable already initialized" ) ? void (0) : __assert_fail ("!var->hasInit() && \"variable already initialized\"" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 7544, __extension__ __PRETTY_FUNCTION__)); | ||||||
7545 | |||||||
7546 | clang::ASTContext &ast = var->getASTContext(); | ||||||
7547 | QualType qt = var->getType(); | ||||||
7548 | assert(qt->isFloatingType() && "only floating point types supported")(static_cast <bool> (qt->isFloatingType() && "only floating point types supported") ? void (0) : __assert_fail ("qt->isFloatingType() && \"only floating point types supported\"" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 7548, __extension__ __PRETTY_FUNCTION__)); | ||||||
7549 | var->setInit(FloatingLiteral::Create( | ||||||
7550 | ast, init_value, true, qt.getUnqualifiedType(), SourceLocation())); | ||||||
7551 | } | ||||||
7552 | |||||||
7553 | clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType( | ||||||
7554 | lldb::opaque_compiler_type_t type, llvm::StringRef name, | ||||||
7555 | const char *mangled_name, const CompilerType &method_clang_type, | ||||||
7556 | lldb::AccessType access, bool is_virtual, bool is_static, bool is_inline, | ||||||
7557 | bool is_explicit, bool is_attr_used, bool is_artificial) { | ||||||
7558 | if (!type || !method_clang_type.IsValid() || name.empty()) | ||||||
7559 | return nullptr; | ||||||
7560 | |||||||
7561 | clang::QualType record_qual_type(GetCanonicalQualType(type)); | ||||||
7562 | |||||||
7563 | clang::CXXRecordDecl *cxx_record_decl = | ||||||
7564 | record_qual_type->getAsCXXRecordDecl(); | ||||||
7565 | |||||||
7566 | if (cxx_record_decl == nullptr) | ||||||
7567 | return nullptr; | ||||||
7568 | |||||||
7569 | clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type)); | ||||||
7570 | |||||||
7571 | clang::CXXMethodDecl *cxx_method_decl = nullptr; | ||||||
7572 | |||||||
7573 | clang::DeclarationName decl_name(&getASTContext().Idents.get(name)); | ||||||
7574 | |||||||
7575 | const clang::FunctionType *function_type = | ||||||
7576 | llvm::dyn_cast<clang::FunctionType>(method_qual_type.getTypePtr()); | ||||||
7577 | |||||||
7578 | if (function_type == nullptr) | ||||||
7579 | return nullptr; | ||||||
7580 | |||||||
7581 | const clang::FunctionProtoType *method_function_prototype( | ||||||
7582 | llvm::dyn_cast<clang::FunctionProtoType>(function_type)); | ||||||
7583 | |||||||
7584 | if (!method_function_prototype) | ||||||
7585 | return nullptr; | ||||||
7586 | |||||||
7587 | unsigned int num_params = method_function_prototype->getNumParams(); | ||||||
7588 | |||||||
7589 | clang::CXXDestructorDecl *cxx_dtor_decl(nullptr); | ||||||
7590 | clang::CXXConstructorDecl *cxx_ctor_decl(nullptr); | ||||||
7591 | |||||||
7592 | if (is_artificial) | ||||||
7593 | return nullptr; // skip everything artificial | ||||||
7594 | |||||||
7595 | const clang::ExplicitSpecifier explicit_spec( | ||||||
7596 | nullptr /*expr*/, is_explicit ? clang::ExplicitSpecKind::ResolvedTrue | ||||||
7597 | : clang::ExplicitSpecKind::ResolvedFalse); | ||||||
7598 | |||||||
7599 | if (name.startswith("~")) { | ||||||
7600 | cxx_dtor_decl = | ||||||
7601 | clang::CXXDestructorDecl::CreateDeserialized(getASTContext(), 0); | ||||||
7602 | cxx_dtor_decl->setDeclContext(cxx_record_decl); | ||||||
7603 | cxx_dtor_decl->setDeclName( | ||||||
7604 | getASTContext().DeclarationNames.getCXXDestructorName( | ||||||
7605 | getASTContext().getCanonicalType(record_qual_type))); | ||||||
7606 | cxx_dtor_decl->setType(method_qual_type); | ||||||
7607 | cxx_dtor_decl->setImplicit(is_artificial); | ||||||
7608 | cxx_dtor_decl->setInlineSpecified(is_inline); | ||||||
7609 | cxx_dtor_decl->setConstexprKind(ConstexprSpecKind::Unspecified); | ||||||
7610 | cxx_method_decl = cxx_dtor_decl; | ||||||
7611 | } else if (decl_name == cxx_record_decl->getDeclName()) { | ||||||
7612 | cxx_ctor_decl = clang::CXXConstructorDecl::CreateDeserialized( | ||||||
7613 | getASTContext(), 0, 0); | ||||||
7614 | cxx_ctor_decl->setDeclContext(cxx_record_decl); | ||||||
7615 | cxx_ctor_decl->setDeclName( | ||||||
7616 | getASTContext().DeclarationNames.getCXXConstructorName( | ||||||
7617 | getASTContext().getCanonicalType(record_qual_type))); | ||||||
7618 | cxx_ctor_decl->setType(method_qual_type); | ||||||
7619 | cxx_ctor_decl->setImplicit(is_artificial); | ||||||
7620 | cxx_ctor_decl->setInlineSpecified(is_inline); | ||||||
7621 | cxx_ctor_decl->setConstexprKind(ConstexprSpecKind::Unspecified); | ||||||
7622 | cxx_ctor_decl->setNumCtorInitializers(0); | ||||||
7623 | cxx_ctor_decl->setExplicitSpecifier(explicit_spec); | ||||||
7624 | cxx_method_decl = cxx_ctor_decl; | ||||||
7625 | } else { | ||||||
7626 | clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None; | ||||||
7627 | clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS; | ||||||
7628 | |||||||
7629 | if (IsOperator(name, op_kind)) { | ||||||
7630 | if (op_kind != clang::NUM_OVERLOADED_OPERATORS) { | ||||||
7631 | // Check the number of operator parameters. Sometimes we have seen bad | ||||||
7632 | // DWARF that doesn't correctly describe operators and if we try to | ||||||
7633 | // create a method and add it to the class, clang will assert and | ||||||
7634 | // crash, so we need to make sure things are acceptable. | ||||||
7635 | const bool is_method = true; | ||||||
7636 | if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount( | ||||||
7637 | is_method, op_kind, num_params)) | ||||||
7638 | return nullptr; | ||||||
7639 | cxx_method_decl = | ||||||
7640 | clang::CXXMethodDecl::CreateDeserialized(getASTContext(), 0); | ||||||
7641 | cxx_method_decl->setDeclContext(cxx_record_decl); | ||||||
7642 | cxx_method_decl->setDeclName( | ||||||
7643 | getASTContext().DeclarationNames.getCXXOperatorName(op_kind)); | ||||||
7644 | cxx_method_decl->setType(method_qual_type); | ||||||
7645 | cxx_method_decl->setStorageClass(SC); | ||||||
7646 | cxx_method_decl->setInlineSpecified(is_inline); | ||||||
7647 | cxx_method_decl->setConstexprKind(ConstexprSpecKind::Unspecified); | ||||||
7648 | } else if (num_params == 0) { | ||||||
7649 | // Conversion operators don't take params... | ||||||
7650 | auto *cxx_conversion_decl = | ||||||
7651 | clang::CXXConversionDecl::CreateDeserialized(getASTContext(), 0); | ||||||
7652 | cxx_conversion_decl->setDeclContext(cxx_record_decl); | ||||||
7653 | cxx_conversion_decl->setDeclName( | ||||||
7654 | getASTContext().DeclarationNames.getCXXConversionFunctionName( | ||||||
7655 | getASTContext().getCanonicalType( | ||||||
7656 | function_type->getReturnType()))); | ||||||
7657 | cxx_conversion_decl->setType(method_qual_type); | ||||||
7658 | cxx_conversion_decl->setInlineSpecified(is_inline); | ||||||
7659 | cxx_conversion_decl->setExplicitSpecifier(explicit_spec); | ||||||
7660 | cxx_conversion_decl->setConstexprKind(ConstexprSpecKind::Unspecified); | ||||||
7661 | cxx_method_decl = cxx_conversion_decl; | ||||||
7662 | } | ||||||
7663 | } | ||||||
7664 | |||||||
7665 | if (cxx_method_decl == nullptr) { | ||||||
7666 | cxx_method_decl = | ||||||
7667 | clang::CXXMethodDecl::CreateDeserialized(getASTContext(), 0); | ||||||
7668 | cxx_method_decl->setDeclContext(cxx_record_decl); | ||||||
7669 | cxx_method_decl->setDeclName(decl_name); | ||||||
7670 | cxx_method_decl->setType(method_qual_type); | ||||||
7671 | cxx_method_decl->setInlineSpecified(is_inline); | ||||||
7672 | cxx_method_decl->setStorageClass(SC); | ||||||
7673 | cxx_method_decl->setConstexprKind(ConstexprSpecKind::Unspecified); | ||||||
7674 | } | ||||||
7675 | } | ||||||
7676 | SetMemberOwningModule(cxx_method_decl, cxx_record_decl); | ||||||
7677 | |||||||
7678 | clang::AccessSpecifier access_specifier = | ||||||
7679 | TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access); | ||||||
7680 | |||||||
7681 | cxx_method_decl->setAccess(access_specifier); | ||||||
7682 | cxx_method_decl->setVirtualAsWritten(is_virtual); | ||||||
7683 | |||||||
7684 | if (is_attr_used) | ||||||
7685 | cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(getASTContext())); | ||||||
7686 | |||||||
7687 | if (mangled_name != nullptr) { | ||||||
7688 | cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit( | ||||||
7689 | getASTContext(), mangled_name, /*literal=*/false)); | ||||||
7690 | } | ||||||
7691 | |||||||
7692 | // Populate the method decl with parameter decls | ||||||
7693 | |||||||
7694 | llvm::SmallVector<clang::ParmVarDecl *, 12> params; | ||||||
7695 | |||||||
7696 | for (unsigned param_index = 0; param_index < num_params; ++param_index) { | ||||||
7697 | params.push_back(clang::ParmVarDecl::Create( | ||||||
7698 | getASTContext(), cxx_method_decl, clang::SourceLocation(), | ||||||
7699 | clang::SourceLocation(), | ||||||
7700 | nullptr, // anonymous | ||||||
7701 | method_function_prototype->getParamType(param_index), nullptr, | ||||||
7702 | clang::SC_None, nullptr)); | ||||||
7703 | } | ||||||
7704 | |||||||
7705 | cxx_method_decl->setParams(llvm::ArrayRef<clang::ParmVarDecl *>(params)); | ||||||
7706 | |||||||
7707 | AddAccessSpecifierDecl(cxx_record_decl, getASTContext(), | ||||||
7708 | GetCXXRecordDeclAccess(cxx_record_decl), | ||||||
7709 | access_specifier); | ||||||
7710 | SetCXXRecordDeclAccess(cxx_record_decl, access_specifier); | ||||||
7711 | |||||||
7712 | cxx_record_decl->addDecl(cxx_method_decl); | ||||||
7713 | |||||||
7714 | // Sometimes the debug info will mention a constructor (default/copy/move), | ||||||
7715 | // destructor, or assignment operator (copy/move) but there won't be any | ||||||
7716 | // version of this in the code. So we check if the function was artificially | ||||||
7717 | // generated and if it is trivial and this lets the compiler/backend know | ||||||
7718 | // that it can inline the IR for these when it needs to and we can avoid a | ||||||
7719 | // "missing function" error when running expressions. | ||||||
7720 | |||||||
7721 | if (is_artificial) { | ||||||
7722 | if (cxx_ctor_decl && ((cxx_ctor_decl->isDefaultConstructor() && | ||||||
7723 | cxx_record_decl->hasTrivialDefaultConstructor()) || | ||||||
7724 | (cxx_ctor_decl->isCopyConstructor() && | ||||||
7725 | cxx_record_decl->hasTrivialCopyConstructor()) || | ||||||
7726 | (cxx_ctor_decl->isMoveConstructor() && | ||||||
7727 | cxx_record_decl->hasTrivialMoveConstructor()))) { | ||||||
7728 | cxx_ctor_decl->setDefaulted(); | ||||||
7729 | cxx_ctor_decl->setTrivial(true); | ||||||
7730 | } else if (cxx_dtor_decl) { | ||||||
7731 | if (cxx_record_decl->hasTrivialDestructor()) { | ||||||
7732 | cxx_dtor_decl->setDefaulted(); | ||||||
7733 | cxx_dtor_decl->setTrivial(true); | ||||||
7734 | } | ||||||
7735 | } else if ((cxx_method_decl->isCopyAssignmentOperator() && | ||||||
7736 | cxx_record_decl->hasTrivialCopyAssignment()) || | ||||||
7737 | (cxx_method_decl->isMoveAssignmentOperator() && | ||||||
7738 | cxx_record_decl->hasTrivialMoveAssignment())) { | ||||||
7739 | cxx_method_decl->setDefaulted(); | ||||||
7740 | cxx_method_decl->setTrivial(true); | ||||||
7741 | } | ||||||
7742 | } | ||||||
7743 | |||||||
7744 | VerifyDecl(cxx_method_decl); | ||||||
7745 | |||||||
7746 | return cxx_method_decl; | ||||||
7747 | } | ||||||
7748 | |||||||
7749 | void TypeSystemClang::AddMethodOverridesForCXXRecordType( | ||||||
7750 | lldb::opaque_compiler_type_t type) { | ||||||
7751 | if (auto *record = GetAsCXXRecordDecl(type)) | ||||||
7752 | for (auto *method : record->methods()) | ||||||
7753 | addOverridesForMethod(method); | ||||||
7754 | } | ||||||
7755 | |||||||
7756 | #pragma mark C++ Base Classes | ||||||
7757 | |||||||
7758 | std::unique_ptr<clang::CXXBaseSpecifier> | ||||||
7759 | TypeSystemClang::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, | ||||||
7760 | AccessType access, bool is_virtual, | ||||||
7761 | bool base_of_class) { | ||||||
7762 | if (!type) | ||||||
7763 | return nullptr; | ||||||
7764 | |||||||
7765 | return std::make_unique<clang::CXXBaseSpecifier>( | ||||||
7766 | clang::SourceRange(), is_virtual, base_of_class, | ||||||
7767 | TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access), | ||||||
7768 | getASTContext().getTrivialTypeSourceInfo(GetQualType(type)), | ||||||
7769 | clang::SourceLocation()); | ||||||
7770 | } | ||||||
7771 | |||||||
7772 | bool TypeSystemClang::TransferBaseClasses( | ||||||
7773 | lldb::opaque_compiler_type_t type, | ||||||
7774 | std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases) { | ||||||
7775 | if (!type) | ||||||
7776 | return false; | ||||||
7777 | clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type); | ||||||
7778 | if (!cxx_record_decl) | ||||||
7779 | return false; | ||||||
7780 | std::vector<clang::CXXBaseSpecifier *> raw_bases; | ||||||
7781 | raw_bases.reserve(bases.size()); | ||||||
7782 | |||||||
7783 | // Clang will make a copy of them, so it's ok that we pass pointers that we're | ||||||
7784 | // about to destroy. | ||||||
7785 | for (auto &b : bases) | ||||||
7786 | raw_bases.push_back(b.get()); | ||||||
7787 | cxx_record_decl->setBases(raw_bases.data(), raw_bases.size()); | ||||||
7788 | return true; | ||||||
7789 | } | ||||||
7790 | |||||||
7791 | bool TypeSystemClang::SetObjCSuperClass( | ||||||
7792 | const CompilerType &type, const CompilerType &superclass_clang_type) { | ||||||
7793 | TypeSystemClang *ast = | ||||||
7794 | llvm::dyn_cast_or_null<TypeSystemClang>(type.GetTypeSystem()); | ||||||
7795 | if (!ast) | ||||||
7796 | return false; | ||||||
7797 | clang::ASTContext &clang_ast = ast->getASTContext(); | ||||||
7798 | |||||||
7799 | if (type && superclass_clang_type.IsValid() && | ||||||
7800 | superclass_clang_type.GetTypeSystem() == type.GetTypeSystem()) { | ||||||
7801 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
7802 | GetAsObjCInterfaceDecl(type); | ||||||
7803 | clang::ObjCInterfaceDecl *super_interface_decl = | ||||||
7804 | GetAsObjCInterfaceDecl(superclass_clang_type); | ||||||
7805 | if (class_interface_decl && super_interface_decl) { | ||||||
7806 | class_interface_decl->setSuperClass(clang_ast.getTrivialTypeSourceInfo( | ||||||
7807 | clang_ast.getObjCInterfaceType(super_interface_decl))); | ||||||
7808 | return true; | ||||||
7809 | } | ||||||
7810 | } | ||||||
7811 | return false; | ||||||
7812 | } | ||||||
7813 | |||||||
7814 | bool TypeSystemClang::AddObjCClassProperty( | ||||||
7815 | const CompilerType &type, const char *property_name, | ||||||
7816 | const CompilerType &property_clang_type, clang::ObjCIvarDecl *ivar_decl, | ||||||
7817 | const char *property_setter_name, const char *property_getter_name, | ||||||
7818 | uint32_t property_attributes, ClangASTMetadata *metadata) { | ||||||
7819 | if (!type || !property_clang_type.IsValid() || property_name == nullptr || | ||||||
7820 | property_name[0] == '\0') | ||||||
7821 | return false; | ||||||
7822 | TypeSystemClang *ast = llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem()); | ||||||
7823 | if (!ast) | ||||||
7824 | return false; | ||||||
7825 | clang::ASTContext &clang_ast = ast->getASTContext(); | ||||||
7826 | |||||||
7827 | clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type); | ||||||
7828 | if (!class_interface_decl) | ||||||
7829 | return false; | ||||||
7830 | |||||||
7831 | CompilerType property_clang_type_to_access; | ||||||
7832 | |||||||
7833 | if (property_clang_type.IsValid()) | ||||||
7834 | property_clang_type_to_access = property_clang_type; | ||||||
7835 | else if (ivar_decl) | ||||||
7836 | property_clang_type_to_access = ast->GetType(ivar_decl->getType()); | ||||||
7837 | |||||||
7838 | if (!class_interface_decl || !property_clang_type_to_access.IsValid()) | ||||||
7839 | return false; | ||||||
7840 | |||||||
7841 | clang::TypeSourceInfo *prop_type_source; | ||||||
7842 | if (ivar_decl) | ||||||
7843 | prop_type_source = clang_ast.getTrivialTypeSourceInfo(ivar_decl->getType()); | ||||||
7844 | else | ||||||
7845 | prop_type_source = clang_ast.getTrivialTypeSourceInfo( | ||||||
7846 | ClangUtil::GetQualType(property_clang_type)); | ||||||
7847 | |||||||
7848 | clang::ObjCPropertyDecl *property_decl = | ||||||
7849 | clang::ObjCPropertyDecl::CreateDeserialized(clang_ast, 0); | ||||||
7850 | property_decl->setDeclContext(class_interface_decl); | ||||||
7851 | property_decl->setDeclName(&clang_ast.Idents.get(property_name)); | ||||||
7852 | property_decl->setType(ivar_decl | ||||||
7853 | ? ivar_decl->getType() | ||||||
7854 | : ClangUtil::GetQualType(property_clang_type), | ||||||
7855 | prop_type_source); | ||||||
7856 | SetMemberOwningModule(property_decl, class_interface_decl); | ||||||
7857 | |||||||
7858 | if (!property_decl) | ||||||
7859 | return false; | ||||||
7860 | |||||||
7861 | if (metadata) | ||||||
7862 | ast->SetMetadata(property_decl, *metadata); | ||||||
7863 | |||||||
7864 | class_interface_decl->addDecl(property_decl); | ||||||
7865 | |||||||
7866 | clang::Selector setter_sel, getter_sel; | ||||||
7867 | |||||||
7868 | if (property_setter_name) { | ||||||
7869 | std::string property_setter_no_colon(property_setter_name, | ||||||
7870 | strlen(property_setter_name) - 1); | ||||||
7871 | clang::IdentifierInfo *setter_ident = | ||||||
7872 | &clang_ast.Idents.get(property_setter_no_colon); | ||||||
7873 | setter_sel = clang_ast.Selectors.getSelector(1, &setter_ident); | ||||||
7874 | } else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) { | ||||||
7875 | std::string setter_sel_string("set"); | ||||||
7876 | setter_sel_string.push_back(::toupper(property_name[0])); | ||||||
7877 | setter_sel_string.append(&property_name[1]); | ||||||
7878 | clang::IdentifierInfo *setter_ident = | ||||||
7879 | &clang_ast.Idents.get(setter_sel_string); | ||||||
7880 | setter_sel = clang_ast.Selectors.getSelector(1, &setter_ident); | ||||||
7881 | } | ||||||
7882 | property_decl->setSetterName(setter_sel); | ||||||
7883 | property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_setter); | ||||||
7884 | |||||||
7885 | if (property_getter_name != nullptr) { | ||||||
7886 | clang::IdentifierInfo *getter_ident = | ||||||
7887 | &clang_ast.Idents.get(property_getter_name); | ||||||
7888 | getter_sel = clang_ast.Selectors.getSelector(0, &getter_ident); | ||||||
7889 | } else { | ||||||
7890 | clang::IdentifierInfo *getter_ident = &clang_ast.Idents.get(property_name); | ||||||
7891 | getter_sel = clang_ast.Selectors.getSelector(0, &getter_ident); | ||||||
7892 | } | ||||||
7893 | property_decl->setGetterName(getter_sel); | ||||||
7894 | property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_getter); | ||||||
7895 | |||||||
7896 | if (ivar_decl) | ||||||
7897 | property_decl->setPropertyIvarDecl(ivar_decl); | ||||||
7898 | |||||||
7899 | if (property_attributes & DW_APPLE_PROPERTY_readonly) | ||||||
7900 | property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readonly); | ||||||
7901 | if (property_attributes & DW_APPLE_PROPERTY_readwrite) | ||||||
7902 | property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readwrite); | ||||||
7903 | if (property_attributes & DW_APPLE_PROPERTY_assign) | ||||||
7904 | property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_assign); | ||||||
7905 | if (property_attributes & DW_APPLE_PROPERTY_retain) | ||||||
7906 | property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_retain); | ||||||
7907 | if (property_attributes & DW_APPLE_PROPERTY_copy) | ||||||
7908 | property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_copy); | ||||||
7909 | if (property_attributes & DW_APPLE_PROPERTY_nonatomic) | ||||||
7910 | property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_nonatomic); | ||||||
7911 | if (property_attributes & ObjCPropertyAttribute::kind_nullability) | ||||||
7912 | property_decl->setPropertyAttributes( | ||||||
7913 | ObjCPropertyAttribute::kind_nullability); | ||||||
7914 | if (property_attributes & ObjCPropertyAttribute::kind_null_resettable) | ||||||
7915 | property_decl->setPropertyAttributes( | ||||||
7916 | ObjCPropertyAttribute::kind_null_resettable); | ||||||
7917 | if (property_attributes & ObjCPropertyAttribute::kind_class) | ||||||
7918 | property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_class); | ||||||
7919 | |||||||
7920 | const bool isInstance = | ||||||
7921 | (property_attributes & ObjCPropertyAttribute::kind_class) == 0; | ||||||
7922 | |||||||
7923 | clang::ObjCMethodDecl *getter = nullptr; | ||||||
7924 | if (!getter_sel.isNull()) | ||||||
7925 | getter = isInstance ? class_interface_decl->lookupInstanceMethod(getter_sel) | ||||||
7926 | : class_interface_decl->lookupClassMethod(getter_sel); | ||||||
7927 | if (!getter_sel.isNull() && !getter) { | ||||||
7928 | const bool isVariadic = false; | ||||||
7929 | const bool isPropertyAccessor = true; | ||||||
7930 | const bool isSynthesizedAccessorStub = false; | ||||||
7931 | const bool isImplicitlyDeclared = true; | ||||||
7932 | const bool isDefined = false; | ||||||
7933 | const clang::ObjCMethodDecl::ImplementationControl impControl = | ||||||
7934 | clang::ObjCMethodDecl::None; | ||||||
7935 | const bool HasRelatedResultType = false; | ||||||
7936 | |||||||
7937 | getter = clang::ObjCMethodDecl::CreateDeserialized(clang_ast, 0); | ||||||
7938 | getter->setDeclName(getter_sel); | ||||||
7939 | getter->setReturnType(ClangUtil::GetQualType(property_clang_type_to_access)); | ||||||
7940 | getter->setDeclContext(class_interface_decl); | ||||||
7941 | getter->setInstanceMethod(isInstance); | ||||||
7942 | getter->setVariadic(isVariadic); | ||||||
7943 | getter->setPropertyAccessor(isPropertyAccessor); | ||||||
7944 | getter->setSynthesizedAccessorStub(isSynthesizedAccessorStub); | ||||||
7945 | getter->setImplicit(isImplicitlyDeclared); | ||||||
7946 | getter->setDefined(isDefined); | ||||||
7947 | getter->setDeclImplementation(impControl); | ||||||
7948 | getter->setRelatedResultType(HasRelatedResultType); | ||||||
7949 | SetMemberOwningModule(getter, class_interface_decl); | ||||||
7950 | |||||||
7951 | if (getter) { | ||||||
7952 | if (metadata) | ||||||
7953 | ast->SetMetadata(getter, *metadata); | ||||||
7954 | |||||||
7955 | getter->setMethodParams(clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(), | ||||||
7956 | llvm::ArrayRef<clang::SourceLocation>()); | ||||||
7957 | class_interface_decl->addDecl(getter); | ||||||
7958 | } | ||||||
7959 | } | ||||||
7960 | if (getter) { | ||||||
7961 | getter->setPropertyAccessor(true); | ||||||
7962 | property_decl->setGetterMethodDecl(getter); | ||||||
7963 | } | ||||||
7964 | |||||||
7965 | clang::ObjCMethodDecl *setter = nullptr; | ||||||
7966 | setter = isInstance ? class_interface_decl->lookupInstanceMethod(setter_sel) | ||||||
7967 | : class_interface_decl->lookupClassMethod(setter_sel); | ||||||
7968 | if (!setter_sel.isNull() && !setter) { | ||||||
7969 | clang::QualType result_type = clang_ast.VoidTy; | ||||||
7970 | const bool isVariadic = false; | ||||||
7971 | const bool isPropertyAccessor = true; | ||||||
7972 | const bool isSynthesizedAccessorStub = false; | ||||||
7973 | const bool isImplicitlyDeclared = true; | ||||||
7974 | const bool isDefined = false; | ||||||
7975 | const clang::ObjCMethodDecl::ImplementationControl impControl = | ||||||
7976 | clang::ObjCMethodDecl::None; | ||||||
7977 | const bool HasRelatedResultType = false; | ||||||
7978 | |||||||
7979 | setter = clang::ObjCMethodDecl::CreateDeserialized(clang_ast, 0); | ||||||
7980 | setter->setDeclName(setter_sel); | ||||||
7981 | setter->setReturnType(result_type); | ||||||
7982 | setter->setDeclContext(class_interface_decl); | ||||||
7983 | setter->setInstanceMethod(isInstance); | ||||||
7984 | setter->setVariadic(isVariadic); | ||||||
7985 | setter->setPropertyAccessor(isPropertyAccessor); | ||||||
7986 | setter->setSynthesizedAccessorStub(isSynthesizedAccessorStub); | ||||||
7987 | setter->setImplicit(isImplicitlyDeclared); | ||||||
7988 | setter->setDefined(isDefined); | ||||||
7989 | setter->setDeclImplementation(impControl); | ||||||
7990 | setter->setRelatedResultType(HasRelatedResultType); | ||||||
7991 | SetMemberOwningModule(setter, class_interface_decl); | ||||||
7992 | |||||||
7993 | if (setter) { | ||||||
7994 | if (metadata) | ||||||
7995 | ast->SetMetadata(setter, *metadata); | ||||||
7996 | |||||||
7997 | llvm::SmallVector<clang::ParmVarDecl *, 1> params; | ||||||
7998 | params.push_back(clang::ParmVarDecl::Create( | ||||||
7999 | clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(), | ||||||
8000 | nullptr, // anonymous | ||||||
8001 | ClangUtil::GetQualType(property_clang_type_to_access), nullptr, | ||||||
8002 | clang::SC_Auto, nullptr)); | ||||||
8003 | |||||||
8004 | setter->setMethodParams(clang_ast, | ||||||
8005 | llvm::ArrayRef<clang::ParmVarDecl *>(params), | ||||||
8006 | llvm::ArrayRef<clang::SourceLocation>()); | ||||||
8007 | |||||||
8008 | class_interface_decl->addDecl(setter); | ||||||
8009 | } | ||||||
8010 | } | ||||||
8011 | if (setter) { | ||||||
8012 | setter->setPropertyAccessor(true); | ||||||
8013 | property_decl->setSetterMethodDecl(setter); | ||||||
8014 | } | ||||||
8015 | |||||||
8016 | return true; | ||||||
8017 | } | ||||||
8018 | |||||||
8019 | bool TypeSystemClang::IsObjCClassTypeAndHasIVars(const CompilerType &type, | ||||||
8020 | bool check_superclass) { | ||||||
8021 | clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type); | ||||||
8022 | if (class_interface_decl) | ||||||
8023 | return ObjCDeclHasIVars(class_interface_decl, check_superclass); | ||||||
8024 | return false; | ||||||
8025 | } | ||||||
8026 | |||||||
8027 | clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType( | ||||||
8028 | const CompilerType &type, | ||||||
8029 | const char *name, // the full symbol name as seen in the symbol table | ||||||
8030 | // (lldb::opaque_compiler_type_t type, "-[NString | ||||||
8031 | // stringWithCString:]") | ||||||
8032 | const CompilerType &method_clang_type, lldb::AccessType access, | ||||||
8033 | bool is_artificial, bool is_variadic, bool is_objc_direct_call) { | ||||||
8034 | if (!type || !method_clang_type.IsValid()) | ||||||
8035 | return nullptr; | ||||||
8036 | |||||||
8037 | clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl(type); | ||||||
8038 | |||||||
8039 | if (class_interface_decl == nullptr) | ||||||
8040 | return nullptr; | ||||||
8041 | TypeSystemClang *lldb_ast = | ||||||
8042 | llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem()); | ||||||
8043 | if (lldb_ast == nullptr) | ||||||
8044 | return nullptr; | ||||||
8045 | clang::ASTContext &ast = lldb_ast->getASTContext(); | ||||||
8046 | |||||||
8047 | const char *selector_start = ::strchr(name, ' '); | ||||||
8048 | if (selector_start == nullptr) | ||||||
8049 | return nullptr; | ||||||
8050 | |||||||
8051 | selector_start++; | ||||||
8052 | llvm::SmallVector<clang::IdentifierInfo *, 12> selector_idents; | ||||||
8053 | |||||||
8054 | size_t len = 0; | ||||||
8055 | const char *start; | ||||||
8056 | |||||||
8057 | unsigned num_selectors_with_args = 0; | ||||||
8058 | for (start = selector_start; start && *start != '\0' && *start != ']'; | ||||||
8059 | start += len) { | ||||||
8060 | len = ::strcspn(start, ":]"); | ||||||
8061 | bool has_arg = (start[len] == ':'); | ||||||
8062 | if (has_arg) | ||||||
8063 | ++num_selectors_with_args; | ||||||
8064 | selector_idents.push_back(&ast.Idents.get(llvm::StringRef(start, len))); | ||||||
8065 | if (has_arg) | ||||||
8066 | len += 1; | ||||||
8067 | } | ||||||
8068 | |||||||
8069 | if (selector_idents.size() == 0) | ||||||
8070 | return nullptr; | ||||||
8071 | |||||||
8072 | clang::Selector method_selector = ast.Selectors.getSelector( | ||||||
8073 | num_selectors_with_args ? selector_idents.size() : 0, | ||||||
8074 | selector_idents.data()); | ||||||
8075 | |||||||
8076 | clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type)); | ||||||
8077 | |||||||
8078 | // Populate the method decl with parameter decls | ||||||
8079 | const clang::Type *method_type(method_qual_type.getTypePtr()); | ||||||
8080 | |||||||
8081 | if (method_type == nullptr) | ||||||
8082 | return nullptr; | ||||||
8083 | |||||||
8084 | const clang::FunctionProtoType *method_function_prototype( | ||||||
8085 | llvm::dyn_cast<clang::FunctionProtoType>(method_type)); | ||||||
8086 | |||||||
8087 | if (!method_function_prototype) | ||||||
8088 | return nullptr; | ||||||
8089 | |||||||
8090 | const bool isInstance = (name[0] == '-'); | ||||||
8091 | const bool isVariadic = is_variadic; | ||||||
8092 | const bool isPropertyAccessor = false; | ||||||
8093 | const bool isSynthesizedAccessorStub = false; | ||||||
8094 | /// Force this to true because we don't have source locations. | ||||||
8095 | const bool isImplicitlyDeclared = true; | ||||||
8096 | const bool isDefined = false; | ||||||
8097 | const clang::ObjCMethodDecl::ImplementationControl impControl = | ||||||
8098 | clang::ObjCMethodDecl::None; | ||||||
8099 | const bool HasRelatedResultType = false; | ||||||
8100 | |||||||
8101 | const unsigned num_args = method_function_prototype->getNumParams(); | ||||||
8102 | |||||||
8103 | if (num_args != num_selectors_with_args) | ||||||
8104 | return nullptr; // some debug information is corrupt. We are not going to | ||||||
8105 | // deal with it. | ||||||
8106 | |||||||
8107 | auto *objc_method_decl = clang::ObjCMethodDecl::CreateDeserialized(ast, 0); | ||||||
8108 | objc_method_decl->setDeclName(method_selector); | ||||||
8109 | objc_method_decl->setReturnType(method_function_prototype->getReturnType()); | ||||||
8110 | objc_method_decl->setDeclContext( | ||||||
8111 | lldb_ast->GetDeclContextForType(ClangUtil::GetQualType(type))); | ||||||
8112 | objc_method_decl->setInstanceMethod(isInstance); | ||||||
8113 | objc_method_decl->setVariadic(isVariadic); | ||||||
8114 | objc_method_decl->setPropertyAccessor(isPropertyAccessor); | ||||||
8115 | objc_method_decl->setSynthesizedAccessorStub(isSynthesizedAccessorStub); | ||||||
8116 | objc_method_decl->setImplicit(isImplicitlyDeclared); | ||||||
8117 | objc_method_decl->setDefined(isDefined); | ||||||
8118 | objc_method_decl->setDeclImplementation(impControl); | ||||||
8119 | objc_method_decl->setRelatedResultType(HasRelatedResultType); | ||||||
8120 | SetMemberOwningModule(objc_method_decl, class_interface_decl); | ||||||
8121 | |||||||
8122 | if (objc_method_decl == nullptr) | ||||||
8123 | return nullptr; | ||||||
8124 | |||||||
8125 | if (num_args > 0) { | ||||||
8126 | llvm::SmallVector<clang::ParmVarDecl *, 12> params; | ||||||
8127 | |||||||
8128 | for (unsigned param_index = 0; param_index < num_args; ++param_index) { | ||||||
8129 | params.push_back(clang::ParmVarDecl::Create( | ||||||
8130 | ast, objc_method_decl, clang::SourceLocation(), | ||||||
8131 | clang::SourceLocation(), | ||||||
8132 | nullptr, // anonymous | ||||||
8133 | method_function_prototype->getParamType(param_index), nullptr, | ||||||
8134 | clang::SC_Auto, nullptr)); | ||||||
8135 | } | ||||||
8136 | |||||||
8137 | objc_method_decl->setMethodParams( | ||||||
8138 | ast, llvm::ArrayRef<clang::ParmVarDecl *>(params), | ||||||
8139 | llvm::ArrayRef<clang::SourceLocation>()); | ||||||
8140 | } | ||||||
8141 | |||||||
8142 | if (is_objc_direct_call) { | ||||||
8143 | // Add a the objc_direct attribute to the declaration we generate that | ||||||
8144 | // we generate a direct method call for this ObjCMethodDecl. | ||||||
8145 | objc_method_decl->addAttr( | ||||||
8146 | clang::ObjCDirectAttr::CreateImplicit(ast, SourceLocation())); | ||||||
8147 | // Usually Sema is creating implicit parameters (e.g., self) when it | ||||||
8148 | // parses the method. We don't have a parsing Sema when we build our own | ||||||
8149 | // AST here so we manually need to create these implicit parameters to | ||||||
8150 | // make the direct call code generation happy. | ||||||
8151 | objc_method_decl->createImplicitParams(ast, class_interface_decl); | ||||||
8152 | } | ||||||
8153 | |||||||
8154 | class_interface_decl->addDecl(objc_method_decl); | ||||||
8155 | |||||||
8156 | VerifyDecl(objc_method_decl); | ||||||
8157 | |||||||
8158 | return objc_method_decl; | ||||||
8159 | } | ||||||
8160 | |||||||
8161 | bool TypeSystemClang::SetHasExternalStorage(lldb::opaque_compiler_type_t type, | ||||||
8162 | bool has_extern) { | ||||||
8163 | if (!type) | ||||||
8164 | return false; | ||||||
8165 | |||||||
8166 | clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type))); | ||||||
8167 | |||||||
8168 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
8169 | switch (type_class) { | ||||||
8170 | case clang::Type::Record: { | ||||||
8171 | clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); | ||||||
8172 | if (cxx_record_decl) { | ||||||
8173 | cxx_record_decl->setHasExternalLexicalStorage(has_extern); | ||||||
8174 | cxx_record_decl->setHasExternalVisibleStorage(has_extern); | ||||||
8175 | return true; | ||||||
8176 | } | ||||||
8177 | } break; | ||||||
8178 | |||||||
8179 | case clang::Type::Enum: { | ||||||
8180 | clang::EnumDecl *enum_decl = | ||||||
8181 | llvm::cast<clang::EnumType>(qual_type)->getDecl(); | ||||||
8182 | if (enum_decl) { | ||||||
8183 | enum_decl->setHasExternalLexicalStorage(has_extern); | ||||||
8184 | enum_decl->setHasExternalVisibleStorage(has_extern); | ||||||
8185 | return true; | ||||||
8186 | } | ||||||
8187 | } break; | ||||||
8188 | |||||||
8189 | case clang::Type::ObjCObject: | ||||||
8190 | case clang::Type::ObjCInterface: { | ||||||
8191 | const clang::ObjCObjectType *objc_class_type = | ||||||
8192 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); | ||||||
8193 | assert(objc_class_type)(static_cast <bool> (objc_class_type) ? void (0) : __assert_fail ("objc_class_type", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 8193, __extension__ __PRETTY_FUNCTION__)); | ||||||
8194 | if (objc_class_type) { | ||||||
8195 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
8196 | objc_class_type->getInterface(); | ||||||
8197 | |||||||
8198 | if (class_interface_decl) { | ||||||
8199 | class_interface_decl->setHasExternalLexicalStorage(has_extern); | ||||||
8200 | class_interface_decl->setHasExternalVisibleStorage(has_extern); | ||||||
8201 | return true; | ||||||
8202 | } | ||||||
8203 | } | ||||||
8204 | } break; | ||||||
8205 | |||||||
8206 | default: | ||||||
8207 | break; | ||||||
8208 | } | ||||||
8209 | return false; | ||||||
8210 | } | ||||||
8211 | |||||||
8212 | #pragma mark TagDecl | ||||||
8213 | |||||||
8214 | bool TypeSystemClang::StartTagDeclarationDefinition(const CompilerType &type) { | ||||||
8215 | clang::QualType qual_type(ClangUtil::GetQualType(type)); | ||||||
8216 | if (!qual_type.isNull()) { | ||||||
8217 | const clang::TagType *tag_type = qual_type->getAs<clang::TagType>(); | ||||||
8218 | if (tag_type) { | ||||||
8219 | clang::TagDecl *tag_decl = tag_type->getDecl(); | ||||||
8220 | if (tag_decl) { | ||||||
8221 | tag_decl->startDefinition(); | ||||||
8222 | return true; | ||||||
8223 | } | ||||||
8224 | } | ||||||
8225 | |||||||
8226 | const clang::ObjCObjectType *object_type = | ||||||
8227 | qual_type->getAs<clang::ObjCObjectType>(); | ||||||
8228 | if (object_type) { | ||||||
8229 | clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface(); | ||||||
8230 | if (interface_decl) { | ||||||
8231 | interface_decl->startDefinition(); | ||||||
8232 | return true; | ||||||
8233 | } | ||||||
8234 | } | ||||||
8235 | } | ||||||
8236 | return false; | ||||||
8237 | } | ||||||
8238 | |||||||
8239 | bool TypeSystemClang::CompleteTagDeclarationDefinition( | ||||||
8240 | const CompilerType &type) { | ||||||
8241 | clang::QualType qual_type(ClangUtil::GetQualType(type)); | ||||||
8242 | if (qual_type.isNull()) | ||||||
8243 | return false; | ||||||
8244 | |||||||
8245 | TypeSystemClang *lldb_ast = | ||||||
8246 | llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem()); | ||||||
8247 | if (lldb_ast == nullptr) | ||||||
8248 | return false; | ||||||
8249 | |||||||
8250 | // Make sure we use the same methodology as | ||||||
8251 | // TypeSystemClang::StartTagDeclarationDefinition() as to how we start/end | ||||||
8252 | // the definition. | ||||||
8253 | const clang::TagType *tag_type = qual_type->getAs<clang::TagType>(); | ||||||
8254 | if (tag_type) { | ||||||
8255 | clang::TagDecl *tag_decl = tag_type->getDecl(); | ||||||
8256 | |||||||
8257 | if (auto *cxx_record_decl = llvm::dyn_cast<CXXRecordDecl>(tag_decl)) { | ||||||
8258 | // If we have a move constructor declared but no copy constructor we | ||||||
8259 | // need to explicitly mark it as deleted. Usually Sema would do this for | ||||||
8260 | // us in Sema::DeclareImplicitCopyConstructor but we don't have a Sema | ||||||
8261 | // when building an AST from debug information. | ||||||
8262 | // See also: | ||||||
8263 | // C++11 [class.copy]p7, p18: | ||||||
8264 | // If the class definition declares a move constructor or move assignment | ||||||
8265 | // operator, an implicitly declared copy constructor or copy assignment | ||||||
8266 | // operator is defined as deleted. | ||||||
8267 | if (cxx_record_decl->hasUserDeclaredMoveConstructor() || | ||||||
8268 | cxx_record_decl->hasUserDeclaredMoveAssignment()) { | ||||||
8269 | if (cxx_record_decl->needsImplicitCopyConstructor()) | ||||||
8270 | cxx_record_decl->setImplicitCopyConstructorIsDeleted(); | ||||||
8271 | if (cxx_record_decl->needsImplicitCopyAssignment()) | ||||||
8272 | cxx_record_decl->setImplicitCopyAssignmentIsDeleted(); | ||||||
8273 | } | ||||||
8274 | |||||||
8275 | if (!cxx_record_decl->isCompleteDefinition()) | ||||||
8276 | cxx_record_decl->completeDefinition(); | ||||||
8277 | cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); | ||||||
8278 | cxx_record_decl->setHasExternalLexicalStorage(false); | ||||||
8279 | cxx_record_decl->setHasExternalVisibleStorage(false); | ||||||
8280 | lldb_ast->SetCXXRecordDeclAccess(cxx_record_decl, | ||||||
8281 | clang::AccessSpecifier::AS_none); | ||||||
8282 | return true; | ||||||
8283 | } | ||||||
8284 | } | ||||||
8285 | |||||||
8286 | const clang::EnumType *enutype = qual_type->getAs<clang::EnumType>(); | ||||||
8287 | |||||||
8288 | if (!enutype) | ||||||
8289 | return false; | ||||||
8290 | clang::EnumDecl *enum_decl = enutype->getDecl(); | ||||||
8291 | |||||||
8292 | if (enum_decl->isCompleteDefinition()) | ||||||
8293 | return true; | ||||||
8294 | |||||||
8295 | clang::ASTContext &ast = lldb_ast->getASTContext(); | ||||||
8296 | |||||||
8297 | /// TODO This really needs to be fixed. | ||||||
8298 | |||||||
8299 | QualType integer_type(enum_decl->getIntegerType()); | ||||||
8300 | if (!integer_type.isNull()) { | ||||||
8301 | unsigned NumPositiveBits = 1; | ||||||
8302 | unsigned NumNegativeBits = 0; | ||||||
8303 | |||||||
8304 | clang::QualType promotion_qual_type; | ||||||
8305 | // If the enum integer type is less than an integer in bit width, | ||||||
8306 | // then we must promote it to an integer size. | ||||||
8307 | if (ast.getTypeSize(enum_decl->getIntegerType()) < | ||||||
8308 | ast.getTypeSize(ast.IntTy)) { | ||||||
8309 | if (enum_decl->getIntegerType()->isSignedIntegerType()) | ||||||
8310 | promotion_qual_type = ast.IntTy; | ||||||
8311 | else | ||||||
8312 | promotion_qual_type = ast.UnsignedIntTy; | ||||||
8313 | } else | ||||||
8314 | promotion_qual_type = enum_decl->getIntegerType(); | ||||||
8315 | |||||||
8316 | enum_decl->completeDefinition(enum_decl->getIntegerType(), | ||||||
8317 | promotion_qual_type, NumPositiveBits, | ||||||
8318 | NumNegativeBits); | ||||||
8319 | } | ||||||
8320 | return true; | ||||||
8321 | } | ||||||
8322 | |||||||
8323 | clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType( | ||||||
8324 | const CompilerType &enum_type, const Declaration &decl, const char *name, | ||||||
8325 | const llvm::APSInt &value) { | ||||||
8326 | |||||||
8327 | if (!enum_type || ConstString(name).IsEmpty()) | ||||||
8328 | return nullptr; | ||||||
8329 | |||||||
8330 | lldbassert(enum_type.GetTypeSystem() == static_cast<TypeSystem *>(this))lldb_private::lldb_assert(static_cast<bool>(enum_type.GetTypeSystem () == static_cast<TypeSystem *>(this)), "enum_type.GetTypeSystem() == static_cast<TypeSystem *>(this)" , __FUNCTION__, "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 8330); | ||||||
8331 | |||||||
8332 | lldb::opaque_compiler_type_t enum_opaque_compiler_type = | ||||||
8333 | enum_type.GetOpaqueQualType(); | ||||||
8334 | |||||||
8335 | if (!enum_opaque_compiler_type) | ||||||
8336 | return nullptr; | ||||||
8337 | |||||||
8338 | clang::QualType enum_qual_type( | ||||||
8339 | GetCanonicalQualType(enum_opaque_compiler_type)); | ||||||
8340 | |||||||
8341 | const clang::Type *clang_type = enum_qual_type.getTypePtr(); | ||||||
8342 | |||||||
8343 | if (!clang_type) | ||||||
8344 | return nullptr; | ||||||
8345 | |||||||
8346 | const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(clang_type); | ||||||
8347 | |||||||
8348 | if (!enutype) | ||||||
8349 | return nullptr; | ||||||
8350 | |||||||
8351 | clang::EnumConstantDecl *enumerator_decl = | ||||||
8352 | clang::EnumConstantDecl::CreateDeserialized(getASTContext(), 0); | ||||||
8353 | enumerator_decl->setDeclContext(enutype->getDecl()); | ||||||
8354 | if (name && name[0]) | ||||||
8355 | enumerator_decl->setDeclName(&getASTContext().Idents.get(name)); | ||||||
8356 | enumerator_decl->setType(clang::QualType(enutype, 0)); | ||||||
8357 | enumerator_decl->setInitVal(value); | ||||||
8358 | SetMemberOwningModule(enumerator_decl, enutype->getDecl()); | ||||||
8359 | |||||||
8360 | if (!enumerator_decl) | ||||||
8361 | return nullptr; | ||||||
8362 | |||||||
8363 | enutype->getDecl()->addDecl(enumerator_decl); | ||||||
8364 | |||||||
8365 | VerifyDecl(enumerator_decl); | ||||||
8366 | return enumerator_decl; | ||||||
8367 | } | ||||||
8368 | |||||||
8369 | clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType( | ||||||
8370 | const CompilerType &enum_type, const Declaration &decl, const char *name, | ||||||
8371 | int64_t enum_value, uint32_t enum_value_bit_size) { | ||||||
8372 | CompilerType underlying_type = GetEnumerationIntegerType(enum_type); | ||||||
8373 | bool is_signed = false; | ||||||
8374 | underlying_type.IsIntegerType(is_signed); | ||||||
8375 | |||||||
8376 | llvm::APSInt value(enum_value_bit_size, is_signed); | ||||||
8377 | value = enum_value; | ||||||
8378 | |||||||
8379 | return AddEnumerationValueToEnumerationType(enum_type, decl, name, value); | ||||||
8380 | } | ||||||
8381 | |||||||
8382 | CompilerType TypeSystemClang::GetEnumerationIntegerType(CompilerType type) { | ||||||
8383 | clang::QualType qt(ClangUtil::GetQualType(type)); | ||||||
8384 | const clang::Type *clang_type = qt.getTypePtrOrNull(); | ||||||
8385 | const auto *enum_type = llvm::dyn_cast_or_null<clang::EnumType>(clang_type); | ||||||
8386 | if (!enum_type) | ||||||
8387 | return CompilerType(); | ||||||
8388 | |||||||
8389 | return GetType(enum_type->getDecl()->getIntegerType()); | ||||||
8390 | } | ||||||
8391 | |||||||
8392 | CompilerType | ||||||
8393 | TypeSystemClang::CreateMemberPointerType(const CompilerType &type, | ||||||
8394 | const CompilerType &pointee_type) { | ||||||
8395 | if (type && pointee_type.IsValid() && | ||||||
8396 | type.GetTypeSystem() == pointee_type.GetTypeSystem()) { | ||||||
8397 | TypeSystemClang *ast = | ||||||
8398 | llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem()); | ||||||
8399 | if (!ast) | ||||||
8400 | return CompilerType(); | ||||||
8401 | return ast->GetType(ast->getASTContext().getMemberPointerType( | ||||||
8402 | ClangUtil::GetQualType(pointee_type), | ||||||
8403 | ClangUtil::GetQualType(type).getTypePtr())); | ||||||
8404 | } | ||||||
8405 | return CompilerType(); | ||||||
8406 | } | ||||||
8407 | |||||||
8408 | // Dumping types | ||||||
8409 | #define DEPTH_INCREMENT2 2 | ||||||
8410 | |||||||
8411 | #ifndef NDEBUG | ||||||
8412 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void | ||||||
8413 | TypeSystemClang::dump(lldb::opaque_compiler_type_t type) const { | ||||||
8414 | if (!type) | ||||||
8415 | return; | ||||||
8416 | clang::QualType qual_type(GetQualType(type)); | ||||||
8417 | qual_type.dump(); | ||||||
8418 | } | ||||||
8419 | #endif | ||||||
8420 | |||||||
8421 | void TypeSystemClang::Dump(llvm::raw_ostream &output) { | ||||||
8422 | GetTranslationUnitDecl()->dump(output); | ||||||
8423 | } | ||||||
8424 | |||||||
8425 | void TypeSystemClang::DumpFromSymbolFile(Stream &s, | ||||||
8426 | llvm::StringRef symbol_name) { | ||||||
8427 | SymbolFile *symfile = GetSymbolFile(); | ||||||
8428 | |||||||
8429 | if (!symfile) | ||||||
8430 | return; | ||||||
8431 | |||||||
8432 | lldb_private::TypeList type_list; | ||||||
8433 | symfile->GetTypes(nullptr, eTypeClassAny, type_list); | ||||||
8434 | size_t ntypes = type_list.GetSize(); | ||||||
8435 | |||||||
8436 | for (size_t i = 0; i < ntypes; ++i) { | ||||||
8437 | TypeSP type = type_list.GetTypeAtIndex(i); | ||||||
8438 | |||||||
8439 | if (!symbol_name.empty()) | ||||||
8440 | if (symbol_name != type->GetName().GetStringRef()) | ||||||
8441 | continue; | ||||||
8442 | |||||||
8443 | s << type->GetName().AsCString() << "\n"; | ||||||
8444 | |||||||
8445 | CompilerType full_type = type->GetFullCompilerType(); | ||||||
8446 | if (clang::TagDecl *tag_decl = GetAsTagDecl(full_type)) { | ||||||
8447 | tag_decl->dump(s.AsRawOstream()); | ||||||
8448 | continue; | ||||||
8449 | } | ||||||
8450 | if (clang::TypedefNameDecl *typedef_decl = GetAsTypedefDecl(full_type)) { | ||||||
8451 | typedef_decl->dump(s.AsRawOstream()); | ||||||
8452 | continue; | ||||||
8453 | } | ||||||
8454 | if (auto *objc_obj = llvm::dyn_cast<clang::ObjCObjectType>( | ||||||
8455 | ClangUtil::GetQualType(full_type).getTypePtr())) { | ||||||
8456 | if (clang::ObjCInterfaceDecl *interface_decl = objc_obj->getInterface()) { | ||||||
8457 | interface_decl->dump(s.AsRawOstream()); | ||||||
8458 | continue; | ||||||
8459 | } | ||||||
8460 | } | ||||||
8461 | GetCanonicalQualType(full_type.GetOpaqueQualType()) | ||||||
8462 | .dump(s.AsRawOstream(), getASTContext()); | ||||||
8463 | } | ||||||
8464 | } | ||||||
8465 | |||||||
8466 | void TypeSystemClang::DumpValue( | ||||||
8467 | lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, | ||||||
8468 | lldb::Format format, const lldb_private::DataExtractor &data, | ||||||
8469 | lldb::offset_t data_byte_offset, size_t data_byte_size, | ||||||
8470 | uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, | ||||||
8471 | bool show_summary, bool verbose, uint32_t depth) { | ||||||
8472 | if (!type) | ||||||
8473 | return; | ||||||
8474 | |||||||
8475 | clang::QualType qual_type(GetQualType(type)); | ||||||
8476 | switch (qual_type->getTypeClass()) { | ||||||
8477 | case clang::Type::Record: | ||||||
8478 | if (GetCompleteType(type)) { | ||||||
8479 | const clang::RecordType *record_type = | ||||||
8480 | llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
8481 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
8482 | assert(record_decl)(static_cast <bool> (record_decl) ? void (0) : __assert_fail ("record_decl", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 8482, __extension__ __PRETTY_FUNCTION__)); | ||||||
8483 | uint32_t field_bit_offset = 0; | ||||||
8484 | uint32_t field_byte_offset = 0; | ||||||
8485 | const clang::ASTRecordLayout &record_layout = | ||||||
8486 | getASTContext().getASTRecordLayout(record_decl); | ||||||
8487 | uint32_t child_idx = 0; | ||||||
8488 | |||||||
8489 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
8490 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); | ||||||
8491 | if (cxx_record_decl) { | ||||||
8492 | // We might have base classes to print out first | ||||||
8493 | clang::CXXRecordDecl::base_class_const_iterator base_class, | ||||||
8494 | base_class_end; | ||||||
8495 | for (base_class = cxx_record_decl->bases_begin(), | ||||||
8496 | base_class_end = cxx_record_decl->bases_end(); | ||||||
8497 | base_class != base_class_end; ++base_class) { | ||||||
8498 | const clang::CXXRecordDecl *base_class_decl = | ||||||
8499 | llvm::cast<clang::CXXRecordDecl>( | ||||||
8500 | base_class->getType()->getAs<clang::RecordType>()->getDecl()); | ||||||
8501 | |||||||
8502 | // Skip empty base classes | ||||||
8503 | if (!verbose && !TypeSystemClang::RecordHasFields(base_class_decl)) | ||||||
8504 | continue; | ||||||
8505 | |||||||
8506 | if (base_class->isVirtual()) | ||||||
8507 | field_bit_offset = | ||||||
8508 | record_layout.getVBaseClassOffset(base_class_decl) | ||||||
8509 | .getQuantity() * | ||||||
8510 | 8; | ||||||
8511 | else | ||||||
8512 | field_bit_offset = record_layout.getBaseClassOffset(base_class_decl) | ||||||
8513 | .getQuantity() * | ||||||
8514 | 8; | ||||||
8515 | field_byte_offset = field_bit_offset / 8; | ||||||
8516 | assert(field_bit_offset % 8 == 0)(static_cast <bool> (field_bit_offset % 8 == 0) ? void ( 0) : __assert_fail ("field_bit_offset % 8 == 0", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 8516, __extension__ __PRETTY_FUNCTION__)); | ||||||
8517 | if (child_idx == 0) | ||||||
8518 | s->PutChar('{'); | ||||||
8519 | else | ||||||
8520 | s->PutChar(','); | ||||||
8521 | |||||||
8522 | clang::QualType base_class_qual_type = base_class->getType(); | ||||||
8523 | std::string base_class_type_name(base_class_qual_type.getAsString()); | ||||||
8524 | |||||||
8525 | // Indent and print the base class type name | ||||||
8526 | s->Format("\n{0}{1}", llvm::fmt_repeat(" ", depth + DEPTH_INCREMENT2), | ||||||
8527 | base_class_type_name); | ||||||
8528 | |||||||
8529 | clang::TypeInfo base_class_type_info = | ||||||
8530 | getASTContext().getTypeInfo(base_class_qual_type); | ||||||
8531 | |||||||
8532 | // Dump the value of the member | ||||||
8533 | CompilerType base_clang_type = GetType(base_class_qual_type); | ||||||
8534 | base_clang_type.DumpValue( | ||||||
8535 | exe_ctx, | ||||||
8536 | s, // Stream to dump to | ||||||
8537 | base_clang_type | ||||||
8538 | .GetFormat(), // The format with which to display the member | ||||||
8539 | data, // Data buffer containing all bytes for this type | ||||||
8540 | data_byte_offset + field_byte_offset, // Offset into "data" where | ||||||
8541 | // to grab value from | ||||||
8542 | base_class_type_info.Width / 8, // Size of this type in bytes | ||||||
8543 | 0, // Bitfield bit size | ||||||
8544 | 0, // Bitfield bit offset | ||||||
8545 | show_types, // Boolean indicating if we should show the variable | ||||||
8546 | // types | ||||||
8547 | show_summary, // Boolean indicating if we should show a summary | ||||||
8548 | // for the current type | ||||||
8549 | verbose, // Verbose output? | ||||||
8550 | depth + DEPTH_INCREMENT2); // Scope depth for any types that have | ||||||
8551 | // children | ||||||
8552 | |||||||
8553 | ++child_idx; | ||||||
8554 | } | ||||||
8555 | } | ||||||
8556 | uint32_t field_idx = 0; | ||||||
8557 | clang::RecordDecl::field_iterator field, field_end; | ||||||
8558 | for (field = record_decl->field_begin(), | ||||||
8559 | field_end = record_decl->field_end(); | ||||||
8560 | field != field_end; ++field, ++field_idx, ++child_idx) { | ||||||
8561 | // Print the starting squiggly bracket (if this is the first member) or | ||||||
8562 | // comma (for member 2 and beyond) for the struct/union/class member. | ||||||
8563 | if (child_idx == 0) | ||||||
8564 | s->PutChar('{'); | ||||||
8565 | else | ||||||
8566 | s->PutChar(','); | ||||||
8567 | |||||||
8568 | // Indent | ||||||
8569 | s->Printf("\n%*s", depth + DEPTH_INCREMENT2, ""); | ||||||
8570 | |||||||
8571 | clang::QualType field_type = field->getType(); | ||||||
8572 | // Print the member type if requested | ||||||
8573 | // Figure out the type byte size (field_type_info.first) and alignment | ||||||
8574 | // (field_type_info.second) from the AST context. | ||||||
8575 | clang::TypeInfo field_type_info = | ||||||
8576 | getASTContext().getTypeInfo(field_type); | ||||||
8577 | assert(field_idx < record_layout.getFieldCount())(static_cast <bool> (field_idx < record_layout.getFieldCount ()) ? void (0) : __assert_fail ("field_idx < record_layout.getFieldCount()" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 8577, __extension__ __PRETTY_FUNCTION__)); | ||||||
8578 | // Figure out the field offset within the current struct/union/class | ||||||
8579 | // type | ||||||
8580 | field_bit_offset = record_layout.getFieldOffset(field_idx); | ||||||
8581 | field_byte_offset = field_bit_offset / 8; | ||||||
8582 | uint32_t field_bitfield_bit_size = 0; | ||||||
8583 | uint32_t field_bitfield_bit_offset = 0; | ||||||
8584 | if (FieldIsBitfield(*field, field_bitfield_bit_size)) | ||||||
8585 | field_bitfield_bit_offset = field_bit_offset % 8; | ||||||
8586 | |||||||
8587 | if (show_types) { | ||||||
8588 | std::string field_type_name(field_type.getAsString()); | ||||||
8589 | if (field_bitfield_bit_size > 0) | ||||||
8590 | s->Printf("(%s:%u) ", field_type_name.c_str(), | ||||||
8591 | field_bitfield_bit_size); | ||||||
8592 | else | ||||||
8593 | s->Printf("(%s) ", field_type_name.c_str()); | ||||||
8594 | } | ||||||
8595 | // Print the member name and equal sign | ||||||
8596 | s->Printf("%s = ", field->getNameAsString().c_str()); | ||||||
8597 | |||||||
8598 | // Dump the value of the member | ||||||
8599 | CompilerType field_clang_type = GetType(field_type); | ||||||
8600 | field_clang_type.DumpValue( | ||||||
8601 | exe_ctx, | ||||||
8602 | s, // Stream to dump to | ||||||
8603 | field_clang_type | ||||||
8604 | .GetFormat(), // The format with which to display the member | ||||||
8605 | data, // Data buffer containing all bytes for this type | ||||||
8606 | data_byte_offset + field_byte_offset, // Offset into "data" where to | ||||||
8607 | // grab value from | ||||||
8608 | field_type_info.Width / 8, // Size of this type in bytes | ||||||
8609 | field_bitfield_bit_size, // Bitfield bit size | ||||||
8610 | field_bitfield_bit_offset, // Bitfield bit offset | ||||||
8611 | show_types, // Boolean indicating if we should show the variable | ||||||
8612 | // types | ||||||
8613 | show_summary, // Boolean indicating if we should show a summary for | ||||||
8614 | // the current type | ||||||
8615 | verbose, // Verbose output? | ||||||
8616 | depth + DEPTH_INCREMENT2); // Scope depth for any types that have | ||||||
8617 | // children | ||||||
8618 | } | ||||||
8619 | |||||||
8620 | // Indent the trailing squiggly bracket | ||||||
8621 | if (child_idx > 0) | ||||||
8622 | s->Printf("\n%*s}", depth, ""); | ||||||
8623 | } | ||||||
8624 | return; | ||||||
8625 | |||||||
8626 | case clang::Type::Enum: | ||||||
8627 | if (GetCompleteType(type)) { | ||||||
8628 | const clang::EnumType *enutype = | ||||||
8629 | llvm::cast<clang::EnumType>(qual_type.getTypePtr()); | ||||||
8630 | const clang::EnumDecl *enum_decl = enutype->getDecl(); | ||||||
8631 | assert(enum_decl)(static_cast <bool> (enum_decl) ? void (0) : __assert_fail ("enum_decl", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 8631, __extension__ __PRETTY_FUNCTION__)); | ||||||
8632 | clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; | ||||||
8633 | lldb::offset_t offset = data_byte_offset; | ||||||
8634 | const int64_t enum_value = data.GetMaxU64Bitfield( | ||||||
8635 | &offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset); | ||||||
8636 | for (enum_pos = enum_decl->enumerator_begin(), | ||||||
8637 | enum_end_pos = enum_decl->enumerator_end(); | ||||||
8638 | enum_pos != enum_end_pos; ++enum_pos) { | ||||||
8639 | if (enum_pos->getInitVal() == enum_value) { | ||||||
8640 | s->Printf("%s", enum_pos->getNameAsString().c_str()); | ||||||
8641 | return; | ||||||
8642 | } | ||||||
8643 | } | ||||||
8644 | // If we have gotten here we didn't get find the enumerator in the enum | ||||||
8645 | // decl, so just print the integer. | ||||||
8646 | s->Printf("%" PRIi64"l" "i", enum_value); | ||||||
8647 | } | ||||||
8648 | return; | ||||||
8649 | |||||||
8650 | case clang::Type::ConstantArray: { | ||||||
8651 | const clang::ConstantArrayType *array = | ||||||
8652 | llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr()); | ||||||
8653 | bool is_array_of_characters = false; | ||||||
8654 | clang::QualType element_qual_type = array->getElementType(); | ||||||
8655 | |||||||
8656 | const clang::Type *canonical_type = | ||||||
8657 | element_qual_type->getCanonicalTypeInternal().getTypePtr(); | ||||||
8658 | if (canonical_type) | ||||||
8659 | is_array_of_characters = canonical_type->isCharType(); | ||||||
8660 | |||||||
8661 | const uint64_t element_count = array->getSize().getLimitedValue(); | ||||||
8662 | |||||||
8663 | clang::TypeInfo field_type_info = | ||||||
8664 | getASTContext().getTypeInfo(element_qual_type); | ||||||
8665 | |||||||
8666 | uint32_t element_idx = 0; | ||||||
8667 | uint32_t element_offset = 0; | ||||||
8668 | uint64_t element_byte_size = field_type_info.Width / 8; | ||||||
8669 | uint32_t element_stride = element_byte_size; | ||||||
8670 | |||||||
8671 | if (is_array_of_characters) { | ||||||
8672 | s->PutChar('"'); | ||||||
8673 | DumpDataExtractor(data, s, data_byte_offset, lldb::eFormatChar, | ||||||
8674 | element_byte_size, element_count, UINT32_MAX(4294967295U), | ||||||
8675 | LLDB_INVALID_ADDRESS(18446744073709551615UL), 0, 0); | ||||||
8676 | s->PutChar('"'); | ||||||
8677 | return; | ||||||
8678 | } else { | ||||||
8679 | CompilerType element_clang_type = GetType(element_qual_type); | ||||||
8680 | lldb::Format element_format = element_clang_type.GetFormat(); | ||||||
8681 | |||||||
8682 | for (element_idx = 0; element_idx < element_count; ++element_idx) { | ||||||
8683 | // Print the starting squiggly bracket (if this is the first member) or | ||||||
8684 | // comman (for member 2 and beyong) for the struct/union/class member. | ||||||
8685 | if (element_idx == 0) | ||||||
8686 | s->PutChar('{'); | ||||||
8687 | else | ||||||
8688 | s->PutChar(','); | ||||||
8689 | |||||||
8690 | // Indent and print the index | ||||||
8691 | s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT2, "", element_idx); | ||||||
8692 | |||||||
8693 | // Figure out the field offset within the current struct/union/class | ||||||
8694 | // type | ||||||
8695 | element_offset = element_idx * element_stride; | ||||||
8696 | |||||||
8697 | // Dump the value of the member | ||||||
8698 | element_clang_type.DumpValue( | ||||||
8699 | exe_ctx, | ||||||
8700 | s, // Stream to dump to | ||||||
8701 | element_format, // The format with which to display the element | ||||||
8702 | data, // Data buffer containing all bytes for this type | ||||||
8703 | data_byte_offset + | ||||||
8704 | element_offset, // Offset into "data" where to grab value from | ||||||
8705 | element_byte_size, // Size of this type in bytes | ||||||
8706 | 0, // Bitfield bit size | ||||||
8707 | 0, // Bitfield bit offset | ||||||
8708 | show_types, // Boolean indicating if we should show the variable | ||||||
8709 | // types | ||||||
8710 | show_summary, // Boolean indicating if we should show a summary for | ||||||
8711 | // the current type | ||||||
8712 | verbose, // Verbose output? | ||||||
8713 | depth + DEPTH_INCREMENT2); // Scope depth for any types that have | ||||||
8714 | // children | ||||||
8715 | } | ||||||
8716 | |||||||
8717 | // Indent the trailing squiggly bracket | ||||||
8718 | if (element_idx > 0) | ||||||
8719 | s->Printf("\n%*s}", depth, ""); | ||||||
8720 | } | ||||||
8721 | } | ||||||
8722 | return; | ||||||
8723 | |||||||
8724 | case clang::Type::Typedef: { | ||||||
8725 | clang::QualType typedef_qual_type = | ||||||
8726 | llvm::cast<clang::TypedefType>(qual_type) | ||||||
8727 | ->getDecl() | ||||||
8728 | ->getUnderlyingType(); | ||||||
8729 | |||||||
8730 | CompilerType typedef_clang_type = GetType(typedef_qual_type); | ||||||
8731 | lldb::Format typedef_format = typedef_clang_type.GetFormat(); | ||||||
8732 | clang::TypeInfo typedef_type_info = | ||||||
8733 | getASTContext().getTypeInfo(typedef_qual_type); | ||||||
8734 | uint64_t typedef_byte_size = typedef_type_info.Width / 8; | ||||||
8735 | |||||||
8736 | return typedef_clang_type.DumpValue( | ||||||
8737 | exe_ctx, | ||||||
8738 | s, // Stream to dump to | ||||||
8739 | typedef_format, // The format with which to display the element | ||||||
8740 | data, // Data buffer containing all bytes for this type | ||||||
8741 | data_byte_offset, // Offset into "data" where to grab value from | ||||||
8742 | typedef_byte_size, // Size of this type in bytes | ||||||
8743 | bitfield_bit_size, // Bitfield bit size | ||||||
8744 | bitfield_bit_offset, // Bitfield bit offset | ||||||
8745 | show_types, // Boolean indicating if we should show the variable types | ||||||
8746 | show_summary, // Boolean indicating if we should show a summary for the | ||||||
8747 | // current type | ||||||
8748 | verbose, // Verbose output? | ||||||
8749 | depth); // Scope depth for any types that have children | ||||||
8750 | } break; | ||||||
8751 | |||||||
8752 | case clang::Type::Auto: { | ||||||
8753 | clang::QualType elaborated_qual_type = | ||||||
8754 | llvm::cast<clang::AutoType>(qual_type)->getDeducedType(); | ||||||
8755 | CompilerType elaborated_clang_type = GetType(elaborated_qual_type); | ||||||
8756 | lldb::Format elaborated_format = elaborated_clang_type.GetFormat(); | ||||||
8757 | clang::TypeInfo elaborated_type_info = | ||||||
8758 | getASTContext().getTypeInfo(elaborated_qual_type); | ||||||
8759 | uint64_t elaborated_byte_size = elaborated_type_info.Width / 8; | ||||||
8760 | |||||||
8761 | return elaborated_clang_type.DumpValue( | ||||||
8762 | exe_ctx, | ||||||
8763 | s, // Stream to dump to | ||||||
8764 | elaborated_format, // The format with which to display the element | ||||||
8765 | data, // Data buffer containing all bytes for this type | ||||||
8766 | data_byte_offset, // Offset into "data" where to grab value from | ||||||
8767 | elaborated_byte_size, // Size of this type in bytes | ||||||
8768 | bitfield_bit_size, // Bitfield bit size | ||||||
8769 | bitfield_bit_offset, // Bitfield bit offset | ||||||
8770 | show_types, // Boolean indicating if we should show the variable types | ||||||
8771 | show_summary, // Boolean indicating if we should show a summary for the | ||||||
8772 | // current type | ||||||
8773 | verbose, // Verbose output? | ||||||
8774 | depth); // Scope depth for any types that have children | ||||||
8775 | } break; | ||||||
8776 | |||||||
8777 | case clang::Type::Elaborated: { | ||||||
8778 | clang::QualType elaborated_qual_type = | ||||||
8779 | llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(); | ||||||
8780 | CompilerType elaborated_clang_type = GetType(elaborated_qual_type); | ||||||
8781 | lldb::Format elaborated_format = elaborated_clang_type.GetFormat(); | ||||||
8782 | clang::TypeInfo elaborated_type_info = | ||||||
8783 | getASTContext().getTypeInfo(elaborated_qual_type); | ||||||
8784 | uint64_t elaborated_byte_size = elaborated_type_info.Width / 8; | ||||||
8785 | |||||||
8786 | return elaborated_clang_type.DumpValue( | ||||||
8787 | exe_ctx, | ||||||
8788 | s, // Stream to dump to | ||||||
8789 | elaborated_format, // The format with which to display the element | ||||||
8790 | data, // Data buffer containing all bytes for this type | ||||||
8791 | data_byte_offset, // Offset into "data" where to grab value from | ||||||
8792 | elaborated_byte_size, // Size of this type in bytes | ||||||
8793 | bitfield_bit_size, // Bitfield bit size | ||||||
8794 | bitfield_bit_offset, // Bitfield bit offset | ||||||
8795 | show_types, // Boolean indicating if we should show the variable types | ||||||
8796 | show_summary, // Boolean indicating if we should show a summary for the | ||||||
8797 | // current type | ||||||
8798 | verbose, // Verbose output? | ||||||
8799 | depth); // Scope depth for any types that have children | ||||||
8800 | } break; | ||||||
8801 | |||||||
8802 | case clang::Type::Paren: { | ||||||
8803 | clang::QualType desugar_qual_type = | ||||||
8804 | llvm::cast<clang::ParenType>(qual_type)->desugar(); | ||||||
8805 | CompilerType desugar_clang_type = GetType(desugar_qual_type); | ||||||
8806 | |||||||
8807 | lldb::Format desugar_format = desugar_clang_type.GetFormat(); | ||||||
8808 | clang::TypeInfo desugar_type_info = | ||||||
8809 | getASTContext().getTypeInfo(desugar_qual_type); | ||||||
8810 | uint64_t desugar_byte_size = desugar_type_info.Width / 8; | ||||||
8811 | |||||||
8812 | return desugar_clang_type.DumpValue( | ||||||
8813 | exe_ctx, | ||||||
8814 | s, // Stream to dump to | ||||||
8815 | desugar_format, // The format with which to display the element | ||||||
8816 | data, // Data buffer containing all bytes for this type | ||||||
8817 | data_byte_offset, // Offset into "data" where to grab value from | ||||||
8818 | desugar_byte_size, // Size of this type in bytes | ||||||
8819 | bitfield_bit_size, // Bitfield bit size | ||||||
8820 | bitfield_bit_offset, // Bitfield bit offset | ||||||
8821 | show_types, // Boolean indicating if we should show the variable types | ||||||
8822 | show_summary, // Boolean indicating if we should show a summary for the | ||||||
8823 | // current type | ||||||
8824 | verbose, // Verbose output? | ||||||
8825 | depth); // Scope depth for any types that have children | ||||||
8826 | } break; | ||||||
8827 | |||||||
8828 | default: | ||||||
8829 | // We are down to a scalar type that we just need to display. | ||||||
8830 | DumpDataExtractor(data, s, data_byte_offset, format, data_byte_size, 1, | ||||||
8831 | UINT32_MAX(4294967295U), LLDB_INVALID_ADDRESS(18446744073709551615UL), bitfield_bit_size, | ||||||
8832 | bitfield_bit_offset); | ||||||
8833 | |||||||
8834 | if (show_summary) | ||||||
8835 | DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size); | ||||||
8836 | break; | ||||||
8837 | } | ||||||
8838 | } | ||||||
8839 | |||||||
8840 | static bool DumpEnumValue(const clang::QualType &qual_type, Stream *s, | ||||||
8841 | const DataExtractor &data, lldb::offset_t byte_offset, | ||||||
8842 | size_t byte_size, uint32_t bitfield_bit_offset, | ||||||
8843 | uint32_t bitfield_bit_size) { | ||||||
8844 | const clang::EnumType *enutype = | ||||||
8845 | llvm::cast<clang::EnumType>(qual_type.getTypePtr()); | ||||||
8846 | const clang::EnumDecl *enum_decl = enutype->getDecl(); | ||||||
8847 | assert(enum_decl)(static_cast <bool> (enum_decl) ? void (0) : __assert_fail ("enum_decl", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 8847, __extension__ __PRETTY_FUNCTION__)); | ||||||
8848 | lldb::offset_t offset = byte_offset; | ||||||
8849 | const uint64_t enum_svalue = data.GetMaxS64Bitfield( | ||||||
8850 | &offset, byte_size, bitfield_bit_size, bitfield_bit_offset); | ||||||
8851 | bool can_be_bitfield = true; | ||||||
8852 | uint64_t covered_bits = 0; | ||||||
8853 | int num_enumerators = 0; | ||||||
8854 | |||||||
8855 | // Try to find an exact match for the value. | ||||||
8856 | // At the same time, we're applying a heuristic to determine whether we want | ||||||
8857 | // to print this enum as a bitfield. We're likely dealing with a bitfield if | ||||||
8858 | // every enumerator is either a one bit value or a superset of the previous | ||||||
8859 | // enumerators. Also 0 doesn't make sense when the enumerators are used as | ||||||
8860 | // flags. | ||||||
8861 | for (auto *enumerator : enum_decl->enumerators()) { | ||||||
8862 | uint64_t val = enumerator->getInitVal().getSExtValue(); | ||||||
8863 | val = llvm::SignExtend64(val, 8*byte_size); | ||||||
8864 | if (llvm::countPopulation(val) != 1 && (val & ~covered_bits) != 0) | ||||||
8865 | can_be_bitfield = false; | ||||||
8866 | covered_bits |= val; | ||||||
8867 | ++num_enumerators; | ||||||
8868 | if (val == enum_svalue) { | ||||||
8869 | // Found an exact match, that's all we need to do. | ||||||
8870 | s->PutCString(enumerator->getNameAsString()); | ||||||
8871 | return true; | ||||||
8872 | } | ||||||
8873 | } | ||||||
8874 | |||||||
8875 | // Unsigned values make more sense for flags. | ||||||
8876 | offset = byte_offset; | ||||||
8877 | const uint64_t enum_uvalue = data.GetMaxU64Bitfield( | ||||||
8878 | &offset, byte_size, bitfield_bit_size, bitfield_bit_offset); | ||||||
8879 | |||||||
8880 | // No exact match, but we don't think this is a bitfield. Print the value as | ||||||
8881 | // decimal. | ||||||
8882 | if (!can_be_bitfield) { | ||||||
8883 | if (qual_type->isSignedIntegerOrEnumerationType()) | ||||||
8884 | s->Printf("%" PRIi64"l" "i", enum_svalue); | ||||||
8885 | else | ||||||
8886 | s->Printf("%" PRIu64"l" "u", enum_uvalue); | ||||||
8887 | return true; | ||||||
8888 | } | ||||||
8889 | |||||||
8890 | uint64_t remaining_value = enum_uvalue; | ||||||
8891 | std::vector<std::pair<uint64_t, llvm::StringRef>> values; | ||||||
8892 | values.reserve(num_enumerators); | ||||||
8893 | for (auto *enumerator : enum_decl->enumerators()) | ||||||
8894 | if (auto val = enumerator->getInitVal().getZExtValue()) | ||||||
8895 | values.emplace_back(val, enumerator->getName()); | ||||||
8896 | |||||||
8897 | // Sort in reverse order of the number of the population count, so that in | ||||||
8898 | // `enum {A, B, ALL = A|B }` we visit ALL first. Use a stable sort so that | ||||||
8899 | // A | C where A is declared before C is displayed in this order. | ||||||
8900 | std::stable_sort(values.begin(), values.end(), [](const auto &a, const auto &b) { | ||||||
8901 | return llvm::countPopulation(a.first) > llvm::countPopulation(b.first); | ||||||
8902 | }); | ||||||
8903 | |||||||
8904 | for (const auto &val : values) { | ||||||
8905 | if ((remaining_value & val.first) != val.first) | ||||||
8906 | continue; | ||||||
8907 | remaining_value &= ~val.first; | ||||||
8908 | s->PutCString(val.second); | ||||||
8909 | if (remaining_value) | ||||||
8910 | s->PutCString(" | "); | ||||||
8911 | } | ||||||
8912 | |||||||
8913 | // If there is a remainder that is not covered by the value, print it as hex. | ||||||
8914 | if (remaining_value) | ||||||
8915 | s->Printf("0x%" PRIx64"l" "x", remaining_value); | ||||||
8916 | |||||||
8917 | return true; | ||||||
8918 | } | ||||||
8919 | |||||||
8920 | bool TypeSystemClang::DumpTypeValue( | ||||||
8921 | lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, | ||||||
8922 | const lldb_private::DataExtractor &data, lldb::offset_t byte_offset, | ||||||
8923 | size_t byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, | ||||||
8924 | ExecutionContextScope *exe_scope) { | ||||||
8925 | if (!type) | ||||||
8926 | return false; | ||||||
8927 | if (IsAggregateType(type)) { | ||||||
8928 | return false; | ||||||
8929 | } else { | ||||||
8930 | clang::QualType qual_type(GetQualType(type)); | ||||||
8931 | |||||||
8932 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
8933 | |||||||
8934 | if (type_class == clang::Type::Elaborated) { | ||||||
8935 | qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(); | ||||||
8936 | return DumpTypeValue(qual_type.getAsOpaquePtr(), s, format, data, byte_offset, byte_size, | ||||||
8937 | bitfield_bit_size, bitfield_bit_offset, exe_scope); | ||||||
8938 | } | ||||||
8939 | |||||||
8940 | switch (type_class) { | ||||||
8941 | case clang::Type::Typedef: { | ||||||
8942 | clang::QualType typedef_qual_type = | ||||||
8943 | llvm::cast<clang::TypedefType>(qual_type) | ||||||
8944 | ->getDecl() | ||||||
8945 | ->getUnderlyingType(); | ||||||
8946 | CompilerType typedef_clang_type = GetType(typedef_qual_type); | ||||||
8947 | if (format == eFormatDefault) | ||||||
8948 | format = typedef_clang_type.GetFormat(); | ||||||
8949 | clang::TypeInfo typedef_type_info = | ||||||
8950 | getASTContext().getTypeInfo(typedef_qual_type); | ||||||
8951 | uint64_t typedef_byte_size = typedef_type_info.Width / 8; | ||||||
8952 | |||||||
8953 | return typedef_clang_type.DumpTypeValue( | ||||||
8954 | s, | ||||||
8955 | format, // The format with which to display the element | ||||||
8956 | data, // Data buffer containing all bytes for this type | ||||||
8957 | byte_offset, // Offset into "data" where to grab value from | ||||||
8958 | typedef_byte_size, // Size of this type in bytes | ||||||
8959 | bitfield_bit_size, // Size in bits of a bitfield value, if zero don't | ||||||
8960 | // treat as a bitfield | ||||||
8961 | bitfield_bit_offset, // Offset in bits of a bitfield value if | ||||||
8962 | // bitfield_bit_size != 0 | ||||||
8963 | exe_scope); | ||||||
8964 | } break; | ||||||
8965 | |||||||
8966 | case clang::Type::Enum: | ||||||
8967 | // If our format is enum or default, show the enumeration value as its | ||||||
8968 | // enumeration string value, else just display it as requested. | ||||||
8969 | if ((format == eFormatEnum || format == eFormatDefault) && | ||||||
8970 | GetCompleteType(type)) | ||||||
8971 | return DumpEnumValue(qual_type, s, data, byte_offset, byte_size, | ||||||
8972 | bitfield_bit_offset, bitfield_bit_size); | ||||||
8973 | // format was not enum, just fall through and dump the value as | ||||||
8974 | // requested.... | ||||||
8975 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | ||||||
8976 | |||||||
8977 | default: | ||||||
8978 | // We are down to a scalar type that we just need to display. | ||||||
8979 | { | ||||||
8980 | uint32_t item_count = 1; | ||||||
8981 | // A few formats, we might need to modify our size and count for | ||||||
8982 | // depending | ||||||
8983 | // on how we are trying to display the value... | ||||||
8984 | switch (format) { | ||||||
8985 | default: | ||||||
8986 | case eFormatBoolean: | ||||||
8987 | case eFormatBinary: | ||||||
8988 | case eFormatComplex: | ||||||
8989 | case eFormatCString: // NULL terminated C strings | ||||||
8990 | case eFormatDecimal: | ||||||
8991 | case eFormatEnum: | ||||||
8992 | case eFormatHex: | ||||||
8993 | case eFormatHexUppercase: | ||||||
8994 | case eFormatFloat: | ||||||
8995 | case eFormatOctal: | ||||||
8996 | case eFormatOSType: | ||||||
8997 | case eFormatUnsigned: | ||||||
8998 | case eFormatPointer: | ||||||
8999 | case eFormatVectorOfChar: | ||||||
9000 | case eFormatVectorOfSInt8: | ||||||
9001 | case eFormatVectorOfUInt8: | ||||||
9002 | case eFormatVectorOfSInt16: | ||||||
9003 | case eFormatVectorOfUInt16: | ||||||
9004 | case eFormatVectorOfSInt32: | ||||||
9005 | case eFormatVectorOfUInt32: | ||||||
9006 | case eFormatVectorOfSInt64: | ||||||
9007 | case eFormatVectorOfUInt64: | ||||||
9008 | case eFormatVectorOfFloat32: | ||||||
9009 | case eFormatVectorOfFloat64: | ||||||
9010 | case eFormatVectorOfUInt128: | ||||||
9011 | break; | ||||||
9012 | |||||||
9013 | case eFormatChar: | ||||||
9014 | case eFormatCharPrintable: | ||||||
9015 | case eFormatCharArray: | ||||||
9016 | case eFormatBytes: | ||||||
9017 | case eFormatUnicode8: | ||||||
9018 | case eFormatBytesWithASCII: | ||||||
9019 | item_count = byte_size; | ||||||
9020 | byte_size = 1; | ||||||
9021 | break; | ||||||
9022 | |||||||
9023 | case eFormatUnicode16: | ||||||
9024 | item_count = byte_size / 2; | ||||||
9025 | byte_size = 2; | ||||||
9026 | break; | ||||||
9027 | |||||||
9028 | case eFormatUnicode32: | ||||||
9029 | item_count = byte_size / 4; | ||||||
9030 | byte_size = 4; | ||||||
9031 | break; | ||||||
9032 | } | ||||||
9033 | return DumpDataExtractor(data, s, byte_offset, format, byte_size, | ||||||
9034 | item_count, UINT32_MAX(4294967295U), LLDB_INVALID_ADDRESS(18446744073709551615UL), | ||||||
9035 | bitfield_bit_size, bitfield_bit_offset, | ||||||
9036 | exe_scope); | ||||||
9037 | } | ||||||
9038 | break; | ||||||
9039 | } | ||||||
9040 | } | ||||||
9041 | return false; | ||||||
9042 | } | ||||||
9043 | |||||||
9044 | void TypeSystemClang::DumpSummary(lldb::opaque_compiler_type_t type, | ||||||
9045 | ExecutionContext *exe_ctx, Stream *s, | ||||||
9046 | const lldb_private::DataExtractor &data, | ||||||
9047 | lldb::offset_t data_byte_offset, | ||||||
9048 | size_t data_byte_size) { | ||||||
9049 | uint32_t length = 0; | ||||||
9050 | if (IsCStringType(type, length)) { | ||||||
9051 | if (exe_ctx) { | ||||||
9052 | Process *process = exe_ctx->GetProcessPtr(); | ||||||
9053 | if (process) { | ||||||
9054 | lldb::offset_t offset = data_byte_offset; | ||||||
9055 | lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size); | ||||||
9056 | std::vector<uint8_t> buf; | ||||||
9057 | if (length > 0) | ||||||
9058 | buf.resize(length); | ||||||
9059 | else | ||||||
9060 | buf.resize(256); | ||||||
9061 | |||||||
9062 | DataExtractor cstr_data(&buf.front(), buf.size(), | ||||||
9063 | process->GetByteOrder(), 4); | ||||||
9064 | buf.back() = '\0'; | ||||||
9065 | size_t bytes_read; | ||||||
9066 | size_t total_cstr_len = 0; | ||||||
9067 | Status error; | ||||||
9068 | while ((bytes_read = process->ReadMemory(pointer_address, &buf.front(), | ||||||
9069 | buf.size(), error)) > 0) { | ||||||
9070 | const size_t len = strlen((const char *)&buf.front()); | ||||||
9071 | if (len == 0) | ||||||
9072 | break; | ||||||
9073 | if (total_cstr_len == 0) | ||||||
9074 | s->PutCString(" \""); | ||||||
9075 | DumpDataExtractor(cstr_data, s, 0, lldb::eFormatChar, 1, len, | ||||||
9076 | UINT32_MAX(4294967295U), LLDB_INVALID_ADDRESS(18446744073709551615UL), 0, 0); | ||||||
9077 | total_cstr_len += len; | ||||||
9078 | if (len < buf.size()) | ||||||
9079 | break; | ||||||
9080 | pointer_address += total_cstr_len; | ||||||
9081 | } | ||||||
9082 | if (total_cstr_len > 0) | ||||||
9083 | s->PutChar('"'); | ||||||
9084 | } | ||||||
9085 | } | ||||||
9086 | } | ||||||
9087 | } | ||||||
9088 | |||||||
9089 | void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, | ||||||
9090 | lldb::DescriptionLevel level) { | ||||||
9091 | StreamFile s(stdoutstdout, false); | ||||||
9092 | DumpTypeDescription(type, &s, level); | ||||||
9093 | |||||||
9094 | CompilerType ct(this, type); | ||||||
9095 | const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr(); | ||||||
9096 | ClangASTMetadata *metadata = GetMetadata(clang_type); | ||||||
9097 | if (metadata) { | ||||||
9098 | metadata->Dump(&s); | ||||||
9099 | } | ||||||
9100 | } | ||||||
9101 | |||||||
9102 | void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, | ||||||
9103 | Stream *s, | ||||||
9104 | lldb::DescriptionLevel level) { | ||||||
9105 | if (type) { | ||||||
9106 | clang::QualType qual_type = | ||||||
9107 | RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}); | ||||||
9108 | |||||||
9109 | llvm::SmallVector<char, 1024> buf; | ||||||
9110 | llvm::raw_svector_ostream llvm_ostrm(buf); | ||||||
9111 | |||||||
9112 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
9113 | switch (type_class) { | ||||||
9114 | case clang::Type::ObjCObject: | ||||||
9115 | case clang::Type::ObjCInterface: { | ||||||
9116 | GetCompleteType(type); | ||||||
9117 | |||||||
9118 | auto *objc_class_type = | ||||||
9119 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); | ||||||
9120 | assert(objc_class_type)(static_cast <bool> (objc_class_type) ? void (0) : __assert_fail ("objc_class_type", "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , 9120, __extension__ __PRETTY_FUNCTION__)); | ||||||
9121 | if (!objc_class_type) | ||||||
9122 | break; | ||||||
9123 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
9124 | objc_class_type->getInterface(); | ||||||
9125 | if (!class_interface_decl) | ||||||
9126 | break; | ||||||
9127 | if (level == eDescriptionLevelVerbose) | ||||||
9128 | class_interface_decl->dump(llvm_ostrm); | ||||||
9129 | else | ||||||
9130 | class_interface_decl->print(llvm_ostrm, | ||||||
9131 | getASTContext().getPrintingPolicy(), | ||||||
9132 | s->GetIndentLevel()); | ||||||
9133 | } break; | ||||||
9134 | |||||||
9135 | case clang::Type::Typedef: { | ||||||
9136 | auto *typedef_type = qual_type->getAs<clang::TypedefType>(); | ||||||
9137 | if (!typedef_type) | ||||||
9138 | break; | ||||||
9139 | const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); | ||||||
9140 | if (level == eDescriptionLevelVerbose) | ||||||
9141 | typedef_decl->dump(llvm_ostrm); | ||||||
9142 | else { | ||||||
9143 | std::string clang_typedef_name(GetTypeNameForDecl(typedef_decl)); | ||||||
9144 | if (!clang_typedef_name.empty()) { | ||||||
9145 | s->PutCString("typedef "); | ||||||
9146 | s->PutCString(clang_typedef_name); | ||||||
9147 | } | ||||||
9148 | } | ||||||
9149 | } break; | ||||||
9150 | |||||||
9151 | case clang::Type::Record: { | ||||||
9152 | GetCompleteType(type); | ||||||
9153 | |||||||
9154 | auto *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr()); | ||||||
9155 | const clang::RecordDecl *record_decl = record_type->getDecl(); | ||||||
9156 | if (level == eDescriptionLevelVerbose) | ||||||
9157 | record_decl->dump(llvm_ostrm); | ||||||
9158 | else { | ||||||
9159 | if (auto *cxx_record_decl = | ||||||
9160 | llvm::dyn_cast<clang::CXXRecordDecl>(record_decl)) | ||||||
9161 | cxx_record_decl->print(llvm_ostrm, | ||||||
9162 | getASTContext().getPrintingPolicy(), | ||||||
9163 | s->GetIndentLevel()); | ||||||
9164 | else | ||||||
9165 | record_decl->print(llvm_ostrm, getASTContext().getPrintingPolicy(), | ||||||
9166 | s->GetIndentLevel()); | ||||||
9167 | } | ||||||
9168 | } break; | ||||||
9169 | |||||||
9170 | default: { | ||||||
9171 | if (auto *tag_type = | ||||||
9172 | llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr())) { | ||||||
9173 | if (clang::TagDecl *tag_decl = tag_type->getDecl()) { | ||||||
9174 | if (level == eDescriptionLevelVerbose) | ||||||
9175 | tag_decl->dump(llvm_ostrm); | ||||||
9176 | else | ||||||
9177 | tag_decl->print(llvm_ostrm, 0); | ||||||
9178 | } | ||||||
9179 | } else { | ||||||
9180 | if (level == eDescriptionLevelVerbose) | ||||||
9181 | qual_type->dump(llvm_ostrm, getASTContext()); | ||||||
9182 | else { | ||||||
9183 | std::string clang_type_name(qual_type.getAsString()); | ||||||
9184 | if (!clang_type_name.empty()) | ||||||
9185 | s->PutCString(clang_type_name); | ||||||
9186 | } | ||||||
9187 | } | ||||||
9188 | } | ||||||
9189 | } | ||||||
9190 | |||||||
9191 | if (buf.size() > 0) { | ||||||
9192 | s->Write(buf.data(), buf.size()); | ||||||
9193 | } | ||||||
9194 | } | ||||||
9195 | } | ||||||
9196 | |||||||
9197 | void TypeSystemClang::DumpTypeName(const CompilerType &type) { | ||||||
9198 | if (ClangUtil::IsClangType(type)) { | ||||||
9199 | clang::QualType qual_type( | ||||||
9200 | ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); | ||||||
9201 | |||||||
9202 | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||||
9203 | switch (type_class) { | ||||||
9204 | case clang::Type::Record: { | ||||||
9205 | const clang::CXXRecordDecl *cxx_record_decl = | ||||||
9206 | qual_type->getAsCXXRecordDecl(); | ||||||
9207 | if (cxx_record_decl) | ||||||
9208 | printf("class %s", cxx_record_decl->getName().str().c_str()); | ||||||
9209 | } break; | ||||||
9210 | |||||||
9211 | case clang::Type::Enum: { | ||||||
9212 | clang::EnumDecl *enum_decl = | ||||||
9213 | llvm::cast<clang::EnumType>(qual_type)->getDecl(); | ||||||
9214 | if (enum_decl) { | ||||||
9215 | printf("enum %s", enum_decl->getName().str().c_str()); | ||||||
9216 | } | ||||||
9217 | } break; | ||||||
9218 | |||||||
9219 | case clang::Type::ObjCObject: | ||||||
9220 | case clang::Type::ObjCInterface: { | ||||||
9221 | const clang::ObjCObjectType *objc_class_type = | ||||||
9222 | llvm::dyn_cast<clang::ObjCObjectType>(qual_type); | ||||||
9223 | if (objc_class_type) { | ||||||
9224 | clang::ObjCInterfaceDecl *class_interface_decl = | ||||||
9225 | objc_class_type->getInterface(); | ||||||
9226 | // We currently can't complete objective C types through the newly | ||||||
9227 | // added ASTContext because it only supports TagDecl objects right | ||||||
9228 | // now... | ||||||
9229 | if (class_interface_decl) | ||||||
9230 | printf("@class %s", class_interface_decl->getName().str().c_str()); | ||||||
9231 | } | ||||||
9232 | } break; | ||||||
9233 | |||||||
9234 | case clang::Type::Typedef: | ||||||
9235 | printf("typedef %s", llvm::cast<clang::TypedefType>(qual_type) | ||||||
9236 | ->getDecl() | ||||||
9237 | ->getName() | ||||||
9238 | .str() | ||||||
9239 | .c_str()); | ||||||
9240 | break; | ||||||
9241 | |||||||
9242 | case clang::Type::Auto: | ||||||
9243 | printf("auto "); | ||||||
9244 | return DumpTypeName(CompilerType(type.GetTypeSystem(), | ||||||
9245 | llvm::cast<clang::AutoType>(qual_type) | ||||||
9246 | ->getDeducedType() | ||||||
9247 | .getAsOpaquePtr())); | ||||||
9248 | |||||||
9249 | case clang::Type::Elaborated: | ||||||
9250 | printf("elaborated "); | ||||||
9251 | return DumpTypeName(CompilerType( | ||||||
9252 | type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type) | ||||||
9253 | ->getNamedType() | ||||||
9254 | .getAsOpaquePtr())); | ||||||
9255 | |||||||
9256 | case clang::Type::Paren: | ||||||
9257 | printf("paren "); | ||||||
9258 | return DumpTypeName(CompilerType( | ||||||
9259 | type.GetTypeSystem(), | ||||||
9260 | llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr())); | ||||||
9261 | |||||||
9262 | default: | ||||||
9263 | printf("TypeSystemClang::DumpTypeName() type_class = %u", type_class); | ||||||
9264 | break; | ||||||
9265 | } | ||||||
9266 | } | ||||||
9267 | } | ||||||
9268 | |||||||
9269 | clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl( | ||||||
9270 | clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, | ||||||
9271 | lldb::AccessType access_type, const char *parent_name, int tag_decl_kind, | ||||||
9272 | const TypeSystemClang::TemplateParameterInfos &template_param_infos) { | ||||||
9273 | if (template_param_infos.IsValid()) { | ||||||
9274 | std::string template_basename(parent_name); | ||||||
9275 | template_basename.erase(template_basename.find('<')); | ||||||
9276 | |||||||
9277 | return CreateClassTemplateDecl(decl_ctx, owning_module, access_type, | ||||||
9278 | template_basename.c_str(), tag_decl_kind, | ||||||
9279 | template_param_infos); | ||||||
9280 | } | ||||||
9281 | return nullptr; | ||||||
9282 | } | ||||||
9283 | |||||||
9284 | void TypeSystemClang::CompleteTagDecl(clang::TagDecl *decl) { | ||||||
9285 | SymbolFile *sym_file = GetSymbolFile(); | ||||||
9286 | if (sym_file) { | ||||||
9287 | CompilerType clang_type = GetTypeForDecl(decl); | ||||||
9288 | if (clang_type) | ||||||
9289 | sym_file->CompleteType(clang_type); | ||||||
9290 | } | ||||||
9291 | } | ||||||
9292 | |||||||
9293 | void TypeSystemClang::CompleteObjCInterfaceDecl( | ||||||
9294 | clang::ObjCInterfaceDecl *decl) { | ||||||
9295 | SymbolFile *sym_file = GetSymbolFile(); | ||||||
9296 | if (sym_file) { | ||||||
9297 | CompilerType clang_type = GetTypeForDecl(decl); | ||||||
9298 | if (clang_type) | ||||||
9299 | sym_file->CompleteType(clang_type); | ||||||
9300 | } | ||||||
9301 | } | ||||||
9302 | |||||||
9303 | DWARFASTParser *TypeSystemClang::GetDWARFParser() { | ||||||
9304 | if (!m_dwarf_ast_parser_up) | ||||||
9305 | m_dwarf_ast_parser_up = std::make_unique<DWARFASTParserClang>(*this); | ||||||
9306 | return m_dwarf_ast_parser_up.get(); | ||||||
9307 | } | ||||||
9308 | |||||||
9309 | PDBASTParser *TypeSystemClang::GetPDBParser() { | ||||||
9310 | if (!m_pdb_ast_parser_up) | ||||||
9311 | m_pdb_ast_parser_up = std::make_unique<PDBASTParser>(*this); | ||||||
9312 | return m_pdb_ast_parser_up.get(); | ||||||
9313 | } | ||||||
9314 | |||||||
9315 | bool TypeSystemClang::LayoutRecordType( | ||||||
9316 | const clang::RecordDecl *record_decl, uint64_t &bit_size, | ||||||
9317 | uint64_t &alignment, | ||||||
9318 | llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, | ||||||
9319 | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> | ||||||
9320 | &base_offsets, | ||||||
9321 | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> | ||||||
9322 | &vbase_offsets) { | ||||||
9323 | lldb_private::ClangASTImporter *importer = nullptr; | ||||||
9324 | if (m_dwarf_ast_parser_up) | ||||||
9325 | importer = &m_dwarf_ast_parser_up->GetClangASTImporter(); | ||||||
9326 | if (!importer && m_pdb_ast_parser_up) | ||||||
9327 | importer = &m_pdb_ast_parser_up->GetClangASTImporter(); | ||||||
9328 | if (!importer) | ||||||
9329 | return false; | ||||||
9330 | |||||||
9331 | return importer->LayoutRecordType(record_decl, bit_size, alignment, | ||||||
9332 | field_offsets, base_offsets, vbase_offsets); | ||||||
9333 | } | ||||||
9334 | |||||||
9335 | // CompilerDecl override functions | ||||||
9336 | |||||||
9337 | ConstString TypeSystemClang::DeclGetName(void *opaque_decl) { | ||||||
9338 | if (opaque_decl) { | ||||||
9339 | clang::NamedDecl *nd = | ||||||
9340 | llvm::dyn_cast<NamedDecl>((clang::Decl *)opaque_decl); | ||||||
9341 | if (nd != nullptr) | ||||||
9342 | return ConstString(nd->getDeclName().getAsString()); | ||||||
9343 | } | ||||||
9344 | return ConstString(); | ||||||
9345 | } | ||||||
9346 | |||||||
9347 | ConstString TypeSystemClang::DeclGetMangledName(void *opaque_decl) { | ||||||
9348 | if (opaque_decl) { | ||||||
9349 | clang::NamedDecl *nd = | ||||||
9350 | llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)opaque_decl); | ||||||
9351 | if (nd != nullptr && !llvm::isa<clang::ObjCMethodDecl>(nd)) { | ||||||
9352 | clang::MangleContext *mc = getMangleContext(); | ||||||
9353 | if (mc && mc->shouldMangleCXXName(nd)) { | ||||||
9354 | llvm::SmallVector<char, 1024> buf; | ||||||
9355 | llvm::raw_svector_ostream llvm_ostrm(buf); | ||||||
9356 | if (llvm::isa<clang::CXXConstructorDecl>(nd)) { | ||||||
9357 | mc->mangleName( | ||||||
9358 | clang::GlobalDecl(llvm::dyn_cast<clang::CXXConstructorDecl>(nd), | ||||||
9359 | Ctor_Complete), | ||||||
9360 | llvm_ostrm); | ||||||
9361 | } else if (llvm::isa<clang::CXXDestructorDecl>(nd)) { | ||||||
9362 | mc->mangleName( | ||||||
9363 | clang::GlobalDecl(llvm::dyn_cast<clang::CXXDestructorDecl>(nd), | ||||||
9364 | Dtor_Complete), | ||||||
9365 | llvm_ostrm); | ||||||
9366 | } else { | ||||||
9367 | mc->mangleName(nd, llvm_ostrm); | ||||||
9368 | } | ||||||
9369 | if (buf.size() > 0) | ||||||
9370 | return ConstString(buf.data(), buf.size()); | ||||||
9371 | } | ||||||
9372 | } | ||||||
9373 | } | ||||||
9374 | return ConstString(); | ||||||
9375 | } | ||||||
9376 | |||||||
9377 | CompilerDeclContext TypeSystemClang::DeclGetDeclContext(void *opaque_decl) { | ||||||
9378 | if (opaque_decl) | ||||||
9379 | return CreateDeclContext(((clang::Decl *)opaque_decl)->getDeclContext()); | ||||||
9380 | return CompilerDeclContext(); | ||||||
9381 | } | ||||||
9382 | |||||||
9383 | CompilerType TypeSystemClang::DeclGetFunctionReturnType(void *opaque_decl) { | ||||||
9384 | if (clang::FunctionDecl *func_decl = | ||||||
9385 | llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl)) | ||||||
9386 | return GetType(func_decl->getReturnType()); | ||||||
9387 | if (clang::ObjCMethodDecl *objc_method = | ||||||
9388 | llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl)) | ||||||
9389 | return GetType(objc_method->getReturnType()); | ||||||
9390 | else | ||||||
9391 | return CompilerType(); | ||||||
9392 | } | ||||||
9393 | |||||||
9394 | size_t TypeSystemClang::DeclGetFunctionNumArguments(void *opaque_decl) { | ||||||
9395 | if (clang::FunctionDecl *func_decl = | ||||||
9396 | llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl)) | ||||||
9397 | return func_decl->param_size(); | ||||||
9398 | if (clang::ObjCMethodDecl *objc_method = | ||||||
9399 | llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl *)opaque_decl)) | ||||||
9400 | return objc_method->param_size(); | ||||||
9401 | else | ||||||
9402 | return 0; | ||||||
9403 | } | ||||||
9404 | |||||||
9405 | CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl, | ||||||
9406 | size_t idx) { | ||||||
9407 | if (clang::FunctionDecl *func_decl = | ||||||
9408 | llvm::dyn_cast<clang::FunctionDecl>((clang::Decl *)opaque_decl)) { | ||||||
9409 | if (idx < func_decl->param_size()) { | ||||||
9410 | ParmVarDecl *var_decl = func_decl->getParamDecl(idx); | ||||||
9411 | if (var_decl) | ||||||
9412 | return GetType(var_decl->getOriginalType()); | ||||||
9413 | } | ||||||
9414 | } else if (clang::ObjCMethodDecl *objc_method = | ||||||
9415 | llvm::dyn_cast<clang::ObjCMethodDecl>( | ||||||
9416 | (clang::Decl *)opaque_decl)) { | ||||||
9417 | if (idx < objc_method->param_size()) | ||||||
9418 | return GetType(objc_method->parameters()[idx]->getOriginalType()); | ||||||
9419 | } | ||||||
9420 | return CompilerType(); | ||||||
9421 | } | ||||||
9422 | |||||||
9423 | // CompilerDeclContext functions | ||||||
9424 | |||||||
9425 | std::vector<CompilerDecl> TypeSystemClang::DeclContextFindDeclByName( | ||||||
9426 | void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) { | ||||||
9427 | std::vector<CompilerDecl> found_decls; | ||||||
9428 | SymbolFile *symbol_file = GetSymbolFile(); | ||||||
9429 | if (opaque_decl_ctx && symbol_file) { | ||||||
9430 | DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx; | ||||||
9431 | std::set<DeclContext *> searched; | ||||||
9432 | std::multimap<DeclContext *, DeclContext *> search_queue; | ||||||
9433 | |||||||
9434 | for (clang::DeclContext *decl_context = root_decl_ctx; | ||||||
9435 | decl_context != nullptr && found_decls.empty(); | ||||||
9436 | decl_context = decl_context->getParent()) { | ||||||
9437 | search_queue.insert(std::make_pair(decl_context, decl_context)); | ||||||
9438 | |||||||
9439 | for (auto it = search_queue.find(decl_context); it != search_queue.end(); | ||||||
9440 | it++) { | ||||||
9441 | if (!searched.insert(it->second).second) | ||||||
9442 | continue; | ||||||
9443 | symbol_file->ParseDeclsForContext( | ||||||
9444 | CreateDeclContext(it->second)); | ||||||
9445 | |||||||
9446 | for (clang::Decl *child : it->second->decls()) { | ||||||
9447 | if (clang::UsingDirectiveDecl *ud = | ||||||
9448 | llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) { | ||||||
9449 | if (ignore_using_decls) | ||||||
9450 | continue; | ||||||
9451 | clang::DeclContext *from = ud->getCommonAncestor(); | ||||||
9452 | if (searched.find(ud->getNominatedNamespace()) == searched.end()) | ||||||
9453 | search_queue.insert( | ||||||
9454 | std::make_pair(from, ud->getNominatedNamespace())); | ||||||
9455 | } else if (clang::UsingDecl *ud = | ||||||
9456 | llvm::dyn_cast<clang::UsingDecl>(child)) { | ||||||
9457 | if (ignore_using_decls) | ||||||
9458 | continue; | ||||||
9459 | for (clang::UsingShadowDecl *usd : ud->shadows()) { | ||||||
9460 | clang::Decl *target = usd->getTargetDecl(); | ||||||
9461 | if (clang::NamedDecl *nd = | ||||||
9462 | llvm::dyn_cast<clang::NamedDecl>(target)) { | ||||||
9463 | IdentifierInfo *ii = nd->getIdentifier(); | ||||||
9464 | if (ii != nullptr && | ||||||
9465 | ii->getName().equals(name.AsCString(nullptr))) | ||||||
9466 | found_decls.push_back(GetCompilerDecl(nd)); | ||||||
9467 | } | ||||||
9468 | } | ||||||
9469 | } else if (clang::NamedDecl *nd = | ||||||
9470 | llvm::dyn_cast<clang::NamedDecl>(child)) { | ||||||
9471 | IdentifierInfo *ii = nd->getIdentifier(); | ||||||
9472 | if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr))) | ||||||
9473 | found_decls.push_back(GetCompilerDecl(nd)); | ||||||
9474 | } | ||||||
9475 | } | ||||||
9476 | } | ||||||
9477 | } | ||||||
9478 | } | ||||||
9479 | return found_decls; | ||||||
9480 | } | ||||||
9481 | |||||||
9482 | // Look for child_decl_ctx's lookup scope in frame_decl_ctx and its parents, | ||||||
9483 | // and return the number of levels it took to find it, or | ||||||
9484 | // LLDB_INVALID_DECL_LEVEL if not found. If the decl was imported via a using | ||||||
9485 | // declaration, its name and/or type, if set, will be used to check that the | ||||||
9486 | // decl found in the scope is a match. | ||||||
9487 | // | ||||||
9488 | // The optional name is required by languages (like C++) to handle using | ||||||
9489 | // declarations like: | ||||||
9490 | // | ||||||
9491 | // void poo(); | ||||||
9492 | // namespace ns { | ||||||
9493 | // void foo(); | ||||||
9494 | // void goo(); | ||||||
9495 | // } | ||||||
9496 | // void bar() { | ||||||
9497 | // using ns::foo; | ||||||
9498 | // // CountDeclLevels returns 0 for 'foo', 1 for 'poo', and | ||||||
9499 | // // LLDB_INVALID_DECL_LEVEL for 'goo'. | ||||||
9500 | // } | ||||||
9501 | // | ||||||
9502 | // The optional type is useful in the case that there's a specific overload | ||||||
9503 | // that we're looking for that might otherwise be shadowed, like: | ||||||
9504 | // | ||||||
9505 | // void foo(int); | ||||||
9506 | // namespace ns { | ||||||
9507 | // void foo(); | ||||||
9508 | // } | ||||||
9509 | // void bar() { | ||||||
9510 | // using ns::foo; | ||||||
9511 | // // CountDeclLevels returns 0 for { 'foo', void() }, | ||||||
9512 | // // 1 for { 'foo', void(int) }, and | ||||||
9513 | // // LLDB_INVALID_DECL_LEVEL for { 'foo', void(int, int) }. | ||||||
9514 | // } | ||||||
9515 | // | ||||||
9516 | // NOTE: Because file statics are at the TranslationUnit along with globals, a | ||||||
9517 | // function at file scope will return the same level as a function at global | ||||||
9518 | // scope. Ideally we'd like to treat the file scope as an additional scope just | ||||||
9519 | // below the global scope. More work needs to be done to recognise that, if | ||||||
9520 | // the decl we're trying to look up is static, we should compare its source | ||||||
9521 | // file with that of the current scope and return a lower number for it. | ||||||
9522 | uint32_t TypeSystemClang::CountDeclLevels(clang::DeclContext *frame_decl_ctx, | ||||||
9523 | clang::DeclContext *child_decl_ctx, | ||||||
9524 | ConstString *child_name, | ||||||
9525 | CompilerType *child_type) { | ||||||
9526 | SymbolFile *symbol_file = GetSymbolFile(); | ||||||
9527 | if (frame_decl_ctx && symbol_file) { | ||||||
9528 | std::set<DeclContext *> searched; | ||||||
9529 | std::multimap<DeclContext *, DeclContext *> search_queue; | ||||||
9530 | |||||||
9531 | // Get the lookup scope for the decl we're trying to find. | ||||||
9532 | clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent(); | ||||||
9533 | |||||||
9534 | // Look for it in our scope's decl context and its parents. | ||||||
9535 | uint32_t level = 0; | ||||||
9536 | for (clang::DeclContext *decl_ctx = frame_decl_ctx; decl_ctx != nullptr; | ||||||
9537 | decl_ctx = decl_ctx->getParent()) { | ||||||
9538 | if (!decl_ctx->isLookupContext()) | ||||||
9539 | continue; | ||||||
9540 | if (decl_ctx == parent_decl_ctx) | ||||||
9541 | // Found it! | ||||||
9542 | return level; | ||||||
9543 | search_queue.insert(std::make_pair(decl_ctx, decl_ctx)); | ||||||
9544 | for (auto it = search_queue.find(decl_ctx); it != search_queue.end(); | ||||||
9545 | it++) { | ||||||
9546 | if (searched.find(it->second) != searched.end()) | ||||||
9547 | continue; | ||||||
9548 | |||||||
9549 | // Currently DWARF has one shared translation unit for all Decls at top | ||||||
9550 | // level, so this would erroneously find using statements anywhere. So | ||||||
9551 | // don't look at the top-level translation unit. | ||||||
9552 | // TODO fix this and add a testcase that depends on it. | ||||||
9553 | |||||||
9554 | if (llvm::isa<clang::TranslationUnitDecl>(it->second)) | ||||||
9555 | continue; | ||||||
9556 | |||||||
9557 | searched.insert(it->second); | ||||||
9558 | symbol_file->ParseDeclsForContext( | ||||||
9559 | CreateDeclContext(it->second)); | ||||||
9560 | |||||||
9561 | for (clang::Decl *child : it->second->decls()) { | ||||||
9562 | if (clang::UsingDirectiveDecl *ud = | ||||||
9563 | llvm::dyn_cast<clang::UsingDirectiveDecl>(child)) { | ||||||
9564 | clang::DeclContext *ns = ud->getNominatedNamespace(); | ||||||
9565 | if (ns == parent_decl_ctx) | ||||||
9566 | // Found it! | ||||||
9567 | return level; | ||||||
9568 | clang::DeclContext *from = ud->getCommonAncestor(); | ||||||
9569 | if (searched.find(ns) == searched.end()) | ||||||
9570 | search_queue.insert(std::make_pair(from, ns)); | ||||||
9571 | } else if (child_name) { | ||||||
9572 | if (clang::UsingDecl *ud = | ||||||
9573 | llvm::dyn_cast<clang::UsingDecl>(child)) { | ||||||
9574 | for (clang::UsingShadowDecl *usd : ud->shadows()) { | ||||||
9575 | clang::Decl *target = usd->getTargetDecl(); | ||||||
9576 | clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(target); | ||||||
9577 | if (!nd) | ||||||
9578 | continue; | ||||||
9579 | // Check names. | ||||||
9580 | IdentifierInfo *ii = nd->getIdentifier(); | ||||||
9581 | if (ii == nullptr || | ||||||
9582 | !ii->getName().equals(child_name->AsCString(nullptr))) | ||||||
9583 | continue; | ||||||
9584 | // Check types, if one was provided. | ||||||
9585 | if (child_type) { | ||||||
9586 | CompilerType clang_type = GetTypeForDecl(nd); | ||||||
9587 | if (!AreTypesSame(clang_type, *child_type, | ||||||
9588 | /*ignore_qualifiers=*/true)) | ||||||
9589 | continue; | ||||||
9590 | } | ||||||
9591 | // Found it! | ||||||
9592 | return level; | ||||||
9593 | } | ||||||
9594 | } | ||||||
9595 | } | ||||||
9596 | } | ||||||
9597 | } | ||||||
9598 | ++level; | ||||||
9599 | } | ||||||
9600 | } | ||||||
9601 | return LLDB_INVALID_DECL_LEVEL(4294967295U); | ||||||
9602 | } | ||||||
9603 | |||||||
9604 | ConstString TypeSystemClang::DeclContextGetName(void *opaque_decl_ctx) { | ||||||
9605 | if (opaque_decl_ctx) { | ||||||
9606 | clang::NamedDecl *named_decl = | ||||||
9607 | llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx); | ||||||
9608 | if (named_decl) | ||||||
9609 | return ConstString(named_decl->getName()); | ||||||
9610 | } | ||||||
9611 | return ConstString(); | ||||||
9612 | } | ||||||
9613 | |||||||
9614 | ConstString | ||||||
9615 | TypeSystemClang::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) { | ||||||
9616 | if (opaque_decl_ctx) { | ||||||
9617 | clang::NamedDecl *named_decl = | ||||||
9618 | llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx); | ||||||
9619 | if (named_decl) | ||||||
9620 | return ConstString(GetTypeNameForDecl(named_decl)); | ||||||
9621 | } | ||||||
9622 | return ConstString(); | ||||||
9623 | } | ||||||
9624 | |||||||
9625 | bool TypeSystemClang::DeclContextIsClassMethod( | ||||||
9626 | void *opaque_decl_ctx, lldb::LanguageType *language_ptr, | ||||||
9627 | bool *is_instance_method_ptr, ConstString *language_object_name_ptr) { | ||||||
9628 | if (opaque_decl_ctx) { | ||||||
9629 | clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; | ||||||
9630 | if (ObjCMethodDecl *objc_method = | ||||||
9631 | llvm::dyn_cast<clang::ObjCMethodDecl>(decl_ctx)) { | ||||||
9632 | if (is_instance_method_ptr) | ||||||
9633 | *is_instance_method_ptr = objc_method->isInstanceMethod(); | ||||||
9634 | if (language_ptr) | ||||||
9635 | *language_ptr = eLanguageTypeObjC; | ||||||
9636 | if (language_object_name_ptr) | ||||||
9637 | language_object_name_ptr->SetCString("self"); | ||||||
9638 | return true; | ||||||
9639 | } else if (CXXMethodDecl *cxx_method = | ||||||
9640 | llvm::dyn_cast<clang::CXXMethodDecl>(decl_ctx)) { | ||||||
9641 | if (is_instance_method_ptr) | ||||||
9642 | *is_instance_method_ptr = cxx_method->isInstance(); | ||||||
9643 | if (language_ptr) | ||||||
9644 | *language_ptr = eLanguageTypeC_plus_plus; | ||||||
9645 | if (language_object_name_ptr) | ||||||
9646 | language_object_name_ptr->SetCString("this"); | ||||||
9647 | return true; | ||||||
9648 | } else if (clang::FunctionDecl *function_decl = | ||||||
9649 | llvm::dyn_cast<clang::FunctionDecl>(decl_ctx)) { | ||||||
9650 | ClangASTMetadata *metadata = GetMetadata(function_decl); | ||||||
9651 | if (metadata && metadata->HasObjectPtr()) { | ||||||
9652 | if (is_instance_method_ptr) | ||||||
9653 | *is_instance_method_ptr = true; | ||||||
9654 | if (language_ptr) | ||||||
9655 | *language_ptr = eLanguageTypeObjC; | ||||||
9656 | if (language_object_name_ptr) | ||||||
9657 | language_object_name_ptr->SetCString(metadata->GetObjectPtrName()); | ||||||
9658 | return true; | ||||||
9659 | } | ||||||
9660 | } | ||||||
9661 | } | ||||||
9662 | return false; | ||||||
9663 | } | ||||||
9664 | |||||||
9665 | bool TypeSystemClang::DeclContextIsContainedInLookup( | ||||||
9666 | void *opaque_decl_ctx, void *other_opaque_decl_ctx) { | ||||||
9667 | auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; | ||||||
9668 | auto *other = (clang::DeclContext *)other_opaque_decl_ctx; | ||||||
9669 | |||||||
9670 | do { | ||||||
9671 | // A decl context always includes its own contents in its lookup. | ||||||
9672 | if (decl_ctx == other) | ||||||
9673 | return true; | ||||||
9674 | |||||||
9675 | // If we have an inline namespace, then the lookup of the parent context | ||||||
9676 | // also includes the inline namespace contents. | ||||||
9677 | } while (other->isInlineNamespace() && (other = other->getParent())); | ||||||
9678 | |||||||
9679 | return false; | ||||||
9680 | } | ||||||
9681 | |||||||
9682 | static bool IsClangDeclContext(const CompilerDeclContext &dc) { | ||||||
9683 | return dc.IsValid() && isa<TypeSystemClang>(dc.GetTypeSystem()); | ||||||
9684 | } | ||||||
9685 | |||||||
9686 | clang::DeclContext * | ||||||
9687 | TypeSystemClang::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) { | ||||||
9688 | if (IsClangDeclContext(dc)) | ||||||
9689 | return (clang::DeclContext *)dc.GetOpaqueDeclContext(); | ||||||
9690 | return nullptr; | ||||||
9691 | } | ||||||
9692 | |||||||
9693 | ObjCMethodDecl * | ||||||
9694 | TypeSystemClang::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) { | ||||||
9695 | if (IsClangDeclContext(dc)) | ||||||
9696 | return llvm::dyn_cast<clang::ObjCMethodDecl>( | ||||||
9697 | (clang::DeclContext *)dc.GetOpaqueDeclContext()); | ||||||
9698 | return nullptr; | ||||||
9699 | } | ||||||
9700 | |||||||
9701 | CXXMethodDecl * | ||||||
9702 | TypeSystemClang::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) { | ||||||
9703 | if (IsClangDeclContext(dc)) | ||||||
9704 | return llvm::dyn_cast<clang::CXXMethodDecl>( | ||||||
9705 | (clang::DeclContext *)dc.GetOpaqueDeclContext()); | ||||||
9706 | return nullptr; | ||||||
9707 | } | ||||||
9708 | |||||||
9709 | clang::FunctionDecl * | ||||||
9710 | TypeSystemClang::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) { | ||||||
9711 | if (IsClangDeclContext(dc)) | ||||||
9712 | return llvm::dyn_cast<clang::FunctionDecl>( | ||||||
9713 | (clang::DeclContext *)dc.GetOpaqueDeclContext()); | ||||||
9714 | return nullptr; | ||||||
9715 | } | ||||||
9716 | |||||||
9717 | clang::NamespaceDecl * | ||||||
9718 | TypeSystemClang::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) { | ||||||
9719 | if (IsClangDeclContext(dc)) | ||||||
9720 | return llvm::dyn_cast<clang::NamespaceDecl>( | ||||||
9721 | (clang::DeclContext *)dc.GetOpaqueDeclContext()); | ||||||
9722 | return nullptr; | ||||||
9723 | } | ||||||
9724 | |||||||
9725 | ClangASTMetadata * | ||||||
9726 | TypeSystemClang::DeclContextGetMetaData(const CompilerDeclContext &dc, | ||||||
9727 | const Decl *object) { | ||||||
9728 | TypeSystemClang *ast = llvm::cast<TypeSystemClang>(dc.GetTypeSystem()); | ||||||
9729 | return ast->GetMetadata(object); | ||||||
9730 | } | ||||||
9731 | |||||||
9732 | clang::ASTContext * | ||||||
9733 | TypeSystemClang::DeclContextGetTypeSystemClang(const CompilerDeclContext &dc) { | ||||||
9734 | TypeSystemClang *ast = | ||||||
9735 | llvm::dyn_cast_or_null<TypeSystemClang>(dc.GetTypeSystem()); | ||||||
9736 | if (ast) | ||||||
9737 | return &ast->getASTContext(); | ||||||
9738 | return nullptr; | ||||||
9739 | } | ||||||
9740 | |||||||
9741 | namespace { | ||||||
9742 | /// A specialized scratch AST used within ScratchTypeSystemClang. | ||||||
9743 | /// These are the ASTs backing the different IsolatedASTKinds. They behave | ||||||
9744 | /// like a normal ScratchTypeSystemClang but they don't own their own | ||||||
9745 | /// persistent storage or target reference. | ||||||
9746 | class SpecializedScratchAST : public TypeSystemClang { | ||||||
9747 | public: | ||||||
9748 | /// \param name The display name of the TypeSystemClang instance. | ||||||
9749 | /// \param triple The triple used for the TypeSystemClang instance. | ||||||
9750 | /// \param ast_source The ClangASTSource that should be used to complete | ||||||
9751 | /// type information. | ||||||
9752 | SpecializedScratchAST(llvm::StringRef name, llvm::Triple triple, | ||||||
9753 | std::unique_ptr<ClangASTSource> ast_source) | ||||||
9754 | : TypeSystemClang(name, triple), | ||||||
9755 | m_scratch_ast_source_up(std::move(ast_source)) { | ||||||
9756 | // Setup the ClangASTSource to complete this AST. | ||||||
9757 | m_scratch_ast_source_up->InstallASTContext(*this); | ||||||
9758 | llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source( | ||||||
9759 | m_scratch_ast_source_up->CreateProxy()); | ||||||
9760 | SetExternalSource(proxy_ast_source); | ||||||
9761 | } | ||||||
9762 | |||||||
9763 | /// The ExternalASTSource that performs lookups and completes types. | ||||||
9764 | std::unique_ptr<ClangASTSource> m_scratch_ast_source_up; | ||||||
9765 | }; | ||||||
9766 | } // namespace | ||||||
9767 | |||||||
9768 | char ScratchTypeSystemClang::ID; | ||||||
9769 | const llvm::NoneType ScratchTypeSystemClang::DefaultAST = llvm::None; | ||||||
9770 | |||||||
9771 | ScratchTypeSystemClang::ScratchTypeSystemClang(Target &target, | ||||||
9772 | llvm::Triple triple) | ||||||
9773 | : TypeSystemClang("scratch ASTContext", triple), m_triple(triple), | ||||||
9774 | m_target_wp(target.shared_from_this()), | ||||||
9775 | m_persistent_variables( | ||||||
9776 | new ClangPersistentVariables(target.shared_from_this())) { | ||||||
9777 | m_scratch_ast_source_up = CreateASTSource(); | ||||||
9778 | m_scratch_ast_source_up->InstallASTContext(*this); | ||||||
9779 | llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source( | ||||||
9780 | m_scratch_ast_source_up->CreateProxy()); | ||||||
9781 | SetExternalSource(proxy_ast_source); | ||||||
9782 | } | ||||||
9783 | |||||||
9784 | void ScratchTypeSystemClang::Finalize() { | ||||||
9785 | TypeSystemClang::Finalize(); | ||||||
9786 | m_scratch_ast_source_up.reset(); | ||||||
9787 | } | ||||||
9788 | |||||||
9789 | TypeSystemClang * | ||||||
9790 | ScratchTypeSystemClang::GetForTarget(Target &target, | ||||||
9791 | llvm::Optional<IsolatedASTKind> ast_kind, | ||||||
9792 | bool create_on_demand) { | ||||||
9793 | auto type_system_or_err = target.GetScratchTypeSystemForLanguage( | ||||||
9794 | lldb::eLanguageTypeC, create_on_demand); | ||||||
9795 | if (auto err = type_system_or_err.takeError()) { | ||||||
9796 | LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet (::lldb_private::LLDBLog::Target)); ::llvm::Error error_private = (std::move(err)); if (log_private && error_private ) { log_private->FormatError(::std::move(error_private), "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , __func__, "Couldn't get scratch TypeSystemClang"); } else :: llvm::consumeError(::std::move(error_private)); } while (0) | ||||||
9797 | std::move(err), "Couldn't get scratch TypeSystemClang")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet (::lldb_private::LLDBLog::Target)); ::llvm::Error error_private = (std::move(err)); if (log_private && error_private ) { log_private->FormatError(::std::move(error_private), "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp" , __func__, "Couldn't get scratch TypeSystemClang"); } else :: llvm::consumeError(::std::move(error_private)); } while (0); | ||||||
9798 | return nullptr; | ||||||
9799 | } | ||||||
9800 | ScratchTypeSystemClang &scratch_ast = | ||||||
9801 | llvm::cast<ScratchTypeSystemClang>(type_system_or_err.get()); | ||||||
9802 | // If no dedicated sub-AST was requested, just return the main AST. | ||||||
9803 | if (ast_kind == DefaultAST) | ||||||
9804 | return &scratch_ast; | ||||||
9805 | // Search the sub-ASTs. | ||||||
9806 | return &scratch_ast.GetIsolatedAST(*ast_kind); | ||||||
9807 | } | ||||||
9808 | |||||||
9809 | /// Returns a human-readable name that uniquely identifiers the sub-AST kind. | ||||||
9810 | static llvm::StringRef | ||||||
9811 | GetNameForIsolatedASTKind(ScratchTypeSystemClang::IsolatedASTKind kind) { | ||||||
9812 | switch (kind) { | ||||||
9813 | case ScratchTypeSystemClang::IsolatedASTKind::CppModules: | ||||||
9814 | return "C++ modules"; | ||||||
9815 | } | ||||||
9816 | llvm_unreachable("Unimplemented IsolatedASTKind?")::llvm::llvm_unreachable_internal("Unimplemented IsolatedASTKind?" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 9816); | ||||||
9817 | } | ||||||
9818 | |||||||
9819 | void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output) { | ||||||
9820 | // First dump the main scratch AST. | ||||||
9821 | output << "State of scratch Clang type system:\n"; | ||||||
9822 | TypeSystemClang::Dump(output); | ||||||
9823 | |||||||
9824 | // Now sort the isolated sub-ASTs. | ||||||
9825 | typedef std::pair<IsolatedASTKey, TypeSystem *> KeyAndTS; | ||||||
9826 | std::vector<KeyAndTS> sorted_typesystems; | ||||||
9827 | for (const auto &a : m_isolated_asts) | ||||||
9828 | sorted_typesystems.emplace_back(a.first, a.second.get()); | ||||||
9829 | llvm::stable_sort(sorted_typesystems, | ||||||
9830 | [](const KeyAndTS &lhs, const KeyAndTS &rhs) { | ||||||
9831 | return lhs.first < rhs.first; | ||||||
9832 | }); | ||||||
9833 | |||||||
9834 | // Dump each sub-AST too. | ||||||
9835 | for (const auto &a : sorted_typesystems) { | ||||||
9836 | IsolatedASTKind kind = | ||||||
9837 | static_cast<ScratchTypeSystemClang::IsolatedASTKind>(a.first); | ||||||
9838 | output << "State of scratch Clang type subsystem " | ||||||
9839 | << GetNameForIsolatedASTKind(kind) << ":\n"; | ||||||
9840 | a.second->Dump(output); | ||||||
9841 | } | ||||||
9842 | } | ||||||
9843 | |||||||
9844 | UserExpression *ScratchTypeSystemClang::GetUserExpression( | ||||||
9845 | llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, | ||||||
9846 | Expression::ResultType desired_type, | ||||||
9847 | const EvaluateExpressionOptions &options, ValueObject *ctx_obj) { | ||||||
9848 | TargetSP target_sp = m_target_wp.lock(); | ||||||
9849 | if (!target_sp) | ||||||
9850 | return nullptr; | ||||||
9851 | |||||||
9852 | return new ClangUserExpression(*target_sp.get(), expr, prefix, language, | ||||||
9853 | desired_type, options, ctx_obj); | ||||||
9854 | } | ||||||
9855 | |||||||
9856 | FunctionCaller *ScratchTypeSystemClang::GetFunctionCaller( | ||||||
9857 | const CompilerType &return_type, const Address &function_address, | ||||||
9858 | const ValueList &arg_value_list, const char *name) { | ||||||
9859 | TargetSP target_sp = m_target_wp.lock(); | ||||||
9860 | if (!target_sp) | ||||||
9861 | return nullptr; | ||||||
9862 | |||||||
9863 | Process *process = target_sp->GetProcessSP().get(); | ||||||
9864 | if (!process) | ||||||
9865 | return nullptr; | ||||||
9866 | |||||||
9867 | return new ClangFunctionCaller(*process, return_type, function_address, | ||||||
9868 | arg_value_list, name); | ||||||
9869 | } | ||||||
9870 | |||||||
9871 | std::unique_ptr<UtilityFunction> | ||||||
9872 | ScratchTypeSystemClang::CreateUtilityFunction(std::string text, | ||||||
9873 | std::string name) { | ||||||
9874 | TargetSP target_sp = m_target_wp.lock(); | ||||||
9875 | if (!target_sp) | ||||||
9876 | return {}; | ||||||
9877 | |||||||
9878 | return std::make_unique<ClangUtilityFunction>( | ||||||
9879 | *target_sp.get(), std::move(text), std::move(name), | ||||||
9880 | target_sp->GetDebugUtilityExpression()); | ||||||
9881 | } | ||||||
9882 | |||||||
9883 | PersistentExpressionState * | ||||||
9884 | ScratchTypeSystemClang::GetPersistentExpressionState() { | ||||||
9885 | return m_persistent_variables.get(); | ||||||
9886 | } | ||||||
9887 | |||||||
9888 | void ScratchTypeSystemClang::ForgetSource(ASTContext *src_ctx, | ||||||
9889 | ClangASTImporter &importer) { | ||||||
9890 | // Remove it as a source from the main AST. | ||||||
9891 | importer.ForgetSource(&getASTContext(), src_ctx); | ||||||
9892 | // Remove it as a source from all created sub-ASTs. | ||||||
9893 | for (const auto &a : m_isolated_asts) | ||||||
9894 | importer.ForgetSource(&a.second->getASTContext(), src_ctx); | ||||||
9895 | } | ||||||
9896 | |||||||
9897 | std::unique_ptr<ClangASTSource> ScratchTypeSystemClang::CreateASTSource() { | ||||||
9898 | return std::make_unique<ClangASTSource>( | ||||||
9899 | m_target_wp.lock()->shared_from_this(), | ||||||
9900 | m_persistent_variables->GetClangASTImporter()); | ||||||
9901 | } | ||||||
9902 | |||||||
9903 | static llvm::StringRef | ||||||
9904 | GetSpecializedASTName(ScratchTypeSystemClang::IsolatedASTKind feature) { | ||||||
9905 | switch (feature) { | ||||||
9906 | case ScratchTypeSystemClang::IsolatedASTKind::CppModules: | ||||||
9907 | return "scratch ASTContext for C++ module types"; | ||||||
9908 | } | ||||||
9909 | llvm_unreachable("Unimplemented ASTFeature kind?")::llvm::llvm_unreachable_internal("Unimplemented ASTFeature kind?" , "lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp", 9909); | ||||||
9910 | } | ||||||
9911 | |||||||
9912 | TypeSystemClang &ScratchTypeSystemClang::GetIsolatedAST( | ||||||
9913 | ScratchTypeSystemClang::IsolatedASTKind feature) { | ||||||
9914 | auto found_ast = m_isolated_asts.find(feature); | ||||||
9915 | if (found_ast != m_isolated_asts.end()) | ||||||
9916 | return *found_ast->second; | ||||||
9917 | |||||||
9918 | // Couldn't find the requested sub-AST, so create it now. | ||||||
9919 | std::unique_ptr<TypeSystemClang> new_ast; | ||||||
9920 | new_ast.reset(new SpecializedScratchAST(GetSpecializedASTName(feature), | ||||||
9921 | m_triple, CreateASTSource())); | ||||||
9922 | m_isolated_asts[feature] = std::move(new_ast); | ||||||
9923 | return *m_isolated_asts[feature]; | ||||||
9924 | } |
1 | //===- DeclBase.h - Base Classes for representing declarations --*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the Decl and DeclContext interfaces. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_CLANG_AST_DECLBASE_H |
14 | #define LLVM_CLANG_AST_DECLBASE_H |
15 | |
16 | #include "clang/AST/ASTDumperUtils.h" |
17 | #include "clang/AST/AttrIterator.h" |
18 | #include "clang/AST/DeclarationName.h" |
19 | #include "clang/Basic/IdentifierTable.h" |
20 | #include "clang/Basic/LLVM.h" |
21 | #include "clang/Basic/SourceLocation.h" |
22 | #include "clang/Basic/Specifiers.h" |
23 | #include "llvm/ADT/ArrayRef.h" |
24 | #include "llvm/ADT/PointerIntPair.h" |
25 | #include "llvm/ADT/PointerUnion.h" |
26 | #include "llvm/ADT/iterator.h" |
27 | #include "llvm/ADT/iterator_range.h" |
28 | #include "llvm/Support/Casting.h" |
29 | #include "llvm/Support/Compiler.h" |
30 | #include "llvm/Support/PrettyStackTrace.h" |
31 | #include "llvm/Support/VersionTuple.h" |
32 | #include <algorithm> |
33 | #include <cassert> |
34 | #include <cstddef> |
35 | #include <iterator> |
36 | #include <string> |
37 | #include <type_traits> |
38 | #include <utility> |
39 | |
40 | namespace clang { |
41 | |
42 | class ASTContext; |
43 | class ASTMutationListener; |
44 | class Attr; |
45 | class BlockDecl; |
46 | class DeclContext; |
47 | class ExternalSourceSymbolAttr; |
48 | class FunctionDecl; |
49 | class FunctionType; |
50 | class IdentifierInfo; |
51 | enum Linkage : unsigned char; |
52 | class LinkageSpecDecl; |
53 | class Module; |
54 | class NamedDecl; |
55 | class ObjCContainerDecl; |
56 | class ObjCMethodDecl; |
57 | struct PrintingPolicy; |
58 | class RecordDecl; |
59 | class SourceManager; |
60 | class Stmt; |
61 | class StoredDeclsMap; |
62 | class TemplateDecl; |
63 | class TemplateParameterList; |
64 | class TranslationUnitDecl; |
65 | class UsingDirectiveDecl; |
66 | |
67 | /// Captures the result of checking the availability of a |
68 | /// declaration. |
69 | enum AvailabilityResult { |
70 | AR_Available = 0, |
71 | AR_NotYetIntroduced, |
72 | AR_Deprecated, |
73 | AR_Unavailable |
74 | }; |
75 | |
76 | /// Decl - This represents one declaration (or definition), e.g. a variable, |
77 | /// typedef, function, struct, etc. |
78 | /// |
79 | /// Note: There are objects tacked on before the *beginning* of Decl |
80 | /// (and its subclasses) in its Decl::operator new(). Proper alignment |
81 | /// of all subclasses (not requiring more than the alignment of Decl) is |
82 | /// asserted in DeclBase.cpp. |
83 | class alignas(8) Decl { |
84 | public: |
85 | /// Lists the kind of concrete classes of Decl. |
86 | enum Kind { |
87 | #define DECL(DERIVED, BASE) DERIVED, |
88 | #define ABSTRACT_DECL(DECL) |
89 | #define DECL_RANGE(BASE, START, END) \ |
90 | first##BASE = START, last##BASE = END, |
91 | #define LAST_DECL_RANGE(BASE, START, END) \ |
92 | first##BASE = START, last##BASE = END |
93 | #include "clang/AST/DeclNodes.inc" |
94 | }; |
95 | |
96 | /// A placeholder type used to construct an empty shell of a |
97 | /// decl-derived type that will be filled in later (e.g., by some |
98 | /// deserialization method). |
99 | struct EmptyShell {}; |
100 | |
101 | /// IdentifierNamespace - The different namespaces in which |
102 | /// declarations may appear. According to C99 6.2.3, there are |
103 | /// four namespaces, labels, tags, members and ordinary |
104 | /// identifiers. C++ describes lookup completely differently: |
105 | /// certain lookups merely "ignore" certain kinds of declarations, |
106 | /// usually based on whether the declaration is of a type, etc. |
107 | /// |
108 | /// These are meant as bitmasks, so that searches in |
109 | /// C++ can look into the "tag" namespace during ordinary lookup. |
110 | /// |
111 | /// Decl currently provides 15 bits of IDNS bits. |
112 | enum IdentifierNamespace { |
113 | /// Labels, declared with 'x:' and referenced with 'goto x'. |
114 | IDNS_Label = 0x0001, |
115 | |
116 | /// Tags, declared with 'struct foo;' and referenced with |
117 | /// 'struct foo'. All tags are also types. This is what |
118 | /// elaborated-type-specifiers look for in C. |
119 | /// This also contains names that conflict with tags in the |
120 | /// same scope but that are otherwise ordinary names (non-type |
121 | /// template parameters and indirect field declarations). |
122 | IDNS_Tag = 0x0002, |
123 | |
124 | /// Types, declared with 'struct foo', typedefs, etc. |
125 | /// This is what elaborated-type-specifiers look for in C++, |
126 | /// but note that it's ill-formed to find a non-tag. |
127 | IDNS_Type = 0x0004, |
128 | |
129 | /// Members, declared with object declarations within tag |
130 | /// definitions. In C, these can only be found by "qualified" |
131 | /// lookup in member expressions. In C++, they're found by |
132 | /// normal lookup. |
133 | IDNS_Member = 0x0008, |
134 | |
135 | /// Namespaces, declared with 'namespace foo {}'. |
136 | /// Lookup for nested-name-specifiers find these. |
137 | IDNS_Namespace = 0x0010, |
138 | |
139 | /// Ordinary names. In C, everything that's not a label, tag, |
140 | /// member, or function-local extern ends up here. |
141 | IDNS_Ordinary = 0x0020, |
142 | |
143 | /// Objective C \@protocol. |
144 | IDNS_ObjCProtocol = 0x0040, |
145 | |
146 | /// This declaration is a friend function. A friend function |
147 | /// declaration is always in this namespace but may also be in |
148 | /// IDNS_Ordinary if it was previously declared. |
149 | IDNS_OrdinaryFriend = 0x0080, |
150 | |
151 | /// This declaration is a friend class. A friend class |
152 | /// declaration is always in this namespace but may also be in |
153 | /// IDNS_Tag|IDNS_Type if it was previously declared. |
154 | IDNS_TagFriend = 0x0100, |
155 | |
156 | /// This declaration is a using declaration. A using declaration |
157 | /// *introduces* a number of other declarations into the current |
158 | /// scope, and those declarations use the IDNS of their targets, |
159 | /// but the actual using declarations go in this namespace. |
160 | IDNS_Using = 0x0200, |
161 | |
162 | /// This declaration is a C++ operator declared in a non-class |
163 | /// context. All such operators are also in IDNS_Ordinary. |
164 | /// C++ lexical operator lookup looks for these. |
165 | IDNS_NonMemberOperator = 0x0400, |
166 | |
167 | /// This declaration is a function-local extern declaration of a |
168 | /// variable or function. This may also be IDNS_Ordinary if it |
169 | /// has been declared outside any function. These act mostly like |
170 | /// invisible friend declarations, but are also visible to unqualified |
171 | /// lookup within the scope of the declaring function. |
172 | IDNS_LocalExtern = 0x0800, |
173 | |
174 | /// This declaration is an OpenMP user defined reduction construction. |
175 | IDNS_OMPReduction = 0x1000, |
176 | |
177 | /// This declaration is an OpenMP user defined mapper. |
178 | IDNS_OMPMapper = 0x2000, |
179 | }; |
180 | |
181 | /// ObjCDeclQualifier - 'Qualifiers' written next to the return and |
182 | /// parameter types in method declarations. Other than remembering |
183 | /// them and mangling them into the method's signature string, these |
184 | /// are ignored by the compiler; they are consumed by certain |
185 | /// remote-messaging frameworks. |
186 | /// |
187 | /// in, inout, and out are mutually exclusive and apply only to |
188 | /// method parameters. bycopy and byref are mutually exclusive and |
189 | /// apply only to method parameters (?). oneway applies only to |
190 | /// results. All of these expect their corresponding parameter to |
191 | /// have a particular type. None of this is currently enforced by |
192 | /// clang. |
193 | /// |
194 | /// This should be kept in sync with ObjCDeclSpec::ObjCDeclQualifier. |
195 | enum ObjCDeclQualifier { |
196 | OBJC_TQ_None = 0x0, |
197 | OBJC_TQ_In = 0x1, |
198 | OBJC_TQ_Inout = 0x2, |
199 | OBJC_TQ_Out = 0x4, |
200 | OBJC_TQ_Bycopy = 0x8, |
201 | OBJC_TQ_Byref = 0x10, |
202 | OBJC_TQ_Oneway = 0x20, |
203 | |
204 | /// The nullability qualifier is set when the nullability of the |
205 | /// result or parameter was expressed via a context-sensitive |
206 | /// keyword. |
207 | OBJC_TQ_CSNullability = 0x40 |
208 | }; |
209 | |
210 | /// The kind of ownership a declaration has, for visibility purposes. |
211 | /// This enumeration is designed such that higher values represent higher |
212 | /// levels of name hiding. |
213 | enum class ModuleOwnershipKind : unsigned { |
214 | /// This declaration is not owned by a module. |
215 | Unowned, |
216 | |
217 | /// This declaration has an owning module, but is globally visible |
218 | /// (typically because its owning module is visible and we know that |
219 | /// modules cannot later become hidden in this compilation). |
220 | /// After serialization and deserialization, this will be converted |
221 | /// to VisibleWhenImported. |
222 | Visible, |
223 | |
224 | /// This declaration has an owning module, and is visible when that |
225 | /// module is imported. |
226 | VisibleWhenImported, |
227 | |
228 | /// This declaration has an owning module, but is only visible to |
229 | /// lookups that occur within that module. |
230 | ModulePrivate |
231 | }; |
232 | |
233 | protected: |
234 | /// The next declaration within the same lexical |
235 | /// DeclContext. These pointers form the linked list that is |
236 | /// traversed via DeclContext's decls_begin()/decls_end(). |
237 | /// |
238 | /// The extra two bits are used for the ModuleOwnershipKind. |
239 | llvm::PointerIntPair<Decl *, 2, ModuleOwnershipKind> NextInContextAndBits; |
240 | |
241 | private: |
242 | friend class DeclContext; |
243 | |
244 | struct MultipleDC { |
245 | DeclContext *SemanticDC; |
246 | DeclContext *LexicalDC; |
247 | }; |
248 | |
249 | /// DeclCtx - Holds either a DeclContext* or a MultipleDC*. |
250 | /// For declarations that don't contain C++ scope specifiers, it contains |
251 | /// the DeclContext where the Decl was declared. |
252 | /// For declarations with C++ scope specifiers, it contains a MultipleDC* |
253 | /// with the context where it semantically belongs (SemanticDC) and the |
254 | /// context where it was lexically declared (LexicalDC). |
255 | /// e.g.: |
256 | /// |
257 | /// namespace A { |
258 | /// void f(); // SemanticDC == LexicalDC == 'namespace A' |
259 | /// } |
260 | /// void A::f(); // SemanticDC == namespace 'A' |
261 | /// // LexicalDC == global namespace |
262 | llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx; |
263 | |
264 | bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); } |
265 | bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); } |
266 | |
267 | MultipleDC *getMultipleDC() const { |
268 | return DeclCtx.get<MultipleDC*>(); |
269 | } |
270 | |
271 | DeclContext *getSemanticDC() const { |
272 | return DeclCtx.get<DeclContext*>(); |
273 | } |
274 | |
275 | /// Loc - The location of this decl. |
276 | SourceLocation Loc; |
277 | |
278 | /// DeclKind - This indicates which class this is. |
279 | unsigned DeclKind : 7; |
280 | |
281 | /// InvalidDecl - This indicates a semantic error occurred. |
282 | unsigned InvalidDecl : 1; |
283 | |
284 | /// HasAttrs - This indicates whether the decl has attributes or not. |
285 | unsigned HasAttrs : 1; |
286 | |
287 | /// Implicit - Whether this declaration was implicitly generated by |
288 | /// the implementation rather than explicitly written by the user. |
289 | unsigned Implicit : 1; |
290 | |
291 | /// Whether this declaration was "used", meaning that a definition is |
292 | /// required. |
293 | unsigned Used : 1; |
294 | |
295 | /// Whether this declaration was "referenced". |
296 | /// The difference with 'Used' is whether the reference appears in a |
297 | /// evaluated context or not, e.g. functions used in uninstantiated templates |
298 | /// are regarded as "referenced" but not "used". |
299 | unsigned Referenced : 1; |
300 | |
301 | /// Whether this declaration is a top-level declaration (function, |
302 | /// global variable, etc.) that is lexically inside an objc container |
303 | /// definition. |
304 | unsigned TopLevelDeclInObjCContainer : 1; |
305 | |
306 | /// Whether statistic collection is enabled. |
307 | static bool StatisticsEnabled; |
308 | |
309 | protected: |
310 | friend class ASTDeclReader; |
311 | friend class ASTDeclWriter; |
312 | friend class ASTNodeImporter; |
313 | friend class ASTReader; |
314 | friend class CXXClassMemberWrapper; |
315 | friend class LinkageComputer; |
316 | template<typename decl_type> friend class Redeclarable; |
317 | |
318 | /// Access - Used by C++ decls for the access specifier. |
319 | // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum |
320 | unsigned Access : 2; |
321 | |
322 | /// Whether this declaration was loaded from an AST file. |
323 | unsigned FromASTFile : 1; |
324 | |
325 | /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. |
326 | unsigned IdentifierNamespace : 14; |
327 | |
328 | /// If 0, we have not computed the linkage of this declaration. |
329 | /// Otherwise, it is the linkage + 1. |
330 | mutable unsigned CacheValidAndLinkage : 3; |
331 | |
332 | /// Allocate memory for a deserialized declaration. |
333 | /// |
334 | /// This routine must be used to allocate memory for any declaration that is |
335 | /// deserialized from a module file. |
336 | /// |
337 | /// \param Size The size of the allocated object. |
338 | /// \param Ctx The context in which we will allocate memory. |
339 | /// \param ID The global ID of the deserialized declaration. |
340 | /// \param Extra The amount of extra space to allocate after the object. |
341 | void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID, |
342 | std::size_t Extra = 0); |
343 | |
344 | /// Allocate memory for a non-deserialized declaration. |
345 | void *operator new(std::size_t Size, const ASTContext &Ctx, |
346 | DeclContext *Parent, std::size_t Extra = 0); |
347 | |
348 | private: |
349 | bool AccessDeclContextCheck() const; |
350 | |
351 | /// Get the module ownership kind to use for a local lexical child of \p DC, |
352 | /// which may be either a local or (rarely) an imported declaration. |
353 | static ModuleOwnershipKind getModuleOwnershipKindForChildOf(DeclContext *DC) { |
354 | if (DC) { |
355 | auto *D = cast<Decl>(DC); |
356 | auto MOK = D->getModuleOwnershipKind(); |
357 | if (MOK != ModuleOwnershipKind::Unowned && |
358 | (!D->isFromASTFile() || D->hasLocalOwningModuleStorage())) |
359 | return MOK; |
360 | // If D is not local and we have no local module storage, then we don't |
361 | // need to track module ownership at all. |
362 | } |
363 | return ModuleOwnershipKind::Unowned; |
364 | } |
365 | |
366 | public: |
367 | Decl() = delete; |
368 | Decl(const Decl&) = delete; |
369 | Decl(Decl &&) = delete; |
370 | Decl &operator=(const Decl&) = delete; |
371 | Decl &operator=(Decl&&) = delete; |
372 | |
373 | protected: |
374 | Decl(Kind DK, DeclContext *DC, SourceLocation L) |
375 | : NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)), |
376 | DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false), |
377 | Implicit(false), Used(false), Referenced(false), |
378 | TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), |
379 | IdentifierNamespace(getIdentifierNamespaceForKind(DK)), |
380 | CacheValidAndLinkage(0) { |
381 | if (StatisticsEnabled) add(DK); |
382 | } |
383 | |
384 | Decl(Kind DK, EmptyShell Empty) |
385 | : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false), |
386 | Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), |
387 | Access(AS_none), FromASTFile(0), |
388 | IdentifierNamespace(getIdentifierNamespaceForKind(DK)), |
389 | CacheValidAndLinkage(0) { |
390 | if (StatisticsEnabled) add(DK); |
391 | } |
392 | |
393 | virtual ~Decl(); |
394 | |
395 | /// Update a potentially out-of-date declaration. |
396 | void updateOutOfDate(IdentifierInfo &II) const; |
397 | |
398 | Linkage getCachedLinkage() const { |
399 | return Linkage(CacheValidAndLinkage - 1); |
400 | } |
401 | |
402 | void setCachedLinkage(Linkage L) const { |
403 | CacheValidAndLinkage = L + 1; |
404 | } |
405 | |
406 | bool hasCachedLinkage() const { |
407 | return CacheValidAndLinkage; |
408 | } |
409 | |
410 | public: |
411 | /// Source range that this declaration covers. |
412 | virtual SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) { |
413 | return SourceRange(getLocation(), getLocation()); |
414 | } |
415 | |
416 | SourceLocation getBeginLoc() const LLVM_READONLY__attribute__((__pure__)) { |
417 | return getSourceRange().getBegin(); |
418 | } |
419 | |
420 | SourceLocation getEndLoc() const LLVM_READONLY__attribute__((__pure__)) { |
421 | return getSourceRange().getEnd(); |
422 | } |
423 | |
424 | SourceLocation getLocation() const { return Loc; } |
425 | void setLocation(SourceLocation L) { Loc = L; } |
426 | |
427 | Kind getKind() const { return static_cast<Kind>(DeclKind); } |
428 | const char *getDeclKindName() const; |
429 | |
430 | Decl *getNextDeclInContext() { return NextInContextAndBits.getPointer(); } |
431 | const Decl *getNextDeclInContext() const {return NextInContextAndBits.getPointer();} |
432 | |
433 | DeclContext *getDeclContext() { |
434 | if (isInSemaDC()) |
435 | return getSemanticDC(); |
436 | return getMultipleDC()->SemanticDC; |
437 | } |
438 | const DeclContext *getDeclContext() const { |
439 | return const_cast<Decl*>(this)->getDeclContext(); |
440 | } |
441 | |
442 | /// Find the innermost non-closure ancestor of this declaration, |
443 | /// walking up through blocks, lambdas, etc. If that ancestor is |
444 | /// not a code context (!isFunctionOrMethod()), returns null. |
445 | /// |
446 | /// A declaration may be its own non-closure context. |
447 | Decl *getNonClosureContext(); |
448 | const Decl *getNonClosureContext() const { |
449 | return const_cast<Decl*>(this)->getNonClosureContext(); |
450 | } |
451 | |
452 | TranslationUnitDecl *getTranslationUnitDecl(); |
453 | const TranslationUnitDecl *getTranslationUnitDecl() const { |
454 | return const_cast<Decl*>(this)->getTranslationUnitDecl(); |
455 | } |
456 | |
457 | bool isInAnonymousNamespace() const; |
458 | |
459 | bool isInStdNamespace() const; |
460 | |
461 | ASTContext &getASTContext() const LLVM_READONLY__attribute__((__pure__)); |
462 | |
463 | /// Helper to get the language options from the ASTContext. |
464 | /// Defined out of line to avoid depending on ASTContext.h. |
465 | const LangOptions &getLangOpts() const LLVM_READONLY__attribute__((__pure__)); |
466 | |
467 | void setAccess(AccessSpecifier AS) { |
468 | Access = AS; |
469 | assert(AccessDeclContextCheck())(static_cast <bool> (AccessDeclContextCheck()) ? void ( 0) : __assert_fail ("AccessDeclContextCheck()", "clang/include/clang/AST/DeclBase.h" , 469, __extension__ __PRETTY_FUNCTION__)); |
470 | } |
471 | |
472 | AccessSpecifier getAccess() const { |
473 | assert(AccessDeclContextCheck())(static_cast <bool> (AccessDeclContextCheck()) ? void ( 0) : __assert_fail ("AccessDeclContextCheck()", "clang/include/clang/AST/DeclBase.h" , 473, __extension__ __PRETTY_FUNCTION__)); |
474 | return AccessSpecifier(Access); |
475 | } |
476 | |
477 | /// Retrieve the access specifier for this declaration, even though |
478 | /// it may not yet have been properly set. |
479 | AccessSpecifier getAccessUnsafe() const { |
480 | return AccessSpecifier(Access); |
481 | } |
482 | |
483 | bool hasAttrs() const { return HasAttrs; } |
484 | |
485 | void setAttrs(const AttrVec& Attrs) { |
486 | return setAttrsImpl(Attrs, getASTContext()); |
487 | } |
488 | |
489 | AttrVec &getAttrs() { |
490 | return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs()); |
491 | } |
492 | |
493 | const AttrVec &getAttrs() const; |
494 | void dropAttrs(); |
495 | void addAttr(Attr *A); |
496 | |
497 | using attr_iterator = AttrVec::const_iterator; |
498 | using attr_range = llvm::iterator_range<attr_iterator>; |
499 | |
500 | attr_range attrs() const { |
501 | return attr_range(attr_begin(), attr_end()); |
502 | } |
503 | |
504 | attr_iterator attr_begin() const { |
505 | return hasAttrs() ? getAttrs().begin() : nullptr; |
506 | } |
507 | attr_iterator attr_end() const { |
508 | return hasAttrs() ? getAttrs().end() : nullptr; |
509 | } |
510 | |
511 | template <typename T> |
512 | void dropAttr() { |
513 | if (!HasAttrs) return; |
514 | |
515 | AttrVec &Vec = getAttrs(); |
516 | llvm::erase_if(Vec, [](Attr *A) { return isa<T>(A); }); |
517 | |
518 | if (Vec.empty()) |
519 | HasAttrs = false; |
520 | } |
521 | |
522 | template <typename T> |
523 | llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const { |
524 | return llvm::make_range(specific_attr_begin<T>(), specific_attr_end<T>()); |
525 | } |
526 | |
527 | template <typename T> |
528 | specific_attr_iterator<T> specific_attr_begin() const { |
529 | return specific_attr_iterator<T>(attr_begin()); |
530 | } |
531 | |
532 | template <typename T> |
533 | specific_attr_iterator<T> specific_attr_end() const { |
534 | return specific_attr_iterator<T>(attr_end()); |
535 | } |
536 | |
537 | template<typename T> T *getAttr() const { |
538 | return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr; |
539 | } |
540 | |
541 | template<typename T> bool hasAttr() const { |
542 | return hasAttrs() && hasSpecificAttr<T>(getAttrs()); |
543 | } |
544 | |
545 | /// getMaxAlignment - return the maximum alignment specified by attributes |
546 | /// on this decl, 0 if there are none. |
547 | unsigned getMaxAlignment() const; |
548 | |
549 | /// setInvalidDecl - Indicates the Decl had a semantic error. This |
550 | /// allows for graceful error recovery. |
551 | void setInvalidDecl(bool Invalid = true); |
552 | bool isInvalidDecl() const { return (bool) InvalidDecl; } |
553 | |
554 | /// isImplicit - Indicates whether the declaration was implicitly |
555 | /// generated by the implementation. If false, this declaration |
556 | /// was written explicitly in the source code. |
557 | bool isImplicit() const { return Implicit; } |
558 | void setImplicit(bool I = true) { Implicit = I; } |
559 | |
560 | /// Whether *any* (re-)declaration of the entity was used, meaning that |
561 | /// a definition is required. |
562 | /// |
563 | /// \param CheckUsedAttr When true, also consider the "used" attribute |
564 | /// (in addition to the "used" bit set by \c setUsed()) when determining |
565 | /// whether the function is used. |
566 | bool isUsed(bool CheckUsedAttr = true) const; |
567 | |
568 | /// Set whether the declaration is used, in the sense of odr-use. |
569 | /// |
570 | /// This should only be used immediately after creating a declaration. |
571 | /// It intentionally doesn't notify any listeners. |
572 | void setIsUsed() { getCanonicalDecl()->Used = true; } |
573 | |
574 | /// Mark the declaration used, in the sense of odr-use. |
575 | /// |
576 | /// This notifies any mutation listeners in addition to setting a bit |
577 | /// indicating the declaration is used. |
578 | void markUsed(ASTContext &C); |
579 | |
580 | /// Whether any declaration of this entity was referenced. |
581 | bool isReferenced() const; |
582 | |
583 | /// Whether this declaration was referenced. This should not be relied |
584 | /// upon for anything other than debugging. |
585 | bool isThisDeclarationReferenced() const { return Referenced; } |
586 | |
587 | void setReferenced(bool R = true) { Referenced = R; } |
588 | |
589 | /// Whether this declaration is a top-level declaration (function, |
590 | /// global variable, etc.) that is lexically inside an objc container |
591 | /// definition. |
592 | bool isTopLevelDeclInObjCContainer() const { |
593 | return TopLevelDeclInObjCContainer; |
594 | } |
595 | |
596 | void setTopLevelDeclInObjCContainer(bool V = true) { |
597 | TopLevelDeclInObjCContainer = V; |
598 | } |
599 | |
600 | /// Looks on this and related declarations for an applicable |
601 | /// external source symbol attribute. |
602 | ExternalSourceSymbolAttr *getExternalSourceSymbolAttr() const; |
603 | |
604 | /// Whether this declaration was marked as being private to the |
605 | /// module in which it was defined. |
606 | bool isModulePrivate() const { |
607 | return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate; |
608 | } |
609 | |
610 | /// Whether this declaration was exported in a lexical context. |
611 | /// e.g.: |
612 | /// |
613 | /// export namespace A { |
614 | /// void f1(); // isInExportDeclContext() == true |
615 | /// } |
616 | /// void A::f1(); // isInExportDeclContext() == false |
617 | /// |
618 | /// namespace B { |
619 | /// void f2(); // isInExportDeclContext() == false |
620 | /// } |
621 | /// export void B::f2(); // isInExportDeclContext() == true |
622 | bool isInExportDeclContext() const; |
623 | |
624 | /// Return true if this declaration has an attribute which acts as |
625 | /// definition of the entity, such as 'alias' or 'ifunc'. |
626 | bool hasDefiningAttr() const; |
627 | |
628 | /// Return this declaration's defining attribute if it has one. |
629 | const Attr *getDefiningAttr() const; |
630 | |
631 | protected: |
632 | /// Specify that this declaration was marked as being private |
633 | /// to the module in which it was defined. |
634 | void setModulePrivate() { |
635 | // The module-private specifier has no effect on unowned declarations. |
636 | // FIXME: We should track this in some way for source fidelity. |
637 | if (getModuleOwnershipKind() == ModuleOwnershipKind::Unowned) |
638 | return; |
639 | setModuleOwnershipKind(ModuleOwnershipKind::ModulePrivate); |
640 | } |
641 | |
642 | public: |
643 | /// Set the FromASTFile flag. This indicates that this declaration |
644 | /// was deserialized and not parsed from source code and enables |
645 | /// features such as module ownership information. |
646 | void setFromASTFile() { |
647 | FromASTFile = true; |
648 | } |
649 | |
650 | /// Set the owning module ID. This may only be called for |
651 | /// deserialized Decls. |
652 | void setOwningModuleID(unsigned ID) { |
653 | assert(isFromASTFile() && "Only works on a deserialized declaration")(static_cast <bool> (isFromASTFile() && "Only works on a deserialized declaration" ) ? void (0) : __assert_fail ("isFromASTFile() && \"Only works on a deserialized declaration\"" , "clang/include/clang/AST/DeclBase.h", 653, __extension__ __PRETTY_FUNCTION__ )); |
654 | *((unsigned*)this - 2) = ID; |
655 | } |
656 | |
657 | public: |
658 | /// Determine the availability of the given declaration. |
659 | /// |
660 | /// This routine will determine the most restrictive availability of |
661 | /// the given declaration (e.g., preferring 'unavailable' to |
662 | /// 'deprecated'). |
663 | /// |
664 | /// \param Message If non-NULL and the result is not \c |
665 | /// AR_Available, will be set to a (possibly empty) message |
666 | /// describing why the declaration has not been introduced, is |
667 | /// deprecated, or is unavailable. |
668 | /// |
669 | /// \param EnclosingVersion The version to compare with. If empty, assume the |
670 | /// deployment target version. |
671 | /// |
672 | /// \param RealizedPlatform If non-NULL and the availability result is found |
673 | /// in an available attribute it will set to the platform which is written in |
674 | /// the available attribute. |
675 | AvailabilityResult |
676 | getAvailability(std::string *Message = nullptr, |
677 | VersionTuple EnclosingVersion = VersionTuple(), |
678 | StringRef *RealizedPlatform = nullptr) const; |
679 | |
680 | /// Retrieve the version of the target platform in which this |
681 | /// declaration was introduced. |
682 | /// |
683 | /// \returns An empty version tuple if this declaration has no 'introduced' |
684 | /// availability attributes, or the version tuple that's specified in the |
685 | /// attribute otherwise. |
686 | VersionTuple getVersionIntroduced() const; |
687 | |
688 | /// Determine whether this declaration is marked 'deprecated'. |
689 | /// |
690 | /// \param Message If non-NULL and the declaration is deprecated, |
691 | /// this will be set to the message describing why the declaration |
692 | /// was deprecated (which may be empty). |
693 | bool isDeprecated(std::string *Message = nullptr) const { |
694 | return getAvailability(Message) == AR_Deprecated; |
695 | } |
696 | |
697 | /// Determine whether this declaration is marked 'unavailable'. |
698 | /// |
699 | /// \param Message If non-NULL and the declaration is unavailable, |
700 | /// this will be set to the message describing why the declaration |
701 | /// was made unavailable (which may be empty). |
702 | bool isUnavailable(std::string *Message = nullptr) const { |
703 | return getAvailability(Message) == AR_Unavailable; |
704 | } |
705 | |
706 | /// Determine whether this is a weak-imported symbol. |
707 | /// |
708 | /// Weak-imported symbols are typically marked with the |
709 | /// 'weak_import' attribute, but may also be marked with an |
710 | /// 'availability' attribute where we're targing a platform prior to |
711 | /// the introduction of this feature. |
712 | bool isWeakImported() const; |
713 | |
714 | /// Determines whether this symbol can be weak-imported, |
715 | /// e.g., whether it would be well-formed to add the weak_import |
716 | /// attribute. |
717 | /// |
718 | /// \param IsDefinition Set to \c true to indicate that this |
719 | /// declaration cannot be weak-imported because it has a definition. |
720 | bool canBeWeakImported(bool &IsDefinition) const; |
721 | |
722 | /// Determine whether this declaration came from an AST file (such as |
723 | /// a precompiled header or module) rather than having been parsed. |
724 | bool isFromASTFile() const { return FromASTFile; } |
725 | |
726 | /// Retrieve the global declaration ID associated with this |
727 | /// declaration, which specifies where this Decl was loaded from. |
728 | unsigned getGlobalID() const { |
729 | if (isFromASTFile()) |
730 | return *((const unsigned*)this - 1); |
731 | return 0; |
732 | } |
733 | |
734 | /// Retrieve the global ID of the module that owns this particular |
735 | /// declaration. |
736 | unsigned getOwningModuleID() const { |
737 | if (isFromASTFile()) |
738 | return *((const unsigned*)this - 2); |
739 | return 0; |
740 | } |
741 | |
742 | private: |
743 | Module *getOwningModuleSlow() const; |
744 | |
745 | protected: |
746 | bool hasLocalOwningModuleStorage() const; |
747 | |
748 | public: |
749 | /// Get the imported owning module, if this decl is from an imported |
750 | /// (non-local) module. |
751 | Module *getImportedOwningModule() const { |
752 | if (!isFromASTFile() || !hasOwningModule()) |
753 | return nullptr; |
754 | |
755 | return getOwningModuleSlow(); |
756 | } |
757 | |
758 | /// Get the local owning module, if known. Returns nullptr if owner is |
759 | /// not yet known or declaration is not from a module. |
760 | Module *getLocalOwningModule() const { |
761 | if (isFromASTFile() || !hasOwningModule()) |
762 | return nullptr; |
763 | |
764 | assert(hasLocalOwningModuleStorage() &&(static_cast <bool> (hasLocalOwningModuleStorage() && "owned local decl but no local module storage") ? void (0) : __assert_fail ("hasLocalOwningModuleStorage() && \"owned local decl but no local module storage\"" , "clang/include/clang/AST/DeclBase.h", 765, __extension__ __PRETTY_FUNCTION__ )) |
765 | "owned local decl but no local module storage")(static_cast <bool> (hasLocalOwningModuleStorage() && "owned local decl but no local module storage") ? void (0) : __assert_fail ("hasLocalOwningModuleStorage() && \"owned local decl but no local module storage\"" , "clang/include/clang/AST/DeclBase.h", 765, __extension__ __PRETTY_FUNCTION__ )); |
766 | return reinterpret_cast<Module *const *>(this)[-1]; |
767 | } |
768 | void setLocalOwningModule(Module *M) { |
769 | assert(!isFromASTFile() && hasOwningModule() &&(static_cast <bool> (!isFromASTFile() && hasOwningModule () && hasLocalOwningModuleStorage() && "should not have a cached owning module" ) ? void (0) : __assert_fail ("!isFromASTFile() && hasOwningModule() && hasLocalOwningModuleStorage() && \"should not have a cached owning module\"" , "clang/include/clang/AST/DeclBase.h", 771, __extension__ __PRETTY_FUNCTION__ )) |
770 | hasLocalOwningModuleStorage() &&(static_cast <bool> (!isFromASTFile() && hasOwningModule () && hasLocalOwningModuleStorage() && "should not have a cached owning module" ) ? void (0) : __assert_fail ("!isFromASTFile() && hasOwningModule() && hasLocalOwningModuleStorage() && \"should not have a cached owning module\"" , "clang/include/clang/AST/DeclBase.h", 771, __extension__ __PRETTY_FUNCTION__ )) |
771 | "should not have a cached owning module")(static_cast <bool> (!isFromASTFile() && hasOwningModule () && hasLocalOwningModuleStorage() && "should not have a cached owning module" ) ? void (0) : __assert_fail ("!isFromASTFile() && hasOwningModule() && hasLocalOwningModuleStorage() && \"should not have a cached owning module\"" , "clang/include/clang/AST/DeclBase.h", 771, __extension__ __PRETTY_FUNCTION__ )); |
772 | reinterpret_cast<Module **>(this)[-1] = M; |
773 | } |
774 | |
775 | /// Is this declaration owned by some module? |
776 | bool hasOwningModule() const { |
777 | return getModuleOwnershipKind() != ModuleOwnershipKind::Unowned; |
778 | } |
779 | |
780 | /// Get the module that owns this declaration (for visibility purposes). |
781 | Module *getOwningModule() const { |
782 | return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule(); |
783 | } |
784 | |
785 | /// Get the module that owns this declaration for linkage purposes. |
786 | /// There only ever is such a module under the C++ Modules TS. |
787 | /// |
788 | /// \param IgnoreLinkage Ignore the linkage of the entity; assume that |
789 | /// all declarations in a global module fragment are unowned. |
790 | Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const; |
791 | |
792 | /// Determine whether this declaration is definitely visible to name lookup, |
793 | /// independent of whether the owning module is visible. |
794 | /// Note: The declaration may be visible even if this returns \c false if the |
795 | /// owning module is visible within the query context. This is a low-level |
796 | /// helper function; most code should be calling Sema::isVisible() instead. |
797 | bool isUnconditionallyVisible() const { |
798 | return (int)getModuleOwnershipKind() <= (int)ModuleOwnershipKind::Visible; |
799 | } |
800 | |
801 | /// Set that this declaration is globally visible, even if it came from a |
802 | /// module that is not visible. |
803 | void setVisibleDespiteOwningModule() { |
804 | if (!isUnconditionallyVisible()) |
805 | setModuleOwnershipKind(ModuleOwnershipKind::Visible); |
806 | } |
807 | |
808 | /// Get the kind of module ownership for this declaration. |
809 | ModuleOwnershipKind getModuleOwnershipKind() const { |
810 | return NextInContextAndBits.getInt(); |
811 | } |
812 | |
813 | /// Set whether this declaration is hidden from name lookup. |
814 | void setModuleOwnershipKind(ModuleOwnershipKind MOK) { |
815 | assert(!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned &&(static_cast <bool> (!(getModuleOwnershipKind() == ModuleOwnershipKind ::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && "no storage available for owning module for this declaration" ) ? void (0) : __assert_fail ("!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && \"no storage available for owning module for this declaration\"" , "clang/include/clang/AST/DeclBase.h", 818, __extension__ __PRETTY_FUNCTION__ )) |
816 | MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() &&(static_cast <bool> (!(getModuleOwnershipKind() == ModuleOwnershipKind ::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && "no storage available for owning module for this declaration" ) ? void (0) : __assert_fail ("!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && \"no storage available for owning module for this declaration\"" , "clang/include/clang/AST/DeclBase.h", 818, __extension__ __PRETTY_FUNCTION__ )) |
817 | !hasLocalOwningModuleStorage()) &&(static_cast <bool> (!(getModuleOwnershipKind() == ModuleOwnershipKind ::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && "no storage available for owning module for this declaration" ) ? void (0) : __assert_fail ("!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && \"no storage available for owning module for this declaration\"" , "clang/include/clang/AST/DeclBase.h", 818, __extension__ __PRETTY_FUNCTION__ )) |
818 | "no storage available for owning module for this declaration")(static_cast <bool> (!(getModuleOwnershipKind() == ModuleOwnershipKind ::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && "no storage available for owning module for this declaration" ) ? void (0) : __assert_fail ("!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && \"no storage available for owning module for this declaration\"" , "clang/include/clang/AST/DeclBase.h", 818, __extension__ __PRETTY_FUNCTION__ )); |
819 | NextInContextAndBits.setInt(MOK); |
820 | } |
821 | |
822 | unsigned getIdentifierNamespace() const { |
823 | return IdentifierNamespace; |
824 | } |
825 | |
826 | bool isInIdentifierNamespace(unsigned NS) const { |
827 | return getIdentifierNamespace() & NS; |
828 | } |
829 | |
830 | static unsigned getIdentifierNamespaceForKind(Kind DK); |
831 | |
832 | bool hasTagIdentifierNamespace() const { |
833 | return isTagIdentifierNamespace(getIdentifierNamespace()); |
834 | } |
835 | |
836 | static bool isTagIdentifierNamespace(unsigned NS) { |
837 | // TagDecls have Tag and Type set and may also have TagFriend. |
838 | return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type); |
839 | } |
840 | |
841 | /// getLexicalDeclContext - The declaration context where this Decl was |
842 | /// lexically declared (LexicalDC). May be different from |
843 | /// getDeclContext() (SemanticDC). |
844 | /// e.g.: |
845 | /// |
846 | /// namespace A { |
847 | /// void f(); // SemanticDC == LexicalDC == 'namespace A' |
848 | /// } |
849 | /// void A::f(); // SemanticDC == namespace 'A' |
850 | /// // LexicalDC == global namespace |
851 | DeclContext *getLexicalDeclContext() { |
852 | if (isInSemaDC()) |
853 | return getSemanticDC(); |
854 | return getMultipleDC()->LexicalDC; |
855 | } |
856 | const DeclContext *getLexicalDeclContext() const { |
857 | return const_cast<Decl*>(this)->getLexicalDeclContext(); |
858 | } |
859 | |
860 | /// Determine whether this declaration is declared out of line (outside its |
861 | /// semantic context). |
862 | virtual bool isOutOfLine() const; |
863 | |
864 | /// setDeclContext - Set both the semantic and lexical DeclContext |
865 | /// to DC. |
866 | void setDeclContext(DeclContext *DC); |
867 | |
868 | void setLexicalDeclContext(DeclContext *DC); |
869 | |
870 | /// Determine whether this declaration is a templated entity (whether it is |
871 | // within the scope of a template parameter). |
872 | bool isTemplated() const; |
873 | |
874 | /// Determine the number of levels of template parameter surrounding this |
875 | /// declaration. |
876 | unsigned getTemplateDepth() const; |
877 | |
878 | /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this |
879 | /// scoped decl is defined outside the current function or method. This is |
880 | /// roughly global variables and functions, but also handles enums (which |
881 | /// could be defined inside or outside a function etc). |
882 | bool isDefinedOutsideFunctionOrMethod() const { |
883 | return getParentFunctionOrMethod() == nullptr; |
884 | } |
885 | |
886 | /// Determine whether a substitution into this declaration would occur as |
887 | /// part of a substitution into a dependent local scope. Such a substitution |
888 | /// transitively substitutes into all constructs nested within this |
889 | /// declaration. |
890 | /// |
891 | /// This recognizes non-defining declarations as well as members of local |
892 | /// classes and lambdas: |
893 | /// \code |
894 | /// template<typename T> void foo() { void bar(); } |
895 | /// template<typename T> void foo2() { class ABC { void bar(); }; } |
896 | /// template<typename T> inline int x = [](){ return 0; }(); |
897 | /// \endcode |
898 | bool isInLocalScopeForInstantiation() const; |
899 | |
900 | /// If this decl is defined inside a function/method/block it returns |
901 | /// the corresponding DeclContext, otherwise it returns null. |
902 | const DeclContext *getParentFunctionOrMethod() const; |
903 | DeclContext *getParentFunctionOrMethod() { |
904 | return const_cast<DeclContext*>( |
905 | const_cast<const Decl*>(this)->getParentFunctionOrMethod()); |
906 | } |
907 | |
908 | /// Retrieves the "canonical" declaration of the given declaration. |
909 | virtual Decl *getCanonicalDecl() { return this; } |
910 | const Decl *getCanonicalDecl() const { |
911 | return const_cast<Decl*>(this)->getCanonicalDecl(); |
912 | } |
913 | |
914 | /// Whether this particular Decl is a canonical one. |
915 | bool isCanonicalDecl() const { return getCanonicalDecl() == this; } |
916 | |
917 | protected: |
918 | /// Returns the next redeclaration or itself if this is the only decl. |
919 | /// |
920 | /// Decl subclasses that can be redeclared should override this method so that |
921 | /// Decl::redecl_iterator can iterate over them. |
922 | virtual Decl *getNextRedeclarationImpl() { return this; } |
923 | |
924 | /// Implementation of getPreviousDecl(), to be overridden by any |
925 | /// subclass that has a redeclaration chain. |
926 | virtual Decl *getPreviousDeclImpl() { return nullptr; } |
927 | |
928 | /// Implementation of getMostRecentDecl(), to be overridden by any |
929 | /// subclass that has a redeclaration chain. |
930 | virtual Decl *getMostRecentDeclImpl() { return this; } |
931 | |
932 | public: |
933 | /// Iterates through all the redeclarations of the same decl. |
934 | class redecl_iterator { |
935 | /// Current - The current declaration. |
936 | Decl *Current = nullptr; |
937 | Decl *Starter; |
938 | |
939 | public: |
940 | using value_type = Decl *; |
941 | using reference = const value_type &; |
942 | using pointer = const value_type *; |
943 | using iterator_category = std::forward_iterator_tag; |
944 | using difference_type = std::ptrdiff_t; |
945 | |
946 | redecl_iterator() = default; |
947 | explicit redecl_iterator(Decl *C) : Current(C), Starter(C) {} |
948 | |
949 | reference operator*() const { return Current; } |
950 | value_type operator->() const { return Current; } |
951 | |
952 | redecl_iterator& operator++() { |
953 | assert(Current && "Advancing while iterator has reached end")(static_cast <bool> (Current && "Advancing while iterator has reached end" ) ? void (0) : __assert_fail ("Current && \"Advancing while iterator has reached end\"" , "clang/include/clang/AST/DeclBase.h", 953, __extension__ __PRETTY_FUNCTION__ )); |
954 | // Get either previous decl or latest decl. |
955 | Decl *Next = Current->getNextRedeclarationImpl(); |
956 | assert(Next && "Should return next redeclaration or itself, never null!")(static_cast <bool> (Next && "Should return next redeclaration or itself, never null!" ) ? void (0) : __assert_fail ("Next && \"Should return next redeclaration or itself, never null!\"" , "clang/include/clang/AST/DeclBase.h", 956, __extension__ __PRETTY_FUNCTION__ )); |
957 | Current = (Next != Starter) ? Next : nullptr; |
958 | return *this; |
959 | } |
960 | |
961 | redecl_iterator operator++(int) { |
962 | redecl_iterator tmp(*this); |
963 | ++(*this); |
964 | return tmp; |
965 | } |
966 | |
967 | friend bool operator==(redecl_iterator x, redecl_iterator y) { |
968 | return x.Current == y.Current; |
969 | } |
970 | |
971 | friend bool operator!=(redecl_iterator x, redecl_iterator y) { |
972 | return x.Current != y.Current; |
973 | } |
974 | }; |
975 | |
976 | using redecl_range = llvm::iterator_range<redecl_iterator>; |
977 | |
978 | /// Returns an iterator range for all the redeclarations of the same |
979 | /// decl. It will iterate at least once (when this decl is the only one). |
980 | redecl_range redecls() const { |
981 | return redecl_range(redecls_begin(), redecls_end()); |
982 | } |
983 | |
984 | redecl_iterator redecls_begin() const { |
985 | return redecl_iterator(const_cast<Decl *>(this)); |
986 | } |
987 | |
988 | redecl_iterator redecls_end() const { return redecl_iterator(); } |
989 | |
990 | /// Retrieve the previous declaration that declares the same entity |
991 | /// as this declaration, or NULL if there is no previous declaration. |
992 | Decl *getPreviousDecl() { return getPreviousDeclImpl(); } |
993 | |
994 | /// Retrieve the previous declaration that declares the same entity |
995 | /// as this declaration, or NULL if there is no previous declaration. |
996 | const Decl *getPreviousDecl() const { |
997 | return const_cast<Decl *>(this)->getPreviousDeclImpl(); |
998 | } |
999 | |
1000 | /// True if this is the first declaration in its redeclaration chain. |
1001 | bool isFirstDecl() const { |
1002 | return getPreviousDecl() == nullptr; |
1003 | } |
1004 | |
1005 | /// Retrieve the most recent declaration that declares the same entity |
1006 | /// as this declaration (which may be this declaration). |
1007 | Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); } |
1008 | |
1009 | /// Retrieve the most recent declaration that declares the same entity |
1010 | /// as this declaration (which may be this declaration). |
1011 | const Decl *getMostRecentDecl() const { |
1012 | return const_cast<Decl *>(this)->getMostRecentDeclImpl(); |
1013 | } |
1014 | |
1015 | /// getBody - If this Decl represents a declaration for a body of code, |
1016 | /// such as a function or method definition, this method returns the |
1017 | /// top-level Stmt* of that body. Otherwise this method returns null. |
1018 | virtual Stmt* getBody() const { return nullptr; } |
1019 | |
1020 | /// Returns true if this \c Decl represents a declaration for a body of |
1021 | /// code, such as a function or method definition. |
1022 | /// Note that \c hasBody can also return true if any redeclaration of this |
1023 | /// \c Decl represents a declaration for a body of code. |
1024 | virtual bool hasBody() const { return getBody() != nullptr; } |
1025 | |
1026 | /// getBodyRBrace - Gets the right brace of the body, if a body exists. |
1027 | /// This works whether the body is a CompoundStmt or a CXXTryStmt. |
1028 | SourceLocation getBodyRBrace() const; |
1029 | |
1030 | // global temp stats (until we have a per-module visitor) |
1031 | static void add(Kind k); |
1032 | static void EnableStatistics(); |
1033 | static void PrintStats(); |
1034 | |
1035 | /// isTemplateParameter - Determines whether this declaration is a |
1036 | /// template parameter. |
1037 | bool isTemplateParameter() const; |
1038 | |
1039 | /// isTemplateParameter - Determines whether this declaration is a |
1040 | /// template parameter pack. |
1041 | bool isTemplateParameterPack() const; |
1042 | |
1043 | /// Whether this declaration is a parameter pack. |
1044 | bool isParameterPack() const; |
1045 | |
1046 | /// returns true if this declaration is a template |
1047 | bool isTemplateDecl() const; |
1048 | |
1049 | /// Whether this declaration is a function or function template. |
1050 | bool isFunctionOrFunctionTemplate() const { |
1051 | return (DeclKind >= Decl::firstFunction && |
1052 | DeclKind <= Decl::lastFunction) || |
1053 | DeclKind == FunctionTemplate; |
1054 | } |
1055 | |
1056 | /// If this is a declaration that describes some template, this |
1057 | /// method returns that template declaration. |
1058 | /// |
1059 | /// Note that this returns nullptr for partial specializations, because they |
1060 | /// are not modeled as TemplateDecls. Use getDescribedTemplateParams to handle |
1061 | /// those cases. |
1062 | TemplateDecl *getDescribedTemplate() const; |
1063 | |
1064 | /// If this is a declaration that describes some template or partial |
1065 | /// specialization, this returns the corresponding template parameter list. |
1066 | const TemplateParameterList *getDescribedTemplateParams() const; |
1067 | |
1068 | /// Returns the function itself, or the templated function if this is a |
1069 | /// function template. |
1070 | FunctionDecl *getAsFunction() LLVM_READONLY__attribute__((__pure__)); |
1071 | |
1072 | const FunctionDecl *getAsFunction() const { |
1073 | return const_cast<Decl *>(this)->getAsFunction(); |
1074 | } |
1075 | |
1076 | /// Changes the namespace of this declaration to reflect that it's |
1077 | /// a function-local extern declaration. |
1078 | /// |
1079 | /// These declarations appear in the lexical context of the extern |
1080 | /// declaration, but in the semantic context of the enclosing namespace |
1081 | /// scope. |
1082 | void setLocalExternDecl() { |
1083 | Decl *Prev = getPreviousDecl(); |
1084 | IdentifierNamespace &= ~IDNS_Ordinary; |
1085 | |
1086 | // It's OK for the declaration to still have the "invisible friend" flag or |
1087 | // the "conflicts with tag declarations in this scope" flag for the outer |
1088 | // scope. |
1089 | assert((IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 &&(static_cast <bool> ((IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 && "namespace is not ordinary") ? void (0) : __assert_fail ("(IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 && \"namespace is not ordinary\"" , "clang/include/clang/AST/DeclBase.h", 1090, __extension__ __PRETTY_FUNCTION__ )) |
1090 | "namespace is not ordinary")(static_cast <bool> ((IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 && "namespace is not ordinary") ? void (0) : __assert_fail ("(IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 && \"namespace is not ordinary\"" , "clang/include/clang/AST/DeclBase.h", 1090, __extension__ __PRETTY_FUNCTION__ )); |
1091 | |
1092 | IdentifierNamespace |= IDNS_LocalExtern; |
1093 | if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary) |
1094 | IdentifierNamespace |= IDNS_Ordinary; |
1095 | } |
1096 | |
1097 | /// Determine whether this is a block-scope declaration with linkage. |
1098 | /// This will either be a local variable declaration declared 'extern', or a |
1099 | /// local function declaration. |
1100 | bool isLocalExternDecl() { |
1101 | return IdentifierNamespace & IDNS_LocalExtern; |
1102 | } |
1103 | |
1104 | /// Changes the namespace of this declaration to reflect that it's |
1105 | /// the object of a friend declaration. |
1106 | /// |
1107 | /// These declarations appear in the lexical context of the friending |
1108 | /// class, but in the semantic context of the actual entity. This property |
1109 | /// applies only to a specific decl object; other redeclarations of the |
1110 | /// same entity may not (and probably don't) share this property. |
1111 | void setObjectOfFriendDecl(bool PerformFriendInjection = false) { |
1112 | unsigned OldNS = IdentifierNamespace; |
1113 | assert((OldNS & (IDNS_Tag | IDNS_Ordinary |(static_cast <bool> ((OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator )) && "namespace includes neither ordinary nor tag") ? void (0) : __assert_fail ("(OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes neither ordinary nor tag\"" , "clang/include/clang/AST/DeclBase.h", 1116, __extension__ __PRETTY_FUNCTION__ )) |
1114 | IDNS_TagFriend | IDNS_OrdinaryFriend |(static_cast <bool> ((OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator )) && "namespace includes neither ordinary nor tag") ? void (0) : __assert_fail ("(OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes neither ordinary nor tag\"" , "clang/include/clang/AST/DeclBase.h", 1116, __extension__ __PRETTY_FUNCTION__ )) |
1115 | IDNS_LocalExtern | IDNS_NonMemberOperator)) &&(static_cast <bool> ((OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator )) && "namespace includes neither ordinary nor tag") ? void (0) : __assert_fail ("(OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes neither ordinary nor tag\"" , "clang/include/clang/AST/DeclBase.h", 1116, __extension__ __PRETTY_FUNCTION__ )) |
1116 | "namespace includes neither ordinary nor tag")(static_cast <bool> ((OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator )) && "namespace includes neither ordinary nor tag") ? void (0) : __assert_fail ("(OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes neither ordinary nor tag\"" , "clang/include/clang/AST/DeclBase.h", 1116, __extension__ __PRETTY_FUNCTION__ )); |
1117 | assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |(static_cast <bool> (!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && "namespace includes other than ordinary or tag" ) ? void (0) : __assert_fail ("!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes other than ordinary or tag\"" , "clang/include/clang/AST/DeclBase.h", 1120, __extension__ __PRETTY_FUNCTION__ )) |
1118 | IDNS_TagFriend | IDNS_OrdinaryFriend |(static_cast <bool> (!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && "namespace includes other than ordinary or tag" ) ? void (0) : __assert_fail ("!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes other than ordinary or tag\"" , "clang/include/clang/AST/DeclBase.h", 1120, __extension__ __PRETTY_FUNCTION__ )) |
1119 | IDNS_LocalExtern | IDNS_NonMemberOperator)) &&(static_cast <bool> (!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && "namespace includes other than ordinary or tag" ) ? void (0) : __assert_fail ("!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes other than ordinary or tag\"" , "clang/include/clang/AST/DeclBase.h", 1120, __extension__ __PRETTY_FUNCTION__ )) |
1120 | "namespace includes other than ordinary or tag")(static_cast <bool> (!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && "namespace includes other than ordinary or tag" ) ? void (0) : __assert_fail ("!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes other than ordinary or tag\"" , "clang/include/clang/AST/DeclBase.h", 1120, __extension__ __PRETTY_FUNCTION__ )); |
1121 | |
1122 | Decl *Prev = getPreviousDecl(); |
1123 | IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type); |
1124 | |
1125 | if (OldNS & (IDNS_Tag | IDNS_TagFriend)) { |
1126 | IdentifierNamespace |= IDNS_TagFriend; |
1127 | if (PerformFriendInjection || |
1128 | (Prev && Prev->getIdentifierNamespace() & IDNS_Tag)) |
1129 | IdentifierNamespace |= IDNS_Tag | IDNS_Type; |
1130 | } |
1131 | |
1132 | if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | |
1133 | IDNS_LocalExtern | IDNS_NonMemberOperator)) { |
1134 | IdentifierNamespace |= IDNS_OrdinaryFriend; |
1135 | if (PerformFriendInjection || |
1136 | (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)) |
1137 | IdentifierNamespace |= IDNS_Ordinary; |
1138 | } |
1139 | } |
1140 | |
1141 | enum FriendObjectKind { |
1142 | FOK_None, ///< Not a friend object. |
1143 | FOK_Declared, ///< A friend of a previously-declared entity. |
1144 | FOK_Undeclared ///< A friend of a previously-undeclared entity. |
1145 | }; |
1146 | |
1147 | /// Determines whether this declaration is the object of a |
1148 | /// friend declaration and, if so, what kind. |
1149 | /// |
1150 | /// There is currently no direct way to find the associated FriendDecl. |
1151 | FriendObjectKind getFriendObjectKind() const { |
1152 | unsigned mask = |
1153 | (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend)); |
1154 | if (!mask) return FOK_None; |
1155 | return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? FOK_Declared |
1156 | : FOK_Undeclared); |
1157 | } |
1158 | |
1159 | /// Specifies that this declaration is a C++ overloaded non-member. |
1160 | void setNonMemberOperator() { |
1161 | assert(getKind() == Function || getKind() == FunctionTemplate)(static_cast <bool> (getKind() == Function || getKind() == FunctionTemplate) ? void (0) : __assert_fail ("getKind() == Function || getKind() == FunctionTemplate" , "clang/include/clang/AST/DeclBase.h", 1161, __extension__ __PRETTY_FUNCTION__ )); |
1162 | assert((IdentifierNamespace & IDNS_Ordinary) &&(static_cast <bool> ((IdentifierNamespace & IDNS_Ordinary ) && "visible non-member operators should be in ordinary namespace" ) ? void (0) : __assert_fail ("(IdentifierNamespace & IDNS_Ordinary) && \"visible non-member operators should be in ordinary namespace\"" , "clang/include/clang/AST/DeclBase.h", 1163, __extension__ __PRETTY_FUNCTION__ )) |
1163 | "visible non-member operators should be in ordinary namespace")(static_cast <bool> ((IdentifierNamespace & IDNS_Ordinary ) && "visible non-member operators should be in ordinary namespace" ) ? void (0) : __assert_fail ("(IdentifierNamespace & IDNS_Ordinary) && \"visible non-member operators should be in ordinary namespace\"" , "clang/include/clang/AST/DeclBase.h", 1163, __extension__ __PRETTY_FUNCTION__ )); |
1164 | IdentifierNamespace |= IDNS_NonMemberOperator; |
1165 | } |
1166 | |
1167 | static bool classofKind(Kind K) { return true; } |
1168 | static DeclContext *castToDeclContext(const Decl *); |
1169 | static Decl *castFromDeclContext(const DeclContext *); |
1170 | |
1171 | void print(raw_ostream &Out, unsigned Indentation = 0, |
1172 | bool PrintInstantiation = false) const; |
1173 | void print(raw_ostream &Out, const PrintingPolicy &Policy, |
1174 | unsigned Indentation = 0, bool PrintInstantiation = false) const; |
1175 | static void printGroup(Decl** Begin, unsigned NumDecls, |
1176 | raw_ostream &Out, const PrintingPolicy &Policy, |
1177 | unsigned Indentation = 0); |
1178 | |
1179 | // Debuggers don't usually respect default arguments. |
1180 | void dump() const; |
1181 | |
1182 | // Same as dump(), but forces color printing. |
1183 | void dumpColor() const; |
1184 | |
1185 | void dump(raw_ostream &Out, bool Deserialize = false, |
1186 | ASTDumpOutputFormat OutputFormat = ADOF_Default) const; |
1187 | |
1188 | /// \return Unique reproducible object identifier |
1189 | int64_t getID() const; |
1190 | |
1191 | /// Looks through the Decl's underlying type to extract a FunctionType |
1192 | /// when possible. Will return null if the type underlying the Decl does not |
1193 | /// have a FunctionType. |
1194 | const FunctionType *getFunctionType(bool BlocksToo = true) const; |
1195 | |
1196 | private: |
1197 | void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx); |
1198 | void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, |
1199 | ASTContext &Ctx); |
1200 | |
1201 | protected: |
1202 | ASTMutationListener *getASTMutationListener() const; |
1203 | }; |
1204 | |
1205 | /// Determine whether two declarations declare the same entity. |
1206 | inline bool declaresSameEntity(const Decl *D1, const Decl *D2) { |
1207 | if (!D1 || !D2) |
1208 | return false; |
1209 | |
1210 | if (D1 == D2) |
1211 | return true; |
1212 | |
1213 | return D1->getCanonicalDecl() == D2->getCanonicalDecl(); |
1214 | } |
1215 | |
1216 | /// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when |
1217 | /// doing something to a specific decl. |
1218 | class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry { |
1219 | const Decl *TheDecl; |
1220 | SourceLocation Loc; |
1221 | SourceManager &SM; |
1222 | const char *Message; |
1223 | |
1224 | public: |
1225 | PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L, |
1226 | SourceManager &sm, const char *Msg) |
1227 | : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} |
1228 | |
1229 | void print(raw_ostream &OS) const override; |
1230 | }; |
1231 | } // namespace clang |
1232 | |
1233 | // Required to determine the layout of the PointerUnion<NamedDecl*> before |
1234 | // seeing the NamedDecl definition being first used in DeclListNode::operator*. |
1235 | namespace llvm { |
1236 | template <> struct PointerLikeTypeTraits<::clang::NamedDecl *> { |
1237 | static inline void *getAsVoidPointer(::clang::NamedDecl *P) { return P; } |
1238 | static inline ::clang::NamedDecl *getFromVoidPointer(void *P) { |
1239 | return static_cast<::clang::NamedDecl *>(P); |
1240 | } |
1241 | static constexpr int NumLowBitsAvailable = 3; |
1242 | }; |
1243 | } |
1244 | |
1245 | namespace clang { |
1246 | /// A list storing NamedDecls in the lookup tables. |
1247 | class DeclListNode { |
1248 | friend class ASTContext; // allocate, deallocate nodes. |
1249 | friend class StoredDeclsList; |
1250 | public: |
1251 | using Decls = llvm::PointerUnion<NamedDecl*, DeclListNode*>; |
1252 | class iterator { |
1253 | friend class DeclContextLookupResult; |
1254 | friend class StoredDeclsList; |
1255 | |
1256 | Decls Ptr; |
1257 | iterator(Decls Node) : Ptr(Node) { } |
1258 | public: |
1259 | using difference_type = ptrdiff_t; |
1260 | using value_type = NamedDecl*; |
1261 | using pointer = void; |
1262 | using reference = value_type; |
1263 | using iterator_category = std::forward_iterator_tag; |
1264 | |
1265 | iterator() = default; |
1266 | |
1267 | reference operator*() const { |
1268 | assert(Ptr && "dereferencing end() iterator")(static_cast <bool> (Ptr && "dereferencing end() iterator" ) ? void (0) : __assert_fail ("Ptr && \"dereferencing end() iterator\"" , "clang/include/clang/AST/DeclBase.h", 1268, __extension__ __PRETTY_FUNCTION__ )); |
1269 | if (DeclListNode *CurNode = Ptr.dyn_cast<DeclListNode*>()) |
1270 | return CurNode->D; |
1271 | return Ptr.get<NamedDecl*>(); |
1272 | } |
1273 | void operator->() const { } // Unsupported. |
1274 | bool operator==(const iterator &X) const { return Ptr == X.Ptr; } |
1275 | bool operator!=(const iterator &X) const { return Ptr != X.Ptr; } |
1276 | inline iterator &operator++() { // ++It |
1277 | assert(!Ptr.isNull() && "Advancing empty iterator")(static_cast <bool> (!Ptr.isNull() && "Advancing empty iterator" ) ? void (0) : __assert_fail ("!Ptr.isNull() && \"Advancing empty iterator\"" , "clang/include/clang/AST/DeclBase.h", 1277, __extension__ __PRETTY_FUNCTION__ )); |
1278 | |
1279 | if (DeclListNode *CurNode = Ptr.dyn_cast<DeclListNode*>()) |
1280 | Ptr = CurNode->Rest; |
1281 | else |
1282 | Ptr = nullptr; |
1283 | return *this; |
1284 | } |
1285 | iterator operator++(int) { // It++ |
1286 | iterator temp = *this; |
1287 | ++(*this); |
1288 | return temp; |
1289 | } |
1290 | // Enables the pattern for (iterator I =..., E = I.end(); I != E; ++I) |
1291 | iterator end() { return iterator(); } |
1292 | }; |
1293 | private: |
1294 | NamedDecl *D = nullptr; |
1295 | Decls Rest = nullptr; |
1296 | DeclListNode(NamedDecl *ND) : D(ND) {} |
1297 | }; |
1298 | |
1299 | /// The results of name lookup within a DeclContext. |
1300 | class DeclContextLookupResult { |
1301 | using Decls = DeclListNode::Decls; |
1302 | |
1303 | /// When in collection form, this is what the Data pointer points to. |
1304 | Decls Result; |
1305 | |
1306 | public: |
1307 | DeclContextLookupResult() = default; |
1308 | DeclContextLookupResult(Decls Result) : Result(Result) {} |
1309 | |
1310 | using iterator = DeclListNode::iterator; |
1311 | using const_iterator = iterator; |
1312 | using reference = iterator::reference; |
1313 | |
1314 | iterator begin() { return iterator(Result); } |
1315 | iterator end() { return iterator(); } |
1316 | const_iterator begin() const { |
1317 | return const_cast<DeclContextLookupResult*>(this)->begin(); |
1318 | } |
1319 | const_iterator end() const { return iterator(); } |
1320 | |
1321 | bool empty() const { return Result.isNull(); } |
1322 | bool isSingleResult() const { return Result.dyn_cast<NamedDecl*>(); } |
1323 | reference front() const { return *begin(); } |
1324 | |
1325 | // Find the first declaration of the given type in the list. Note that this |
1326 | // is not in general the earliest-declared declaration, and should only be |
1327 | // used when it's not possible for there to be more than one match or where |
1328 | // it doesn't matter which one is found. |
1329 | template<class T> T *find_first() const { |
1330 | for (auto *D : *this) |
1331 | if (T *Decl = dyn_cast<T>(D)) |
1332 | return Decl; |
1333 | |
1334 | return nullptr; |
1335 | } |
1336 | }; |
1337 | |
1338 | /// DeclContext - This is used only as base class of specific decl types that |
1339 | /// can act as declaration contexts. These decls are (only the top classes |
1340 | /// that directly derive from DeclContext are mentioned, not their subclasses): |
1341 | /// |
1342 | /// TranslationUnitDecl |
1343 | /// ExternCContext |
1344 | /// NamespaceDecl |
1345 | /// TagDecl |
1346 | /// OMPDeclareReductionDecl |
1347 | /// OMPDeclareMapperDecl |
1348 | /// FunctionDecl |
1349 | /// ObjCMethodDecl |
1350 | /// ObjCContainerDecl |
1351 | /// LinkageSpecDecl |
1352 | /// ExportDecl |
1353 | /// BlockDecl |
1354 | /// CapturedDecl |
1355 | class DeclContext { |
1356 | /// For makeDeclVisibleInContextImpl |
1357 | friend class ASTDeclReader; |
1358 | /// For reconcileExternalVisibleStorage, CreateStoredDeclsMap, |
1359 | /// hasNeedToReconcileExternalVisibleStorage |
1360 | friend class ExternalASTSource; |
1361 | /// For CreateStoredDeclsMap |
1362 | friend class DependentDiagnostic; |
1363 | /// For hasNeedToReconcileExternalVisibleStorage, |
1364 | /// hasLazyLocalLexicalLookups, hasLazyExternalLexicalLookups |
1365 | friend class ASTWriter; |
1366 | |
1367 | // We use uint64_t in the bit-fields below since some bit-fields |
1368 | // cross the unsigned boundary and this breaks the packing. |
1369 | |
1370 | /// Stores the bits used by DeclContext. |
1371 | /// If modified NumDeclContextBit, the ctor of DeclContext and the accessor |
1372 | /// methods in DeclContext should be updated appropriately. |
1373 | class DeclContextBitfields { |
1374 | friend class DeclContext; |
1375 | /// DeclKind - This indicates which class this is. |
1376 | uint64_t DeclKind : 7; |
1377 | |
1378 | /// Whether this declaration context also has some external |
1379 | /// storage that contains additional declarations that are lexically |
1380 | /// part of this context. |
1381 | mutable uint64_t ExternalLexicalStorage : 1; |
1382 | |
1383 | /// Whether this declaration context also has some external |
1384 | /// storage that contains additional declarations that are visible |
1385 | /// in this context. |
1386 | mutable uint64_t ExternalVisibleStorage : 1; |
1387 | |
1388 | /// Whether this declaration context has had externally visible |
1389 | /// storage added since the last lookup. In this case, \c LookupPtr's |
1390 | /// invariant may not hold and needs to be fixed before we perform |
1391 | /// another lookup. |
1392 | mutable uint64_t NeedToReconcileExternalVisibleStorage : 1; |
1393 | |
1394 | /// If \c true, this context may have local lexical declarations |
1395 | /// that are missing from the lookup table. |
1396 | mutable uint64_t HasLazyLocalLexicalLookups : 1; |
1397 | |
1398 | /// If \c true, the external source may have lexical declarations |
1399 | /// that are missing from the lookup table. |
1400 | mutable uint64_t HasLazyExternalLexicalLookups : 1; |
1401 | |
1402 | /// If \c true, lookups should only return identifier from |
1403 | /// DeclContext scope (for example TranslationUnit). Used in |
1404 | /// LookupQualifiedName() |
1405 | mutable uint64_t UseQualifiedLookup : 1; |
1406 | }; |
1407 | |
1408 | /// Number of bits in DeclContextBitfields. |
1409 | enum { NumDeclContextBits = 13 }; |
1410 | |
1411 | /// Stores the bits used by TagDecl. |
1412 | /// If modified NumTagDeclBits and the accessor |
1413 | /// methods in TagDecl should be updated appropriately. |
1414 | class TagDeclBitfields { |
1415 | friend class TagDecl; |
1416 | /// For the bits in DeclContextBitfields |
1417 | uint64_t : NumDeclContextBits; |
1418 | |
1419 | /// The TagKind enum. |
1420 | uint64_t TagDeclKind : 3; |
1421 | |
1422 | /// True if this is a definition ("struct foo {};"), false if it is a |
1423 | /// declaration ("struct foo;"). It is not considered a definition |
1424 | /// until the definition has been fully processed. |
1425 | uint64_t IsCompleteDefinition : 1; |
1426 | |
1427 | /// True if this is currently being defined. |
1428 | uint64_t IsBeingDefined : 1; |
1429 | |
1430 | /// True if this tag declaration is "embedded" (i.e., defined or declared |
1431 | /// for the very first time) in the syntax of a declarator. |
1432 | uint64_t IsEmbeddedInDeclarator : 1; |
1433 | |
1434 | /// True if this tag is free standing, e.g. "struct foo;". |
1435 | uint64_t IsFreeStanding : 1; |
1436 | |
1437 | /// Indicates whether it is possible for declarations of this kind |
1438 | /// to have an out-of-date definition. |
1439 | /// |
1440 | /// This option is only enabled when modules are enabled. |
1441 | uint64_t MayHaveOutOfDateDef : 1; |
1442 | |
1443 | /// Has the full definition of this type been required by a use somewhere in |
1444 | /// the TU. |
1445 | uint64_t IsCompleteDefinitionRequired : 1; |
1446 | }; |
1447 | |
1448 | /// Number of non-inherited bits in TagDeclBitfields. |
1449 | enum { NumTagDeclBits = 9 }; |
1450 | |
1451 | /// Stores the bits used by EnumDecl. |
1452 | /// If modified NumEnumDeclBit and the accessor |
1453 | /// methods in EnumDecl should be updated appropriately. |
1454 | class EnumDeclBitfields { |
1455 | friend class EnumDecl; |
1456 | /// For the bits in DeclContextBitfields. |
1457 | uint64_t : NumDeclContextBits; |
1458 | /// For the bits in TagDeclBitfields. |
1459 | uint64_t : NumTagDeclBits; |
1460 | |
1461 | /// Width in bits required to store all the non-negative |
1462 | /// enumerators of this enum. |
1463 | uint64_t NumPositiveBits : 8; |
1464 | |
1465 | /// Width in bits required to store all the negative |
1466 | /// enumerators of this enum. |
1467 | uint64_t NumNegativeBits : 8; |
1468 | |
1469 | /// True if this tag declaration is a scoped enumeration. Only |
1470 | /// possible in C++11 mode. |
1471 | uint64_t IsScoped : 1; |
1472 | |
1473 | /// If this tag declaration is a scoped enum, |
1474 | /// then this is true if the scoped enum was declared using the class |
1475 | /// tag, false if it was declared with the struct tag. No meaning is |
1476 | /// associated if this tag declaration is not a scoped enum. |
1477 | uint64_t IsScopedUsingClassTag : 1; |
1478 | |
1479 | /// True if this is an enumeration with fixed underlying type. Only |
1480 | /// possible in C++11, Microsoft extensions, or Objective C mode. |
1481 | uint64_t IsFixed : 1; |
1482 | |
1483 | /// True if a valid hash is stored in ODRHash. |
1484 | uint64_t HasODRHash : 1; |
1485 | }; |
1486 | |
1487 | /// Number of non-inherited bits in EnumDeclBitfields. |
1488 | enum { NumEnumDeclBits = 20 }; |
1489 | |
1490 | /// Stores the bits used by RecordDecl. |
1491 | /// If modified NumRecordDeclBits and the accessor |
1492 | /// methods in RecordDecl should be updated appropriately. |
1493 | class RecordDeclBitfields { |
1494 | friend class RecordDecl; |
1495 | /// For the bits in DeclContextBitfields. |
1496 | uint64_t : NumDeclContextBits; |
1497 | /// For the bits in TagDeclBitfields. |
1498 | uint64_t : NumTagDeclBits; |
1499 | |
1500 | /// This is true if this struct ends with a flexible |
1501 | /// array member (e.g. int X[]) or if this union contains a struct that does. |
1502 | /// If so, this cannot be contained in arrays or other structs as a member. |
1503 | uint64_t HasFlexibleArrayMember : 1; |
1504 | |
1505 | /// Whether this is the type of an anonymous struct or union. |
1506 | uint64_t AnonymousStructOrUnion : 1; |
1507 | |
1508 | /// This is true if this struct has at least one member |
1509 | /// containing an Objective-C object pointer type. |
1510 | uint64_t HasObjectMember : 1; |
1511 | |
1512 | /// This is true if struct has at least one member of |
1513 | /// 'volatile' type. |
1514 | uint64_t HasVolatileMember : 1; |
1515 | |
1516 | /// Whether the field declarations of this record have been loaded |
1517 | /// from external storage. To avoid unnecessary deserialization of |
1518 | /// methods/nested types we allow deserialization of just the fields |
1519 | /// when needed. |
1520 | mutable uint64_t LoadedFieldsFromExternalStorage : 1; |
1521 | |
1522 | /// Basic properties of non-trivial C structs. |
1523 | uint64_t NonTrivialToPrimitiveDefaultInitialize : 1; |
1524 | uint64_t NonTrivialToPrimitiveCopy : 1; |
1525 | uint64_t NonTrivialToPrimitiveDestroy : 1; |
1526 | |
1527 | /// The following bits indicate whether this is or contains a C union that |
1528 | /// is non-trivial to default-initialize, destruct, or copy. These bits |
1529 | /// imply the associated basic non-triviality predicates declared above. |
1530 | uint64_t HasNonTrivialToPrimitiveDefaultInitializeCUnion : 1; |
1531 | uint64_t HasNonTrivialToPrimitiveDestructCUnion : 1; |
1532 | uint64_t HasNonTrivialToPrimitiveCopyCUnion : 1; |
1533 | |
1534 | /// Indicates whether this struct is destroyed in the callee. |
1535 | uint64_t ParamDestroyedInCallee : 1; |
1536 | |
1537 | /// Represents the way this type is passed to a function. |
1538 | uint64_t ArgPassingRestrictions : 2; |
1539 | }; |
1540 | |
1541 | /// Number of non-inherited bits in RecordDeclBitfields. |
1542 | enum { NumRecordDeclBits = 14 }; |
1543 | |
1544 | /// Stores the bits used by OMPDeclareReductionDecl. |
1545 | /// If modified NumOMPDeclareReductionDeclBits and the accessor |
1546 | /// methods in OMPDeclareReductionDecl should be updated appropriately. |
1547 | class OMPDeclareReductionDeclBitfields { |
1548 | friend class OMPDeclareReductionDecl; |
1549 | /// For the bits in DeclContextBitfields |
1550 | uint64_t : NumDeclContextBits; |
1551 | |
1552 | /// Kind of initializer, |
1553 | /// function call or omp_priv<init_expr> initializtion. |
1554 | uint64_t InitializerKind : 2; |
1555 | }; |
1556 | |
1557 | /// Number of non-inherited bits in OMPDeclareReductionDeclBitfields. |
1558 | enum { NumOMPDeclareReductionDeclBits = 2 }; |
1559 | |
1560 | /// Stores the bits used by FunctionDecl. |
1561 | /// If modified NumFunctionDeclBits and the accessor |
1562 | /// methods in FunctionDecl and CXXDeductionGuideDecl |
1563 | /// (for IsCopyDeductionCandidate) should be updated appropriately. |
1564 | class FunctionDeclBitfields { |
1565 | friend class FunctionDecl; |
1566 | /// For IsCopyDeductionCandidate |
1567 | friend class CXXDeductionGuideDecl; |
1568 | /// For the bits in DeclContextBitfields. |
1569 | uint64_t : NumDeclContextBits; |
1570 | |
1571 | uint64_t SClass : 3; |
1572 | uint64_t IsInline : 1; |
1573 | uint64_t IsInlineSpecified : 1; |
1574 | |
1575 | uint64_t IsVirtualAsWritten : 1; |
1576 | uint64_t IsPure : 1; |
1577 | uint64_t HasInheritedPrototype : 1; |
1578 | uint64_t HasWrittenPrototype : 1; |
1579 | uint64_t IsDeleted : 1; |
1580 | /// Used by CXXMethodDecl |
1581 | uint64_t IsTrivial : 1; |
1582 | |
1583 | /// This flag indicates whether this function is trivial for the purpose of |
1584 | /// calls. This is meaningful only when this function is a copy/move |
1585 | /// constructor or a destructor. |
1586 | uint64_t IsTrivialForCall : 1; |
1587 | |
1588 | uint64_t IsDefaulted : 1; |
1589 | uint64_t IsExplicitlyDefaulted : 1; |
1590 | uint64_t HasDefaultedFunctionInfo : 1; |
1591 | uint64_t HasImplicitReturnZero : 1; |
1592 | uint64_t IsLateTemplateParsed : 1; |
1593 | |
1594 | /// Kind of contexpr specifier as defined by ConstexprSpecKind. |
1595 | uint64_t ConstexprKind : 2; |
1596 | uint64_t InstantiationIsPending : 1; |
1597 | |
1598 | /// Indicates if the function uses __try. |
1599 | uint64_t UsesSEHTry : 1; |
1600 | |
1601 | /// Indicates if the function was a definition |
1602 | /// but its body was skipped. |
1603 | uint64_t HasSkippedBody : 1; |
1604 | |
1605 | /// Indicates if the function declaration will |
1606 | /// have a body, once we're done parsing it. |
1607 | uint64_t WillHaveBody : 1; |
1608 | |
1609 | /// Indicates that this function is a multiversioned |
1610 | /// function using attribute 'target'. |
1611 | uint64_t IsMultiVersion : 1; |
1612 | |
1613 | /// [C++17] Only used by CXXDeductionGuideDecl. Indicates that |
1614 | /// the Deduction Guide is the implicitly generated 'copy |
1615 | /// deduction candidate' (is used during overload resolution). |
1616 | uint64_t IsCopyDeductionCandidate : 1; |
1617 | |
1618 | /// Store the ODRHash after first calculation. |
1619 | uint64_t HasODRHash : 1; |
1620 | |
1621 | /// Indicates if the function uses Floating Point Constrained Intrinsics |
1622 | uint64_t UsesFPIntrin : 1; |
1623 | }; |
1624 | |
1625 | /// Number of non-inherited bits in FunctionDeclBitfields. |
1626 | enum { NumFunctionDeclBits = 27 }; |
1627 | |
1628 | /// Stores the bits used by CXXConstructorDecl. If modified |
1629 | /// NumCXXConstructorDeclBits and the accessor |
1630 | /// methods in CXXConstructorDecl should be updated appropriately. |
1631 | class CXXConstructorDeclBitfields { |
1632 | friend class CXXConstructorDecl; |
1633 | /// For the bits in DeclContextBitfields. |
1634 | uint64_t : NumDeclContextBits; |
1635 | /// For the bits in FunctionDeclBitfields. |
1636 | uint64_t : NumFunctionDeclBits; |
1637 | |
1638 | /// 24 bits to fit in the remaining available space. |
1639 | /// Note that this makes CXXConstructorDeclBitfields take |
1640 | /// exactly 64 bits and thus the width of NumCtorInitializers |
1641 | /// will need to be shrunk if some bit is added to NumDeclContextBitfields, |
1642 | /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields. |
1643 | uint64_t NumCtorInitializers : 21; |
1644 | uint64_t IsInheritingConstructor : 1; |
1645 | |
1646 | /// Whether this constructor has a trail-allocated explicit specifier. |
1647 | uint64_t HasTrailingExplicitSpecifier : 1; |
1648 | /// If this constructor does't have a trail-allocated explicit specifier. |
1649 | /// Whether this constructor is explicit specified. |
1650 | uint64_t IsSimpleExplicit : 1; |
1651 | }; |
1652 | |
1653 | /// Number of non-inherited bits in CXXConstructorDeclBitfields. |
1654 | enum { |
1655 | NumCXXConstructorDeclBits = 64 - NumDeclContextBits - NumFunctionDeclBits |
1656 | }; |
1657 | |
1658 | /// Stores the bits used by ObjCMethodDecl. |
1659 | /// If modified NumObjCMethodDeclBits and the accessor |
1660 | /// methods in ObjCMethodDecl should be updated appropriately. |
1661 | class ObjCMethodDeclBitfields { |
1662 | friend class ObjCMethodDecl; |
1663 | |
1664 | /// For the bits in DeclContextBitfields. |
1665 | uint64_t : NumDeclContextBits; |
1666 | |
1667 | /// The conventional meaning of this method; an ObjCMethodFamily. |
1668 | /// This is not serialized; instead, it is computed on demand and |
1669 | /// cached. |
1670 | mutable uint64_t Family : ObjCMethodFamilyBitWidth; |
1671 | |
1672 | /// instance (true) or class (false) method. |
1673 | uint64_t IsInstance : 1; |
1674 | uint64_t IsVariadic : 1; |
1675 | |
1676 | /// True if this method is the getter or setter for an explicit property. |
1677 | uint64_t IsPropertyAccessor : 1; |
1678 | |
1679 | /// True if this method is a synthesized property accessor stub. |
1680 | uint64_t IsSynthesizedAccessorStub : 1; |
1681 | |
1682 | /// Method has a definition. |
1683 | uint64_t IsDefined : 1; |
1684 | |
1685 | /// Method redeclaration in the same interface. |
1686 | uint64_t IsRedeclaration : 1; |
1687 | |
1688 | /// Is redeclared in the same interface. |
1689 | mutable uint64_t HasRedeclaration : 1; |
1690 | |
1691 | /// \@required/\@optional |
1692 | uint64_t DeclImplementation : 2; |
1693 | |
1694 | /// in, inout, etc. |
1695 | uint64_t objcDeclQualifier : 7; |
1696 | |
1697 | /// Indicates whether this method has a related result type. |
1698 | uint64_t RelatedResultType : 1; |
1699 | |
1700 | /// Whether the locations of the selector identifiers are in a |
1701 | /// "standard" position, a enum SelectorLocationsKind. |
1702 | uint64_t SelLocsKind : 2; |
1703 | |
1704 | /// Whether this method overrides any other in the class hierarchy. |
1705 | /// |
1706 | /// A method is said to override any method in the class's |
1707 | /// base classes, its protocols, or its categories' protocols, that has |
1708 | /// the same selector and is of the same kind (class or instance). |
1709 | /// A method in an implementation is not considered as overriding the same |
1710 | /// method in the interface or its categories. |
1711 | uint64_t IsOverriding : 1; |
1712 | |
1713 | /// Indicates if the method was a definition but its body was skipped. |
1714 | uint64_t HasSkippedBody : 1; |
1715 | }; |
1716 | |
1717 | /// Number of non-inherited bits in ObjCMethodDeclBitfields. |
1718 | enum { NumObjCMethodDeclBits = 24 }; |
1719 | |
1720 | /// Stores the bits used by ObjCContainerDecl. |
1721 | /// If modified NumObjCContainerDeclBits and the accessor |
1722 | /// methods in ObjCContainerDecl should be updated appropriately. |
1723 | class ObjCContainerDeclBitfields { |
1724 | friend class ObjCContainerDecl; |
1725 | /// For the bits in DeclContextBitfields |
1726 | uint32_t : NumDeclContextBits; |
1727 | |
1728 | // Not a bitfield but this saves space. |
1729 | // Note that ObjCContainerDeclBitfields is full. |
1730 | SourceLocation AtStart; |
1731 | }; |
1732 | |
1733 | /// Number of non-inherited bits in ObjCContainerDeclBitfields. |
1734 | /// Note that here we rely on the fact that SourceLocation is 32 bits |
1735 | /// wide. We check this with the static_assert in the ctor of DeclContext. |
1736 | enum { NumObjCContainerDeclBits = 64 - NumDeclContextBits }; |
1737 | |
1738 | /// Stores the bits used by LinkageSpecDecl. |
1739 | /// If modified NumLinkageSpecDeclBits and the accessor |
1740 | /// methods in LinkageSpecDecl should be updated appropriately. |
1741 | class LinkageSpecDeclBitfields { |
1742 | friend class LinkageSpecDecl; |
1743 | /// For the bits in DeclContextBitfields. |
1744 | uint64_t : NumDeclContextBits; |
1745 | |
1746 | /// The language for this linkage specification with values |
1747 | /// in the enum LinkageSpecDecl::LanguageIDs. |
1748 | uint64_t Language : 3; |
1749 | |
1750 | /// True if this linkage spec has braces. |
1751 | /// This is needed so that hasBraces() returns the correct result while the |
1752 | /// linkage spec body is being parsed. Once RBraceLoc has been set this is |
1753 | /// not used, so it doesn't need to be serialized. |
1754 | uint64_t HasBraces : 1; |
1755 | }; |
1756 | |
1757 | /// Number of non-inherited bits in LinkageSpecDeclBitfields. |
1758 | enum { NumLinkageSpecDeclBits = 4 }; |
1759 | |
1760 | /// Stores the bits used by BlockDecl. |
1761 | /// If modified NumBlockDeclBits and the accessor |
1762 | /// methods in BlockDecl should be updated appropriately. |
1763 | class BlockDeclBitfields { |
1764 | friend class BlockDecl; |
1765 | /// For the bits in DeclContextBitfields. |
1766 | uint64_t : NumDeclContextBits; |
1767 | |
1768 | uint64_t IsVariadic : 1; |
1769 | uint64_t CapturesCXXThis : 1; |
1770 | uint64_t BlockMissingReturnType : 1; |
1771 | uint64_t IsConversionFromLambda : 1; |
1772 | |
1773 | /// A bit that indicates this block is passed directly to a function as a |
1774 | /// non-escaping parameter. |
1775 | uint64_t DoesNotEscape : 1; |
1776 | |
1777 | /// A bit that indicates whether it's possible to avoid coying this block to |
1778 | /// the heap when it initializes or is assigned to a local variable with |
1779 | /// automatic storage. |
1780 | uint64_t CanAvoidCopyToHeap : 1; |
1781 | }; |
1782 | |
1783 | /// Number of non-inherited bits in BlockDeclBitfields. |
1784 | enum { NumBlockDeclBits = 5 }; |
1785 | |
1786 | /// Pointer to the data structure used to lookup declarations |
1787 | /// within this context (or a DependentStoredDeclsMap if this is a |
1788 | /// dependent context). We maintain the invariant that, if the map |
1789 | /// contains an entry for a DeclarationName (and we haven't lazily |
1790 | /// omitted anything), then it contains all relevant entries for that |
1791 | /// name (modulo the hasExternalDecls() flag). |
1792 | mutable StoredDeclsMap *LookupPtr = nullptr; |
1793 | |
1794 | protected: |
1795 | /// This anonymous union stores the bits belonging to DeclContext and classes |
1796 | /// deriving from it. The goal is to use otherwise wasted |
1797 | /// space in DeclContext to store data belonging to derived classes. |
1798 | /// The space saved is especially significient when pointers are aligned |
1799 | /// to 8 bytes. In this case due to alignment requirements we have a |
1800 | /// little less than 8 bytes free in DeclContext which we can use. |
1801 | /// We check that none of the classes in this union is larger than |
1802 | /// 8 bytes with static_asserts in the ctor of DeclContext. |
1803 | union { |
1804 | DeclContextBitfields DeclContextBits; |
1805 | TagDeclBitfields TagDeclBits; |
1806 | EnumDeclBitfields EnumDeclBits; |
1807 | RecordDeclBitfields RecordDeclBits; |
1808 | OMPDeclareReductionDeclBitfields OMPDeclareReductionDeclBits; |
1809 | FunctionDeclBitfields FunctionDeclBits; |
1810 | CXXConstructorDeclBitfields CXXConstructorDeclBits; |
1811 | ObjCMethodDeclBitfields ObjCMethodDeclBits; |
1812 | ObjCContainerDeclBitfields ObjCContainerDeclBits; |
1813 | LinkageSpecDeclBitfields LinkageSpecDeclBits; |
1814 | BlockDeclBitfields BlockDeclBits; |
1815 | |
1816 | static_assert(sizeof(DeclContextBitfields) <= 8, |
1817 | "DeclContextBitfields is larger than 8 bytes!"); |
1818 | static_assert(sizeof(TagDeclBitfields) <= 8, |
1819 | "TagDeclBitfields is larger than 8 bytes!"); |
1820 | static_assert(sizeof(EnumDeclBitfields) <= 8, |
1821 | "EnumDeclBitfields is larger than 8 bytes!"); |
1822 | static_assert(sizeof(RecordDeclBitfields) <= 8, |
1823 | "RecordDeclBitfields is larger than 8 bytes!"); |
1824 | static_assert(sizeof(OMPDeclareReductionDeclBitfields) <= 8, |
1825 | "OMPDeclareReductionDeclBitfields is larger than 8 bytes!"); |
1826 | static_assert(sizeof(FunctionDeclBitfields) <= 8, |
1827 | "FunctionDeclBitfields is larger than 8 bytes!"); |
1828 | static_assert(sizeof(CXXConstructorDeclBitfields) <= 8, |
1829 | "CXXConstructorDeclBitfields is larger than 8 bytes!"); |
1830 | static_assert(sizeof(ObjCMethodDeclBitfields) <= 8, |
1831 | "ObjCMethodDeclBitfields is larger than 8 bytes!"); |
1832 | static_assert(sizeof(ObjCContainerDeclBitfields) <= 8, |
1833 | "ObjCContainerDeclBitfields is larger than 8 bytes!"); |
1834 | static_assert(sizeof(LinkageSpecDeclBitfields) <= 8, |
1835 | "LinkageSpecDeclBitfields is larger than 8 bytes!"); |
1836 | static_assert(sizeof(BlockDeclBitfields) <= 8, |
1837 | "BlockDeclBitfields is larger than 8 bytes!"); |
1838 | }; |
1839 | |
1840 | /// FirstDecl - The first declaration stored within this declaration |
1841 | /// context. |
1842 | mutable Decl *FirstDecl = nullptr; |
1843 | |
1844 | /// LastDecl - The last declaration stored within this declaration |
1845 | /// context. FIXME: We could probably cache this value somewhere |
1846 | /// outside of the DeclContext, to reduce the size of DeclContext by |
1847 | /// another pointer. |
1848 | mutable Decl *LastDecl = nullptr; |
1849 | |
1850 | /// Build up a chain of declarations. |
1851 | /// |
1852 | /// \returns the first/last pair of declarations. |
1853 | static std::pair<Decl *, Decl *> |
1854 | BuildDeclChain(ArrayRef<Decl*> Decls, bool FieldsAlreadyLoaded); |
1855 | |
1856 | DeclContext(Decl::Kind K); |
1857 | |
1858 | public: |
1859 | ~DeclContext(); |
1860 | |
1861 | Decl::Kind getDeclKind() const { |
1862 | return static_cast<Decl::Kind>(DeclContextBits.DeclKind); |
1863 | } |
1864 | |
1865 | const char *getDeclKindName() const; |
1866 | |
1867 | /// getParent - Returns the containing DeclContext. |
1868 | DeclContext *getParent() { |
1869 | return cast<Decl>(this)->getDeclContext(); |
1870 | } |
1871 | const DeclContext *getParent() const { |
1872 | return const_cast<DeclContext*>(this)->getParent(); |
1873 | } |
1874 | |
1875 | /// getLexicalParent - Returns the containing lexical DeclContext. May be |
1876 | /// different from getParent, e.g.: |
1877 | /// |
1878 | /// namespace A { |
1879 | /// struct S; |
1880 | /// } |
1881 | /// struct A::S {}; // getParent() == namespace 'A' |
1882 | /// // getLexicalParent() == translation unit |
1883 | /// |
1884 | DeclContext *getLexicalParent() { |
1885 | return cast<Decl>(this)->getLexicalDeclContext(); |
1886 | } |
1887 | const DeclContext *getLexicalParent() const { |
1888 | return const_cast<DeclContext*>(this)->getLexicalParent(); |
1889 | } |
1890 | |
1891 | DeclContext *getLookupParent(); |
1892 | |
1893 | const DeclContext *getLookupParent() const { |
1894 | return const_cast<DeclContext*>(this)->getLookupParent(); |
1895 | } |
1896 | |
1897 | ASTContext &getParentASTContext() const { |
1898 | return cast<Decl>(this)->getASTContext(); |
1899 | } |
1900 | |
1901 | bool isClosure() const { return getDeclKind() == Decl::Block; } |
1902 | |
1903 | /// Return this DeclContext if it is a BlockDecl. Otherwise, return the |
1904 | /// innermost enclosing BlockDecl or null if there are no enclosing blocks. |
1905 | const BlockDecl *getInnermostBlockDecl() const; |
1906 | |
1907 | bool isObjCContainer() const { |
1908 | switch (getDeclKind()) { |
1909 | case Decl::ObjCCategory: |
1910 | case Decl::ObjCCategoryImpl: |
1911 | case Decl::ObjCImplementation: |
1912 | case Decl::ObjCInterface: |
1913 | case Decl::ObjCProtocol: |
1914 | return true; |
1915 | default: |
1916 | return false; |
1917 | } |
1918 | } |
1919 | |
1920 | bool isFunctionOrMethod() const { |
1921 | switch (getDeclKind()) { |
1922 | case Decl::Block: |
1923 | case Decl::Captured: |
1924 | case Decl::ObjCMethod: |
1925 | return true; |
1926 | default: |
1927 | return getDeclKind() >= Decl::firstFunction && |
1928 | getDeclKind() <= Decl::lastFunction; |
1929 | } |
1930 | } |
1931 | |
1932 | /// Test whether the context supports looking up names. |
1933 | bool isLookupContext() const { |
1934 | return !isFunctionOrMethod() && getDeclKind() != Decl::LinkageSpec && |
1935 | getDeclKind() != Decl::Export; |
1936 | } |
1937 | |
1938 | bool isFileContext() const { |
1939 | return getDeclKind() == Decl::TranslationUnit || |
1940 | getDeclKind() == Decl::Namespace; |
1941 | } |
1942 | |
1943 | bool isTranslationUnit() const { |
1944 | return getDeclKind() == Decl::TranslationUnit; |
1945 | } |
1946 | |
1947 | bool isRecord() const { |
1948 | return getDeclKind() >= Decl::firstRecord && |
1949 | getDeclKind() <= Decl::lastRecord; |
1950 | } |
1951 | |
1952 | bool isNamespace() const { return getDeclKind() == Decl::Namespace; } |
1953 | |
1954 | bool isStdNamespace() const; |
1955 | |
1956 | bool isInlineNamespace() const; |
1957 | |
1958 | /// Determines whether this context is dependent on a |
1959 | /// template parameter. |
1960 | bool isDependentContext() const; |
1961 | |
1962 | /// isTransparentContext - Determines whether this context is a |
1963 | /// "transparent" context, meaning that the members declared in this |
1964 | /// context are semantically declared in the nearest enclosing |
1965 | /// non-transparent (opaque) context but are lexically declared in |
1966 | /// this context. For example, consider the enumerators of an |
1967 | /// enumeration type: |
1968 | /// @code |
1969 | /// enum E { |
1970 | /// Val1 |
1971 | /// }; |
1972 | /// @endcode |
1973 | /// Here, E is a transparent context, so its enumerator (Val1) will |
1974 | /// appear (semantically) that it is in the same context of E. |
1975 | /// Examples of transparent contexts include: enumerations (except for |
1976 | /// C++0x scoped enums), and C++ linkage specifications. |
1977 | bool isTransparentContext() const; |
1978 | |
1979 | /// Determines whether this context or some of its ancestors is a |
1980 | /// linkage specification context that specifies C linkage. |
1981 | bool isExternCContext() const; |
1982 | |
1983 | /// Retrieve the nearest enclosing C linkage specification context. |
1984 | const LinkageSpecDecl *getExternCContext() const; |
1985 | |
1986 | /// Determines whether this context or some of its ancestors is a |
1987 | /// linkage specification context that specifies C++ linkage. |
1988 | bool isExternCXXContext() const; |
1989 | |
1990 | /// Determine whether this declaration context is equivalent |
1991 | /// to the declaration context DC. |
1992 | bool Equals(const DeclContext *DC) const { |
1993 | return DC && this->getPrimaryContext() == DC->getPrimaryContext(); |
1994 | } |
1995 | |
1996 | /// Determine whether this declaration context encloses the |
1997 | /// declaration context DC. |
1998 | bool Encloses(const DeclContext *DC) const; |
1999 | |
2000 | /// Find the nearest non-closure ancestor of this context, |
2001 | /// i.e. the innermost semantic parent of this context which is not |
2002 | /// a closure. A context may be its own non-closure ancestor. |
2003 | Decl *getNonClosureAncestor(); |
2004 | const Decl *getNonClosureAncestor() const { |
2005 | return const_cast<DeclContext*>(this)->getNonClosureAncestor(); |
2006 | } |
2007 | |
2008 | // Retrieve the nearest context that is not a transparent context. |
2009 | DeclContext *getNonTransparentContext(); |
2010 | const DeclContext *getNonTransparentContext() const { |
2011 | return const_cast<DeclContext *>(this)->getNonTransparentContext(); |
2012 | } |
2013 | |
2014 | /// getPrimaryContext - There may be many different |
2015 | /// declarations of the same entity (including forward declarations |
2016 | /// of classes, multiple definitions of namespaces, etc.), each with |
2017 | /// a different set of declarations. This routine returns the |
2018 | /// "primary" DeclContext structure, which will contain the |
2019 | /// information needed to perform name lookup into this context. |
2020 | DeclContext *getPrimaryContext(); |
2021 | const DeclContext *getPrimaryContext() const { |
2022 | return const_cast<DeclContext*>(this)->getPrimaryContext(); |
2023 | } |
2024 | |
2025 | /// getRedeclContext - Retrieve the context in which an entity conflicts with |
2026 | /// other entities of the same name, or where it is a redeclaration if the |
2027 | /// two entities are compatible. This skips through transparent contexts. |
2028 | DeclContext *getRedeclContext(); |
2029 | const DeclContext *getRedeclContext() const { |
2030 | return const_cast<DeclContext *>(this)->getRedeclContext(); |
2031 | } |
2032 | |
2033 | /// Retrieve the nearest enclosing namespace context. |
2034 | DeclContext *getEnclosingNamespaceContext(); |
2035 | const DeclContext *getEnclosingNamespaceContext() const { |
2036 | return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext(); |
2037 | } |
2038 | |
2039 | /// Retrieve the outermost lexically enclosing record context. |
2040 | RecordDecl *getOuterLexicalRecordContext(); |
2041 | const RecordDecl *getOuterLexicalRecordContext() const { |
2042 | return const_cast<DeclContext *>(this)->getOuterLexicalRecordContext(); |
2043 | } |
2044 | |
2045 | /// Test if this context is part of the enclosing namespace set of |
2046 | /// the context NS, as defined in C++0x [namespace.def]p9. If either context |
2047 | /// isn't a namespace, this is equivalent to Equals(). |
2048 | /// |
2049 | /// The enclosing namespace set of a namespace is the namespace and, if it is |
2050 | /// inline, its enclosing namespace, recursively. |
2051 | bool InEnclosingNamespaceSetOf(const DeclContext *NS) const; |
2052 | |
2053 | /// Collects all of the declaration contexts that are semantically |
2054 | /// connected to this declaration context. |
2055 | /// |
2056 | /// For declaration contexts that have multiple semantically connected but |
2057 | /// syntactically distinct contexts, such as C++ namespaces, this routine |
2058 | /// retrieves the complete set of such declaration contexts in source order. |
2059 | /// For example, given: |
2060 | /// |
2061 | /// \code |
2062 | /// namespace N { |
2063 | /// int x; |
2064 | /// } |
2065 | /// namespace N { |
2066 | /// int y; |
2067 | /// } |
2068 | /// \endcode |
2069 | /// |
2070 | /// The \c Contexts parameter will contain both definitions of N. |
2071 | /// |
2072 | /// \param Contexts Will be cleared and set to the set of declaration |
2073 | /// contexts that are semanticaly connected to this declaration context, |
2074 | /// in source order, including this context (which may be the only result, |
2075 | /// for non-namespace contexts). |
2076 | void collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts); |
2077 | |
2078 | /// decl_iterator - Iterates through the declarations stored |
2079 | /// within this context. |
2080 | class decl_iterator { |
2081 | /// Current - The current declaration. |
2082 | Decl *Current = nullptr; |
2083 | |
2084 | public: |
2085 | using value_type = Decl *; |
2086 | using reference = const value_type &; |
2087 | using pointer = const value_type *; |
2088 | using iterator_category = std::forward_iterator_tag; |
2089 | using difference_type = std::ptrdiff_t; |
2090 | |
2091 | decl_iterator() = default; |
2092 | explicit decl_iterator(Decl *C) : Current(C) {} |
2093 | |
2094 | reference operator*() const { return Current; } |
2095 | |
2096 | // This doesn't meet the iterator requirements, but it's convenient |
2097 | value_type operator->() const { return Current; } |
2098 | |
2099 | decl_iterator& operator++() { |
2100 | Current = Current->getNextDeclInContext(); |
2101 | return *this; |
2102 | } |
2103 | |
2104 | decl_iterator operator++(int) { |
2105 | decl_iterator tmp(*this); |
2106 | ++(*this); |
2107 | return tmp; |
2108 | } |
2109 | |
2110 | friend bool operator==(decl_iterator x, decl_iterator y) { |
2111 | return x.Current == y.Current; |
2112 | } |
2113 | |
2114 | friend bool operator!=(decl_iterator x, decl_iterator y) { |
2115 | return x.Current != y.Current; |
2116 | } |
2117 | }; |
2118 | |
2119 | using decl_range = llvm::iterator_range<decl_iterator>; |
2120 | |
2121 | /// decls_begin/decls_end - Iterate over the declarations stored in |
2122 | /// this context. |
2123 | decl_range decls() const { return decl_range(decls_begin(), decls_end()); } |
2124 | decl_iterator decls_begin() const; |
2125 | decl_iterator decls_end() const { return decl_iterator(); } |
2126 | bool decls_empty() const; |
2127 | |
2128 | /// noload_decls_begin/end - Iterate over the declarations stored in this |
2129 | /// context that are currently loaded; don't attempt to retrieve anything |
2130 | /// from an external source. |
2131 | decl_range noload_decls() const { |
2132 | return decl_range(noload_decls_begin(), noload_decls_end()); |
2133 | } |
2134 | decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); } |
2135 | decl_iterator noload_decls_end() const { return decl_iterator(); } |
2136 | |
2137 | /// specific_decl_iterator - Iterates over a subrange of |
2138 | /// declarations stored in a DeclContext, providing only those that |
2139 | /// are of type SpecificDecl (or a class derived from it). This |
2140 | /// iterator is used, for example, to provide iteration over just |
2141 | /// the fields within a RecordDecl (with SpecificDecl = FieldDecl). |
2142 | template<typename SpecificDecl> |
2143 | class specific_decl_iterator { |
2144 | /// Current - The current, underlying declaration iterator, which |
2145 | /// will either be NULL or will point to a declaration of |
2146 | /// type SpecificDecl. |
2147 | DeclContext::decl_iterator Current; |
2148 | |
2149 | /// SkipToNextDecl - Advances the current position up to the next |
2150 | /// declaration of type SpecificDecl that also meets the criteria |
2151 | /// required by Acceptable. |
2152 | void SkipToNextDecl() { |
2153 | while (*Current && !isa<SpecificDecl>(*Current)) |
2154 | ++Current; |
2155 | } |
2156 | |
2157 | public: |
2158 | using value_type = SpecificDecl *; |
2159 | // TODO: Add reference and pointer types (with some appropriate proxy type) |
2160 | // if we ever have a need for them. |
2161 | using reference = void; |
2162 | using pointer = void; |
2163 | using difference_type = |
2164 | std::iterator_traits<DeclContext::decl_iterator>::difference_type; |
2165 | using iterator_category = std::forward_iterator_tag; |
2166 | |
2167 | specific_decl_iterator() = default; |
2168 | |
2169 | /// specific_decl_iterator - Construct a new iterator over a |
2170 | /// subset of the declarations the range [C, |
2171 | /// end-of-declarations). If A is non-NULL, it is a pointer to a |
2172 | /// member function of SpecificDecl that should return true for |
2173 | /// all of the SpecificDecl instances that will be in the subset |
2174 | /// of iterators. For example, if you want Objective-C instance |
2175 | /// methods, SpecificDecl will be ObjCMethodDecl and A will be |
2176 | /// &ObjCMethodDecl::isInstanceMethod. |
2177 | explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) { |
2178 | SkipToNextDecl(); |
2179 | } |
2180 | |
2181 | value_type operator*() const { return cast<SpecificDecl>(*Current); } |
2182 | |
2183 | // This doesn't meet the iterator requirements, but it's convenient |
2184 | value_type operator->() const { return **this; } |
2185 | |
2186 | specific_decl_iterator& operator++() { |
2187 | ++Current; |
2188 | SkipToNextDecl(); |
2189 | return *this; |
2190 | } |
2191 | |
2192 | specific_decl_iterator operator++(int) { |
2193 | specific_decl_iterator tmp(*this); |
2194 | ++(*this); |
2195 | return tmp; |
2196 | } |
2197 | |
2198 | friend bool operator==(const specific_decl_iterator& x, |
2199 | const specific_decl_iterator& y) { |
2200 | return x.Current == y.Current; |
2201 | } |
2202 | |
2203 | friend bool operator!=(const specific_decl_iterator& x, |
2204 | const specific_decl_iterator& y) { |
2205 | return x.Current != y.Current; |
2206 | } |
2207 | }; |
2208 | |
2209 | /// Iterates over a filtered subrange of declarations stored |
2210 | /// in a DeclContext. |
2211 | /// |
2212 | /// This iterator visits only those declarations that are of type |
2213 | /// SpecificDecl (or a class derived from it) and that meet some |
2214 | /// additional run-time criteria. This iterator is used, for |
2215 | /// example, to provide access to the instance methods within an |
2216 | /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and |
2217 | /// Acceptable = ObjCMethodDecl::isInstanceMethod). |
2218 | template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const> |
2219 | class filtered_decl_iterator { |
2220 | /// Current - The current, underlying declaration iterator, which |
2221 | /// will either be NULL or will point to a declaration of |
2222 | /// type SpecificDecl. |
2223 | DeclContext::decl_iterator Current; |
2224 | |
2225 | /// SkipToNextDecl - Advances the current position up to the next |
2226 | /// declaration of type SpecificDecl that also meets the criteria |
2227 | /// required by Acceptable. |
2228 | void SkipToNextDecl() { |
2229 | while (*Current && |
2230 | (!isa<SpecificDecl>(*Current) || |
2231 | (Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)()))) |
2232 | ++Current; |
2233 | } |
2234 | |
2235 | public: |
2236 | using value_type = SpecificDecl *; |
2237 | // TODO: Add reference and pointer types (with some appropriate proxy type) |
2238 | // if we ever have a need for them. |
2239 | using reference = void; |
2240 | using pointer = void; |
2241 | using difference_type = |
2242 | std::iterator_traits<DeclContext::decl_iterator>::difference_type; |
2243 | using iterator_category = std::forward_iterator_tag; |
2244 | |
2245 | filtered_decl_iterator() = default; |
2246 | |
2247 | /// filtered_decl_iterator - Construct a new iterator over a |
2248 | /// subset of the declarations the range [C, |
2249 | /// end-of-declarations). If A is non-NULL, it is a pointer to a |
2250 | /// member function of SpecificDecl that should return true for |
2251 | /// all of the SpecificDecl instances that will be in the subset |
2252 | /// of iterators. For example, if you want Objective-C instance |
2253 | /// methods, SpecificDecl will be ObjCMethodDecl and A will be |
2254 | /// &ObjCMethodDecl::isInstanceMethod. |
2255 | explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) { |
2256 | SkipToNextDecl(); |
2257 | } |
2258 | |
2259 | value_type operator*() const { return cast<SpecificDecl>(*Current); } |
2260 | value_type operator->() const { return cast<SpecificDecl>(*Current); } |
2261 | |
2262 | filtered_decl_iterator& operator++() { |
2263 | ++Current; |
2264 | SkipToNextDecl(); |
2265 | return *this; |
2266 | } |
2267 | |
2268 | filtered_decl_iterator operator++(int) { |
2269 | filtered_decl_iterator tmp(*this); |
2270 | ++(*this); |
2271 | return tmp; |
2272 | } |
2273 | |
2274 | friend bool operator==(const filtered_decl_iterator& x, |
2275 | const filtered_decl_iterator& y) { |
2276 | return x.Current == y.Current; |
2277 | } |
2278 | |
2279 | friend bool operator!=(const filtered_decl_iterator& x, |
2280 | const filtered_decl_iterator& y) { |
2281 | return x.Current != y.Current; |
2282 | } |
2283 | }; |
2284 | |
2285 | /// Add the declaration D into this context. |
2286 | /// |
2287 | /// This routine should be invoked when the declaration D has first |
2288 | /// been declared, to place D into the context where it was |
2289 | /// (lexically) defined. Every declaration must be added to one |
2290 | /// (and only one!) context, where it can be visited via |
2291 | /// [decls_begin(), decls_end()). Once a declaration has been added |
2292 | /// to its lexical context, the corresponding DeclContext owns the |
2293 | /// declaration. |
2294 | /// |
2295 | /// If D is also a NamedDecl, it will be made visible within its |
2296 | /// semantic context via makeDeclVisibleInContext. |
2297 | void addDecl(Decl *D); |
2298 | |
2299 | /// Add the declaration D into this context, but suppress |
2300 | /// searches for external declarations with the same name. |
2301 | /// |
2302 | /// Although analogous in function to addDecl, this removes an |
2303 | /// important check. This is only useful if the Decl is being |
2304 | /// added in response to an external search; in all other cases, |
2305 | /// addDecl() is the right function to use. |
2306 | /// See the ASTImporter for use cases. |
2307 | void addDeclInternal(Decl *D); |
2308 | |
2309 | /// Add the declaration D to this context without modifying |
2310 | /// any lookup tables. |
2311 | /// |
2312 | /// This is useful for some operations in dependent contexts where |
2313 | /// the semantic context might not be dependent; this basically |
2314 | /// only happens with friends. |
2315 | void addHiddenDecl(Decl *D); |
2316 | |
2317 | /// Removes a declaration from this context. |
2318 | void removeDecl(Decl *D); |
2319 | |
2320 | /// Checks whether a declaration is in this context. |
2321 | bool containsDecl(Decl *D) const; |
2322 | |
2323 | /// Checks whether a declaration is in this context. |
2324 | /// This also loads the Decls from the external source before the check. |
2325 | bool containsDeclAndLoad(Decl *D) const; |
2326 | |
2327 | using lookup_result = DeclContextLookupResult; |
2328 | using lookup_iterator = lookup_result::iterator; |
2329 | |
2330 | /// lookup - Find the declarations (if any) with the given Name in |
2331 | /// this context. Returns a range of iterators that contains all of |
2332 | /// the declarations with this name, with object, function, member, |
2333 | /// and enumerator names preceding any tag name. Note that this |
2334 | /// routine will not look into parent contexts. |
2335 | lookup_result lookup(DeclarationName Name) const; |
2336 | |
2337 | /// Find the declarations with the given name that are visible |
2338 | /// within this context; don't attempt to retrieve anything from an |
2339 | /// external source. |
2340 | lookup_result noload_lookup(DeclarationName Name); |
2341 | |
2342 | /// A simplistic name lookup mechanism that performs name lookup |
2343 | /// into this declaration context without consulting the external source. |
2344 | /// |
2345 | /// This function should almost never be used, because it subverts the |
2346 | /// usual relationship between a DeclContext and the external source. |
2347 | /// See the ASTImporter for the (few, but important) use cases. |
2348 | /// |
2349 | /// FIXME: This is very inefficient; replace uses of it with uses of |
2350 | /// noload_lookup. |
2351 | void localUncachedLookup(DeclarationName Name, |
2352 | SmallVectorImpl<NamedDecl *> &Results); |
2353 | |
2354 | /// Makes a declaration visible within this context. |
2355 | /// |
2356 | /// This routine makes the declaration D visible to name lookup |
2357 | /// within this context and, if this is a transparent context, |
2358 | /// within its parent contexts up to the first enclosing |
2359 | /// non-transparent context. Making a declaration visible within a |
2360 | /// context does not transfer ownership of a declaration, and a |
2361 | /// declaration can be visible in many contexts that aren't its |
2362 | /// lexical context. |
2363 | /// |
2364 | /// If D is a redeclaration of an existing declaration that is |
2365 | /// visible from this context, as determined by |
2366 | /// NamedDecl::declarationReplaces, the previous declaration will be |
2367 | /// replaced with D. |
2368 | void makeDeclVisibleInContext(NamedDecl *D); |
2369 | |
2370 | /// all_lookups_iterator - An iterator that provides a view over the results |
2371 | /// of looking up every possible name. |
2372 | class all_lookups_iterator; |
2373 | |
2374 | using lookups_range = llvm::iterator_range<all_lookups_iterator>; |
2375 | |
2376 | lookups_range lookups() const; |
2377 | // Like lookups(), but avoids loading external declarations. |
2378 | // If PreserveInternalState, avoids building lookup data structures too. |
2379 | lookups_range noload_lookups(bool PreserveInternalState) const; |
2380 | |
2381 | /// Iterators over all possible lookups within this context. |
2382 | all_lookups_iterator lookups_begin() const; |
2383 | all_lookups_iterator lookups_end() const; |
2384 | |
2385 | /// Iterators over all possible lookups within this context that are |
2386 | /// currently loaded; don't attempt to retrieve anything from an external |
2387 | /// source. |
2388 | all_lookups_iterator noload_lookups_begin() const; |
2389 | all_lookups_iterator noload_lookups_end() const; |
2390 | |
2391 | struct udir_iterator; |
2392 | |
2393 | using udir_iterator_base = |
2394 | llvm::iterator_adaptor_base<udir_iterator, lookup_iterator, |
2395 | typename lookup_iterator::iterator_category, |
2396 | UsingDirectiveDecl *>; |
2397 | |
2398 | struct udir_iterator : udir_iterator_base { |
2399 | udir_iterator(lookup_iterator I) : udir_iterator_base(I) {} |
2400 | |
2401 | UsingDirectiveDecl *operator*() const; |
2402 | }; |
2403 | |
2404 | using udir_range = llvm::iterator_range<udir_iterator>; |
2405 | |
2406 | udir_range using_directives() const; |
2407 | |
2408 | // These are all defined in DependentDiagnostic.h. |
2409 | class ddiag_iterator; |
2410 | |
2411 | using ddiag_range = llvm::iterator_range<DeclContext::ddiag_iterator>; |
2412 | |
2413 | inline ddiag_range ddiags() const; |
2414 | |
2415 | // Low-level accessors |
2416 | |
2417 | /// Mark that there are external lexical declarations that we need |
2418 | /// to include in our lookup table (and that are not available as external |
2419 | /// visible lookups). These extra lookup results will be found by walking |
2420 | /// the lexical declarations of this context. This should be used only if |
2421 | /// setHasExternalLexicalStorage() has been called on any decl context for |
2422 | /// which this is the primary context. |
2423 | void setMustBuildLookupTable() { |
2424 | assert(this == getPrimaryContext() &&(static_cast <bool> (this == getPrimaryContext() && "should only be called on primary context") ? void (0) : __assert_fail ("this == getPrimaryContext() && \"should only be called on primary context\"" , "clang/include/clang/AST/DeclBase.h", 2425, __extension__ __PRETTY_FUNCTION__ )) |
2425 | "should only be called on primary context")(static_cast <bool> (this == getPrimaryContext() && "should only be called on primary context") ? void (0) : __assert_fail ("this == getPrimaryContext() && \"should only be called on primary context\"" , "clang/include/clang/AST/DeclBase.h", 2425, __extension__ __PRETTY_FUNCTION__ )); |
2426 | DeclContextBits.HasLazyExternalLexicalLookups = true; |
2427 | } |
2428 | |
2429 | /// Retrieve the internal representation of the lookup structure. |
2430 | /// This may omit some names if we are lazily building the structure. |
2431 | StoredDeclsMap *getLookupPtr() const { return LookupPtr; } |
2432 | |
2433 | /// Ensure the lookup structure is fully-built and return it. |
2434 | StoredDeclsMap *buildLookup(); |
2435 | |
2436 | /// Whether this DeclContext has external storage containing |
2437 | /// additional declarations that are lexically in this context. |
2438 | bool hasExternalLexicalStorage() const { |
2439 | return DeclContextBits.ExternalLexicalStorage; |
2440 | } |
2441 | |
2442 | /// State whether this DeclContext has external storage for |
2443 | /// declarations lexically in this context. |
2444 | void setHasExternalLexicalStorage(bool ES = true) const { |
2445 | DeclContextBits.ExternalLexicalStorage = ES; |
2446 | } |
2447 | |
2448 | /// Whether this DeclContext has external storage containing |
2449 | /// additional declarations that are visible in this context. |
2450 | bool hasExternalVisibleStorage() const { |
2451 | return DeclContextBits.ExternalVisibleStorage; |
2452 | } |
2453 | |
2454 | /// State whether this DeclContext has external storage for |
2455 | /// declarations visible in this context. |
2456 | void setHasExternalVisibleStorage(bool ES = true) const { |
2457 | DeclContextBits.ExternalVisibleStorage = ES; |
2458 | if (ES && LookupPtr) |
2459 | DeclContextBits.NeedToReconcileExternalVisibleStorage = true; |
2460 | } |
2461 | |
2462 | /// Determine whether the given declaration is stored in the list of |
2463 | /// declarations lexically within this context. |
2464 | bool isDeclInLexicalTraversal(const Decl *D) const { |
2465 | return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl || |
2466 | D == LastDecl); |
2467 | } |
2468 | |
2469 | bool setUseQualifiedLookup(bool use = true) const { |
2470 | bool old_value = DeclContextBits.UseQualifiedLookup; |
2471 | DeclContextBits.UseQualifiedLookup = use; |
2472 | return old_value; |
2473 | } |
2474 | |
2475 | bool shouldUseQualifiedLookup() const { |
2476 | return DeclContextBits.UseQualifiedLookup; |
2477 | } |
2478 | |
2479 | static bool classof(const Decl *D); |
2480 | static bool classof(const DeclContext *D) { return true; } |
2481 | |
2482 | void dumpDeclContext() const; |
2483 | void dumpLookups() const; |
2484 | void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false, |
2485 | bool Deserialize = false) const; |
2486 | |
2487 | private: |
2488 | /// Whether this declaration context has had externally visible |
2489 | /// storage added since the last lookup. In this case, \c LookupPtr's |
2490 | /// invariant may not hold and needs to be fixed before we perform |
2491 | /// another lookup. |
2492 | bool hasNeedToReconcileExternalVisibleStorage() const { |
2493 | return DeclContextBits.NeedToReconcileExternalVisibleStorage; |
2494 | } |
2495 | |
2496 | /// State that this declaration context has had externally visible |
2497 | /// storage added since the last lookup. In this case, \c LookupPtr's |
2498 | /// invariant may not hold and needs to be fixed before we perform |
2499 | /// another lookup. |
2500 | void setNeedToReconcileExternalVisibleStorage(bool Need = true) const { |
2501 | DeclContextBits.NeedToReconcileExternalVisibleStorage = Need; |
2502 | } |
2503 | |
2504 | /// If \c true, this context may have local lexical declarations |
2505 | /// that are missing from the lookup table. |
2506 | bool hasLazyLocalLexicalLookups() const { |
2507 | return DeclContextBits.HasLazyLocalLexicalLookups; |
2508 | } |
2509 | |
2510 | /// If \c true, this context may have local lexical declarations |
2511 | /// that are missing from the lookup table. |
2512 | void setHasLazyLocalLexicalLookups(bool HasLLLL = true) const { |
2513 | DeclContextBits.HasLazyLocalLexicalLookups = HasLLLL; |
2514 | } |
2515 | |
2516 | /// If \c true, the external source may have lexical declarations |
2517 | /// that are missing from the lookup table. |
2518 | bool hasLazyExternalLexicalLookups() const { |
2519 | return DeclContextBits.HasLazyExternalLexicalLookups; |
2520 | } |
2521 | |
2522 | /// If \c true, the external source may have lexical declarations |
2523 | /// that are missing from the lookup table. |
2524 | void setHasLazyExternalLexicalLookups(bool HasLELL = true) const { |
2525 | DeclContextBits.HasLazyExternalLexicalLookups = HasLELL; |
2526 | } |
2527 | |
2528 | void reconcileExternalVisibleStorage() const; |
2529 | bool LoadLexicalDeclsFromExternalStorage() const; |
2530 | |
2531 | /// Makes a declaration visible within this context, but |
2532 | /// suppresses searches for external declarations with the same |
2533 | /// name. |
2534 | /// |
2535 | /// Analogous to makeDeclVisibleInContext, but for the exclusive |
2536 | /// use of addDeclInternal(). |
2537 | void makeDeclVisibleInContextInternal(NamedDecl *D); |
2538 | |
2539 | StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; |
2540 | |
2541 | void loadLazyLocalLexicalLookups(); |
2542 | void buildLookupImpl(DeclContext *DCtx, bool Internal); |
2543 | void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, |
2544 | bool Rediscoverable); |
2545 | void makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal); |
2546 | }; |
2547 | |
2548 | inline bool Decl::isTemplateParameter() const { |
2549 | return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm || |
2550 | getKind() == TemplateTemplateParm; |
2551 | } |
2552 | |
2553 | // Specialization selected when ToTy is not a known subclass of DeclContext. |
2554 | template <class ToTy, |
2555 | bool IsKnownSubtype = ::std::is_base_of<DeclContext, ToTy>::value> |
2556 | struct cast_convert_decl_context { |
2557 | static const ToTy *doit(const DeclContext *Val) { |
2558 | return static_cast<const ToTy*>(Decl::castFromDeclContext(Val)); |
2559 | } |
2560 | |
2561 | static ToTy *doit(DeclContext *Val) { |
2562 | return static_cast<ToTy*>(Decl::castFromDeclContext(Val)); |
2563 | } |
2564 | }; |
2565 | |
2566 | // Specialization selected when ToTy is a known subclass of DeclContext. |
2567 | template <class ToTy> |
2568 | struct cast_convert_decl_context<ToTy, true> { |
2569 | static const ToTy *doit(const DeclContext *Val) { |
2570 | return static_cast<const ToTy*>(Val); |
2571 | } |
2572 | |
2573 | static ToTy *doit(DeclContext *Val) { |
2574 | return static_cast<ToTy*>(Val); |
2575 | } |
2576 | }; |
2577 | |
2578 | } // namespace clang |
2579 | |
2580 | namespace llvm { |
2581 | |
2582 | /// isa<T>(DeclContext*) |
2583 | template <typename To> |
2584 | struct isa_impl<To, ::clang::DeclContext> { |
2585 | static bool doit(const ::clang::DeclContext &Val) { |
2586 | return To::classofKind(Val.getDeclKind()); |
2587 | } |
2588 | }; |
2589 | |
2590 | /// cast<T>(DeclContext*) |
2591 | template<class ToTy> |
2592 | struct cast_convert_val<ToTy, |
2593 | const ::clang::DeclContext,const ::clang::DeclContext> { |
2594 | static const ToTy &doit(const ::clang::DeclContext &Val) { |
2595 | return *::clang::cast_convert_decl_context<ToTy>::doit(&Val); |
2596 | } |
2597 | }; |
2598 | |
2599 | template<class ToTy> |
2600 | struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> { |
2601 | static ToTy &doit(::clang::DeclContext &Val) { |
2602 | return *::clang::cast_convert_decl_context<ToTy>::doit(&Val); |
2603 | } |
2604 | }; |
2605 | |
2606 | template<class ToTy> |
2607 | struct cast_convert_val<ToTy, |
2608 | const ::clang::DeclContext*, const ::clang::DeclContext*> { |
2609 | static const ToTy *doit(const ::clang::DeclContext *Val) { |
2610 | return ::clang::cast_convert_decl_context<ToTy>::doit(Val); |
2611 | } |
2612 | }; |
2613 | |
2614 | template<class ToTy> |
2615 | struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> { |
2616 | static ToTy *doit(::clang::DeclContext *Val) { |
2617 | return ::clang::cast_convert_decl_context<ToTy>::doit(Val); |
2618 | } |
2619 | }; |
2620 | |
2621 | /// Implement cast_convert_val for Decl -> DeclContext conversions. |
2622 | template<class FromTy> |
2623 | struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> { |
2624 | static ::clang::DeclContext &doit(const FromTy &Val) { |
2625 | return *FromTy::castToDeclContext(&Val); |
2626 | } |
2627 | }; |
2628 | |
2629 | template<class FromTy> |
2630 | struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> { |
2631 | static ::clang::DeclContext *doit(const FromTy *Val) { |
2632 | return FromTy::castToDeclContext(Val); |
2633 | } |
2634 | }; |
2635 | |
2636 | template<class FromTy> |
2637 | struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> { |
2638 | static const ::clang::DeclContext &doit(const FromTy &Val) { |
2639 | return *FromTy::castToDeclContext(&Val); |
2640 | } |
2641 | }; |
2642 | |
2643 | template<class FromTy> |
2644 | struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> { |
2645 | static const ::clang::DeclContext *doit(const FromTy *Val) { |
2646 | return FromTy::castToDeclContext(Val); |
2647 | } |
2648 | }; |
2649 | |
2650 | } // namespace llvm |
2651 | |
2652 | #endif // LLVM_CLANG_AST_DECLBASE_H |
1 | // List implementation -*- C++ -*- |
2 | |
3 | // Copyright (C) 2001-2020 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /* |
26 | * |
27 | * Copyright (c) 1994 |
28 | * Hewlett-Packard Company |
29 | * |
30 | * Permission to use, copy, modify, distribute and sell this software |
31 | * and its documentation for any purpose is hereby granted without fee, |
32 | * provided that the above copyright notice appear in all copies and |
33 | * that both that copyright notice and this permission notice appear |
34 | * in supporting documentation. Hewlett-Packard Company makes no |
35 | * representations about the suitability of this software for any |
36 | * purpose. It is provided "as is" without express or implied warranty. |
37 | * |
38 | * |
39 | * Copyright (c) 1996,1997 |
40 | * Silicon Graphics Computer Systems, Inc. |
41 | * |
42 | * Permission to use, copy, modify, distribute and sell this software |
43 | * and its documentation for any purpose is hereby granted without fee, |
44 | * provided that the above copyright notice appear in all copies and |
45 | * that both that copyright notice and this permission notice appear |
46 | * in supporting documentation. Silicon Graphics makes no |
47 | * representations about the suitability of this software for any |
48 | * purpose. It is provided "as is" without express or implied warranty. |
49 | */ |
50 | |
51 | /** @file bits/stl_list.h |
52 | * This is an internal header file, included by other library headers. |
53 | * Do not attempt to use it directly. @headername{list} |
54 | */ |
55 | |
56 | #ifndef _STL_LIST_H1 |
57 | #define _STL_LIST_H1 1 |
58 | |
59 | #include <bits/concept_check.h> |
60 | #include <ext/alloc_traits.h> |
61 | #if __cplusplus201402L >= 201103L |
62 | #include <initializer_list> |
63 | #include <bits/allocated_ptr.h> |
64 | #include <ext/aligned_buffer.h> |
65 | #endif |
66 | |
67 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
68 | { |
69 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
70 | |
71 | namespace __detail |
72 | { |
73 | // Supporting structures are split into common and templated |
74 | // types; the latter publicly inherits from the former in an |
75 | // effort to reduce code duplication. This results in some |
76 | // "needless" static_cast'ing later on, but it's all safe |
77 | // downcasting. |
78 | |
79 | /// Common part of a node in the %list. |
80 | struct _List_node_base |
81 | { |
82 | _List_node_base* _M_next; |
83 | _List_node_base* _M_prev; |
84 | |
85 | static void |
86 | swap(_List_node_base& __x, _List_node_base& __y) _GLIBCXX_USE_NOEXCEPTnoexcept; |
87 | |
88 | void |
89 | _M_transfer(_List_node_base* const __first, |
90 | _List_node_base* const __last) _GLIBCXX_USE_NOEXCEPTnoexcept; |
91 | |
92 | void |
93 | _M_reverse() _GLIBCXX_USE_NOEXCEPTnoexcept; |
94 | |
95 | void |
96 | _M_hook(_List_node_base* const __position) _GLIBCXX_USE_NOEXCEPTnoexcept; |
97 | |
98 | void |
99 | _M_unhook() _GLIBCXX_USE_NOEXCEPTnoexcept; |
100 | }; |
101 | |
102 | /// The %list node header. |
103 | struct _List_node_header : public _List_node_base |
104 | { |
105 | #if _GLIBCXX_USE_CXX11_ABI1 |
106 | std::size_t _M_size; |
107 | #endif |
108 | |
109 | _List_node_header() _GLIBCXX_NOEXCEPTnoexcept |
110 | { _M_init(); } |
111 | |
112 | #if __cplusplus201402L >= 201103L |
113 | _List_node_header(_List_node_header&& __x) noexcept |
114 | : _List_node_base{ __x._M_next, __x._M_prev } |
115 | # if _GLIBCXX_USE_CXX11_ABI1 |
116 | , _M_size(__x._M_size) |
117 | # endif |
118 | { |
119 | if (__x._M_base()->_M_next == __x._M_base()) |
120 | this->_M_next = this->_M_prev = this; |
121 | else |
122 | { |
123 | this->_M_next->_M_prev = this->_M_prev->_M_next = this->_M_base(); |
124 | __x._M_init(); |
125 | } |
126 | } |
127 | |
128 | void |
129 | _M_move_nodes(_List_node_header&& __x) |
130 | { |
131 | _List_node_base* const __xnode = __x._M_base(); |
132 | if (__xnode->_M_next == __xnode) |
133 | _M_init(); |
134 | else |
135 | { |
136 | _List_node_base* const __node = this->_M_base(); |
137 | __node->_M_next = __xnode->_M_next; |
138 | __node->_M_prev = __xnode->_M_prev; |
139 | __node->_M_next->_M_prev = __node->_M_prev->_M_next = __node; |
140 | # if _GLIBCXX_USE_CXX11_ABI1 |
141 | _M_size = __x._M_size; |
142 | # endif |
143 | __x._M_init(); |
144 | } |
145 | } |
146 | #endif |
147 | |
148 | void |
149 | _M_init() _GLIBCXX_NOEXCEPTnoexcept |
150 | { |
151 | this->_M_next = this->_M_prev = this; |
152 | #if _GLIBCXX_USE_CXX11_ABI1 |
153 | this->_M_size = 0; |
154 | #endif |
155 | } |
156 | |
157 | private: |
158 | _List_node_base* _M_base() { return this; } |
159 | }; |
160 | } // namespace detail |
161 | |
162 | _GLIBCXX_BEGIN_NAMESPACE_CONTAINER |
163 | |
164 | /// An actual node in the %list. |
165 | template<typename _Tp> |
166 | struct _List_node : public __detail::_List_node_base |
167 | { |
168 | #if __cplusplus201402L >= 201103L |
169 | __gnu_cxx::__aligned_membuf<_Tp> _M_storage; |
170 | _Tp* _M_valptr() { return _M_storage._M_ptr(); } |
171 | _Tp const* _M_valptr() const { return _M_storage._M_ptr(); } |
172 | #else |
173 | _Tp _M_data; |
174 | _Tp* _M_valptr() { return std::__addressof(_M_data); } |
175 | _Tp const* _M_valptr() const { return std::__addressof(_M_data); } |
176 | #endif |
177 | }; |
178 | |
179 | /** |
180 | * @brief A list::iterator. |
181 | * |
182 | * All the functions are op overloads. |
183 | */ |
184 | template<typename _Tp> |
185 | struct _List_iterator |
186 | { |
187 | typedef _List_iterator<_Tp> _Self; |
188 | typedef _List_node<_Tp> _Node; |
189 | |
190 | typedef ptrdiff_t difference_type; |
191 | typedef std::bidirectional_iterator_tag iterator_category; |
192 | typedef _Tp value_type; |
193 | typedef _Tp* pointer; |
194 | typedef _Tp& reference; |
195 | |
196 | _List_iterator() _GLIBCXX_NOEXCEPTnoexcept |
197 | : _M_node() { } |
198 | |
199 | explicit |
200 | _List_iterator(__detail::_List_node_base* __x) _GLIBCXX_NOEXCEPTnoexcept |
201 | : _M_node(__x) { } |
202 | |
203 | _Self |
204 | _M_const_cast() const _GLIBCXX_NOEXCEPTnoexcept |
205 | { return *this; } |
206 | |
207 | // Must downcast from _List_node_base to _List_node to get to value. |
208 | reference |
209 | operator*() const _GLIBCXX_NOEXCEPTnoexcept |
210 | { return *static_cast<_Node*>(_M_node)->_M_valptr(); } |
211 | |
212 | pointer |
213 | operator->() const _GLIBCXX_NOEXCEPTnoexcept |
214 | { return static_cast<_Node*>(_M_node)->_M_valptr(); } |
215 | |
216 | _Self& |
217 | operator++() _GLIBCXX_NOEXCEPTnoexcept |
218 | { |
219 | _M_node = _M_node->_M_next; |
220 | return *this; |
221 | } |
222 | |
223 | _Self |
224 | operator++(int) _GLIBCXX_NOEXCEPTnoexcept |
225 | { |
226 | _Self __tmp = *this; |
227 | _M_node = _M_node->_M_next; |
228 | return __tmp; |
229 | } |
230 | |
231 | _Self& |
232 | operator--() _GLIBCXX_NOEXCEPTnoexcept |
233 | { |
234 | _M_node = _M_node->_M_prev; |
235 | return *this; |
236 | } |
237 | |
238 | _Self |
239 | operator--(int) _GLIBCXX_NOEXCEPTnoexcept |
240 | { |
241 | _Self __tmp = *this; |
242 | _M_node = _M_node->_M_prev; |
243 | return __tmp; |
244 | } |
245 | |
246 | friend bool |
247 | operator==(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPTnoexcept |
248 | { return __x._M_node == __y._M_node; } |
249 | |
250 | #if __cpp_impl_three_way_comparison < 201907L |
251 | friend bool |
252 | operator!=(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPTnoexcept |
253 | { return __x._M_node != __y._M_node; } |
254 | #endif |
255 | |
256 | // The only member points to the %list element. |
257 | __detail::_List_node_base* _M_node; |
258 | }; |
259 | |
260 | /** |
261 | * @brief A list::const_iterator. |
262 | * |
263 | * All the functions are op overloads. |
264 | */ |
265 | template<typename _Tp> |
266 | struct _List_const_iterator |
267 | { |
268 | typedef _List_const_iterator<_Tp> _Self; |
269 | typedef const _List_node<_Tp> _Node; |
270 | typedef _List_iterator<_Tp> iterator; |
271 | |
272 | typedef ptrdiff_t difference_type; |
273 | typedef std::bidirectional_iterator_tag iterator_category; |
274 | typedef _Tp value_type; |
275 | typedef const _Tp* pointer; |
276 | typedef const _Tp& reference; |
277 | |
278 | _List_const_iterator() _GLIBCXX_NOEXCEPTnoexcept |
279 | : _M_node() { } |
280 | |
281 | explicit |
282 | _List_const_iterator(const __detail::_List_node_base* __x) |
283 | _GLIBCXX_NOEXCEPTnoexcept |
284 | : _M_node(__x) { } |
285 | |
286 | _List_const_iterator(const iterator& __x) _GLIBCXX_NOEXCEPTnoexcept |
287 | : _M_node(__x._M_node) { } |
288 | |
289 | iterator |
290 | _M_const_cast() const _GLIBCXX_NOEXCEPTnoexcept |
291 | { return iterator(const_cast<__detail::_List_node_base*>(_M_node)); } |
292 | |
293 | // Must downcast from List_node_base to _List_node to get to value. |
294 | reference |
295 | operator*() const _GLIBCXX_NOEXCEPTnoexcept |
296 | { return *static_cast<_Node*>(_M_node)->_M_valptr(); } |
297 | |
298 | pointer |
299 | operator->() const _GLIBCXX_NOEXCEPTnoexcept |
300 | { return static_cast<_Node*>(_M_node)->_M_valptr(); } |
301 | |
302 | _Self& |
303 | operator++() _GLIBCXX_NOEXCEPTnoexcept |
304 | { |
305 | _M_node = _M_node->_M_next; |
306 | return *this; |
307 | } |
308 | |
309 | _Self |
310 | operator++(int) _GLIBCXX_NOEXCEPTnoexcept |
311 | { |
312 | _Self __tmp = *this; |
313 | _M_node = _M_node->_M_next; |
314 | return __tmp; |
315 | } |
316 | |
317 | _Self& |
318 | operator--() _GLIBCXX_NOEXCEPTnoexcept |
319 | { |
320 | _M_node = _M_node->_M_prev; |
321 | return *this; |
322 | } |
323 | |
324 | _Self |
325 | operator--(int) _GLIBCXX_NOEXCEPTnoexcept |
326 | { |
327 | _Self __tmp = *this; |
328 | _M_node = _M_node->_M_prev; |
329 | return __tmp; |
330 | } |
331 | |
332 | friend bool |
333 | operator==(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPTnoexcept |
334 | { return __x._M_node == __y._M_node; } |
335 | |
336 | #if __cpp_impl_three_way_comparison < 201907L |
337 | friend bool |
338 | operator!=(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPTnoexcept |
339 | { return __x._M_node != __y._M_node; } |
340 | #endif |
341 | |
342 | // The only member points to the %list element. |
343 | const __detail::_List_node_base* _M_node; |
344 | }; |
345 | |
346 | _GLIBCXX_BEGIN_NAMESPACE_CXX11namespace __cxx11 { |
347 | /// See bits/stl_deque.h's _Deque_base for an explanation. |
348 | template<typename _Tp, typename _Alloc> |
349 | class _List_base |
350 | { |
351 | protected: |
352 | typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template |
353 | rebind<_Tp>::other _Tp_alloc_type; |
354 | typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tp_alloc_traits; |
355 | typedef typename _Tp_alloc_traits::template |
356 | rebind<_List_node<_Tp> >::other _Node_alloc_type; |
357 | typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits; |
358 | |
359 | #if !_GLIBCXX_INLINE_VERSION0 |
360 | static size_t |
361 | _S_distance(const __detail::_List_node_base* __first, |
362 | const __detail::_List_node_base* __last) |
363 | { |
364 | size_t __n = 0; |
365 | while (__first != __last) |
366 | { |
367 | __first = __first->_M_next; |
368 | ++__n; |
369 | } |
370 | return __n; |
371 | } |
372 | #endif |
373 | |
374 | struct _List_impl |
375 | : public _Node_alloc_type |
376 | { |
377 | __detail::_List_node_header _M_node; |
378 | |
379 | _List_impl() _GLIBCXX_NOEXCEPT_IF(noexcept(is_nothrow_default_constructible<_Node_alloc_type >::value) |
380 | is_nothrow_default_constructible<_Node_alloc_type>::value)noexcept(is_nothrow_default_constructible<_Node_alloc_type >::value) |
381 | : _Node_alloc_type() |
382 | { } |
383 | |
384 | _List_impl(const _Node_alloc_type& __a) _GLIBCXX_NOEXCEPTnoexcept |
385 | : _Node_alloc_type(__a) |
386 | { } |
387 | |
388 | #if __cplusplus201402L >= 201103L |
389 | _List_impl(_List_impl&&) = default; |
390 | |
391 | _List_impl(_Node_alloc_type&& __a, _List_impl&& __x) |
392 | : _Node_alloc_type(std::move(__a)), _M_node(std::move(__x._M_node)) |
393 | { } |
394 | |
395 | _List_impl(_Node_alloc_type&& __a) noexcept |
396 | : _Node_alloc_type(std::move(__a)) |
397 | { } |
398 | #endif |
399 | }; |
400 | |
401 | _List_impl _M_impl; |
402 | |
403 | #if _GLIBCXX_USE_CXX11_ABI1 |
404 | size_t _M_get_size() const { return _M_impl._M_node._M_size; } |
405 | |
406 | void _M_set_size(size_t __n) { _M_impl._M_node._M_size = __n; } |
407 | |
408 | void _M_inc_size(size_t __n) { _M_impl._M_node._M_size += __n; } |
409 | |
410 | void _M_dec_size(size_t __n) { _M_impl._M_node._M_size -= __n; } |
411 | |
412 | # if !_GLIBCXX_INLINE_VERSION0 |
413 | size_t |
414 | _M_distance(const __detail::_List_node_base* __first, |
415 | const __detail::_List_node_base* __last) const |
416 | { return _S_distance(__first, __last); } |
417 | |
418 | // return the stored size |
419 | size_t _M_node_count() const { return _M_get_size(); } |
420 | # endif |
421 | #else |
422 | // dummy implementations used when the size is not stored |
423 | size_t _M_get_size() const { return 0; } |
424 | void _M_set_size(size_t) { } |
425 | void _M_inc_size(size_t) { } |
426 | void _M_dec_size(size_t) { } |
427 | |
428 | # if !_GLIBCXX_INLINE_VERSION0 |
429 | size_t _M_distance(const void*, const void*) const { return 0; } |
430 | |
431 | // count the number of nodes |
432 | size_t _M_node_count() const |
433 | { |
434 | return _S_distance(_M_impl._M_node._M_next, |
435 | std::__addressof(_M_impl._M_node)); |
436 | } |
437 | # endif |
438 | #endif |
439 | |
440 | typename _Node_alloc_traits::pointer |
441 | _M_get_node() |
442 | { return _Node_alloc_traits::allocate(_M_impl, 1); } |
443 | |
444 | void |
445 | _M_put_node(typename _Node_alloc_traits::pointer __p) _GLIBCXX_NOEXCEPTnoexcept |
446 | { _Node_alloc_traits::deallocate(_M_impl, __p, 1); } |
447 | |
448 | public: |
449 | typedef _Alloc allocator_type; |
450 | |
451 | _Node_alloc_type& |
452 | _M_get_Node_allocator() _GLIBCXX_NOEXCEPTnoexcept |
453 | { return _M_impl; } |
454 | |
455 | const _Node_alloc_type& |
456 | _M_get_Node_allocator() const _GLIBCXX_NOEXCEPTnoexcept |
457 | { return _M_impl; } |
458 | |
459 | #if __cplusplus201402L >= 201103L |
460 | _List_base() = default; |
461 | #else |
462 | _List_base() { } |
463 | #endif |
464 | |
465 | _List_base(const _Node_alloc_type& __a) _GLIBCXX_NOEXCEPTnoexcept |
466 | : _M_impl(__a) |
467 | { } |
468 | |
469 | #if __cplusplus201402L >= 201103L |
470 | _List_base(_List_base&&) = default; |
471 | |
472 | # if !_GLIBCXX_INLINE_VERSION0 |
473 | _List_base(_List_base&& __x, _Node_alloc_type&& __a) |
474 | : _M_impl(std::move(__a)) |
475 | { |
476 | if (__x._M_get_Node_allocator() == _M_get_Node_allocator()) |
477 | _M_move_nodes(std::move(__x)); |
478 | // else caller must move individual elements. |
479 | } |
480 | # endif |
481 | |
482 | // Used when allocator is_always_equal. |
483 | _List_base(_Node_alloc_type&& __a, _List_base&& __x) |
484 | : _M_impl(std::move(__a), std::move(__x._M_impl)) |
485 | { } |
486 | |
487 | // Used when allocator !is_always_equal. |
488 | _List_base(_Node_alloc_type&& __a) |
489 | : _M_impl(std::move(__a)) |
490 | { } |
491 | |
492 | void |
493 | _M_move_nodes(_List_base&& __x) |
494 | { _M_impl._M_node._M_move_nodes(std::move(__x._M_impl._M_node)); } |
495 | #endif |
496 | |
497 | // This is what actually destroys the list. |
498 | ~_List_base() _GLIBCXX_NOEXCEPTnoexcept |
499 | { _M_clear(); } |
500 | |
501 | void |
502 | _M_clear() _GLIBCXX_NOEXCEPTnoexcept; |
503 | |
504 | void |
505 | _M_init() _GLIBCXX_NOEXCEPTnoexcept |
506 | { this->_M_impl._M_node._M_init(); } |
507 | }; |
508 | |
509 | /** |
510 | * @brief A standard container with linear time access to elements, |
511 | * and fixed time insertion/deletion at any point in the sequence. |
512 | * |
513 | * @ingroup sequences |
514 | * |
515 | * @tparam _Tp Type of element. |
516 | * @tparam _Alloc Allocator type, defaults to allocator<_Tp>. |
517 | * |
518 | * Meets the requirements of a <a href="tables.html#65">container</a>, a |
519 | * <a href="tables.html#66">reversible container</a>, and a |
520 | * <a href="tables.html#67">sequence</a>, including the |
521 | * <a href="tables.html#68">optional sequence requirements</a> with the |
522 | * %exception of @c at and @c operator[]. |
523 | * |
524 | * This is a @e doubly @e linked %list. Traversal up and down the |
525 | * %list requires linear time, but adding and removing elements (or |
526 | * @e nodes) is done in constant time, regardless of where the |
527 | * change takes place. Unlike std::vector and std::deque, |
528 | * random-access iterators are not provided, so subscripting ( @c |
529 | * [] ) access is not allowed. For algorithms which only need |
530 | * sequential access, this lack makes no difference. |
531 | * |
532 | * Also unlike the other standard containers, std::list provides |
533 | * specialized algorithms %unique to linked lists, such as |
534 | * splicing, sorting, and in-place reversal. |
535 | * |
536 | * A couple points on memory allocation for list<Tp>: |
537 | * |
538 | * First, we never actually allocate a Tp, we allocate |
539 | * List_node<Tp>'s and trust [20.1.5]/4 to DTRT. This is to ensure |
540 | * that after elements from %list<X,Alloc1> are spliced into |
541 | * %list<X,Alloc2>, destroying the memory of the second %list is a |
542 | * valid operation, i.e., Alloc1 giveth and Alloc2 taketh away. |
543 | * |
544 | * Second, a %list conceptually represented as |
545 | * @code |
546 | * A <---> B <---> C <---> D |
547 | * @endcode |
548 | * is actually circular; a link exists between A and D. The %list |
549 | * class holds (as its only data member) a private list::iterator |
550 | * pointing to @e D, not to @e A! To get to the head of the %list, |
551 | * we start at the tail and move forward by one. When this member |
552 | * iterator's next/previous pointers refer to itself, the %list is |
553 | * %empty. |
554 | */ |
555 | template<typename _Tp, typename _Alloc = std::allocator<_Tp> > |
556 | class list : protected _List_base<_Tp, _Alloc> |
557 | { |
558 | #ifdef _GLIBCXX_CONCEPT_CHECKS |
559 | // concept requirements |
560 | typedef typename _Alloc::value_type _Alloc_value_type; |
561 | # if __cplusplus201402L < 201103L |
562 | __glibcxx_class_requires(_Tp, _SGIAssignableConcept) |
563 | # endif |
564 | __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) |
565 | #endif |
566 | |
567 | #if __cplusplus201402L >= 201103L |
568 | static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value, |
569 | "std::list must have a non-const, non-volatile value_type"); |
570 | # if __cplusplus201402L > 201703L || defined __STRICT_ANSI__1 |
571 | static_assert(is_same<typename _Alloc::value_type, _Tp>::value, |
572 | "std::list must have the same value_type as its allocator"); |
573 | # endif |
574 | #endif |
575 | |
576 | typedef _List_base<_Tp, _Alloc> _Base; |
577 | typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; |
578 | typedef typename _Base::_Tp_alloc_traits _Tp_alloc_traits; |
579 | typedef typename _Base::_Node_alloc_type _Node_alloc_type; |
580 | typedef typename _Base::_Node_alloc_traits _Node_alloc_traits; |
581 | |
582 | public: |
583 | typedef _Tp value_type; |
584 | typedef typename _Tp_alloc_traits::pointer pointer; |
585 | typedef typename _Tp_alloc_traits::const_pointer const_pointer; |
586 | typedef typename _Tp_alloc_traits::reference reference; |
587 | typedef typename _Tp_alloc_traits::const_reference const_reference; |
588 | typedef _List_iterator<_Tp> iterator; |
589 | typedef _List_const_iterator<_Tp> const_iterator; |
590 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
591 | typedef std::reverse_iterator<iterator> reverse_iterator; |
592 | typedef size_t size_type; |
593 | typedef ptrdiff_t difference_type; |
594 | typedef _Alloc allocator_type; |
595 | |
596 | protected: |
597 | // Note that pointers-to-_Node's can be ctor-converted to |
598 | // iterator types. |
599 | typedef _List_node<_Tp> _Node; |
600 | |
601 | using _Base::_M_impl; |
602 | using _Base::_M_put_node; |
603 | using _Base::_M_get_node; |
604 | using _Base::_M_get_Node_allocator; |
605 | |
606 | /** |
607 | * @param __args An instance of user data. |
608 | * |
609 | * Allocates space for a new node and constructs a copy of |
610 | * @a __args in it. |
611 | */ |
612 | #if __cplusplus201402L < 201103L |
613 | _Node* |
614 | _M_create_node(const value_type& __x) |
615 | { |
616 | _Node* __p = this->_M_get_node(); |
617 | __tryif (true) |
618 | { |
619 | _Tp_alloc_type __alloc(_M_get_Node_allocator()); |
620 | __alloc.construct(__p->_M_valptr(), __x); |
621 | } |
622 | __catch(...)if (false) |
623 | { |
624 | _M_put_node(__p); |
625 | __throw_exception_again; |
626 | } |
627 | return __p; |
628 | } |
629 | #else |
630 | template<typename... _Args> |
631 | _Node* |
632 | _M_create_node(_Args&&... __args) |
633 | { |
634 | auto __p = this->_M_get_node(); |
635 | auto& __alloc = _M_get_Node_allocator(); |
636 | __allocated_ptr<_Node_alloc_type> __guard{__alloc, __p}; |
637 | _Node_alloc_traits::construct(__alloc, __p->_M_valptr(), |
638 | std::forward<_Args>(__args)...); |
639 | __guard = nullptr; |
640 | return __p; |
641 | } |
642 | #endif |
643 | |
644 | #if _GLIBCXX_USE_CXX11_ABI1 |
645 | static size_t |
646 | _S_distance(const_iterator __first, const_iterator __last) |
647 | { return std::distance(__first, __last); } |
648 | |
649 | // return the stored size |
650 | size_t |
651 | _M_node_count() const |
652 | { return this->_M_get_size(); } |
653 | #else |
654 | // dummy implementations used when the size is not stored |
655 | static size_t |
656 | _S_distance(const_iterator, const_iterator) |
657 | { return 0; } |
658 | |
659 | // count the number of nodes |
660 | size_t |
661 | _M_node_count() const |
662 | { return std::distance(begin(), end()); } |
663 | #endif |
664 | |
665 | public: |
666 | // [23.2.2.1] construct/copy/destroy |
667 | // (assign() and get_allocator() are also listed in this section) |
668 | |
669 | /** |
670 | * @brief Creates a %list with no elements. |
671 | */ |
672 | #if __cplusplus201402L >= 201103L |
673 | list() = default; |
674 | #else |
675 | list() { } |
676 | #endif |
677 | |
678 | /** |
679 | * @brief Creates a %list with no elements. |
680 | * @param __a An allocator object. |
681 | */ |
682 | explicit |
683 | list(const allocator_type& __a) _GLIBCXX_NOEXCEPTnoexcept |
684 | : _Base(_Node_alloc_type(__a)) { } |
685 | |
686 | #if __cplusplus201402L >= 201103L |
687 | /** |
688 | * @brief Creates a %list with default constructed elements. |
689 | * @param __n The number of elements to initially create. |
690 | * @param __a An allocator object. |
691 | * |
692 | * This constructor fills the %list with @a __n default |
693 | * constructed elements. |
694 | */ |
695 | explicit |
696 | list(size_type __n, const allocator_type& __a = allocator_type()) |
697 | : _Base(_Node_alloc_type(__a)) |
698 | { _M_default_initialize(__n); } |
699 | |
700 | /** |
701 | * @brief Creates a %list with copies of an exemplar element. |
702 | * @param __n The number of elements to initially create. |
703 | * @param __value An element to copy. |
704 | * @param __a An allocator object. |
705 | * |
706 | * This constructor fills the %list with @a __n copies of @a __value. |
707 | */ |
708 | list(size_type __n, const value_type& __value, |
709 | const allocator_type& __a = allocator_type()) |
710 | : _Base(_Node_alloc_type(__a)) |
711 | { _M_fill_initialize(__n, __value); } |
712 | #else |
713 | /** |
714 | * @brief Creates a %list with copies of an exemplar element. |
715 | * @param __n The number of elements to initially create. |
716 | * @param __value An element to copy. |
717 | * @param __a An allocator object. |
718 | * |
719 | * This constructor fills the %list with @a __n copies of @a __value. |
720 | */ |
721 | explicit |
722 | list(size_type __n, const value_type& __value = value_type(), |
723 | const allocator_type& __a = allocator_type()) |
724 | : _Base(_Node_alloc_type(__a)) |
725 | { _M_fill_initialize(__n, __value); } |
726 | #endif |
727 | |
728 | /** |
729 | * @brief %List copy constructor. |
730 | * @param __x A %list of identical element and allocator types. |
731 | * |
732 | * The newly-created %list uses a copy of the allocation object used |
733 | * by @a __x (unless the allocator traits dictate a different object). |
734 | */ |
735 | list(const list& __x) |
736 | : _Base(_Node_alloc_traits:: |
737 | _S_select_on_copy(__x._M_get_Node_allocator())) |
738 | { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); } |
739 | |
740 | #if __cplusplus201402L >= 201103L |
741 | /** |
742 | * @brief %List move constructor. |
743 | * |
744 | * The newly-created %list contains the exact contents of the moved |
745 | * instance. The contents of the moved instance are a valid, but |
746 | * unspecified %list. |
747 | */ |
748 | list(list&&) = default; |
749 | |
750 | /** |
751 | * @brief Builds a %list from an initializer_list |
752 | * @param __l An initializer_list of value_type. |
753 | * @param __a An allocator object. |
754 | * |
755 | * Create a %list consisting of copies of the elements in the |
756 | * initializer_list @a __l. This is linear in __l.size(). |
757 | */ |
758 | list(initializer_list<value_type> __l, |
759 | const allocator_type& __a = allocator_type()) |
760 | : _Base(_Node_alloc_type(__a)) |
761 | { _M_initialize_dispatch(__l.begin(), __l.end(), __false_type()); } |
762 | |
763 | list(const list& __x, const allocator_type& __a) |
764 | : _Base(_Node_alloc_type(__a)) |
765 | { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); } |
766 | |
767 | private: |
768 | list(list&& __x, const allocator_type& __a, true_type) noexcept |
769 | : _Base(_Node_alloc_type(__a), std::move(__x)) |
770 | { } |
771 | |
772 | list(list&& __x, const allocator_type& __a, false_type) |
773 | : _Base(_Node_alloc_type(__a)) |
774 | { |
775 | if (__x._M_get_Node_allocator() == this->_M_get_Node_allocator()) |
776 | this->_M_move_nodes(std::move(__x)); |
777 | else |
778 | insert(begin(), std::__make_move_if_noexcept_iterator(__x.begin()), |
779 | std::__make_move_if_noexcept_iterator(__x.end())); |
780 | } |
781 | |
782 | public: |
783 | list(list&& __x, const allocator_type& __a) |
784 | noexcept(_Node_alloc_traits::_S_always_equal()) |
785 | : list(std::move(__x), __a, |
786 | typename _Node_alloc_traits::is_always_equal{}) |
787 | { } |
788 | #endif |
789 | |
790 | /** |
791 | * @brief Builds a %list from a range. |
792 | * @param __first An input iterator. |
793 | * @param __last An input iterator. |
794 | * @param __a An allocator object. |
795 | * |
796 | * Create a %list consisting of copies of the elements from |
797 | * [@a __first,@a __last). This is linear in N (where N is |
798 | * distance(@a __first,@a __last)). |
799 | */ |
800 | #if __cplusplus201402L >= 201103L |
801 | template<typename _InputIterator, |
802 | typename = std::_RequireInputIter<_InputIterator>> |
803 | list(_InputIterator __first, _InputIterator __last, |
804 | const allocator_type& __a = allocator_type()) |
805 | : _Base(_Node_alloc_type(__a)) |
806 | { _M_initialize_dispatch(__first, __last, __false_type()); } |
807 | #else |
808 | template<typename _InputIterator> |
809 | list(_InputIterator __first, _InputIterator __last, |
810 | const allocator_type& __a = allocator_type()) |
811 | : _Base(_Node_alloc_type(__a)) |
812 | { |
813 | // Check whether it's an integral type. If so, it's not an iterator. |
814 | typedef typename std::__is_integer<_InputIterator>::__type _Integral; |
815 | _M_initialize_dispatch(__first, __last, _Integral()); |
816 | } |
817 | #endif |
818 | |
819 | #if __cplusplus201402L >= 201103L |
820 | /** |
821 | * No explicit dtor needed as the _Base dtor takes care of |
822 | * things. The _Base dtor only erases the elements, and note |
823 | * that if the elements themselves are pointers, the pointed-to |
824 | * memory is not touched in any way. Managing the pointer is |
825 | * the user's responsibility. |
826 | */ |
827 | ~list() = default; |
828 | #endif |
829 | |
830 | /** |
831 | * @brief %List assignment operator. |
832 | * @param __x A %list of identical element and allocator types. |
833 | * |
834 | * All the elements of @a __x are copied. |
835 | * |
836 | * Whether the allocator is copied depends on the allocator traits. |
837 | */ |
838 | list& |
839 | operator=(const list& __x); |
840 | |
841 | #if __cplusplus201402L >= 201103L |
842 | /** |
843 | * @brief %List move assignment operator. |
844 | * @param __x A %list of identical element and allocator types. |
845 | * |
846 | * The contents of @a __x are moved into this %list (without copying). |
847 | * |
848 | * Afterwards @a __x is a valid, but unspecified %list |
849 | * |
850 | * Whether the allocator is moved depends on the allocator traits. |
851 | */ |
852 | list& |
853 | operator=(list&& __x) |
854 | noexcept(_Node_alloc_traits::_S_nothrow_move()) |
855 | { |
856 | constexpr bool __move_storage = |
857 | _Node_alloc_traits::_S_propagate_on_move_assign() |
858 | || _Node_alloc_traits::_S_always_equal(); |
859 | _M_move_assign(std::move(__x), __bool_constant<__move_storage>()); |
860 | return *this; |
861 | } |
862 | |
863 | /** |
864 | * @brief %List initializer list assignment operator. |
865 | * @param __l An initializer_list of value_type. |
866 | * |
867 | * Replace the contents of the %list with copies of the elements |
868 | * in the initializer_list @a __l. This is linear in l.size(). |
869 | */ |
870 | list& |
871 | operator=(initializer_list<value_type> __l) |
872 | { |
873 | this->assign(__l.begin(), __l.end()); |
874 | return *this; |
875 | } |
876 | #endif |
877 | |
878 | /** |
879 | * @brief Assigns a given value to a %list. |
880 | * @param __n Number of elements to be assigned. |
881 | * @param __val Value to be assigned. |
882 | * |
883 | * This function fills a %list with @a __n copies of the given |
884 | * value. Note that the assignment completely changes the %list |
885 | * and that the resulting %list's size is the same as the number |
886 | * of elements assigned. |
887 | */ |
888 | void |
889 | assign(size_type __n, const value_type& __val) |
890 | { _M_fill_assign(__n, __val); } |
891 | |
892 | /** |
893 | * @brief Assigns a range to a %list. |
894 | * @param __first An input iterator. |
895 | * @param __last An input iterator. |
896 | * |
897 | * This function fills a %list with copies of the elements in the |
898 | * range [@a __first,@a __last). |
899 | * |
900 | * Note that the assignment completely changes the %list and |
901 | * that the resulting %list's size is the same as the number of |
902 | * elements assigned. |
903 | */ |
904 | #if __cplusplus201402L >= 201103L |
905 | template<typename _InputIterator, |
906 | typename = std::_RequireInputIter<_InputIterator>> |
907 | void |
908 | assign(_InputIterator __first, _InputIterator __last) |
909 | { _M_assign_dispatch(__first, __last, __false_type()); } |
910 | #else |
911 | template<typename _InputIterator> |
912 | void |
913 | assign(_InputIterator __first, _InputIterator __last) |
914 | { |
915 | // Check whether it's an integral type. If so, it's not an iterator. |
916 | typedef typename std::__is_integer<_InputIterator>::__type _Integral; |
917 | _M_assign_dispatch(__first, __last, _Integral()); |
918 | } |
919 | #endif |
920 | |
921 | #if __cplusplus201402L >= 201103L |
922 | /** |
923 | * @brief Assigns an initializer_list to a %list. |
924 | * @param __l An initializer_list of value_type. |
925 | * |
926 | * Replace the contents of the %list with copies of the elements |
927 | * in the initializer_list @a __l. This is linear in __l.size(). |
928 | */ |
929 | void |
930 | assign(initializer_list<value_type> __l) |
931 | { this->_M_assign_dispatch(__l.begin(), __l.end(), __false_type()); } |
932 | #endif |
933 | |
934 | /// Get a copy of the memory allocation object. |
935 | allocator_type |
936 | get_allocator() const _GLIBCXX_NOEXCEPTnoexcept |
937 | { return allocator_type(_Base::_M_get_Node_allocator()); } |
938 | |
939 | // iterators |
940 | /** |
941 | * Returns a read/write iterator that points to the first element in the |
942 | * %list. Iteration is done in ordinary element order. |
943 | */ |
944 | iterator |
945 | begin() _GLIBCXX_NOEXCEPTnoexcept |
946 | { return iterator(this->_M_impl._M_node._M_next); } |
947 | |
948 | /** |
949 | * Returns a read-only (constant) iterator that points to the |
950 | * first element in the %list. Iteration is done in ordinary |
951 | * element order. |
952 | */ |
953 | const_iterator |
954 | begin() const _GLIBCXX_NOEXCEPTnoexcept |
955 | { return const_iterator(this->_M_impl._M_node._M_next); } |
956 | |
957 | /** |
958 | * Returns a read/write iterator that points one past the last |
959 | * element in the %list. Iteration is done in ordinary element |
960 | * order. |
961 | */ |
962 | iterator |
963 | end() _GLIBCXX_NOEXCEPTnoexcept |
964 | { return iterator(&this->_M_impl._M_node); } |
965 | |
966 | /** |
967 | * Returns a read-only (constant) iterator that points one past |
968 | * the last element in the %list. Iteration is done in ordinary |
969 | * element order. |
970 | */ |
971 | const_iterator |
972 | end() const _GLIBCXX_NOEXCEPTnoexcept |
973 | { return const_iterator(&this->_M_impl._M_node); } |
974 | |
975 | /** |
976 | * Returns a read/write reverse iterator that points to the last |
977 | * element in the %list. Iteration is done in reverse element |
978 | * order. |
979 | */ |
980 | reverse_iterator |
981 | rbegin() _GLIBCXX_NOEXCEPTnoexcept |
982 | { return reverse_iterator(end()); } |
983 | |
984 | /** |
985 | * Returns a read-only (constant) reverse iterator that points to |
986 | * the last element in the %list. Iteration is done in reverse |
987 | * element order. |
988 | */ |
989 | const_reverse_iterator |
990 | rbegin() const _GLIBCXX_NOEXCEPTnoexcept |
991 | { return const_reverse_iterator(end()); } |
992 | |
993 | /** |
994 | * Returns a read/write reverse iterator that points to one |
995 | * before the first element in the %list. Iteration is done in |
996 | * reverse element order. |
997 | */ |
998 | reverse_iterator |
999 | rend() _GLIBCXX_NOEXCEPTnoexcept |
1000 | { return reverse_iterator(begin()); } |
1001 | |
1002 | /** |
1003 | * Returns a read-only (constant) reverse iterator that points to one |
1004 | * before the first element in the %list. Iteration is done in reverse |
1005 | * element order. |
1006 | */ |
1007 | const_reverse_iterator |
1008 | rend() const _GLIBCXX_NOEXCEPTnoexcept |
1009 | { return const_reverse_iterator(begin()); } |
1010 | |
1011 | #if __cplusplus201402L >= 201103L |
1012 | /** |
1013 | * Returns a read-only (constant) iterator that points to the |
1014 | * first element in the %list. Iteration is done in ordinary |
1015 | * element order. |
1016 | */ |
1017 | const_iterator |
1018 | cbegin() const noexcept |
1019 | { return const_iterator(this->_M_impl._M_node._M_next); } |
1020 | |
1021 | /** |
1022 | * Returns a read-only (constant) iterator that points one past |
1023 | * the last element in the %list. Iteration is done in ordinary |
1024 | * element order. |
1025 | */ |
1026 | const_iterator |
1027 | cend() const noexcept |
1028 | { return const_iterator(&this->_M_impl._M_node); } |
1029 | |
1030 | /** |
1031 | * Returns a read-only (constant) reverse iterator that points to |
1032 | * the last element in the %list. Iteration is done in reverse |
1033 | * element order. |
1034 | */ |
1035 | const_reverse_iterator |
1036 | crbegin() const noexcept |
1037 | { return const_reverse_iterator(end()); } |
1038 | |
1039 | /** |
1040 | * Returns a read-only (constant) reverse iterator that points to one |
1041 | * before the first element in the %list. Iteration is done in reverse |
1042 | * element order. |
1043 | */ |
1044 | const_reverse_iterator |
1045 | crend() const noexcept |
1046 | { return const_reverse_iterator(begin()); } |
1047 | #endif |
1048 | |
1049 | // [23.2.2.2] capacity |
1050 | /** |
1051 | * Returns true if the %list is empty. (Thus begin() would equal |
1052 | * end().) |
1053 | */ |
1054 | _GLIBCXX_NODISCARD bool |
1055 | empty() const _GLIBCXX_NOEXCEPTnoexcept |
1056 | { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; } |
1057 | |
1058 | /** Returns the number of elements in the %list. */ |
1059 | size_type |
1060 | size() const _GLIBCXX_NOEXCEPTnoexcept |
1061 | { return _M_node_count(); } |
1062 | |
1063 | /** Returns the size() of the largest possible %list. */ |
1064 | size_type |
1065 | max_size() const _GLIBCXX_NOEXCEPTnoexcept |
1066 | { return _Node_alloc_traits::max_size(_M_get_Node_allocator()); } |
1067 | |
1068 | #if __cplusplus201402L >= 201103L |
1069 | /** |
1070 | * @brief Resizes the %list to the specified number of elements. |
1071 | * @param __new_size Number of elements the %list should contain. |
1072 | * |
1073 | * This function will %resize the %list to the specified number |
1074 | * of elements. If the number is smaller than the %list's |
1075 | * current size the %list is truncated, otherwise default |
1076 | * constructed elements are appended. |
1077 | */ |
1078 | void |
1079 | resize(size_type __new_size); |
1080 | |
1081 | /** |
1082 | * @brief Resizes the %list to the specified number of elements. |
1083 | * @param __new_size Number of elements the %list should contain. |
1084 | * @param __x Data with which new elements should be populated. |
1085 | * |
1086 | * This function will %resize the %list to the specified number |
1087 | * of elements. If the number is smaller than the %list's |
1088 | * current size the %list is truncated, otherwise the %list is |
1089 | * extended and new elements are populated with given data. |
1090 | */ |
1091 | void |
1092 | resize(size_type __new_size, const value_type& __x); |
1093 | #else |
1094 | /** |
1095 | * @brief Resizes the %list to the specified number of elements. |
1096 | * @param __new_size Number of elements the %list should contain. |
1097 | * @param __x Data with which new elements should be populated. |
1098 | * |
1099 | * This function will %resize the %list to the specified number |
1100 | * of elements. If the number is smaller than the %list's |
1101 | * current size the %list is truncated, otherwise the %list is |
1102 | * extended and new elements are populated with given data. |
1103 | */ |
1104 | void |
1105 | resize(size_type __new_size, value_type __x = value_type()); |
1106 | #endif |
1107 | |
1108 | // element access |
1109 | /** |
1110 | * Returns a read/write reference to the data at the first |
1111 | * element of the %list. |
1112 | */ |
1113 | reference |
1114 | front() _GLIBCXX_NOEXCEPTnoexcept |
1115 | { return *begin(); } |
1116 | |
1117 | /** |
1118 | * Returns a read-only (constant) reference to the data at the first |
1119 | * element of the %list. |
1120 | */ |
1121 | const_reference |
1122 | front() const _GLIBCXX_NOEXCEPTnoexcept |
1123 | { return *begin(); } |
1124 | |
1125 | /** |
1126 | * Returns a read/write reference to the data at the last element |
1127 | * of the %list. |
1128 | */ |
1129 | reference |
1130 | back() _GLIBCXX_NOEXCEPTnoexcept |
1131 | { |
1132 | iterator __tmp = end(); |
1133 | --__tmp; |
1134 | return *__tmp; |
1135 | } |
1136 | |
1137 | /** |
1138 | * Returns a read-only (constant) reference to the data at the last |
1139 | * element of the %list. |
1140 | */ |
1141 | const_reference |
1142 | back() const _GLIBCXX_NOEXCEPTnoexcept |
1143 | { |
1144 | const_iterator __tmp = end(); |
1145 | --__tmp; |
1146 | return *__tmp; |
1147 | } |
1148 | |
1149 | // [23.2.2.3] modifiers |
1150 | /** |
1151 | * @brief Add data to the front of the %list. |
1152 | * @param __x Data to be added. |
1153 | * |
1154 | * This is a typical stack operation. The function creates an |
1155 | * element at the front of the %list and assigns the given data |
1156 | * to it. Due to the nature of a %list this operation can be |
1157 | * done in constant time, and does not invalidate iterators and |
1158 | * references. |
1159 | */ |
1160 | void |
1161 | push_front(const value_type& __x) |
1162 | { this->_M_insert(begin(), __x); } |
1163 | |
1164 | #if __cplusplus201402L >= 201103L |
1165 | void |
1166 | push_front(value_type&& __x) |
1167 | { this->_M_insert(begin(), std::move(__x)); } |
1168 | |
1169 | template<typename... _Args> |
1170 | #if __cplusplus201402L > 201402L |
1171 | reference |
1172 | #else |
1173 | void |
1174 | #endif |
1175 | emplace_front(_Args&&... __args) |
1176 | { |
1177 | this->_M_insert(begin(), std::forward<_Args>(__args)...); |
1178 | #if __cplusplus201402L > 201402L |
1179 | return front(); |
1180 | #endif |
1181 | } |
1182 | #endif |
1183 | |
1184 | /** |
1185 | * @brief Removes first element. |
1186 | * |
1187 | * This is a typical stack operation. It shrinks the %list by |
1188 | * one. Due to the nature of a %list this operation can be done |
1189 | * in constant time, and only invalidates iterators/references to |
1190 | * the element being removed. |
1191 | * |
1192 | * Note that no data is returned, and if the first element's data |
1193 | * is needed, it should be retrieved before pop_front() is |
1194 | * called. |
1195 | */ |
1196 | void |
1197 | pop_front() _GLIBCXX_NOEXCEPTnoexcept |
1198 | { this->_M_erase(begin()); } |
1199 | |
1200 | /** |
1201 | * @brief Add data to the end of the %list. |
1202 | * @param __x Data to be added. |
1203 | * |
1204 | * This is a typical stack operation. The function creates an |
1205 | * element at the end of the %list and assigns the given data to |
1206 | * it. Due to the nature of a %list this operation can be done |
1207 | * in constant time, and does not invalidate iterators and |
1208 | * references. |
1209 | */ |
1210 | void |
1211 | push_back(const value_type& __x) |
1212 | { this->_M_insert(end(), __x); } |
1213 | |
1214 | #if __cplusplus201402L >= 201103L |
1215 | void |
1216 | push_back(value_type&& __x) |
1217 | { this->_M_insert(end(), std::move(__x)); } |
1218 | |
1219 | template<typename... _Args> |
1220 | #if __cplusplus201402L > 201402L |
1221 | reference |
1222 | #else |
1223 | void |
1224 | #endif |
1225 | emplace_back(_Args&&... __args) |
1226 | { |
1227 | this->_M_insert(end(), std::forward<_Args>(__args)...); |
1228 | #if __cplusplus201402L > 201402L |
1229 | return back(); |
1230 | #endif |
1231 | } |
1232 | #endif |
1233 | |
1234 | /** |
1235 | * @brief Removes last element. |
1236 | * |
1237 | * This is a typical stack operation. It shrinks the %list by |
1238 | * one. Due to the nature of a %list this operation can be done |
1239 | * in constant time, and only invalidates iterators/references to |
1240 | * the element being removed. |
1241 | * |
1242 | * Note that no data is returned, and if the last element's data |
1243 | * is needed, it should be retrieved before pop_back() is called. |
1244 | */ |
1245 | void |
1246 | pop_back() _GLIBCXX_NOEXCEPTnoexcept |
1247 | { this->_M_erase(iterator(this->_M_impl._M_node._M_prev)); } |
1248 | |
1249 | #if __cplusplus201402L >= 201103L |
1250 | /** |
1251 | * @brief Constructs object in %list before specified iterator. |
1252 | * @param __position A const_iterator into the %list. |
1253 | * @param __args Arguments. |
1254 | * @return An iterator that points to the inserted data. |
1255 | * |
1256 | * This function will insert an object of type T constructed |
1257 | * with T(std::forward<Args>(args)...) before the specified |
1258 | * location. Due to the nature of a %list this operation can |
1259 | * be done in constant time, and does not invalidate iterators |
1260 | * and references. |
1261 | */ |
1262 | template<typename... _Args> |
1263 | iterator |
1264 | emplace(const_iterator __position, _Args&&... __args); |
1265 | |
1266 | /** |
1267 | * @brief Inserts given value into %list before specified iterator. |
1268 | * @param __position A const_iterator into the %list. |
1269 | * @param __x Data to be inserted. |
1270 | * @return An iterator that points to the inserted data. |
1271 | * |
1272 | * This function will insert a copy of the given value before |
1273 | * the specified location. Due to the nature of a %list this |
1274 | * operation can be done in constant time, and does not |
1275 | * invalidate iterators and references. |
1276 | */ |
1277 | iterator |
1278 | insert(const_iterator __position, const value_type& __x); |
1279 | #else |
1280 | /** |
1281 | * @brief Inserts given value into %list before specified iterator. |
1282 | * @param __position An iterator into the %list. |
1283 | * @param __x Data to be inserted. |
1284 | * @return An iterator that points to the inserted data. |
1285 | * |
1286 | * This function will insert a copy of the given value before |
1287 | * the specified location. Due to the nature of a %list this |
1288 | * operation can be done in constant time, and does not |
1289 | * invalidate iterators and references. |
1290 | */ |
1291 | iterator |
1292 | insert(iterator __position, const value_type& __x); |
1293 | #endif |
1294 | |
1295 | #if __cplusplus201402L >= 201103L |
1296 | /** |
1297 | * @brief Inserts given rvalue into %list before specified iterator. |
1298 | * @param __position A const_iterator into the %list. |
1299 | * @param __x Data to be inserted. |
1300 | * @return An iterator that points to the inserted data. |
1301 | * |
1302 | * This function will insert a copy of the given rvalue before |
1303 | * the specified location. Due to the nature of a %list this |
1304 | * operation can be done in constant time, and does not |
1305 | * invalidate iterators and references. |
1306 | */ |
1307 | iterator |
1308 | insert(const_iterator __position, value_type&& __x) |
1309 | { return emplace(__position, std::move(__x)); } |
1310 | |
1311 | /** |
1312 | * @brief Inserts the contents of an initializer_list into %list |
1313 | * before specified const_iterator. |
1314 | * @param __p A const_iterator into the %list. |
1315 | * @param __l An initializer_list of value_type. |
1316 | * @return An iterator pointing to the first element inserted |
1317 | * (or __position). |
1318 | * |
1319 | * This function will insert copies of the data in the |
1320 | * initializer_list @a l into the %list before the location |
1321 | * specified by @a p. |
1322 | * |
1323 | * This operation is linear in the number of elements inserted and |
1324 | * does not invalidate iterators and references. |
1325 | */ |
1326 | iterator |
1327 | insert(const_iterator __p, initializer_list<value_type> __l) |
1328 | { return this->insert(__p, __l.begin(), __l.end()); } |
1329 | #endif |
1330 | |
1331 | #if __cplusplus201402L >= 201103L |
1332 | /** |
1333 | * @brief Inserts a number of copies of given data into the %list. |
1334 | * @param __position A const_iterator into the %list. |
1335 | * @param __n Number of elements to be inserted. |
1336 | * @param __x Data to be inserted. |
1337 | * @return An iterator pointing to the first element inserted |
1338 | * (or __position). |
1339 | * |
1340 | * This function will insert a specified number of copies of the |
1341 | * given data before the location specified by @a position. |
1342 | * |
1343 | * This operation is linear in the number of elements inserted and |
1344 | * does not invalidate iterators and references. |
1345 | */ |
1346 | iterator |
1347 | insert(const_iterator __position, size_type __n, const value_type& __x); |
1348 | #else |
1349 | /** |
1350 | * @brief Inserts a number of copies of given data into the %list. |
1351 | * @param __position An iterator into the %list. |
1352 | * @param __n Number of elements to be inserted. |
1353 | * @param __x Data to be inserted. |
1354 | * |
1355 | * This function will insert a specified number of copies of the |
1356 | * given data before the location specified by @a position. |
1357 | * |
1358 | * This operation is linear in the number of elements inserted and |
1359 | * does not invalidate iterators and references. |
1360 | */ |
1361 | void |
1362 | insert(iterator __position, size_type __n, const value_type& __x) |
1363 | { |
1364 | list __tmp(__n, __x, get_allocator()); |
1365 | splice(__position, __tmp); |
1366 | } |
1367 | #endif |
1368 | |
1369 | #if __cplusplus201402L >= 201103L |
1370 | /** |
1371 | * @brief Inserts a range into the %list. |
1372 | * @param __position A const_iterator into the %list. |
1373 | * @param __first An input iterator. |
1374 | * @param __last An input iterator. |
1375 | * @return An iterator pointing to the first element inserted |
1376 | * (or __position). |
1377 | * |
1378 | * This function will insert copies of the data in the range [@a |
1379 | * first,@a last) into the %list before the location specified by |
1380 | * @a position. |
1381 | * |
1382 | * This operation is linear in the number of elements inserted and |
1383 | * does not invalidate iterators and references. |
1384 | */ |
1385 | template<typename _InputIterator, |
1386 | typename = std::_RequireInputIter<_InputIterator>> |
1387 | iterator |
1388 | insert(const_iterator __position, _InputIterator __first, |
1389 | _InputIterator __last); |
1390 | #else |
1391 | /** |
1392 | * @brief Inserts a range into the %list. |
1393 | * @param __position An iterator into the %list. |
1394 | * @param __first An input iterator. |
1395 | * @param __last An input iterator. |
1396 | * |
1397 | * This function will insert copies of the data in the range [@a |
1398 | * first,@a last) into the %list before the location specified by |
1399 | * @a position. |
1400 | * |
1401 | * This operation is linear in the number of elements inserted and |
1402 | * does not invalidate iterators and references. |
1403 | */ |
1404 | template<typename _InputIterator> |
1405 | void |
1406 | insert(iterator __position, _InputIterator __first, |
1407 | _InputIterator __last) |
1408 | { |
1409 | list __tmp(__first, __last, get_allocator()); |
1410 | splice(__position, __tmp); |
1411 | } |
1412 | #endif |
1413 | |
1414 | /** |
1415 | * @brief Remove element at given position. |
1416 | * @param __position Iterator pointing to element to be erased. |
1417 | * @return An iterator pointing to the next element (or end()). |
1418 | * |
1419 | * This function will erase the element at the given position and thus |
1420 | * shorten the %list by one. |
1421 | * |
1422 | * Due to the nature of a %list this operation can be done in |
1423 | * constant time, and only invalidates iterators/references to |
1424 | * the element being removed. The user is also cautioned that |
1425 | * this function only erases the element, and that if the element |
1426 | * is itself a pointer, the pointed-to memory is not touched in |
1427 | * any way. Managing the pointer is the user's responsibility. |
1428 | */ |
1429 | iterator |
1430 | #if __cplusplus201402L >= 201103L |
1431 | erase(const_iterator __position) noexcept; |
1432 | #else |
1433 | erase(iterator __position); |
1434 | #endif |
1435 | |
1436 | /** |
1437 | * @brief Remove a range of elements. |
1438 | * @param __first Iterator pointing to the first element to be erased. |
1439 | * @param __last Iterator pointing to one past the last element to be |
1440 | * erased. |
1441 | * @return An iterator pointing to the element pointed to by @a last |
1442 | * prior to erasing (or end()). |
1443 | * |
1444 | * This function will erase the elements in the range @a |
1445 | * [first,last) and shorten the %list accordingly. |
1446 | * |
1447 | * This operation is linear time in the size of the range and only |
1448 | * invalidates iterators/references to the element being removed. |
1449 | * The user is also cautioned that this function only erases the |
1450 | * elements, and that if the elements themselves are pointers, the |
1451 | * pointed-to memory is not touched in any way. Managing the pointer |
1452 | * is the user's responsibility. |
1453 | */ |
1454 | iterator |
1455 | #if __cplusplus201402L >= 201103L |
1456 | erase(const_iterator __first, const_iterator __last) noexcept |
1457 | #else |
1458 | erase(iterator __first, iterator __last) |
1459 | #endif |
1460 | { |
1461 | while (__first != __last) |
1462 | __first = erase(__first); |
1463 | return __last._M_const_cast(); |
1464 | } |
1465 | |
1466 | /** |
1467 | * @brief Swaps data with another %list. |
1468 | * @param __x A %list of the same element and allocator types. |
1469 | * |
1470 | * This exchanges the elements between two lists in constant |
1471 | * time. Note that the global std::swap() function is |
1472 | * specialized such that std::swap(l1,l2) will feed to this |
1473 | * function. |
1474 | * |
1475 | * Whether the allocators are swapped depends on the allocator traits. |
1476 | */ |
1477 | void |
1478 | swap(list& __x) _GLIBCXX_NOEXCEPTnoexcept |
1479 | { |
1480 | __detail::_List_node_base::swap(this->_M_impl._M_node, |
1481 | __x._M_impl._M_node); |
1482 | |
1483 | size_t __xsize = __x._M_get_size(); |
1484 | __x._M_set_size(this->_M_get_size()); |
1485 | this->_M_set_size(__xsize); |
1486 | |
1487 | _Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(), |
1488 | __x._M_get_Node_allocator()); |
1489 | } |
1490 | |
1491 | /** |
1492 | * Erases all the elements. Note that this function only erases |
1493 | * the elements, and that if the elements themselves are |
1494 | * pointers, the pointed-to memory is not touched in any way. |
1495 | * Managing the pointer is the user's responsibility. |
1496 | */ |
1497 | void |
1498 | clear() _GLIBCXX_NOEXCEPTnoexcept |
1499 | { |
1500 | _Base::_M_clear(); |
1501 | _Base::_M_init(); |
1502 | } |
1503 | |
1504 | // [23.2.2.4] list operations |
1505 | /** |
1506 | * @brief Insert contents of another %list. |
1507 | * @param __position Iterator referencing the element to insert before. |
1508 | * @param __x Source list. |
1509 | * |
1510 | * The elements of @a __x are inserted in constant time in front of |
1511 | * the element referenced by @a __position. @a __x becomes an empty |
1512 | * list. |
1513 | * |
1514 | * Requires this != @a __x. |
1515 | */ |
1516 | void |
1517 | #if __cplusplus201402L >= 201103L |
1518 | splice(const_iterator __position, list&& __x) noexcept |
1519 | #else |
1520 | splice(iterator __position, list& __x) |
1521 | #endif |
1522 | { |
1523 | if (!__x.empty()) |
1524 | { |
1525 | _M_check_equal_allocators(__x); |
1526 | |
1527 | this->_M_transfer(__position._M_const_cast(), |
1528 | __x.begin(), __x.end()); |
1529 | |
1530 | this->_M_inc_size(__x._M_get_size()); |
1531 | __x._M_set_size(0); |
1532 | } |
1533 | } |
1534 | |
1535 | #if __cplusplus201402L >= 201103L |
1536 | void |
1537 | splice(const_iterator __position, list& __x) noexcept |
1538 | { splice(__position, std::move(__x)); } |
1539 | #endif |
1540 | |
1541 | #if __cplusplus201402L >= 201103L |
1542 | /** |
1543 | * @brief Insert element from another %list. |
1544 | * @param __position Const_iterator referencing the element to |
1545 | * insert before. |
1546 | * @param __x Source list. |
1547 | * @param __i Const_iterator referencing the element to move. |
1548 | * |
1549 | * Removes the element in list @a __x referenced by @a __i and |
1550 | * inserts it into the current list before @a __position. |
1551 | */ |
1552 | void |
1553 | splice(const_iterator __position, list&& __x, const_iterator __i) noexcept |
1554 | #else |
1555 | /** |
1556 | * @brief Insert element from another %list. |
1557 | * @param __position Iterator referencing the element to insert before. |
1558 | * @param __x Source list. |
1559 | * @param __i Iterator referencing the element to move. |
1560 | * |
1561 | * Removes the element in list @a __x referenced by @a __i and |
1562 | * inserts it into the current list before @a __position. |
1563 | */ |
1564 | void |
1565 | splice(iterator __position, list& __x, iterator __i) |
1566 | #endif |
1567 | { |
1568 | iterator __j = __i._M_const_cast(); |
1569 | ++__j; |
1570 | if (__position == __i || __position == __j) |
1571 | return; |
1572 | |
1573 | if (this != std::__addressof(__x)) |
1574 | _M_check_equal_allocators(__x); |
1575 | |
1576 | this->_M_transfer(__position._M_const_cast(), |
1577 | __i._M_const_cast(), __j); |
1578 | |
1579 | this->_M_inc_size(1); |
1580 | __x._M_dec_size(1); |
1581 | } |
1582 | |
1583 | #if __cplusplus201402L >= 201103L |
1584 | /** |
1585 | * @brief Insert element from another %list. |
1586 | * @param __position Const_iterator referencing the element to |
1587 | * insert before. |
1588 | * @param __x Source list. |
1589 | * @param __i Const_iterator referencing the element to move. |
1590 | * |
1591 | * Removes the element in list @a __x referenced by @a __i and |
1592 | * inserts it into the current list before @a __position. |
1593 | */ |
1594 | void |
1595 | splice(const_iterator __position, list& __x, const_iterator __i) noexcept |
1596 | { splice(__position, std::move(__x), __i); } |
1597 | #endif |
1598 | |
1599 | #if __cplusplus201402L >= 201103L |
1600 | /** |
1601 | * @brief Insert range from another %list. |
1602 | * @param __position Const_iterator referencing the element to |
1603 | * insert before. |
1604 | * @param __x Source list. |
1605 | * @param __first Const_iterator referencing the start of range in x. |
1606 | * @param __last Const_iterator referencing the end of range in x. |
1607 | * |
1608 | * Removes elements in the range [__first,__last) and inserts them |
1609 | * before @a __position in constant time. |
1610 | * |
1611 | * Undefined if @a __position is in [__first,__last). |
1612 | */ |
1613 | void |
1614 | splice(const_iterator __position, list&& __x, const_iterator __first, |
1615 | const_iterator __last) noexcept |
1616 | #else |
1617 | /** |
1618 | * @brief Insert range from another %list. |
1619 | * @param __position Iterator referencing the element to insert before. |
1620 | * @param __x Source list. |
1621 | * @param __first Iterator referencing the start of range in x. |
1622 | * @param __last Iterator referencing the end of range in x. |
1623 | * |
1624 | * Removes elements in the range [__first,__last) and inserts them |
1625 | * before @a __position in constant time. |
1626 | * |
1627 | * Undefined if @a __position is in [__first,__last). |
1628 | */ |
1629 | void |
1630 | splice(iterator __position, list& __x, iterator __first, |
1631 | iterator __last) |
1632 | #endif |
1633 | { |
1634 | if (__first != __last) |
1635 | { |
1636 | if (this != std::__addressof(__x)) |
1637 | _M_check_equal_allocators(__x); |
1638 | |
1639 | size_t __n = _S_distance(__first, __last); |
1640 | this->_M_inc_size(__n); |
1641 | __x._M_dec_size(__n); |
1642 | |
1643 | this->_M_transfer(__position._M_const_cast(), |
1644 | __first._M_const_cast(), |
1645 | __last._M_const_cast()); |
1646 | } |
1647 | } |
1648 | |
1649 | #if __cplusplus201402L >= 201103L |
1650 | /** |
1651 | * @brief Insert range from another %list. |
1652 | * @param __position Const_iterator referencing the element to |
1653 | * insert before. |
1654 | * @param __x Source list. |
1655 | * @param __first Const_iterator referencing the start of range in x. |
1656 | * @param __last Const_iterator referencing the end of range in x. |
1657 | * |
1658 | * Removes elements in the range [__first,__last) and inserts them |
1659 | * before @a __position in constant time. |
1660 | * |
1661 | * Undefined if @a __position is in [__first,__last). |
1662 | */ |
1663 | void |
1664 | splice(const_iterator __position, list& __x, const_iterator __first, |
1665 | const_iterator __last) noexcept |
1666 | { splice(__position, std::move(__x), __first, __last); } |
1667 | #endif |
1668 | |
1669 | private: |
1670 | #if __cplusplus201402L > 201703L |
1671 | # define __cpp_lib_list_remove_return_type 201806L |
1672 | typedef size_type __remove_return_type; |
1673 | # define _GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG \ |
1674 | __attribute__((__abi_tag__("__cxx20"))) |
1675 | #else |
1676 | typedef void __remove_return_type; |
1677 | # define _GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG |
1678 | #endif |
1679 | public: |
1680 | |
1681 | /** |
1682 | * @brief Remove all elements equal to value. |
1683 | * @param __value The value to remove. |
1684 | * |
1685 | * Removes every element in the list equal to @a value. |
1686 | * Remaining elements stay in list order. Note that this |
1687 | * function only erases the elements, and that if the elements |
1688 | * themselves are pointers, the pointed-to memory is not |
1689 | * touched in any way. Managing the pointer is the user's |
1690 | * responsibility. |
1691 | */ |
1692 | _GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG |
1693 | __remove_return_type |
1694 | remove(const _Tp& __value); |
1695 | |
1696 | /** |
1697 | * @brief Remove all elements satisfying a predicate. |
1698 | * @tparam _Predicate Unary predicate function or object. |
1699 | * |
1700 | * Removes every element in the list for which the predicate |
1701 | * returns true. Remaining elements stay in list order. Note |
1702 | * that this function only erases the elements, and that if the |
1703 | * elements themselves are pointers, the pointed-to memory is |
1704 | * not touched in any way. Managing the pointer is the user's |
1705 | * responsibility. |
1706 | */ |
1707 | template<typename _Predicate> |
1708 | __remove_return_type |
1709 | remove_if(_Predicate); |
1710 | |
1711 | /** |
1712 | * @brief Remove consecutive duplicate elements. |
1713 | * |
1714 | * For each consecutive set of elements with the same value, |
1715 | * remove all but the first one. Remaining elements stay in |
1716 | * list order. Note that this function only erases the |
1717 | * elements, and that if the elements themselves are pointers, |
1718 | * the pointed-to memory is not touched in any way. Managing |
1719 | * the pointer is the user's responsibility. |
1720 | */ |
1721 | _GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG |
1722 | __remove_return_type |
1723 | unique(); |
1724 | |
1725 | /** |
1726 | * @brief Remove consecutive elements satisfying a predicate. |
1727 | * @tparam _BinaryPredicate Binary predicate function or object. |
1728 | * |
1729 | * For each consecutive set of elements [first,last) that |
1730 | * satisfy predicate(first,i) where i is an iterator in |
1731 | * [first,last), remove all but the first one. Remaining |
1732 | * elements stay in list order. Note that this function only |
1733 | * erases the elements, and that if the elements themselves are |
1734 | * pointers, the pointed-to memory is not touched in any way. |
1735 | * Managing the pointer is the user's responsibility. |
1736 | */ |
1737 | template<typename _BinaryPredicate> |
1738 | __remove_return_type |
1739 | unique(_BinaryPredicate); |
1740 | |
1741 | #undef _GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG |
1742 | |
1743 | /** |
1744 | * @brief Merge sorted lists. |
1745 | * @param __x Sorted list to merge. |
1746 | * |
1747 | * Assumes that both @a __x and this list are sorted according to |
1748 | * operator<(). Merges elements of @a __x into this list in |
1749 | * sorted order, leaving @a __x empty when complete. Elements in |
1750 | * this list precede elements in @a __x that are equal. |
1751 | */ |
1752 | #if __cplusplus201402L >= 201103L |
1753 | void |
1754 | merge(list&& __x); |
1755 | |
1756 | void |
1757 | merge(list& __x) |
1758 | { merge(std::move(__x)); } |
1759 | #else |
1760 | void |
1761 | merge(list& __x); |
1762 | #endif |
1763 | |
1764 | /** |
1765 | * @brief Merge sorted lists according to comparison function. |
1766 | * @tparam _StrictWeakOrdering Comparison function defining |
1767 | * sort order. |
1768 | * @param __x Sorted list to merge. |
1769 | * @param __comp Comparison functor. |
1770 | * |
1771 | * Assumes that both @a __x and this list are sorted according to |
1772 | * StrictWeakOrdering. Merges elements of @a __x into this list |
1773 | * in sorted order, leaving @a __x empty when complete. Elements |
1774 | * in this list precede elements in @a __x that are equivalent |
1775 | * according to StrictWeakOrdering(). |
1776 | */ |
1777 | #if __cplusplus201402L >= 201103L |
1778 | template<typename _StrictWeakOrdering> |
1779 | void |
1780 | merge(list&& __x, _StrictWeakOrdering __comp); |
1781 | |
1782 | template<typename _StrictWeakOrdering> |
1783 | void |
1784 | merge(list& __x, _StrictWeakOrdering __comp) |
1785 | { merge(std::move(__x), __comp); } |
1786 | #else |
1787 | template<typename _StrictWeakOrdering> |
1788 | void |
1789 | merge(list& __x, _StrictWeakOrdering __comp); |
1790 | #endif |
1791 | |
1792 | /** |
1793 | * @brief Reverse the elements in list. |
1794 | * |
1795 | * Reverse the order of elements in the list in linear time. |
1796 | */ |
1797 | void |
1798 | reverse() _GLIBCXX_NOEXCEPTnoexcept |
1799 | { this->_M_impl._M_node._M_reverse(); } |
1800 | |
1801 | /** |
1802 | * @brief Sort the elements. |
1803 | * |
1804 | * Sorts the elements of this list in NlogN time. Equivalent |
1805 | * elements remain in list order. |
1806 | */ |
1807 | void |
1808 | sort(); |
1809 | |
1810 | /** |
1811 | * @brief Sort the elements according to comparison function. |
1812 | * |
1813 | * Sorts the elements of this list in NlogN time. Equivalent |
1814 | * elements remain in list order. |
1815 | */ |
1816 | template<typename _StrictWeakOrdering> |
1817 | void |
1818 | sort(_StrictWeakOrdering); |
1819 | |
1820 | protected: |
1821 | // Internal constructor functions follow. |
1822 | |
1823 | // Called by the range constructor to implement [23.1.1]/9 |
1824 | |
1825 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1826 | // 438. Ambiguity in the "do the right thing" clause |
1827 | template<typename _Integer> |
1828 | void |
1829 | _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) |
1830 | { _M_fill_initialize(static_cast<size_type>(__n), __x); } |
1831 | |
1832 | // Called by the range constructor to implement [23.1.1]/9 |
1833 | template<typename _InputIterator> |
1834 | void |
1835 | _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, |
1836 | __false_type) |
1837 | { |
1838 | for (; __first != __last; ++__first) |
1839 | #if __cplusplus201402L >= 201103L |
1840 | emplace_back(*__first); |
1841 | #else |
1842 | push_back(*__first); |
1843 | #endif |
1844 | } |
1845 | |
1846 | // Called by list(n,v,a), and the range constructor when it turns out |
1847 | // to be the same thing. |
1848 | void |
1849 | _M_fill_initialize(size_type __n, const value_type& __x) |
1850 | { |
1851 | for (; __n; --__n) |
1852 | push_back(__x); |
1853 | } |
1854 | |
1855 | #if __cplusplus201402L >= 201103L |
1856 | // Called by list(n). |
1857 | void |
1858 | _M_default_initialize(size_type __n) |
1859 | { |
1860 | for (; __n; --__n) |
1861 | emplace_back(); |
1862 | } |
1863 | |
1864 | // Called by resize(sz). |
1865 | void |
1866 | _M_default_append(size_type __n); |
1867 | #endif |
1868 | |
1869 | // Internal assign functions follow. |
1870 | |
1871 | // Called by the range assign to implement [23.1.1]/9 |
1872 | |
1873 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1874 | // 438. Ambiguity in the "do the right thing" clause |
1875 | template<typename _Integer> |
1876 | void |
1877 | _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) |
1878 | { _M_fill_assign(__n, __val); } |
1879 | |
1880 | // Called by the range assign to implement [23.1.1]/9 |
1881 | template<typename _InputIterator> |
1882 | void |
1883 | _M_assign_dispatch(_InputIterator __first, _InputIterator __last, |
1884 | __false_type); |
1885 | |
1886 | // Called by assign(n,t), and the range assign when it turns out |
1887 | // to be the same thing. |
1888 | void |
1889 | _M_fill_assign(size_type __n, const value_type& __val); |
1890 | |
1891 | |
1892 | // Moves the elements from [first,last) before position. |
1893 | void |
1894 | _M_transfer(iterator __position, iterator __first, iterator __last) |
1895 | { __position._M_node->_M_transfer(__first._M_node, __last._M_node); } |
1896 | |
1897 | // Inserts new element at position given and with value given. |
1898 | #if __cplusplus201402L < 201103L |
1899 | void |
1900 | _M_insert(iterator __position, const value_type& __x) |
1901 | { |
1902 | _Node* __tmp = _M_create_node(__x); |
1903 | __tmp->_M_hook(__position._M_node); |
1904 | this->_M_inc_size(1); |
1905 | } |
1906 | #else |
1907 | template<typename... _Args> |
1908 | void |
1909 | _M_insert(iterator __position, _Args&&... __args) |
1910 | { |
1911 | _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...); |
1912 | __tmp->_M_hook(__position._M_node); |
1913 | this->_M_inc_size(1); |
1914 | } |
1915 | #endif |
1916 | |
1917 | // Erases element at position given. |
1918 | void |
1919 | _M_erase(iterator __position) _GLIBCXX_NOEXCEPTnoexcept |
1920 | { |
1921 | this->_M_dec_size(1); |
1922 | __position._M_node->_M_unhook(); |
1923 | _Node* __n = static_cast<_Node*>(__position._M_node); |
1924 | #if __cplusplus201402L >= 201103L |
1925 | _Node_alloc_traits::destroy(_M_get_Node_allocator(), __n->_M_valptr()); |
1926 | #else |
1927 | _Tp_alloc_type(_M_get_Node_allocator()).destroy(__n->_M_valptr()); |
1928 | #endif |
1929 | |
1930 | _M_put_node(__n); |
1931 | } |
1932 | |
1933 | // To implement the splice (and merge) bits of N1599. |
1934 | void |
1935 | _M_check_equal_allocators(list& __x) _GLIBCXX_NOEXCEPTnoexcept |
1936 | { |
1937 | if (std::__alloc_neq<typename _Base::_Node_alloc_type>:: |
1938 | _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator())) |
1939 | __builtin_abort(); |
1940 | } |
1941 | |
1942 | // Used to implement resize. |
1943 | const_iterator |
1944 | _M_resize_pos(size_type& __new_size) const; |
1945 | |
1946 | #if __cplusplus201402L >= 201103L |
1947 | void |
1948 | _M_move_assign(list&& __x, true_type) noexcept |
1949 | { |
1950 | this->_M_clear(); |
1951 | this->_M_move_nodes(std::move(__x)); |
1952 | std::__alloc_on_move(this->_M_get_Node_allocator(), |
1953 | __x._M_get_Node_allocator()); |
1954 | } |
1955 | |
1956 | void |
1957 | _M_move_assign(list&& __x, false_type) |
1958 | { |
1959 | if (__x._M_get_Node_allocator() == this->_M_get_Node_allocator()) |
1960 | _M_move_assign(std::move(__x), true_type{}); |
1961 | else |
1962 | // The rvalue's allocator cannot be moved, or is not equal, |
1963 | // so we need to individually move each element. |
1964 | _M_assign_dispatch(std::make_move_iterator(__x.begin()), |
1965 | std::make_move_iterator(__x.end()), |
1966 | __false_type{}); |
1967 | } |
1968 | #endif |
1969 | }; |
1970 | |
1971 | #if __cpp_deduction_guides >= 201606 |
1972 | template<typename _InputIterator, typename _ValT |
1973 | = typename iterator_traits<_InputIterator>::value_type, |
1974 | typename _Allocator = allocator<_ValT>, |
1975 | typename = _RequireInputIter<_InputIterator>, |
1976 | typename = _RequireAllocator<_Allocator>> |
1977 | list(_InputIterator, _InputIterator, _Allocator = _Allocator()) |
1978 | -> list<_ValT, _Allocator>; |
1979 | #endif |
1980 | |
1981 | _GLIBCXX_END_NAMESPACE_CXX11} |
1982 | |
1983 | /** |
1984 | * @brief List equality comparison. |
1985 | * @param __x A %list. |
1986 | * @param __y A %list of the same type as @a __x. |
1987 | * @return True iff the size and elements of the lists are equal. |
1988 | * |
1989 | * This is an equivalence relation. It is linear in the size of |
1990 | * the lists. Lists are considered equivalent if their sizes are |
1991 | * equal, and if corresponding elements compare equal. |
1992 | */ |
1993 | template<typename _Tp, typename _Alloc> |
1994 | inline bool |
1995 | operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) |
1996 | { |
1997 | #if _GLIBCXX_USE_CXX11_ABI1 |
1998 | if (__x.size() != __y.size()) |
1999 | return false; |
2000 | #endif |
2001 | |
2002 | typedef typename list<_Tp, _Alloc>::const_iterator const_iterator; |
2003 | const_iterator __end1 = __x.end(); |
2004 | const_iterator __end2 = __y.end(); |
2005 | |
2006 | const_iterator __i1 = __x.begin(); |
2007 | const_iterator __i2 = __y.begin(); |
2008 | while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) |
2009 | { |
2010 | ++__i1; |
2011 | ++__i2; |
2012 | } |
2013 | return __i1 == __end1 && __i2 == __end2; |
2014 | } |
2015 | |
2016 | #if __cpp_lib_three_way_comparison |
2017 | /** |
2018 | * @brief List ordering relation. |
2019 | * @param __x A `list`. |
2020 | * @param __y A `list` of the same type as `__x`. |
2021 | * @return A value indicating whether `__x` is less than, equal to, |
2022 | * greater than, or incomparable with `__y`. |
2023 | * |
2024 | * See `std::lexicographical_compare_three_way()` for how the determination |
2025 | * is made. This operator is used to synthesize relational operators like |
2026 | * `<` and `>=` etc. |
2027 | */ |
2028 | template<typename _Tp, typename _Alloc> |
2029 | inline __detail::__synth3way_t<_Tp> |
2030 | operator<=>(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) |
2031 | { |
2032 | return std::lexicographical_compare_three_way(__x.begin(), __x.end(), |
2033 | __y.begin(), __y.end(), |
2034 | __detail::__synth3way); |
2035 | } |
2036 | #else |
2037 | /** |
2038 | * @brief List ordering relation. |
2039 | * @param __x A %list. |
2040 | * @param __y A %list of the same type as @a __x. |
2041 | * @return True iff @a __x is lexicographically less than @a __y. |
2042 | * |
2043 | * This is a total ordering relation. It is linear in the size of the |
2044 | * lists. The elements must be comparable with @c <. |
2045 | * |
2046 | * See std::lexicographical_compare() for how the determination is made. |
2047 | */ |
2048 | template<typename _Tp, typename _Alloc> |
2049 | inline bool |
2050 | operator<(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) |
2051 | { return std::lexicographical_compare(__x.begin(), __x.end(), |
2052 | __y.begin(), __y.end()); } |
2053 | |
2054 | /// Based on operator== |
2055 | template<typename _Tp, typename _Alloc> |
2056 | inline bool |
2057 | operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) |
2058 | { return !(__x == __y); } |
2059 | |
2060 | /// Based on operator< |
2061 | template<typename _Tp, typename _Alloc> |
2062 | inline bool |
2063 | operator>(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) |
2064 | { return __y < __x; } |
2065 | |
2066 | /// Based on operator< |
2067 | template<typename _Tp, typename _Alloc> |
2068 | inline bool |
2069 | operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) |
2070 | { return !(__y < __x); } |
2071 | |
2072 | /// Based on operator< |
2073 | template<typename _Tp, typename _Alloc> |
2074 | inline bool |
2075 | operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) |
2076 | { return !(__x < __y); } |
2077 | #endif // three-way comparison |
2078 | |
2079 | /// See std::list::swap(). |
2080 | template<typename _Tp, typename _Alloc> |
2081 | inline void |
2082 | swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) |
2083 | _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))noexcept(noexcept(__x.swap(__y))) |
2084 | { __x.swap(__y); } |
2085 | |
2086 | _GLIBCXX_END_NAMESPACE_CONTAINER |
2087 | |
2088 | #if _GLIBCXX_USE_CXX11_ABI1 |
2089 | |
2090 | // Detect when distance is used to compute the size of the whole list. |
2091 | template<typename _Tp> |
2092 | inline ptrdiff_t |
2093 | __distance(_GLIBCXX_STD_Cstd::_List_iterator<_Tp> __first, |
2094 | _GLIBCXX_STD_Cstd::_List_iterator<_Tp> __last, |
2095 | input_iterator_tag __tag) |
2096 | { |
2097 | typedef _GLIBCXX_STD_Cstd::_List_const_iterator<_Tp> _CIter; |
2098 | return std::__distance(_CIter(__first), _CIter(__last), __tag); |
2099 | } |
2100 | |
2101 | template<typename _Tp> |
2102 | inline ptrdiff_t |
2103 | __distance(_GLIBCXX_STD_Cstd::_List_const_iterator<_Tp> __first, |
2104 | _GLIBCXX_STD_Cstd::_List_const_iterator<_Tp> __last, |
2105 | input_iterator_tag) |
2106 | { |
2107 | typedef __detail::_List_node_header _Sentinel; |
2108 | _GLIBCXX_STD_Cstd::_List_const_iterator<_Tp> __beyond = __last; |
2109 | ++__beyond; |
2110 | const bool __whole = __first == __beyond; |
2111 | if (__builtin_constant_p (__whole) && __whole) |
2112 | return static_cast<const _Sentinel*>(__last._M_node)->_M_size; |
2113 | |
2114 | ptrdiff_t __n = 0; |
2115 | while (__first != __last) |
2116 | { |
2117 | ++__first; |
2118 | ++__n; |
2119 | } |
2120 | return __n; |
2121 | } |
2122 | #endif |
2123 | |
2124 | _GLIBCXX_END_NAMESPACE_VERSION |
2125 | } // namespace std |
2126 | |
2127 | #endif /* _STL_LIST_H */ |