1 //===-- CompilerType.h ------------------------------------------*- 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 #ifndef LLDB_SYMBOL_COMPILERTYPE_H 10 #define LLDB_SYMBOL_COMPILERTYPE_H 11 12 #include <functional> 13 #include <string> 14 #include <vector> 15 16 #include "lldb/lldb-private.h" 17 #include "llvm/ADT/APSInt.h" 18 19 namespace lldb_private { 20 21 class DataExtractor; 22 23 /// Generic representation of a type in a programming language. 24 /// 25 /// This class serves as an abstraction for a type inside one of the TypeSystems 26 /// implemented by the language plugins. It does not have any actual logic in it 27 /// but only stores an opaque pointer and a pointer to the TypeSystem that 28 /// gives meaning to this opaque pointer. All methods of this class should call 29 /// their respective method in the TypeSystem interface and pass the opaque 30 /// pointer along. 31 /// 32 /// \see lldb_private::TypeSystem 33 class CompilerType { 34 public: 35 /// Creates a CompilerType with the given TypeSystem and opaque compiler type. 36 /// 37 /// This constructor should only be called from the respective TypeSystem 38 /// implementation. 39 /// 40 /// \see lldb_private::TypeSystemClang::GetType(clang::QualType) 41 CompilerType(TypeSystem *type_system, lldb::opaque_compiler_type_t type) 42 : m_type(type), m_type_system(type_system) { 43 assert(Verify() && "verification failed"); 44 } 45 46 CompilerType(const CompilerType &rhs) 47 : m_type(rhs.m_type), m_type_system(rhs.m_type_system) {} 48 49 CompilerType() = default; 50 51 /// Operators. 52 /// \{ 53 const CompilerType &operator=(const CompilerType &rhs) { 54 m_type = rhs.m_type; 55 m_type_system = rhs.m_type_system; 56 return *this; 57 } 58 59 bool operator<(const CompilerType &rhs) const { 60 if (m_type_system == rhs.m_type_system) 61 return m_type < rhs.m_type; 62 return m_type_system < rhs.m_type_system; 63 } 64 /// \} 65 66 /// Tests. 67 /// \{ 68 explicit operator bool() const { 69 return m_type != nullptr && m_type_system != nullptr; 70 } 71 72 bool IsValid() const { return m_type != nullptr && m_type_system != nullptr; } 73 74 bool IsArrayType(CompilerType *element_type = nullptr, 75 uint64_t *size = nullptr, 76 bool *is_incomplete = nullptr) const; 77 78 bool IsVectorType(CompilerType *element_type = nullptr, 79 uint64_t *size = nullptr) const; 80 81 bool IsArrayOfScalarType() const; 82 83 bool IsAggregateType() const; 84 85 bool IsAnonymousType() const; 86 87 bool IsScopedEnumerationType() const; 88 89 bool IsBeingDefined() const; 90 91 bool IsCharType() const; 92 93 bool IsCompleteType() const; 94 95 bool IsConst() const; 96 97 bool IsCStringType(uint32_t &length) const; 98 99 bool IsDefined() const; 100 101 bool IsFloatingPointType(uint32_t &count, bool &is_complex) const; 102 103 bool IsFunctionType() const; 104 105 uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const; 106 107 size_t GetNumberOfFunctionArguments() const; 108 109 CompilerType GetFunctionArgumentAtIndex(const size_t index) const; 110 111 bool IsVariadicFunctionType() const; 112 113 bool IsFunctionPointerType() const; 114 115 bool 116 IsBlockPointerType(CompilerType *function_pointer_type_ptr = nullptr) const; 117 118 bool IsIntegerType(bool &is_signed) const; 119 120 bool IsEnumerationType(bool &is_signed) const; 121 122 bool IsIntegerOrEnumerationType(bool &is_signed) const; 123 124 bool IsPolymorphicClass() const; 125 126 /// \param target_type Can pass nullptr. 127 bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus, 128 bool check_objc) const; 129 130 bool IsPointerToScalarType() const; 131 132 bool IsRuntimeGeneratedType() const; 133 134 bool IsPointerType(CompilerType *pointee_type = nullptr) const; 135 136 bool IsPointerOrReferenceType(CompilerType *pointee_type = nullptr) const; 137 138 bool IsReferenceType(CompilerType *pointee_type = nullptr, 139 bool *is_rvalue = nullptr) const; 140 141 bool ShouldTreatScalarValueAsAddress() const; 142 143 bool IsScalarType() const; 144 145 bool IsTypedefType() const; 146 147 bool IsVoidType() const; 148 /// \} 149 150 /// Type Completion. 151 /// \{ 152 bool GetCompleteType() const; 153 /// \} 154 155 /// AST related queries. 156 /// \{ 157 size_t GetPointerByteSize() const; 158 /// \} 159 160 /// Accessors. 161 /// \{ 162 TypeSystem *GetTypeSystem() const { return m_type_system; } 163 164 ConstString GetTypeName() const; 165 166 ConstString GetDisplayTypeName() const; 167 168 uint32_t 169 GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) const; 170 171 lldb::LanguageType GetMinimumLanguage(); 172 173 lldb::opaque_compiler_type_t GetOpaqueQualType() const { return m_type; } 174 175 lldb::TypeClass GetTypeClass() const; 176 177 void SetCompilerType(TypeSystem *type_system, 178 lldb::opaque_compiler_type_t type); 179 180 unsigned GetTypeQualifiers() const; 181 /// \} 182 183 /// Creating related types. 184 /// \{ 185 CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const; 186 187 CompilerType GetArrayType(uint64_t size) const; 188 189 CompilerType GetCanonicalType() const; 190 191 CompilerType GetFullyUnqualifiedType() const; 192 193 CompilerType GetEnumerationIntegerType() const; 194 195 /// Returns -1 if this isn't a function of if the function doesn't 196 /// have a prototype Returns a value >= 0 if there is a prototype. 197 int GetFunctionArgumentCount() const; 198 199 CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const; 200 201 CompilerType GetFunctionReturnType() const; 202 203 size_t GetNumMemberFunctions() const; 204 205 TypeMemberFunctionImpl GetMemberFunctionAtIndex(size_t idx); 206 207 /// If this type is a reference to a type (L value or R value reference), 208 /// return a new type with the reference removed, else return the current type 209 /// itself. 210 CompilerType GetNonReferenceType() const; 211 212 /// If this type is a pointer type, return the type that the pointer points 213 /// to, else return an invalid type. 214 CompilerType GetPointeeType() const; 215 216 /// Return a new CompilerType that is a pointer to this type 217 CompilerType GetPointerType() const; 218 219 /// Return a new CompilerType that is a L value reference to this type if this 220 /// type is valid and the type system supports L value references, else return 221 /// an invalid type. 222 CompilerType GetLValueReferenceType() const; 223 224 /// Return a new CompilerType that is a R value reference to this type if this 225 /// type is valid and the type system supports R value references, else return 226 /// an invalid type. 227 CompilerType GetRValueReferenceType() const; 228 229 /// Return a new CompilerType adds a const modifier to this type if this type 230 /// is valid and the type system supports const modifiers, else return an 231 /// invalid type. 232 CompilerType AddConstModifier() const; 233 234 /// Return a new CompilerType adds a volatile modifier to this type if this 235 /// type is valid and the type system supports volatile modifiers, else return 236 /// an invalid type. 237 CompilerType AddVolatileModifier() const; 238 239 /// Return a new CompilerType that is the atomic type of this type. If this 240 /// type is not valid or the type system doesn't support atomic types, this 241 /// returns an invalid type. 242 CompilerType GetAtomicType() const; 243 244 /// Return a new CompilerType adds a restrict modifier to this type if this 245 /// type is valid and the type system supports restrict modifiers, else return 246 /// an invalid type. 247 CompilerType AddRestrictModifier() const; 248 249 /// Create a typedef to this type using "name" as the name of the typedef this 250 /// type is valid and the type system supports typedefs, else return an 251 /// invalid type. 252 /// \param payload The typesystem-specific \p lldb::Type payload. 253 CompilerType CreateTypedef(const char *name, 254 const CompilerDeclContext &decl_ctx, 255 uint32_t payload) const; 256 257 /// If the current object represents a typedef type, get the underlying type 258 CompilerType GetTypedefedType() const; 259 260 /// Create related types using the current type's AST 261 CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const; 262 /// \} 263 264 /// Exploring the type. 265 /// \{ 266 struct IntegralTemplateArgument; 267 268 /// Return the size of the type in bytes. 269 llvm::Optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope) const; 270 /// Return the size of the type in bits. 271 llvm::Optional<uint64_t> GetBitSize(ExecutionContextScope *exe_scope) const; 272 273 lldb::Encoding GetEncoding(uint64_t &count) const; 274 275 lldb::Format GetFormat() const; 276 277 llvm::Optional<size_t> 278 GetTypeBitAlign(ExecutionContextScope *exe_scope) const; 279 280 uint32_t GetNumChildren(bool omit_empty_base_classes, 281 const ExecutionContext *exe_ctx) const; 282 283 lldb::BasicType GetBasicTypeEnumeration() const; 284 285 static lldb::BasicType GetBasicTypeEnumeration(ConstString name); 286 287 /// If this type is an enumeration, iterate through all of its enumerators 288 /// using a callback. If the callback returns true, keep iterating, else abort 289 /// the iteration. 290 void ForEachEnumerator( 291 std::function<bool(const CompilerType &integer_type, ConstString name, 292 const llvm::APSInt &value)> const &callback) const; 293 294 uint32_t GetNumFields() const; 295 296 CompilerType GetFieldAtIndex(size_t idx, std::string &name, 297 uint64_t *bit_offset_ptr, 298 uint32_t *bitfield_bit_size_ptr, 299 bool *is_bitfield_ptr) const; 300 301 uint32_t GetNumDirectBaseClasses() const; 302 303 uint32_t GetNumVirtualBaseClasses() const; 304 305 CompilerType GetDirectBaseClassAtIndex(size_t idx, 306 uint32_t *bit_offset_ptr) const; 307 308 CompilerType GetVirtualBaseClassAtIndex(size_t idx, 309 uint32_t *bit_offset_ptr) const; 310 311 uint32_t GetIndexOfFieldWithName(const char *name, 312 CompilerType *field_compiler_type = nullptr, 313 uint64_t *bit_offset_ptr = nullptr, 314 uint32_t *bitfield_bit_size_ptr = nullptr, 315 bool *is_bitfield_ptr = nullptr) const; 316 317 CompilerType GetChildCompilerTypeAtIndex( 318 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, 319 bool omit_empty_base_classes, bool ignore_array_bounds, 320 std::string &child_name, uint32_t &child_byte_size, 321 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, 322 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, 323 bool &child_is_deref_of_parent, ValueObject *valobj, 324 uint64_t &language_flags) const; 325 326 /// Lookup a child given a name. This function will match base class names and 327 /// member member names in "clang_type" only, not descendants. 328 uint32_t GetIndexOfChildWithName(const char *name, 329 bool omit_empty_base_classes) const; 330 331 /// Lookup a child member given a name. This function will match member names 332 /// only and will descend into "clang_type" children in search for the first 333 /// member in this class, or any base class that matches "name". 334 /// TODO: Return all matches for a given name by returning a 335 /// vector<vector<uint32_t>> 336 /// so we catch all names that match a given child name, not just the first. 337 size_t 338 GetIndexOfChildMemberWithName(const char *name, bool omit_empty_base_classes, 339 std::vector<uint32_t> &child_indexes) const; 340 341 size_t GetNumTemplateArguments() const; 342 343 lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx) const; 344 CompilerType GetTypeTemplateArgument(size_t idx) const; 345 346 /// Returns the value of the template argument and its type. 347 llvm::Optional<IntegralTemplateArgument> 348 GetIntegralTemplateArgument(size_t idx) const; 349 350 CompilerType GetTypeForFormatters() const; 351 352 LazyBool ShouldPrintAsOneLiner(ValueObject *valobj) const; 353 354 bool IsMeaninglessWithoutDynamicResolution() const; 355 /// \} 356 357 /// Dumping types. 358 /// \{ 359 #ifndef NDEBUG 360 /// Convenience LLVM-style dump method for use in the debugger only. 361 /// Don't call this function from actual code. 362 LLVM_DUMP_METHOD void dump() const; 363 #endif 364 365 void DumpValue(ExecutionContext *exe_ctx, Stream *s, lldb::Format format, 366 const DataExtractor &data, lldb::offset_t data_offset, 367 size_t data_byte_size, uint32_t bitfield_bit_size, 368 uint32_t bitfield_bit_offset, bool show_types, 369 bool show_summary, bool verbose, uint32_t depth); 370 371 bool DumpTypeValue(Stream *s, lldb::Format format, const DataExtractor &data, 372 lldb::offset_t data_offset, size_t data_byte_size, 373 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, 374 ExecutionContextScope *exe_scope); 375 376 void DumpSummary(ExecutionContext *exe_ctx, Stream *s, 377 const DataExtractor &data, lldb::offset_t data_offset, 378 size_t data_byte_size); 379 380 /// Dump to stdout. 381 void DumpTypeDescription(lldb::DescriptionLevel level = 382 lldb::eDescriptionLevelFull) const; 383 384 /// Print a description of the type to a stream. The exact implementation 385 /// varies, but the expectation is that eDescriptionLevelFull returns a 386 /// source-like representation of the type, whereas eDescriptionLevelVerbose 387 /// does a dump of the underlying AST if applicable. 388 void DumpTypeDescription(Stream *s, lldb::DescriptionLevel level = 389 lldb::eDescriptionLevelFull) const; 390 /// \} 391 392 bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset, 393 size_t data_byte_size, Scalar &value, 394 ExecutionContextScope *exe_scope) const; 395 void Clear() { 396 m_type = nullptr; 397 m_type_system = nullptr; 398 } 399 400 private: 401 #ifndef NDEBUG 402 /// If the type is valid, ask the TypeSystem to verify the integrity 403 /// of the type to catch CompilerTypes that mix and match invalid 404 /// TypeSystem/Opaque type pairs. 405 bool Verify() const; 406 #endif 407 408 lldb::opaque_compiler_type_t m_type = nullptr; 409 TypeSystem *m_type_system = nullptr; 410 }; 411 412 bool operator==(const CompilerType &lhs, const CompilerType &rhs); 413 bool operator!=(const CompilerType &lhs, const CompilerType &rhs); 414 415 struct CompilerType::IntegralTemplateArgument { 416 llvm::APSInt value; 417 CompilerType type; 418 }; 419 420 } // namespace lldb_private 421 422 #endif // LLDB_SYMBOL_COMPILERTYPE_H 423