aboutsummaryrefslogtreecommitdiffstats
path: root/source/Symbol
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
commit14f1b3e8826ce43b978db93a62d1166055db5394 (patch)
tree0a00ad8d3498783fe0193f3b656bca17c4c8697d /source/Symbol
parent4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff)
downloadsrc-14f1b3e8826ce43b978db93a62d1166055db5394.tar.gz
src-14f1b3e8826ce43b978db93a62d1166055db5394.zip
Vendor import of lldb trunk r290819:vendor/lldb/lldb-trunk-r290819
Notes
Notes: svn path=/vendor/lldb/dist/; revision=311128 svn path=/vendor/lldb/lldb-trunk-r290819/; revision=311129; tag=vendor/lldb/lldb-trunk-r290819
Diffstat (limited to 'source/Symbol')
-rw-r--r--source/Symbol/ArmUnwindInfo.cpp696
-rw-r--r--source/Symbol/Block.cpp962
-rw-r--r--source/Symbol/CMakeLists.txt1
-rw-r--r--source/Symbol/ClangASTContext.cpp18278
-rw-r--r--source/Symbol/ClangASTImporter.cpp1952
-rw-r--r--source/Symbol/ClangExternalASTSourceCallbacks.cpp238
-rw-r--r--source/Symbol/ClangExternalASTSourceCommon.cpp131
-rw-r--r--source/Symbol/ClangUtil.cpp50
-rw-r--r--source/Symbol/CompactUnwindInfo.cpp2944
-rw-r--r--source/Symbol/CompileUnit.cpp712
-rw-r--r--source/Symbol/CompilerDecl.cpp60
-rw-r--r--source/Symbol/CompilerDeclContext.cpp94
-rw-r--r--source/Symbol/CompilerType.cpp1779
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp1642
-rw-r--r--source/Symbol/DebugMacros.cpp55
-rw-r--r--source/Symbol/Declaration.cpp138
-rw-r--r--source/Symbol/FuncUnwinders.cpp665
-rw-r--r--source/Symbol/Function.cpp1012
-rw-r--r--source/Symbol/GoASTContext.cpp2488
-rw-r--r--source/Symbol/JavaASTContext.cpp2290
-rw-r--r--source/Symbol/LineEntry.cpp445
-rw-r--r--source/Symbol/LineTable.cpp1000
-rw-r--r--source/Symbol/OCamlASTContext.cpp669
-rw-r--r--source/Symbol/ObjectFile.cpp1143
-rw-r--r--source/Symbol/Symbol.cpp1111
-rw-r--r--source/Symbol/SymbolContext.cpp2400
-rw-r--r--source/Symbol/SymbolFile.cpp218
-rw-r--r--source/Symbol/SymbolVendor.cpp895
-rw-r--r--source/Symbol/Symtab.cpp2059
-rw-r--r--source/Symbol/Type.cpp2151
-rw-r--r--source/Symbol/TypeList.cpp326
-rw-r--r--source/Symbol/TypeMap.cpp382
-rw-r--r--source/Symbol/TypeSystem.cpp365
-rw-r--r--source/Symbol/UnwindPlan.cpp967
-rw-r--r--source/Symbol/UnwindTable.cpp269
-rw-r--r--source/Symbol/Variable.cpp1529
-rw-r--r--source/Symbol/VariableList.cpp346
-rw-r--r--source/Symbol/VerifyDecl.cpp5
38 files changed, 25061 insertions, 27406 deletions
diff --git a/source/Symbol/ArmUnwindInfo.cpp b/source/Symbol/ArmUnwindInfo.cpp
index 95207cbe320d..19951498c1d7 100644
--- a/source/Symbol/ArmUnwindInfo.cpp
+++ b/source/Symbol/ArmUnwindInfo.cpp
@@ -9,13 +9,13 @@
#include <vector>
+#include "Utility/ARM_DWARF_Registers.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/UnwindPlan.h"
-#include "Utility/ARM_DWARF_Registers.h"
/*
* Unwind information reader and parser for the ARM exception handling ABI
@@ -31,415 +31,341 @@ using namespace lldb;
using namespace lldb_private;
// Converts a prel31 avlue to lldb::addr_t with sign extension
-static addr_t
-Prel31ToAddr(uint32_t prel31)
-{
- addr_t res = prel31;
- if (prel31 & (1<<30))
- res |= 0xffffffff80000000ULL;
- return res;
+static addr_t Prel31ToAddr(uint32_t prel31) {
+ addr_t res = prel31;
+ if (prel31 & (1 << 30))
+ res |= 0xffffffff80000000ULL;
+ return res;
}
-ArmUnwindInfo::ArmExidxEntry::ArmExidxEntry(uint32_t f, lldb::addr_t a, uint32_t d) :
- file_address(f), address(a), data(d)
-{
-}
+ArmUnwindInfo::ArmExidxEntry::ArmExidxEntry(uint32_t f, lldb::addr_t a,
+ uint32_t d)
+ : file_address(f), address(a), data(d) {}
-bool
-ArmUnwindInfo::ArmExidxEntry::operator<(const ArmExidxEntry& other) const
-{
- return address < other.address;
+bool ArmUnwindInfo::ArmExidxEntry::operator<(const ArmExidxEntry &other) const {
+ return address < other.address;
}
-ArmUnwindInfo::ArmUnwindInfo(const ObjectFile& objfile,
- SectionSP& arm_exidx,
- SectionSP& arm_extab) :
- m_byte_order(objfile.GetByteOrder()),
- m_arm_exidx_sp(arm_exidx),
- m_arm_extab_sp(arm_extab)
-{
- objfile.ReadSectionData(arm_exidx.get(), m_arm_exidx_data);
- objfile.ReadSectionData(arm_extab.get(), m_arm_extab_data);
-
- addr_t exidx_base_addr = m_arm_exidx_sp->GetFileAddress();
-
- offset_t offset = 0;
- while (m_arm_exidx_data.ValidOffset(offset))
- {
- lldb::addr_t file_addr = exidx_base_addr + offset;
- lldb::addr_t addr = exidx_base_addr +
- (addr_t)offset +
- Prel31ToAddr(m_arm_exidx_data.GetU32(&offset));
- uint32_t data = m_arm_exidx_data.GetU32(&offset);
- m_exidx_entries.emplace_back(file_addr, addr, data);
- }
-
- // Sort the entries in the exidx section. The entries should be sorted inside the section but
- // some old compiler isn't sorted them.
- std::sort(m_exidx_entries.begin(), m_exidx_entries.end());
+ArmUnwindInfo::ArmUnwindInfo(const ObjectFile &objfile, SectionSP &arm_exidx,
+ SectionSP &arm_extab)
+ : m_byte_order(objfile.GetByteOrder()), m_arm_exidx_sp(arm_exidx),
+ m_arm_extab_sp(arm_extab) {
+ objfile.ReadSectionData(arm_exidx.get(), m_arm_exidx_data);
+ objfile.ReadSectionData(arm_extab.get(), m_arm_extab_data);
+
+ addr_t exidx_base_addr = m_arm_exidx_sp->GetFileAddress();
+
+ offset_t offset = 0;
+ while (m_arm_exidx_data.ValidOffset(offset)) {
+ lldb::addr_t file_addr = exidx_base_addr + offset;
+ lldb::addr_t addr = exidx_base_addr + (addr_t)offset +
+ Prel31ToAddr(m_arm_exidx_data.GetU32(&offset));
+ uint32_t data = m_arm_exidx_data.GetU32(&offset);
+ m_exidx_entries.emplace_back(file_addr, addr, data);
+ }
+
+ // Sort the entries in the exidx section. The entries should be sorted inside
+ // the section but
+ // some old compiler isn't sorted them.
+ std::sort(m_exidx_entries.begin(), m_exidx_entries.end());
}
-ArmUnwindInfo::~ArmUnwindInfo()
-{
-}
+ArmUnwindInfo::~ArmUnwindInfo() {}
// Read a byte from the unwind instruction stream with the given offset.
-// Custom function is required because have to red in order of significance within their containing
+// Custom function is required because have to red in order of significance
+// within their containing
// word (most significant byte first) and in increasing word address order.
-uint8_t
-ArmUnwindInfo::GetByteAtOffset(const uint32_t* data, uint16_t offset) const
-{
- uint32_t value = data[offset / 4];
- if (m_byte_order != endian::InlHostByteOrder())
- value = llvm::ByteSwap_32(value);
- return (value >> ((3 - (offset % 4)) * 8)) & 0xff;
+uint8_t ArmUnwindInfo::GetByteAtOffset(const uint32_t *data,
+ uint16_t offset) const {
+ uint32_t value = data[offset / 4];
+ if (m_byte_order != endian::InlHostByteOrder())
+ value = llvm::ByteSwap_32(value);
+ return (value >> ((3 - (offset % 4)) * 8)) & 0xff;
}
-uint64_t
-ArmUnwindInfo::GetULEB128(const uint32_t* data, uint16_t& offset, uint16_t max_offset) const
-{
- uint64_t result = 0;
- uint8_t shift = 0;
- while (offset < max_offset)
- {
- uint8_t byte = GetByteAtOffset(data, offset++);
- result |= (uint64_t)(byte & 0x7f) << shift;
- if ((byte & 0x80) == 0)
- break;
- shift += 7;
- }
- return result;
+uint64_t ArmUnwindInfo::GetULEB128(const uint32_t *data, uint16_t &offset,
+ uint16_t max_offset) const {
+ uint64_t result = 0;
+ uint8_t shift = 0;
+ while (offset < max_offset) {
+ uint8_t byte = GetByteAtOffset(data, offset++);
+ result |= (uint64_t)(byte & 0x7f) << shift;
+ if ((byte & 0x80) == 0)
+ break;
+ shift += 7;
+ }
+ return result;
}
-bool
-ArmUnwindInfo::GetUnwindPlan(Target &target, const Address& addr, UnwindPlan& unwind_plan)
-{
- const uint32_t* data = (const uint32_t*)GetExceptionHandlingTableEntry(addr);
- if (data == nullptr)
- return false; // No unwind information for the function
-
- if (data[0] == 0x1)
- return false; // EXIDX_CANTUNWIND
-
- uint16_t byte_count = 0;
- uint16_t byte_offset = 0;
- if (data[0] & 0x80000000)
- {
- switch ((data[0] >> 24) & 0x0f)
- {
- case 0:
- byte_count = 4;
- byte_offset = 1;
- break;
- case 1:
- case 2:
- byte_count = 4 * ((data[0] >> 16) & 0xff) + 4;
- byte_offset = 2;
- break;
- default:
- // Unhandled personality routine index
- return false;
- }
- }
- else
- {
- byte_count = 4 * ((data[1] >> 24) & 0xff) + 8;
- byte_offset = 5;
+bool ArmUnwindInfo::GetUnwindPlan(Target &target, const Address &addr,
+ UnwindPlan &unwind_plan) {
+ const uint32_t *data = (const uint32_t *)GetExceptionHandlingTableEntry(addr);
+ if (data == nullptr)
+ return false; // No unwind information for the function
+
+ if (data[0] == 0x1)
+ return false; // EXIDX_CANTUNWIND
+
+ uint16_t byte_count = 0;
+ uint16_t byte_offset = 0;
+ if (data[0] & 0x80000000) {
+ switch ((data[0] >> 24) & 0x0f) {
+ case 0:
+ byte_count = 4;
+ byte_offset = 1;
+ break;
+ case 1:
+ case 2:
+ byte_count = 4 * ((data[0] >> 16) & 0xff) + 4;
+ byte_offset = 2;
+ break;
+ default:
+ // Unhandled personality routine index
+ return false;
}
-
- uint8_t vsp_reg = dwarf_sp;
- int32_t vsp = 0;
- std::vector<std::pair<uint32_t, int32_t>> register_offsets; // register -> (offset from vsp_reg)
-
- while (byte_offset < byte_count)
- {
- uint8_t byte1 = GetByteAtOffset(data, byte_offset++);
- if ((byte1&0xc0) == 0x00)
- {
- // 00xxxxxx
- // vsp = vsp + (xxxxxx << 2) + 4. Covers range 0x04-0x100 inclusive
- vsp += ((byte1 & 0x3f) << 2) + 4;
- }
- else if ((byte1&0xc0) == 0x40)
- {
- // 01xxxxxx
- // vsp = vsp – (xxxxxx << 2) - 4. Covers range 0x04-0x100 inclusive
- vsp -= ((byte1 & 0x3f) << 2) + 4;
- }
- else if ((byte1&0xf0) == 0x80)
- {
- if (byte_offset >= byte_count)
- return false;
-
- uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
- if (byte1 == 0x80 && byte2 == 0)
- {
- // 10000000 00000000
- // Refuse to unwind (for example, out of a cleanup) (see remark a)
- return false;
- }
- else
- {
- // 1000iiii iiiiiiii (i not all 0)
- // Pop up to 12 integer registers under masks {r15-r12}, {r11-r4} (see remark b)
- uint16_t regs = ((byte1&0x0f) << 8) | byte2;
- for (uint8_t i = 0; i < 12; ++i)
- {
- if (regs & (1<<i))
- {
- register_offsets.emplace_back(dwarf_r4 + i, vsp);
- vsp += 4;
- }
- }
- }
- }
- else if ((byte1&0xff) == 0x9d)
- {
- // 10011101
- // Reserved as prefix for ARM register to register moves
- return false;
- }
- else if ((byte1&0xff) == 0x9f)
- {
- // 10011111
- // Reserved as prefix for Intel Wireless MMX register to register moves
- return false;
- }
- else if ((byte1&0xf0) == 0x90)
- {
- // 1001nnnn (nnnn != 13,15)
- // Set vsp = r[nnnn]
- vsp_reg = dwarf_r0 + (byte1&0x0f);
- }
- else if ((byte1&0xf8) == 0xa0)
- {
- // 10100nnn
- // Pop r4-r[4+nnn]
- uint8_t n = byte1&0x7;
- for (uint8_t i = 0; i <= n; ++i)
- {
- register_offsets.emplace_back(dwarf_r4 + i, vsp);
- vsp += 4;
- }
- }
- else if ((byte1&0xf8) == 0xa8)
- {
- // 10101nnn
- // Pop r4-r[4+nnn], r14
- uint8_t n = byte1&0x7;
- for (uint8_t i = 0; i <= n; ++i)
- {
- register_offsets.emplace_back(dwarf_r4 + i, vsp);
- vsp += 4;
- }
-
- register_offsets.emplace_back(dwarf_lr, vsp);
- vsp += 4;
- }
- else if ((byte1&0xff) == 0xb0)
- {
- // 10110000
- // Finish (see remark c)
- break;
- }
- else if ((byte1&0xff) == 0xb1)
- {
- if (byte_offset >= byte_count)
- return false;
-
- uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
- if ((byte2&0xff) == 0x00)
- {
- // 10110001 00000000
- // Spare (see remark f)
- return false;
- }
- else if ((byte2&0xf0) == 0x00)
- {
- // 10110001 0000iiii (i not all 0)
- // Pop integer registers under mask {r3, r2, r1, r0}
- for (uint8_t i = 0; i < 4; ++i)
- {
- if (byte2 & (1<<i))
- {
- register_offsets.emplace_back(dwarf_r0 + i, vsp);
- vsp += 4;
- }
- }
- }
- else
- {
- // 10110001 xxxxyyyy
- // Spare (xxxx != 0000)
- return false;
- }
- }
- else if ((byte1&0xff) == 0xb2)
- {
- // 10110010 uleb128
- // vsp = vsp + 0x204+ (uleb128 << 2)
- uint64_t uleb128 = GetULEB128(data, byte_offset, byte_count);
- vsp += 0x204 + (uleb128 << 2);
- }
- else if ((byte1&0xff) == 0xb3)
- {
- // 10110011 sssscccc
- // Pop VFP double-precision registers D[ssss]-D[ssss+cccc] saved (as if) by FSTMFDX (see remark d)
- if (byte_offset >= byte_count)
- return false;
-
- uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
- uint8_t s = (byte2&0xf0) >> 4;
- uint8_t c = (byte2&0x0f) >> 0;
- for (uint8_t i = 0; i <= c; ++i)
- {
- register_offsets.emplace_back(dwarf_d0 + s + i, vsp);
- vsp += 8;
- }
+ } else {
+ byte_count = 4 * ((data[1] >> 24) & 0xff) + 8;
+ byte_offset = 5;
+ }
+
+ uint8_t vsp_reg = dwarf_sp;
+ int32_t vsp = 0;
+ std::vector<std::pair<uint32_t, int32_t>>
+ register_offsets; // register -> (offset from vsp_reg)
+
+ while (byte_offset < byte_count) {
+ uint8_t byte1 = GetByteAtOffset(data, byte_offset++);
+ if ((byte1 & 0xc0) == 0x00) {
+ // 00xxxxxx
+ // vsp = vsp + (xxxxxx << 2) + 4. Covers range 0x04-0x100 inclusive
+ vsp += ((byte1 & 0x3f) << 2) + 4;
+ } else if ((byte1 & 0xc0) == 0x40) {
+ // 01xxxxxx
+ // vsp = vsp – (xxxxxx << 2) - 4. Covers range 0x04-0x100 inclusive
+ vsp -= ((byte1 & 0x3f) << 2) + 4;
+ } else if ((byte1 & 0xf0) == 0x80) {
+ if (byte_offset >= byte_count)
+ return false;
+
+ uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
+ if (byte1 == 0x80 && byte2 == 0) {
+ // 10000000 00000000
+ // Refuse to unwind (for example, out of a cleanup) (see remark a)
+ return false;
+ } else {
+ // 1000iiii iiiiiiii (i not all 0)
+ // Pop up to 12 integer registers under masks {r15-r12}, {r11-r4} (see
+ // remark b)
+ uint16_t regs = ((byte1 & 0x0f) << 8) | byte2;
+ for (uint8_t i = 0; i < 12; ++i) {
+ if (regs & (1 << i)) {
+ register_offsets.emplace_back(dwarf_r4 + i, vsp);
vsp += 4;
+ }
}
- else if ((byte1&0xfc) == 0xb4)
- {
- // 101101nn
- // Spare (was Pop FPA)
- return false;
- }
- else if ((byte1&0xf8) == 0xb8)
- {
- // 10111nnn
- // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by FSTMFDX (see remark d)
- uint8_t n = byte1&0x07;
- for (uint8_t i = 0; i <= n; ++i)
- {
- register_offsets.emplace_back(dwarf_d8 + i, vsp);
- vsp += 8;
- }
+ }
+ } else if ((byte1 & 0xff) == 0x9d) {
+ // 10011101
+ // Reserved as prefix for ARM register to register moves
+ return false;
+ } else if ((byte1 & 0xff) == 0x9f) {
+ // 10011111
+ // Reserved as prefix for Intel Wireless MMX register to register moves
+ return false;
+ } else if ((byte1 & 0xf0) == 0x90) {
+ // 1001nnnn (nnnn != 13,15)
+ // Set vsp = r[nnnn]
+ vsp_reg = dwarf_r0 + (byte1 & 0x0f);
+ } else if ((byte1 & 0xf8) == 0xa0) {
+ // 10100nnn
+ // Pop r4-r[4+nnn]
+ uint8_t n = byte1 & 0x7;
+ for (uint8_t i = 0; i <= n; ++i) {
+ register_offsets.emplace_back(dwarf_r4 + i, vsp);
+ vsp += 4;
+ }
+ } else if ((byte1 & 0xf8) == 0xa8) {
+ // 10101nnn
+ // Pop r4-r[4+nnn], r14
+ uint8_t n = byte1 & 0x7;
+ for (uint8_t i = 0; i <= n; ++i) {
+ register_offsets.emplace_back(dwarf_r4 + i, vsp);
+ vsp += 4;
+ }
+
+ register_offsets.emplace_back(dwarf_lr, vsp);
+ vsp += 4;
+ } else if ((byte1 & 0xff) == 0xb0) {
+ // 10110000
+ // Finish (see remark c)
+ break;
+ } else if ((byte1 & 0xff) == 0xb1) {
+ if (byte_offset >= byte_count)
+ return false;
+
+ uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
+ if ((byte2 & 0xff) == 0x00) {
+ // 10110001 00000000
+ // Spare (see remark f)
+ return false;
+ } else if ((byte2 & 0xf0) == 0x00) {
+ // 10110001 0000iiii (i not all 0)
+ // Pop integer registers under mask {r3, r2, r1, r0}
+ for (uint8_t i = 0; i < 4; ++i) {
+ if (byte2 & (1 << i)) {
+ register_offsets.emplace_back(dwarf_r0 + i, vsp);
vsp += 4;
+ }
}
- else if ((byte1&0xf8) == 0xc0)
- {
- // 11000nnn (nnn != 6,7)
- // Intel Wireless MMX pop wR[10]-wR[10+nnn]
-
- // 11000110 sssscccc
- // Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc] (see remark e)
-
- // 11000111 00000000
- // Spare
-
- // 11000111 0000iiii
- // Intel Wireless MMX pop wCGR registers under mask {wCGR3,2,1,0}
-
- // 11000111 xxxxyyyy
- // Spare (xxxx != 0000)
-
- return false;
- }
- else if ((byte1&0xff) == 0xc8)
- {
- // 11001000 sssscccc
- // Pop VFP double precision registers D[16+ssss]-D[16+ssss+cccc] saved (as if) by FSTMFDD (see remarks d,e)
- if (byte_offset >= byte_count)
- return false;
-
- uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
- uint8_t s = (byte2&0xf0) >> 4;
- uint8_t c = (byte2&0x0f) >> 0;
- for (uint8_t i = 0; i <= c; ++i)
- {
- register_offsets.emplace_back(dwarf_d16 + s + i, vsp);
- vsp += 8;
- }
- }
- else if ((byte1&0xff) == 0xc9)
- {
- // 11001001 sssscccc
- // Pop VFP double precision registers D[ssss]-D[ssss+cccc] saved (as if) by FSTMFDD (see remark d)
- if (byte_offset >= byte_count)
- return false;
-
- uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
- uint8_t s = (byte2&0xf0) >> 4;
- uint8_t c = (byte2&0x0f) >> 0;
- for (uint8_t i = 0; i <= c; ++i)
- {
- register_offsets.emplace_back(dwarf_d0 + s + i, vsp);
- vsp += 8;
- }
- }
- else if ((byte1&0xf8) == 0xc8)
- {
- // 11001yyy
- // Spare (yyy != 000, 001)
- return false;
- }
- else if ((byte1&0xf8) == 0xc0)
- {
- // 11010nnn
- // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by FSTMFDD (see remark d)
- uint8_t n = byte1&0x07;
- for (uint8_t i = 0; i <= n; ++i)
- {
- register_offsets.emplace_back(dwarf_d8 + i, vsp);
- vsp += 8;
- }
- }
- else if ((byte1&0xc0) == 0xc0)
- {
- // 11xxxyyy Spare (xxx != 000, 001, 010)
- return false;
- }
- else
- {
- return false;
- }
- }
-
- UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>();
- row->SetOffset(0);
- row->GetCFAValue().SetIsRegisterPlusOffset(vsp_reg, vsp);
-
- bool have_location_for_pc = false;
- for (const auto& offset : register_offsets)
- {
- have_location_for_pc |= offset.first == dwarf_pc;
- row->SetRegisterLocationToAtCFAPlusOffset(offset.first, offset.second - vsp, true);
- }
-
- if (!have_location_for_pc)
- {
- UnwindPlan::Row::RegisterLocation lr_location;
- if (row->GetRegisterInfo(dwarf_lr, lr_location))
- row->SetRegisterInfo(dwarf_pc, lr_location);
- else
- row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, false);
+ } else {
+ // 10110001 xxxxyyyy
+ // Spare (xxxx != 0000)
+ return false;
+ }
+ } else if ((byte1 & 0xff) == 0xb2) {
+ // 10110010 uleb128
+ // vsp = vsp + 0x204+ (uleb128 << 2)
+ uint64_t uleb128 = GetULEB128(data, byte_offset, byte_count);
+ vsp += 0x204 + (uleb128 << 2);
+ } else if ((byte1 & 0xff) == 0xb3) {
+ // 10110011 sssscccc
+ // Pop VFP double-precision registers D[ssss]-D[ssss+cccc] saved (as if)
+ // by FSTMFDX (see remark d)
+ if (byte_offset >= byte_count)
+ return false;
+
+ uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
+ uint8_t s = (byte2 & 0xf0) >> 4;
+ uint8_t c = (byte2 & 0x0f) >> 0;
+ for (uint8_t i = 0; i <= c; ++i) {
+ register_offsets.emplace_back(dwarf_d0 + s + i, vsp);
+ vsp += 8;
+ }
+ vsp += 4;
+ } else if ((byte1 & 0xfc) == 0xb4) {
+ // 101101nn
+ // Spare (was Pop FPA)
+ return false;
+ } else if ((byte1 & 0xf8) == 0xb8) {
+ // 10111nnn
+ // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by
+ // FSTMFDX (see remark d)
+ uint8_t n = byte1 & 0x07;
+ for (uint8_t i = 0; i <= n; ++i) {
+ register_offsets.emplace_back(dwarf_d8 + i, vsp);
+ vsp += 8;
+ }
+ vsp += 4;
+ } else if ((byte1 & 0xf8) == 0xc0) {
+ // 11000nnn (nnn != 6,7)
+ // Intel Wireless MMX pop wR[10]-wR[10+nnn]
+
+ // 11000110 sssscccc
+ // Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc] (see remark e)
+
+ // 11000111 00000000
+ // Spare
+
+ // 11000111 0000iiii
+ // Intel Wireless MMX pop wCGR registers under mask {wCGR3,2,1,0}
+
+ // 11000111 xxxxyyyy
+ // Spare (xxxx != 0000)
+
+ return false;
+ } else if ((byte1 & 0xff) == 0xc8) {
+ // 11001000 sssscccc
+ // Pop VFP double precision registers D[16+ssss]-D[16+ssss+cccc] saved (as
+ // if) by FSTMFDD (see remarks d,e)
+ if (byte_offset >= byte_count)
+ return false;
+
+ uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
+ uint8_t s = (byte2 & 0xf0) >> 4;
+ uint8_t c = (byte2 & 0x0f) >> 0;
+ for (uint8_t i = 0; i <= c; ++i) {
+ register_offsets.emplace_back(dwarf_d16 + s + i, vsp);
+ vsp += 8;
+ }
+ } else if ((byte1 & 0xff) == 0xc9) {
+ // 11001001 sssscccc
+ // Pop VFP double precision registers D[ssss]-D[ssss+cccc] saved (as if)
+ // by FSTMFDD (see remark d)
+ if (byte_offset >= byte_count)
+ return false;
+
+ uint8_t byte2 = GetByteAtOffset(data, byte_offset++);
+ uint8_t s = (byte2 & 0xf0) >> 4;
+ uint8_t c = (byte2 & 0x0f) >> 0;
+ for (uint8_t i = 0; i <= c; ++i) {
+ register_offsets.emplace_back(dwarf_d0 + s + i, vsp);
+ vsp += 8;
+ }
+ } else if ((byte1 & 0xf8) == 0xc8) {
+ // 11001yyy
+ // Spare (yyy != 000, 001)
+ return false;
+ } else if ((byte1 & 0xf8) == 0xc0) {
+ // 11010nnn
+ // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by
+ // FSTMFDD (see remark d)
+ uint8_t n = byte1 & 0x07;
+ for (uint8_t i = 0; i <= n; ++i) {
+ register_offsets.emplace_back(dwarf_d8 + i, vsp);
+ vsp += 8;
+ }
+ } else if ((byte1 & 0xc0) == 0xc0) {
+ // 11xxxyyy Spare (xxx != 000, 001, 010)
+ return false;
+ } else {
+ return false;
}
+ }
+
+ UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>();
+ row->SetOffset(0);
+ row->GetCFAValue().SetIsRegisterPlusOffset(vsp_reg, vsp);
+
+ bool have_location_for_pc = false;
+ for (const auto &offset : register_offsets) {
+ have_location_for_pc |= offset.first == dwarf_pc;
+ row->SetRegisterLocationToAtCFAPlusOffset(offset.first, offset.second - vsp,
+ true);
+ }
+
+ if (!have_location_for_pc) {
+ UnwindPlan::Row::RegisterLocation lr_location;
+ if (row->GetRegisterInfo(dwarf_lr, lr_location))
+ row->SetRegisterInfo(dwarf_pc, lr_location);
+ else
+ row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, false);
+ }
- unwind_plan.AppendRow(row);
- unwind_plan.SetSourceName ("ARM.exidx unwind info");
- unwind_plan.SetSourcedFromCompiler (eLazyBoolYes);
- unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
- unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("ARM.exidx unwind info");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan.SetRegisterKind(eRegisterKindDWARF);
- return true;
+ return true;
}
-const uint8_t*
-ArmUnwindInfo::GetExceptionHandlingTableEntry(const Address& addr)
-{
- auto it = std::upper_bound(m_exidx_entries.begin(),
- m_exidx_entries.end(),
- ArmExidxEntry{0, addr.GetFileAddress(), 0});
- if (it == m_exidx_entries.begin())
- return nullptr;
- --it;
+const uint8_t *
+ArmUnwindInfo::GetExceptionHandlingTableEntry(const Address &addr) {
+ auto it = std::upper_bound(m_exidx_entries.begin(), m_exidx_entries.end(),
+ ArmExidxEntry{0, addr.GetFileAddress(), 0});
+ if (it == m_exidx_entries.begin())
+ return nullptr;
+ --it;
- if (it->data == 0x1)
- return nullptr; // EXIDX_CANTUNWIND
+ if (it->data == 0x1)
+ return nullptr; // EXIDX_CANTUNWIND
- if (it->data & 0x80000000)
- return (const uint8_t*)&it->data;
+ if (it->data & 0x80000000)
+ return (const uint8_t *)&it->data;
- addr_t data_file_addr = it->file_address + 4 + Prel31ToAddr(it->data);
- return m_arm_extab_data.GetDataStart() + (data_file_addr - m_arm_extab_sp->GetFileAddress());
+ addr_t data_file_addr = it->file_address + 4 + Prel31ToAddr(it->data);
+ return m_arm_extab_data.GetDataStart() +
+ (data_file_addr - m_arm_extab_sp->GetFileAddress());
}
diff --git a/source/Symbol/Block.cpp b/source/Symbol/Block.cpp
index 9d50c5cb7c9a..6c4c28d1f7f7 100644
--- a/source/Symbol/Block.cpp
+++ b/source/Symbol/Block.cpp
@@ -20,628 +20,486 @@
using namespace lldb;
using namespace lldb_private;
-Block::Block(lldb::user_id_t uid) :
- UserID(uid),
- m_parent_scope (nullptr),
- m_children (),
- m_ranges (),
- m_inlineInfoSP (),
- m_variable_list_sp (),
- m_parsed_block_info (false),
- m_parsed_block_variables (false),
- m_parsed_child_blocks (false)
-{
-}
-
-Block::~Block ()
-{
-}
-
-void
-Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel level, Target *target) const
-{
- *s << "id = " << ((const UserID&)*this);
-
- size_t num_ranges = m_ranges.GetSize();
- if (num_ranges > 0)
- {
-
- addr_t base_addr = LLDB_INVALID_ADDRESS;
- if (target)
- base_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
- if (base_addr == LLDB_INVALID_ADDRESS)
- base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
-
- s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
- for (size_t i=0; i<num_ranges; ++i)
- {
- const Range &range = m_ranges.GetEntryRef(i);
- s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
- }
- }
-
- if (m_inlineInfoSP.get() != nullptr)
- {
- bool show_fullpaths = (level == eDescriptionLevelVerbose);
- m_inlineInfoSP->Dump(s, show_fullpaths);
+Block::Block(lldb::user_id_t uid)
+ : UserID(uid), m_parent_scope(nullptr), m_children(), m_ranges(),
+ m_inlineInfoSP(), m_variable_list_sp(), m_parsed_block_info(false),
+ m_parsed_block_variables(false), m_parsed_child_blocks(false) {}
+
+Block::~Block() {}
+
+void Block::GetDescription(Stream *s, Function *function,
+ lldb::DescriptionLevel level, Target *target) const {
+ *s << "id = " << ((const UserID &)*this);
+
+ size_t num_ranges = m_ranges.GetSize();
+ if (num_ranges > 0) {
+
+ addr_t base_addr = LLDB_INVALID_ADDRESS;
+ if (target)
+ base_addr =
+ function->GetAddressRange().GetBaseAddress().GetLoadAddress(target);
+ if (base_addr == LLDB_INVALID_ADDRESS)
+ base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
+
+ s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const Range &range = m_ranges.GetEntryRef(i);
+ s->AddressRange(base_addr + range.GetRangeBase(),
+ base_addr + range.GetRangeEnd(), 4);
}
-}
-
-void
-Block::Dump(Stream *s, addr_t base_addr, int32_t depth, bool show_context) const
-{
- if (depth < 0)
- {
- Block *parent = GetParent();
- if (parent)
- {
- // We have a depth that is less than zero, print our parent blocks
- // first
- parent->Dump(s, base_addr, depth + 1, show_context);
- }
+ }
+
+ if (m_inlineInfoSP.get() != nullptr) {
+ bool show_fullpaths = (level == eDescriptionLevelVerbose);
+ m_inlineInfoSP->Dump(s, show_fullpaths);
+ }
+}
+
+void Block::Dump(Stream *s, addr_t base_addr, int32_t depth,
+ bool show_context) const {
+ if (depth < 0) {
+ Block *parent = GetParent();
+ if (parent) {
+ // We have a depth that is less than zero, print our parent blocks
+ // first
+ parent->Dump(s, base_addr, depth + 1, show_context);
}
+ }
+
+ s->Printf("%p: ", static_cast<const void *>(this));
+ s->Indent();
+ *s << "Block" << static_cast<const UserID &>(*this);
+ const Block *parent_block = GetParent();
+ if (parent_block) {
+ s->Printf(", parent = {0x%8.8" PRIx64 "}", parent_block->GetID());
+ }
+ if (m_inlineInfoSP.get() != nullptr) {
+ bool show_fullpaths = false;
+ m_inlineInfoSP->Dump(s, show_fullpaths);
+ }
+
+ if (!m_ranges.IsEmpty()) {
+ *s << ", ranges =";
- s->Printf("%p: ", static_cast<const void*>(this));
- s->Indent();
- *s << "Block" << static_cast<const UserID&>(*this);
- const Block* parent_block = GetParent();
- if (parent_block)
- {
- s->Printf(", parent = {0x%8.8" PRIx64 "}", parent_block->GetID());
- }
- if (m_inlineInfoSP.get() != nullptr)
- {
- bool show_fullpaths = false;
- m_inlineInfoSP->Dump(s, show_fullpaths);
- }
-
- if (!m_ranges.IsEmpty())
- {
- *s << ", ranges =";
-
- size_t num_ranges = m_ranges.GetSize();
- for (size_t i=0; i<num_ranges; ++i)
- {
- const Range &range = m_ranges.GetEntryRef(i);
- if (parent_block != nullptr && parent_block->Contains(range) == false)
- *s << '!';
- else
- *s << ' ';
- s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
- }
+ size_t num_ranges = m_ranges.GetSize();
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const Range &range = m_ranges.GetEntryRef(i);
+ if (parent_block != nullptr && parent_block->Contains(range) == false)
+ *s << '!';
+ else
+ *s << ' ';
+ s->AddressRange(base_addr + range.GetRangeBase(),
+ base_addr + range.GetRangeEnd(), 4);
}
- s->EOL();
+ }
+ s->EOL();
- if (depth > 0)
- {
- s->IndentMore();
+ if (depth > 0) {
+ s->IndentMore();
- if (m_variable_list_sp.get())
- {
- m_variable_list_sp->Dump(s, show_context);
- }
-
- collection::const_iterator pos, end = m_children.end();
- for (pos = m_children.begin(); pos != end; ++pos)
- (*pos)->Dump(s, base_addr, depth - 1, show_context);
-
- s->IndentLess();
+ if (m_variable_list_sp.get()) {
+ m_variable_list_sp->Dump(s, show_context);
}
-}
-
-
-Block *
-Block::FindBlockByID (user_id_t block_id)
-{
- if (block_id == GetID())
- return this;
-
- Block *matching_block = nullptr;
collection::const_iterator pos, end = m_children.end();
for (pos = m_children.begin(); pos != end; ++pos)
- {
- matching_block = (*pos)->FindBlockByID (block_id);
- if (matching_block)
- break;
- }
- return matching_block;
-}
-
-void
-Block::CalculateSymbolContext (SymbolContext* sc)
-{
- if (m_parent_scope)
- m_parent_scope->CalculateSymbolContext(sc);
- sc->block = this;
-}
+ (*pos)->Dump(s, base_addr, depth - 1, show_context);
-lldb::ModuleSP
-Block::CalculateSymbolContextModule ()
-{
- if (m_parent_scope)
- return m_parent_scope->CalculateSymbolContextModule ();
- return lldb::ModuleSP();
+ s->IndentLess();
+ }
}
-CompileUnit *
-Block::CalculateSymbolContextCompileUnit ()
-{
- if (m_parent_scope)
- return m_parent_scope->CalculateSymbolContextCompileUnit ();
- return nullptr;
-}
+Block *Block::FindBlockByID(user_id_t block_id) {
+ if (block_id == GetID())
+ return this;
-Function *
-Block::CalculateSymbolContextFunction ()
-{
- if (m_parent_scope)
- return m_parent_scope->CalculateSymbolContextFunction ();
- return nullptr;
+ Block *matching_block = nullptr;
+ collection::const_iterator pos, end = m_children.end();
+ for (pos = m_children.begin(); pos != end; ++pos) {
+ matching_block = (*pos)->FindBlockByID(block_id);
+ if (matching_block)
+ break;
+ }
+ return matching_block;
}
-Block *
-Block::CalculateSymbolContextBlock ()
-{
- return this;
+void Block::CalculateSymbolContext(SymbolContext *sc) {
+ if (m_parent_scope)
+ m_parent_scope->CalculateSymbolContext(sc);
+ sc->block = this;
}
-void
-Block::DumpSymbolContext(Stream *s)
-{
- Function *function = CalculateSymbolContextFunction();
- if (function)
- function->DumpSymbolContext(s);
- s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
-}
-
-void
-Block::DumpAddressRanges (Stream *s, lldb::addr_t base_addr)
-{
- if (!m_ranges.IsEmpty())
- {
- size_t num_ranges = m_ranges.GetSize();
- for (size_t i=0; i<num_ranges; ++i)
- {
- const Range &range = m_ranges.GetEntryRef(i);
- s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
- }
- }
+lldb::ModuleSP Block::CalculateSymbolContextModule() {
+ if (m_parent_scope)
+ return m_parent_scope->CalculateSymbolContextModule();
+ return lldb::ModuleSP();
}
-bool
-Block::Contains (addr_t range_offset) const
-{
- return m_ranges.FindEntryThatContains(range_offset) != nullptr;
-}
-
-bool
-Block::Contains (const Block *block) const
-{
- if (this == block)
- return false; // This block doesn't contain itself...
-
- // Walk the parent chain for "block" and see if any if them match this block
- const Block *block_parent;
- for (block_parent = block->GetParent();
- block_parent != nullptr;
- block_parent = block_parent->GetParent())
- {
- if (this == block_parent)
- return true; // One of the parents of "block" is this object!
- }
- return false;
+CompileUnit *Block::CalculateSymbolContextCompileUnit() {
+ if (m_parent_scope)
+ return m_parent_scope->CalculateSymbolContextCompileUnit();
+ return nullptr;
}
-bool
-Block::Contains (const Range& range) const
-{
- return m_ranges.FindEntryThatContains (range) != nullptr;
+Function *Block::CalculateSymbolContextFunction() {
+ if (m_parent_scope)
+ return m_parent_scope->CalculateSymbolContextFunction();
+ return nullptr;
}
-Block *
-Block::GetParent () const
-{
- if (m_parent_scope)
- return m_parent_scope->CalculateSymbolContextBlock();
- return nullptr;
-}
+Block *Block::CalculateSymbolContextBlock() { return this; }
-Block *
-Block::GetContainingInlinedBlock ()
-{
- if (GetInlinedFunctionInfo())
- return this;
- return GetInlinedParent ();
+void Block::DumpSymbolContext(Stream *s) {
+ Function *function = CalculateSymbolContextFunction();
+ if (function)
+ function->DumpSymbolContext(s);
+ s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
}
-Block *
-Block::GetInlinedParent ()
-{
- Block *parent_block = GetParent ();
- if (parent_block)
- {
- if (parent_block->GetInlinedFunctionInfo())
- return parent_block;
- else
- return parent_block->GetInlinedParent();
+void Block::DumpAddressRanges(Stream *s, lldb::addr_t base_addr) {
+ if (!m_ranges.IsEmpty()) {
+ size_t num_ranges = m_ranges.GetSize();
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const Range &range = m_ranges.GetEntryRef(i);
+ s->AddressRange(base_addr + range.GetRangeBase(),
+ base_addr + range.GetRangeEnd(), 4);
}
- return nullptr;
+ }
}
-
-bool
-Block::GetRangeContainingOffset (const addr_t offset, Range &range)
-{
- const Range *range_ptr = m_ranges.FindEntryThatContains (offset);
- if (range_ptr)
- {
- range = *range_ptr;
- return true;
- }
- range.Clear();
- return false;
+bool Block::Contains(addr_t range_offset) const {
+ return m_ranges.FindEntryThatContains(range_offset) != nullptr;
}
+bool Block::Contains(const Block *block) const {
+ if (this == block)
+ return false; // This block doesn't contain itself...
-bool
-Block::GetRangeContainingAddress (const Address& addr, AddressRange &range)
-{
- Function *function = CalculateSymbolContextFunction();
- if (function)
- {
- const AddressRange &func_range = function->GetAddressRange();
- if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
- {
- const addr_t addr_offset = addr.GetOffset();
- const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
- if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
- {
- addr_t offset = addr_offset - func_offset;
-
- const Range *range_ptr = m_ranges.FindEntryThatContains (offset);
-
- if (range_ptr)
- {
- range.GetBaseAddress() = func_range.GetBaseAddress();
- range.GetBaseAddress().SetOffset(func_offset + range_ptr->GetRangeBase());
- range.SetByteSize(range_ptr->GetByteSize());
- return true;
- }
- }
- }
- }
- range.Clear();
- return false;
+ // Walk the parent chain for "block" and see if any if them match this block
+ const Block *block_parent;
+ for (block_parent = block->GetParent(); block_parent != nullptr;
+ block_parent = block_parent->GetParent()) {
+ if (this == block_parent)
+ return true; // One of the parents of "block" is this object!
+ }
+ return false;
}
-bool
-Block::GetRangeContainingLoadAddress (lldb::addr_t load_addr, Target &target, AddressRange &range)
-{
- Address load_address;
- load_address.SetLoadAddress(load_addr, &target);
- AddressRange containing_range;
- return GetRangeContainingAddress(load_address, containing_range);
+bool Block::Contains(const Range &range) const {
+ return m_ranges.FindEntryThatContains(range) != nullptr;
}
+Block *Block::GetParent() const {
+ if (m_parent_scope)
+ return m_parent_scope->CalculateSymbolContextBlock();
+ return nullptr;
+}
-uint32_t
-Block::GetRangeIndexContainingAddress (const Address& addr)
-{
- Function *function = CalculateSymbolContextFunction();
- if (function)
- {
- const AddressRange &func_range = function->GetAddressRange();
- if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
- {
- const addr_t addr_offset = addr.GetOffset();
- const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
- if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
- {
- addr_t offset = addr_offset - func_offset;
- return m_ranges.FindEntryIndexThatContains (offset);
- }
+Block *Block::GetContainingInlinedBlock() {
+ if (GetInlinedFunctionInfo())
+ return this;
+ return GetInlinedParent();
+}
+
+Block *Block::GetInlinedParent() {
+ Block *parent_block = GetParent();
+ if (parent_block) {
+ if (parent_block->GetInlinedFunctionInfo())
+ return parent_block;
+ else
+ return parent_block->GetInlinedParent();
+ }
+ return nullptr;
+}
+
+bool Block::GetRangeContainingOffset(const addr_t offset, Range &range) {
+ const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
+ if (range_ptr) {
+ range = *range_ptr;
+ return true;
+ }
+ range.Clear();
+ return false;
+}
+
+bool Block::GetRangeContainingAddress(const Address &addr,
+ AddressRange &range) {
+ Function *function = CalculateSymbolContextFunction();
+ if (function) {
+ const AddressRange &func_range = function->GetAddressRange();
+ if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
+ const addr_t addr_offset = addr.GetOffset();
+ const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
+ if (addr_offset >= func_offset &&
+ addr_offset < func_offset + func_range.GetByteSize()) {
+ addr_t offset = addr_offset - func_offset;
+
+ const Range *range_ptr = m_ranges.FindEntryThatContains(offset);
+
+ if (range_ptr) {
+ range.GetBaseAddress() = func_range.GetBaseAddress();
+ range.GetBaseAddress().SetOffset(func_offset +
+ range_ptr->GetRangeBase());
+ range.SetByteSize(range_ptr->GetByteSize());
+ return true;
}
+ }
}
- return UINT32_MAX;
-}
-
-bool
-Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
-{
- if (range_idx < m_ranges.GetSize())
- {
- Function *function = CalculateSymbolContextFunction();
- if (function)
- {
- const Range &vm_range = m_ranges.GetEntryRef(range_idx);
- range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
- range.GetBaseAddress().Slide(vm_range.GetRangeBase ());
- range.SetByteSize (vm_range.GetByteSize());
- return true;
- }
+ }
+ range.Clear();
+ return false;
+}
+
+bool Block::GetRangeContainingLoadAddress(lldb::addr_t load_addr,
+ Target &target, AddressRange &range) {
+ Address load_address;
+ load_address.SetLoadAddress(load_addr, &target);
+ AddressRange containing_range;
+ return GetRangeContainingAddress(load_address, containing_range);
+}
+
+uint32_t Block::GetRangeIndexContainingAddress(const Address &addr) {
+ Function *function = CalculateSymbolContextFunction();
+ if (function) {
+ const AddressRange &func_range = function->GetAddressRange();
+ if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) {
+ const addr_t addr_offset = addr.GetOffset();
+ const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
+ if (addr_offset >= func_offset &&
+ addr_offset < func_offset + func_range.GetByteSize()) {
+ addr_t offset = addr_offset - func_offset;
+ return m_ranges.FindEntryIndexThatContains(offset);
+ }
}
- return false;
+ }
+ return UINT32_MAX;
}
-bool
-Block::GetStartAddress (Address &addr)
-{
- if (m_ranges.IsEmpty())
- return false;
-
+bool Block::GetRangeAtIndex(uint32_t range_idx, AddressRange &range) {
+ if (range_idx < m_ranges.GetSize()) {
Function *function = CalculateSymbolContextFunction();
- if (function)
- {
- addr = function->GetAddressRange().GetBaseAddress();
- addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase ());
- return true;
+ if (function) {
+ const Range &vm_range = m_ranges.GetEntryRef(range_idx);
+ range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
+ range.GetBaseAddress().Slide(vm_range.GetRangeBase());
+ range.SetByteSize(vm_range.GetByteSize());
+ return true;
}
- return false;
+ }
+ return false;
}
-void
-Block::FinalizeRanges ()
-{
- m_ranges.Sort();
- m_ranges.CombineConsecutiveRanges ();
-}
-
-void
-Block::AddRange (const Range& range)
-{
- Block *parent_block = GetParent ();
- if (parent_block && !parent_block->Contains(range))
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
- if (log)
- {
- ModuleSP module_sp (m_parent_scope->CalculateSymbolContextModule());
- Function *function = m_parent_scope->CalculateSymbolContextFunction();
- const addr_t function_file_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
- const addr_t block_start_addr = function_file_addr + range.GetRangeBase ();
- const addr_t block_end_addr = function_file_addr + range.GetRangeEnd ();
- Type *func_type = function->GetType();
-
- const Declaration &func_decl = func_type->GetDeclaration();
- if (func_decl.GetLine())
- {
- log->Printf ("warning: %s:%u block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64 ") which is not contained in parent block {0x%8.8" PRIx64 "} in function {0x%8.8" PRIx64 "} from %s",
- func_decl.GetFile().GetPath().c_str(),
- func_decl.GetLine(),
- GetID(),
- (uint32_t)m_ranges.GetSize(),
- block_start_addr,
- block_end_addr,
- parent_block->GetID(),
- function->GetID(),
- module_sp->GetFileSpec().GetPath().c_str());
- }
- else
- {
- log->Printf ("warning: block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64 ") which is not contained in parent block {0x%8.8" PRIx64 "} in function {0x%8.8" PRIx64 "} from %s",
- GetID(),
- (uint32_t)m_ranges.GetSize(),
- block_start_addr,
- block_end_addr,
- parent_block->GetID(),
- function->GetID(),
- module_sp->GetFileSpec().GetPath().c_str());
- }
- }
- parent_block->AddRange (range);
+bool Block::GetStartAddress(Address &addr) {
+ if (m_ranges.IsEmpty())
+ return false;
+
+ Function *function = CalculateSymbolContextFunction();
+ if (function) {
+ addr = function->GetAddressRange().GetBaseAddress();
+ addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase());
+ return true;
+ }
+ return false;
+}
+
+void Block::FinalizeRanges() {
+ m_ranges.Sort();
+ m_ranges.CombineConsecutiveRanges();
+}
+
+void Block::AddRange(const Range &range) {
+ Block *parent_block = GetParent();
+ if (parent_block && !parent_block->Contains(range)) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
+ if (log) {
+ ModuleSP module_sp(m_parent_scope->CalculateSymbolContextModule());
+ Function *function = m_parent_scope->CalculateSymbolContextFunction();
+ const addr_t function_file_addr =
+ function->GetAddressRange().GetBaseAddress().GetFileAddress();
+ const addr_t block_start_addr = function_file_addr + range.GetRangeBase();
+ const addr_t block_end_addr = function_file_addr + range.GetRangeEnd();
+ Type *func_type = function->GetType();
+
+ const Declaration &func_decl = func_type->GetDeclaration();
+ if (func_decl.GetLine()) {
+ log->Printf("warning: %s:%u block {0x%8.8" PRIx64
+ "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64
+ ") which is not contained in parent block {0x%8.8" PRIx64
+ "} in function {0x%8.8" PRIx64 "} from %s",
+ func_decl.GetFile().GetPath().c_str(), func_decl.GetLine(),
+ GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
+ block_end_addr, parent_block->GetID(), function->GetID(),
+ module_sp->GetFileSpec().GetPath().c_str());
+ } else {
+ log->Printf("warning: block {0x%8.8" PRIx64
+ "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64
+ ") which is not contained in parent block {0x%8.8" PRIx64
+ "} in function {0x%8.8" PRIx64 "} from %s",
+ GetID(), (uint32_t)m_ranges.GetSize(), block_start_addr,
+ block_end_addr, parent_block->GetID(), function->GetID(),
+ module_sp->GetFileSpec().GetPath().c_str());
+ }
}
- m_ranges.Append(range);
+ parent_block->AddRange(range);
+ }
+ m_ranges.Append(range);
}
// Return the current number of bytes that this object occupies in memory
-size_t
-Block::MemorySize() const
-{
- size_t mem_size = sizeof(Block) + m_ranges.GetSize() * sizeof(Range);
- if (m_inlineInfoSP.get())
- mem_size += m_inlineInfoSP->MemorySize();
- if (m_variable_list_sp.get())
- mem_size += m_variable_list_sp->MemorySize();
- return mem_size;
-
-}
-
-void
-Block::AddChild(const BlockSP &child_block_sp)
-{
- if (child_block_sp)
- {
- child_block_sp->SetParentScope (this);
- m_children.push_back (child_block_sp);
+size_t Block::MemorySize() const {
+ size_t mem_size = sizeof(Block) + m_ranges.GetSize() * sizeof(Range);
+ if (m_inlineInfoSP.get())
+ mem_size += m_inlineInfoSP->MemorySize();
+ if (m_variable_list_sp.get())
+ mem_size += m_variable_list_sp->MemorySize();
+ return mem_size;
+}
+
+void Block::AddChild(const BlockSP &child_block_sp) {
+ if (child_block_sp) {
+ child_block_sp->SetParentScope(this);
+ m_children.push_back(child_block_sp);
+ }
+}
+
+void Block::SetInlinedFunctionInfo(const char *name, const char *mangled,
+ const Declaration *decl_ptr,
+ const Declaration *call_decl_ptr) {
+ m_inlineInfoSP.reset(
+ new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr));
+}
+
+VariableListSP Block::GetBlockVariableList(bool can_create) {
+ if (m_parsed_block_variables == false) {
+ if (m_variable_list_sp.get() == nullptr && can_create) {
+ m_parsed_block_variables = true;
+ SymbolContext sc;
+ CalculateSymbolContext(&sc);
+ assert(sc.module_sp);
+ sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
}
+ }
+ return m_variable_list_sp;
}
-void
-Block::SetInlinedFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
-{
- m_inlineInfoSP.reset(new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr));
-}
+uint32_t
+Block::AppendBlockVariables(bool can_create, bool get_child_block_variables,
+ bool stop_if_child_block_is_inlined_function,
+ const std::function<bool(Variable *)> &filter,
+ VariableList *variable_list) {
+ uint32_t num_variables_added = 0;
+ VariableList *block_var_list = GetBlockVariableList(can_create).get();
+ if (block_var_list) {
+ for (size_t i = 0; i < block_var_list->GetSize(); ++i) {
+ VariableSP variable = block_var_list->GetVariableAtIndex(i);
+ if (filter(variable.get())) {
+ num_variables_added++;
+ variable_list->AddVariable(variable);
+ }
+ }
+ }
+ if (get_child_block_variables) {
+ collection::const_iterator pos, end = m_children.end();
+ for (pos = m_children.begin(); pos != end; ++pos) {
+ Block *child_block = pos->get();
+ if (stop_if_child_block_is_inlined_function == false ||
+ child_block->GetInlinedFunctionInfo() == nullptr) {
+ num_variables_added += child_block->AppendBlockVariables(
+ can_create, get_child_block_variables,
+ stop_if_child_block_is_inlined_function, filter, variable_list);
+ }
+ }
+ }
+ return num_variables_added;
+}
+
+uint32_t Block::AppendVariables(bool can_create, bool get_parent_variables,
+ bool stop_if_block_is_inlined_function,
+ const std::function<bool(Variable *)> &filter,
+ VariableList *variable_list) {
+ uint32_t num_variables_added = 0;
+ VariableListSP variable_list_sp(GetBlockVariableList(can_create));
+
+ bool is_inlined_function = GetInlinedFunctionInfo() != nullptr;
+ if (variable_list_sp) {
+ for (size_t i = 0; i < variable_list_sp->GetSize(); ++i) {
+ VariableSP variable = variable_list_sp->GetVariableAtIndex(i);
+ if (filter(variable.get())) {
+ num_variables_added++;
+ variable_list->AddVariable(variable);
+ }
+ }
+ }
+ if (get_parent_variables) {
+ if (stop_if_block_is_inlined_function && is_inlined_function)
+ return num_variables_added;
-VariableListSP
-Block::GetBlockVariableList (bool can_create)
-{
- if (m_parsed_block_variables == false)
- {
- if (m_variable_list_sp.get() == nullptr && can_create)
- {
- m_parsed_block_variables = true;
- SymbolContext sc;
- CalculateSymbolContext(&sc);
- assert(sc.module_sp);
- sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
- }
- }
- return m_variable_list_sp;
+ Block *parent_block = GetParent();
+ if (parent_block)
+ num_variables_added += parent_block->AppendVariables(
+ can_create, get_parent_variables, stop_if_block_is_inlined_function,
+ filter, variable_list);
+ }
+ return num_variables_added;
}
-uint32_t
-Block::AppendBlockVariables (bool can_create,
- bool get_child_block_variables,
- bool stop_if_child_block_is_inlined_function,
- const std::function<bool(Variable*)>& filter,
- VariableList *variable_list)
-{
- uint32_t num_variables_added = 0;
- VariableList *block_var_list = GetBlockVariableList (can_create).get();
- if (block_var_list)
- {
- for (size_t i = 0; i < block_var_list->GetSize(); ++i)
- {
- VariableSP variable = block_var_list->GetVariableAtIndex(i);
- if (filter(variable.get()))
- {
- num_variables_added++;
- variable_list->AddVariable(variable);
- }
- }
- }
+CompilerDeclContext Block::GetDeclContext() {
+ ModuleSP module_sp = CalculateSymbolContextModule();
- if (get_child_block_variables)
- {
- collection::const_iterator pos, end = m_children.end();
- for (pos = m_children.begin(); pos != end; ++pos)
- {
- Block *child_block = pos->get();
- if (stop_if_child_block_is_inlined_function == false ||
- child_block->GetInlinedFunctionInfo() == nullptr)
- {
- num_variables_added += child_block->AppendBlockVariables (can_create,
- get_child_block_variables,
- stop_if_child_block_is_inlined_function,
- filter,
- variable_list);
- }
- }
- }
- return num_variables_added;
-}
+ if (module_sp) {
+ SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
-uint32_t
-Block::AppendVariables
-(
- bool can_create,
- bool get_parent_variables,
- bool stop_if_block_is_inlined_function,
- const std::function<bool(Variable*)>& filter,
- VariableList *variable_list
-)
-{
- uint32_t num_variables_added = 0;
- VariableListSP variable_list_sp(GetBlockVariableList(can_create));
-
- bool is_inlined_function = GetInlinedFunctionInfo() != nullptr;
- if (variable_list_sp)
- {
- for (size_t i = 0; i < variable_list_sp->GetSize(); ++i)
- {
- VariableSP variable = variable_list_sp->GetVariableAtIndex(i);
- if (filter(variable.get()))
- {
- num_variables_added++;
- variable_list->AddVariable(variable);
- }
- }
- }
+ if (sym_vendor) {
+ SymbolFile *sym_file = sym_vendor->GetSymbolFile();
- if (get_parent_variables)
- {
- if (stop_if_block_is_inlined_function && is_inlined_function)
- return num_variables_added;
-
- Block* parent_block = GetParent();
- if (parent_block)
- num_variables_added += parent_block->AppendVariables(can_create,
- get_parent_variables,
- stop_if_block_is_inlined_function,
- filter,
- variable_list);
- }
- return num_variables_added;
-}
-
-CompilerDeclContext
-Block::GetDeclContext()
-{
- ModuleSP module_sp = CalculateSymbolContextModule ();
-
- if (module_sp)
- {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
-
- if (sym_vendor)
- {
- SymbolFile *sym_file = sym_vendor->GetSymbolFile();
-
- if (sym_file)
- return sym_file->GetDeclContextForUID (GetID());
- }
- }
- return CompilerDeclContext();
-}
-
-void
-Block::SetBlockInfoHasBeenParsed (bool b, bool set_children)
-{
- m_parsed_block_info = b;
- if (set_children)
- {
- m_parsed_child_blocks = true;
- collection::const_iterator pos, end = m_children.end();
- for (pos = m_children.begin(); pos != end; ++pos)
- (*pos)->SetBlockInfoHasBeenParsed (b, true);
+ if (sym_file)
+ return sym_file->GetDeclContextForUID(GetID());
}
+ }
+ return CompilerDeclContext();
}
-void
-Block::SetDidParseVariables (bool b, bool set_children)
-{
- m_parsed_block_variables = b;
- if (set_children)
- {
- collection::const_iterator pos, end = m_children.end();
- for (pos = m_children.begin(); pos != end; ++pos)
- (*pos)->SetDidParseVariables (b, true);
- }
+void Block::SetBlockInfoHasBeenParsed(bool b, bool set_children) {
+ m_parsed_block_info = b;
+ if (set_children) {
+ m_parsed_child_blocks = true;
+ collection::const_iterator pos, end = m_children.end();
+ for (pos = m_children.begin(); pos != end; ++pos)
+ (*pos)->SetBlockInfoHasBeenParsed(b, true);
+ }
}
+void Block::SetDidParseVariables(bool b, bool set_children) {
+ m_parsed_block_variables = b;
+ if (set_children) {
+ collection::const_iterator pos, end = m_children.end();
+ for (pos = m_children.begin(); pos != end; ++pos)
+ (*pos)->SetDidParseVariables(b, true);
+ }
+}
-Block *
-Block::GetSibling() const
-{
- if (m_parent_scope)
- {
- Block *parent_block = GetParent();
- if (parent_block)
- return parent_block->GetSiblingForChild (this);
- }
- return nullptr;
+Block *Block::GetSibling() const {
+ if (m_parent_scope) {
+ Block *parent_block = GetParent();
+ if (parent_block)
+ return parent_block->GetSiblingForChild(this);
+ }
+ return nullptr;
}
// A parent of child blocks can be asked to find a sibling block given
// one of its child blocks
-Block *
-Block::GetSiblingForChild (const Block *child_block) const
-{
- if (!m_children.empty())
- {
- collection::const_iterator pos, end = m_children.end();
- for (pos = m_children.begin(); pos != end; ++pos)
- {
- if (pos->get() == child_block)
- {
- if (++pos != end)
- return pos->get();
- break;
- }
- }
+Block *Block::GetSiblingForChild(const Block *child_block) const {
+ if (!m_children.empty()) {
+ collection::const_iterator pos, end = m_children.end();
+ for (pos = m_children.begin(); pos != end; ++pos) {
+ if (pos->get() == child_block) {
+ if (++pos != end)
+ return pos->get();
+ break;
+ }
}
- return nullptr;
+ }
+ return nullptr;
}
-
diff --git a/source/Symbol/CMakeLists.txt b/source/Symbol/CMakeLists.txt
index 320a780dc98e..c5f7be73f4bf 100644
--- a/source/Symbol/CMakeLists.txt
+++ b/source/Symbol/CMakeLists.txt
@@ -21,6 +21,7 @@ add_lldb_library(lldbSymbol
LineEntry.cpp
LineTable.cpp
ObjectFile.cpp
+ OCamlASTContext.cpp
Symbol.cpp
SymbolContext.cpp
SymbolFile.cpp
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index 02882ef2ef4d..caebd0ce8c6b 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -9,6 +9,9 @@
#include "lldb/Symbol/ClangASTContext.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
+
// C Includes
// C++ Includes
#include <mutex> // std::once
@@ -17,7 +20,7 @@
// Other libraries and framework includes
-// Clang headers like to use NDEBUG inside of them to enable/disable debug
+// Clang headers like to use NDEBUG inside of them to enable/disable debug
// related features using "#ifndef NDEBUG" preprocessor blocks to do one thing
// or another. This is bad because it means that if clang was built in release
// mode, it assumes that you are building in release mode which is not always
@@ -103,2087 +106,2077 @@ using namespace lldb_private;
using namespace llvm;
using namespace clang;
-namespace
-{
- static inline bool ClangASTContextSupportsLanguage (lldb::LanguageType language)
- {
- return language == eLanguageTypeUnknown || // Clang is the default type system
- Language::LanguageIsC (language) ||
- Language::LanguageIsCPlusPlus (language) ||
- Language::LanguageIsObjC (language) ||
- // Use Clang for Rust until there is a proper language plugin for it
- language == eLanguageTypeRust ||
- language == eLanguageTypeExtRenderScript;
+namespace {
+static inline bool
+ClangASTContextSupportsLanguage(lldb::LanguageType language) {
+ return language == eLanguageTypeUnknown || // Clang is the default type system
+ Language::LanguageIsC(language) ||
+ Language::LanguageIsCPlusPlus(language) ||
+ Language::LanguageIsObjC(language) ||
+ Language::LanguageIsPascal(language) ||
+ // Use Clang for Rust until there is a proper language plugin for it
+ language == eLanguageTypeRust ||
+ language == eLanguageTypeExtRenderScript ||
+ // Use Clang for D until there is a proper language plugin for it
+ language == eLanguageTypeD;
+}
+}
+
+typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, ClangASTContext *>
+ ClangASTMap;
+
+static ClangASTMap &GetASTMap() {
+ static ClangASTMap *g_map_ptr = nullptr;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins
+ });
+ return *g_map_ptr;
+}
+
+static bool IsOperator(const char *name,
+ clang::OverloadedOperatorKind &op_kind) {
+ if (name == nullptr || name[0] == '\0')
+ return false;
+
+#define OPERATOR_PREFIX "operator"
+#define OPERATOR_PREFIX_LENGTH (sizeof(OPERATOR_PREFIX) - 1)
+
+ const char *post_op_name = nullptr;
+
+ bool no_space = true;
+
+ if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
+ return false;
+
+ post_op_name = name + OPERATOR_PREFIX_LENGTH;
+
+ if (post_op_name[0] == ' ') {
+ post_op_name++;
+ no_space = false;
+ }
+
+#undef OPERATOR_PREFIX
+#undef OPERATOR_PREFIX_LENGTH
+
+ // This is an operator, set the overloaded operator kind to invalid
+ // in case this is a conversion operator...
+ op_kind = clang::NUM_OVERLOADED_OPERATORS;
+
+ switch (post_op_name[0]) {
+ default:
+ if (no_space)
+ return false;
+ break;
+ case 'n':
+ if (no_space)
+ return false;
+ if (strcmp(post_op_name, "new") == 0)
+ op_kind = clang::OO_New;
+ else if (strcmp(post_op_name, "new[]") == 0)
+ op_kind = clang::OO_Array_New;
+ break;
+
+ case 'd':
+ if (no_space)
+ return false;
+ if (strcmp(post_op_name, "delete") == 0)
+ op_kind = clang::OO_Delete;
+ else if (strcmp(post_op_name, "delete[]") == 0)
+ op_kind = clang::OO_Array_Delete;
+ break;
+
+ case '+':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Plus;
+ else if (post_op_name[2] == '\0') {
+ if (post_op_name[1] == '=')
+ op_kind = clang::OO_PlusEqual;
+ else if (post_op_name[1] == '+')
+ op_kind = clang::OO_PlusPlus;
+ }
+ break;
+
+ case '-':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Minus;
+ else if (post_op_name[2] == '\0') {
+ switch (post_op_name[1]) {
+ case '=':
+ op_kind = clang::OO_MinusEqual;
+ break;
+ case '-':
+ op_kind = clang::OO_MinusMinus;
+ break;
+ case '>':
+ op_kind = clang::OO_Arrow;
+ break;
+ }
+ } else if (post_op_name[3] == '\0') {
+ if (post_op_name[2] == '*')
+ op_kind = clang::OO_ArrowStar;
+ break;
+ }
+ break;
+
+ case '*':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Star;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = clang::OO_StarEqual;
+ break;
+
+ case '/':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Slash;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = clang::OO_SlashEqual;
+ break;
+
+ case '%':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Percent;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = clang::OO_PercentEqual;
+ break;
+
+ case '^':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Caret;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = clang::OO_CaretEqual;
+ break;
+
+ case '&':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Amp;
+ else if (post_op_name[2] == '\0') {
+ switch (post_op_name[1]) {
+ case '=':
+ op_kind = clang::OO_AmpEqual;
+ break;
+ case '&':
+ op_kind = clang::OO_AmpAmp;
+ break;
+ }
}
-}
+ break;
-typedef lldb_private::ThreadSafeDenseMap<clang::ASTContext *, ClangASTContext*> ClangASTMap;
+ case '|':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Pipe;
+ else if (post_op_name[2] == '\0') {
+ switch (post_op_name[1]) {
+ case '=':
+ op_kind = clang::OO_PipeEqual;
+ break;
+ case '|':
+ op_kind = clang::OO_PipePipe;
+ break;
+ }
+ }
+ break;
+
+ case '~':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Tilde;
+ break;
+
+ case '!':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Exclaim;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = clang::OO_ExclaimEqual;
+ break;
+
+ case '=':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Equal;
+ else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+ op_kind = clang::OO_EqualEqual;
+ break;
+
+ case '<':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Less;
+ else if (post_op_name[2] == '\0') {
+ switch (post_op_name[1]) {
+ case '<':
+ op_kind = clang::OO_LessLess;
+ break;
+ case '=':
+ op_kind = clang::OO_LessEqual;
+ break;
+ }
+ } else if (post_op_name[3] == '\0') {
+ if (post_op_name[2] == '=')
+ op_kind = clang::OO_LessLessEqual;
+ }
+ break;
+
+ case '>':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Greater;
+ else if (post_op_name[2] == '\0') {
+ switch (post_op_name[1]) {
+ case '>':
+ op_kind = clang::OO_GreaterGreater;
+ break;
+ case '=':
+ op_kind = clang::OO_GreaterEqual;
+ break;
+ }
+ } else if (post_op_name[1] == '>' && post_op_name[2] == '=' &&
+ post_op_name[3] == '\0') {
+ op_kind = clang::OO_GreaterGreaterEqual;
+ }
+ break;
-static ClangASTMap &
-GetASTMap()
-{
- static ClangASTMap *g_map_ptr = nullptr;
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
- g_map_ptr = new ClangASTMap(); // leaked on purpose to avoid spins
- });
- return *g_map_ptr;
-}
+ case ',':
+ if (post_op_name[1] == '\0')
+ op_kind = clang::OO_Comma;
+ break;
+
+ case '(':
+ if (post_op_name[1] == ')' && post_op_name[2] == '\0')
+ op_kind = clang::OO_Call;
+ break;
+ case '[':
+ if (post_op_name[1] == ']' && post_op_name[2] == '\0')
+ op_kind = clang::OO_Subscript;
+ break;
+ }
+
+ return true;
+}
clang::AccessSpecifier
-ClangASTContext::ConvertAccessTypeToAccessSpecifier (AccessType access)
-{
- switch (access)
- {
- default: break;
- case eAccessNone: return AS_none;
- case eAccessPublic: return AS_public;
- case eAccessPrivate: return AS_private;
- case eAccessProtected: return AS_protected;
- }
+ClangASTContext::ConvertAccessTypeToAccessSpecifier(AccessType access) {
+ switch (access) {
+ default:
+ break;
+ case eAccessNone:
return AS_none;
+ case eAccessPublic:
+ return AS_public;
+ case eAccessPrivate:
+ return AS_private;
+ case eAccessProtected:
+ return AS_protected;
+ }
+ return AS_none;
+}
+
+static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
+ // FIXME: Cleanup per-file based stuff.
+
+ // Set some properties which depend solely on the input kind; it would be nice
+ // to move these to the language standard, and have the driver resolve the
+ // input kind + language standard.
+ if (IK == IK_Asm) {
+ Opts.AsmPreprocessor = 1;
+ } else if (IK == IK_ObjC || IK == IK_ObjCXX || IK == IK_PreprocessedObjC ||
+ IK == IK_PreprocessedObjCXX) {
+ Opts.ObjC1 = Opts.ObjC2 = 1;
+ }
+
+ LangStandard::Kind LangStd = LangStandard::lang_unspecified;
+
+ if (LangStd == LangStandard::lang_unspecified) {
+ // Based on the base language, pick one.
+ switch (IK) {
+ case IK_None:
+ case IK_AST:
+ case IK_LLVM_IR:
+ case IK_RenderScript:
+ assert(!"Invalid input kind!");
+ case IK_OpenCL:
+ LangStd = LangStandard::lang_opencl;
+ break;
+ case IK_CUDA:
+ case IK_PreprocessedCuda:
+ LangStd = LangStandard::lang_cuda;
+ break;
+ case IK_Asm:
+ case IK_C:
+ case IK_PreprocessedC:
+ case IK_ObjC:
+ case IK_PreprocessedObjC:
+ LangStd = LangStandard::lang_gnu99;
+ break;
+ case IK_CXX:
+ case IK_PreprocessedCXX:
+ case IK_ObjCXX:
+ case IK_PreprocessedObjCXX:
+ LangStd = LangStandard::lang_gnucxx98;
+ break;
+ }
+ }
+
+ const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
+ Opts.LineComment = Std.hasLineComments();
+ Opts.C99 = Std.isC99();
+ Opts.CPlusPlus = Std.isCPlusPlus();
+ Opts.CPlusPlus11 = Std.isCPlusPlus11();
+ Opts.Digraphs = Std.hasDigraphs();
+ Opts.GNUMode = Std.isGNUMode();
+ Opts.GNUInline = !Std.isC99();
+ Opts.HexFloats = Std.hasHexFloats();
+ Opts.ImplicitInt = Std.hasImplicitInt();
+
+ Opts.WChar = true;
+
+ // OpenCL has some additional defaults.
+ if (LangStd == LangStandard::lang_opencl) {
+ Opts.OpenCL = 1;
+ Opts.AltiVec = 1;
+ Opts.CXXOperatorNames = 1;
+ Opts.LaxVectorConversions = 1;
+ }
+
+ // OpenCL and C++ both have bool, true, false keywords.
+ Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
+
+ // if (Opts.CPlusPlus)
+ // Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
+ //
+ // if (Args.hasArg(OPT_fobjc_gc_only))
+ // Opts.setGCMode(LangOptions::GCOnly);
+ // else if (Args.hasArg(OPT_fobjc_gc))
+ // Opts.setGCMode(LangOptions::HybridGC);
+ //
+ // if (Args.hasArg(OPT_print_ivar_layout))
+ // Opts.ObjCGCBitmapPrint = 1;
+ //
+ // if (Args.hasArg(OPT_faltivec))
+ // Opts.AltiVec = 1;
+ //
+ // if (Args.hasArg(OPT_pthread))
+ // Opts.POSIXThreads = 1;
+ //
+ // llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
+ // "default");
+ // if (Vis == "default")
+ Opts.setValueVisibilityMode(DefaultVisibility);
+ // else if (Vis == "hidden")
+ // Opts.setVisibilityMode(LangOptions::Hidden);
+ // else if (Vis == "protected")
+ // Opts.setVisibilityMode(LangOptions::Protected);
+ // else
+ // Diags.Report(diag::err_drv_invalid_value)
+ // << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
+
+ // Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
+
+ // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
+ // is specified, or -std is set to a conforming mode.
+ Opts.Trigraphs = !Opts.GNUMode;
+ // if (Args.hasArg(OPT_trigraphs))
+ // Opts.Trigraphs = 1;
+ //
+ // Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
+ // OPT_fno_dollars_in_identifiers,
+ // !Opts.AsmPreprocessor);
+ // Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
+ // Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
+ // Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
+ // if (Args.hasArg(OPT_fno_lax_vector_conversions))
+ // Opts.LaxVectorConversions = 0;
+ // Opts.Exceptions = Args.hasArg(OPT_fexceptions);
+ // Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
+ // Opts.Blocks = Args.hasArg(OPT_fblocks);
+ Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
+ // Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
+ // Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
+ // Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
+ // Opts.AssumeSaneOperatorNew =
+ // !Args.hasArg(OPT_fno_assume_sane_operator_new);
+ // Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
+ // Opts.AccessControl = Args.hasArg(OPT_faccess_control);
+ // Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
+ // Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
+ // Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth,
+ // 99,
+ // Diags);
+ // Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
+ // Opts.ObjCConstantStringClass = getLastArgValue(Args,
+ // OPT_fconstant_string_class);
+ // Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
+ // Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
+ // Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
+ // Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
+ // Opts.Static = Args.hasArg(OPT_static_define);
+ Opts.OptimizeSize = 0;
+
+ // FIXME: Eliminate this dependency.
+ // unsigned Opt =
+ // Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
+ // Opts.Optimize = Opt != 0;
+ unsigned Opt = 0;
+
+ // This is the __NO_INLINE__ define, which just depends on things like the
+ // optimization level and -fno-inline, not actually whether the backend has
+ // inlining enabled.
+ //
+ // FIXME: This is affected by other options (-fno-inline).
+ Opts.NoInlineDefine = !Opt;
+
+ // unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
+ // switch (SSP) {
+ // default:
+ // Diags.Report(diag::err_drv_invalid_value)
+ // << Args.getLastArg(OPT_stack_protector)->getAsString(Args) <<
+ // SSP;
+ // break;
+ // case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
+ // case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
+ // case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
+ // }
+}
+
+ClangASTContext::ClangASTContext(const char *target_triple)
+ : TypeSystem(TypeSystem::eKindClang), m_target_triple(), m_ast_ap(),
+ m_language_options_ap(), m_source_manager_ap(), m_diagnostics_engine_ap(),
+ m_target_options_rp(), m_target_info_ap(), m_identifier_table_ap(),
+ m_selector_table_ap(), m_builtins_ap(), m_callback_tag_decl(nullptr),
+ m_callback_objc_decl(nullptr), m_callback_baton(nullptr),
+ m_pointer_byte_size(0), m_ast_owned(false) {
+ if (target_triple && target_triple[0])
+ SetTargetTriple(target_triple);
}
-static void
-ParseLangArgs (LangOptions &Opts, InputKind IK, const char* triple)
-{
- // FIXME: Cleanup per-file based stuff.
-
- // Set some properties which depend solely on the input kind; it would be nice
- // to move these to the language standard, and have the driver resolve the
- // input kind + language standard.
- if (IK == IK_Asm) {
- Opts.AsmPreprocessor = 1;
- } else if (IK == IK_ObjC ||
- IK == IK_ObjCXX ||
- IK == IK_PreprocessedObjC ||
- IK == IK_PreprocessedObjCXX) {
- Opts.ObjC1 = Opts.ObjC2 = 1;
- }
-
- LangStandard::Kind LangStd = LangStandard::lang_unspecified;
-
- if (LangStd == LangStandard::lang_unspecified) {
- // Based on the base language, pick one.
- switch (IK) {
- case IK_None:
- case IK_AST:
- case IK_LLVM_IR:
- assert (!"Invalid input kind!");
- case IK_OpenCL:
- LangStd = LangStandard::lang_opencl;
- break;
- case IK_CUDA:
- case IK_PreprocessedCuda:
- LangStd = LangStandard::lang_cuda;
- break;
- case IK_Asm:
- case IK_C:
- case IK_PreprocessedC:
- case IK_ObjC:
- case IK_PreprocessedObjC:
- LangStd = LangStandard::lang_gnu99;
- break;
- case IK_CXX:
- case IK_PreprocessedCXX:
- case IK_ObjCXX:
- case IK_PreprocessedObjCXX:
- LangStd = LangStandard::lang_gnucxx98;
- break;
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ClangASTContext::~ClangASTContext() { Finalize(); }
+
+ConstString ClangASTContext::GetPluginNameStatic() {
+ return ConstString("clang");
+}
+
+ConstString ClangASTContext::GetPluginName() {
+ return ClangASTContext::GetPluginNameStatic();
+}
+
+uint32_t ClangASTContext::GetPluginVersion() { return 1; }
+
+lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language,
+ lldb_private::Module *module,
+ Target *target) {
+ if (ClangASTContextSupportsLanguage(language)) {
+ ArchSpec arch;
+ if (module)
+ arch = module->GetArchitecture();
+ else if (target)
+ arch = target->GetArchitecture();
+
+ if (arch.IsValid()) {
+ ArchSpec fixed_arch = arch;
+ // LLVM wants this to be set to iOS or MacOSX; if we're working on
+ // a bare-boards type image, change the triple for llvm's benefit.
+ if (fixed_arch.GetTriple().getVendor() == llvm::Triple::Apple &&
+ fixed_arch.GetTriple().getOS() == llvm::Triple::UnknownOS) {
+ if (fixed_arch.GetTriple().getArch() == llvm::Triple::arm ||
+ fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
+ fixed_arch.GetTriple().getArch() == llvm::Triple::thumb) {
+ fixed_arch.GetTriple().setOS(llvm::Triple::IOS);
+ } else {
+ fixed_arch.GetTriple().setOS(llvm::Triple::MacOSX);
+ }
+ }
+
+ if (module) {
+ std::shared_ptr<ClangASTContext> ast_sp(new ClangASTContext);
+ if (ast_sp) {
+ ast_sp->SetArchitecture(fixed_arch);
}
+ return ast_sp;
+ } else if (target && target->IsValid()) {
+ std::shared_ptr<ClangASTContextForExpressions> ast_sp(
+ new ClangASTContextForExpressions(*target));
+ if (ast_sp) {
+ ast_sp->SetArchitecture(fixed_arch);
+ ast_sp->m_scratch_ast_source_ap.reset(
+ new ClangASTSource(target->shared_from_this()));
+ ast_sp->m_scratch_ast_source_ap->InstallASTContext(
+ ast_sp->getASTContext());
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
+ ast_sp->m_scratch_ast_source_ap->CreateProxy());
+ ast_sp->SetExternalSource(proxy_ast_source);
+ return ast_sp;
+ }
+ }
}
+ }
+ return lldb::TypeSystemSP();
+}
- const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
- Opts.LineComment = Std.hasLineComments();
- Opts.C99 = Std.isC99();
- Opts.CPlusPlus = Std.isCPlusPlus();
- Opts.CPlusPlus11 = Std.isCPlusPlus11();
- Opts.Digraphs = Std.hasDigraphs();
- Opts.GNUMode = Std.isGNUMode();
- Opts.GNUInline = !Std.isC99();
- Opts.HexFloats = Std.hasHexFloats();
- Opts.ImplicitInt = Std.hasImplicitInt();
-
- Opts.WChar = true;
-
- // OpenCL has some additional defaults.
- if (LangStd == LangStandard::lang_opencl) {
- Opts.OpenCL = 1;
- Opts.AltiVec = 1;
- Opts.CXXOperatorNames = 1;
- Opts.LaxVectorConversions = 1;
- }
-
- // OpenCL and C++ both have bool, true, false keywords.
- Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
-
-// if (Opts.CPlusPlus)
-// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
-//
-// if (Args.hasArg(OPT_fobjc_gc_only))
-// Opts.setGCMode(LangOptions::GCOnly);
-// else if (Args.hasArg(OPT_fobjc_gc))
-// Opts.setGCMode(LangOptions::HybridGC);
-//
-// if (Args.hasArg(OPT_print_ivar_layout))
-// Opts.ObjCGCBitmapPrint = 1;
-//
-// if (Args.hasArg(OPT_faltivec))
-// Opts.AltiVec = 1;
-//
-// if (Args.hasArg(OPT_pthread))
-// Opts.POSIXThreads = 1;
-//
-// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
-// "default");
-// if (Vis == "default")
- Opts.setValueVisibilityMode(DefaultVisibility);
-// else if (Vis == "hidden")
-// Opts.setVisibilityMode(LangOptions::Hidden);
-// else if (Vis == "protected")
-// Opts.setVisibilityMode(LangOptions::Protected);
-// else
-// Diags.Report(diag::err_drv_invalid_value)
-// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
-
-// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
-
- // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
- // is specified, or -std is set to a conforming mode.
- Opts.Trigraphs = !Opts.GNUMode;
-// if (Args.hasArg(OPT_trigraphs))
-// Opts.Trigraphs = 1;
-//
-// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
-// OPT_fno_dollars_in_identifiers,
-// !Opts.AsmPreprocessor);
-// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
-// Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
-// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
-// if (Args.hasArg(OPT_fno_lax_vector_conversions))
-// Opts.LaxVectorConversions = 0;
-// Opts.Exceptions = Args.hasArg(OPT_fexceptions);
-// Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
-// Opts.Blocks = Args.hasArg(OPT_fblocks);
- Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
-// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
-// Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
-// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
-// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
-// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
-// Opts.AccessControl = Args.hasArg(OPT_faccess_control);
-// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
-// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
-// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
-// Diags);
-// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
-// Opts.ObjCConstantStringClass = getLastArgValue(Args,
-// OPT_fconstant_string_class);
-// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
-// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
-// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
-// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
-// Opts.Static = Args.hasArg(OPT_static_define);
- Opts.OptimizeSize = 0;
-
- // FIXME: Eliminate this dependency.
-// unsigned Opt =
-// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
-// Opts.Optimize = Opt != 0;
- unsigned Opt = 0;
-
- // This is the __NO_INLINE__ define, which just depends on things like the
- // optimization level and -fno-inline, not actually whether the backend has
- // inlining enabled.
- //
- // FIXME: This is affected by other options (-fno-inline).
- Opts.NoInlineDefine = !Opt;
-
-// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
-// switch (SSP) {
-// default:
-// Diags.Report(diag::err_drv_invalid_value)
-// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
-// break;
-// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
-// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
-// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
-// }
-}
-
-
-ClangASTContext::ClangASTContext (const char *target_triple) :
- TypeSystem (TypeSystem::eKindClang),
- m_target_triple (),
- m_ast_ap (),
- m_language_options_ap (),
- m_source_manager_ap (),
- m_diagnostics_engine_ap (),
- m_target_options_rp (),
- m_target_info_ap (),
- m_identifier_table_ap (),
- m_selector_table_ap (),
- m_builtins_ap (),
- m_callback_tag_decl (nullptr),
- m_callback_objc_decl (nullptr),
- m_callback_baton (nullptr),
- m_pointer_byte_size (0),
- m_ast_owned (false)
-{
- if (target_triple && target_triple[0])
- SetTargetTriple (target_triple);
+void ClangASTContext::EnumerateSupportedLanguages(
+ std::set<lldb::LanguageType> &languages_for_types,
+ std::set<lldb::LanguageType> &languages_for_expressions) {
+ static std::vector<lldb::LanguageType> s_supported_languages_for_types(
+ {lldb::eLanguageTypeC89, lldb::eLanguageTypeC, lldb::eLanguageTypeC11,
+ lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeC99,
+ lldb::eLanguageTypeObjC, lldb::eLanguageTypeObjC_plus_plus,
+ lldb::eLanguageTypeC_plus_plus_03, lldb::eLanguageTypeC_plus_plus_11,
+ lldb::eLanguageTypeC11, lldb::eLanguageTypeC_plus_plus_14});
+
+ static std::vector<lldb::LanguageType> s_supported_languages_for_expressions(
+ {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC_plus_plus,
+ lldb::eLanguageTypeC_plus_plus_03, lldb::eLanguageTypeC_plus_plus_11,
+ lldb::eLanguageTypeC_plus_plus_14});
+
+ languages_for_types.insert(s_supported_languages_for_types.begin(),
+ s_supported_languages_for_types.end());
+ languages_for_expressions.insert(
+ s_supported_languages_for_expressions.begin(),
+ s_supported_languages_for_expressions.end());
}
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-ClangASTContext::~ClangASTContext()
-{
- Finalize();
+void ClangASTContext::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "clang base AST context plug-in",
+ CreateInstance, EnumerateSupportedLanguages);
}
-ConstString
-ClangASTContext::GetPluginNameStatic()
-{
- return ConstString("clang");
+void ClangASTContext::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-ConstString
-ClangASTContext::GetPluginName()
-{
- return ClangASTContext::GetPluginNameStatic();
+void ClangASTContext::Finalize() {
+ if (m_ast_ap.get()) {
+ GetASTMap().Erase(m_ast_ap.get());
+ if (!m_ast_owned)
+ m_ast_ap.release();
+ }
+
+ m_builtins_ap.reset();
+ m_selector_table_ap.reset();
+ m_identifier_table_ap.reset();
+ m_target_info_ap.reset();
+ m_target_options_rp.reset();
+ m_diagnostics_engine_ap.reset();
+ m_source_manager_ap.reset();
+ m_language_options_ap.reset();
+ m_ast_ap.reset();
+ m_scratch_ast_source_ap.reset();
}
-uint32_t
-ClangASTContext::GetPluginVersion()
-{
- return 1;
+void ClangASTContext::Clear() {
+ m_ast_ap.reset();
+ m_language_options_ap.reset();
+ m_source_manager_ap.reset();
+ m_diagnostics_engine_ap.reset();
+ m_target_options_rp.reset();
+ m_target_info_ap.reset();
+ m_identifier_table_ap.reset();
+ m_selector_table_ap.reset();
+ m_builtins_ap.reset();
+ m_pointer_byte_size = 0;
}
-lldb::TypeSystemSP
-ClangASTContext::CreateInstance (lldb::LanguageType language,
- lldb_private::Module *module,
- Target *target)
-{
- if (ClangASTContextSupportsLanguage(language))
- {
- ArchSpec arch;
- if (module)
- arch = module->GetArchitecture();
- else if (target)
- arch = target->GetArchitecture();
-
- if (arch.IsValid())
- {
- ArchSpec fixed_arch = arch;
- // LLVM wants this to be set to iOS or MacOSX; if we're working on
- // a bare-boards type image, change the triple for llvm's benefit.
- if (fixed_arch.GetTriple().getVendor() == llvm::Triple::Apple &&
- fixed_arch.GetTriple().getOS() == llvm::Triple::UnknownOS)
- {
- if (fixed_arch.GetTriple().getArch() == llvm::Triple::arm ||
- fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
- fixed_arch.GetTriple().getArch() == llvm::Triple::thumb)
- {
- fixed_arch.GetTriple().setOS(llvm::Triple::IOS);
- }
- else
- {
- fixed_arch.GetTriple().setOS(llvm::Triple::MacOSX);
- }
- }
+const char *ClangASTContext::GetTargetTriple() {
+ return m_target_triple.c_str();
+}
- if (module)
- {
- std::shared_ptr<ClangASTContext> ast_sp(new ClangASTContext);
- if (ast_sp)
- {
- ast_sp->SetArchitecture (fixed_arch);
- }
- return ast_sp;
- }
- else if (target && target->IsValid())
- {
- std::shared_ptr<ClangASTContextForExpressions> ast_sp(new ClangASTContextForExpressions(*target));
- if (ast_sp)
- {
- ast_sp->SetArchitecture(fixed_arch);
- ast_sp->m_scratch_ast_source_ap.reset (new ClangASTSource(target->shared_from_this()));
- ast_sp->m_scratch_ast_source_ap->InstallASTContext(ast_sp->getASTContext());
- llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(ast_sp->m_scratch_ast_source_ap->CreateProxy());
- ast_sp->SetExternalSource(proxy_ast_source);
- return ast_sp;
- }
- }
- }
- }
- return lldb::TypeSystemSP();
-}
-
-void
-ClangASTContext::EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types, std::set<lldb::LanguageType> &languages_for_expressions)
-{
- static std::vector<lldb::LanguageType> s_supported_languages_for_types({
- lldb::eLanguageTypeC89,
- lldb::eLanguageTypeC,
- lldb::eLanguageTypeC11,
- lldb::eLanguageTypeC_plus_plus,
- lldb::eLanguageTypeC99,
- lldb::eLanguageTypeObjC,
- lldb::eLanguageTypeObjC_plus_plus,
- lldb::eLanguageTypeC_plus_plus_03,
- lldb::eLanguageTypeC_plus_plus_11,
- lldb::eLanguageTypeC11,
- lldb::eLanguageTypeC_plus_plus_14});
-
- static std::vector<lldb::LanguageType> s_supported_languages_for_expressions({
- lldb::eLanguageTypeC_plus_plus,
- lldb::eLanguageTypeObjC_plus_plus,
- lldb::eLanguageTypeC_plus_plus_03,
- lldb::eLanguageTypeC_plus_plus_11,
- lldb::eLanguageTypeC_plus_plus_14});
-
- languages_for_types.insert(s_supported_languages_for_types.begin(), s_supported_languages_for_types.end());
- languages_for_expressions.insert(s_supported_languages_for_expressions.begin(), s_supported_languages_for_expressions.end());
-}
-
-
-void
-ClangASTContext::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- "clang base AST context plug-in",
- CreateInstance,
- EnumerateSupportedLanguages);
-}
-
-void
-ClangASTContext::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-void
-ClangASTContext::Finalize()
-{
- if (m_ast_ap.get())
- {
- GetASTMap().Erase(m_ast_ap.get());
- if (!m_ast_owned)
- m_ast_ap.release();
- }
-
- m_builtins_ap.reset();
- m_selector_table_ap.reset();
- m_identifier_table_ap.reset();
- m_target_info_ap.reset();
- m_target_options_rp.reset();
- m_diagnostics_engine_ap.reset();
- m_source_manager_ap.reset();
- m_language_options_ap.reset();
- m_ast_ap.reset();
- m_scratch_ast_source_ap.reset();
-}
-
-void
-ClangASTContext::Clear()
-{
- m_ast_ap.reset();
- m_language_options_ap.reset();
- m_source_manager_ap.reset();
- m_diagnostics_engine_ap.reset();
- m_target_options_rp.reset();
- m_target_info_ap.reset();
- m_identifier_table_ap.reset();
- m_selector_table_ap.reset();
- m_builtins_ap.reset();
- m_pointer_byte_size = 0;
-}
-
-const char *
-ClangASTContext::GetTargetTriple ()
-{
- return m_target_triple.c_str();
-}
-
-void
-ClangASTContext::SetTargetTriple (const char *target_triple)
-{
- Clear();
- m_target_triple.assign(target_triple);
-}
-
-void
-ClangASTContext::SetArchitecture (const ArchSpec &arch)
-{
- SetTargetTriple(arch.GetTriple().str().c_str());
-}
-
-bool
-ClangASTContext::HasExternalSource ()
-{
- ASTContext *ast = getASTContext();
- if (ast)
- return ast->getExternalSource () != nullptr;
- return false;
+void ClangASTContext::SetTargetTriple(const char *target_triple) {
+ Clear();
+ m_target_triple.assign(target_triple);
}
-void
-ClangASTContext::SetExternalSource (llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_ap)
-{
- ASTContext *ast = getASTContext();
- if (ast)
- {
- ast->setExternalSource (ast_source_ap);
- ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
- //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
- }
+void ClangASTContext::SetArchitecture(const ArchSpec &arch) {
+ SetTargetTriple(arch.GetTriple().str().c_str());
}
-void
-ClangASTContext::RemoveExternalSource ()
-{
- ASTContext *ast = getASTContext();
-
- if (ast)
- {
- llvm::IntrusiveRefCntPtr<ExternalASTSource> empty_ast_source_ap;
- ast->setExternalSource (empty_ast_source_ap);
- ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
- //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
- }
-}
-
-void
-ClangASTContext::setASTContext(clang::ASTContext *ast_ctx)
-{
- if (!m_ast_owned) {
- m_ast_ap.release();
- }
- m_ast_owned = false;
- m_ast_ap.reset(ast_ctx);
- GetASTMap().Insert(ast_ctx, this);
-}
-
-ASTContext *
-ClangASTContext::getASTContext()
-{
- if (m_ast_ap.get() == nullptr)
- {
- m_ast_owned = true;
- m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
- *getSourceManager(),
- *getIdentifierTable(),
- *getSelectorTable(),
- *getBuiltinContext()));
-
- m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(), false);
-
- // This can be NULL if we don't know anything about the architecture or if the
- // target for an architecture isn't enabled in the llvm/clang that we built
- TargetInfo *target_info = getTargetInfo();
- if (target_info)
- m_ast_ap->InitBuiltinTypes(*target_info);
-
- if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton)
- {
- m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
- //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
- }
-
- GetASTMap().Insert(m_ast_ap.get(), this);
+bool ClangASTContext::HasExternalSource() {
+ ASTContext *ast = getASTContext();
+ if (ast)
+ return ast->getExternalSource() != nullptr;
+ return false;
+}
+
+void ClangASTContext::SetExternalSource(
+ llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_ap) {
+ ASTContext *ast = getASTContext();
+ if (ast) {
+ ast->setExternalSource(ast_source_ap);
+ ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
+ // ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
+ }
+}
+
+void ClangASTContext::RemoveExternalSource() {
+ ASTContext *ast = getASTContext();
+
+ if (ast) {
+ llvm::IntrusiveRefCntPtr<ExternalASTSource> empty_ast_source_ap;
+ ast->setExternalSource(empty_ast_source_ap);
+ ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
+ // ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
+ }
+}
- llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_ap (new ClangExternalASTSourceCallbacks (ClangASTContext::CompleteTagDecl,
- ClangASTContext::CompleteObjCInterfaceDecl,
- nullptr,
- ClangASTContext::LayoutRecordType,
- this));
- SetExternalSource (ast_source_ap);
+void ClangASTContext::setASTContext(clang::ASTContext *ast_ctx) {
+ if (!m_ast_owned) {
+ m_ast_ap.release();
+ }
+ m_ast_owned = false;
+ m_ast_ap.reset(ast_ctx);
+ GetASTMap().Insert(ast_ctx, this);
+}
+
+ASTContext *ClangASTContext::getASTContext() {
+ if (m_ast_ap.get() == nullptr) {
+ m_ast_owned = true;
+ m_ast_ap.reset(new ASTContext(*getLanguageOptions(), *getSourceManager(),
+ *getIdentifierTable(), *getSelectorTable(),
+ *getBuiltinContext()));
+
+ m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(), false);
+
+ // This can be NULL if we don't know anything about the architecture or if
+ // the
+ // target for an architecture isn't enabled in the llvm/clang that we built
+ TargetInfo *target_info = getTargetInfo();
+ if (target_info)
+ m_ast_ap->InitBuiltinTypes(*target_info);
+
+ if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) {
+ m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
+ // m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
}
- return m_ast_ap.get();
+
+ GetASTMap().Insert(m_ast_ap.get(), this);
+
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_ap(
+ new ClangExternalASTSourceCallbacks(
+ ClangASTContext::CompleteTagDecl,
+ ClangASTContext::CompleteObjCInterfaceDecl, nullptr,
+ ClangASTContext::LayoutRecordType, this));
+ SetExternalSource(ast_source_ap);
+ }
+ return m_ast_ap.get();
}
-ClangASTContext*
-ClangASTContext::GetASTContext (clang::ASTContext* ast)
-{
- ClangASTContext *clang_ast = GetASTMap().Lookup(ast);
- return clang_ast;
+ClangASTContext *ClangASTContext::GetASTContext(clang::ASTContext *ast) {
+ ClangASTContext *clang_ast = GetASTMap().Lookup(ast);
+ return clang_ast;
}
-Builtin::Context *
-ClangASTContext::getBuiltinContext()
-{
- if (m_builtins_ap.get() == nullptr)
- m_builtins_ap.reset (new Builtin::Context());
- return m_builtins_ap.get();
+Builtin::Context *ClangASTContext::getBuiltinContext() {
+ if (m_builtins_ap.get() == nullptr)
+ m_builtins_ap.reset(new Builtin::Context());
+ return m_builtins_ap.get();
}
-IdentifierTable *
-ClangASTContext::getIdentifierTable()
-{
- if (m_identifier_table_ap.get() == nullptr)
- m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), nullptr));
- return m_identifier_table_ap.get();
+IdentifierTable *ClangASTContext::getIdentifierTable() {
+ if (m_identifier_table_ap.get() == nullptr)
+ m_identifier_table_ap.reset(
+ new IdentifierTable(*ClangASTContext::getLanguageOptions(), nullptr));
+ return m_identifier_table_ap.get();
}
-LangOptions *
-ClangASTContext::getLanguageOptions()
-{
- if (m_language_options_ap.get() == nullptr)
- {
- m_language_options_ap.reset(new LangOptions());
- ParseLangArgs(*m_language_options_ap, IK_ObjCXX, GetTargetTriple());
-// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
- }
- return m_language_options_ap.get();
+LangOptions *ClangASTContext::getLanguageOptions() {
+ if (m_language_options_ap.get() == nullptr) {
+ m_language_options_ap.reset(new LangOptions());
+ ParseLangArgs(*m_language_options_ap, IK_ObjCXX, GetTargetTriple());
+ // InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
+ }
+ return m_language_options_ap.get();
}
-SelectorTable *
-ClangASTContext::getSelectorTable()
-{
- if (m_selector_table_ap.get() == nullptr)
- m_selector_table_ap.reset (new SelectorTable());
- return m_selector_table_ap.get();
+SelectorTable *ClangASTContext::getSelectorTable() {
+ if (m_selector_table_ap.get() == nullptr)
+ m_selector_table_ap.reset(new SelectorTable());
+ return m_selector_table_ap.get();
}
-clang::FileManager *
-ClangASTContext::getFileManager()
-{
- if (m_file_manager_ap.get() == nullptr)
- {
- clang::FileSystemOptions file_system_options;
- m_file_manager_ap.reset(new clang::FileManager(file_system_options));
- }
- return m_file_manager_ap.get();
+clang::FileManager *ClangASTContext::getFileManager() {
+ if (m_file_manager_ap.get() == nullptr) {
+ clang::FileSystemOptions file_system_options;
+ m_file_manager_ap.reset(new clang::FileManager(file_system_options));
+ }
+ return m_file_manager_ap.get();
}
-clang::SourceManager *
-ClangASTContext::getSourceManager()
-{
- if (m_source_manager_ap.get() == nullptr)
- m_source_manager_ap.reset(new clang::SourceManager(*getDiagnosticsEngine(), *getFileManager()));
- return m_source_manager_ap.get();
+clang::SourceManager *ClangASTContext::getSourceManager() {
+ if (m_source_manager_ap.get() == nullptr)
+ m_source_manager_ap.reset(
+ new clang::SourceManager(*getDiagnosticsEngine(), *getFileManager()));
+ return m_source_manager_ap.get();
}
-clang::DiagnosticsEngine *
-ClangASTContext::getDiagnosticsEngine()
-{
- if (m_diagnostics_engine_ap.get() == nullptr)
- {
- llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
- m_diagnostics_engine_ap.reset(new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions()));
- }
- return m_diagnostics_engine_ap.get();
+clang::DiagnosticsEngine *ClangASTContext::getDiagnosticsEngine() {
+ if (m_diagnostics_engine_ap.get() == nullptr) {
+ llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
+ m_diagnostics_engine_ap.reset(
+ new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions()));
+ }
+ return m_diagnostics_engine_ap.get();
}
-clang::MangleContext *
-ClangASTContext::getMangleContext()
-{
- if (m_mangle_ctx_ap.get() == nullptr)
- m_mangle_ctx_ap.reset (getASTContext()->createMangleContext());
- return m_mangle_ctx_ap.get();
+clang::MangleContext *ClangASTContext::getMangleContext() {
+ if (m_mangle_ctx_ap.get() == nullptr)
+ m_mangle_ctx_ap.reset(getASTContext()->createMangleContext());
+ return m_mangle_ctx_ap.get();
}
-class NullDiagnosticConsumer : public DiagnosticConsumer
-{
+class NullDiagnosticConsumer : public DiagnosticConsumer {
public:
- NullDiagnosticConsumer ()
- {
- m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
- }
-
- void
- HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info)
- {
- if (m_log)
- {
- llvm::SmallVector<char, 32> diag_str(10);
- info.FormatDiagnostic(diag_str);
- diag_str.push_back('\0');
- m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
- }
- }
-
- DiagnosticConsumer *clone (DiagnosticsEngine &Diags) const
- {
- return new NullDiagnosticConsumer ();
+ NullDiagnosticConsumer() {
+ m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ }
+
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const clang::Diagnostic &info) {
+ if (m_log) {
+ llvm::SmallVector<char, 32> diag_str(10);
+ info.FormatDiagnostic(diag_str);
+ diag_str.push_back('\0');
+ m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
}
+ }
+
+ DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
+ return new NullDiagnosticConsumer();
+ }
+
private:
- Log * m_log;
+ Log *m_log;
};
-DiagnosticConsumer *
-ClangASTContext::getDiagnosticConsumer()
-{
- if (m_diagnostic_consumer_ap.get() == nullptr)
- m_diagnostic_consumer_ap.reset(new NullDiagnosticConsumer);
-
- return m_diagnostic_consumer_ap.get();
-}
+DiagnosticConsumer *ClangASTContext::getDiagnosticConsumer() {
+ if (m_diagnostic_consumer_ap.get() == nullptr)
+ m_diagnostic_consumer_ap.reset(new NullDiagnosticConsumer);
-std::shared_ptr<clang::TargetOptions> &
-ClangASTContext::getTargetOptions() {
- if (m_target_options_rp.get() == nullptr && !m_target_triple.empty())
- {
- m_target_options_rp = std::make_shared<clang::TargetOptions>();
- if (m_target_options_rp.get() != nullptr)
- m_target_options_rp->Triple = m_target_triple;
- }
- return m_target_options_rp;
+ return m_diagnostic_consumer_ap.get();
}
+std::shared_ptr<clang::TargetOptions> &ClangASTContext::getTargetOptions() {
+ if (m_target_options_rp.get() == nullptr && !m_target_triple.empty()) {
+ m_target_options_rp = std::make_shared<clang::TargetOptions>();
+ if (m_target_options_rp.get() != nullptr)
+ m_target_options_rp->Triple = m_target_triple;
+ }
+ return m_target_options_rp;
+}
-TargetInfo *
-ClangASTContext::getTargetInfo()
-{
- // target_triple should be something like "x86_64-apple-macosx"
- if (m_target_info_ap.get() == nullptr && !m_target_triple.empty())
- m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(), getTargetOptions()));
- return m_target_info_ap.get();
+TargetInfo *ClangASTContext::getTargetInfo() {
+ // target_triple should be something like "x86_64-apple-macosx"
+ if (m_target_info_ap.get() == nullptr && !m_target_triple.empty())
+ m_target_info_ap.reset(TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(),
+ getTargetOptions()));
+ return m_target_info_ap.get();
}
#pragma mark Basic Types
-static inline bool
-QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
-{
- uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
- if (qual_type_bit_size == bit_size)
- return true;
- return false;
+static inline bool QualTypeMatchesBitSize(const uint64_t bit_size,
+ ASTContext *ast, QualType qual_type) {
+ uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
+ if (qual_type_bit_size == bit_size)
+ return true;
+ return false;
}
CompilerType
-ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, size_t bit_size)
-{
- return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (getASTContext(), encoding, bit_size);
+ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
+ size_t bit_size) {
+ return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
+ getASTContext(), encoding, bit_size);
}
-CompilerType
-ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
-{
- if (!ast)
- return CompilerType();
- switch (encoding)
- {
- case eEncodingInvalid:
- if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
- return CompilerType (ast, ast->VoidPtrTy);
- break;
-
- case eEncodingUint:
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
- return CompilerType (ast, ast->UnsignedCharTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
- return CompilerType (ast, ast->UnsignedShortTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
- return CompilerType (ast, ast->UnsignedIntTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
- return CompilerType (ast, ast->UnsignedLongTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
- return CompilerType (ast, ast->UnsignedLongLongTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
- return CompilerType (ast, ast->UnsignedInt128Ty);
- break;
-
- case eEncodingSint:
- if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
- return CompilerType (ast, ast->SignedCharTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
- return CompilerType (ast, ast->ShortTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
- return CompilerType (ast, ast->IntTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
- return CompilerType (ast, ast->LongTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
- return CompilerType (ast, ast->LongLongTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
- return CompilerType (ast, ast->Int128Ty);
- break;
-
- case eEncodingIEEE754:
- if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
- return CompilerType (ast, ast->FloatTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
- return CompilerType (ast, ast->DoubleTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
- return CompilerType (ast, ast->LongDoubleTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->HalfTy))
- return CompilerType (ast, ast->HalfTy);
- break;
-
- case eEncodingVector:
- // Sanity check that bit_size is a multiple of 8's.
- if (bit_size && !(bit_size & 0x7u))
- return CompilerType (ast, ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8));
- break;
- }
-
+CompilerType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
+ ASTContext *ast, Encoding encoding, uint32_t bit_size) {
+ if (!ast)
return CompilerType();
+ switch (encoding) {
+ case eEncodingInvalid:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
+ return CompilerType(ast, ast->VoidPtrTy);
+ break;
+
+ case eEncodingUint:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
+ return CompilerType(ast, ast->UnsignedCharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
+ return CompilerType(ast, ast->UnsignedShortTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
+ return CompilerType(ast, ast->UnsignedIntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
+ return CompilerType(ast, ast->UnsignedLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
+ return CompilerType(ast, ast->UnsignedLongLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
+ return CompilerType(ast, ast->UnsignedInt128Ty);
+ break;
+
+ case eEncodingSint:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
+ return CompilerType(ast, ast->SignedCharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
+ return CompilerType(ast, ast->ShortTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
+ return CompilerType(ast, ast->IntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
+ return CompilerType(ast, ast->LongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
+ return CompilerType(ast, ast->LongLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
+ return CompilerType(ast, ast->Int128Ty);
+ break;
+
+ case eEncodingIEEE754:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
+ return CompilerType(ast, ast->FloatTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
+ return CompilerType(ast, ast->DoubleTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
+ return CompilerType(ast, ast->LongDoubleTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
+ return CompilerType(ast, ast->HalfTy);
+ break;
+
+ case eEncodingVector:
+ // Sanity check that bit_size is a multiple of 8's.
+ if (bit_size && !(bit_size & 0x7u))
+ return CompilerType(
+ ast, ast->getExtVectorType(ast->UnsignedCharTy, bit_size / 8));
+ break;
+ }
+
+ return CompilerType();
}
-
-
lldb::BasicType
-ClangASTContext::GetBasicTypeEnumeration (const ConstString &name)
-{
- if (name)
- {
- typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
- static TypeNameToBasicTypeMap g_type_map;
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, [](){
- // "void"
- g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
-
- // "char"
- g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar);
- g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar);
- g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar);
- g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar);
- g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar);
- g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar);
- // "short"
- g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort);
- g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort);
- g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort);
- g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort);
-
- // "int"
- g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
- g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt);
- g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt);
- g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt);
-
- // "long"
- g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong);
- g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong);
- g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong);
- g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong);
-
- // "long long"
- g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong);
- g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong);
- g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong);
- g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong);
-
- // "int128"
- g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128);
- g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128);
-
- // Miscellaneous
- g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
- g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat);
- g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble);
- g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble);
- g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID);
- g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel);
- g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr);
- g_type_map.Sort();
- });
-
- return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
- }
- return eBasicTypeInvalid;
-}
+ClangASTContext::GetBasicTypeEnumeration(const ConstString &name) {
+ if (name) {
+ typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
+ static TypeNameToBasicTypeMap g_type_map;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ // "void"
+ g_type_map.Append(ConstString("void").GetStringRef(), eBasicTypeVoid);
+
+ // "char"
+ g_type_map.Append(ConstString("char").GetStringRef(), eBasicTypeChar);
+ g_type_map.Append(ConstString("signed char").GetStringRef(),
+ eBasicTypeSignedChar);
+ g_type_map.Append(ConstString("unsigned char").GetStringRef(),
+ eBasicTypeUnsignedChar);
+ g_type_map.Append(ConstString("wchar_t").GetStringRef(), eBasicTypeWChar);
+ g_type_map.Append(ConstString("signed wchar_t").GetStringRef(),
+ eBasicTypeSignedWChar);
+ g_type_map.Append(ConstString("unsigned wchar_t").GetStringRef(),
+ eBasicTypeUnsignedWChar);
+ // "short"
+ g_type_map.Append(ConstString("short").GetStringRef(), eBasicTypeShort);
+ g_type_map.Append(ConstString("short int").GetStringRef(),
+ eBasicTypeShort);
+ g_type_map.Append(ConstString("unsigned short").GetStringRef(),
+ eBasicTypeUnsignedShort);
+ g_type_map.Append(ConstString("unsigned short int").GetStringRef(),
+ eBasicTypeUnsignedShort);
+
+ // "int"
+ g_type_map.Append(ConstString("int").GetStringRef(), eBasicTypeInt);
+ g_type_map.Append(ConstString("signed int").GetStringRef(),
+ eBasicTypeInt);
+ g_type_map.Append(ConstString("unsigned int").GetStringRef(),
+ eBasicTypeUnsignedInt);
+ g_type_map.Append(ConstString("unsigned").GetStringRef(),
+ eBasicTypeUnsignedInt);
+
+ // "long"
+ g_type_map.Append(ConstString("long").GetStringRef(), eBasicTypeLong);
+ g_type_map.Append(ConstString("long int").GetStringRef(), eBasicTypeLong);
+ g_type_map.Append(ConstString("unsigned long").GetStringRef(),
+ eBasicTypeUnsignedLong);
+ g_type_map.Append(ConstString("unsigned long int").GetStringRef(),
+ eBasicTypeUnsignedLong);
+
+ // "long long"
+ g_type_map.Append(ConstString("long long").GetStringRef(),
+ eBasicTypeLongLong);
+ g_type_map.Append(ConstString("long long int").GetStringRef(),
+ eBasicTypeLongLong);
+ g_type_map.Append(ConstString("unsigned long long").GetStringRef(),
+ eBasicTypeUnsignedLongLong);
+ g_type_map.Append(ConstString("unsigned long long int").GetStringRef(),
+ eBasicTypeUnsignedLongLong);
+
+ // "int128"
+ g_type_map.Append(ConstString("__int128_t").GetStringRef(),
+ eBasicTypeInt128);
+ g_type_map.Append(ConstString("__uint128_t").GetStringRef(),
+ eBasicTypeUnsignedInt128);
+
+ // Miscellaneous
+ g_type_map.Append(ConstString("bool").GetStringRef(), eBasicTypeBool);
+ g_type_map.Append(ConstString("float").GetStringRef(), eBasicTypeFloat);
+ g_type_map.Append(ConstString("double").GetStringRef(), eBasicTypeDouble);
+ g_type_map.Append(ConstString("long double").GetStringRef(),
+ eBasicTypeLongDouble);
+ g_type_map.Append(ConstString("id").GetStringRef(), eBasicTypeObjCID);
+ g_type_map.Append(ConstString("SEL").GetStringRef(), eBasicTypeObjCSel);
+ g_type_map.Append(ConstString("nullptr").GetStringRef(),
+ eBasicTypeNullPtr);
+ g_type_map.Sort();
+ });
-CompilerType
-ClangASTContext::GetBasicType (ASTContext *ast, const ConstString &name)
-{
- if (ast)
- {
- lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration (name);
- return ClangASTContext::GetBasicType (ast, basic_type);
- }
- return CompilerType();
+ return g_type_map.Find(name.GetStringRef(), eBasicTypeInvalid);
+ }
+ return eBasicTypeInvalid;
}
-uint32_t
-ClangASTContext::GetPointerByteSize ()
-{
- if (m_pointer_byte_size == 0)
- m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid).GetPointerType().GetByteSize(nullptr);
- return m_pointer_byte_size;
+CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
+ const ConstString &name) {
+ if (ast) {
+ lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration(name);
+ return ClangASTContext::GetBasicType(ast, basic_type);
+ }
+ return CompilerType();
}
-CompilerType
-ClangASTContext::GetBasicType (lldb::BasicType basic_type)
-{
- return GetBasicType (getASTContext(), basic_type);
+uint32_t ClangASTContext::GetPointerByteSize() {
+ if (m_pointer_byte_size == 0)
+ m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid)
+ .GetPointerType()
+ .GetByteSize(nullptr);
+ return m_pointer_byte_size;
}
-CompilerType
-ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type)
-{
- if (!ast)
- return CompilerType();
- lldb::opaque_compiler_type_t clang_type = GetOpaqueCompilerType(ast, basic_type);
-
- if (clang_type)
- return CompilerType(GetASTContext(ast), clang_type);
- return CompilerType();
+CompilerType ClangASTContext::GetBasicType(lldb::BasicType basic_type) {
+ return GetBasicType(getASTContext(), basic_type);
}
+CompilerType ClangASTContext::GetBasicType(ASTContext *ast,
+ lldb::BasicType basic_type) {
+ if (!ast)
+ return CompilerType();
+ lldb::opaque_compiler_type_t clang_type =
+ GetOpaqueCompilerType(ast, basic_type);
-CompilerType
-ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
-{
- ASTContext *ast = getASTContext();
-
-#define streq(a,b) strcmp(a,b) == 0
- assert (ast != nullptr);
- if (ast)
- {
- switch (dw_ate)
- {
- default:
- break;
-
- case DW_ATE_address:
- if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
- return CompilerType (ast, ast->VoidPtrTy);
- break;
-
- case DW_ATE_boolean:
- if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
- return CompilerType (ast, ast->BoolTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
- return CompilerType (ast, ast->UnsignedCharTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
- return CompilerType (ast, ast->UnsignedShortTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
- return CompilerType (ast, ast->UnsignedIntTy);
- break;
-
- case DW_ATE_lo_user:
- // This has been seen to mean DW_AT_complex_integer
- if (type_name)
- {
- if (::strstr(type_name, "complex"))
- {
- CompilerType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
- return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_int_clang_type)));
- }
- }
- break;
-
- case DW_ATE_complex_float:
- if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
- return CompilerType (ast, ast->FloatComplexTy);
- else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
- return CompilerType (ast, ast->DoubleComplexTy);
- else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
- return CompilerType (ast, ast->LongDoubleComplexTy);
- else
- {
- CompilerType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
- return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_float_clang_type)));
- }
- break;
-
- case DW_ATE_float:
- if (streq(type_name, "float") && QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
- return CompilerType (ast, ast->FloatTy);
- if (streq(type_name, "double") && QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
- return CompilerType (ast, ast->DoubleTy);
- if (streq(type_name, "long double") && QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
- return CompilerType (ast, ast->LongDoubleTy);
- // Fall back to not requiring a name match
- if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
- return CompilerType (ast, ast->FloatTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
- return CompilerType (ast, ast->DoubleTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
- return CompilerType (ast, ast->LongDoubleTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->HalfTy))
- return CompilerType (ast, ast->HalfTy);
- break;
-
- case DW_ATE_signed:
- if (type_name)
- {
- if (streq(type_name, "wchar_t") &&
- QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy) &&
- (getTargetInfo() && TargetInfo::isTypeSigned (getTargetInfo()->getWCharType())))
- return CompilerType (ast, ast->WCharTy);
- if (streq(type_name, "void") &&
- QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
- return CompilerType (ast, ast->VoidTy);
- if (strstr(type_name, "long long") &&
- QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
- return CompilerType (ast, ast->LongLongTy);
- if (strstr(type_name, "long") &&
- QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
- return CompilerType (ast, ast->LongTy);
- if (strstr(type_name, "short") &&
- QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
- return CompilerType (ast, ast->ShortTy);
- if (strstr(type_name, "char"))
- {
- if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
- return CompilerType (ast, ast->CharTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
- return CompilerType (ast, ast->SignedCharTy);
- }
- if (strstr(type_name, "int"))
- {
- if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
- return CompilerType (ast, ast->IntTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
- return CompilerType (ast, ast->Int128Ty);
- }
- }
- // We weren't able to match up a type name, just search by size
- if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
- return CompilerType (ast, ast->CharTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
- return CompilerType (ast, ast->ShortTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
- return CompilerType (ast, ast->IntTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
- return CompilerType (ast, ast->LongTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
- return CompilerType (ast, ast->LongLongTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
- return CompilerType (ast, ast->Int128Ty);
- break;
+ if (clang_type)
+ return CompilerType(GetASTContext(ast), clang_type);
+ return CompilerType();
+}
- case DW_ATE_signed_char:
- if (ast->getLangOpts().CharIsSigned && type_name && streq(type_name, "char"))
- {
- if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
- return CompilerType (ast, ast->CharTy);
- }
- if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
- return CompilerType (ast, ast->SignedCharTy);
- break;
-
- case DW_ATE_unsigned:
- if (type_name)
- {
- if (streq(type_name, "wchar_t"))
- {
- if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
- {
- if (!(getTargetInfo() && TargetInfo::isTypeSigned (getTargetInfo()->getWCharType())))
- return CompilerType (ast, ast->WCharTy);
- }
- }
- if (strstr(type_name, "long long"))
- {
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
- return CompilerType (ast, ast->UnsignedLongLongTy);
- }
- else if (strstr(type_name, "long"))
- {
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
- return CompilerType (ast, ast->UnsignedLongTy);
- }
- else if (strstr(type_name, "short"))
- {
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
- return CompilerType (ast, ast->UnsignedShortTy);
- }
- else if (strstr(type_name, "char"))
- {
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
- return CompilerType (ast, ast->UnsignedCharTy);
- }
- else if (strstr(type_name, "int"))
- {
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
- return CompilerType (ast, ast->UnsignedIntTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
- return CompilerType (ast, ast->UnsignedInt128Ty);
- }
- }
- // We weren't able to match up a type name, just search by size
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
- return CompilerType (ast, ast->UnsignedCharTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
- return CompilerType (ast, ast->UnsignedShortTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
- return CompilerType (ast, ast->UnsignedIntTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
- return CompilerType (ast, ast->UnsignedLongTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
- return CompilerType (ast, ast->UnsignedLongLongTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
- return CompilerType (ast, ast->UnsignedInt128Ty);
- break;
+CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize(
+ const char *type_name, uint32_t dw_ate, uint32_t bit_size) {
+ ASTContext *ast = getASTContext();
- case DW_ATE_unsigned_char:
- if (!ast->getLangOpts().CharIsSigned && type_name && streq(type_name, "char"))
- {
- if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
- return CompilerType (ast, ast->CharTy);
- }
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
- return CompilerType (ast, ast->UnsignedCharTy);
- if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
- return CompilerType (ast, ast->UnsignedShortTy);
- break;
-
- case DW_ATE_imaginary_float:
- break;
-
- case DW_ATE_UTF:
- if (type_name)
- {
- if (streq(type_name, "char16_t"))
- {
- return CompilerType (ast, ast->Char16Ty);
- }
- else if (streq(type_name, "char32_t"))
- {
- return CompilerType (ast, ast->Char32Ty);
- }
- }
- break;
+#define streq(a, b) strcmp(a, b) == 0
+ assert(ast != nullptr);
+ if (ast) {
+ switch (dw_ate) {
+ default:
+ break;
+
+ case DW_ATE_address:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy))
+ return CompilerType(ast, ast->VoidPtrTy);
+ break;
+
+ case DW_ATE_boolean:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->BoolTy))
+ return CompilerType(ast, ast->BoolTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
+ return CompilerType(ast, ast->UnsignedCharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
+ return CompilerType(ast, ast->UnsignedShortTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
+ return CompilerType(ast, ast->UnsignedIntTy);
+ break;
+
+ case DW_ATE_lo_user:
+ // This has been seen to mean DW_AT_complex_integer
+ if (type_name) {
+ if (::strstr(type_name, "complex")) {
+ CompilerType complex_int_clang_type =
+ GetBuiltinTypeForDWARFEncodingAndBitSize("int", DW_ATE_signed,
+ bit_size / 2);
+ return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(
+ complex_int_clang_type)));
}
+ }
+ break;
+
+ case DW_ATE_complex_float:
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatComplexTy))
+ return CompilerType(ast, ast->FloatComplexTy);
+ else if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleComplexTy))
+ return CompilerType(ast, ast->DoubleComplexTy);
+ else if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleComplexTy))
+ return CompilerType(ast, ast->LongDoubleComplexTy);
+ else {
+ CompilerType complex_float_clang_type =
+ GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float,
+ bit_size / 2);
+ return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(
+ complex_float_clang_type)));
+ }
+ break;
+
+ case DW_ATE_float:
+ if (streq(type_name, "float") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
+ return CompilerType(ast, ast->FloatTy);
+ if (streq(type_name, "double") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
+ return CompilerType(ast, ast->DoubleTy);
+ if (streq(type_name, "long double") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
+ return CompilerType(ast, ast->LongDoubleTy);
+ // Fall back to not requiring a name match
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy))
+ return CompilerType(ast, ast->FloatTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy))
+ return CompilerType(ast, ast->DoubleTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy))
+ return CompilerType(ast, ast->LongDoubleTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy))
+ return CompilerType(ast, ast->HalfTy);
+ break;
+
+ case DW_ATE_signed:
+ if (type_name) {
+ if (streq(type_name, "wchar_t") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy) &&
+ (getTargetInfo() &&
+ TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
+ return CompilerType(ast, ast->WCharTy);
+ if (streq(type_name, "void") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast->VoidTy))
+ return CompilerType(ast, ast->VoidTy);
+ if (strstr(type_name, "long long") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
+ return CompilerType(ast, ast->LongLongTy);
+ if (strstr(type_name, "long") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
+ return CompilerType(ast, ast->LongTy);
+ if (strstr(type_name, "short") &&
+ QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
+ return CompilerType(ast, ast->ShortTy);
+ if (strstr(type_name, "char")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
+ return CompilerType(ast, ast->CharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
+ return CompilerType(ast, ast->SignedCharTy);
+ }
+ if (strstr(type_name, "int")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
+ return CompilerType(ast, ast->IntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
+ return CompilerType(ast, ast->Int128Ty);
+ }
+ }
+ // We weren't able to match up a type name, just search by size
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
+ return CompilerType(ast, ast->CharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy))
+ return CompilerType(ast, ast->ShortTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy))
+ return CompilerType(ast, ast->IntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy))
+ return CompilerType(ast, ast->LongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy))
+ return CompilerType(ast, ast->LongLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty))
+ return CompilerType(ast, ast->Int128Ty);
+ break;
+
+ case DW_ATE_signed_char:
+ if (ast->getLangOpts().CharIsSigned && type_name &&
+ streq(type_name, "char")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
+ return CompilerType(ast, ast->CharTy);
+ }
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy))
+ return CompilerType(ast, ast->SignedCharTy);
+ break;
+
+ case DW_ATE_unsigned:
+ if (type_name) {
+ if (streq(type_name, "wchar_t")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy)) {
+ if (!(getTargetInfo() &&
+ TargetInfo::isTypeSigned(getTargetInfo()->getWCharType())))
+ return CompilerType(ast, ast->WCharTy);
+ }
+ }
+ if (strstr(type_name, "long long")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
+ return CompilerType(ast, ast->UnsignedLongLongTy);
+ } else if (strstr(type_name, "long")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
+ return CompilerType(ast, ast->UnsignedLongTy);
+ } else if (strstr(type_name, "short")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
+ return CompilerType(ast, ast->UnsignedShortTy);
+ } else if (strstr(type_name, "char")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
+ return CompilerType(ast, ast->UnsignedCharTy);
+ } else if (strstr(type_name, "int")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
+ return CompilerType(ast, ast->UnsignedIntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
+ return CompilerType(ast, ast->UnsignedInt128Ty);
+ }
+ }
+ // We weren't able to match up a type name, just search by size
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
+ return CompilerType(ast, ast->UnsignedCharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
+ return CompilerType(ast, ast->UnsignedShortTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy))
+ return CompilerType(ast, ast->UnsignedIntTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy))
+ return CompilerType(ast, ast->UnsignedLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy))
+ return CompilerType(ast, ast->UnsignedLongLongTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty))
+ return CompilerType(ast, ast->UnsignedInt128Ty);
+ break;
+
+ case DW_ATE_unsigned_char:
+ if (!ast->getLangOpts().CharIsSigned && type_name &&
+ streq(type_name, "char")) {
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy))
+ return CompilerType(ast, ast->CharTy);
+ }
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy))
+ return CompilerType(ast, ast->UnsignedCharTy);
+ if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy))
+ return CompilerType(ast, ast->UnsignedShortTy);
+ break;
+
+ case DW_ATE_imaginary_float:
+ break;
+
+ case DW_ATE_UTF:
+ if (type_name) {
+ if (streq(type_name, "char16_t")) {
+ return CompilerType(ast, ast->Char16Ty);
+ } else if (streq(type_name, "char32_t")) {
+ return CompilerType(ast, ast->Char32Ty);
+ }
+ }
+ break;
}
- // This assert should fire for anything that we don't catch above so we know
- // to fix any issues we run into.
- if (type_name)
- {
- Host::SystemLog (Host::eSystemLogError, "error: need to add support for DW_TAG_base_type '%s' encoded with DW_ATE = 0x%x, bit_size = %u\n", type_name, dw_ate, bit_size);
- }
- else
- {
- Host::SystemLog (Host::eSystemLogError, "error: need to add support for DW_TAG_base_type encoded with DW_ATE = 0x%x, bit_size = %u\n", dw_ate, bit_size);
- }
- return CompilerType ();
+ }
+ // This assert should fire for anything that we don't catch above so we know
+ // to fix any issues we run into.
+ if (type_name) {
+ Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
+ "DW_TAG_base_type '%s' encoded with "
+ "DW_ATE = 0x%x, bit_size = %u\n",
+ type_name, dw_ate, bit_size);
+ } else {
+ Host::SystemLog(Host::eSystemLogError, "error: need to add support for "
+ "DW_TAG_base_type encoded with "
+ "DW_ATE = 0x%x, bit_size = %u\n",
+ dw_ate, bit_size);
+ }
+ return CompilerType();
}
-CompilerType
-ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
-{
- if (ast)
- return CompilerType (ast, ast->UnknownAnyTy);
- return CompilerType();
+CompilerType ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast) {
+ if (ast)
+ return CompilerType(ast, ast->UnknownAnyTy);
+ return CompilerType();
}
-CompilerType
-ClangASTContext::GetCStringType (bool is_const)
-{
- ASTContext *ast = getASTContext();
- QualType char_type(ast->CharTy);
-
- if (is_const)
- char_type.addConst();
-
- return CompilerType (ast, ast->getPointerType(char_type));
+CompilerType ClangASTContext::GetCStringType(bool is_const) {
+ ASTContext *ast = getASTContext();
+ QualType char_type(ast->CharTy);
+
+ if (is_const)
+ char_type.addConst();
+
+ return CompilerType(ast, ast->getPointerType(char_type));
}
clang::DeclContext *
-ClangASTContext::GetTranslationUnitDecl (clang::ASTContext *ast)
-{
- return ast->getTranslationUnitDecl();
-}
-
-clang::Decl *
-ClangASTContext::CopyDecl (ASTContext *dst_ast,
- ASTContext *src_ast,
- clang::Decl *source_decl)
-{
- FileSystemOptions file_system_options;
- FileManager file_manager (file_system_options);
- ASTImporter importer(*dst_ast, file_manager,
- *src_ast, file_manager,
- false);
-
- return importer.Import(source_decl);
-}
-
-bool
-ClangASTContext::AreTypesSame (CompilerType type1,
- CompilerType type2,
- bool ignore_qualifiers)
-{
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type1.GetTypeSystem());
- if (!ast || ast != type2.GetTypeSystem())
- return false;
-
- if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
- return true;
+ClangASTContext::GetTranslationUnitDecl(clang::ASTContext *ast) {
+ return ast->getTranslationUnitDecl();
+}
- QualType type1_qual = ClangUtil::GetQualType(type1);
- QualType type2_qual = ClangUtil::GetQualType(type2);
+clang::Decl *ClangASTContext::CopyDecl(ASTContext *dst_ast, ASTContext *src_ast,
+ clang::Decl *source_decl) {
+ FileSystemOptions file_system_options;
+ FileManager file_manager(file_system_options);
+ ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager, false);
- if (ignore_qualifiers)
- {
- type1_qual = type1_qual.getUnqualifiedType();
- type2_qual = type2_qual.getUnqualifiedType();
- }
-
- return ast->getASTContext()->hasSameType (type1_qual, type2_qual);
+ return importer.Import(source_decl);
}
-CompilerType
-ClangASTContext::GetTypeForDecl (clang::NamedDecl *decl)
-{
- if (clang::ObjCInterfaceDecl *interface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
- return GetTypeForDecl(interface_decl);
- if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
- return GetTypeForDecl(tag_decl);
- return CompilerType();
+bool ClangASTContext::AreTypesSame(CompilerType type1, CompilerType type2,
+ bool ignore_qualifiers) {
+ ClangASTContext *ast =
+ llvm::dyn_cast_or_null<ClangASTContext>(type1.GetTypeSystem());
+ if (!ast || ast != type2.GetTypeSystem())
+ return false;
+
+ if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
+ return true;
+
+ QualType type1_qual = ClangUtil::GetQualType(type1);
+ QualType type2_qual = ClangUtil::GetQualType(type2);
+
+ if (ignore_qualifiers) {
+ type1_qual = type1_qual.getUnqualifiedType();
+ type2_qual = type2_qual.getUnqualifiedType();
+ }
+
+ return ast->getASTContext()->hasSameType(type1_qual, type2_qual);
}
+CompilerType ClangASTContext::GetTypeForDecl(clang::NamedDecl *decl) {
+ if (clang::ObjCInterfaceDecl *interface_decl =
+ llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
+ return GetTypeForDecl(interface_decl);
+ if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
+ return GetTypeForDecl(tag_decl);
+ return CompilerType();
+}
-CompilerType
-ClangASTContext::GetTypeForDecl (TagDecl *decl)
-{
- // No need to call the getASTContext() accessor (which can create the AST
- // if it isn't created yet, because we can't have created a decl in this
- // AST if our AST didn't already exist...
- ASTContext *ast = &decl->getASTContext();
- if (ast)
- return CompilerType (ast, ast->getTagDeclType(decl));
- return CompilerType();
+CompilerType ClangASTContext::GetTypeForDecl(TagDecl *decl) {
+ // No need to call the getASTContext() accessor (which can create the AST
+ // if it isn't created yet, because we can't have created a decl in this
+ // AST if our AST didn't already exist...
+ ASTContext *ast = &decl->getASTContext();
+ if (ast)
+ return CompilerType(ast, ast->getTagDeclType(decl));
+ return CompilerType();
}
-CompilerType
-ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
-{
- // No need to call the getASTContext() accessor (which can create the AST
- // if it isn't created yet, because we can't have created a decl in this
- // AST if our AST didn't already exist...
- ASTContext *ast = &decl->getASTContext();
- if (ast)
- return CompilerType (ast, ast->getObjCInterfaceType(decl));
- return CompilerType();
+CompilerType ClangASTContext::GetTypeForDecl(ObjCInterfaceDecl *decl) {
+ // No need to call the getASTContext() accessor (which can create the AST
+ // if it isn't created yet, because we can't have created a decl in this
+ // AST if our AST didn't already exist...
+ ASTContext *ast = &decl->getASTContext();
+ if (ast)
+ return CompilerType(ast, ast->getObjCInterfaceType(decl));
+ return CompilerType();
}
#pragma mark Structure, Unions, Classes
-CompilerType
-ClangASTContext::CreateRecordType (DeclContext *decl_ctx,
- AccessType access_type,
- const char *name,
- int kind,
- LanguageType language,
- ClangASTMetadata *metadata)
-{
- ASTContext *ast = getASTContext();
- assert (ast != nullptr);
-
- if (decl_ctx == nullptr)
- decl_ctx = ast->getTranslationUnitDecl();
-
-
- if (language == eLanguageTypeObjC || language == eLanguageTypeObjC_plus_plus)
- {
- bool isForwardDecl = true;
- bool isInternal = false;
- return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal, metadata);
- }
-
- // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
- // we will need to update this code. I was told to currently always use
- // the CXXRecordDecl class since we often don't know from debug information
- // if something is struct or a class, so we default to always use the more
- // complete definition just in case.
-
- bool is_anonymous = (!name) || (!name[0]);
-
- CXXRecordDecl *decl = CXXRecordDecl::Create (*ast,
- (TagDecl::TagKind)kind,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- is_anonymous ? nullptr : &ast->Idents.get(name));
-
- if (is_anonymous)
- decl->setAnonymousStructOrUnion(true);
-
- if (decl)
- {
- if (metadata)
- SetMetadata(ast, decl, *metadata);
+CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx,
+ AccessType access_type,
+ const char *name, int kind,
+ LanguageType language,
+ ClangASTMetadata *metadata) {
+ ASTContext *ast = getASTContext();
+ assert(ast != nullptr);
- if (access_type != eAccessNone)
- decl->setAccess (ConvertAccessTypeToAccessSpecifier (access_type));
-
- if (decl_ctx)
- decl_ctx->addDecl (decl);
+ if (decl_ctx == nullptr)
+ decl_ctx = ast->getTranslationUnitDecl();
- return CompilerType(ast, ast->getTagDeclType(decl));
- }
- return CompilerType();
-}
+ if (language == eLanguageTypeObjC ||
+ language == eLanguageTypeObjC_plus_plus) {
+ bool isForwardDecl = true;
+ bool isInternal = false;
+ return CreateObjCClass(name, decl_ctx, isForwardDecl, isInternal, metadata);
+ }
-static TemplateParameterList *
-CreateTemplateParameterList (ASTContext *ast,
- const ClangASTContext::TemplateParameterInfos &template_param_infos,
- llvm::SmallVector<NamedDecl *, 8> &template_param_decls)
-{
- const bool parameter_pack = false;
- const bool is_typename = false;
- const unsigned depth = 0;
- const size_t num_template_params = template_param_infos.GetSize();
- for (size_t i=0; i<num_template_params; ++i)
- {
- const char *name = template_param_infos.names[i];
-
- IdentifierInfo *identifier_info = nullptr;
- if (name && name[0])
- identifier_info = &ast->Idents.get(name);
- if (template_param_infos.args[i].getKind() == TemplateArgument::Integral)
- {
- template_param_decls.push_back (NonTypeTemplateParmDecl::Create (*ast,
- ast->getTranslationUnitDecl(), // Is this the right decl context?, SourceLocation StartLoc,
- SourceLocation(),
- SourceLocation(),
- depth,
- i,
- identifier_info,
- template_param_infos.args[i].getIntegralType(),
- parameter_pack,
- nullptr));
-
- }
- else
- {
- template_param_decls.push_back (TemplateTypeParmDecl::Create (*ast,
- ast->getTranslationUnitDecl(), // Is this the right decl context?
- SourceLocation(),
- SourceLocation(),
- depth,
- i,
- identifier_info,
- is_typename,
- parameter_pack));
- }
- }
+ // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
+ // we will need to update this code. I was told to currently always use
+ // the CXXRecordDecl class since we often don't know from debug information
+ // if something is struct or a class, so we default to always use the more
+ // complete definition just in case.
+
+ bool is_anonymous = (!name) || (!name[0]);
- TemplateParameterList *template_param_list = TemplateParameterList::Create (*ast,
- SourceLocation(),
- SourceLocation(),
- template_param_decls,
- SourceLocation());
- return template_param_list;
+ CXXRecordDecl *decl = CXXRecordDecl::Create(
+ *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
+ SourceLocation(), is_anonymous ? nullptr : &ast->Idents.get(name));
+
+ if (is_anonymous)
+ decl->setAnonymousStructOrUnion(true);
+
+ if (decl) {
+ if (metadata)
+ SetMetadata(ast, decl, *metadata);
+
+ if (access_type != eAccessNone)
+ decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type));
+
+ if (decl_ctx)
+ decl_ctx->addDecl(decl);
+
+ return CompilerType(ast, ast->getTagDeclType(decl));
+ }
+ return CompilerType();
}
-clang::FunctionTemplateDecl *
-ClangASTContext::CreateFunctionTemplateDecl (clang::DeclContext *decl_ctx,
- clang::FunctionDecl *func_decl,
- const char *name,
- const TemplateParameterInfos &template_param_infos)
-{
-// /// \brief Create a function template node.
- ASTContext *ast = getASTContext();
-
- llvm::SmallVector<NamedDecl *, 8> template_param_decls;
-
- TemplateParameterList *template_param_list = CreateTemplateParameterList (ast,
- template_param_infos,
- template_param_decls);
- FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create (*ast,
- decl_ctx,
- func_decl->getLocation(),
- func_decl->getDeclName(),
- template_param_list,
- func_decl);
-
- for (size_t i=0, template_param_decl_count = template_param_decls.size();
- i < template_param_decl_count;
- ++i)
- {
- // TODO: verify which decl context we should put template_param_decls into..
- template_param_decls[i]->setDeclContext (func_decl);
- }
-
- return func_tmpl_decl;
-}
-
-void
-ClangASTContext::CreateFunctionTemplateSpecializationInfo (FunctionDecl *func_decl,
- clang::FunctionTemplateDecl *func_tmpl_decl,
- const TemplateParameterInfos &infos)
-{
- TemplateArgumentList template_args (TemplateArgumentList::OnStack, infos.args);
-
- func_decl->setFunctionTemplateSpecialization (func_tmpl_decl,
- &template_args,
- nullptr);
-}
-
-
-ClassTemplateDecl *
-ClangASTContext::CreateClassTemplateDecl (DeclContext *decl_ctx,
- lldb::AccessType access_type,
- const char *class_name,
- int kind,
- const TemplateParameterInfos &template_param_infos)
-{
- ASTContext *ast = getASTContext();
-
- ClassTemplateDecl *class_template_decl = nullptr;
- if (decl_ctx == nullptr)
- decl_ctx = ast->getTranslationUnitDecl();
-
- IdentifierInfo &identifier_info = ast->Idents.get(class_name);
- DeclarationName decl_name (&identifier_info);
+static TemplateParameterList *CreateTemplateParameterList(
+ ASTContext *ast,
+ const ClangASTContext::TemplateParameterInfos &template_param_infos,
+ llvm::SmallVector<NamedDecl *, 8> &template_param_decls) {
+ const bool parameter_pack = false;
+ const bool is_typename = false;
+ const unsigned depth = 0;
+ const size_t num_template_params = template_param_infos.GetSize();
+ for (size_t i = 0; i < num_template_params; ++i) {
+ const char *name = template_param_infos.names[i];
+
+ IdentifierInfo *identifier_info = nullptr;
+ if (name && name[0])
+ identifier_info = &ast->Idents.get(name);
+ if (template_param_infos.args[i].getKind() == TemplateArgument::Integral) {
+ template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
+ *ast,
+ ast->getTranslationUnitDecl(), // Is this the right decl context?,
+ // SourceLocation StartLoc,
+ SourceLocation(), SourceLocation(), depth, i, identifier_info,
+ template_param_infos.args[i].getIntegralType(), parameter_pack,
+ nullptr));
+
+ } else {
+ template_param_decls.push_back(TemplateTypeParmDecl::Create(
+ *ast,
+ ast->getTranslationUnitDecl(), // Is this the right decl context?
+ SourceLocation(), SourceLocation(), depth, i, identifier_info,
+ is_typename, parameter_pack));
+ }
+ }
+
+ clang::Expr *const requires_clause = nullptr; // TODO: Concepts
+ TemplateParameterList *template_param_list = TemplateParameterList::Create(
+ *ast, SourceLocation(), SourceLocation(), template_param_decls,
+ SourceLocation(), requires_clause);
+ return template_param_list;
+}
+
+clang::FunctionTemplateDecl *ClangASTContext::CreateFunctionTemplateDecl(
+ clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl,
+ const char *name, const TemplateParameterInfos &template_param_infos) {
+ // /// \brief Create a function template node.
+ ASTContext *ast = getASTContext();
+
+ llvm::SmallVector<NamedDecl *, 8> template_param_decls;
+
+ TemplateParameterList *template_param_list = CreateTemplateParameterList(
+ ast, template_param_infos, template_param_decls);
+ FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create(
+ *ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(),
+ template_param_list, func_decl);
+
+ for (size_t i = 0, template_param_decl_count = template_param_decls.size();
+ i < template_param_decl_count; ++i) {
+ // TODO: verify which decl context we should put template_param_decls into..
+ template_param_decls[i]->setDeclContext(func_decl);
+ }
+
+ return func_tmpl_decl;
+}
+
+void ClangASTContext::CreateFunctionTemplateSpecializationInfo(
+ FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl,
+ const TemplateParameterInfos &infos) {
+ TemplateArgumentList template_args(TemplateArgumentList::OnStack, infos.args);
+
+ func_decl->setFunctionTemplateSpecialization(func_tmpl_decl, &template_args,
+ nullptr);
+}
- clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
-
- for (NamedDecl *decl : result)
- {
- class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
- if (class_template_decl)
- return class_template_decl;
- }
-
- llvm::SmallVector<NamedDecl *, 8> template_param_decls;
-
- TemplateParameterList *template_param_list = CreateTemplateParameterList (ast,
- template_param_infos,
- template_param_decls);
-
- CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create (*ast,
- (TagDecl::TagKind)kind,
- decl_ctx, // What decl context do we use here? TU? The actual decl context?
- SourceLocation(),
- SourceLocation(),
- &identifier_info);
-
- for (size_t i=0, template_param_decl_count = template_param_decls.size();
- i < template_param_decl_count;
- ++i)
- {
- template_param_decls[i]->setDeclContext (template_cxx_decl);
- }
-
- // With templated classes, we say that a class is templated with
- // specializations, but that the bare class has no functions.
- //template_cxx_decl->startDefinition();
- //template_cxx_decl->completeDefinition();
-
- class_template_decl = ClassTemplateDecl::Create (*ast,
- decl_ctx, // What decl context do we use here? TU? The actual decl context?
- SourceLocation(),
- decl_name,
- template_param_list,
- template_cxx_decl,
- nullptr);
-
+ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl(
+ DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name,
+ int kind, const TemplateParameterInfos &template_param_infos) {
+ ASTContext *ast = getASTContext();
+
+ ClassTemplateDecl *class_template_decl = nullptr;
+ if (decl_ctx == nullptr)
+ decl_ctx = ast->getTranslationUnitDecl();
+
+ IdentifierInfo &identifier_info = ast->Idents.get(class_name);
+ DeclarationName decl_name(&identifier_info);
+
+ clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
+
+ for (NamedDecl *decl : result) {
+ class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
if (class_template_decl)
- {
- if (access_type != eAccessNone)
- class_template_decl->setAccess (ConvertAccessTypeToAccessSpecifier (access_type));
-
- //if (TagDecl *ctx_tag_decl = dyn_cast<TagDecl>(decl_ctx))
- // CompleteTagDeclarationDefinition(GetTypeForDecl(ctx_tag_decl));
-
- decl_ctx->addDecl (class_template_decl);
-
+ return class_template_decl;
+ }
+
+ llvm::SmallVector<NamedDecl *, 8> template_param_decls;
+
+ TemplateParameterList *template_param_list = CreateTemplateParameterList(
+ ast, template_param_infos, template_param_decls);
+
+ CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create(
+ *ast, (TagDecl::TagKind)kind,
+ decl_ctx, // What decl context do we use here? TU? The actual decl
+ // context?
+ SourceLocation(), SourceLocation(), &identifier_info);
+
+ for (size_t i = 0, template_param_decl_count = template_param_decls.size();
+ i < template_param_decl_count; ++i) {
+ template_param_decls[i]->setDeclContext(template_cxx_decl);
+ }
+
+ // With templated classes, we say that a class is templated with
+ // specializations, but that the bare class has no functions.
+ // template_cxx_decl->startDefinition();
+ // template_cxx_decl->completeDefinition();
+
+ class_template_decl = ClassTemplateDecl::Create(
+ *ast,
+ decl_ctx, // What decl context do we use here? TU? The actual decl
+ // context?
+ SourceLocation(), decl_name, template_param_list, template_cxx_decl,
+ nullptr);
+
+ if (class_template_decl) {
+ if (access_type != eAccessNone)
+ class_template_decl->setAccess(
+ ConvertAccessTypeToAccessSpecifier(access_type));
+
+ // if (TagDecl *ctx_tag_decl = dyn_cast<TagDecl>(decl_ctx))
+ // CompleteTagDeclarationDefinition(GetTypeForDecl(ctx_tag_decl));
+
+ decl_ctx->addDecl(class_template_decl);
+
#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(class_template_decl);
+ VerifyDecl(class_template_decl);
#endif
- }
+ }
- return class_template_decl;
+ return class_template_decl;
}
-
ClassTemplateSpecializationDecl *
-ClangASTContext::CreateClassTemplateSpecializationDecl (DeclContext *decl_ctx,
- ClassTemplateDecl *class_template_decl,
- int kind,
- const TemplateParameterInfos &template_param_infos)
-{
- ASTContext *ast = getASTContext();
- ClassTemplateSpecializationDecl *class_template_specialization_decl = ClassTemplateSpecializationDecl::Create (*ast,
- (TagDecl::TagKind)kind,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- class_template_decl,
- template_param_infos.args,
- nullptr);
-
- class_template_specialization_decl->setSpecializationKind(TSK_ExplicitSpecialization);
-
- return class_template_specialization_decl;
-}
+ClangASTContext::CreateClassTemplateSpecializationDecl(
+ DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
+ const TemplateParameterInfos &template_param_infos) {
+ ASTContext *ast = getASTContext();
+ ClassTemplateSpecializationDecl *class_template_specialization_decl =
+ ClassTemplateSpecializationDecl::Create(
+ *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
+ SourceLocation(), class_template_decl, template_param_infos.args,
+ nullptr);
-CompilerType
-ClangASTContext::CreateClassTemplateSpecializationType (ClassTemplateSpecializationDecl *class_template_specialization_decl)
-{
- if (class_template_specialization_decl)
- {
- ASTContext *ast = getASTContext();
- if (ast)
- return CompilerType(ast, ast->getTagDeclType(class_template_specialization_decl));
- }
- return CompilerType();
+ class_template_specialization_decl->setSpecializationKind(
+ TSK_ExplicitSpecialization);
+
+ return class_template_specialization_decl;
}
-static inline bool
-check_op_param (uint32_t op_kind, bool unary, bool binary, uint32_t num_params)
-{
- // Special-case call since it can take any number of operands
- if(op_kind == OO_Call)
- return true;
-
- // The parameter count doesn't include "this"
- if (num_params == 0)
- return unary;
- if (num_params == 1)
- return binary;
- else
+CompilerType ClangASTContext::CreateClassTemplateSpecializationType(
+ ClassTemplateSpecializationDecl *class_template_specialization_decl) {
+ if (class_template_specialization_decl) {
+ ASTContext *ast = getASTContext();
+ if (ast)
+ return CompilerType(
+ ast, ast->getTagDeclType(class_template_specialization_decl));
+ }
+ return CompilerType();
+}
+
+static inline bool check_op_param(bool is_method,
+ clang::OverloadedOperatorKind op_kind,
+ bool unary, bool binary,
+ uint32_t num_params) {
+ // Special-case call since it can take any number of operands
+ if (op_kind == OO_Call)
+ return true;
+
+ // The parameter count doesn't include "this"
+ if (is_method)
+ ++num_params;
+ if (num_params == 1)
+ return unary;
+ if (num_params == 2)
+ return binary;
+ else
return false;
}
-bool
-ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, uint32_t num_params)
-{
- switch (op_kind)
- {
- default:
- break;
- // C++ standard allows any number of arguments to new/delete
- case OO_New:
- case OO_Array_New:
- case OO_Delete:
- case OO_Array_Delete:
- return true;
- }
-
-#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) case OO_##Name: return check_op_param (op_kind, Unary, Binary, num_params);
- switch (op_kind)
- {
+bool ClangASTContext::CheckOverloadedOperatorKindParameterCount(
+ bool is_method, clang::OverloadedOperatorKind op_kind,
+ uint32_t num_params) {
+ switch (op_kind) {
+ default:
+ break;
+ // C++ standard allows any number of arguments to new/delete
+ case OO_New:
+ case OO_Array_New:
+ case OO_Delete:
+ case OO_Array_Delete:
+ return true;
+ }
+
+#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
+ case OO_##Name: \
+ return check_op_param(is_method, op_kind, Unary, Binary, num_params);
+ switch (op_kind) {
#include "clang/Basic/OperatorKinds.def"
- default: break;
- }
- return false;
+ default:
+ break;
+ }
+ return false;
}
clang::AccessSpecifier
-ClangASTContext::UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs)
-{
- // Make the access equal to the stricter of the field and the nested field's access
- if (lhs == AS_none || rhs == AS_none)
- return AS_none;
- if (lhs == AS_private || rhs == AS_private)
- return AS_private;
- if (lhs == AS_protected || rhs == AS_protected)
- return AS_protected;
- return AS_public;
+ClangASTContext::UnifyAccessSpecifiers(clang::AccessSpecifier lhs,
+ clang::AccessSpecifier rhs) {
+ // Make the access equal to the stricter of the field and the nested field's
+ // access
+ if (lhs == AS_none || rhs == AS_none)
+ return AS_none;
+ if (lhs == AS_private || rhs == AS_private)
+ return AS_private;
+ if (lhs == AS_protected || rhs == AS_protected)
+ return AS_protected;
+ return AS_public;
}
-bool
-ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
-{
- return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
+bool ClangASTContext::FieldIsBitfield(FieldDecl *field,
+ uint32_t &bitfield_bit_size) {
+ return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
}
-bool
-ClangASTContext::FieldIsBitfield
-(
- ASTContext *ast,
- FieldDecl* field,
- uint32_t& bitfield_bit_size
-)
-{
- if (ast == nullptr || field == nullptr)
- return false;
+bool ClangASTContext::FieldIsBitfield(ASTContext *ast, FieldDecl *field,
+ uint32_t &bitfield_bit_size) {
+ if (ast == nullptr || field == nullptr)
+ return false;
- if (field->isBitField())
- {
- Expr* bit_width_expr = field->getBitWidth();
- if (bit_width_expr)
- {
- llvm::APSInt bit_width_apsint;
- if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
- {
- bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
- return true;
- }
- }
+ if (field->isBitField()) {
+ Expr *bit_width_expr = field->getBitWidth();
+ if (bit_width_expr) {
+ llvm::APSInt bit_width_apsint;
+ if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast)) {
+ bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-bool
-ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
-{
- if (record_decl == nullptr)
- return false;
+bool ClangASTContext::RecordHasFields(const RecordDecl *record_decl) {
+ if (record_decl == nullptr)
+ return false;
- if (!record_decl->field_empty())
- return true;
+ if (!record_decl->field_empty())
+ return true;
- // No fields, lets check this is a CXX record and check the base classes
- const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
- {
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- if (RecordHasFields(base_class_decl))
- return true;
- }
+ // No fields, lets check this is a CXX record and check the base classes
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+ if (cxx_record_decl) {
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(
+ base_class->getType()->getAs<RecordType>()->getDecl());
+ if (RecordHasFields(base_class_decl))
+ return true;
}
- return false;
+ }
+ return false;
}
#pragma mark Objective C Classes
-CompilerType
-ClangASTContext::CreateObjCClass
-(
- const char *name,
- DeclContext *decl_ctx,
- bool isForwardDecl,
- bool isInternal,
- ClangASTMetadata *metadata
-)
-{
- ASTContext *ast = getASTContext();
- assert (ast != nullptr);
- assert (name && name[0]);
- if (decl_ctx == nullptr)
- decl_ctx = ast->getTranslationUnitDecl();
-
- ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- &ast->Idents.get(name),
- nullptr,
- nullptr,
- SourceLocation(),
- /*isForwardDecl,*/
- isInternal);
-
- if (decl && metadata)
- SetMetadata(ast, decl, *metadata);
-
- return CompilerType (ast, ast->getObjCInterfaceType(decl));
+CompilerType ClangASTContext::CreateObjCClass(const char *name,
+ DeclContext *decl_ctx,
+ bool isForwardDecl,
+ bool isInternal,
+ ClangASTMetadata *metadata) {
+ ASTContext *ast = getASTContext();
+ assert(ast != nullptr);
+ assert(name && name[0]);
+ if (decl_ctx == nullptr)
+ decl_ctx = ast->getTranslationUnitDecl();
+
+ ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create(
+ *ast, decl_ctx, SourceLocation(), &ast->Idents.get(name), nullptr,
+ nullptr, SourceLocation(),
+ /*isForwardDecl,*/
+ isInternal);
+
+ if (decl && metadata)
+ SetMetadata(ast, decl, *metadata);
+
+ return CompilerType(ast, ast->getObjCInterfaceType(decl));
}
-static inline bool
-BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
-{
- return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
+static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) {
+ return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) ==
+ false;
}
uint32_t
-ClangASTContext::GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
-{
- uint32_t num_bases = 0;
- if (cxx_record_decl)
- {
- if (omit_empty_base_classes)
- {
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- // Skip empty base classes
- if (omit_empty_base_classes)
- {
- if (BaseSpecifierIsEmpty (base_class))
- continue;
- }
- ++num_bases;
- }
+ClangASTContext::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl,
+ bool omit_empty_base_classes) {
+ uint32_t num_bases = 0;
+ if (cxx_record_decl) {
+ if (omit_empty_base_classes) {
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ // Skip empty base classes
+ if (omit_empty_base_classes) {
+ if (BaseSpecifierIsEmpty(base_class))
+ continue;
}
- else
- num_bases = cxx_record_decl->getNumBases();
- }
- return num_bases;
+ ++num_bases;
+ }
+ } else
+ num_bases = cxx_record_decl->getNumBases();
+ }
+ return num_bases;
}
-
#pragma mark Namespace Declarations
NamespaceDecl *
-ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *decl_ctx)
-{
- NamespaceDecl *namespace_decl = nullptr;
- ASTContext *ast = getASTContext();
- TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl ();
- if (decl_ctx == nullptr)
- decl_ctx = translation_unit_decl;
-
- if (name)
- {
- IdentifierInfo &identifier_info = ast->Idents.get(name);
- DeclarationName decl_name (&identifier_info);
- clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
- for (NamedDecl *decl : result)
- {
- namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
- if (namespace_decl)
- return namespace_decl;
- }
-
- namespace_decl = NamespaceDecl::Create(*ast,
- decl_ctx,
- false,
- SourceLocation(),
- SourceLocation(),
- &identifier_info,
- nullptr);
-
- decl_ctx->addDecl (namespace_decl);
- }
- else
- {
- if (decl_ctx == translation_unit_decl)
- {
- namespace_decl = translation_unit_decl->getAnonymousNamespace();
- if (namespace_decl)
- return namespace_decl;
-
- namespace_decl = NamespaceDecl::Create(*ast,
- decl_ctx,
- false,
- SourceLocation(),
- SourceLocation(),
- nullptr,
- nullptr);
- translation_unit_decl->setAnonymousNamespace (namespace_decl);
- translation_unit_decl->addDecl (namespace_decl);
- assert (namespace_decl == translation_unit_decl->getAnonymousNamespace());
- }
- else
- {
- NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
- if (parent_namespace_decl)
- {
- namespace_decl = parent_namespace_decl->getAnonymousNamespace();
- if (namespace_decl)
- return namespace_decl;
- namespace_decl = NamespaceDecl::Create(*ast,
- decl_ctx,
- false,
- SourceLocation(),
- SourceLocation(),
- nullptr,
- nullptr);
- parent_namespace_decl->setAnonymousNamespace (namespace_decl);
- parent_namespace_decl->addDecl (namespace_decl);
- assert (namespace_decl == parent_namespace_decl->getAnonymousNamespace());
- }
- else
- {
- // BAD!!!
- }
- }
- }
+ClangASTContext::GetUniqueNamespaceDeclaration(const char *name,
+ DeclContext *decl_ctx) {
+ NamespaceDecl *namespace_decl = nullptr;
+ ASTContext *ast = getASTContext();
+ TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl();
+ if (decl_ctx == nullptr)
+ decl_ctx = translation_unit_decl;
+
+ if (name) {
+ IdentifierInfo &identifier_info = ast->Idents.get(name);
+ DeclarationName decl_name(&identifier_info);
+ clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
+ for (NamedDecl *decl : result) {
+ namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
+ if (namespace_decl)
+ return namespace_decl;
+ }
+
+ namespace_decl =
+ NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
+ SourceLocation(), &identifier_info, nullptr);
+
+ decl_ctx->addDecl(namespace_decl);
+ } else {
+ if (decl_ctx == translation_unit_decl) {
+ namespace_decl = translation_unit_decl->getAnonymousNamespace();
+ if (namespace_decl)
+ return namespace_decl;
+
+ namespace_decl =
+ NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
+ SourceLocation(), nullptr, nullptr);
+ translation_unit_decl->setAnonymousNamespace(namespace_decl);
+ translation_unit_decl->addDecl(namespace_decl);
+ assert(namespace_decl == translation_unit_decl->getAnonymousNamespace());
+ } else {
+ NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
+ if (parent_namespace_decl) {
+ namespace_decl = parent_namespace_decl->getAnonymousNamespace();
+ if (namespace_decl)
+ return namespace_decl;
+ namespace_decl =
+ NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
+ SourceLocation(), nullptr, nullptr);
+ parent_namespace_decl->setAnonymousNamespace(namespace_decl);
+ parent_namespace_decl->addDecl(namespace_decl);
+ assert(namespace_decl ==
+ parent_namespace_decl->getAnonymousNamespace());
+ } else {
+ // BAD!!!
+ }
+ }
+ }
#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(namespace_decl);
+ VerifyDecl(namespace_decl);
#endif
- return namespace_decl;
+ return namespace_decl;
}
-NamespaceDecl *
-ClangASTContext::GetUniqueNamespaceDeclaration (clang::ASTContext *ast,
- const char *name,
- clang::DeclContext *decl_ctx)
-{
- ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast);
- if (ast_ctx == nullptr)
- return nullptr;
+NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration(
+ clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx) {
+ ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast);
+ if (ast_ctx == nullptr)
+ return nullptr;
- return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx);
+ return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx);
}
clang::BlockDecl *
-ClangASTContext::CreateBlockDeclaration (clang::DeclContext *ctx)
-{
- if (ctx != nullptr)
- {
- clang::BlockDecl *decl = clang::BlockDecl::Create(*getASTContext(), ctx, clang::SourceLocation());
- ctx->addDecl(decl);
- return decl;
- }
+ClangASTContext::CreateBlockDeclaration(clang::DeclContext *ctx) {
+ if (ctx != nullptr) {
+ clang::BlockDecl *decl = clang::BlockDecl::Create(*getASTContext(), ctx,
+ clang::SourceLocation());
+ ctx->addDecl(decl);
+ return decl;
+ }
+ return nullptr;
+}
+
+clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left,
+ clang::DeclContext *right,
+ clang::DeclContext *root) {
+ if (root == nullptr)
return nullptr;
-}
-clang::DeclContext *
-FindLCABetweenDecls(clang::DeclContext *left, clang::DeclContext *right, clang::DeclContext *root)
-{
- if (root == nullptr)
- return nullptr;
+ std::set<clang::DeclContext *> path_left;
+ for (clang::DeclContext *d = left; d != nullptr; d = d->getParent())
+ path_left.insert(d);
- std::set<clang::DeclContext *> path_left;
- for (clang::DeclContext *d = left; d != nullptr; d = d->getParent())
- path_left.insert(d);
+ for (clang::DeclContext *d = right; d != nullptr; d = d->getParent())
+ if (path_left.find(d) != path_left.end())
+ return d;
- for (clang::DeclContext *d = right; d != nullptr; d = d->getParent())
- if (path_left.find(d) != path_left.end())
- return d;
-
- return nullptr;
+ return nullptr;
}
-clang::UsingDirectiveDecl *
-ClangASTContext::CreateUsingDirectiveDeclaration (clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl)
-{
- if (decl_ctx != nullptr && ns_decl != nullptr)
- {
- clang::TranslationUnitDecl *translation_unit = (clang::TranslationUnitDecl *)GetTranslationUnitDecl(getASTContext());
- clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(*getASTContext(),
- decl_ctx,
- clang::SourceLocation(),
- clang::SourceLocation(),
- clang::NestedNameSpecifierLoc(),
- clang::SourceLocation(),
- ns_decl,
- FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit));
- decl_ctx->addDecl(using_decl);
- return using_decl;
- }
- return nullptr;
+clang::UsingDirectiveDecl *ClangASTContext::CreateUsingDirectiveDeclaration(
+ clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) {
+ if (decl_ctx != nullptr && ns_decl != nullptr) {
+ clang::TranslationUnitDecl *translation_unit =
+ (clang::TranslationUnitDecl *)GetTranslationUnitDecl(getASTContext());
+ clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(
+ *getASTContext(), decl_ctx, clang::SourceLocation(),
+ clang::SourceLocation(), clang::NestedNameSpecifierLoc(),
+ clang::SourceLocation(), ns_decl,
+ FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit));
+ decl_ctx->addDecl(using_decl);
+ return using_decl;
+ }
+ return nullptr;
}
clang::UsingDecl *
-ClangASTContext::CreateUsingDeclaration (clang::DeclContext *current_decl_ctx, clang::NamedDecl *target)
-{
- if (current_decl_ctx != nullptr && target != nullptr)
- {
- clang::UsingDecl *using_decl = clang::UsingDecl::Create(*getASTContext(),
- current_decl_ctx,
- clang::SourceLocation(),
- clang::NestedNameSpecifierLoc(),
- clang::DeclarationNameInfo(),
- false);
- clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(*getASTContext(),
- current_decl_ctx,
- clang::SourceLocation(),
- using_decl,
- target);
- using_decl->addShadowDecl(shadow_decl);
- current_decl_ctx->addDecl(using_decl);
- return using_decl;
- }
- return nullptr;
-}
-
-clang::VarDecl *
-ClangASTContext::CreateVariableDeclaration (clang::DeclContext *decl_context, const char *name, clang::QualType type)
-{
- if (decl_context != nullptr)
- {
- clang::VarDecl *var_decl = clang::VarDecl::Create(*getASTContext(),
- decl_context,
- clang::SourceLocation(),
- clang::SourceLocation(),
- name && name[0] ? &getASTContext()->Idents.getOwn(name) : nullptr,
- type,
- nullptr,
- clang::SC_None);
- var_decl->setAccess(clang::AS_public);
- decl_context->addDecl(var_decl);
- return var_decl;
- }
- return nullptr;
+ClangASTContext::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
+ clang::NamedDecl *target) {
+ if (current_decl_ctx != nullptr && target != nullptr) {
+ clang::UsingDecl *using_decl = clang::UsingDecl::Create(
+ *getASTContext(), current_decl_ctx, clang::SourceLocation(),
+ clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
+ clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
+ *getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
+ target);
+ using_decl->addShadowDecl(shadow_decl);
+ current_decl_ctx->addDecl(using_decl);
+ return using_decl;
+ }
+ return nullptr;
+}
+
+clang::VarDecl *ClangASTContext::CreateVariableDeclaration(
+ clang::DeclContext *decl_context, const char *name, clang::QualType type) {
+ if (decl_context != nullptr) {
+ clang::VarDecl *var_decl = clang::VarDecl::Create(
+ *getASTContext(), decl_context, clang::SourceLocation(),
+ clang::SourceLocation(),
+ name && name[0] ? &getASTContext()->Idents.getOwn(name) : nullptr, type,
+ nullptr, clang::SC_None);
+ var_decl->setAccess(clang::AS_public);
+ decl_context->addDecl(var_decl);
+ return var_decl;
+ }
+ return nullptr;
}
lldb::opaque_compiler_type_t
-ClangASTContext::GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type)
-{
- switch (basic_type)
- {
- case eBasicTypeVoid:
- return ast->VoidTy.getAsOpaquePtr();
- case eBasicTypeChar:
- return ast->CharTy.getAsOpaquePtr();
- case eBasicTypeSignedChar:
- return ast->SignedCharTy.getAsOpaquePtr();
- case eBasicTypeUnsignedChar:
- return ast->UnsignedCharTy.getAsOpaquePtr();
- case eBasicTypeWChar:
- return ast->getWCharType().getAsOpaquePtr();
- case eBasicTypeSignedWChar:
- return ast->getSignedWCharType().getAsOpaquePtr();
- case eBasicTypeUnsignedWChar:
- return ast->getUnsignedWCharType().getAsOpaquePtr();
- case eBasicTypeChar16:
- return ast->Char16Ty.getAsOpaquePtr();
- case eBasicTypeChar32:
- return ast->Char32Ty.getAsOpaquePtr();
- case eBasicTypeShort:
- return ast->ShortTy.getAsOpaquePtr();
- case eBasicTypeUnsignedShort:
- return ast->UnsignedShortTy.getAsOpaquePtr();
- case eBasicTypeInt:
- return ast->IntTy.getAsOpaquePtr();
- case eBasicTypeUnsignedInt:
- return ast->UnsignedIntTy.getAsOpaquePtr();
- case eBasicTypeLong:
- return ast->LongTy.getAsOpaquePtr();
- case eBasicTypeUnsignedLong:
- return ast->UnsignedLongTy.getAsOpaquePtr();
- case eBasicTypeLongLong:
- return ast->LongLongTy.getAsOpaquePtr();
- case eBasicTypeUnsignedLongLong:
- return ast->UnsignedLongLongTy.getAsOpaquePtr();
- case eBasicTypeInt128:
- return ast->Int128Ty.getAsOpaquePtr();
- case eBasicTypeUnsignedInt128:
- return ast->UnsignedInt128Ty.getAsOpaquePtr();
- case eBasicTypeBool:
- return ast->BoolTy.getAsOpaquePtr();
- case eBasicTypeHalf:
- return ast->HalfTy.getAsOpaquePtr();
- case eBasicTypeFloat:
- return ast->FloatTy.getAsOpaquePtr();
- case eBasicTypeDouble:
- return ast->DoubleTy.getAsOpaquePtr();
- case eBasicTypeLongDouble:
- return ast->LongDoubleTy.getAsOpaquePtr();
- case eBasicTypeFloatComplex:
- return ast->FloatComplexTy.getAsOpaquePtr();
- case eBasicTypeDoubleComplex:
- return ast->DoubleComplexTy.getAsOpaquePtr();
- case eBasicTypeLongDoubleComplex:
- return ast->LongDoubleComplexTy.getAsOpaquePtr();
- case eBasicTypeObjCID:
- return ast->getObjCIdType().getAsOpaquePtr();
- case eBasicTypeObjCClass:
- return ast->getObjCClassType().getAsOpaquePtr();
- case eBasicTypeObjCSel:
- return ast->getObjCSelType().getAsOpaquePtr();
- case eBasicTypeNullPtr:
- return ast->NullPtrTy.getAsOpaquePtr();
- default:
- return nullptr;
- }
+ClangASTContext::GetOpaqueCompilerType(clang::ASTContext *ast,
+ lldb::BasicType basic_type) {
+ switch (basic_type) {
+ case eBasicTypeVoid:
+ return ast->VoidTy.getAsOpaquePtr();
+ case eBasicTypeChar:
+ return ast->CharTy.getAsOpaquePtr();
+ case eBasicTypeSignedChar:
+ return ast->SignedCharTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedChar:
+ return ast->UnsignedCharTy.getAsOpaquePtr();
+ case eBasicTypeWChar:
+ return ast->getWCharType().getAsOpaquePtr();
+ case eBasicTypeSignedWChar:
+ return ast->getSignedWCharType().getAsOpaquePtr();
+ case eBasicTypeUnsignedWChar:
+ return ast->getUnsignedWCharType().getAsOpaquePtr();
+ case eBasicTypeChar16:
+ return ast->Char16Ty.getAsOpaquePtr();
+ case eBasicTypeChar32:
+ return ast->Char32Ty.getAsOpaquePtr();
+ case eBasicTypeShort:
+ return ast->ShortTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedShort:
+ return ast->UnsignedShortTy.getAsOpaquePtr();
+ case eBasicTypeInt:
+ return ast->IntTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedInt:
+ return ast->UnsignedIntTy.getAsOpaquePtr();
+ case eBasicTypeLong:
+ return ast->LongTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedLong:
+ return ast->UnsignedLongTy.getAsOpaquePtr();
+ case eBasicTypeLongLong:
+ return ast->LongLongTy.getAsOpaquePtr();
+ case eBasicTypeUnsignedLongLong:
+ return ast->UnsignedLongLongTy.getAsOpaquePtr();
+ case eBasicTypeInt128:
+ return ast->Int128Ty.getAsOpaquePtr();
+ case eBasicTypeUnsignedInt128:
+ return ast->UnsignedInt128Ty.getAsOpaquePtr();
+ case eBasicTypeBool:
+ return ast->BoolTy.getAsOpaquePtr();
+ case eBasicTypeHalf:
+ return ast->HalfTy.getAsOpaquePtr();
+ case eBasicTypeFloat:
+ return ast->FloatTy.getAsOpaquePtr();
+ case eBasicTypeDouble:
+ return ast->DoubleTy.getAsOpaquePtr();
+ case eBasicTypeLongDouble:
+ return ast->LongDoubleTy.getAsOpaquePtr();
+ case eBasicTypeFloatComplex:
+ return ast->FloatComplexTy.getAsOpaquePtr();
+ case eBasicTypeDoubleComplex:
+ return ast->DoubleComplexTy.getAsOpaquePtr();
+ case eBasicTypeLongDoubleComplex:
+ return ast->LongDoubleComplexTy.getAsOpaquePtr();
+ case eBasicTypeObjCID:
+ return ast->getObjCIdType().getAsOpaquePtr();
+ case eBasicTypeObjCClass:
+ return ast->getObjCClassType().getAsOpaquePtr();
+ case eBasicTypeObjCSel:
+ return ast->getObjCSelType().getAsOpaquePtr();
+ case eBasicTypeNullPtr:
+ return ast->NullPtrTy.getAsOpaquePtr();
+ default:
+ return nullptr;
+ }
}
#pragma mark Function Types
-FunctionDecl *
-ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx,
- const char *name,
- const CompilerType &function_clang_type,
- int storage,
- bool is_inline)
-{
- FunctionDecl *func_decl = nullptr;
- ASTContext *ast = getASTContext();
- if (decl_ctx == nullptr)
- decl_ctx = ast->getTranslationUnitDecl();
-
-
- const bool hasWrittenPrototype = true;
- const bool isConstexprSpecified = false;
+clang::DeclarationName
+ClangASTContext::GetDeclarationName(const char *name,
+ const CompilerType &function_clang_type) {
+ if (!name || !name[0])
+ return clang::DeclarationName();
+
+ clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
+ if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS)
+ return DeclarationName(&getASTContext()->Idents.get(
+ name)); // Not operator, but a regular function.
+
+ // Check the number of operator parameters. Sometimes we have
+ // seen bad DWARF that doesn't correctly describe operators and
+ // if we try to create a method and add it to the class, clang
+ // will assert and crash, so we need to make sure things are
+ // acceptable.
+ clang::QualType method_qual_type(ClangUtil::GetQualType(function_clang_type));
+ const clang::FunctionProtoType *function_type =
+ llvm::dyn_cast<clang::FunctionProtoType>(method_qual_type.getTypePtr());
+ if (function_type == nullptr)
+ return clang::DeclarationName();
+
+ const bool is_method = false;
+ const unsigned int num_params = function_type->getNumParams();
+ if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(
+ is_method, op_kind, num_params))
+ return clang::DeclarationName();
+
+ return getASTContext()->DeclarationNames.getCXXOperatorName(op_kind);
+}
+
+FunctionDecl *ClangASTContext::CreateFunctionDeclaration(
+ DeclContext *decl_ctx, const char *name,
+ const CompilerType &function_clang_type, int storage, bool is_inline) {
+ FunctionDecl *func_decl = nullptr;
+ ASTContext *ast = getASTContext();
+ if (decl_ctx == nullptr)
+ decl_ctx = ast->getTranslationUnitDecl();
+
+ const bool hasWrittenPrototype = true;
+ const bool isConstexprSpecified = false;
+
+ clang::DeclarationName declarationName =
+ GetDeclarationName(name, function_clang_type);
+ func_decl = FunctionDecl::Create(
+ *ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName,
+ ClangUtil::GetQualType(function_clang_type), nullptr,
+ (clang::StorageClass)storage, is_inline, hasWrittenPrototype,
+ isConstexprSpecified);
+ if (func_decl)
+ decl_ctx->addDecl(func_decl);
- if (name && name[0])
- {
- func_decl = FunctionDecl::Create(
- *ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(&ast->Idents.get(name)),
- ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline,
- hasWrittenPrototype, isConstexprSpecified);
- }
- else
- {
- func_decl =
- FunctionDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(),
- ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage,
- is_inline, hasWrittenPrototype, isConstexprSpecified);
- }
- if (func_decl)
- decl_ctx->addDecl (func_decl);
-
#ifdef LLDB_CONFIGURATION_DEBUG
- VerifyDecl(func_decl);
+ VerifyDecl(func_decl);
#endif
-
- return func_decl;
+
+ return func_decl;
+}
+
+CompilerType ClangASTContext::CreateFunctionType(
+ ASTContext *ast, const CompilerType &result_type, const CompilerType *args,
+ unsigned num_args, bool is_variadic, unsigned type_quals) {
+ if (ast == nullptr)
+ return CompilerType(); // invalid AST
+
+ if (!result_type || !ClangUtil::IsClangType(result_type))
+ return CompilerType(); // invalid return type
+
+ std::vector<QualType> qual_type_args;
+ if (num_args > 0 && args == nullptr)
+ return CompilerType(); // invalid argument array passed in
+
+ // Verify that all arguments are valid and the right type
+ for (unsigned i = 0; i < num_args; ++i) {
+ if (args[i]) {
+ // Make sure we have a clang type in args[i] and not a type from another
+ // language whose name might match
+ const bool is_clang_type = ClangUtil::IsClangType(args[i]);
+ lldbassert(is_clang_type);
+ if (is_clang_type)
+ qual_type_args.push_back(ClangUtil::GetQualType(args[i]));
+ else
+ return CompilerType(); // invalid argument type (must be a clang type)
+ } else
+ return CompilerType(); // invalid argument type (empty)
+ }
+
+ // TODO: Detect calling convention in DWARF?
+ FunctionProtoType::ExtProtoInfo proto_info;
+ proto_info.Variadic = is_variadic;
+ proto_info.ExceptionSpec = EST_None;
+ proto_info.TypeQuals = type_quals;
+ proto_info.RefQualifier = RQ_None;
+
+ return CompilerType(ast,
+ ast->getFunctionType(ClangUtil::GetQualType(result_type),
+ qual_type_args, proto_info));
+}
+
+ParmVarDecl *ClangASTContext::CreateParameterDeclaration(
+ const char *name, const CompilerType &param_type, int storage) {
+ ASTContext *ast = getASTContext();
+ assert(ast != nullptr);
+ return ParmVarDecl::Create(*ast, ast->getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(),
+ name && name[0] ? &ast->Idents.get(name) : nullptr,
+ ClangUtil::GetQualType(param_type), nullptr,
+ (clang::StorageClass)storage, nullptr);
+}
+
+void ClangASTContext::SetFunctionParameters(FunctionDecl *function_decl,
+ ParmVarDecl **params,
+ unsigned num_params) {
+ if (function_decl)
+ function_decl->setParams(ArrayRef<ParmVarDecl *>(params, num_params));
}
CompilerType
-ClangASTContext::CreateFunctionType (ASTContext *ast,
- const CompilerType& result_type,
- const CompilerType *args,
- unsigned num_args,
- bool is_variadic,
- unsigned type_quals)
-{
- if (ast == nullptr)
- return CompilerType(); // invalid AST
-
- if (!result_type || !ClangUtil::IsClangType(result_type))
- return CompilerType(); // invalid return type
-
- std::vector<QualType> qual_type_args;
- if (num_args > 0 && args == nullptr)
- return CompilerType(); // invalid argument array passed in
-
- // Verify that all arguments are valid and the right type
- for (unsigned i=0; i<num_args; ++i)
- {
- if (args[i])
- {
- // Make sure we have a clang type in args[i] and not a type from another
- // language whose name might match
- const bool is_clang_type = ClangUtil::IsClangType(args[i]);
- lldbassert(is_clang_type);
- if (is_clang_type)
- qual_type_args.push_back(ClangUtil::GetQualType(args[i]));
- else
- return CompilerType(); // invalid argument type (must be a clang type)
- }
- else
- return CompilerType(); // invalid argument type (empty)
- }
+ClangASTContext::CreateBlockPointerType(const CompilerType &function_type) {
+ QualType block_type = m_ast_ap->getBlockPointerType(
+ clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType()));
- // TODO: Detect calling convention in DWARF?
- FunctionProtoType::ExtProtoInfo proto_info;
- proto_info.Variadic = is_variadic;
- proto_info.ExceptionSpec = EST_None;
- proto_info.TypeQuals = type_quals;
- proto_info.RefQualifier = RQ_None;
-
- return CompilerType(ast, ast->getFunctionType(ClangUtil::GetQualType(result_type), qual_type_args, proto_info));
+ return CompilerType(this, block_type.getAsOpaquePtr());
}
-ParmVarDecl *
-ClangASTContext::CreateParameterDeclaration (const char *name, const CompilerType &param_type, int storage)
-{
- ASTContext *ast = getASTContext();
- assert (ast != nullptr);
- return ParmVarDecl::Create(*ast, ast->getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
- name && name[0] ? &ast->Idents.get(name) : nullptr, ClangUtil::GetQualType(param_type),
- nullptr, (clang::StorageClass)storage, nullptr);
-}
+#pragma mark Array Types
-void
-ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
-{
- if (function_decl)
- function_decl->setParams (ArrayRef<ParmVarDecl*>(params, num_params));
-}
+CompilerType ClangASTContext::CreateArrayType(const CompilerType &element_type,
+ size_t element_count,
+ bool is_vector) {
+ if (element_type.IsValid()) {
+ ASTContext *ast = getASTContext();
+ assert(ast != nullptr);
+
+ if (is_vector) {
+ return CompilerType(
+ ast, ast->getExtVectorType(ClangUtil::GetQualType(element_type),
+ element_count));
+ } else {
+
+ llvm::APInt ap_element_count(64, element_count);
+ if (element_count == 0) {
+ return CompilerType(ast, ast->getIncompleteArrayType(
+ ClangUtil::GetQualType(element_type),
+ clang::ArrayType::Normal, 0));
+ } else {
+ return CompilerType(
+ ast, ast->getConstantArrayType(ClangUtil::GetQualType(element_type),
+ ap_element_count,
+ clang::ArrayType::Normal, 0));
+ }
+ }
+ }
+ return CompilerType();
+}
+
+CompilerType ClangASTContext::CreateStructForIdentifier(
+ const ConstString &type_name,
+ const std::initializer_list<std::pair<const char *, CompilerType>>
+ &type_fields,
+ bool packed) {
+ CompilerType type;
+ if (!type_name.IsEmpty() &&
+ (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name))
+ .IsValid()) {
+ lldbassert("Trying to create a type for an existing name");
+ return type;
+ }
+
+ type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(),
+ clang::TTK_Struct, lldb::eLanguageTypeC);
+ StartTagDeclarationDefinition(type);
+ for (const auto &field : type_fields)
+ AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic,
+ 0);
+ if (packed)
+ SetIsPacked(type);
+ CompleteTagDeclarationDefinition(type);
+ return type;
+}
+
+CompilerType ClangASTContext::GetOrCreateStructForIdentifier(
+ const ConstString &type_name,
+ const std::initializer_list<std::pair<const char *, CompilerType>>
+ &type_fields,
+ bool packed) {
+ CompilerType type;
+ if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
+ return type;
-CompilerType
-ClangASTContext::CreateBlockPointerType (const CompilerType &function_type)
-{
- QualType block_type = m_ast_ap->getBlockPointerType(clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType()));
-
- return CompilerType (this, block_type.getAsOpaquePtr());
+ return CreateStructForIdentifier(type_name, type_fields, packed);
}
-#pragma mark Array Types
-
-CompilerType
-ClangASTContext::CreateArrayType (const CompilerType &element_type,
- size_t element_count,
- bool is_vector)
-{
- if (element_type.IsValid())
- {
- ASTContext *ast = getASTContext();
- assert (ast != nullptr);
-
- if (is_vector)
- {
- return CompilerType(ast, ast->getExtVectorType(ClangUtil::GetQualType(element_type), element_count));
- }
- else
- {
-
- llvm::APInt ap_element_count (64, element_count);
- if (element_count == 0)
- {
- return CompilerType(ast, ast->getIncompleteArrayType(ClangUtil::GetQualType(element_type),
- clang::ArrayType::Normal, 0));
- }
- else
- {
- return CompilerType(ast, ast->getConstantArrayType(ClangUtil::GetQualType(element_type),
- ap_element_count, clang::ArrayType::Normal, 0));
- }
- }
- }
- return CompilerType();
-}
+#pragma mark Enumeration Types
CompilerType
-ClangASTContext::CreateStructForIdentifier (const ConstString &type_name,
- const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
- bool packed)
-{
- CompilerType type;
- if (!type_name.IsEmpty() && (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
- {
- lldbassert("Trying to create a type for an existing name");
- return type;
- }
-
- type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC);
- StartTagDeclarationDefinition(type);
- for (const auto& field : type_fields)
- AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic, 0);
- if (packed)
- SetIsPacked(type);
- CompleteTagDeclarationDefinition(type);
- return type;
-}
+ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx,
+ const Declaration &decl,
+ const CompilerType &integer_clang_type) {
+ // TODO: Do something intelligent with the Declaration object passed in
+ // like maybe filling in the SourceLocation with it...
+ ASTContext *ast = getASTContext();
-CompilerType
-ClangASTContext::GetOrCreateStructForIdentifier (const ConstString &type_name,
- const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields,
- bool packed)
-{
- CompilerType type;
- if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid())
- return type;
+ // TODO: ask about these...
+ // const bool IsScoped = false;
+ // const bool IsFixed = false;
- return CreateStructForIdentifier (type_name,
- type_fields,
- packed);
-}
+ EnumDecl *enum_decl = EnumDecl::Create(
+ *ast, decl_ctx, SourceLocation(), SourceLocation(),
+ name && name[0] ? &ast->Idents.get(name) : nullptr, nullptr,
+ false, // IsScoped
+ false, // IsScopedUsingClassTag
+ false); // IsFixed
-#pragma mark Enumeration Types
+ if (enum_decl) {
+ // TODO: check if we should be setting the promotion type too?
+ enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
-CompilerType
-ClangASTContext::CreateEnumerationType
-(
- const char *name,
- DeclContext *decl_ctx,
- const Declaration &decl,
- const CompilerType &integer_clang_type
- )
-{
- // TODO: Do something intelligent with the Declaration object passed in
- // like maybe filling in the SourceLocation with it...
- ASTContext *ast = getASTContext();
-
- // TODO: ask about these...
- // const bool IsScoped = false;
- // const bool IsFixed = false;
-
- EnumDecl *enum_decl = EnumDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- name && name[0] ? &ast->Idents.get(name) : nullptr,
- nullptr,
- false, // IsScoped
- false, // IsScopedUsingClassTag
- false); // IsFixed
-
-
- if (enum_decl)
- {
- // TODO: check if we should be setting the promotion type too?
- enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type));
+ enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
- enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
-
- return CompilerType (ast, ast->getTagDeclType(enum_decl));
- }
- return CompilerType();
+ return CompilerType(ast, ast->getTagDeclType(enum_decl));
+ }
+ return CompilerType();
}
// Disable this for now since I can't seem to get a nicely formatted float
@@ -2192,8 +2185,10 @@ ClangASTContext::CreateEnumerationType
// would like to get perfect string values for any kind of float semantics
// so we can support remote targets. The code below also requires a patch to
// llvm::APInt.
-//bool
-//ClangASTContext::ConvertFloatValueToString (ASTContext *ast, lldb::opaque_compiler_type_t clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
+// bool
+// ClangASTContext::ConvertFloatValueToString (ASTContext *ast,
+// lldb::opaque_compiler_type_t clang_type, const uint8_t* bytes, size_t
+// byte_size, int apint_byte_order, std::string &float_str)
//{
// uint32_t count = 0;
// bool is_complex = false;
@@ -2206,14 +2201,16 @@ ClangASTContext::CreateEnumerationType
// uint32_t i;
// for (i=0; i<count; i++)
// {
-// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
+// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float,
+// (APInt::ByteOrder)apint_byte_order);
// bool is_ieee = false;
// APFloat ap_float(ap_int, is_ieee);
// char s[1024];
// unsigned int hex_digits = 0;
// bool upper_case = false;
//
-// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
+// if (ap_float.convertToHexString(s, hex_digits, upper_case,
+// APFloat::rmNearestTiesToEven) > 0)
// {
// if (i > 0)
// float_str.append(", ");
@@ -2227,2051 +2224,2118 @@ ClangASTContext::CreateEnumerationType
// return false;
//}
-CompilerType
-ClangASTContext::GetIntTypeFromBitSize (clang::ASTContext *ast,
- size_t bit_size, bool is_signed)
-{
- if (ast)
- {
- if (is_signed)
- {
- if (bit_size == ast->getTypeSize(ast->SignedCharTy))
- return CompilerType(ast, ast->SignedCharTy);
-
- if (bit_size == ast->getTypeSize(ast->ShortTy))
- return CompilerType(ast, ast->ShortTy);
-
- if (bit_size == ast->getTypeSize(ast->IntTy))
- return CompilerType(ast, ast->IntTy);
-
- if (bit_size == ast->getTypeSize(ast->LongTy))
- return CompilerType(ast, ast->LongTy);
-
- if (bit_size == ast->getTypeSize(ast->LongLongTy))
- return CompilerType(ast, ast->LongLongTy);
-
- if (bit_size == ast->getTypeSize(ast->Int128Ty))
- return CompilerType(ast, ast->Int128Ty);
+CompilerType ClangASTContext::GetIntTypeFromBitSize(clang::ASTContext *ast,
+ size_t bit_size,
+ bool is_signed) {
+ if (ast) {
+ if (is_signed) {
+ if (bit_size == ast->getTypeSize(ast->SignedCharTy))
+ return CompilerType(ast, ast->SignedCharTy);
+
+ if (bit_size == ast->getTypeSize(ast->ShortTy))
+ return CompilerType(ast, ast->ShortTy);
+
+ if (bit_size == ast->getTypeSize(ast->IntTy))
+ return CompilerType(ast, ast->IntTy);
+
+ if (bit_size == ast->getTypeSize(ast->LongTy))
+ return CompilerType(ast, ast->LongTy);
+
+ if (bit_size == ast->getTypeSize(ast->LongLongTy))
+ return CompilerType(ast, ast->LongLongTy);
+
+ if (bit_size == ast->getTypeSize(ast->Int128Ty))
+ return CompilerType(ast, ast->Int128Ty);
+ } else {
+ if (bit_size == ast->getTypeSize(ast->UnsignedCharTy))
+ return CompilerType(ast, ast->UnsignedCharTy);
+
+ if (bit_size == ast->getTypeSize(ast->UnsignedShortTy))
+ return CompilerType(ast, ast->UnsignedShortTy);
+
+ if (bit_size == ast->getTypeSize(ast->UnsignedIntTy))
+ return CompilerType(ast, ast->UnsignedIntTy);
+
+ if (bit_size == ast->getTypeSize(ast->UnsignedLongTy))
+ return CompilerType(ast, ast->UnsignedLongTy);
+
+ if (bit_size == ast->getTypeSize(ast->UnsignedLongLongTy))
+ return CompilerType(ast, ast->UnsignedLongLongTy);
+
+ if (bit_size == ast->getTypeSize(ast->UnsignedInt128Ty))
+ return CompilerType(ast, ast->UnsignedInt128Ty);
+ }
+ }
+ return CompilerType();
+}
+
+CompilerType ClangASTContext::GetPointerSizedIntType(clang::ASTContext *ast,
+ bool is_signed) {
+ if (ast)
+ return GetIntTypeFromBitSize(ast, ast->getTypeSize(ast->VoidPtrTy),
+ is_signed);
+ return CompilerType();
+}
+
+void ClangASTContext::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) {
+ if (decl_ctx) {
+ DumpDeclContextHiearchy(decl_ctx->getParent());
+
+ clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl_ctx);
+ if (named_decl) {
+ printf("%20s: %s\n", decl_ctx->getDeclKindName(),
+ named_decl->getDeclName().getAsString().c_str());
+ } else {
+ printf("%20s\n", decl_ctx->getDeclKindName());
+ }
+ }
+}
+
+void ClangASTContext::DumpDeclHiearchy(clang::Decl *decl) {
+ if (decl == nullptr)
+ return;
+ DumpDeclContextHiearchy(decl->getDeclContext());
+
+ clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl);
+ if (record_decl) {
+ printf("%20s: %s%s\n", decl->getDeclKindName(),
+ record_decl->getDeclName().getAsString().c_str(),
+ record_decl->isInjectedClassName() ? " (injected class name)" : "");
+
+ } else {
+ clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl);
+ if (named_decl) {
+ printf("%20s: %s\n", decl->getDeclKindName(),
+ named_decl->getDeclName().getAsString().c_str());
+ } else {
+ printf("%20s\n", decl->getDeclKindName());
+ }
+ }
+}
+
+bool ClangASTContext::DeclsAreEquivalent(clang::Decl *lhs_decl,
+ clang::Decl *rhs_decl) {
+ if (lhs_decl && rhs_decl) {
+ //----------------------------------------------------------------------
+ // Make sure the decl kinds match first
+ //----------------------------------------------------------------------
+ const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind();
+ const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind();
+
+ if (lhs_decl_kind == rhs_decl_kind) {
+ //------------------------------------------------------------------
+ // Now check that the decl contexts kinds are all equivalent
+ // before we have to check any names of the decl contexts...
+ //------------------------------------------------------------------
+ clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
+ clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
+ if (lhs_decl_ctx && rhs_decl_ctx) {
+ while (1) {
+ if (lhs_decl_ctx && rhs_decl_ctx) {
+ const clang::Decl::Kind lhs_decl_ctx_kind =
+ lhs_decl_ctx->getDeclKind();
+ const clang::Decl::Kind rhs_decl_ctx_kind =
+ rhs_decl_ctx->getDeclKind();
+ if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) {
+ lhs_decl_ctx = lhs_decl_ctx->getParent();
+ rhs_decl_ctx = rhs_decl_ctx->getParent();
+
+ if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr)
+ break;
+ } else
+ return false;
+ } else
+ return false;
}
- else
- {
- if (bit_size == ast->getTypeSize(ast->UnsignedCharTy))
- return CompilerType(ast, ast->UnsignedCharTy);
-
- if (bit_size == ast->getTypeSize(ast->UnsignedShortTy))
- return CompilerType(ast, ast->UnsignedShortTy);
-
- if (bit_size == ast->getTypeSize(ast->UnsignedIntTy))
- return CompilerType(ast, ast->UnsignedIntTy);
-
- if (bit_size == ast->getTypeSize(ast->UnsignedLongTy))
- return CompilerType(ast, ast->UnsignedLongTy);
-
- if (bit_size == ast->getTypeSize(ast->UnsignedLongLongTy))
- return CompilerType(ast, ast->UnsignedLongLongTy);
-
- if (bit_size == ast->getTypeSize(ast->UnsignedInt128Ty))
- return CompilerType(ast, ast->UnsignedInt128Ty);
+
+ //--------------------------------------------------------------
+ // Now make sure the name of the decls match
+ //--------------------------------------------------------------
+ clang::NamedDecl *lhs_named_decl =
+ llvm::dyn_cast<clang::NamedDecl>(lhs_decl);
+ clang::NamedDecl *rhs_named_decl =
+ llvm::dyn_cast<clang::NamedDecl>(rhs_decl);
+ if (lhs_named_decl && rhs_named_decl) {
+ clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
+ clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
+ if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
+ if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
+ return false;
+ } else
+ return false;
+ } else
+ return false;
+
+ //--------------------------------------------------------------
+ // We know that the decl context kinds all match, so now we need
+ // to make sure the names match as well
+ //--------------------------------------------------------------
+ lhs_decl_ctx = lhs_decl->getDeclContext();
+ rhs_decl_ctx = rhs_decl->getDeclContext();
+ while (1) {
+ switch (lhs_decl_ctx->getDeclKind()) {
+ case clang::Decl::TranslationUnit:
+ // We don't care about the translation unit names
+ return true;
+ default: {
+ clang::NamedDecl *lhs_named_decl =
+ llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx);
+ clang::NamedDecl *rhs_named_decl =
+ llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx);
+ if (lhs_named_decl && rhs_named_decl) {
+ clang::DeclarationName lhs_decl_name =
+ lhs_named_decl->getDeclName();
+ clang::DeclarationName rhs_decl_name =
+ rhs_named_decl->getDeclName();
+ if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
+ if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
+ return false;
+ } else
+ return false;
+ } else
+ return false;
+ } break;
+ }
+ lhs_decl_ctx = lhs_decl_ctx->getParent();
+ rhs_decl_ctx = rhs_decl_ctx->getParent();
}
+ }
}
- return CompilerType();
+ }
+ return false;
}
+bool ClangASTContext::GetCompleteDecl(clang::ASTContext *ast,
+ clang::Decl *decl) {
+ if (!decl)
+ return false;
-CompilerType
-ClangASTContext::GetPointerSizedIntType (clang::ASTContext *ast, bool is_signed)
-{
- if (ast)
- return GetIntTypeFromBitSize(ast, ast->getTypeSize(ast->VoidPtrTy), is_signed);
- return CompilerType();
-}
+ ExternalASTSource *ast_source = ast->getExternalSource();
-void
-ClangASTContext::DumpDeclContextHiearchy (clang::DeclContext *decl_ctx)
-{
- if (decl_ctx)
- {
- DumpDeclContextHiearchy (decl_ctx->getParent());
+ if (!ast_source)
+ return false;
- clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl_ctx);
- if (named_decl)
- {
- printf ("%20s: %s\n", decl_ctx->getDeclKindName(), named_decl->getDeclName().getAsString().c_str());
- }
- else
- {
- printf ("%20s\n", decl_ctx->getDeclKindName());
- }
- }
-}
+ if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) {
+ if (tag_decl->isCompleteDefinition())
+ return true;
-void
-ClangASTContext::DumpDeclHiearchy (clang::Decl *decl)
-{
- if (decl == nullptr)
- return;
- DumpDeclContextHiearchy(decl->getDeclContext());
+ if (!tag_decl->hasExternalLexicalStorage())
+ return false;
- clang::RecordDecl *record_decl = llvm::dyn_cast<clang::RecordDecl>(decl);
- if (record_decl)
- {
- printf ("%20s: %s%s\n", decl->getDeclKindName(), record_decl->getDeclName().getAsString().c_str(), record_decl->isInjectedClassName() ? " (injected class name)" : "");
+ ast_source->CompleteType(tag_decl);
- }
- else
- {
- clang::NamedDecl *named_decl = llvm::dyn_cast<clang::NamedDecl>(decl);
- if (named_decl)
- {
- printf ("%20s: %s\n", decl->getDeclKindName(), named_decl->getDeclName().getAsString().c_str());
- }
- else
- {
- printf ("%20s\n", decl->getDeclKindName());
- }
- }
-}
+ return !tag_decl->getTypeForDecl()->isIncompleteType();
+ } else if (clang::ObjCInterfaceDecl *objc_interface_decl =
+ llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) {
+ if (objc_interface_decl->getDefinition())
+ return true;
-bool
-ClangASTContext::DeclsAreEquivalent (clang::Decl *lhs_decl, clang::Decl *rhs_decl)
-{
- if (lhs_decl && rhs_decl)
- {
- //----------------------------------------------------------------------
- // Make sure the decl kinds match first
- //----------------------------------------------------------------------
- const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind();
- const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind();
-
- if (lhs_decl_kind == rhs_decl_kind)
- {
- //------------------------------------------------------------------
- // Now check that the decl contexts kinds are all equivalent
- // before we have to check any names of the decl contexts...
- //------------------------------------------------------------------
- clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
- clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
- if (lhs_decl_ctx && rhs_decl_ctx)
- {
- while (1)
- {
- if (lhs_decl_ctx && rhs_decl_ctx)
- {
- const clang::Decl::Kind lhs_decl_ctx_kind = lhs_decl_ctx->getDeclKind();
- const clang::Decl::Kind rhs_decl_ctx_kind = rhs_decl_ctx->getDeclKind();
- if (lhs_decl_ctx_kind == rhs_decl_ctx_kind)
- {
- lhs_decl_ctx = lhs_decl_ctx->getParent();
- rhs_decl_ctx = rhs_decl_ctx->getParent();
-
- if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr)
- break;
- }
- else
- return false;
- }
- else
- return false;
- }
+ if (!objc_interface_decl->hasExternalLexicalStorage())
+ return false;
- //--------------------------------------------------------------
- // Now make sure the name of the decls match
- //--------------------------------------------------------------
- clang::NamedDecl *lhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(lhs_decl);
- clang::NamedDecl *rhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(rhs_decl);
- if (lhs_named_decl && rhs_named_decl)
- {
- clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
- clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
- if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind())
- {
- if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
- return false;
- }
- else
- return false;
- }
- else
- return false;
-
- //--------------------------------------------------------------
- // We know that the decl context kinds all match, so now we need
- // to make sure the names match as well
- //--------------------------------------------------------------
- lhs_decl_ctx = lhs_decl->getDeclContext();
- rhs_decl_ctx = rhs_decl->getDeclContext();
- while (1)
- {
- switch (lhs_decl_ctx->getDeclKind())
- {
- case clang::Decl::TranslationUnit:
- // We don't care about the translation unit names
- return true;
- default:
- {
- clang::NamedDecl *lhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx);
- clang::NamedDecl *rhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx);
- if (lhs_named_decl && rhs_named_decl)
- {
- clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
- clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
- if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind())
- {
- if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
- return false;
- }
- else
- return false;
- }
- else
- return false;
- }
- break;
+ ast_source->CompleteType(objc_interface_decl);
- }
- lhs_decl_ctx = lhs_decl_ctx->getParent();
- rhs_decl_ctx = rhs_decl_ctx->getParent();
- }
- }
- }
- }
+ return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
+ } else {
return false;
-}
-bool
-ClangASTContext::GetCompleteDecl (clang::ASTContext *ast,
- clang::Decl *decl)
-{
- if (!decl)
- return false;
-
- ExternalASTSource *ast_source = ast->getExternalSource();
-
- if (!ast_source)
- return false;
-
- if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
- {
- if (tag_decl->isCompleteDefinition())
- return true;
-
- if (!tag_decl->hasExternalLexicalStorage())
- return false;
-
- ast_source->CompleteType(tag_decl);
-
- return !tag_decl->getTypeForDecl()->isIncompleteType();
- }
- else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
- {
- if (objc_interface_decl->getDefinition())
- return true;
-
- if (!objc_interface_decl->hasExternalLexicalStorage())
- return false;
-
- ast_source->CompleteType(objc_interface_decl);
-
- return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
- }
- else
- {
- return false;
- }
+ }
}
-void
-ClangASTContext::SetMetadataAsUserID (const void *object,
- user_id_t user_id)
-{
- ClangASTMetadata meta_data;
- meta_data.SetUserID (user_id);
- SetMetadata (object, meta_data);
+void ClangASTContext::SetMetadataAsUserID(const void *object,
+ user_id_t user_id) {
+ ClangASTMetadata meta_data;
+ meta_data.SetUserID(user_id);
+ SetMetadata(object, meta_data);
}
-void
-ClangASTContext::SetMetadata (clang::ASTContext *ast,
- const void *object,
- ClangASTMetadata &metadata)
-{
- ClangExternalASTSourceCommon *external_source =
- ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
-
- if (external_source)
- external_source->SetMetadata(object, metadata);
-}
+void ClangASTContext::SetMetadata(clang::ASTContext *ast, const void *object,
+ ClangASTMetadata &metadata) {
+ ClangExternalASTSourceCommon *external_source =
+ ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
-ClangASTMetadata *
-ClangASTContext::GetMetadata (clang::ASTContext *ast,
- const void *object)
-{
- ClangExternalASTSourceCommon *external_source =
- ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
-
- if (external_source && external_source->HasMetadata(object))
- return external_source->GetMetadata(object);
- else
- return nullptr;
+ if (external_source)
+ external_source->SetMetadata(object, metadata);
}
-clang::DeclContext *
-ClangASTContext::GetAsDeclContext (clang::CXXMethodDecl *cxx_method_decl)
-{
- return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
+ClangASTMetadata *ClangASTContext::GetMetadata(clang::ASTContext *ast,
+ const void *object) {
+ ClangExternalASTSourceCommon *external_source =
+ ClangExternalASTSourceCommon::Lookup(ast->getExternalSource());
+
+ if (external_source && external_source->HasMetadata(object))
+ return external_source->GetMetadata(object);
+ else
+ return nullptr;
}
clang::DeclContext *
-ClangASTContext::GetAsDeclContext (clang::ObjCMethodDecl *objc_method_decl)
-{
- return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
+ClangASTContext::GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl) {
+ return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
}
-bool
-ClangASTContext::SetTagTypeKind (clang::QualType tag_qual_type, int kind) const
-{
- const clang::Type *clang_type = tag_qual_type.getTypePtr();
- if (clang_type)
- {
- const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
- if (tag_type)
- {
- clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
- if (tag_decl)
- {
- tag_decl->setTagKind ((clang::TagDecl::TagKind)kind);
- return true;
- }
- }
+clang::DeclContext *
+ClangASTContext::GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl) {
+ return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
+}
+
+bool ClangASTContext::SetTagTypeKind(clang::QualType tag_qual_type,
+ int kind) const {
+ const clang::Type *clang_type = tag_qual_type.getTypePtr();
+ if (clang_type) {
+ const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
+ if (tag_type) {
+ clang::TagDecl *tag_decl =
+ llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
+ if (tag_decl) {
+ tag_decl->setTagKind((clang::TagDecl::TagKind)kind);
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
-
-bool
-ClangASTContext::SetDefaultAccessForRecordFields (clang::RecordDecl* record_decl,
- int default_accessibility,
- int *assigned_accessibilities,
- size_t num_assigned_accessibilities)
-{
- if (record_decl)
- {
- uint32_t field_idx;
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
- field != field_end;
- ++field, ++field_idx)
- {
- // If no accessibility was assigned, assign the correct one
- if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
- field->setAccess ((clang::AccessSpecifier)default_accessibility);
- }
- return true;
+bool ClangASTContext::SetDefaultAccessForRecordFields(
+ clang::RecordDecl *record_decl, int default_accessibility,
+ int *assigned_accessibilities, size_t num_assigned_accessibilities) {
+ if (record_decl) {
+ uint32_t field_idx;
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end(), field_idx = 0;
+ field != field_end; ++field, ++field_idx) {
+ // If no accessibility was assigned, assign the correct one
+ if (field_idx < num_assigned_accessibilities &&
+ assigned_accessibilities[field_idx] == clang::AS_none)
+ field->setAccess((clang::AccessSpecifier)default_accessibility);
}
- return false;
+ return true;
+ }
+ return false;
}
clang::DeclContext *
-ClangASTContext::GetDeclContextForType (const CompilerType& type)
-{
- return GetDeclContextForType(ClangUtil::GetQualType(type));
+ClangASTContext::GetDeclContextForType(const CompilerType &type) {
+ return GetDeclContextForType(ClangUtil::GetQualType(type));
}
clang::DeclContext *
-ClangASTContext::GetDeclContextForType (clang::QualType type)
-{
- if (type.isNull())
- return nullptr;
-
- clang::QualType qual_type = type.getCanonicalType();
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::ObjCInterface: return llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr())->getInterface();
- case clang::Type::ObjCObjectPointer: return GetDeclContextForType (llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
- case clang::Type::Record: return llvm::cast<clang::RecordType>(qual_type)->getDecl();
- case clang::Type::Enum: return llvm::cast<clang::EnumType>(qual_type)->getDecl();
- case clang::Type::Typedef: return GetDeclContextForType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType());
- case clang::Type::Auto: return GetDeclContextForType (llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
- case clang::Type::Elaborated: return GetDeclContextForType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
- case clang::Type::Paren: return GetDeclContextForType (llvm::cast<clang::ParenType>(qual_type)->desugar());
- default:
- break;
- }
- // No DeclContext in this type...
+ClangASTContext::GetDeclContextForType(clang::QualType type) {
+ if (type.isNull())
return nullptr;
-}
-static bool
-GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true)
-{
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::ConstantArray:
- case clang::Type::IncompleteArray:
- case clang::Type::VariableArray:
- {
- const clang::ArrayType *array_type = llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
-
- if (array_type)
- return GetCompleteQualType (ast, array_type->getElementType(), allow_completion);
- }
- break;
- case clang::Type::Record:
- {
- clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- if (cxx_record_decl->hasExternalLexicalStorage())
- {
- const bool is_complete = cxx_record_decl->isCompleteDefinition();
- const bool fields_loaded = cxx_record_decl->hasLoadedFieldsFromExternalStorage();
- if (is_complete && fields_loaded)
- return true;
-
- if (!allow_completion)
- return false;
-
- // Call the field_begin() accessor to for it to use the external source
- // to load the fields...
- clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
- if (external_ast_source)
- {
- external_ast_source->CompleteType(cxx_record_decl);
- if (cxx_record_decl->isCompleteDefinition())
- {
- cxx_record_decl->field_begin();
- cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true);
- }
- }
- }
- }
- const clang::TagType *tag_type = llvm::cast<clang::TagType>(qual_type.getTypePtr());
- return !tag_type->isIncompleteType();
+ clang::QualType qual_type = type.getCanonicalType();
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::ObjCInterface:
+ return llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr())
+ ->getInterface();
+ case clang::Type::ObjCObjectPointer:
+ return GetDeclContextForType(
+ llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
+ ->getPointeeType());
+ case clang::Type::Record:
+ return llvm::cast<clang::RecordType>(qual_type)->getDecl();
+ case clang::Type::Enum:
+ return llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ case clang::Type::Typedef:
+ return GetDeclContextForType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType());
+ case clang::Type::Auto:
+ return GetDeclContextForType(
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
+ case clang::Type::Elaborated:
+ return GetDeclContextForType(
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
+ case clang::Type::Paren:
+ return GetDeclContextForType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar());
+ default:
+ break;
+ }
+ // No DeclContext in this type...
+ return nullptr;
+}
+
+static bool GetCompleteQualType(clang::ASTContext *ast,
+ clang::QualType qual_type,
+ bool allow_completion = true) {
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::ConstantArray:
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray: {
+ const clang::ArrayType *array_type =
+ llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
+
+ if (array_type)
+ return GetCompleteQualType(ast, array_type->getElementType(),
+ allow_completion);
+ } break;
+ case clang::Type::Record: {
+ clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ if (cxx_record_decl->hasExternalLexicalStorage()) {
+ const bool is_complete = cxx_record_decl->isCompleteDefinition();
+ const bool fields_loaded =
+ cxx_record_decl->hasLoadedFieldsFromExternalStorage();
+ if (is_complete && fields_loaded)
+ return true;
+
+ if (!allow_completion)
+ return false;
+
+ // Call the field_begin() accessor to for it to use the external source
+ // to load the fields...
+ clang::ExternalASTSource *external_ast_source =
+ ast->getExternalSource();
+ if (external_ast_source) {
+ external_ast_source->CompleteType(cxx_record_decl);
+ if (cxx_record_decl->isCompleteDefinition()) {
+ cxx_record_decl->field_begin();
+ cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
+ }
+ }
+ }
+ }
+ const clang::TagType *tag_type =
+ llvm::cast<clang::TagType>(qual_type.getTypePtr());
+ return !tag_type->isIncompleteType();
+ } break;
+
+ case clang::Type::Enum: {
+ const clang::TagType *tag_type =
+ llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
+ if (tag_type) {
+ clang::TagDecl *tag_decl = tag_type->getDecl();
+ if (tag_decl) {
+ if (tag_decl->getDefinition())
+ return true;
+
+ if (!allow_completion)
+ return false;
+
+ if (tag_decl->hasExternalLexicalStorage()) {
+ if (ast) {
+ clang::ExternalASTSource *external_ast_source =
+ ast->getExternalSource();
+ if (external_ast_source) {
+ external_ast_source->CompleteType(tag_decl);
+ return !tag_type->isIncompleteType();
}
- break;
+ }
+ }
+ return false;
+ }
+ }
- case clang::Type::Enum:
- {
- const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
- if (tag_type)
- {
- clang::TagDecl *tag_decl = tag_type->getDecl();
- if (tag_decl)
- {
- if (tag_decl->getDefinition())
- return true;
-
- if (!allow_completion)
- return false;
-
- if (tag_decl->hasExternalLexicalStorage())
- {
- if (ast)
- {
- clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
- if (external_ast_source)
- {
- external_ast_source->CompleteType(tag_decl);
- return !tag_type->isIncompleteType();
- }
- }
- }
- return false;
- }
- }
-
- }
- break;
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- // We currently can't complete objective C types through the newly added ASTContext
- // because it only supports TagDecl objects right now...
- if (class_interface_decl)
- {
- if (class_interface_decl->getDefinition())
- return true;
-
- if (!allow_completion)
- return false;
-
- if (class_interface_decl->hasExternalLexicalStorage())
- {
- if (ast)
- {
- clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
- if (external_ast_source)
- {
- external_ast_source->CompleteType (class_interface_decl);
- return !objc_class_type->isIncompleteType();
- }
- }
- }
- return false;
- }
- }
+ } break;
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface: {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added
+ // ASTContext
+ // because it only supports TagDecl objects right now...
+ if (class_interface_decl) {
+ if (class_interface_decl->getDefinition())
+ return true;
+
+ if (!allow_completion)
+ return false;
+
+ if (class_interface_decl->hasExternalLexicalStorage()) {
+ if (ast) {
+ clang::ExternalASTSource *external_ast_source =
+ ast->getExternalSource();
+ if (external_ast_source) {
+ external_ast_source->CompleteType(class_interface_decl);
+ return !objc_class_type->isIncompleteType();
}
- break;
-
- case clang::Type::Typedef:
- return GetCompleteQualType (ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion);
-
- case clang::Type::Auto:
- return GetCompleteQualType (ast, llvm::cast<clang::AutoType>(qual_type)->getDeducedType(), allow_completion);
-
- case clang::Type::Elaborated:
- return GetCompleteQualType (ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(), allow_completion);
-
- case clang::Type::Paren:
- return GetCompleteQualType (ast, llvm::cast<clang::ParenType>(qual_type)->desugar(), allow_completion);
-
- case clang::Type::Attributed:
- return GetCompleteQualType (ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(), allow_completion);
-
- default:
- break;
+ }
+ }
+ return false;
+ }
}
-
- return true;
+ } break;
+
+ case clang::Type::Typedef:
+ return GetCompleteQualType(ast, llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType(),
+ allow_completion);
+
+ case clang::Type::Auto:
+ return GetCompleteQualType(
+ ast, llvm::cast<clang::AutoType>(qual_type)->getDeducedType(),
+ allow_completion);
+
+ case clang::Type::Elaborated:
+ return GetCompleteQualType(
+ ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(),
+ allow_completion);
+
+ case clang::Type::Paren:
+ return GetCompleteQualType(
+ ast, llvm::cast<clang::ParenType>(qual_type)->desugar(),
+ allow_completion);
+
+ case clang::Type::Attributed:
+ return GetCompleteQualType(
+ ast, llvm::cast<clang::AttributedType>(qual_type)->getModifiedType(),
+ allow_completion);
+
+ default:
+ break;
+ }
+
+ return true;
}
static clang::ObjCIvarDecl::AccessControl
-ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
-{
- switch (access)
- {
- case eAccessNone: return clang::ObjCIvarDecl::None;
- case eAccessPublic: return clang::ObjCIvarDecl::Public;
- case eAccessPrivate: return clang::ObjCIvarDecl::Private;
- case eAccessProtected: return clang::ObjCIvarDecl::Protected;
- case eAccessPackage: return clang::ObjCIvarDecl::Package;
- }
+ConvertAccessTypeToObjCIvarAccessControl(AccessType access) {
+ switch (access) {
+ case eAccessNone:
return clang::ObjCIvarDecl::None;
+ case eAccessPublic:
+ return clang::ObjCIvarDecl::Public;
+ case eAccessPrivate:
+ return clang::ObjCIvarDecl::Private;
+ case eAccessProtected:
+ return clang::ObjCIvarDecl::Protected;
+ case eAccessPackage:
+ return clang::ObjCIvarDecl::Package;
+ }
+ return clang::ObjCIvarDecl::None;
}
-
//----------------------------------------------------------------------
// Tests
//----------------------------------------------------------------------
-bool
-ClangASTContext::IsAggregateType (lldb::opaque_compiler_type_t type)
-{
- clang::QualType qual_type (GetCanonicalQualType(type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::IncompleteArray:
- case clang::Type::VariableArray:
- case clang::Type::ConstantArray:
- case clang::Type::ExtVector:
- case clang::Type::Vector:
- case clang::Type::Record:
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- return true;
- case clang::Type::Auto:
- return IsAggregateType(llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr());
- case clang::Type::Elaborated:
- return IsAggregateType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- case clang::Type::Typedef:
- return IsAggregateType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- case clang::Type::Paren:
- return IsAggregateType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
- default:
- break;
- }
- // The clang type does have a value
- return false;
-}
-
-bool
-ClangASTContext::IsAnonymousType (lldb::opaque_compiler_type_t type)
-{
- clang::QualType qual_type (GetCanonicalQualType(type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- {
- if (const clang::RecordType *record_type = llvm::dyn_cast_or_null<clang::RecordType>(qual_type.getTypePtrOrNull()))
- {
- if (const clang::RecordDecl *record_decl = record_type->getDecl())
- {
- return record_decl->isAnonymousStructOrUnion();
- }
- }
- break;
- }
- case clang::Type::Auto:
- return IsAnonymousType(llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr());
- case clang::Type::Elaborated:
- return IsAnonymousType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- case clang::Type::Typedef:
- return IsAnonymousType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- case clang::Type::Paren:
- return IsAnonymousType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
- default:
- break;
- }
- // The clang type does have a value
- return false;
-}
-
-bool
-ClangASTContext::IsArrayType (lldb::opaque_compiler_type_t type,
- CompilerType *element_type_ptr,
- uint64_t *size,
- bool *is_incomplete)
-{
- clang::QualType qual_type (GetCanonicalQualType(type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- default:
- break;
-
- case clang::Type::ConstantArray:
- if (element_type_ptr)
- element_type_ptr->SetCompilerType (getASTContext(), llvm::cast<clang::ConstantArrayType>(qual_type)->getElementType());
- if (size)
- *size = llvm::cast<clang::ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
- if (is_incomplete)
- *is_incomplete = false;
- return true;
-
- case clang::Type::IncompleteArray:
- if (element_type_ptr)
- element_type_ptr->SetCompilerType (getASTContext(), llvm::cast<clang::IncompleteArrayType>(qual_type)->getElementType());
- if (size)
- *size = 0;
- if (is_incomplete)
- *is_incomplete = true;
- return true;
+bool ClangASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ case clang::Type::ConstantArray:
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ case clang::Type::Record:
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ return true;
+ case clang::Type::Auto:
+ return IsAggregateType(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr());
+ case clang::Type::Elaborated:
+ return IsAggregateType(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr());
+ case clang::Type::Typedef:
+ return IsAggregateType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr());
+ case clang::Type::Paren:
+ return IsAggregateType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+ default:
+ break;
+ }
+ // The clang type does have a value
+ return false;
+}
+
+bool ClangASTContext::IsAnonymousType(lldb::opaque_compiler_type_t type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record: {
+ if (const clang::RecordType *record_type =
+ llvm::dyn_cast_or_null<clang::RecordType>(
+ qual_type.getTypePtrOrNull())) {
+ if (const clang::RecordDecl *record_decl = record_type->getDecl()) {
+ return record_decl->isAnonymousStructOrUnion();
+ }
+ }
+ break;
+ }
+ case clang::Type::Auto:
+ return IsAnonymousType(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr());
+ case clang::Type::Elaborated:
+ return IsAnonymousType(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr());
+ case clang::Type::Typedef:
+ return IsAnonymousType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr());
+ case clang::Type::Paren:
+ return IsAnonymousType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+ default:
+ break;
+ }
+ // The clang type does have a value
+ return false;
+}
+
+bool ClangASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
+ CompilerType *element_type_ptr,
+ uint64_t *size, bool *is_incomplete) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ default:
+ break;
+
+ case clang::Type::ConstantArray:
+ if (element_type_ptr)
+ element_type_ptr->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::ConstantArrayType>(qual_type)->getElementType());
+ if (size)
+ *size = llvm::cast<clang::ConstantArrayType>(qual_type)
+ ->getSize()
+ .getLimitedValue(ULLONG_MAX);
+ if (is_incomplete)
+ *is_incomplete = false;
+ return true;
- case clang::Type::VariableArray:
- if (element_type_ptr)
- element_type_ptr->SetCompilerType (getASTContext(), llvm::cast<clang::VariableArrayType>(qual_type)->getElementType());
- if (size)
- *size = 0;
- if (is_incomplete)
- *is_incomplete = false;
- return true;
+ case clang::Type::IncompleteArray:
+ if (element_type_ptr)
+ element_type_ptr->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::IncompleteArrayType>(qual_type)->getElementType());
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = true;
+ return true;
- case clang::Type::DependentSizedArray:
- if (element_type_ptr)
- element_type_ptr->SetCompilerType (getASTContext(), llvm::cast<clang::DependentSizedArrayType>(qual_type)->getElementType());
- if (size)
- *size = 0;
- if (is_incomplete)
- *is_incomplete = false;
- return true;
+ case clang::Type::VariableArray:
+ if (element_type_ptr)
+ element_type_ptr->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::VariableArrayType>(qual_type)->getElementType());
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = false;
+ return true;
- case clang::Type::Typedef:
- return IsArrayType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- element_type_ptr,
- size,
- is_incomplete);
- case clang::Type::Auto:
- return IsArrayType(llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(),
- element_type_ptr,
- size,
- is_incomplete);
- case clang::Type::Elaborated:
- return IsArrayType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- element_type_ptr,
- size,
- is_incomplete);
- case clang::Type::Paren:
- return IsArrayType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- element_type_ptr,
- size,
- is_incomplete);
- }
+ case clang::Type::DependentSizedArray:
if (element_type_ptr)
- element_type_ptr->Clear();
+ element_type_ptr->SetCompilerType(
+ getASTContext(), llvm::cast<clang::DependentSizedArrayType>(qual_type)
+ ->getElementType());
if (size)
- *size = 0;
+ *size = 0;
if (is_incomplete)
- *is_incomplete = false;
- return false;
-}
+ *is_incomplete = false;
+ return true;
-bool
-ClangASTContext::IsVectorType (lldb::opaque_compiler_type_t type,
- CompilerType *element_type,
- uint64_t *size)
-{
- clang::QualType qual_type (GetCanonicalQualType(type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Vector:
- {
- const clang::VectorType *vector_type = qual_type->getAs<clang::VectorType>();
- if (vector_type)
- {
- if (size)
- *size = vector_type->getNumElements();
- if (element_type)
- *element_type = CompilerType(getASTContext(), vector_type->getElementType());
- }
- return true;
- }
- break;
- case clang::Type::ExtVector:
- {
- const clang::ExtVectorType *ext_vector_type = qual_type->getAs<clang::ExtVectorType>();
- if (ext_vector_type)
- {
- if (size)
- *size = ext_vector_type->getNumElements();
- if (element_type)
- *element_type = CompilerType(getASTContext(), ext_vector_type->getElementType());
- }
- return true;
- }
- default:
- break;
+ case clang::Type::Typedef:
+ return IsArrayType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ element_type_ptr, size, is_incomplete);
+ case clang::Type::Auto:
+ return IsArrayType(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ element_type_ptr, size, is_incomplete);
+ case clang::Type::Elaborated:
+ return IsArrayType(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ element_type_ptr, size, is_incomplete);
+ case clang::Type::Paren:
+ return IsArrayType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ element_type_ptr, size, is_incomplete);
+ }
+ if (element_type_ptr)
+ element_type_ptr->Clear();
+ if (size)
+ *size = 0;
+ if (is_incomplete)
+ *is_incomplete = false;
+ return false;
+}
+
+bool ClangASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
+ CompilerType *element_type, uint64_t *size) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Vector: {
+ const clang::VectorType *vector_type =
+ qual_type->getAs<clang::VectorType>();
+ if (vector_type) {
+ if (size)
+ *size = vector_type->getNumElements();
+ if (element_type)
+ *element_type =
+ CompilerType(getASTContext(), vector_type->getElementType());
}
+ return true;
+ } break;
+ case clang::Type::ExtVector: {
+ const clang::ExtVectorType *ext_vector_type =
+ qual_type->getAs<clang::ExtVectorType>();
+ if (ext_vector_type) {
+ if (size)
+ *size = ext_vector_type->getNumElements();
+ if (element_type)
+ *element_type =
+ CompilerType(getASTContext(), ext_vector_type->getElementType());
+ }
+ return true;
+ }
+ default:
+ break;
+ }
+ return false;
+}
+
+bool ClangASTContext::IsRuntimeGeneratedType(
+ lldb::opaque_compiler_type_t type) {
+ clang::DeclContext *decl_ctx = ClangASTContext::GetASTContext(getASTContext())
+ ->GetDeclContextForType(GetQualType(type));
+ if (!decl_ctx)
return false;
-}
-bool
-ClangASTContext::IsRuntimeGeneratedType (lldb::opaque_compiler_type_t type)
-{
- clang::DeclContext* decl_ctx = ClangASTContext::GetASTContext(getASTContext())->GetDeclContextForType(GetQualType(type));
- if (!decl_ctx)
- return false;
-
- if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
- return false;
-
- clang::ObjCInterfaceDecl *result_iface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
-
- ClangASTMetadata* ast_metadata = ClangASTContext::GetMetadata(getASTContext(), result_iface_decl);
- if (!ast_metadata)
- return false;
- return (ast_metadata->GetISAPtr() != 0);
-}
+ if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
+ return false;
+
+ clang::ObjCInterfaceDecl *result_iface_decl =
+ llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
-bool
-ClangASTContext::IsCharType (lldb::opaque_compiler_type_t type)
-{
- return GetQualType(type).getUnqualifiedType()->isCharType();
+ ClangASTMetadata *ast_metadata =
+ ClangASTContext::GetMetadata(getASTContext(), result_iface_decl);
+ if (!ast_metadata)
+ return false;
+ return (ast_metadata->GetISAPtr() != 0);
}
+bool ClangASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
+ return GetQualType(type).getUnqualifiedType()->isCharType();
+}
-bool
-ClangASTContext::IsCompleteType (lldb::opaque_compiler_type_t type)
-{
- const bool allow_completion = false;
- return GetCompleteQualType (getASTContext(), GetQualType(type), allow_completion);
+bool ClangASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
+ const bool allow_completion = false;
+ return GetCompleteQualType(getASTContext(), GetQualType(type),
+ allow_completion);
}
-bool
-ClangASTContext::IsConst(lldb::opaque_compiler_type_t type)
-{
- return GetQualType(type).isConstQualified();
+bool ClangASTContext::IsConst(lldb::opaque_compiler_type_t type) {
+ return GetQualType(type).isConstQualified();
}
-bool
-ClangASTContext::IsCStringType (lldb::opaque_compiler_type_t type, uint32_t &length)
-{
- CompilerType pointee_or_element_clang_type;
- length = 0;
- Flags type_flags (GetTypeInfo (type, &pointee_or_element_clang_type));
-
- if (!pointee_or_element_clang_type.IsValid())
- return false;
-
- if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
- {
- if (pointee_or_element_clang_type.IsCharType())
- {
- if (type_flags.Test (eTypeIsArray))
- {
- // We know the size of the array and it could be a C string
- // since it is an array of characters
- length = llvm::cast<clang::ConstantArrayType>(GetCanonicalQualType(type).getTypePtr())->getSize().getLimitedValue();
- }
- return true;
-
- }
- }
+bool ClangASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
+ uint32_t &length) {
+ CompilerType pointee_or_element_clang_type;
+ length = 0;
+ Flags type_flags(GetTypeInfo(type, &pointee_or_element_clang_type));
+
+ if (!pointee_or_element_clang_type.IsValid())
return false;
-}
-bool
-ClangASTContext::IsFunctionType (lldb::opaque_compiler_type_t type, bool *is_variadic_ptr)
-{
- if (type)
- {
- clang::QualType qual_type (GetCanonicalQualType(type));
-
- if (qual_type->isFunctionType())
- {
- if (is_variadic_ptr)
- {
- const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
- if (function_proto_type)
- *is_variadic_ptr = function_proto_type->isVariadic();
- else
- *is_variadic_ptr = false;
- }
- return true;
- }
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- default:
- break;
- case clang::Type::Typedef:
- return IsFunctionType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), nullptr);
- case clang::Type::Auto:
- return IsFunctionType(llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), nullptr);
- case clang::Type::Elaborated:
- return IsFunctionType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), nullptr);
- case clang::Type::Paren:
- return IsFunctionType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), nullptr);
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
- if (reference_type)
- return IsFunctionType(reference_type->getPointeeType().getAsOpaquePtr(), nullptr);
- }
- break;
- }
+ if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer)) {
+ if (pointee_or_element_clang_type.IsCharType()) {
+ if (type_flags.Test(eTypeIsArray)) {
+ // We know the size of the array and it could be a C string
+ // since it is an array of characters
+ length = llvm::cast<clang::ConstantArrayType>(
+ GetCanonicalQualType(type).getTypePtr())
+ ->getSize()
+ .getLimitedValue();
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ClangASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
+ bool *is_variadic_ptr) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ if (qual_type->isFunctionType()) {
+ if (is_variadic_ptr) {
+ const clang::FunctionProtoType *function_proto_type =
+ llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+ if (function_proto_type)
+ *is_variadic_ptr = function_proto_type->isVariadic();
+ else
+ *is_variadic_ptr = false;
+ }
+ return true;
}
- return false;
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ default:
+ break;
+ case clang::Type::Typedef:
+ return IsFunctionType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ nullptr);
+ case clang::Type::Auto:
+ return IsFunctionType(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ nullptr);
+ case clang::Type::Elaborated:
+ return IsFunctionType(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ nullptr);
+ case clang::Type::Paren:
+ return IsFunctionType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ nullptr);
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return IsFunctionType(reference_type->getPointeeType().getAsOpaquePtr(),
+ nullptr);
+ } break;
+ }
+ }
+ return false;
}
// Used to detect "Homogeneous Floating-point Aggregates"
uint32_t
-ClangASTContext::IsHomogeneousAggregate (lldb::opaque_compiler_type_t type, CompilerType* base_type_ptr)
-{
- if (!type)
- return 0;
-
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType (type))
- {
- const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- if (cxx_record_decl->getNumBases() ||
- cxx_record_decl->isDynamicClass())
- return 0;
- }
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- if (record_type)
- {
- const clang::RecordDecl *record_decl = record_type->getDecl();
- if (record_decl)
- {
- // We are looking for a structure that contains only floating point types
- clang::RecordDecl::field_iterator field_pos, field_end = record_decl->field_end();
- uint32_t num_fields = 0;
- bool is_hva = false;
- bool is_hfa = false;
- clang::QualType base_qual_type;
- uint64_t base_bitwidth = 0;
- for (field_pos = record_decl->field_begin(); field_pos != field_end; ++field_pos)
- {
- clang::QualType field_qual_type = field_pos->getType();
- uint64_t field_bitwidth = getASTContext()->getTypeSize (qual_type);
- if (field_qual_type->isFloatingType())
- {
- if (field_qual_type->isComplexType())
- return 0;
- else
- {
- if (num_fields == 0)
- base_qual_type = field_qual_type;
- else
- {
- if (is_hva)
- return 0;
- is_hfa = true;
- if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
- return 0;
- }
- }
- }
- else if (field_qual_type->isVectorType() || field_qual_type->isExtVectorType())
- {
- if (num_fields == 0)
- {
- base_qual_type = field_qual_type;
- base_bitwidth = field_bitwidth;
- }
- else
- {
- if (is_hfa)
- return 0;
- is_hva = true;
- if (base_bitwidth != field_bitwidth)
- return 0;
- if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
- return 0;
- }
- }
- else
- return 0;
- ++num_fields;
- }
- if (base_type_ptr)
- *base_type_ptr = CompilerType (getASTContext(), base_qual_type);
- return num_fields;
- }
- }
- }
- break;
-
- case clang::Type::Typedef:
- return IsHomogeneousAggregate(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), base_type_ptr);
-
- case clang::Type::Auto:
- return IsHomogeneousAggregate(llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), base_type_ptr);
-
- case clang::Type::Elaborated:
- return IsHomogeneousAggregate(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), base_type_ptr);
- default:
- break;
- }
+ClangASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
+ CompilerType *base_type_ptr) {
+ if (!type)
return 0;
-}
-size_t
-ClangASTContext::GetNumberOfFunctionArguments (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- clang::QualType qual_type (GetCanonicalQualType(type));
- const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
- if (func)
- return func->getNumParams();
- }
- return 0;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ if (cxx_record_decl->getNumBases() || cxx_record_decl->isDynamicClass())
+ return 0;
+ }
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ if (record_type) {
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl) {
+ // We are looking for a structure that contains only floating point
+ // types
+ clang::RecordDecl::field_iterator field_pos,
+ field_end = record_decl->field_end();
+ uint32_t num_fields = 0;
+ bool is_hva = false;
+ bool is_hfa = false;
+ clang::QualType base_qual_type;
+ uint64_t base_bitwidth = 0;
+ for (field_pos = record_decl->field_begin(); field_pos != field_end;
+ ++field_pos) {
+ clang::QualType field_qual_type = field_pos->getType();
+ uint64_t field_bitwidth = getASTContext()->getTypeSize(qual_type);
+ if (field_qual_type->isFloatingType()) {
+ if (field_qual_type->isComplexType())
+ return 0;
+ else {
+ if (num_fields == 0)
+ base_qual_type = field_qual_type;
+ else {
+ if (is_hva)
+ return 0;
+ is_hfa = true;
+ if (field_qual_type.getTypePtr() !=
+ base_qual_type.getTypePtr())
+ return 0;
+ }
+ }
+ } else if (field_qual_type->isVectorType() ||
+ field_qual_type->isExtVectorType()) {
+ if (num_fields == 0) {
+ base_qual_type = field_qual_type;
+ base_bitwidth = field_bitwidth;
+ } else {
+ if (is_hfa)
+ return 0;
+ is_hva = true;
+ if (base_bitwidth != field_bitwidth)
+ return 0;
+ if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
+ return 0;
+ }
+ } else
+ return 0;
+ ++num_fields;
+ }
+ if (base_type_ptr)
+ *base_type_ptr = CompilerType(getASTContext(), base_qual_type);
+ return num_fields;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return IsHomogeneousAggregate(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ base_type_ptr);
+
+ case clang::Type::Auto:
+ return IsHomogeneousAggregate(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ base_type_ptr);
+
+ case clang::Type::Elaborated:
+ return IsHomogeneousAggregate(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ base_type_ptr);
+ default:
+ break;
+ }
+ return 0;
+}
+
+size_t ClangASTContext::GetNumberOfFunctionArguments(
+ lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::FunctionProtoType *func =
+ llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+ if (func)
+ return func->getNumParams();
+ }
+ return 0;
}
CompilerType
-ClangASTContext::GetFunctionArgumentAtIndex (lldb::opaque_compiler_type_t type, const size_t index)
-{
- if (type)
- {
- clang::QualType qual_type (GetQualType(type));
- const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
- if (func)
- {
- if (index < func->getNumParams())
- return CompilerType(getASTContext(), func->getParamType(index));
- }
+ClangASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
+ const size_t index) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+ const clang::FunctionProtoType *func =
+ llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+ if (func) {
+ if (index < func->getNumParams())
+ return CompilerType(getASTContext(), func->getParamType(index));
}
- return CompilerType();
+ }
+ return CompilerType();
}
-bool
-ClangASTContext::IsFunctionPointerType (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- clang::QualType qual_type (GetCanonicalQualType(type));
-
- if (qual_type->isFunctionPointerType())
- return true;
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- default:
- break;
- case clang::Type::Typedef:
- return IsFunctionPointerType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- case clang::Type::Auto:
- return IsFunctionPointerType (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr());
- case clang::Type::Elaborated:
- return IsFunctionPointerType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- case clang::Type::Paren:
- return IsFunctionPointerType (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
- if (reference_type)
- return IsFunctionPointerType(reference_type->getPointeeType().getAsOpaquePtr());
- }
- break;
- }
- }
- return false;
-
-}
-
-bool
-ClangASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
-{
- if (type)
- {
- clang::QualType qual_type (GetCanonicalQualType(type));
-
- if (qual_type->isBlockPointerType())
- {
- if (function_pointer_type_ptr)
- {
- const clang::BlockPointerType *block_pointer_type = qual_type->getAs<clang::BlockPointerType>();
- QualType pointee_type = block_pointer_type->getPointeeType();
- QualType function_pointer_type = m_ast_ap->getPointerType(pointee_type);
- *function_pointer_type_ptr = CompilerType (getASTContext(), function_pointer_type);
- }
- return true;
- }
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- default:
- break;
- case clang::Type::Typedef:
- return IsBlockPointerType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), function_pointer_type_ptr);
- case clang::Type::Auto:
- return IsBlockPointerType (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), function_pointer_type_ptr);
- case clang::Type::Elaborated:
- return IsBlockPointerType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), function_pointer_type_ptr);
- case clang::Type::Paren:
- return IsBlockPointerType (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), function_pointer_type_ptr);
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
- if (reference_type)
- return IsBlockPointerType(reference_type->getPointeeType().getAsOpaquePtr(), function_pointer_type_ptr);
- }
- break;
- }
+bool ClangASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ if (qual_type->isFunctionPointerType())
+ return true;
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ default:
+ break;
+ case clang::Type::Typedef:
+ return IsFunctionPointerType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr());
+ case clang::Type::Auto:
+ return IsFunctionPointerType(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr());
+ case clang::Type::Elaborated:
+ return IsFunctionPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr());
+ case clang::Type::Paren:
+ return IsFunctionPointerType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return IsFunctionPointerType(
+ reference_type->getPointeeType().getAsOpaquePtr());
+ } break;
+ }
+ }
+ return false;
+}
+
+bool ClangASTContext::IsBlockPointerType(
+ lldb::opaque_compiler_type_t type,
+ CompilerType *function_pointer_type_ptr) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ if (qual_type->isBlockPointerType()) {
+ if (function_pointer_type_ptr) {
+ const clang::BlockPointerType *block_pointer_type =
+ qual_type->getAs<clang::BlockPointerType>();
+ QualType pointee_type = block_pointer_type->getPointeeType();
+ QualType function_pointer_type = m_ast_ap->getPointerType(pointee_type);
+ *function_pointer_type_ptr =
+ CompilerType(getASTContext(), function_pointer_type);
+ }
+ return true;
}
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ default:
+ break;
+ case clang::Type::Typedef:
+ return IsBlockPointerType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ function_pointer_type_ptr);
+ case clang::Type::Auto:
+ return IsBlockPointerType(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ function_pointer_type_ptr);
+ case clang::Type::Elaborated:
+ return IsBlockPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ function_pointer_type_ptr);
+ case clang::Type::Paren:
+ return IsBlockPointerType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ function_pointer_type_ptr);
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ if (reference_type)
+ return IsBlockPointerType(
+ reference_type->getPointeeType().getAsOpaquePtr(),
+ function_pointer_type_ptr);
+ } break;
+ }
+ }
+ return false;
+}
+
+bool ClangASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
+ bool &is_signed) {
+ if (!type)
return false;
-}
-bool
-ClangASTContext::IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed)
-{
- if (!type)
- return false;
-
- clang::QualType qual_type (GetCanonicalQualType(type));
- const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
-
- if (builtin_type)
- {
- if (builtin_type->isInteger())
- {
- is_signed = builtin_type->isSignedInteger();
- return true;
- }
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::BuiltinType *builtin_type =
+ llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
+
+ if (builtin_type) {
+ if (builtin_type->isInteger()) {
+ is_signed = builtin_type->isSignedInteger();
+ return true;
}
-
- return false;
+ }
+
+ return false;
}
-bool
-ClangASTContext::IsEnumerationType(lldb::opaque_compiler_type_t type, bool &is_signed)
-{
- if (type)
- {
- const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type)->getCanonicalTypeInternal());
+bool ClangASTContext::IsEnumerationType(lldb::opaque_compiler_type_t type,
+ bool &is_signed) {
+ if (type) {
+ const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
+ GetCanonicalQualType(type)->getCanonicalTypeInternal());
- if (enum_type)
- {
- IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(), is_signed);
- return true;
- }
+ if (enum_type) {
+ IsIntegerType(enum_type->getDecl()->getIntegerType().getAsOpaquePtr(),
+ is_signed);
+ return true;
}
+ }
- return false;
+ return false;
}
-bool
-ClangASTContext::IsPointerType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
-{
- if (type)
- {
- clang::QualType qual_type (GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- default:
- break;
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- return true;
- }
- return false;
- case clang::Type::ObjCObjectPointer:
- if (pointee_type)
- pointee_type->SetCompilerType (getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
- return true;
- case clang::Type::BlockPointer:
- if (pointee_type)
- pointee_type->SetCompilerType (getASTContext(), llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
- return true;
- case clang::Type::Pointer:
- if (pointee_type)
- pointee_type->SetCompilerType (getASTContext(), llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
- return true;
- case clang::Type::MemberPointer:
- if (pointee_type)
- pointee_type->SetCompilerType (getASTContext(), llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
- return true;
- case clang::Type::Typedef:
- return IsPointerType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), pointee_type);
- case clang::Type::Auto:
- return IsPointerType (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), pointee_type);
- case clang::Type::Elaborated:
- return IsPointerType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), pointee_type);
- case clang::Type::Paren:
- return IsPointerType (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), pointee_type);
- default:
- break;
- }
+bool ClangASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
+ CompilerType *pointee_type) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ default:
+ break;
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ return true;
+ }
+ return false;
+ case clang::Type::ObjCObjectPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+ ->getPointeeType());
+ return true;
+ case clang::Type::BlockPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::Pointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::MemberPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::Typedef:
+ return IsPointerType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ pointee_type);
+ case clang::Type::Auto:
+ return IsPointerType(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ pointee_type);
+ case clang::Type::Elaborated:
+ return IsPointerType(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ pointee_type);
+ case clang::Type::Paren:
+ return IsPointerType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ pointee_type);
+ default:
+ break;
}
- if (pointee_type)
- pointee_type->Clear();
- return false;
+ }
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
}
-
-bool
-ClangASTContext::IsPointerOrReferenceType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
-{
- if (type)
- {
- clang::QualType qual_type (GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- default:
- break;
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- return true;
- }
- return false;
- case clang::Type::ObjCObjectPointer:
- if (pointee_type)
- pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
- return true;
- case clang::Type::BlockPointer:
- if (pointee_type)
- pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
- return true;
- case clang::Type::Pointer:
- if (pointee_type)
- pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
- return true;
- case clang::Type::MemberPointer:
- if (pointee_type)
- pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
- return true;
- case clang::Type::LValueReference:
- if (pointee_type)
- pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
- return true;
- case clang::Type::RValueReference:
- if (pointee_type)
- pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
- return true;
- case clang::Type::Typedef:
- return IsPointerOrReferenceType(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), pointee_type);
- case clang::Type::Auto:
- return IsPointerOrReferenceType(llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), pointee_type);
- case clang::Type::Elaborated:
- return IsPointerOrReferenceType(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), pointee_type);
- case clang::Type::Paren:
- return IsPointerOrReferenceType(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), pointee_type);
- default:
- break;
- }
+bool ClangASTContext::IsPointerOrReferenceType(
+ lldb::opaque_compiler_type_t type, CompilerType *pointee_type) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ default:
+ break;
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ return true;
+ }
+ return false;
+ case clang::Type::ObjCObjectPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+ ->getPointeeType());
+ return true;
+ case clang::Type::BlockPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::Pointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::MemberPointer:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
+ return true;
+ case clang::Type::LValueReference:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
+ return true;
+ case clang::Type::RValueReference:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
+ return true;
+ case clang::Type::Typedef:
+ return IsPointerOrReferenceType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ pointee_type);
+ case clang::Type::Auto:
+ return IsPointerOrReferenceType(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ pointee_type);
+ case clang::Type::Elaborated:
+ return IsPointerOrReferenceType(
+ llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ pointee_type);
+ case clang::Type::Paren:
+ return IsPointerOrReferenceType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ pointee_type);
+ default:
+ break;
}
- if (pointee_type)
- pointee_type->Clear();
- return false;
+ }
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
}
+bool ClangASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
+ CompilerType *pointee_type,
+ bool *is_rvalue) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-bool
-ClangASTContext::IsReferenceType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool* is_rvalue)
-{
- if (type)
- {
- clang::QualType qual_type (GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-
- switch (type_class)
- {
- case clang::Type::LValueReference:
- if (pointee_type)
- pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
- if (is_rvalue)
- *is_rvalue = false;
- return true;
- case clang::Type::RValueReference:
- if (pointee_type)
- pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
- if (is_rvalue)
- *is_rvalue = true;
- return true;
- case clang::Type::Typedef:
- return IsReferenceType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), pointee_type, is_rvalue);
- case clang::Type::Auto:
- return IsReferenceType (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), pointee_type, is_rvalue);
- case clang::Type::Elaborated:
- return IsReferenceType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), pointee_type, is_rvalue);
- case clang::Type::Paren:
- return IsReferenceType (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), pointee_type, is_rvalue);
-
- default:
- break;
- }
+ switch (type_class) {
+ case clang::Type::LValueReference:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
+ if (is_rvalue)
+ *is_rvalue = false;
+ return true;
+ case clang::Type::RValueReference:
+ if (pointee_type)
+ pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
+ if (is_rvalue)
+ *is_rvalue = true;
+ return true;
+ case clang::Type::Typedef:
+ return IsReferenceType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ pointee_type, is_rvalue);
+ case clang::Type::Auto:
+ return IsReferenceType(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ pointee_type, is_rvalue);
+ case clang::Type::Elaborated:
+ return IsReferenceType(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ pointee_type, is_rvalue);
+ case clang::Type::Paren:
+ return IsReferenceType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ pointee_type, is_rvalue);
+
+ default:
+ break;
}
- if (pointee_type)
- pointee_type->Clear();
- return false;
+ }
+ if (pointee_type)
+ pointee_type->Clear();
+ return false;
}
-bool
-ClangASTContext::IsFloatingPointType (lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex)
-{
- if (type)
- {
- clang::QualType qual_type (GetCanonicalQualType(type));
-
- if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal()))
- {
- clang::BuiltinType::Kind kind = BT->getKind();
- if (kind >= clang::BuiltinType::Float && kind <= clang::BuiltinType::LongDouble)
- {
- count = 1;
- is_complex = false;
- return true;
- }
- }
- else if (const clang::ComplexType *CT = llvm::dyn_cast<clang::ComplexType>(qual_type->getCanonicalTypeInternal()))
- {
- if (IsFloatingPointType (CT->getElementType().getAsOpaquePtr(), count, is_complex))
- {
- count = 2;
- is_complex = true;
- return true;
- }
- }
- else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(qual_type->getCanonicalTypeInternal()))
- {
- if (IsFloatingPointType (VT->getElementType().getAsOpaquePtr(), count, is_complex))
- {
- count = VT->getNumElements();
- is_complex = false;
- return true;
- }
- }
+bool ClangASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
+ uint32_t &count, bool &is_complex) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(
+ qual_type->getCanonicalTypeInternal())) {
+ clang::BuiltinType::Kind kind = BT->getKind();
+ if (kind >= clang::BuiltinType::Float &&
+ kind <= clang::BuiltinType::LongDouble) {
+ count = 1;
+ is_complex = false;
+ return true;
+ }
+ } else if (const clang::ComplexType *CT =
+ llvm::dyn_cast<clang::ComplexType>(
+ qual_type->getCanonicalTypeInternal())) {
+ if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count,
+ is_complex)) {
+ count = 2;
+ is_complex = true;
+ return true;
+ }
+ } else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(
+ qual_type->getCanonicalTypeInternal())) {
+ if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count,
+ is_complex)) {
+ count = VT->getNumElements();
+ is_complex = false;
+ return true;
+ }
}
- count = 0;
- is_complex = false;
- return false;
+ }
+ count = 0;
+ is_complex = false;
+ return false;
}
+bool ClangASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
-bool
-ClangASTContext::IsDefined(lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return false;
-
- clang::QualType qual_type(GetQualType(type));
- const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
- if (tag_type)
- {
- clang::TagDecl *tag_decl = tag_type->getDecl();
- if (tag_decl)
- return tag_decl->isCompleteDefinition();
- return false;
- }
- else
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- if (class_interface_decl)
- return class_interface_decl->getDefinition() != nullptr;
- return false;
- }
+ clang::QualType qual_type(GetQualType(type));
+ const clang::TagType *tag_type =
+ llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
+ if (tag_type) {
+ clang::TagDecl *tag_decl = tag_type->getDecl();
+ if (tag_decl)
+ return tag_decl->isCompleteDefinition();
+ return false;
+ } else {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ if (class_interface_decl)
+ return class_interface_decl->getDefinition() != nullptr;
+ return false;
}
- return true;
+ }
+ return true;
}
-bool
-ClangASTContext::IsObjCClassType (const CompilerType& type)
-{
- if (type)
- {
- clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+bool ClangASTContext::IsObjCClassType(const CompilerType &type) {
+ if (type) {
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
- const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
-
- if (obj_pointer_type)
- return obj_pointer_type->isObjCClassType();
- }
- return false;
+ const clang::ObjCObjectPointerType *obj_pointer_type =
+ llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
+
+ if (obj_pointer_type)
+ return obj_pointer_type->isObjCClassType();
+ }
+ return false;
}
-bool
-ClangASTContext::IsObjCObjectOrInterfaceType (const CompilerType& type)
-{
- if (ClangUtil::IsClangType(type))
- return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
+bool ClangASTContext::IsObjCObjectOrInterfaceType(const CompilerType &type) {
+ if (ClangUtil::IsClangType(type))
+ return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType();
+ return false;
+}
+
+bool ClangASTContext::IsClassType(lldb::opaque_compiler_type_t type) {
+ if (!type)
return false;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ return (type_class == clang::Type::Record);
}
-bool
-ClangASTContext::IsClassType(lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return false;
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- return (type_class == clang::Type::Record);
+bool ClangASTContext::IsEnumType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ return (type_class == clang::Type::Enum);
}
-bool
-ClangASTContext::IsEnumType(lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return false;
+bool ClangASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
+ if (type) {
clang::QualType qual_type(GetCanonicalQualType(type));
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- return (type_class == clang::Type::Enum);
-}
-
-bool
-ClangASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- if (record_decl)
- {
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
- return cxx_record_decl->isPolymorphic();
- }
- }
- break;
-
- default:
- break;
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl)
+ return cxx_record_decl->isPolymorphic();
}
+ }
+ break;
+
+ default:
+ break;
}
- return false;
+ }
+ return false;
}
-bool
-ClangASTContext::IsPossibleDynamicType (lldb::opaque_compiler_type_t type, CompilerType *dynamic_pointee_type,
- bool check_cplusplus,
- bool check_objc)
-{
- clang::QualType pointee_qual_type;
- if (type)
- {
- clang::QualType qual_type (GetCanonicalQualType(type));
- bool success = false;
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Builtin:
- if (check_objc && llvm::cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
- {
- if (dynamic_pointee_type)
- dynamic_pointee_type->SetCompilerType(this, type);
- return true;
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (check_objc)
- {
- if (auto objc_pointee_type = qual_type->getPointeeType().getTypePtrOrNull())
- {
- if (auto objc_object_type = llvm::dyn_cast_or_null<clang::ObjCObjectType>(objc_pointee_type))
- {
- if (objc_object_type->isObjCClass())
- return false;
- }
- }
- if (dynamic_pointee_type)
- dynamic_pointee_type->SetCompilerType(getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
- return true;
- }
- break;
-
- case clang::Type::Pointer:
- pointee_qual_type = llvm::cast<clang::PointerType>(qual_type)->getPointeeType();
- success = true;
- break;
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- pointee_qual_type = llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType();
- success = true;
- break;
-
- case clang::Type::Typedef:
- return IsPossibleDynamicType (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- dynamic_pointee_type,
- check_cplusplus,
- check_objc);
-
- case clang::Type::Auto:
- return IsPossibleDynamicType (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(),
- dynamic_pointee_type,
- check_cplusplus,
- check_objc);
-
- case clang::Type::Elaborated:
- return IsPossibleDynamicType (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
- dynamic_pointee_type,
- check_cplusplus,
- check_objc);
-
- case clang::Type::Paren:
- return IsPossibleDynamicType (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
- dynamic_pointee_type,
- check_cplusplus,
- check_objc);
- default:
- break;
+bool ClangASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
+ CompilerType *dynamic_pointee_type,
+ bool check_cplusplus,
+ bool check_objc) {
+ clang::QualType pointee_qual_type;
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ bool success = false;
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin:
+ if (check_objc &&
+ llvm::cast<clang::BuiltinType>(qual_type)->getKind() ==
+ clang::BuiltinType::ObjCId) {
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetCompilerType(this, type);
+ return true;
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (check_objc) {
+ if (auto objc_pointee_type =
+ qual_type->getPointeeType().getTypePtrOrNull()) {
+ if (auto objc_object_type =
+ llvm::dyn_cast_or_null<clang::ObjCObjectType>(
+ objc_pointee_type)) {
+ if (objc_object_type->isObjCClass())
+ return false;
+ }
}
-
- if (success)
- {
- // Check to make sure what we are pointing too is a possible dynamic C++ type
- // We currently accept any "void *" (in case we have a class that has been
- // watered down to an opaque pointer) and virtual C++ classes.
- const clang::Type::TypeClass pointee_type_class = pointee_qual_type.getCanonicalType()->getTypeClass();
- switch (pointee_type_class)
- {
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind())
- {
- case clang::BuiltinType::UnknownAny:
- case clang::BuiltinType::Void:
- if (dynamic_pointee_type)
- dynamic_pointee_type->SetCompilerType(getASTContext(), pointee_qual_type);
- return true;
- default:
- break;
- }
- break;
-
- case clang::Type::Record:
- if (check_cplusplus)
- {
- clang::CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- bool is_complete = cxx_record_decl->isCompleteDefinition();
-
- if (is_complete)
- success = cxx_record_decl->isDynamicClass();
- else
- {
- ClangASTMetadata *metadata = ClangASTContext::GetMetadata (getASTContext(), cxx_record_decl);
- if (metadata)
- success = metadata->GetIsDynamicCXXType();
- else
- {
- is_complete = CompilerType(getASTContext(), pointee_qual_type).GetCompleteType();
- if (is_complete)
- success = cxx_record_decl->isDynamicClass();
- else
- success = false;
- }
- }
-
- if (success)
- {
- if (dynamic_pointee_type)
- dynamic_pointee_type->SetCompilerType(getASTContext(), pointee_qual_type);
- return true;
- }
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (check_objc)
- {
- if (dynamic_pointee_type)
- dynamic_pointee_type->SetCompilerType(getASTContext(), pointee_qual_type);
- return true;
- }
- break;
-
- default:
- break;
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+ ->getPointeeType());
+ return true;
+ }
+ break;
+
+ case clang::Type::Pointer:
+ pointee_qual_type =
+ llvm::cast<clang::PointerType>(qual_type)->getPointeeType();
+ success = true;
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ pointee_qual_type =
+ llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType();
+ success = true;
+ break;
+
+ case clang::Type::Typedef:
+ return IsPossibleDynamicType(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ dynamic_pointee_type, check_cplusplus,
+ check_objc);
+
+ case clang::Type::Auto:
+ return IsPossibleDynamicType(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ dynamic_pointee_type, check_cplusplus,
+ check_objc);
+
+ case clang::Type::Elaborated:
+ return IsPossibleDynamicType(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ dynamic_pointee_type, check_cplusplus,
+ check_objc);
+
+ case clang::Type::Paren:
+ return IsPossibleDynamicType(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ dynamic_pointee_type, check_cplusplus, check_objc);
+ default:
+ break;
+ }
+
+ if (success) {
+ // Check to make sure what we are pointing too is a possible dynamic C++
+ // type
+ // We currently accept any "void *" (in case we have a class that has been
+ // watered down to an opaque pointer) and virtual C++ classes.
+ const clang::Type::TypeClass pointee_type_class =
+ pointee_qual_type.getCanonicalType()->getTypeClass();
+ switch (pointee_type_class) {
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind()) {
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::Void:
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetCompilerType(getASTContext(),
+ pointee_qual_type);
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case clang::Type::Record:
+ if (check_cplusplus) {
+ clang::CXXRecordDecl *cxx_record_decl =
+ pointee_qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ bool is_complete = cxx_record_decl->isCompleteDefinition();
+
+ if (is_complete)
+ success = cxx_record_decl->isDynamicClass();
+ else {
+ ClangASTMetadata *metadata = ClangASTContext::GetMetadata(
+ getASTContext(), cxx_record_decl);
+ if (metadata)
+ success = metadata->GetIsDynamicCXXType();
+ else {
+ is_complete = CompilerType(getASTContext(), pointee_qual_type)
+ .GetCompleteType();
+ if (is_complete)
+ success = cxx_record_decl->isDynamicClass();
+ else
+ success = false;
+ }
+ }
+
+ if (success) {
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetCompilerType(getASTContext(),
+ pointee_qual_type);
+ return true;
}
+ }
}
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (check_objc) {
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->SetCompilerType(getASTContext(),
+ pointee_qual_type);
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
}
- if (dynamic_pointee_type)
- dynamic_pointee_type->Clear();
- return false;
+ }
+ if (dynamic_pointee_type)
+ dynamic_pointee_type->Clear();
+ return false;
}
+bool ClangASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
-bool
-ClangASTContext::IsScalarType (lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return false;
-
- return (GetTypeInfo (type, nullptr) & eTypeIsScalar) != 0;
+ return (GetTypeInfo(type, nullptr) & eTypeIsScalar) != 0;
}
-bool
-ClangASTContext::IsTypedefType (lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return false;
- return GetQualType(type)->getTypeClass() == clang::Type::Typedef;
+bool ClangASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+ return GetQualType(type)->getTypeClass() == clang::Type::Typedef;
}
-bool
-ClangASTContext::IsVoidType (lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return false;
- return GetCanonicalQualType(type)->isVoidType();
-}
-
-bool
-ClangASTContext::SupportsLanguage (lldb::LanguageType language)
-{
- return ClangASTContextSupportsLanguage(language);
-}
-
-bool
-ClangASTContext::GetCXXClassName (const CompilerType& type, std::string &class_name)
-{
- if (type)
- {
- clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
- if (!qual_type.isNull())
- {
- clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- class_name.assign(cxx_record_decl->getIdentifier()->getNameStart());
- return true;
- }
- }
- }
- class_name.clear();
+bool ClangASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
+ if (!type)
return false;
+ return GetCanonicalQualType(type)->isVoidType();
}
+bool ClangASTContext::SupportsLanguage(lldb::LanguageType language) {
+ return ClangASTContextSupportsLanguage(language);
+}
-bool
-ClangASTContext::IsCXXClassType (const CompilerType& type)
-{
- if (!type)
- return false;
-
+bool ClangASTContext::GetCXXClassName(const CompilerType &type,
+ std::string &class_name) {
+ if (type) {
clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
- if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr)
+ if (!qual_type.isNull()) {
+ clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ class_name.assign(cxx_record_decl->getIdentifier()->getNameStart());
return true;
+ }
+ }
+ }
+ class_name.clear();
+ return false;
+}
+
+bool ClangASTContext::IsCXXClassType(const CompilerType &type) {
+ if (!type)
return false;
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+ if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr)
+ return true;
+ return false;
}
-bool
-ClangASTContext::IsBeingDefined (lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return false;
- clang::QualType qual_type (GetCanonicalQualType(type));
- const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type);
- if (tag_type)
- return tag_type->isBeingDefined();
+bool ClangASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
+ if (!type)
return false;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type);
+ if (tag_type)
+ return tag_type->isBeingDefined();
+ return false;
}
-bool
-ClangASTContext::IsObjCObjectPointerType (const CompilerType& type, CompilerType *class_type_ptr)
-{
- if (!type)
- return false;
+bool ClangASTContext::IsObjCObjectPointerType(const CompilerType &type,
+ CompilerType *class_type_ptr) {
+ if (!type)
+ return false;
- clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
- if (!qual_type.isNull() && qual_type->isObjCObjectPointerType())
- {
- if (class_type_ptr)
- {
- if (!qual_type->isObjCClassType() &&
- !qual_type->isObjCIdType())
- {
- const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
- if (obj_pointer_type == nullptr)
- class_type_ptr->Clear();
- else
- class_type_ptr->SetCompilerType (type.GetTypeSystem(), clang::QualType(obj_pointer_type->getInterfaceType(), 0).getAsOpaquePtr());
- }
- }
- return true;
+ if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) {
+ if (class_type_ptr) {
+ if (!qual_type->isObjCClassType() && !qual_type->isObjCIdType()) {
+ const clang::ObjCObjectPointerType *obj_pointer_type =
+ llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
+ if (obj_pointer_type == nullptr)
+ class_type_ptr->Clear();
+ else
+ class_type_ptr->SetCompilerType(
+ type.GetTypeSystem(),
+ clang::QualType(obj_pointer_type->getInterfaceType(), 0)
+ .getAsOpaquePtr());
+ }
}
- if (class_type_ptr)
- class_type_ptr->Clear();
- return false;
+ return true;
+ }
+ if (class_type_ptr)
+ class_type_ptr->Clear();
+ return false;
}
-bool
-ClangASTContext::GetObjCClassName (const CompilerType& type, std::string &class_name)
-{
- if (!type)
- return false;
+bool ClangASTContext::GetObjCClassName(const CompilerType &type,
+ std::string &class_name) {
+ if (!type)
+ return false;
- clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
- const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
- if (object_type)
- {
- const clang::ObjCInterfaceDecl *interface = object_type->getInterface();
- if (interface)
- {
- class_name = interface->getNameAsString();
- return true;
- }
+ const clang::ObjCObjectType *object_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (object_type) {
+ const clang::ObjCInterfaceDecl *interface = object_type->getInterface();
+ if (interface) {
+ class_name = interface->getNameAsString();
+ return true;
}
- return false;
+ }
+ return false;
}
-
//----------------------------------------------------------------------
// Type Completion
//----------------------------------------------------------------------
-bool
-ClangASTContext::GetCompleteType (lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return false;
- const bool allow_completion = true;
- return GetCompleteQualType (getASTContext(), GetQualType(type), allow_completion);
+bool ClangASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return false;
+ const bool allow_completion = true;
+ return GetCompleteQualType(getASTContext(), GetQualType(type),
+ allow_completion);
}
-ConstString
-ClangASTContext::GetTypeName (lldb::opaque_compiler_type_t type)
-{
- std::string type_name;
- if (type)
- {
- clang::PrintingPolicy printing_policy (getASTContext()->getPrintingPolicy());
- clang::QualType qual_type(GetQualType(type));
- printing_policy.SuppressTagKeyword = true;
- const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
- if (typedef_type)
- {
- const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
- type_name = typedef_decl->getQualifiedNameAsString();
- }
- else
- {
- type_name = qual_type.getAsString(printing_policy);
- }
+ConstString ClangASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
+ std::string type_name;
+ if (type) {
+ clang::PrintingPolicy printing_policy(getASTContext()->getPrintingPolicy());
+ clang::QualType qual_type(GetQualType(type));
+ printing_policy.SuppressTagKeyword = true;
+ const clang::TypedefType *typedef_type =
+ qual_type->getAs<clang::TypedefType>();
+ if (typedef_type) {
+ const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+ type_name = typedef_decl->getQualifiedNameAsString();
+ } else {
+ type_name = qual_type.getAsString(printing_policy);
}
- return ConstString(type_name);
+ }
+ return ConstString(type_name);
}
uint32_t
-ClangASTContext::GetTypeInfo (lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_clang_type)
-{
- if (!type)
- return 0;
-
- if (pointee_or_element_clang_type)
- pointee_or_element_clang_type->Clear();
-
- clang::QualType qual_type (GetQualType(type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Builtin:
- {
- const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
-
- uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
- switch (builtin_type->getKind())
- {
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- if (pointee_or_element_clang_type)
- pointee_or_element_clang_type->SetCompilerType(getASTContext(), getASTContext()->ObjCBuiltinClassTy);
- builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
- break;
-
- case clang::BuiltinType::ObjCSel:
- if (pointee_or_element_clang_type)
- pointee_or_element_clang_type->SetCompilerType(getASTContext(), getASTContext()->CharTy);
- builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
- break;
-
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble:
- builtin_type_flags |= eTypeIsScalar;
- if (builtin_type->isInteger())
- {
- builtin_type_flags |= eTypeIsInteger;
- if (builtin_type->isSignedInteger())
- builtin_type_flags |= eTypeIsSigned;
- }
- else if (builtin_type->isFloatingPoint())
- builtin_type_flags |= eTypeIsFloat;
- break;
- default:
- break;
- }
- return builtin_type_flags;
- }
-
- case clang::Type::BlockPointer:
- if (pointee_or_element_clang_type)
- pointee_or_element_clang_type->SetCompilerType(getASTContext(), qual_type->getPointeeType());
- return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
-
- case clang::Type::Complex:
- {
- uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
- const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(qual_type->getCanonicalTypeInternal());
- if (complex_type)
- {
- clang::QualType complex_element_type (complex_type->getElementType());
- if (complex_element_type->isIntegerType())
- complex_type_flags |= eTypeIsFloat;
- else if (complex_element_type->isFloatingType())
- complex_type_flags |= eTypeIsInteger;
- }
- return complex_type_flags;
- }
- break;
-
- case clang::Type::ConstantArray:
- case clang::Type::DependentSizedArray:
- case clang::Type::IncompleteArray:
- case clang::Type::VariableArray:
- if (pointee_or_element_clang_type)
- pointee_or_element_clang_type->SetCompilerType(getASTContext(), llvm::cast<clang::ArrayType>(qual_type.getTypePtr())->getElementType());
- return eTypeHasChildren | eTypeIsArray;
-
- case clang::Type::DependentName: return 0;
- case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
- case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
- case clang::Type::Decltype: return 0;
-
- case clang::Type::Enum:
- if (pointee_or_element_clang_type)
- pointee_or_element_clang_type->SetCompilerType(getASTContext(), llvm::cast<clang::EnumType>(qual_type)->getDecl()->getIntegerType());
- return eTypeIsEnumeration | eTypeHasValue;
-
- case clang::Type::Auto:
- return CompilerType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetTypeInfo (pointee_or_element_clang_type);
- case clang::Type::Elaborated:
- return CompilerType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetTypeInfo (pointee_or_element_clang_type);
- case clang::Type::Paren:
- return CompilerType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetTypeInfo (pointee_or_element_clang_type);
-
- case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
- case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
- case clang::Type::InjectedClassName: return 0;
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- if (pointee_or_element_clang_type)
- pointee_or_element_clang_type->SetCompilerType(getASTContext(), llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())->getPointeeType());
- return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
-
- case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
-
- case clang::Type::ObjCObjectPointer:
- if (pointee_or_element_clang_type)
- pointee_or_element_clang_type->SetCompilerType(getASTContext(), qual_type->getPointeeType());
- return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
-
- case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
- case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
-
- case clang::Type::Pointer:
- if (pointee_or_element_clang_type)
- pointee_or_element_clang_type->SetCompilerType(getASTContext(), qual_type->getPointeeType());
- return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
-
- case clang::Type::Record:
- if (qual_type->getAsCXXRecordDecl())
- return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
- else
- return eTypeHasChildren | eTypeIsStructUnion;
- break;
- case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
- case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
- case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
-
- case clang::Type::Typedef:
- return eTypeIsTypedef | CompilerType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetTypeInfo (pointee_or_element_clang_type);
- case clang::Type::TypeOfExpr: return 0;
- case clang::Type::TypeOf: return 0;
- case clang::Type::UnresolvedUsing: return 0;
-
- case clang::Type::ExtVector:
- case clang::Type::Vector:
- {
- uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
- const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>(qual_type->getCanonicalTypeInternal());
- if (vector_type)
- {
- if (vector_type->isIntegerType())
- vector_type_flags |= eTypeIsFloat;
- else if (vector_type->isFloatingType())
- vector_type_flags |= eTypeIsInteger;
- }
- return vector_type_flags;
- }
- default: return 0;
+ClangASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
+ CompilerType *pointee_or_element_clang_type) {
+ if (!type)
+ return 0;
+
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->Clear();
+
+ clang::QualType qual_type(GetQualType(type));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin: {
+ const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(
+ qual_type->getCanonicalTypeInternal());
+
+ uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
+ switch (builtin_type->getKind()) {
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ getASTContext(), getASTContext()->ObjCBuiltinClassTy);
+ builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
+ break;
+
+ case clang::BuiltinType::ObjCSel:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(getASTContext(),
+ getASTContext()->CharTy);
+ builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
+ break;
+
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ builtin_type_flags |= eTypeIsScalar;
+ if (builtin_type->isInteger()) {
+ builtin_type_flags |= eTypeIsInteger;
+ if (builtin_type->isSignedInteger())
+ builtin_type_flags |= eTypeIsSigned;
+ } else if (builtin_type->isFloatingPoint())
+ builtin_type_flags |= eTypeIsFloat;
+ break;
+ default:
+ break;
}
+ return builtin_type_flags;
+ }
+
+ case clang::Type::BlockPointer:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ getASTContext(), qual_type->getPointeeType());
+ return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
+
+ case clang::Type::Complex: {
+ uint32_t complex_type_flags =
+ eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
+ const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(
+ qual_type->getCanonicalTypeInternal());
+ if (complex_type) {
+ clang::QualType complex_element_type(complex_type->getElementType());
+ if (complex_element_type->isIntegerType())
+ complex_type_flags |= eTypeIsFloat;
+ else if (complex_element_type->isFloatingType())
+ complex_type_flags |= eTypeIsInteger;
+ }
+ return complex_type_flags;
+ } break;
+
+ case clang::Type::ConstantArray:
+ case clang::Type::DependentSizedArray:
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ getASTContext(), llvm::cast<clang::ArrayType>(qual_type.getTypePtr())
+ ->getElementType());
+ return eTypeHasChildren | eTypeIsArray;
+
+ case clang::Type::DependentName:
+ return 0;
+ case clang::Type::DependentSizedExtVector:
+ return eTypeHasChildren | eTypeIsVector;
+ case clang::Type::DependentTemplateSpecialization:
+ return eTypeIsTemplate;
+ case clang::Type::Decltype:
return 0;
-}
+ case clang::Type::Enum:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::EnumType>(qual_type)->getDecl()->getIntegerType());
+ return eTypeIsEnumeration | eTypeHasValue;
+
+ case clang::Type::Auto:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ .GetTypeInfo(pointee_or_element_clang_type);
+ case clang::Type::Elaborated:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ .GetTypeInfo(pointee_or_element_clang_type);
+ case clang::Type::Paren:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar())
+ .GetTypeInfo(pointee_or_element_clang_type);
+
+ case clang::Type::FunctionProto:
+ return eTypeIsFuncPrototype | eTypeHasValue;
+ case clang::Type::FunctionNoProto:
+ return eTypeIsFuncPrototype | eTypeHasValue;
+ case clang::Type::InjectedClassName:
+ return 0;
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ getASTContext(),
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())
+ ->getPointeeType());
+ return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
-lldb::LanguageType
-ClangASTContext::GetMinimumLanguage (lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return lldb::eLanguageTypeC;
-
- // If the type is a reference, then resolve it to what it refers to first:
- clang::QualType qual_type (GetCanonicalQualType(type).getNonReferenceType());
- if (qual_type->isAnyPointerType())
- {
- if (qual_type->isObjCObjectPointerType())
- return lldb::eLanguageTypeObjC;
-
- clang::QualType pointee_type (qual_type->getPointeeType());
- if (pointee_type->getPointeeCXXRecordDecl() != nullptr)
- return lldb::eLanguageTypeC_plus_plus;
- if (pointee_type->isObjCObjectOrInterfaceType())
- return lldb::eLanguageTypeObjC;
- if (pointee_type->isObjCClassType())
- return lldb::eLanguageTypeObjC;
- if (pointee_type.getTypePtr() == getASTContext()->ObjCBuiltinIdTy.getTypePtr())
- return lldb::eLanguageTypeObjC;
- }
+ case clang::Type::MemberPointer:
+ return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
+
+ case clang::Type::ObjCObjectPointer:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ getASTContext(), qual_type->getPointeeType());
+ return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer |
+ eTypeHasValue;
+
+ case clang::Type::ObjCObject:
+ return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
+ case clang::Type::ObjCInterface:
+ return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
+
+ case clang::Type::Pointer:
+ if (pointee_or_element_clang_type)
+ pointee_or_element_clang_type->SetCompilerType(
+ getASTContext(), qual_type->getPointeeType());
+ return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
+
+ case clang::Type::Record:
+ if (qual_type->getAsCXXRecordDecl())
+ return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
else
- {
- if (qual_type->isObjCObjectOrInterfaceType())
- return lldb::eLanguageTypeObjC;
- if (qual_type->getAsCXXRecordDecl())
- return lldb::eLanguageTypeC_plus_plus;
- switch (qual_type->getTypeClass())
- {
- default:
- break;
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- default:
- case clang::BuiltinType::Void:
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble:
- break;
-
- case clang::BuiltinType::NullPtr:
- return eLanguageTypeC_plus_plus;
-
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- case clang::BuiltinType::ObjCSel:
- return eLanguageTypeObjC;
-
- case clang::BuiltinType::Dependent:
- case clang::BuiltinType::Overload:
- case clang::BuiltinType::BoundMember:
- case clang::BuiltinType::UnknownAny:
- break;
- }
- break;
- case clang::Type::Typedef:
- return CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMinimumLanguage();
- }
- }
+ return eTypeHasChildren | eTypeIsStructUnion;
+ break;
+ case clang::Type::SubstTemplateTypeParm:
+ return eTypeIsTemplate;
+ case clang::Type::TemplateTypeParm:
+ return eTypeIsTemplate;
+ case clang::Type::TemplateSpecialization:
+ return eTypeIsTemplate;
+
+ case clang::Type::Typedef:
+ return eTypeIsTypedef |
+ CompilerType(getASTContext(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetTypeInfo(pointee_or_element_clang_type);
+ case clang::Type::TypeOfExpr:
+ return 0;
+ case clang::Type::TypeOf:
+ return 0;
+ case clang::Type::UnresolvedUsing:
+ return 0;
+
+ case clang::Type::ExtVector:
+ case clang::Type::Vector: {
+ uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
+ const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>(
+ qual_type->getCanonicalTypeInternal());
+ if (vector_type) {
+ if (vector_type->isIntegerType())
+ vector_type_flags |= eTypeIsFloat;
+ else if (vector_type->isFloatingType())
+ vector_type_flags |= eTypeIsInteger;
+ }
+ return vector_type_flags;
+ }
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+lldb::LanguageType
+ClangASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
+ if (!type)
return lldb::eLanguageTypeC;
+
+ // If the type is a reference, then resolve it to what it refers to first:
+ clang::QualType qual_type(GetCanonicalQualType(type).getNonReferenceType());
+ if (qual_type->isAnyPointerType()) {
+ if (qual_type->isObjCObjectPointerType())
+ return lldb::eLanguageTypeObjC;
+
+ clang::QualType pointee_type(qual_type->getPointeeType());
+ if (pointee_type->getPointeeCXXRecordDecl() != nullptr)
+ return lldb::eLanguageTypeC_plus_plus;
+ if (pointee_type->isObjCObjectOrInterfaceType())
+ return lldb::eLanguageTypeObjC;
+ if (pointee_type->isObjCClassType())
+ return lldb::eLanguageTypeObjC;
+ if (pointee_type.getTypePtr() ==
+ getASTContext()->ObjCBuiltinIdTy.getTypePtr())
+ return lldb::eLanguageTypeObjC;
+ } else {
+ if (qual_type->isObjCObjectOrInterfaceType())
+ return lldb::eLanguageTypeObjC;
+ if (qual_type->getAsCXXRecordDecl())
+ return lldb::eLanguageTypeC_plus_plus;
+ switch (qual_type->getTypeClass()) {
+ default:
+ break;
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ default:
+ case clang::BuiltinType::Void:
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ break;
+
+ case clang::BuiltinType::NullPtr:
+ return eLanguageTypeC_plus_plus;
+
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCSel:
+ return eLanguageTypeObjC;
+
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::BoundMember:
+ case clang::BuiltinType::UnknownAny:
+ break;
+ }
+ break;
+ case clang::Type::Typedef:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetMinimumLanguage();
+ }
+ }
+ return lldb::eLanguageTypeC;
}
lldb::TypeClass
-ClangASTContext::GetTypeClass (lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return lldb::eTypeClassInvalid;
-
- clang::QualType qual_type(GetQualType(type));
-
- switch (qual_type->getTypeClass())
- {
- case clang::Type::UnaryTransform: break;
- case clang::Type::FunctionNoProto: return lldb::eTypeClassFunction;
- case clang::Type::FunctionProto: return lldb::eTypeClassFunction;
- case clang::Type::IncompleteArray: return lldb::eTypeClassArray;
- case clang::Type::VariableArray: return lldb::eTypeClassArray;
- case clang::Type::ConstantArray: return lldb::eTypeClassArray;
- case clang::Type::DependentSizedArray: return lldb::eTypeClassArray;
- case clang::Type::DependentSizedExtVector: return lldb::eTypeClassVector;
- case clang::Type::ExtVector: return lldb::eTypeClassVector;
- case clang::Type::Vector: return lldb::eTypeClassVector;
- case clang::Type::Builtin: return lldb::eTypeClassBuiltin;
- case clang::Type::ObjCObjectPointer: return lldb::eTypeClassObjCObjectPointer;
- case clang::Type::BlockPointer: return lldb::eTypeClassBlockPointer;
- case clang::Type::Pointer: return lldb::eTypeClassPointer;
- case clang::Type::LValueReference: return lldb::eTypeClassReference;
- case clang::Type::RValueReference: return lldb::eTypeClassReference;
- case clang::Type::MemberPointer: return lldb::eTypeClassMemberPointer;
- case clang::Type::Complex:
- if (qual_type->isComplexType())
- return lldb::eTypeClassComplexFloat;
- else
- return lldb::eTypeClassComplexInteger;
- case clang::Type::ObjCObject: return lldb::eTypeClassObjCObject;
- case clang::Type::ObjCInterface: return lldb::eTypeClassObjCInterface;
- case clang::Type::Record:
- {
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- if (record_decl->isUnion())
- return lldb::eTypeClassUnion;
- else if (record_decl->isStruct())
- return lldb::eTypeClassStruct;
- else
- return lldb::eTypeClassClass;
- }
- break;
- case clang::Type::Enum: return lldb::eTypeClassEnumeration;
- case clang::Type::Typedef: return lldb::eTypeClassTypedef;
- case clang::Type::UnresolvedUsing: break;
- case clang::Type::Paren:
- return CompilerType(getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetTypeClass();
- case clang::Type::Auto:
- return CompilerType(getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetTypeClass();
- case clang::Type::Elaborated:
- return CompilerType(getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetTypeClass();
-
- case clang::Type::Attributed: break;
- case clang::Type::TemplateTypeParm: break;
- case clang::Type::SubstTemplateTypeParm: break;
- case clang::Type::SubstTemplateTypeParmPack:break;
- case clang::Type::InjectedClassName: break;
- case clang::Type::DependentName: break;
- case clang::Type::DependentTemplateSpecialization: break;
- case clang::Type::PackExpansion: break;
-
- case clang::Type::TypeOfExpr: break;
- case clang::Type::TypeOf: break;
- case clang::Type::Decltype: break;
- case clang::Type::TemplateSpecialization: break;
- case clang::Type::Atomic: break;
- case clang::Type::Pipe: break;
-
- // pointer type decayed from an array or function type.
- case clang::Type::Decayed: break;
- case clang::Type::Adjusted: break;
- }
- // We don't know hot to display this type...
- return lldb::eTypeClassOther;
-
-}
-
-unsigned
-ClangASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type)
-{
- if (type)
- return GetQualType(type).getQualifiers().getCVRQualifiers();
- return 0;
+ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return lldb::eTypeClassInvalid;
+
+ clang::QualType qual_type(GetQualType(type));
+
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::UnaryTransform:
+ break;
+ case clang::Type::FunctionNoProto:
+ return lldb::eTypeClassFunction;
+ case clang::Type::FunctionProto:
+ return lldb::eTypeClassFunction;
+ case clang::Type::IncompleteArray:
+ return lldb::eTypeClassArray;
+ case clang::Type::VariableArray:
+ return lldb::eTypeClassArray;
+ case clang::Type::ConstantArray:
+ return lldb::eTypeClassArray;
+ case clang::Type::DependentSizedArray:
+ return lldb::eTypeClassArray;
+ case clang::Type::DependentSizedExtVector:
+ return lldb::eTypeClassVector;
+ case clang::Type::ExtVector:
+ return lldb::eTypeClassVector;
+ case clang::Type::Vector:
+ return lldb::eTypeClassVector;
+ case clang::Type::Builtin:
+ return lldb::eTypeClassBuiltin;
+ case clang::Type::ObjCObjectPointer:
+ return lldb::eTypeClassObjCObjectPointer;
+ case clang::Type::BlockPointer:
+ return lldb::eTypeClassBlockPointer;
+ case clang::Type::Pointer:
+ return lldb::eTypeClassPointer;
+ case clang::Type::LValueReference:
+ return lldb::eTypeClassReference;
+ case clang::Type::RValueReference:
+ return lldb::eTypeClassReference;
+ case clang::Type::MemberPointer:
+ return lldb::eTypeClassMemberPointer;
+ case clang::Type::Complex:
+ if (qual_type->isComplexType())
+ return lldb::eTypeClassComplexFloat;
+ else
+ return lldb::eTypeClassComplexInteger;
+ case clang::Type::ObjCObject:
+ return lldb::eTypeClassObjCObject;
+ case clang::Type::ObjCInterface:
+ return lldb::eTypeClassObjCInterface;
+ case clang::Type::Record: {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl->isUnion())
+ return lldb::eTypeClassUnion;
+ else if (record_decl->isStruct())
+ return lldb::eTypeClassStruct;
+ else
+ return lldb::eTypeClassClass;
+ } break;
+ case clang::Type::Enum:
+ return lldb::eTypeClassEnumeration;
+ case clang::Type::Typedef:
+ return lldb::eTypeClassTypedef;
+ case clang::Type::UnresolvedUsing:
+ break;
+ case clang::Type::Paren:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar())
+ .GetTypeClass();
+ case clang::Type::Auto:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ .GetTypeClass();
+ case clang::Type::Elaborated:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ .GetTypeClass();
+
+ case clang::Type::Attributed:
+ break;
+ case clang::Type::TemplateTypeParm:
+ break;
+ case clang::Type::SubstTemplateTypeParm:
+ break;
+ case clang::Type::SubstTemplateTypeParmPack:
+ break;
+ case clang::Type::InjectedClassName:
+ break;
+ case clang::Type::DependentName:
+ break;
+ case clang::Type::DependentTemplateSpecialization:
+ break;
+ case clang::Type::PackExpansion:
+ break;
+
+ case clang::Type::TypeOfExpr:
+ break;
+ case clang::Type::TypeOf:
+ break;
+ case clang::Type::Decltype:
+ break;
+ case clang::Type::TemplateSpecialization:
+ break;
+ case clang::Type::Atomic:
+ break;
+ case clang::Type::Pipe:
+ break;
+
+ // pointer type decayed from an array or function type.
+ case clang::Type::Decayed:
+ break;
+ case clang::Type::Adjusted:
+ break;
+ case clang::Type::ObjCTypeParam:
+ break;
+ }
+ // We don't know hot to display this type...
+ return lldb::eTypeClassOther;
+}
+
+unsigned ClangASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return GetQualType(type).getQualifiers().getCVRQualifiers();
+ return 0;
}
//----------------------------------------------------------------------
@@ -4279,1689 +4343,1837 @@ ClangASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type)
//----------------------------------------------------------------------
CompilerType
-ClangASTContext::GetArrayElementType (lldb::opaque_compiler_type_t type, uint64_t *stride)
-{
- if (type)
- {
- clang::QualType qual_type(GetCanonicalQualType(type));
-
- const clang::Type *array_eletype = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
-
- if (!array_eletype)
- return CompilerType();
-
- CompilerType element_type (getASTContext(), array_eletype->getCanonicalTypeUnqualified());
-
- // TODO: the real stride will be >= this value.. find the real one!
- if (stride)
- *stride = element_type.GetByteSize(nullptr);
-
- return element_type;
-
- }
- return CompilerType();
-}
+ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
+ uint64_t *stride) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
-CompilerType
-ClangASTContext::GetCanonicalType (lldb::opaque_compiler_type_t type)
-{
- if (type)
- return CompilerType (getASTContext(), GetCanonicalQualType(type));
- return CompilerType();
+ const clang::Type *array_eletype =
+ qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
+
+ if (!array_eletype)
+ return CompilerType();
+
+ CompilerType element_type(getASTContext(),
+ array_eletype->getCanonicalTypeUnqualified());
+
+ // TODO: the real stride will be >= this value.. find the real one!
+ if (stride)
+ *stride = element_type.GetByteSize(nullptr);
+
+ return element_type;
+ }
+ return CompilerType();
}
-static clang::QualType
-GetFullyUnqualifiedType_Impl (clang::ASTContext *ast, clang::QualType qual_type)
-{
- if (qual_type->isPointerType())
- qual_type = ast->getPointerType(GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType()));
- else
- qual_type = qual_type.getUnqualifiedType();
- qual_type.removeLocalConst();
- qual_type.removeLocalRestrict();
- qual_type.removeLocalVolatile();
- return qual_type;
+CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type,
+ uint64_t size) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ if (clang::ASTContext *ast_ctx = getASTContext()) {
+ if (size != 0)
+ return CompilerType(
+ ast_ctx, ast_ctx->getConstantArrayType(
+ qual_type, llvm::APInt(64, size),
+ clang::ArrayType::ArraySizeModifier::Normal, 0));
+ else
+ return CompilerType(
+ ast_ctx,
+ ast_ctx->getIncompleteArrayType(
+ qual_type, clang::ArrayType::ArraySizeModifier::Normal, 0));
+ }
+ }
+
+ return CompilerType();
}
CompilerType
-ClangASTContext::GetFullyUnqualifiedType (lldb::opaque_compiler_type_t type)
-{
- if (type)
- return CompilerType(getASTContext(), GetFullyUnqualifiedType_Impl(getASTContext(), GetQualType(type)));
- return CompilerType();
+ClangASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return CompilerType(getASTContext(), GetCanonicalQualType(type));
+ return CompilerType();
}
-
-int
-ClangASTContext::GetFunctionArgumentCount (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType(type));
- if (func)
- return func->getNumParams();
- }
- return -1;
+static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast,
+ clang::QualType qual_type) {
+ if (qual_type->isPointerType())
+ qual_type = ast->getPointerType(
+ GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType()));
+ else
+ qual_type = qual_type.getUnqualifiedType();
+ qual_type.removeLocalConst();
+ qual_type.removeLocalRestrict();
+ qual_type.removeLocalVolatile();
+ return qual_type;
}
CompilerType
-ClangASTContext::GetFunctionArgumentTypeAtIndex (lldb::opaque_compiler_type_t type, size_t idx)
-{
- if (type)
- {
- const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(GetQualType(type));
- if (func)
- {
- const uint32_t num_args = func->getNumParams();
- if (idx < num_args)
- return CompilerType(getASTContext(), func->getParamType(idx));
- }
- }
- return CompilerType();
+ClangASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return CompilerType(
+ getASTContext(),
+ GetFullyUnqualifiedType_Impl(getASTContext(), GetQualType(type)));
+ return CompilerType();
+}
+
+int ClangASTContext::GetFunctionArgumentCount(
+ lldb::opaque_compiler_type_t type) {
+ if (type) {
+ const clang::FunctionProtoType *func =
+ llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType(type));
+ if (func)
+ return func->getNumParams();
+ }
+ return -1;
+}
+
+CompilerType ClangASTContext::GetFunctionArgumentTypeAtIndex(
+ lldb::opaque_compiler_type_t type, size_t idx) {
+ if (type) {
+ const clang::FunctionProtoType *func =
+ llvm::dyn_cast<clang::FunctionProtoType>(GetQualType(type));
+ if (func) {
+ const uint32_t num_args = func->getNumParams();
+ if (idx < num_args)
+ return CompilerType(getASTContext(), func->getParamType(idx));
+ }
+ }
+ return CompilerType();
}
CompilerType
-ClangASTContext::GetFunctionReturnType (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- clang::QualType qual_type(GetQualType(type));
- const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
- if (func)
- return CompilerType(getASTContext(), func->getReturnType());
- }
- return CompilerType();
+ClangASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+ const clang::FunctionProtoType *func =
+ llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
+ if (func)
+ return CompilerType(getASTContext(), func->getReturnType());
+ }
+ return CompilerType();
}
size_t
-ClangASTContext::GetNumMemberFunctions (lldb::opaque_compiler_type_t type)
-{
- size_t num_functions = 0;
- if (type)
- {
- clang::QualType qual_type(GetCanonicalQualType(type));
- switch (qual_type->getTypeClass()) {
- case clang::Type::Record:
- if (GetCompleteQualType (getASTContext(), qual_type))
- {
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- assert(record_decl);
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
- num_functions = std::distance(cxx_record_decl->method_begin(), cxx_record_decl->method_end());
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (GetCompleteType(type))
- {
- const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
- if (class_interface_decl)
- num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end());
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteType(type))
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- if (class_interface_decl)
- num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end());
- }
- }
- break;
-
-
- case clang::Type::Typedef:
- return CompilerType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumMemberFunctions();
-
- case clang::Type::Auto:
- return CompilerType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetNumMemberFunctions();
-
- case clang::Type::Elaborated:
- return CompilerType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumMemberFunctions();
-
- case clang::Type::Paren:
- return CompilerType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumMemberFunctions();
-
- default:
- break;
+ClangASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
+ size_t num_functions = 0;
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::Record:
+ if (GetCompleteQualType(getASTContext(), qual_type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl)
+ num_functions = std::distance(cxx_record_decl->method_begin(),
+ cxx_record_decl->method_end());
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ const clang::ObjCObjectPointerType *objc_class_type =
+ qual_type->getAsObjCInterfacePointerType();
+ const clang::ObjCInterfaceType *objc_interface_type =
+ objc_class_type->getInterfaceType();
+ if (objc_interface_type &&
+ GetCompleteType((lldb::opaque_compiler_type_t)objc_interface_type)) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getDecl();
+ if (class_interface_decl) {
+ num_functions = std::distance(class_interface_decl->meth_begin(),
+ class_interface_decl->meth_end());
+ }
+ }
+ break;
+ }
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ if (class_interface_decl)
+ num_functions = std::distance(class_interface_decl->meth_begin(),
+ class_interface_decl->meth_end());
}
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetNumMemberFunctions();
+
+ case clang::Type::Auto:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ .GetNumMemberFunctions();
+
+ case clang::Type::Elaborated:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ .GetNumMemberFunctions();
+
+ case clang::Type::Paren:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar())
+ .GetNumMemberFunctions();
+
+ default:
+ break;
}
- return num_functions;
+ }
+ return num_functions;
}
TypeMemberFunctionImpl
-ClangASTContext::GetMemberFunctionAtIndex (lldb::opaque_compiler_type_t type, size_t idx)
-{
- std::string name;
- MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
- CompilerType clang_type;
- CompilerDecl clang_decl;
- if (type)
- {
- clang::QualType qual_type(GetCanonicalQualType(type));
- switch (qual_type->getTypeClass()) {
- case clang::Type::Record:
- if (GetCompleteQualType (getASTContext(), qual_type))
- {
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- assert(record_decl);
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
- {
- auto method_iter = cxx_record_decl->method_begin();
- auto method_end = cxx_record_decl->method_end();
- if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
- {
- std::advance(method_iter, idx);
- clang::CXXMethodDecl *cxx_method_decl = method_iter->getCanonicalDecl();
- if (cxx_method_decl)
- {
- name = cxx_method_decl->getDeclName().getAsString();
- if (cxx_method_decl->isStatic())
- kind = lldb::eMemberFunctionKindStaticMethod;
- else if (llvm::isa<clang::CXXConstructorDecl>(cxx_method_decl))
- kind = lldb::eMemberFunctionKindConstructor;
- else if (llvm::isa<clang::CXXDestructorDecl>(cxx_method_decl))
- kind = lldb::eMemberFunctionKindDestructor;
- else
- kind = lldb::eMemberFunctionKindInstanceMethod;
- clang_type = CompilerType(this, cxx_method_decl->getType().getAsOpaquePtr());
- clang_decl = CompilerDecl(this, cxx_method_decl);
- }
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (GetCompleteType(type))
- {
- const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
- if (class_interface_decl)
- {
- auto method_iter = class_interface_decl->meth_begin();
- auto method_end = class_interface_decl->meth_end();
- if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
- {
- std::advance(method_iter, idx);
- clang::ObjCMethodDecl *objc_method_decl = method_iter->getCanonicalDecl();
- if (objc_method_decl)
- {
- clang_decl = CompilerDecl(this, objc_method_decl);
- name = objc_method_decl->getSelector().getAsString();
- if (objc_method_decl->isClassMethod())
- kind = lldb::eMemberFunctionKindStaticMethod;
- else
- kind = lldb::eMemberFunctionKindInstanceMethod;
- }
- }
- }
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteType(type))
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- if (class_interface_decl)
- {
- auto method_iter = class_interface_decl->meth_begin();
- auto method_end = class_interface_decl->meth_end();
- if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
- {
- std::advance(method_iter, idx);
- clang::ObjCMethodDecl *objc_method_decl = method_iter->getCanonicalDecl();
- if (objc_method_decl)
- {
- clang_decl = CompilerDecl(this, objc_method_decl);
- name = objc_method_decl->getSelector().getAsString();
- if (objc_method_decl->isClassMethod())
- kind = lldb::eMemberFunctionKindStaticMethod;
- else
- kind = lldb::eMemberFunctionKindInstanceMethod;
- }
- }
- }
- }
- }
- break;
-
- case clang::Type::Typedef:
- return GetMemberFunctionAtIndex(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), idx);
-
- case clang::Type::Auto:
- return GetMemberFunctionAtIndex(llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), idx);
-
- case clang::Type::Elaborated:
- return GetMemberFunctionAtIndex(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), idx);
-
- case clang::Type::Paren:
- return GetMemberFunctionAtIndex(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx);
-
- default:
- break;
+ClangASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
+ size_t idx) {
+ std::string name;
+ MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
+ CompilerType clang_type;
+ CompilerDecl clang_decl;
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::Record:
+ if (GetCompleteQualType(getASTContext(), qual_type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl) {
+ auto method_iter = cxx_record_decl->method_begin();
+ auto method_end = cxx_record_decl->method_end();
+ if (idx <
+ static_cast<size_t>(std::distance(method_iter, method_end))) {
+ std::advance(method_iter, idx);
+ clang::CXXMethodDecl *cxx_method_decl =
+ method_iter->getCanonicalDecl();
+ if (cxx_method_decl) {
+ name = cxx_method_decl->getDeclName().getAsString();
+ if (cxx_method_decl->isStatic())
+ kind = lldb::eMemberFunctionKindStaticMethod;
+ else if (llvm::isa<clang::CXXConstructorDecl>(cxx_method_decl))
+ kind = lldb::eMemberFunctionKindConstructor;
+ else if (llvm::isa<clang::CXXDestructorDecl>(cxx_method_decl))
+ kind = lldb::eMemberFunctionKindDestructor;
+ else
+ kind = lldb::eMemberFunctionKindInstanceMethod;
+ clang_type = CompilerType(
+ this, cxx_method_decl->getType().getAsOpaquePtr());
+ clang_decl = CompilerDecl(this, cxx_method_decl);
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ const clang::ObjCObjectPointerType *objc_class_type =
+ qual_type->getAsObjCInterfacePointerType();
+ const clang::ObjCInterfaceType *objc_interface_type =
+ objc_class_type->getInterfaceType();
+ if (objc_interface_type &&
+ GetCompleteType((lldb::opaque_compiler_type_t)objc_interface_type)) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getDecl();
+ if (class_interface_decl) {
+ auto method_iter = class_interface_decl->meth_begin();
+ auto method_end = class_interface_decl->meth_end();
+ if (idx <
+ static_cast<size_t>(std::distance(method_iter, method_end))) {
+ std::advance(method_iter, idx);
+ clang::ObjCMethodDecl *objc_method_decl =
+ method_iter->getCanonicalDecl();
+ if (objc_method_decl) {
+ clang_decl = CompilerDecl(this, objc_method_decl);
+ name = objc_method_decl->getSelector().getAsString();
+ if (objc_method_decl->isClassMethod())
+ kind = lldb::eMemberFunctionKindStaticMethod;
+ else
+ kind = lldb::eMemberFunctionKindInstanceMethod;
+ }
+ }
}
+ }
+ break;
+ }
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ if (class_interface_decl) {
+ auto method_iter = class_interface_decl->meth_begin();
+ auto method_end = class_interface_decl->meth_end();
+ if (idx <
+ static_cast<size_t>(std::distance(method_iter, method_end))) {
+ std::advance(method_iter, idx);
+ clang::ObjCMethodDecl *objc_method_decl =
+ method_iter->getCanonicalDecl();
+ if (objc_method_decl) {
+ clang_decl = CompilerDecl(this, objc_method_decl);
+ name = objc_method_decl->getSelector().getAsString();
+ if (objc_method_decl->isClassMethod())
+ kind = lldb::eMemberFunctionKindStaticMethod;
+ else
+ kind = lldb::eMemberFunctionKindInstanceMethod;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return GetMemberFunctionAtIndex(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ idx);
+
+ case clang::Type::Auto:
+ return GetMemberFunctionAtIndex(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ idx);
+
+ case clang::Type::Elaborated:
+ return GetMemberFunctionAtIndex(
+ llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ idx);
+
+ case clang::Type::Paren:
+ return GetMemberFunctionAtIndex(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ idx);
+
+ default:
+ break;
}
-
- if (kind == eMemberFunctionKindUnknown)
- return TypeMemberFunctionImpl();
- else
- return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
+ }
+
+ if (kind == eMemberFunctionKindUnknown)
+ return TypeMemberFunctionImpl();
+ else
+ return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
}
CompilerType
-ClangASTContext::GetNonReferenceType (lldb::opaque_compiler_type_t type)
-{
- if (type)
- return CompilerType(getASTContext(), GetQualType(type).getNonReferenceType());
- return CompilerType();
+ClangASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return CompilerType(getASTContext(),
+ GetQualType(type).getNonReferenceType());
+ return CompilerType();
+}
+
+CompilerType ClangASTContext::CreateTypedefType(
+ const CompilerType &type, const char *typedef_name,
+ const CompilerDeclContext &compiler_decl_ctx) {
+ if (type && typedef_name && typedef_name[0]) {
+ ClangASTContext *ast =
+ llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
+ if (!ast)
+ return CompilerType();
+ clang::ASTContext *clang_ast = ast->getASTContext();
+ clang::QualType qual_type(ClangUtil::GetQualType(type));
+
+ clang::DeclContext *decl_ctx =
+ ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
+ if (decl_ctx == nullptr)
+ decl_ctx = ast->getASTContext()->getTranslationUnitDecl();
+
+ clang::TypedefDecl *decl = clang::TypedefDecl::Create(
+ *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
+ &clang_ast->Idents.get(typedef_name),
+ clang_ast->getTrivialTypeSourceInfo(qual_type));
+
+ decl->setAccess(clang::AS_public); // TODO respect proper access specifier
+
+ // Get a uniqued clang::QualType for the typedef decl type
+ return CompilerType(clang_ast, clang_ast->getTypedefType(decl));
+ }
+ return CompilerType();
}
CompilerType
-ClangASTContext::CreateTypedefType (const CompilerType& type,
- const char *typedef_name,
- const CompilerDeclContext &compiler_decl_ctx)
-{
- if (type && typedef_name && typedef_name[0])
- {
- ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem());
- if (!ast)
- return CompilerType();
- clang::ASTContext* clang_ast = ast->getASTContext();
- clang::QualType qual_type(ClangUtil::GetQualType(type));
-
- clang::DeclContext *decl_ctx = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
- if (decl_ctx == nullptr)
- decl_ctx = ast->getASTContext()->getTranslationUnitDecl();
-
- clang::TypedefDecl *decl = clang::TypedefDecl::Create (*clang_ast,
- decl_ctx,
- clang::SourceLocation(),
- clang::SourceLocation(),
- &clang_ast->Idents.get(typedef_name),
- clang_ast->getTrivialTypeSourceInfo(qual_type));
-
- decl->setAccess(clang::AS_public); // TODO respect proper access specifier
-
- // Get a uniqued clang::QualType for the typedef decl type
- return CompilerType (clang_ast, clang_ast->getTypedefType (decl));
- }
- return CompilerType();
-
+ClangASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+ return CompilerType(getASTContext(),
+ qual_type.getTypePtr()->getPointeeType());
+ }
+ return CompilerType();
}
CompilerType
-ClangASTContext::GetPointeeType (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- clang::QualType qual_type(GetQualType(type));
- return CompilerType (getASTContext(), qual_type.getTypePtr()->getPointeeType());
+ClangASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ return CompilerType(getASTContext(),
+ getASTContext()->getObjCObjectPointerType(qual_type));
+
+ default:
+ return CompilerType(getASTContext(),
+ getASTContext()->getPointerType(qual_type));
}
- return CompilerType();
+ }
+ return CompilerType();
}
CompilerType
-ClangASTContext::GetPointerType (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- clang::QualType qual_type (GetQualType(type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- return CompilerType(getASTContext(), getASTContext()->getObjCObjectPointerType(qual_type));
-
- default:
- return CompilerType(getASTContext(), getASTContext()->getPointerType(qual_type));
- }
- }
+ClangASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return CompilerType(this, getASTContext()
+ ->getLValueReferenceType(GetQualType(type))
+ .getAsOpaquePtr());
+ else
return CompilerType();
}
-
CompilerType
-ClangASTContext::GetLValueReferenceType (lldb::opaque_compiler_type_t type)
-{
- if (type)
- return CompilerType(this, getASTContext()->getLValueReferenceType(GetQualType(type)).getAsOpaquePtr());
- else
- return CompilerType();
+ClangASTContext::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return CompilerType(this, getASTContext()
+ ->getRValueReferenceType(GetQualType(type))
+ .getAsOpaquePtr());
+ else
+ return CompilerType();
}
CompilerType
-ClangASTContext::GetRValueReferenceType (lldb::opaque_compiler_type_t type)
-{
- if (type)
- return CompilerType(this, getASTContext()->getRValueReferenceType(GetQualType(type)).getAsOpaquePtr());
- else
- return CompilerType();
+ClangASTContext::AddConstModifier(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType result(GetQualType(type));
+ result.addConst();
+ return CompilerType(this, result.getAsOpaquePtr());
+ }
+ return CompilerType();
}
CompilerType
-ClangASTContext::AddConstModifier (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- clang::QualType result(GetQualType(type));
- result.addConst();
- return CompilerType (this, result.getAsOpaquePtr());
- }
- return CompilerType();
+ClangASTContext::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType result(GetQualType(type));
+ result.addVolatile();
+ return CompilerType(this, result.getAsOpaquePtr());
+ }
+ return CompilerType();
}
CompilerType
-ClangASTContext::AddVolatileModifier (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- clang::QualType result(GetQualType(type));
- result.addVolatile();
- return CompilerType (this, result.getAsOpaquePtr());
- }
- return CompilerType();
-
+ClangASTContext::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType result(GetQualType(type));
+ result.addRestrict();
+ return CompilerType(this, result.getAsOpaquePtr());
+ }
+ return CompilerType();
}
CompilerType
-ClangASTContext::AddRestrictModifier (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- clang::QualType result(GetQualType(type));
- result.addRestrict();
- return CompilerType (this, result.getAsOpaquePtr());
- }
- return CompilerType();
-
-}
+ClangASTContext::CreateTypedef(lldb::opaque_compiler_type_t type,
+ const char *typedef_name,
+ const CompilerDeclContext &compiler_decl_ctx) {
+ if (type) {
+ clang::ASTContext *clang_ast = getASTContext();
+ clang::QualType qual_type(GetQualType(type));
-CompilerType
-ClangASTContext::CreateTypedef (lldb::opaque_compiler_type_t type, const char *typedef_name, const CompilerDeclContext &compiler_decl_ctx)
-{
- if (type)
- {
- clang::ASTContext* clang_ast = getASTContext();
- clang::QualType qual_type (GetQualType(type));
-
- clang::DeclContext *decl_ctx = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
- if (decl_ctx == nullptr)
- decl_ctx = getASTContext()->getTranslationUnitDecl();
-
- clang::TypedefDecl *decl = clang::TypedefDecl::Create (*clang_ast,
- decl_ctx,
- clang::SourceLocation(),
- clang::SourceLocation(),
- &clang_ast->Idents.get(typedef_name),
- clang_ast->getTrivialTypeSourceInfo(qual_type));
-
- clang::TagDecl *tdecl = nullptr;
- if (!qual_type.isNull())
- {
- if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
- tdecl = rt->getDecl();
- if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
- tdecl = et->getDecl();
- }
+ clang::DeclContext *decl_ctx =
+ ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx);
+ if (decl_ctx == nullptr)
+ decl_ctx = getASTContext()->getTranslationUnitDecl();
- // Check whether this declaration is an anonymous struct, union, or enum, hidden behind a typedef. If so, we
- // try to check whether we have a typedef tag to attach to the original record declaration
- if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
- tdecl->setTypedefNameForAnonDecl(decl);
+ clang::TypedefDecl *decl = clang::TypedefDecl::Create(
+ *clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
+ &clang_ast->Idents.get(typedef_name),
+ clang_ast->getTrivialTypeSourceInfo(qual_type));
- decl->setAccess(clang::AS_public); // TODO respect proper access specifier
+ clang::TagDecl *tdecl = nullptr;
+ if (!qual_type.isNull()) {
+ if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>())
+ tdecl = rt->getDecl();
+ if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
+ tdecl = et->getDecl();
+ }
- // Get a uniqued clang::QualType for the typedef decl type
- return CompilerType (this, clang_ast->getTypedefType (decl).getAsOpaquePtr());
+ // Check whether this declaration is an anonymous struct, union, or enum,
+ // hidden behind a typedef. If so, we
+ // try to check whether we have a typedef tag to attach to the original
+ // record declaration
+ if (tdecl && !tdecl->getIdentifier() && !tdecl->getTypedefNameForAnonDecl())
+ tdecl->setTypedefNameForAnonDecl(decl);
- }
- return CompilerType();
+ decl->setAccess(clang::AS_public); // TODO respect proper access specifier
+ // Get a uniqued clang::QualType for the typedef decl type
+ return CompilerType(this, clang_ast->getTypedefType(decl).getAsOpaquePtr());
+ }
+ return CompilerType();
}
CompilerType
-ClangASTContext::GetTypedefedType (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(GetQualType(type));
- if (typedef_type)
- return CompilerType (getASTContext(), typedef_type->getDecl()->getUnderlyingType());
- }
- return CompilerType();
+ClangASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ const clang::TypedefType *typedef_type =
+ llvm::dyn_cast<clang::TypedefType>(GetQualType(type));
+ if (typedef_type)
+ return CompilerType(getASTContext(),
+ typedef_type->getDecl()->getUnderlyingType());
+ }
+ return CompilerType();
}
-
//----------------------------------------------------------------------
// Create related types using the current type's AST
//----------------------------------------------------------------------
-CompilerType
-ClangASTContext::GetBasicTypeFromAST (lldb::BasicType basic_type)
-{
- return ClangASTContext::GetBasicType(getASTContext(), basic_type);
+CompilerType ClangASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
+ return ClangASTContext::GetBasicType(getASTContext(), basic_type);
}
//----------------------------------------------------------------------
// Exploring the type
//----------------------------------------------------------------------
-uint64_t
-ClangASTContext::GetBitSize (lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope)
-{
- if (GetCompleteType (type))
- {
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- return getASTContext()->getTypeSize(qual_type);
- else
- return 0;
- break;
-
- case clang::Type::ObjCInterface:
- case clang::Type::ObjCObject:
- {
- ExecutionContext exe_ctx (exe_scope);
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
- if (objc_runtime)
- {
- uint64_t bit_size = 0;
- if (objc_runtime->GetTypeBitSize(CompilerType(getASTContext(), qual_type), bit_size))
- return bit_size;
- }
- }
- else
- {
- static bool g_printed = false;
- if (!g_printed)
- {
- StreamString s;
- DumpTypeDescription(type, &s);
-
- llvm::outs() << "warning: trying to determine the size of type ";
- llvm::outs() << s.GetString() << "\n";
- llvm::outs() << "without a valid ExecutionContext. this is not reliable. please file a bug against LLDB.\n";
- llvm::outs() << "backtrace:\n";
- llvm::sys::PrintStackTrace(llvm::outs());
- llvm::outs() << "\n";
- g_printed = true;
- }
- }
- }
- LLVM_FALLTHROUGH;
- default:
- const uint32_t bit_size = getASTContext()->getTypeSize (qual_type);
- if (bit_size == 0)
- {
- if (qual_type->isIncompleteArrayType())
- return getASTContext()->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
- }
- if (qual_type->isObjCObjectOrInterfaceType())
- return bit_size + getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy);
- return bit_size;
- }
- }
- return 0;
-}
-
-size_t
-ClangASTContext::GetTypeBitAlign (lldb::opaque_compiler_type_t type)
-{
- if (GetCompleteType(type))
- return getASTContext()->getTypeAlign(GetQualType(type));
- return 0;
-}
-
-
-lldb::Encoding
-ClangASTContext::GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count)
-{
- if (!type)
- return lldb::eEncodingInvalid;
-
- count = 1;
+uint64_t ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
+ ExecutionContextScope *exe_scope) {
+ if (GetCompleteType(type)) {
clang::QualType qual_type(GetCanonicalQualType(type));
-
- switch (qual_type->getTypeClass())
- {
- case clang::Type::UnaryTransform:
- break;
-
- case clang::Type::FunctionNoProto:
- case clang::Type::FunctionProto:
- break;
-
- case clang::Type::IncompleteArray:
- case clang::Type::VariableArray:
- break;
-
- case clang::Type::ConstantArray:
- break;
-
- case clang::Type::ExtVector:
- case clang::Type::Vector:
- // TODO: Set this to more than one???
- break;
-
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- case clang::BuiltinType::Void:
- break;
-
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128:
- return lldb::eEncodingSint;
-
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128:
- return lldb::eEncodingUint;
-
- case clang::BuiltinType::Half:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Float128:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble:
- return lldb::eEncodingIEEE754;
-
- case clang::BuiltinType::ObjCClass:
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCSel:
- return lldb::eEncodingUint;
-
- case clang::BuiltinType::NullPtr:
- return lldb::eEncodingUint;
-
- case clang::BuiltinType::Kind::ARCUnbridgedCast:
- case clang::BuiltinType::Kind::BoundMember:
- case clang::BuiltinType::Kind::BuiltinFn:
- case clang::BuiltinType::Kind::Dependent:
- case clang::BuiltinType::Kind::OCLClkEvent:
- case clang::BuiltinType::Kind::OCLEvent:
- case clang::BuiltinType::Kind::OCLImage1dRO:
- case clang::BuiltinType::Kind::OCLImage1dWO:
- case clang::BuiltinType::Kind::OCLImage1dRW:
- case clang::BuiltinType::Kind::OCLImage1dArrayRO:
- case clang::BuiltinType::Kind::OCLImage1dArrayWO:
- case clang::BuiltinType::Kind::OCLImage1dArrayRW:
- case clang::BuiltinType::Kind::OCLImage1dBufferRO:
- case clang::BuiltinType::Kind::OCLImage1dBufferWO:
- case clang::BuiltinType::Kind::OCLImage1dBufferRW:
- case clang::BuiltinType::Kind::OCLImage2dRO:
- case clang::BuiltinType::Kind::OCLImage2dWO:
- case clang::BuiltinType::Kind::OCLImage2dRW:
- case clang::BuiltinType::Kind::OCLImage2dArrayRO:
- case clang::BuiltinType::Kind::OCLImage2dArrayWO:
- case clang::BuiltinType::Kind::OCLImage2dArrayRW:
- case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
- case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
- case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
- case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
- case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
- case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
- case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
- case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
- case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
- case clang::BuiltinType::Kind::OCLImage2dDepthRO:
- case clang::BuiltinType::Kind::OCLImage2dDepthWO:
- case clang::BuiltinType::Kind::OCLImage2dDepthRW:
- case clang::BuiltinType::Kind::OCLImage2dMSAARO:
- case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
- case clang::BuiltinType::Kind::OCLImage2dMSAARW:
- case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
- case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
- case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
- case clang::BuiltinType::Kind::OCLImage3dRO:
- case clang::BuiltinType::Kind::OCLImage3dWO:
- case clang::BuiltinType::Kind::OCLImage3dRW:
- case clang::BuiltinType::Kind::OCLQueue:
- case clang::BuiltinType::Kind::OCLNDRange:
- case clang::BuiltinType::Kind::OCLReserveID:
- case clang::BuiltinType::Kind::OCLSampler:
- case clang::BuiltinType::Kind::OMPArraySection:
- case clang::BuiltinType::Kind::Overload:
- case clang::BuiltinType::Kind::PseudoObject:
- case clang::BuiltinType::Kind::UnknownAny:
- break;
- }
- break;
- // All pointer types are represented as unsigned integer encodings.
- // We may nee to add a eEncodingPointer if we ever need to know the
- // difference
- case clang::Type::ObjCObjectPointer:
- case clang::Type::BlockPointer:
- case clang::Type::Pointer:
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- case clang::Type::MemberPointer: return lldb::eEncodingUint;
- case clang::Type::Complex:
- {
- lldb::Encoding encoding = lldb::eEncodingIEEE754;
- if (qual_type->isComplexType())
- encoding = lldb::eEncodingIEEE754;
- else
- {
- const clang::ComplexType *complex_type = qual_type->getAsComplexIntegerType();
- if (complex_type)
- encoding = CompilerType(getASTContext(), complex_type->getElementType()).GetEncoding(count);
- else
- encoding = lldb::eEncodingSint;
- }
- count = 2;
- return encoding;
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type))
+ return getASTContext()->getTypeSize(qual_type);
+ else
+ return 0;
+ break;
+
+ case clang::Type::ObjCInterface:
+ case clang::Type::ObjCObject: {
+ ExecutionContext exe_ctx(exe_scope);
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+ if (objc_runtime) {
+ uint64_t bit_size = 0;
+ if (objc_runtime->GetTypeBitSize(
+ CompilerType(getASTContext(), qual_type), bit_size))
+ return bit_size;
}
-
- case clang::Type::ObjCInterface: break;
- case clang::Type::Record: break;
- case clang::Type::Enum: return lldb::eEncodingSint;
- case clang::Type::Typedef:
- return CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetEncoding(count);
-
- case clang::Type::Auto:
- return CompilerType(getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetEncoding(count);
-
- case clang::Type::Elaborated:
- return CompilerType(getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetEncoding(count);
-
- case clang::Type::Paren:
- return CompilerType(getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetEncoding(count);
-
- case clang::Type::DependentSizedArray:
- case clang::Type::DependentSizedExtVector:
- case clang::Type::UnresolvedUsing:
- case clang::Type::Attributed:
- case clang::Type::TemplateTypeParm:
- case clang::Type::SubstTemplateTypeParm:
- case clang::Type::SubstTemplateTypeParmPack:
- case clang::Type::InjectedClassName:
- case clang::Type::DependentName:
- case clang::Type::DependentTemplateSpecialization:
- case clang::Type::PackExpansion:
- case clang::Type::ObjCObject:
-
- case clang::Type::TypeOfExpr:
- case clang::Type::TypeOf:
- case clang::Type::Decltype:
- case clang::Type::TemplateSpecialization:
- case clang::Type::Atomic:
- case clang::Type::Adjusted:
- case clang::Type::Pipe:
- break;
-
- // pointer type decayed from an array or function type.
- case clang::Type::Decayed:
- break;
+ } else {
+ static bool g_printed = false;
+ if (!g_printed) {
+ StreamString s;
+ DumpTypeDescription(type, &s);
+
+ llvm::outs() << "warning: trying to determine the size of type ";
+ llvm::outs() << s.GetString() << "\n";
+ llvm::outs() << "without a valid ExecutionContext. this is not "
+ "reliable. please file a bug against LLDB.\n";
+ llvm::outs() << "backtrace:\n";
+ llvm::sys::PrintStackTrace(llvm::outs());
+ llvm::outs() << "\n";
+ g_printed = true;
+ }
+ }
}
- count = 0;
+ LLVM_FALLTHROUGH;
+ default:
+ const uint32_t bit_size = getASTContext()->getTypeSize(qual_type);
+ if (bit_size == 0) {
+ if (qual_type->isIncompleteArrayType())
+ return getASTContext()->getTypeSize(
+ qual_type->getArrayElementTypeNoTypeQual()
+ ->getCanonicalTypeUnqualified());
+ }
+ if (qual_type->isObjCObjectOrInterfaceType())
+ return bit_size +
+ getASTContext()->getTypeSize(
+ getASTContext()->ObjCBuiltinClassTy);
+ return bit_size;
+ }
+ }
+ return 0;
+}
+
+size_t ClangASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) {
+ if (GetCompleteType(type))
+ return getASTContext()->getTypeAlign(GetQualType(type));
+ return 0;
+}
+
+lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
+ uint64_t &count) {
+ if (!type)
return lldb::eEncodingInvalid;
-}
-lldb::Format
-ClangASTContext::GetFormat (lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return lldb::eFormatDefault;
-
- clang::QualType qual_type(GetCanonicalQualType(type));
-
- switch (qual_type->getTypeClass())
- {
- case clang::Type::UnaryTransform:
- break;
-
- case clang::Type::FunctionNoProto:
- case clang::Type::FunctionProto:
- break;
-
- case clang::Type::IncompleteArray:
- case clang::Type::VariableArray:
- break;
-
- case clang::Type::ConstantArray:
- return lldb::eFormatVoid; // no value
-
- case clang::Type::ExtVector:
- case clang::Type::Vector:
- break;
-
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- //default: assert(0 && "Unknown builtin type!");
- case clang::BuiltinType::UnknownAny:
- case clang::BuiltinType::Void:
- case clang::BuiltinType::BoundMember:
- break;
-
- case clang::BuiltinType::Bool: return lldb::eFormatBoolean;
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U: return lldb::eFormatChar;
- case clang::BuiltinType::Char16: return lldb::eFormatUnicode16;
- case clang::BuiltinType::Char32: return lldb::eFormatUnicode32;
- case clang::BuiltinType::UShort: return lldb::eFormatUnsigned;
- case clang::BuiltinType::Short: return lldb::eFormatDecimal;
- case clang::BuiltinType::UInt: return lldb::eFormatUnsigned;
- case clang::BuiltinType::Int: return lldb::eFormatDecimal;
- case clang::BuiltinType::ULong: return lldb::eFormatUnsigned;
- case clang::BuiltinType::Long: return lldb::eFormatDecimal;
- case clang::BuiltinType::ULongLong: return lldb::eFormatUnsigned;
- case clang::BuiltinType::LongLong: return lldb::eFormatDecimal;
- case clang::BuiltinType::UInt128: return lldb::eFormatUnsigned;
- case clang::BuiltinType::Int128: return lldb::eFormatDecimal;
- case clang::BuiltinType::Half:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble: return lldb::eFormatFloat;
- default:
- return lldb::eFormatHex;
- }
- break;
- case clang::Type::ObjCObjectPointer: return lldb::eFormatHex;
- case clang::Type::BlockPointer: return lldb::eFormatHex;
- case clang::Type::Pointer: return lldb::eFormatHex;
- case clang::Type::LValueReference:
- case clang::Type::RValueReference: return lldb::eFormatHex;
- case clang::Type::MemberPointer: break;
- case clang::Type::Complex:
- {
- if (qual_type->isComplexType())
- return lldb::eFormatComplex;
- else
- return lldb::eFormatComplexInteger;
- }
- case clang::Type::ObjCInterface: break;
- case clang::Type::Record: break;
- case clang::Type::Enum: return lldb::eFormatEnum;
- case clang::Type::Typedef:
- return CompilerType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetFormat();
- case clang::Type::Auto:
- return CompilerType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->desugar()).GetFormat();
- case clang::Type::Paren:
- return CompilerType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetFormat();
- case clang::Type::Elaborated:
- return CompilerType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetFormat();
- case clang::Type::DependentSizedArray:
- case clang::Type::DependentSizedExtVector:
- case clang::Type::UnresolvedUsing:
- case clang::Type::Attributed:
- case clang::Type::TemplateTypeParm:
- case clang::Type::SubstTemplateTypeParm:
- case clang::Type::SubstTemplateTypeParmPack:
- case clang::Type::InjectedClassName:
- case clang::Type::DependentName:
- case clang::Type::DependentTemplateSpecialization:
- case clang::Type::PackExpansion:
- case clang::Type::ObjCObject:
-
- case clang::Type::TypeOfExpr:
- case clang::Type::TypeOf:
- case clang::Type::Decltype:
- case clang::Type::TemplateSpecialization:
- case clang::Type::Atomic:
- case clang::Type::Adjusted:
- case clang::Type::Pipe:
- break;
-
- // pointer type decayed from an array or function type.
- case clang::Type::Decayed:
- break;
- }
- // We don't know hot to display this type...
- return lldb::eFormatBytes;
+ count = 1;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::UnaryTransform:
+ break;
+
+ case clang::Type::FunctionNoProto:
+ case clang::Type::FunctionProto:
+ break;
+
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ break;
+
+ case clang::Type::ConstantArray:
+ break;
+
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ // TODO: Set this to more than one???
+ break;
+
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ case clang::BuiltinType::Void:
+ break;
+
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ return lldb::eEncodingSint;
+
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Float128:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ return lldb::eEncodingIEEE754;
+
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCSel:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::NullPtr:
+ return lldb::eEncodingUint;
+
+ case clang::BuiltinType::Kind::ARCUnbridgedCast:
+ case clang::BuiltinType::Kind::BoundMember:
+ case clang::BuiltinType::Kind::BuiltinFn:
+ case clang::BuiltinType::Kind::Dependent:
+ case clang::BuiltinType::Kind::OCLClkEvent:
+ case clang::BuiltinType::Kind::OCLEvent:
+ case clang::BuiltinType::Kind::OCLImage1dRO:
+ case clang::BuiltinType::Kind::OCLImage1dWO:
+ case clang::BuiltinType::Kind::OCLImage1dRW:
+ case clang::BuiltinType::Kind::OCLImage1dArrayRO:
+ case clang::BuiltinType::Kind::OCLImage1dArrayWO:
+ case clang::BuiltinType::Kind::OCLImage1dArrayRW:
+ case clang::BuiltinType::Kind::OCLImage1dBufferRO:
+ case clang::BuiltinType::Kind::OCLImage1dBufferWO:
+ case clang::BuiltinType::Kind::OCLImage1dBufferRW:
+ case clang::BuiltinType::Kind::OCLImage2dRO:
+ case clang::BuiltinType::Kind::OCLImage2dWO:
+ case clang::BuiltinType::Kind::OCLImage2dRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayDepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAARO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAAWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAARW:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dArrayMSAADepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dDepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dDepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dDepthRW:
+ case clang::BuiltinType::Kind::OCLImage2dMSAARO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAAWO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAARW:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthRO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthWO:
+ case clang::BuiltinType::Kind::OCLImage2dMSAADepthRW:
+ case clang::BuiltinType::Kind::OCLImage3dRO:
+ case clang::BuiltinType::Kind::OCLImage3dWO:
+ case clang::BuiltinType::Kind::OCLImage3dRW:
+ case clang::BuiltinType::Kind::OCLQueue:
+ case clang::BuiltinType::Kind::OCLNDRange:
+ case clang::BuiltinType::Kind::OCLReserveID:
+ case clang::BuiltinType::Kind::OCLSampler:
+ case clang::BuiltinType::Kind::OMPArraySection:
+ case clang::BuiltinType::Kind::Overload:
+ case clang::BuiltinType::Kind::PseudoObject:
+ case clang::BuiltinType::Kind::UnknownAny:
+ break;
+ }
+ break;
+ // All pointer types are represented as unsigned integer encodings.
+ // We may nee to add a eEncodingPointer if we ever need to know the
+ // difference
+ case clang::Type::ObjCObjectPointer:
+ case clang::Type::BlockPointer:
+ case clang::Type::Pointer:
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ case clang::Type::MemberPointer:
+ return lldb::eEncodingUint;
+ case clang::Type::Complex: {
+ lldb::Encoding encoding = lldb::eEncodingIEEE754;
+ if (qual_type->isComplexType())
+ encoding = lldb::eEncodingIEEE754;
+ else {
+ const clang::ComplexType *complex_type =
+ qual_type->getAsComplexIntegerType();
+ if (complex_type)
+ encoding = CompilerType(getASTContext(), complex_type->getElementType())
+ .GetEncoding(count);
+ else
+ encoding = lldb::eEncodingSint;
+ }
+ count = 2;
+ return encoding;
+ }
+
+ case clang::Type::ObjCInterface:
+ break;
+ case clang::Type::Record:
+ break;
+ case clang::Type::Enum:
+ return lldb::eEncodingSint;
+ case clang::Type::Typedef:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetEncoding(count);
+
+ case clang::Type::Auto:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ .GetEncoding(count);
+
+ case clang::Type::Elaborated:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ .GetEncoding(count);
+
+ case clang::Type::Paren:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar())
+ .GetEncoding(count);
+
+ case clang::Type::DependentSizedArray:
+ case clang::Type::DependentSizedExtVector:
+ case clang::Type::UnresolvedUsing:
+ case clang::Type::Attributed:
+ case clang::Type::TemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParmPack:
+ case clang::Type::InjectedClassName:
+ case clang::Type::DependentName:
+ case clang::Type::DependentTemplateSpecialization:
+ case clang::Type::PackExpansion:
+ case clang::Type::ObjCObject:
+
+ case clang::Type::TypeOfExpr:
+ case clang::Type::TypeOf:
+ case clang::Type::Decltype:
+ case clang::Type::TemplateSpecialization:
+ case clang::Type::Atomic:
+ case clang::Type::Adjusted:
+ case clang::Type::Pipe:
+ break;
+
+ // pointer type decayed from an array or function type.
+ case clang::Type::Decayed:
+ break;
+ case clang::Type::ObjCTypeParam:
+ break;
+ }
+ count = 0;
+ return lldb::eEncodingInvalid;
+}
+
+lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return lldb::eFormatDefault;
+
+ clang::QualType qual_type(GetCanonicalQualType(type));
+
+ switch (qual_type->getTypeClass()) {
+ case clang::Type::UnaryTransform:
+ break;
+
+ case clang::Type::FunctionNoProto:
+ case clang::Type::FunctionProto:
+ break;
+
+ case clang::Type::IncompleteArray:
+ case clang::Type::VariableArray:
+ break;
+
+ case clang::Type::ConstantArray:
+ return lldb::eFormatVoid; // no value
+
+ case clang::Type::ExtVector:
+ case clang::Type::Vector:
+ break;
+
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ // default: assert(0 && "Unknown builtin type!");
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::Void:
+ case clang::BuiltinType::BoundMember:
+ break;
+
+ case clang::BuiltinType::Bool:
+ return lldb::eFormatBoolean;
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ return lldb::eFormatChar;
+ case clang::BuiltinType::Char16:
+ return lldb::eFormatUnicode16;
+ case clang::BuiltinType::Char32:
+ return lldb::eFormatUnicode32;
+ case clang::BuiltinType::UShort:
+ return lldb::eFormatUnsigned;
+ case clang::BuiltinType::Short:
+ return lldb::eFormatDecimal;
+ case clang::BuiltinType::UInt:
+ return lldb::eFormatUnsigned;
+ case clang::BuiltinType::Int:
+ return lldb::eFormatDecimal;
+ case clang::BuiltinType::ULong:
+ return lldb::eFormatUnsigned;
+ case clang::BuiltinType::Long:
+ return lldb::eFormatDecimal;
+ case clang::BuiltinType::ULongLong:
+ return lldb::eFormatUnsigned;
+ case clang::BuiltinType::LongLong:
+ return lldb::eFormatDecimal;
+ case clang::BuiltinType::UInt128:
+ return lldb::eFormatUnsigned;
+ case clang::BuiltinType::Int128:
+ return lldb::eFormatDecimal;
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ return lldb::eFormatFloat;
+ default:
+ return lldb::eFormatHex;
+ }
+ break;
+ case clang::Type::ObjCObjectPointer:
+ return lldb::eFormatHex;
+ case clang::Type::BlockPointer:
+ return lldb::eFormatHex;
+ case clang::Type::Pointer:
+ return lldb::eFormatHex;
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ return lldb::eFormatHex;
+ case clang::Type::MemberPointer:
+ break;
+ case clang::Type::Complex: {
+ if (qual_type->isComplexType())
+ return lldb::eFormatComplex;
+ else
+ return lldb::eFormatComplexInteger;
+ }
+ case clang::Type::ObjCInterface:
+ break;
+ case clang::Type::Record:
+ break;
+ case clang::Type::Enum:
+ return lldb::eFormatEnum;
+ case clang::Type::Typedef:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetFormat();
+ case clang::Type::Auto:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::AutoType>(qual_type)->desugar())
+ .GetFormat();
+ case clang::Type::Paren:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar())
+ .GetFormat();
+ case clang::Type::Elaborated:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ .GetFormat();
+ case clang::Type::DependentSizedArray:
+ case clang::Type::DependentSizedExtVector:
+ case clang::Type::UnresolvedUsing:
+ case clang::Type::Attributed:
+ case clang::Type::TemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParmPack:
+ case clang::Type::InjectedClassName:
+ case clang::Type::DependentName:
+ case clang::Type::DependentTemplateSpecialization:
+ case clang::Type::PackExpansion:
+ case clang::Type::ObjCObject:
+
+ case clang::Type::TypeOfExpr:
+ case clang::Type::TypeOf:
+ case clang::Type::Decltype:
+ case clang::Type::TemplateSpecialization:
+ case clang::Type::Atomic:
+ case clang::Type::Adjusted:
+ case clang::Type::Pipe:
+ break;
+
+ // pointer type decayed from an array or function type.
+ case clang::Type::Decayed:
+ break;
+ case clang::Type::ObjCTypeParam:
+ break;
+ }
+ // We don't know hot to display this type...
+ return lldb::eFormatBytes;
+}
+
+static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl,
+ bool check_superclass) {
+ while (class_interface_decl) {
+ if (class_interface_decl->ivar_size() > 0)
+ return true;
+
+ if (check_superclass)
+ class_interface_decl = class_interface_decl->getSuperClass();
+ else
+ break;
+ }
+ return false;
}
-static bool
-ObjCDeclHasIVars (clang::ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
-{
- while (class_interface_decl)
- {
- if (class_interface_decl->ivar_size() > 0)
- return true;
-
- if (check_superclass)
- class_interface_decl = class_interface_decl->getSuperClass();
- else
- break;
- }
- return false;
-}
+uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
+ bool omit_empty_base_classes) {
+ if (!type)
+ return 0;
-uint32_t
-ClangASTContext::GetNumChildren (lldb::opaque_compiler_type_t type, bool omit_empty_base_classes)
-{
- if (!type)
- return 0;
-
- uint32_t num_children = 0;
- clang::QualType qual_type(GetQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- case clang::BuiltinType::ObjCId: // child is Class
- case clang::BuiltinType::ObjCClass: // child is Class
- num_children = 1;
- break;
-
- default:
- break;
- }
- break;
-
- case clang::Type::Complex: return 0;
-
- case clang::Type::Record:
- if (GetCompleteQualType (getASTContext(), qual_type))
- {
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- assert(record_decl);
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
- {
- if (omit_empty_base_classes)
- {
- // Check each base classes to see if it or any of its
- // base classes contain any fields. This can help
- // limit the noise in variable views by not having to
- // show base classes that contain no members.
- clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
-
- // Skip empty base classes
- if (ClangASTContext::RecordHasFields(base_class_decl) == false)
- continue;
-
- num_children++;
- }
- }
- else
- {
- // Include all base classes
- num_children += cxx_record_decl->getNumBases();
- }
-
- }
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
- ++num_children;
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteQualType (getASTContext(), qual_type))
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
-
- clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
- {
- if (omit_empty_base_classes)
- {
- if (ObjCDeclHasIVars (superclass_interface_decl, true))
- ++num_children;
- }
- else
- ++num_children;
- }
-
- num_children += class_interface_decl->ivar_size();
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- {
- const clang::ObjCObjectPointerType *pointer_type = llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
- clang::QualType pointee_type = pointer_type->getPointeeType();
- uint32_t num_pointee_children = CompilerType (getASTContext(),pointee_type).GetNumChildren (omit_empty_base_classes);
- // If this type points to a simple type, then it has 1 child
- if (num_pointee_children == 0)
- num_children = 1;
- else
- num_children = num_pointee_children;
- }
- break;
-
- case clang::Type::Vector:
- case clang::Type::ExtVector:
- num_children = llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements();
- break;
-
- case clang::Type::ConstantArray:
- num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
- break;
-
- case clang::Type::Pointer:
- {
- const clang::PointerType *pointer_type = llvm::cast<clang::PointerType>(qual_type.getTypePtr());
- clang::QualType pointee_type (pointer_type->getPointeeType());
- uint32_t num_pointee_children = CompilerType (getASTContext(),pointee_type).GetNumChildren (omit_empty_base_classes);
- if (num_pointee_children == 0)
- {
- // We have a pointer to a pointee type that claims it has no children.
- // We will want to look at
- num_children = GetNumPointeeChildren (pointee_type);
- }
- else
- num_children = num_pointee_children;
- }
- break;
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
- clang::QualType pointee_type = reference_type->getPointeeType();
- uint32_t num_pointee_children = CompilerType (getASTContext(), pointee_type).GetNumChildren (omit_empty_base_classes);
- // If this type points to a simple type, then it has 1 child
- if (num_pointee_children == 0)
- num_children = 1;
- else
- num_children = num_pointee_children;
- }
- break;
-
-
- case clang::Type::Typedef:
- num_children = CompilerType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumChildren (omit_empty_base_classes);
- break;
+ uint32_t num_children = 0;
+ clang::QualType qual_type(GetQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ case clang::BuiltinType::ObjCId: // child is Class
+ case clang::BuiltinType::ObjCClass: // child is Class
+ num_children = 1;
+ break;
- case clang::Type::Auto:
- num_children = CompilerType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetNumChildren (omit_empty_base_classes);
- break;
-
- case clang::Type::Elaborated:
- num_children = CompilerType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumChildren (omit_empty_base_classes);
- break;
-
- case clang::Type::Paren:
- num_children = CompilerType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumChildren (omit_empty_base_classes);
- break;
- default:
- break;
+ default:
+ break;
}
- return num_children;
-}
+ break;
-CompilerType
-ClangASTContext::GetBuiltinTypeByName (const ConstString &name)
-{
- return GetBasicType(GetBasicTypeEnumeration(name));
-}
+ case clang::Type::Complex:
+ return 0;
-lldb::BasicType
-ClangASTContext::GetBasicTypeEnumeration (lldb::opaque_compiler_type_t type)
-{
- if (type)
- {
- clang::QualType qual_type(GetQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- if (type_class == clang::Type::Builtin)
- {
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- case clang::BuiltinType::Void: return eBasicTypeVoid;
- case clang::BuiltinType::Bool: return eBasicTypeBool;
- case clang::BuiltinType::Char_S: return eBasicTypeSignedChar;
- case clang::BuiltinType::Char_U: return eBasicTypeUnsignedChar;
- case clang::BuiltinType::Char16: return eBasicTypeChar16;
- case clang::BuiltinType::Char32: return eBasicTypeChar32;
- case clang::BuiltinType::UChar: return eBasicTypeUnsignedChar;
- case clang::BuiltinType::SChar: return eBasicTypeSignedChar;
- case clang::BuiltinType::WChar_S: return eBasicTypeSignedWChar;
- case clang::BuiltinType::WChar_U: return eBasicTypeUnsignedWChar;
- case clang::BuiltinType::Short: return eBasicTypeShort;
- case clang::BuiltinType::UShort: return eBasicTypeUnsignedShort;
- case clang::BuiltinType::Int: return eBasicTypeInt;
- case clang::BuiltinType::UInt: return eBasicTypeUnsignedInt;
- case clang::BuiltinType::Long: return eBasicTypeLong;
- case clang::BuiltinType::ULong: return eBasicTypeUnsignedLong;
- case clang::BuiltinType::LongLong: return eBasicTypeLongLong;
- case clang::BuiltinType::ULongLong: return eBasicTypeUnsignedLongLong;
- case clang::BuiltinType::Int128: return eBasicTypeInt128;
- case clang::BuiltinType::UInt128: return eBasicTypeUnsignedInt128;
-
- case clang::BuiltinType::Half: return eBasicTypeHalf;
- case clang::BuiltinType::Float: return eBasicTypeFloat;
- case clang::BuiltinType::Double: return eBasicTypeDouble;
- case clang::BuiltinType::LongDouble:return eBasicTypeLongDouble;
-
- case clang::BuiltinType::NullPtr: return eBasicTypeNullPtr;
- case clang::BuiltinType::ObjCId: return eBasicTypeObjCID;
- case clang::BuiltinType::ObjCClass: return eBasicTypeObjCClass;
- case clang::BuiltinType::ObjCSel: return eBasicTypeObjCSel;
- default:
- return eBasicTypeOther;
- }
+ case clang::Type::Record:
+ if (GetCompleteQualType(getASTContext(), qual_type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl) {
+ if (omit_empty_base_classes) {
+ // Check each base classes to see if it or any of its
+ // base classes contain any fields. This can help
+ // limit the noise in variable views by not having to
+ // show base classes that contain no members.
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ const clang::CXXRecordDecl *base_class_decl =
+ llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()
+ ->getAs<clang::RecordType>()
+ ->getDecl());
+
+ // Skip empty base classes
+ if (ClangASTContext::RecordHasFields(base_class_decl) == false)
+ continue;
+
+ num_children++;
+ }
+ } else {
+ // Include all base classes
+ num_children += cxx_record_decl->getNumBases();
}
- }
- return eBasicTypeInvalid;
-}
-
-void
-ClangASTContext::ForEachEnumerator (lldb::opaque_compiler_type_t type, std::function <bool (const CompilerType &integer_type, const ConstString &name, const llvm::APSInt &value)> const &callback)
-{
- const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
- if (enum_type)
- {
- const clang::EnumDecl *enum_decl = enum_type->getDecl();
- if (enum_decl)
- {
- CompilerType integer_type(this, enum_decl->getIntegerType().getAsOpaquePtr());
-
- clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
- for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
- {
- ConstString name(enum_pos->getNameAsString().c_str());
- if (!callback (integer_type, name, enum_pos->getInitVal()))
- break;
- }
+ }
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field)
+ ++num_children;
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteQualType(getASTContext(), qual_type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+ if (superclass_interface_decl) {
+ if (omit_empty_base_classes) {
+ if (ObjCDeclHasIVars(superclass_interface_decl, true))
+ ++num_children;
+ } else
+ ++num_children;
+ }
+
+ num_children += class_interface_decl->ivar_size();
}
- }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ const clang::ObjCObjectPointerType *pointer_type =
+ llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
+ clang::QualType pointee_type = pointer_type->getPointeeType();
+ uint32_t num_pointee_children =
+ CompilerType(getASTContext(), pointee_type)
+ .GetNumChildren(omit_empty_base_classes);
+ // If this type points to a simple type, then it has 1 child
+ if (num_pointee_children == 0)
+ num_children = 1;
+ else
+ num_children = num_pointee_children;
+ } break;
+
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ num_children =
+ llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements();
+ break;
+
+ case clang::Type::ConstantArray:
+ num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr())
+ ->getSize()
+ .getLimitedValue();
+ break;
+
+ case clang::Type::Pointer: {
+ const clang::PointerType *pointer_type =
+ llvm::cast<clang::PointerType>(qual_type.getTypePtr());
+ clang::QualType pointee_type(pointer_type->getPointeeType());
+ uint32_t num_pointee_children =
+ CompilerType(getASTContext(), pointee_type)
+ .GetNumChildren(omit_empty_base_classes);
+ if (num_pointee_children == 0) {
+ // We have a pointer to a pointee type that claims it has no children.
+ // We will want to look at
+ num_children = GetNumPointeeChildren(pointee_type);
+ } else
+ num_children = num_pointee_children;
+ } break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ clang::QualType pointee_type = reference_type->getPointeeType();
+ uint32_t num_pointee_children =
+ CompilerType(getASTContext(), pointee_type)
+ .GetNumChildren(omit_empty_base_classes);
+ // If this type points to a simple type, then it has 1 child
+ if (num_pointee_children == 0)
+ num_children = 1;
+ else
+ num_children = num_pointee_children;
+ } break;
+
+ case clang::Type::Typedef:
+ num_children =
+ CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetNumChildren(omit_empty_base_classes);
+ break;
+
+ case clang::Type::Auto:
+ num_children =
+ CompilerType(getASTContext(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ .GetNumChildren(omit_empty_base_classes);
+ break;
+
+ case clang::Type::Elaborated:
+ num_children =
+ CompilerType(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ .GetNumChildren(omit_empty_base_classes);
+ break;
+
+ case clang::Type::Paren:
+ num_children =
+ CompilerType(getASTContext(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar())
+ .GetNumChildren(omit_empty_base_classes);
+ break;
+ default:
+ break;
+ }
+ return num_children;
+}
+
+CompilerType ClangASTContext::GetBuiltinTypeByName(const ConstString &name) {
+ return GetBasicType(GetBasicTypeEnumeration(name));
}
+lldb::BasicType
+ClangASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ if (type_class == clang::Type::Builtin) {
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ case clang::BuiltinType::Void:
+ return eBasicTypeVoid;
+ case clang::BuiltinType::Bool:
+ return eBasicTypeBool;
+ case clang::BuiltinType::Char_S:
+ return eBasicTypeSignedChar;
+ case clang::BuiltinType::Char_U:
+ return eBasicTypeUnsignedChar;
+ case clang::BuiltinType::Char16:
+ return eBasicTypeChar16;
+ case clang::BuiltinType::Char32:
+ return eBasicTypeChar32;
+ case clang::BuiltinType::UChar:
+ return eBasicTypeUnsignedChar;
+ case clang::BuiltinType::SChar:
+ return eBasicTypeSignedChar;
+ case clang::BuiltinType::WChar_S:
+ return eBasicTypeSignedWChar;
+ case clang::BuiltinType::WChar_U:
+ return eBasicTypeUnsignedWChar;
+ case clang::BuiltinType::Short:
+ return eBasicTypeShort;
+ case clang::BuiltinType::UShort:
+ return eBasicTypeUnsignedShort;
+ case clang::BuiltinType::Int:
+ return eBasicTypeInt;
+ case clang::BuiltinType::UInt:
+ return eBasicTypeUnsignedInt;
+ case clang::BuiltinType::Long:
+ return eBasicTypeLong;
+ case clang::BuiltinType::ULong:
+ return eBasicTypeUnsignedLong;
+ case clang::BuiltinType::LongLong:
+ return eBasicTypeLongLong;
+ case clang::BuiltinType::ULongLong:
+ return eBasicTypeUnsignedLongLong;
+ case clang::BuiltinType::Int128:
+ return eBasicTypeInt128;
+ case clang::BuiltinType::UInt128:
+ return eBasicTypeUnsignedInt128;
+
+ case clang::BuiltinType::Half:
+ return eBasicTypeHalf;
+ case clang::BuiltinType::Float:
+ return eBasicTypeFloat;
+ case clang::BuiltinType::Double:
+ return eBasicTypeDouble;
+ case clang::BuiltinType::LongDouble:
+ return eBasicTypeLongDouble;
+
+ case clang::BuiltinType::NullPtr:
+ return eBasicTypeNullPtr;
+ case clang::BuiltinType::ObjCId:
+ return eBasicTypeObjCID;
+ case clang::BuiltinType::ObjCClass:
+ return eBasicTypeObjCClass;
+ case clang::BuiltinType::ObjCSel:
+ return eBasicTypeObjCSel;
+ default:
+ return eBasicTypeOther;
+ }
+ }
+ }
+ return eBasicTypeInvalid;
+}
+
+void ClangASTContext::ForEachEnumerator(
+ lldb::opaque_compiler_type_t type,
+ std::function<bool(const CompilerType &integer_type,
+ const ConstString &name,
+ const llvm::APSInt &value)> const &callback) {
+ const clang::EnumType *enum_type =
+ llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type));
+ if (enum_type) {
+ const clang::EnumDecl *enum_decl = enum_type->getDecl();
+ if (enum_decl) {
+ CompilerType integer_type(this,
+ enum_decl->getIntegerType().getAsOpaquePtr());
+
+ clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
+ for (enum_pos = enum_decl->enumerator_begin(),
+ enum_end_pos = enum_decl->enumerator_end();
+ enum_pos != enum_end_pos; ++enum_pos) {
+ ConstString name(enum_pos->getNameAsString().c_str());
+ if (!callback(integer_type, name, enum_pos->getInitVal()))
+ break;
+ }
+ }
+ }
+}
#pragma mark Aggregate Types
-uint32_t
-ClangASTContext::GetNumFields (lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return 0;
-
- uint32_t count = 0;
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
- if (record_type)
- {
- clang::RecordDecl *record_decl = record_type->getDecl();
- if (record_decl)
- {
- uint32_t field_idx = 0;
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
- ++field_idx;
- count = field_idx;
- }
- }
- }
- break;
-
- case clang::Type::Typedef:
- count = CompilerType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumFields();
- break;
+uint32_t ClangASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return 0;
- case clang::Type::Auto:
- count = CompilerType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetNumFields();
- break;
-
- case clang::Type::Elaborated:
- count = CompilerType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumFields();
- break;
-
- case clang::Type::Paren:
- count = CompilerType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumFields();
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (GetCompleteType(type))
- {
- const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
-
- if (class_interface_decl)
- count = class_interface_decl->ivar_size();
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteType(type))
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- count = class_interface_decl->ivar_size();
- }
- }
- break;
-
- default:
- break;
+ uint32_t count = 0;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
+ if (record_type) {
+ clang::RecordDecl *record_decl = record_type->getDecl();
+ if (record_decl) {
+ uint32_t field_idx = 0;
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field)
+ ++field_idx;
+ count = field_idx;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ count =
+ CompilerType(getASTContext(), llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetNumFields();
+ break;
+
+ case clang::Type::Auto:
+ count =
+ CompilerType(getASTContext(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ .GetNumFields();
+ break;
+
+ case clang::Type::Elaborated:
+ count = CompilerType(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ .GetNumFields();
+ break;
+
+ case clang::Type::Paren:
+ count = CompilerType(getASTContext(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar())
+ .GetNumFields();
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ const clang::ObjCObjectPointerType *objc_class_type =
+ qual_type->getAsObjCInterfacePointerType();
+ const clang::ObjCInterfaceType *objc_interface_type =
+ objc_class_type->getInterfaceType();
+ if (objc_interface_type &&
+ GetCompleteType((lldb::opaque_compiler_type_t)objc_interface_type)) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getDecl();
+ if (class_interface_decl) {
+ count = class_interface_decl->ivar_size();
+ }
+ }
+ break;
+ }
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl)
+ count = class_interface_decl->ivar_size();
+ }
}
- return count;
+ break;
+
+ default:
+ break;
+ }
+ return count;
}
static lldb::opaque_compiler_type_t
-GetObjCFieldAtIndex (clang::ASTContext *ast,
- clang::ObjCInterfaceDecl *class_interface_decl,
- size_t idx,
- std::string& name,
- uint64_t *bit_offset_ptr,
- uint32_t *bitfield_bit_size_ptr,
- bool *is_bitfield_ptr)
-{
- if (class_interface_decl)
- {
- if (idx < (class_interface_decl->ivar_size()))
- {
- clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
- uint32_t ivar_idx = 0;
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx)
- {
- if (ivar_idx == idx)
- {
- const clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
-
- clang::QualType ivar_qual_type(ivar_decl->getType());
-
- name.assign(ivar_decl->getNameAsString());
-
- if (bit_offset_ptr)
- {
- const clang::ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
- *bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx);
- }
-
- const bool is_bitfield = ivar_pos->isBitField();
-
- if (bitfield_bit_size_ptr)
- {
- *bitfield_bit_size_ptr = 0;
-
- if (is_bitfield && ast)
- {
- clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
- llvm::APSInt bitfield_apsint;
- if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
- {
- *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
- }
- }
- }
- if (is_bitfield_ptr)
- *is_bitfield_ptr = is_bitfield;
-
- return ivar_qual_type.getAsOpaquePtr();
- }
+GetObjCFieldAtIndex(clang::ASTContext *ast,
+ clang::ObjCInterfaceDecl *class_interface_decl, size_t idx,
+ std::string &name, uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) {
+ if (class_interface_decl) {
+ if (idx < (class_interface_decl->ivar_size())) {
+ clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
+ ivar_end = class_interface_decl->ivar_end();
+ uint32_t ivar_idx = 0;
+
+ for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end;
+ ++ivar_pos, ++ivar_idx) {
+ if (ivar_idx == idx) {
+ const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
+
+ clang::QualType ivar_qual_type(ivar_decl->getType());
+
+ name.assign(ivar_decl->getNameAsString());
+
+ if (bit_offset_ptr) {
+ const clang::ASTRecordLayout &interface_layout =
+ ast->getASTObjCInterfaceLayout(class_interface_decl);
+ *bit_offset_ptr = interface_layout.getFieldOffset(ivar_idx);
+ }
+
+ const bool is_bitfield = ivar_pos->isBitField();
+
+ if (bitfield_bit_size_ptr) {
+ *bitfield_bit_size_ptr = 0;
+
+ if (is_bitfield && ast) {
+ clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
+ llvm::APSInt bitfield_apsint;
+ if (bitfield_bit_size_expr &&
+ bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint,
+ *ast)) {
+ *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+ }
}
+ }
+ if (is_bitfield_ptr)
+ *is_bitfield_ptr = is_bitfield;
+
+ return ivar_qual_type.getAsOpaquePtr();
}
+ }
}
- return nullptr;
+ }
+ return nullptr;
}
-CompilerType
-ClangASTContext::GetFieldAtIndex (lldb::opaque_compiler_type_t type, size_t idx,
- std::string& name,
- uint64_t *bit_offset_ptr,
- uint32_t *bitfield_bit_size_ptr,
- bool *is_bitfield_ptr)
-{
- if (!type)
- return CompilerType();
-
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- uint32_t field_idx = 0;
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
- {
- if (idx == field_idx)
- {
- // Print the member type if requested
- // Print the member name and equal sign
- name.assign(field->getNameAsString());
-
- // Figure out the type byte size (field_type_info.first) and
- // alignment (field_type_info.second) from the AST context.
- if (bit_offset_ptr)
- {
- const clang::ASTRecordLayout &record_layout = getASTContext()->getASTRecordLayout(record_decl);
- *bit_offset_ptr = record_layout.getFieldOffset (field_idx);
- }
-
- const bool is_bitfield = field->isBitField();
-
- if (bitfield_bit_size_ptr)
- {
- *bitfield_bit_size_ptr = 0;
-
- if (is_bitfield)
- {
- clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
- llvm::APSInt bitfield_apsint;
- if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *getASTContext()))
- {
- *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
- }
- }
- }
- if (is_bitfield_ptr)
- *is_bitfield_ptr = is_bitfield;
-
- return CompilerType (getASTContext(), field->getType());
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (GetCompleteType(type))
- {
- const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
- return CompilerType (this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteType(type))
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- return CompilerType (this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
- }
- }
- break;
-
-
- case clang::Type::Typedef:
- return CompilerType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).
- GetFieldAtIndex (idx,
- name,
- bit_offset_ptr,
- bitfield_bit_size_ptr,
- is_bitfield_ptr);
-
- case clang::Type::Auto:
- return CompilerType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).
- GetFieldAtIndex (idx,
- name,
- bit_offset_ptr,
- bitfield_bit_size_ptr,
- is_bitfield_ptr);
-
- case clang::Type::Elaborated:
- return CompilerType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).
- GetFieldAtIndex (idx,
- name,
- bit_offset_ptr,
- bitfield_bit_size_ptr,
- is_bitfield_ptr);
-
- case clang::Type::Paren:
- return CompilerType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).
- GetFieldAtIndex (idx,
- name,
- bit_offset_ptr,
- bitfield_bit_size_ptr,
- is_bitfield_ptr);
-
- default:
- break;
- }
+CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
+ size_t idx, std::string &name,
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr) {
+ if (!type)
return CompilerType();
-}
-uint32_t
-ClangASTContext::GetNumDirectBaseClasses (lldb::opaque_compiler_type_t type)
-{
- uint32_t count = 0;
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- count = cxx_record_decl->getNumBases();
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ uint32_t field_idx = 0;
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field, ++field_idx) {
+ if (idx == field_idx) {
+ // Print the member type if requested
+ // Print the member name and equal sign
+ name.assign(field->getNameAsString());
+
+ // Figure out the type byte size (field_type_info.first) and
+ // alignment (field_type_info.second) from the AST context.
+ if (bit_offset_ptr) {
+ const clang::ASTRecordLayout &record_layout =
+ getASTContext()->getASTRecordLayout(record_decl);
+ *bit_offset_ptr = record_layout.getFieldOffset(field_idx);
+ }
+
+ const bool is_bitfield = field->isBitField();
+
+ if (bitfield_bit_size_ptr) {
+ *bitfield_bit_size_ptr = 0;
+
+ if (is_bitfield) {
+ clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
+ llvm::APSInt bitfield_apsint;
+ if (bitfield_bit_size_expr &&
+ bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint,
+ *getASTContext())) {
+ *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+ }
}
- break;
-
- case clang::Type::ObjCObjectPointer:
- count = GetPointeeType(type).GetNumDirectBaseClasses();
- break;
-
- case clang::Type::ObjCObject:
- if (GetCompleteType(type))
- {
- const clang::ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl && class_interface_decl->getSuperClass())
- count = 1;
- }
- }
- break;
- case clang::Type::ObjCInterface:
- if (GetCompleteType(type))
- {
- const clang::ObjCInterfaceType *objc_interface_type = qual_type->getAs<clang::ObjCInterfaceType>();
- if (objc_interface_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
-
- if (class_interface_decl && class_interface_decl->getSuperClass())
- count = 1;
- }
- }
- break;
-
-
- case clang::Type::Typedef:
- count = GetNumDirectBaseClasses(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- break;
-
- case clang::Type::Auto:
- count = GetNumDirectBaseClasses(llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr());
- break;
-
- case clang::Type::Elaborated:
- count = GetNumDirectBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- break;
-
- case clang::Type::Paren:
- return GetNumDirectBaseClasses(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
-
- default:
- break;
- }
- return count;
+ }
+ if (is_bitfield_ptr)
+ *is_bitfield_ptr = is_bitfield;
+ return CompilerType(getASTContext(), field->getType());
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ const clang::ObjCObjectPointerType *objc_class_type =
+ qual_type->getAsObjCInterfacePointerType();
+ const clang::ObjCInterfaceType *objc_interface_type =
+ objc_class_type->getInterfaceType();
+ if (objc_interface_type &&
+ GetCompleteType((lldb::opaque_compiler_type_t)objc_interface_type)) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getDecl();
+ if (class_interface_decl) {
+ return CompilerType(
+ this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl,
+ idx, name, bit_offset_ptr,
+ bitfield_bit_size_ptr, is_bitfield_ptr));
+ }
+ }
+ break;
+ }
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+ return CompilerType(
+ this, GetObjCFieldAtIndex(getASTContext(), class_interface_decl,
+ idx, name, bit_offset_ptr,
+ bitfield_bit_size_ptr, is_bitfield_ptr));
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
+ is_bitfield_ptr);
+
+ case clang::Type::Auto:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
+ is_bitfield_ptr);
+
+ case clang::Type::Elaborated:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
+ is_bitfield_ptr);
+
+ case clang::Type::Paren:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar())
+ .GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr,
+ is_bitfield_ptr);
+
+ default:
+ break;
+ }
+ return CompilerType();
}
uint32_t
-ClangASTContext::GetNumVirtualBaseClasses (lldb::opaque_compiler_type_t type)
-{
- uint32_t count = 0;
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- count = cxx_record_decl->getNumVBases();
- }
- break;
-
- case clang::Type::Typedef:
- count = GetNumVirtualBaseClasses(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
- break;
-
- case clang::Type::Auto:
- count = GetNumVirtualBaseClasses(llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr());
- break;
-
- case clang::Type::Elaborated:
- count = GetNumVirtualBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
- break;
-
- case clang::Type::Paren:
- count = GetNumVirtualBaseClasses(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
- break;
-
- default:
- break;
- }
- return count;
-
+ClangASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) {
+ uint32_t count = 0;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ count = cxx_record_decl->getNumBases();
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ count = GetPointeeType(type).GetNumDirectBaseClasses();
+ break;
+
+ case clang::Type::ObjCObject:
+ if (GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ qual_type->getAsObjCQualifiedInterfaceType();
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl && class_interface_decl->getSuperClass())
+ count = 1;
+ }
+ }
+ break;
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ const clang::ObjCInterfaceType *objc_interface_type =
+ qual_type->getAs<clang::ObjCInterfaceType>();
+ if (objc_interface_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getInterface();
+
+ if (class_interface_decl && class_interface_decl->getSuperClass())
+ count = 1;
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ count = GetNumDirectBaseClasses(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr());
+ break;
+
+ case clang::Type::Auto:
+ count = GetNumDirectBaseClasses(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr());
+ break;
+
+ case clang::Type::Elaborated:
+ count = GetNumDirectBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr());
+ break;
+
+ case clang::Type::Paren:
+ return GetNumDirectBaseClasses(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+
+ default:
+ break;
+ }
+ return count;
}
-CompilerType
-ClangASTContext::GetDirectBaseClassAtIndex (lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr)
-{
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- uint32_t curr_idx = 0;
- clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class, ++curr_idx)
- {
- if (curr_idx == idx)
- {
- if (bit_offset_ptr)
- {
- const clang::ASTRecordLayout &record_layout = getASTContext()->getASTRecordLayout(cxx_record_decl);
- const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
- if (base_class->isVirtual())
- *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
- else
- *bit_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
- }
- return CompilerType (this, base_class->getType().getAsOpaquePtr());
- }
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr);
-
- case clang::Type::ObjCObject:
- if (idx == 0 && GetCompleteType(type))
- {
- const clang::ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
- if (objc_class_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
- clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
- {
- if (bit_offset_ptr)
- *bit_offset_ptr = 0;
- return CompilerType (getASTContext(), getASTContext()->getObjCInterfaceType(superclass_interface_decl));
- }
- }
- }
+uint32_t
+ClangASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) {
+ uint32_t count = 0;
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ count = cxx_record_decl->getNumVBases();
+ }
+ break;
+
+ case clang::Type::Typedef:
+ count = GetNumVirtualBaseClasses(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr());
+ break;
+
+ case clang::Type::Auto:
+ count = GetNumVirtualBaseClasses(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr());
+ break;
+
+ case clang::Type::Elaborated:
+ count =
+ GetNumVirtualBaseClasses(llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr());
+ break;
+
+ case clang::Type::Paren:
+ count = GetNumVirtualBaseClasses(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr());
+ break;
+
+ default:
+ break;
+ }
+ return count;
+}
+
+CompilerType ClangASTContext::GetDirectBaseClassAtIndex(
+ lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ uint32_t curr_idx = 0;
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class, ++curr_idx) {
+ if (curr_idx == idx) {
+ if (bit_offset_ptr) {
+ const clang::ASTRecordLayout &record_layout =
+ getASTContext()->getASTRecordLayout(cxx_record_decl);
+ const clang::CXXRecordDecl *base_class_decl =
+ llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()
+ ->getAs<clang::RecordType>()
+ ->getDecl());
+ if (base_class->isVirtual())
+ *bit_offset_ptr =
+ record_layout.getVBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
+ else
+ *bit_offset_ptr =
+ record_layout.getBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
}
- break;
- case clang::Type::ObjCInterface:
- if (idx == 0 && GetCompleteType(type))
- {
- const clang::ObjCObjectType *objc_interface_type = qual_type->getAs<clang::ObjCInterfaceType>();
- if (objc_interface_type)
- {
- clang::ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
-
- if (class_interface_decl)
- {
- clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
- {
- if (bit_offset_ptr)
- *bit_offset_ptr = 0;
- return CompilerType (getASTContext(), getASTContext()->getObjCInterfaceType(superclass_interface_decl));
- }
- }
- }
+ return CompilerType(this, base_class->getType().getAsOpaquePtr());
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ return GetPointeeType(type).GetDirectBaseClassAtIndex(idx, bit_offset_ptr);
+
+ case clang::Type::ObjCObject:
+ if (idx == 0 && GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ qual_type->getAsObjCQualifiedInterfaceType();
+ if (objc_class_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+ if (superclass_interface_decl) {
+ if (bit_offset_ptr)
+ *bit_offset_ptr = 0;
+ return CompilerType(getASTContext(),
+ getASTContext()->getObjCInterfaceType(
+ superclass_interface_decl));
+ }
+ }
+ }
+ }
+ break;
+ case clang::Type::ObjCInterface:
+ if (idx == 0 && GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_interface_type =
+ qual_type->getAs<clang::ObjCInterfaceType>();
+ if (objc_interface_type) {
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_interface_type->getInterface();
+
+ if (class_interface_decl) {
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+ if (superclass_interface_decl) {
+ if (bit_offset_ptr)
+ *bit_offset_ptr = 0;
+ return CompilerType(getASTContext(),
+ getASTContext()->getObjCInterfaceType(
+ superclass_interface_decl));
+ }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return GetDirectBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ idx, bit_offset_ptr);
+
+ case clang::Type::Auto:
+ return GetDirectBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ idx, bit_offset_ptr);
+
+ case clang::Type::Elaborated:
+ return GetDirectBaseClassAtIndex(
+ llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ idx, bit_offset_ptr);
+
+ case clang::Type::Paren:
+ return GetDirectBaseClassAtIndex(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ idx, bit_offset_ptr);
+
+ default:
+ break;
+ }
+ return CompilerType();
+}
+
+CompilerType ClangASTContext::GetVirtualBaseClassAtIndex(
+ lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::CXXRecordDecl *cxx_record_decl =
+ qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl) {
+ uint32_t curr_idx = 0;
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->vbases_begin(),
+ base_class_end = cxx_record_decl->vbases_end();
+ base_class != base_class_end; ++base_class, ++curr_idx) {
+ if (curr_idx == idx) {
+ if (bit_offset_ptr) {
+ const clang::ASTRecordLayout &record_layout =
+ getASTContext()->getASTRecordLayout(cxx_record_decl);
+ const clang::CXXRecordDecl *base_class_decl =
+ llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()
+ ->getAs<clang::RecordType>()
+ ->getDecl());
+ *bit_offset_ptr =
+ record_layout.getVBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
}
- break;
-
-
- case clang::Type::Typedef:
- return GetDirectBaseClassAtIndex (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), idx, bit_offset_ptr);
-
- case clang::Type::Auto:
- return GetDirectBaseClassAtIndex (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), idx, bit_offset_ptr);
-
- case clang::Type::Elaborated:
- return GetDirectBaseClassAtIndex (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), idx, bit_offset_ptr);
-
- case clang::Type::Paren:
- return GetDirectBaseClassAtIndex (llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx, bit_offset_ptr);
-
- default:
- break;
+ return CompilerType(this, base_class->getType().getAsOpaquePtr());
+ }
+ }
+ }
}
- return CompilerType();
-}
+ break;
-CompilerType
-ClangASTContext::GetVirtualBaseClassAtIndex (lldb::opaque_compiler_type_t type,
- size_t idx,
- uint32_t *bit_offset_ptr)
-{
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- uint32_t curr_idx = 0;
- clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end();
- base_class != base_class_end;
- ++base_class, ++curr_idx)
- {
- if (curr_idx == idx)
- {
- if (bit_offset_ptr)
- {
- const clang::ASTRecordLayout &record_layout = getASTContext()->getASTRecordLayout(cxx_record_decl);
- const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
- *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+ case clang::Type::Typedef:
+ return GetVirtualBaseClassAtIndex(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType()
+ .getAsOpaquePtr(),
+ idx, bit_offset_ptr);
- }
- return CompilerType (this, base_class->getType().getAsOpaquePtr());
- }
- }
- }
- }
- break;
+ case clang::Type::Auto:
+ return GetVirtualBaseClassAtIndex(llvm::cast<clang::AutoType>(qual_type)
+ ->getDeducedType()
+ .getAsOpaquePtr(),
+ idx, bit_offset_ptr);
- case clang::Type::Typedef:
- return GetVirtualBaseClassAtIndex (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), idx, bit_offset_ptr);
-
- case clang::Type::Auto:
- return GetVirtualBaseClassAtIndex (llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr(), idx, bit_offset_ptr);
-
- case clang::Type::Elaborated:
- return GetVirtualBaseClassAtIndex (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), idx, bit_offset_ptr);
+ case clang::Type::Elaborated:
+ return GetVirtualBaseClassAtIndex(
+ llvm::cast<clang::ElaboratedType>(qual_type)
+ ->getNamedType()
+ .getAsOpaquePtr(),
+ idx, bit_offset_ptr);
- case clang::Type::Paren:
- return GetVirtualBaseClassAtIndex(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), idx,
- bit_offset_ptr);
-
- default:
- break;
- }
- return CompilerType();
+ case clang::Type::Paren:
+ return GetVirtualBaseClassAtIndex(
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
+ idx, bit_offset_ptr);
+ default:
+ break;
+ }
+ return CompilerType();
}
// If a pointer to a pointee type (the clang_type arg) says that it has no
@@ -5969,776 +6181,754 @@ ClangASTContext::GetVirtualBaseClassAtIndex (lldb::opaque_compiler_type_t type,
// different result. For example, an "int *" has one child that is an integer,
// but a function pointer doesn't have any children. Likewise if a Record type
// claims it has no children, then there really is nothing to show.
-uint32_t
-ClangASTContext::GetNumPointeeChildren (clang::QualType type)
-{
- if (type.isNull())
- return 0;
-
- clang::QualType qual_type(type.getCanonicalType());
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Builtin:
- switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
- {
- case clang::BuiltinType::UnknownAny:
- case clang::BuiltinType::Void:
- case clang::BuiltinType::NullPtr:
- case clang::BuiltinType::OCLEvent:
- case clang::BuiltinType::OCLImage1dRO:
- case clang::BuiltinType::OCLImage1dWO:
- case clang::BuiltinType::OCLImage1dRW:
- case clang::BuiltinType::OCLImage1dArrayRO:
- case clang::BuiltinType::OCLImage1dArrayWO:
- case clang::BuiltinType::OCLImage1dArrayRW:
- case clang::BuiltinType::OCLImage1dBufferRO:
- case clang::BuiltinType::OCLImage1dBufferWO:
- case clang::BuiltinType::OCLImage1dBufferRW:
- case clang::BuiltinType::OCLImage2dRO:
- case clang::BuiltinType::OCLImage2dWO:
- case clang::BuiltinType::OCLImage2dRW:
- case clang::BuiltinType::OCLImage2dArrayRO:
- case clang::BuiltinType::OCLImage2dArrayWO:
- case clang::BuiltinType::OCLImage2dArrayRW:
- case clang::BuiltinType::OCLImage3dRO:
- case clang::BuiltinType::OCLImage3dWO:
- case clang::BuiltinType::OCLImage3dRW:
- case clang::BuiltinType::OCLSampler:
- return 0;
- case clang::BuiltinType::Bool:
- case clang::BuiltinType::Char_U:
- case clang::BuiltinType::UChar:
- case clang::BuiltinType::WChar_U:
- case clang::BuiltinType::Char16:
- case clang::BuiltinType::Char32:
- case clang::BuiltinType::UShort:
- case clang::BuiltinType::UInt:
- case clang::BuiltinType::ULong:
- case clang::BuiltinType::ULongLong:
- case clang::BuiltinType::UInt128:
- case clang::BuiltinType::Char_S:
- case clang::BuiltinType::SChar:
- case clang::BuiltinType::WChar_S:
- case clang::BuiltinType::Short:
- case clang::BuiltinType::Int:
- case clang::BuiltinType::Long:
- case clang::BuiltinType::LongLong:
- case clang::BuiltinType::Int128:
- case clang::BuiltinType::Float:
- case clang::BuiltinType::Double:
- case clang::BuiltinType::LongDouble:
- case clang::BuiltinType::Dependent:
- case clang::BuiltinType::Overload:
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- case clang::BuiltinType::ObjCSel:
- case clang::BuiltinType::BoundMember:
- case clang::BuiltinType::Half:
- case clang::BuiltinType::ARCUnbridgedCast:
- case clang::BuiltinType::PseudoObject:
- case clang::BuiltinType::BuiltinFn:
- case clang::BuiltinType::OMPArraySection:
- return 1;
- default:
- return 0;
- }
- break;
-
- case clang::Type::Complex: return 1;
- case clang::Type::Pointer: return 1;
- case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
- case clang::Type::LValueReference: return 1;
- case clang::Type::RValueReference: return 1;
- case clang::Type::MemberPointer: return 0;
- case clang::Type::ConstantArray: return 0;
- case clang::Type::IncompleteArray: return 0;
- case clang::Type::VariableArray: return 0;
- case clang::Type::DependentSizedArray: return 0;
- case clang::Type::DependentSizedExtVector: return 0;
- case clang::Type::Vector: return 0;
- case clang::Type::ExtVector: return 0;
- case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
- case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
- case clang::Type::UnresolvedUsing: return 0;
- case clang::Type::Paren: return GetNumPointeeChildren (llvm::cast<clang::ParenType>(qual_type)->desugar());
- case clang::Type::Typedef: return GetNumPointeeChildren (llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType());
- case clang::Type::Auto: return GetNumPointeeChildren (llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
- case clang::Type::Elaborated: return GetNumPointeeChildren (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
- case clang::Type::TypeOfExpr: return 0;
- case clang::Type::TypeOf: return 0;
- case clang::Type::Decltype: return 0;
- case clang::Type::Record: return 0;
- case clang::Type::Enum: return 1;
- case clang::Type::TemplateTypeParm: return 1;
- case clang::Type::SubstTemplateTypeParm: return 1;
- case clang::Type::TemplateSpecialization: return 1;
- case clang::Type::InjectedClassName: return 0;
- case clang::Type::DependentName: return 1;
- case clang::Type::DependentTemplateSpecialization: return 1;
- case clang::Type::ObjCObject: return 0;
- case clang::Type::ObjCInterface: return 0;
- case clang::Type::ObjCObjectPointer: return 1;
- default:
- break;
- }
+uint32_t ClangASTContext::GetNumPointeeChildren(clang::QualType type) {
+ if (type.isNull())
return 0;
-}
+ clang::QualType qual_type(type.getCanonicalType());
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Builtin:
+ switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind()) {
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::Void:
+ case clang::BuiltinType::NullPtr:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLImage1dRO:
+ case clang::BuiltinType::OCLImage1dWO:
+ case clang::BuiltinType::OCLImage1dRW:
+ case clang::BuiltinType::OCLImage1dArrayRO:
+ case clang::BuiltinType::OCLImage1dArrayWO:
+ case clang::BuiltinType::OCLImage1dArrayRW:
+ case clang::BuiltinType::OCLImage1dBufferRO:
+ case clang::BuiltinType::OCLImage1dBufferWO:
+ case clang::BuiltinType::OCLImage1dBufferRW:
+ case clang::BuiltinType::OCLImage2dRO:
+ case clang::BuiltinType::OCLImage2dWO:
+ case clang::BuiltinType::OCLImage2dRW:
+ case clang::BuiltinType::OCLImage2dArrayRO:
+ case clang::BuiltinType::OCLImage2dArrayWO:
+ case clang::BuiltinType::OCLImage2dArrayRW:
+ case clang::BuiltinType::OCLImage3dRO:
+ case clang::BuiltinType::OCLImage3dWO:
+ case clang::BuiltinType::OCLImage3dRW:
+ case clang::BuiltinType::OCLSampler:
+ return 0;
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::LongDouble:
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCSel:
+ case clang::BuiltinType::BoundMember:
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::ARCUnbridgedCast:
+ case clang::BuiltinType::PseudoObject:
+ case clang::BuiltinType::BuiltinFn:
+ case clang::BuiltinType::OMPArraySection:
+ return 1;
+ default:
+ return 0;
+ }
+ break;
-CompilerType
-ClangASTContext::GetChildCompilerTypeAtIndex (lldb::opaque_compiler_type_t type,
- ExecutionContext *exe_ctx,
- size_t idx,
- bool transparent_pointers,
- bool omit_empty_base_classes,
- bool ignore_array_bounds,
- std::string& child_name,
- uint32_t &child_byte_size,
- int32_t &child_byte_offset,
- uint32_t &child_bitfield_bit_size,
- uint32_t &child_bitfield_bit_offset,
- bool &child_is_base_class,
- bool &child_is_deref_of_parent,
- ValueObject *valobj,
- uint64_t &language_flags)
-{
- if (!type)
- return CompilerType();
-
- clang::QualType parent_qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
- child_bitfield_bit_size = 0;
- child_bitfield_bit_offset = 0;
- child_is_base_class = false;
- language_flags = 0;
-
- const bool idx_is_valid = idx < GetNumChildren (type, omit_empty_base_classes);
- uint32_t bit_offset;
- switch (parent_type_class)
- {
- case clang::Type::Builtin:
- if (idx_is_valid)
- {
- switch (llvm::cast<clang::BuiltinType>(parent_qual_type)->getKind())
- {
- case clang::BuiltinType::ObjCId:
- case clang::BuiltinType::ObjCClass:
- child_name = "isa";
- child_byte_size = getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy) / CHAR_BIT;
- return CompilerType (getASTContext(), getASTContext()->ObjCBuiltinClassTy);
-
- default:
- break;
- }
- }
- break;
-
- case clang::Type::Record:
- if (idx_is_valid && GetCompleteType(type))
- {
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
- assert(record_decl);
- const clang::ASTRecordLayout &record_layout = getASTContext()->getASTRecordLayout(record_decl);
- uint32_t child_idx = 0;
-
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
- {
- // We might have base classes to print out first
- clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- const clang::CXXRecordDecl *base_class_decl = nullptr;
-
- // Skip empty base classes
- if (omit_empty_base_classes)
- {
- base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
- if (ClangASTContext::RecordHasFields(base_class_decl) == false)
- continue;
- }
-
- if (idx == child_idx)
- {
- if (base_class_decl == nullptr)
- base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
-
-
- if (base_class->isVirtual())
- {
- bool handled = false;
- if (valobj)
- {
- Error err;
- AddressType addr_type = eAddressTypeInvalid;
- lldb::addr_t vtable_ptr_addr = valobj->GetCPPVTableAddress(addr_type);
-
- if (vtable_ptr_addr != LLDB_INVALID_ADDRESS && addr_type == eAddressTypeLoad)
- {
-
- ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- clang::VTableContextBase *vtable_ctx = getASTContext()->getVTableContext();
- if (vtable_ctx)
- {
- if (vtable_ctx->isMicrosoft())
- {
- clang::MicrosoftVTableContext *msoft_vtable_ctx = static_cast<clang::MicrosoftVTableContext *>(vtable_ctx);
-
- if (vtable_ptr_addr)
- {
- const lldb::addr_t vbtable_ptr_addr = vtable_ptr_addr + record_layout.getVBPtrOffset().getQuantity();
-
- const lldb::addr_t vbtable_ptr = process->ReadPointerFromMemory(vbtable_ptr_addr, err);
- if (vbtable_ptr != LLDB_INVALID_ADDRESS)
- {
- // Get the index into the virtual base table. The index is the index in uint32_t from vbtable_ptr
- const unsigned vbtable_index = msoft_vtable_ctx->getVBTableIndex(cxx_record_decl, base_class_decl);
- const lldb::addr_t base_offset_addr = vbtable_ptr + vbtable_index * 4;
- const uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
- if (base_offset != UINT32_MAX)
- {
- handled = true;
- bit_offset = base_offset * 8;
- }
- }
- }
- }
- else
- {
- clang::ItaniumVTableContext *itanium_vtable_ctx = static_cast<clang::ItaniumVTableContext *>(vtable_ctx);
- if (vtable_ptr_addr)
- {
- const lldb::addr_t vtable_ptr = process->ReadPointerFromMemory(vtable_ptr_addr, err);
- if (vtable_ptr != LLDB_INVALID_ADDRESS)
- {
- clang::CharUnits base_offset_offset = itanium_vtable_ctx->getVirtualBaseOffsetOffset(cxx_record_decl, base_class_decl);
- const lldb::addr_t base_offset_addr = vtable_ptr + base_offset_offset.getQuantity();
- const uint32_t base_offset_size = process->GetAddressByteSize();
- const uint64_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, base_offset_size, UINT32_MAX, err);
- if (base_offset < UINT32_MAX)
- {
- handled = true;
- bit_offset = base_offset * 8;
- }
- }
- }
- }
- }
- }
- }
-
- }
- if (!handled)
- bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
- }
- else
- bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
-
- // Base classes should be a multiple of 8 bits in size
- child_byte_offset = bit_offset/8;
- CompilerType base_class_clang_type(getASTContext(), base_class->getType());
- child_name = base_class_clang_type.GetTypeName().AsCString("");
- uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
-
- // Base classes bit sizes should be a multiple of 8 bits in size
- assert (base_class_clang_type_bit_size % 8 == 0);
- child_byte_size = base_class_clang_type_bit_size / 8;
- child_is_base_class = true;
- return base_class_clang_type;
- }
- // We don't increment the child index in the for loop since we might
- // be skipping empty base classes
- ++child_idx;
- }
- }
- // Make sure index is in range...
- uint32_t field_idx = 0;
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
- {
- if (idx == child_idx)
- {
- // Print the member type if requested
- // Print the member name and equal sign
- child_name.assign(field->getNameAsString().c_str());
-
- // Figure out the type byte size (field_type_info.first) and
- // alignment (field_type_info.second) from the AST context.
- CompilerType field_clang_type (getASTContext(), field->getType());
- assert(field_idx < record_layout.getFieldCount());
- child_byte_size = field_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- const uint32_t child_bit_size = child_byte_size * 8;
-
- // Figure out the field offset within the current struct/union/class type
- bit_offset = record_layout.getFieldOffset (field_idx);
- if (ClangASTContext::FieldIsBitfield (getASTContext(), *field, child_bitfield_bit_size))
- {
- child_bitfield_bit_offset = bit_offset % child_bit_size;
- const uint32_t child_bit_offset = bit_offset - child_bitfield_bit_offset;
- child_byte_offset = child_bit_offset / 8;
- }
- else
- {
- child_byte_offset = bit_offset / 8;
- }
-
- return field_clang_type;
- }
- }
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (idx_is_valid && GetCompleteType(type))
- {
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- uint32_t child_idx = 0;
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
-
- const clang::ASTRecordLayout &interface_layout = getASTContext()->getASTObjCInterfaceLayout(class_interface_decl);
- clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
- {
- if (omit_empty_base_classes)
- {
- CompilerType base_class_clang_type (getASTContext(), getASTContext()->getObjCInterfaceType(superclass_interface_decl));
- if (base_class_clang_type.GetNumChildren(omit_empty_base_classes) > 0)
- {
- if (idx == 0)
- {
- clang::QualType ivar_qual_type(getASTContext()->getObjCInterfaceType(superclass_interface_decl));
-
-
- child_name.assign(superclass_interface_decl->getNameAsString().c_str());
-
- clang::TypeInfo ivar_type_info = getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
-
- child_byte_size = ivar_type_info.Width / 8;
- child_byte_offset = 0;
- child_is_base_class = true;
-
- return CompilerType (getASTContext(), ivar_qual_type);
- }
-
- ++child_idx;
- }
+ case clang::Type::Complex:
+ return 1;
+ case clang::Type::Pointer:
+ return 1;
+ case clang::Type::BlockPointer:
+ return 0; // If block pointers don't have debug info, then no children for
+ // them
+ case clang::Type::LValueReference:
+ return 1;
+ case clang::Type::RValueReference:
+ return 1;
+ case clang::Type::MemberPointer:
+ return 0;
+ case clang::Type::ConstantArray:
+ return 0;
+ case clang::Type::IncompleteArray:
+ return 0;
+ case clang::Type::VariableArray:
+ return 0;
+ case clang::Type::DependentSizedArray:
+ return 0;
+ case clang::Type::DependentSizedExtVector:
+ return 0;
+ case clang::Type::Vector:
+ return 0;
+ case clang::Type::ExtVector:
+ return 0;
+ case clang::Type::FunctionProto:
+ return 0; // When we function pointers, they have no children...
+ case clang::Type::FunctionNoProto:
+ return 0; // When we function pointers, they have no children...
+ case clang::Type::UnresolvedUsing:
+ return 0;
+ case clang::Type::Paren:
+ return GetNumPointeeChildren(
+ llvm::cast<clang::ParenType>(qual_type)->desugar());
+ case clang::Type::Typedef:
+ return GetNumPointeeChildren(llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType());
+ case clang::Type::Auto:
+ return GetNumPointeeChildren(
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType());
+ case clang::Type::Elaborated:
+ return GetNumPointeeChildren(
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType());
+ case clang::Type::TypeOfExpr:
+ return 0;
+ case clang::Type::TypeOf:
+ return 0;
+ case clang::Type::Decltype:
+ return 0;
+ case clang::Type::Record:
+ return 0;
+ case clang::Type::Enum:
+ return 1;
+ case clang::Type::TemplateTypeParm:
+ return 1;
+ case clang::Type::SubstTemplateTypeParm:
+ return 1;
+ case clang::Type::TemplateSpecialization:
+ return 1;
+ case clang::Type::InjectedClassName:
+ return 0;
+ case clang::Type::DependentName:
+ return 1;
+ case clang::Type::DependentTemplateSpecialization:
+ return 1;
+ case clang::Type::ObjCObject:
+ return 0;
+ case clang::Type::ObjCInterface:
+ return 0;
+ case clang::Type::ObjCObjectPointer:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+CompilerType ClangASTContext::GetChildCompilerTypeAtIndex(
+ lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
+ bool transparent_pointers, bool omit_empty_base_classes,
+ bool ignore_array_bounds, std::string &child_name,
+ uint32_t &child_byte_size, int32_t &child_byte_offset,
+ uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
+ bool &child_is_base_class, bool &child_is_deref_of_parent,
+ ValueObject *valobj, uint64_t &language_flags) {
+ if (!type)
+ return CompilerType();
+
+ clang::QualType parent_qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass parent_type_class =
+ parent_qual_type->getTypeClass();
+ child_bitfield_bit_size = 0;
+ child_bitfield_bit_offset = 0;
+ child_is_base_class = false;
+ language_flags = 0;
+
+ const bool idx_is_valid = idx < GetNumChildren(type, omit_empty_base_classes);
+ uint32_t bit_offset;
+ switch (parent_type_class) {
+ case clang::Type::Builtin:
+ if (idx_is_valid) {
+ switch (llvm::cast<clang::BuiltinType>(parent_qual_type)->getKind()) {
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ child_name = "isa";
+ child_byte_size =
+ getASTContext()->getTypeSize(getASTContext()->ObjCBuiltinClassTy) /
+ CHAR_BIT;
+ return CompilerType(getASTContext(),
+ getASTContext()->ObjCBuiltinClassTy);
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case clang::Type::Record:
+ if (idx_is_valid && GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const clang::ASTRecordLayout &record_layout =
+ getASTContext()->getASTRecordLayout(record_decl);
+ uint32_t child_idx = 0;
+
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+ if (cxx_record_decl) {
+ // We might have base classes to print out first
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ const clang::CXXRecordDecl *base_class_decl = nullptr;
+
+ // Skip empty base classes
+ if (omit_empty_base_classes) {
+ base_class_decl = llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()->getAs<clang::RecordType>()->getDecl());
+ if (ClangASTContext::RecordHasFields(base_class_decl) == false)
+ continue;
+ }
+
+ if (idx == child_idx) {
+ if (base_class_decl == nullptr)
+ base_class_decl = llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()->getAs<clang::RecordType>()->getDecl());
+
+ if (base_class->isVirtual()) {
+ bool handled = false;
+ if (valobj) {
+ Error err;
+ AddressType addr_type = eAddressTypeInvalid;
+ lldb::addr_t vtable_ptr_addr =
+ valobj->GetCPPVTableAddress(addr_type);
+
+ if (vtable_ptr_addr != LLDB_INVALID_ADDRESS &&
+ addr_type == eAddressTypeLoad) {
+
+ ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ clang::VTableContextBase *vtable_ctx =
+ getASTContext()->getVTableContext();
+ if (vtable_ctx) {
+ if (vtable_ctx->isMicrosoft()) {
+ clang::MicrosoftVTableContext *msoft_vtable_ctx =
+ static_cast<clang::MicrosoftVTableContext *>(
+ vtable_ctx);
+
+ if (vtable_ptr_addr) {
+ const lldb::addr_t vbtable_ptr_addr =
+ vtable_ptr_addr +
+ record_layout.getVBPtrOffset().getQuantity();
+
+ const lldb::addr_t vbtable_ptr =
+ process->ReadPointerFromMemory(vbtable_ptr_addr,
+ err);
+ if (vbtable_ptr != LLDB_INVALID_ADDRESS) {
+ // Get the index into the virtual base table. The
+ // index is the index in uint32_t from vbtable_ptr
+ const unsigned vbtable_index =
+ msoft_vtable_ctx->getVBTableIndex(
+ cxx_record_decl, base_class_decl);
+ const lldb::addr_t base_offset_addr =
+ vbtable_ptr + vbtable_index * 4;
+ const uint32_t base_offset =
+ process->ReadUnsignedIntegerFromMemory(
+ base_offset_addr, 4, UINT32_MAX, err);
+ if (base_offset != UINT32_MAX) {
+ handled = true;
+ bit_offset = base_offset * 8;
}
- else
- ++child_idx;
+ }
}
-
- const uint32_t superclass_idx = child_idx;
-
- if (idx < (child_idx + class_interface_decl->ivar_size()))
- {
- clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
- {
- if (child_idx == idx)
- {
- clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
-
- clang::QualType ivar_qual_type(ivar_decl->getType());
-
- child_name.assign(ivar_decl->getNameAsString().c_str());
-
- clang::TypeInfo ivar_type_info = getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
-
- child_byte_size = ivar_type_info.Width / 8;
-
- // Figure out the field offset within the current struct/union/class type
- // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
- // that doesn't account for the space taken up by unbacked properties, or from
- // the changing size of base classes that are newer than this class.
- // So if we have a process around that we can ask about this object, do so.
- child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
- Process *process = nullptr;
- if (exe_ctx)
- process = exe_ctx->GetProcessPtr();
- if (process)
- {
- ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
- if (objc_runtime != nullptr)
- {
- CompilerType parent_ast_type (getASTContext(), parent_qual_type);
- child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
- }
- }
-
- // Setting this to UINT32_MAX to make sure we don't compute it twice...
- bit_offset = UINT32_MAX;
-
- if (child_byte_offset == static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET))
- {
- bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
- child_byte_offset = bit_offset / 8;
- }
-
- // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
- // of a bitfield within its containing object. So regardless of where we get the byte
- // offset from, we still need to get the bit offset for bitfields from the layout.
-
- if (ClangASTContext::FieldIsBitfield (getASTContext(), ivar_decl, child_bitfield_bit_size))
- {
- if (bit_offset == UINT32_MAX)
- bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
-
- child_bitfield_bit_offset = bit_offset % 8;
- }
- return CompilerType (getASTContext(), ivar_qual_type);
- }
- ++child_idx;
+ } else {
+ clang::ItaniumVTableContext *itanium_vtable_ctx =
+ static_cast<clang::ItaniumVTableContext *>(
+ vtable_ctx);
+ if (vtable_ptr_addr) {
+ const lldb::addr_t vtable_ptr =
+ process->ReadPointerFromMemory(vtable_ptr_addr,
+ err);
+ if (vtable_ptr != LLDB_INVALID_ADDRESS) {
+ clang::CharUnits base_offset_offset =
+ itanium_vtable_ctx->getVirtualBaseOffsetOffset(
+ cxx_record_decl, base_class_decl);
+ const lldb::addr_t base_offset_addr =
+ vtable_ptr + base_offset_offset.getQuantity();
+ const uint32_t base_offset_size =
+ process->GetAddressByteSize();
+ const uint64_t base_offset =
+ process->ReadUnsignedIntegerFromMemory(
+ base_offset_addr, base_offset_size,
+ UINT32_MAX, err);
+ if (base_offset < UINT32_MAX) {
+ handled = true;
+ bit_offset = base_offset * 8;
}
+ }
}
+ }
}
+ }
}
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- if (idx_is_valid)
- {
- CompilerType pointee_clang_type (GetPointeeType(type));
-
- if (transparent_pointers && pointee_clang_type.IsAggregateType())
- {
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return pointee_clang_type.GetChildCompilerTypeAtIndex (exe_ctx,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent,
- valobj,
- language_flags);
- }
- else
- {
- child_is_deref_of_parent = true;
- const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
- if (parent_name)
- {
- child_name.assign(1, '*');
- child_name += parent_name;
- }
-
- // We have a pointer to an simple type
- if (idx == 0 && pointee_clang_type.GetCompleteType())
- {
- child_byte_size = pointee_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- child_byte_offset = 0;
- return pointee_clang_type;
- }
- }
- }
- break;
-
- case clang::Type::Vector:
- case clang::Type::ExtVector:
- if (idx_is_valid)
- {
- const clang::VectorType *array = llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr());
- if (array)
- {
- CompilerType element_type (getASTContext(), array->getElementType());
- if (element_type.GetCompleteType())
- {
- char element_name[64];
- ::snprintf (element_name, sizeof (element_name), "[%" PRIu64 "]", static_cast<uint64_t>(idx));
- child_name.assign(element_name);
- child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
- return element_type;
- }
- }
- }
- break;
-
- case clang::Type::ConstantArray:
- case clang::Type::IncompleteArray:
- if (ignore_array_bounds || idx_is_valid)
- {
- const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
- if (array)
- {
- CompilerType element_type (getASTContext(), array->getElementType());
- if (element_type.GetCompleteType())
- {
- char element_name[64];
- ::snprintf (element_name, sizeof (element_name), "[%" PRIu64 "]", static_cast<uint64_t>(idx));
- child_name.assign(element_name);
- child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
- return element_type;
- }
- }
- }
- break;
-
-
- case clang::Type::Pointer:
- if (idx_is_valid)
- {
- CompilerType pointee_clang_type (GetPointeeType(type));
-
- // Don't dereference "void *" pointers
- if (pointee_clang_type.IsVoidType())
- return CompilerType();
-
- if (transparent_pointers && pointee_clang_type.IsAggregateType ())
- {
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return pointee_clang_type.GetChildCompilerTypeAtIndex (exe_ctx,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent,
- valobj,
- language_flags);
+ }
+ if (!handled)
+ bit_offset = record_layout.getVBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
+ } else
+ bit_offset = record_layout.getBaseClassOffset(base_class_decl)
+ .getQuantity() *
+ 8;
+
+ // Base classes should be a multiple of 8 bits in size
+ child_byte_offset = bit_offset / 8;
+ CompilerType base_class_clang_type(getASTContext(),
+ base_class->getType());
+ child_name = base_class_clang_type.GetTypeName().AsCString("");
+ uint64_t base_class_clang_type_bit_size =
+ base_class_clang_type.GetBitSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+
+ // Base classes bit sizes should be a multiple of 8 bits in size
+ assert(base_class_clang_type_bit_size % 8 == 0);
+ child_byte_size = base_class_clang_type_bit_size / 8;
+ child_is_base_class = true;
+ return base_class_clang_type;
+ }
+ // We don't increment the child index in the for loop since we might
+ // be skipping empty base classes
+ ++child_idx;
+ }
+ }
+ // Make sure index is in range...
+ uint32_t field_idx = 0;
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field, ++field_idx, ++child_idx) {
+ if (idx == child_idx) {
+ // Print the member type if requested
+ // Print the member name and equal sign
+ child_name.assign(field->getNameAsString());
+
+ // Figure out the type byte size (field_type_info.first) and
+ // alignment (field_type_info.second) from the AST context.
+ CompilerType field_clang_type(getASTContext(), field->getType());
+ assert(field_idx < record_layout.getFieldCount());
+ child_byte_size = field_clang_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+ const uint32_t child_bit_size = child_byte_size * 8;
+
+ // Figure out the field offset within the current struct/union/class
+ // type
+ bit_offset = record_layout.getFieldOffset(field_idx);
+ if (ClangASTContext::FieldIsBitfield(getASTContext(), *field,
+ child_bitfield_bit_size)) {
+ child_bitfield_bit_offset = bit_offset % child_bit_size;
+ const uint32_t child_bit_offset =
+ bit_offset - child_bitfield_bit_offset;
+ child_byte_offset = child_bit_offset / 8;
+ } else {
+ child_byte_offset = bit_offset / 8;
+ }
+
+ return field_clang_type;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (idx_is_valid && GetCompleteType(type)) {
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ uint32_t child_idx = 0;
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+
+ const clang::ASTRecordLayout &interface_layout =
+ getASTContext()->getASTObjCInterfaceLayout(class_interface_decl);
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+ if (superclass_interface_decl) {
+ if (omit_empty_base_classes) {
+ CompilerType base_class_clang_type(
+ getASTContext(), getASTContext()->getObjCInterfaceType(
+ superclass_interface_decl));
+ if (base_class_clang_type.GetNumChildren(
+ omit_empty_base_classes) > 0) {
+ if (idx == 0) {
+ clang::QualType ivar_qual_type(
+ getASTContext()->getObjCInterfaceType(
+ superclass_interface_decl));
+
+ child_name.assign(
+ superclass_interface_decl->getNameAsString());
+
+ clang::TypeInfo ivar_type_info =
+ getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
+
+ child_byte_size = ivar_type_info.Width / 8;
+ child_byte_offset = 0;
+ child_is_base_class = true;
+
+ return CompilerType(getASTContext(), ivar_qual_type);
}
- else
- {
- child_is_deref_of_parent = true;
-
- const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
- if (parent_name)
- {
- child_name.assign(1, '*');
- child_name += parent_name;
- }
-
- // We have a pointer to an simple type
- if (idx == 0)
- {
- child_byte_size = pointee_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- child_byte_offset = 0;
- return pointee_clang_type;
- }
+
+ ++child_idx;
+ }
+ } else
+ ++child_idx;
+ }
+
+ const uint32_t superclass_idx = child_idx;
+
+ if (idx < (child_idx + class_interface_decl->ivar_size())) {
+ clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
+ ivar_end = class_interface_decl->ivar_end();
+
+ for (ivar_pos = class_interface_decl->ivar_begin();
+ ivar_pos != ivar_end; ++ivar_pos) {
+ if (child_idx == idx) {
+ clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
+
+ clang::QualType ivar_qual_type(ivar_decl->getType());
+
+ child_name.assign(ivar_decl->getNameAsString());
+
+ clang::TypeInfo ivar_type_info =
+ getASTContext()->getTypeInfo(ivar_qual_type.getTypePtr());
+
+ child_byte_size = ivar_type_info.Width / 8;
+
+ // Figure out the field offset within the current
+ // struct/union/class type
+ // For ObjC objects, we can't trust the bit offset we get from
+ // the Clang AST, since
+ // that doesn't account for the space taken up by unbacked
+ // properties, or from
+ // the changing size of base classes that are newer than this
+ // class.
+ // So if we have a process around that we can ask about this
+ // object, do so.
+ child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
+ Process *process = nullptr;
+ if (exe_ctx)
+ process = exe_ctx->GetProcessPtr();
+ if (process) {
+ ObjCLanguageRuntime *objc_runtime =
+ process->GetObjCLanguageRuntime();
+ if (objc_runtime != nullptr) {
+ CompilerType parent_ast_type(getASTContext(),
+ parent_qual_type);
+ child_byte_offset = objc_runtime->GetByteOffsetForIvar(
+ parent_ast_type, ivar_decl->getNameAsString().c_str());
+ }
}
- }
- break;
-
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- if (idx_is_valid)
- {
- const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
- CompilerType pointee_clang_type (getASTContext(), reference_type->getPointeeType());
- if (transparent_pointers && pointee_clang_type.IsAggregateType ())
- {
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return pointee_clang_type.GetChildCompilerTypeAtIndex (exe_ctx,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent,
- valobj,
- language_flags);
+
+ // Setting this to UINT32_MAX to make sure we don't compute it
+ // twice...
+ bit_offset = UINT32_MAX;
+
+ if (child_byte_offset ==
+ static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET)) {
+ bit_offset = interface_layout.getFieldOffset(child_idx -
+ superclass_idx);
+ child_byte_offset = bit_offset / 8;
}
- else
- {
- const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
- if (parent_name)
- {
- child_name.assign(1, '&');
- child_name += parent_name;
- }
-
- // We have a pointer to an simple type
- if (idx == 0)
- {
- child_byte_size = pointee_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
- child_byte_offset = 0;
- return pointee_clang_type;
- }
+
+ // Note, the ObjC Ivar Byte offset is just that, it doesn't
+ // account for the bit offset
+ // of a bitfield within its containing object. So regardless of
+ // where we get the byte
+ // offset from, we still need to get the bit offset for
+ // bitfields from the layout.
+
+ if (ClangASTContext::FieldIsBitfield(getASTContext(), ivar_decl,
+ child_bitfield_bit_size)) {
+ if (bit_offset == UINT32_MAX)
+ bit_offset = interface_layout.getFieldOffset(
+ child_idx - superclass_idx);
+
+ child_bitfield_bit_offset = bit_offset % 8;
}
+ return CompilerType(getASTContext(), ivar_qual_type);
+ }
+ ++child_idx;
}
- break;
-
- case clang::Type::Typedef:
- {
- CompilerType typedefed_clang_type (getASTContext(), llvm::cast<clang::TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType());
- return typedefed_clang_type.GetChildCompilerTypeAtIndex (exe_ctx,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent,
- valobj,
- language_flags);
+ }
}
- break;
-
- case clang::Type::Auto:
- {
- CompilerType elaborated_clang_type (getASTContext(), llvm::cast<clang::AutoType>(parent_qual_type)->getDeducedType());
- return elaborated_clang_type.GetChildCompilerTypeAtIndex (exe_ctx,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent,
- valobj,
- language_flags);
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (idx_is_valid) {
+ CompilerType pointee_clang_type(GetPointeeType(type));
+
+ if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return pointee_clang_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset,
+ child_is_base_class, tmp_child_is_deref_of_parent, valobj,
+ language_flags);
+ } else {
+ child_is_deref_of_parent = true;
+ const char *parent_name =
+ valobj ? valobj->GetName().GetCString() : NULL;
+ if (parent_name) {
+ child_name.assign(1, '*');
+ child_name += parent_name;
+ }
+
+ // We have a pointer to an simple type
+ if (idx == 0 && pointee_clang_type.GetCompleteType()) {
+ child_byte_size = pointee_clang_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+ child_byte_offset = 0;
+ return pointee_clang_type;
}
-
- case clang::Type::Elaborated:
- {
- CompilerType elaborated_clang_type (getASTContext(), llvm::cast<clang::ElaboratedType>(parent_qual_type)->getNamedType());
- return elaborated_clang_type.GetChildCompilerTypeAtIndex (exe_ctx,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent,
- valobj,
- language_flags);
+ }
+ }
+ break;
+
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ if (idx_is_valid) {
+ const clang::VectorType *array =
+ llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr());
+ if (array) {
+ CompilerType element_type(getASTContext(), array->getElementType());
+ if (element_type.GetCompleteType()) {
+ char element_name[64];
+ ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]",
+ static_cast<uint64_t>(idx));
+ child_name.assign(element_name);
+ child_byte_size = element_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+ child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+ return element_type;
}
-
- case clang::Type::Paren:
- {
- CompilerType paren_clang_type (getASTContext(), llvm::cast<clang::ParenType>(parent_qual_type)->desugar());
- return paren_clang_type.GetChildCompilerTypeAtIndex (exe_ctx,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent,
- valobj,
- language_flags);
+ }
+ }
+ break;
+
+ case clang::Type::ConstantArray:
+ case clang::Type::IncompleteArray:
+ if (ignore_array_bounds || idx_is_valid) {
+ const clang::ArrayType *array = GetQualType(type)->getAsArrayTypeUnsafe();
+ if (array) {
+ CompilerType element_type(getASTContext(), array->getElementType());
+ if (element_type.GetCompleteType()) {
+ child_name = llvm::formatv("[{0}]", idx);
+ child_byte_size = element_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+ child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+ return element_type;
}
-
-
- default:
- break;
+ }
}
- return CompilerType();
-}
+ break;
-static uint32_t
-GetIndexForRecordBase
-(
- const clang::RecordDecl *record_decl,
- const clang::CXXBaseSpecifier *base_spec,
- bool omit_empty_base_classes
- )
-{
- uint32_t child_idx = 0;
-
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
-
- // const char *super_name = record_decl->getNameAsCString();
- // const char *base_name = base_spec->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString();
- // printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
- //
- if (cxx_record_decl)
- {
- clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- if (omit_empty_base_classes)
- {
- if (BaseSpecifierIsEmpty (base_class))
- continue;
- }
-
- // printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
- // child_idx,
- // base_class->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString());
- //
- //
- if (base_class == base_spec)
- return child_idx;
- ++child_idx;
+ case clang::Type::Pointer:
+ if (idx_is_valid) {
+ CompilerType pointee_clang_type(GetPointeeType(type));
+
+ // Don't dereference "void *" pointers
+ if (pointee_clang_type.IsVoidType())
+ return CompilerType();
+
+ if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return pointee_clang_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset,
+ child_is_base_class, tmp_child_is_deref_of_parent, valobj,
+ language_flags);
+ } else {
+ child_is_deref_of_parent = true;
+
+ const char *parent_name =
+ valobj ? valobj->GetName().GetCString() : NULL;
+ if (parent_name) {
+ child_name.assign(1, '*');
+ child_name += parent_name;
}
- }
-
- return UINT32_MAX;
-}
+ // We have a pointer to an simple type
+ if (idx == 0) {
+ child_byte_size = pointee_clang_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ if (idx_is_valid) {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
+ CompilerType pointee_clang_type(getASTContext(),
+ reference_type->getPointeeType());
+ if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return pointee_clang_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset,
+ child_is_base_class, tmp_child_is_deref_of_parent, valobj,
+ language_flags);
+ } else {
+ const char *parent_name =
+ valobj ? valobj->GetName().GetCString() : NULL;
+ if (parent_name) {
+ child_name.assign(1, '&');
+ child_name += parent_name;
+ }
-static uint32_t
-GetIndexForRecordChild (const clang::RecordDecl *record_decl,
- clang::NamedDecl *canonical_decl,
- bool omit_empty_base_classes)
-{
- uint32_t child_idx = ClangASTContext::GetNumBaseClasses (llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
- omit_empty_base_classes);
-
- clang::RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end();
- field != field_end;
- ++field, ++child_idx)
- {
- if (field->getCanonicalDecl() == canonical_decl)
- return child_idx;
- }
-
- return UINT32_MAX;
+ // We have a pointer to an simple type
+ if (idx == 0) {
+ child_byte_size = pointee_clang_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
+ child_byte_offset = 0;
+ return pointee_clang_type;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef: {
+ CompilerType typedefed_clang_type(
+ getASTContext(), llvm::cast<clang::TypedefType>(parent_qual_type)
+ ->getDecl()
+ ->getUnderlyingType());
+ return typedefed_clang_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
+ child_is_deref_of_parent, valobj, language_flags);
+ } break;
+
+ case clang::Type::Auto: {
+ CompilerType elaborated_clang_type(
+ getASTContext(),
+ llvm::cast<clang::AutoType>(parent_qual_type)->getDeducedType());
+ return elaborated_clang_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
+ child_is_deref_of_parent, valobj, language_flags);
+ }
+
+ case clang::Type::Elaborated: {
+ CompilerType elaborated_clang_type(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(parent_qual_type)->getNamedType());
+ return elaborated_clang_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
+ child_is_deref_of_parent, valobj, language_flags);
+ }
+
+ case clang::Type::Paren: {
+ CompilerType paren_clang_type(
+ getASTContext(),
+ llvm::cast<clang::ParenType>(parent_qual_type)->desugar());
+ return paren_clang_type.GetChildCompilerTypeAtIndex(
+ exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+ ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+ child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
+ child_is_deref_of_parent, valobj, language_flags);
+ }
+
+ default:
+ break;
+ }
+ return CompilerType();
+}
+
+static uint32_t GetIndexForRecordBase(const clang::RecordDecl *record_decl,
+ const clang::CXXBaseSpecifier *base_spec,
+ bool omit_empty_base_classes) {
+ uint32_t child_idx = 0;
+
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+
+ // const char *super_name = record_decl->getNameAsCString();
+ // const char *base_name =
+ // base_spec->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString();
+ // printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
+ //
+ if (cxx_record_decl) {
+ clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ if (omit_empty_base_classes) {
+ if (BaseSpecifierIsEmpty(base_class))
+ continue;
+ }
+
+ // printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
+ // super_name, base_name,
+ // child_idx,
+ // base_class->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString());
+ //
+ //
+ if (base_class == base_spec)
+ return child_idx;
+ ++child_idx;
+ }
+ }
+
+ return UINT32_MAX;
+}
+
+static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl,
+ clang::NamedDecl *canonical_decl,
+ bool omit_empty_base_classes) {
+ uint32_t child_idx = ClangASTContext::GetNumBaseClasses(
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
+ omit_empty_base_classes);
+
+ clang::RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+ field != field_end; ++field, ++child_idx) {
+ if (field->getCanonicalDecl() == canonical_decl)
+ return child_idx;
+ }
+
+ return UINT32_MAX;
}
// Look for a child member (doesn't include base classes, but it does include
@@ -6765,3074 +6955,2849 @@ GetIndexForRecordChild (const clang::RecordDecl *record_decl,
// If we have a clang type that describes "class C", and we wanted to looked
// "m_b" in it:
//
-// With omit_empty_base_classes == false we would get an integer array back with:
+// With omit_empty_base_classes == false we would get an integer array back
+// with:
// { 1, 1 }
// The first index 1 is the child index for "class A" within class C
// The second index 1 is the child index for "m_b" within class A
//
// With omit_empty_base_classes == true we would get an integer array back with:
// { 0, 1 }
-// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count)
+// The first index 0 is the child index for "class A" within class C (since
+// class B doesn't have any members it doesn't count)
// The second index 1 is the child index for "m_b" within class A
-size_t
-ClangASTContext::GetIndexOfChildMemberWithName (lldb::opaque_compiler_type_t type, const char *name,
- bool omit_empty_base_classes,
- std::vector<uint32_t>& child_indexes)
-{
- if (type && name && name[0])
- {
- clang::QualType qual_type(GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
-
- assert(record_decl);
- uint32_t child_idx = 0;
-
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
-
- // Try and find a field that matches NAME
- clang::RecordDecl::field_iterator field, field_end;
- llvm::StringRef name_sref(name);
- for (field = record_decl->field_begin(), field_end = record_decl->field_end();
- field != field_end;
- ++field, ++child_idx)
- {
- llvm::StringRef field_name = field->getName();
- if (field_name.empty())
- {
- CompilerType field_type(getASTContext(),field->getType());
- child_indexes.push_back(child_idx);
- if (field_type.GetIndexOfChildMemberWithName(name, omit_empty_base_classes, child_indexes))
- return child_indexes.size();
- child_indexes.pop_back();
-
- }
- else if (field_name.equals (name_sref))
- {
- // We have to add on the number of base classes to this index!
- child_indexes.push_back (child_idx + ClangASTContext::GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
- return child_indexes.size();
- }
- }
-
- if (cxx_record_decl)
- {
- const clang::RecordDecl *parent_record_decl = cxx_record_decl;
-
- //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
-
- //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
- // Didn't find things easily, lets let clang do its thang...
- clang::IdentifierInfo & ident_ref = getASTContext()->Idents.get(name_sref);
- clang::DeclarationName decl_name(&ident_ref);
-
- clang::CXXBasePaths paths;
- if (cxx_record_decl->lookupInBases([decl_name](const clang::CXXBaseSpecifier *specifier, clang::CXXBasePath &path) {
- return clang::CXXRecordDecl::FindOrdinaryMember(specifier, path, decl_name);
- },
- paths))
- {
- clang::CXXBasePaths::const_paths_iterator path, path_end = paths.end();
- for (path = paths.begin(); path != path_end; ++path)
- {
- const size_t num_path_elements = path->size();
- for (size_t e=0; e<num_path_elements; ++e)
- {
- clang::CXXBasePathElement elem = (*path)[e];
-
- child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
- if (child_idx == UINT32_MAX)
- {
- child_indexes.clear();
- return 0;
- }
- else
- {
- child_indexes.push_back (child_idx);
- parent_record_decl = llvm::cast<clang::RecordDecl>(elem.Base->getType()->getAs<clang::RecordType>()->getDecl());
- }
- }
- for (clang::NamedDecl *path_decl : path->Decls)
- {
- child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes);
- if (child_idx == UINT32_MAX)
- {
- child_indexes.clear();
- return 0;
- }
- else
- {
- child_indexes.push_back (child_idx);
- }
- }
- }
- return child_indexes.size();
- }
- }
-
+size_t ClangASTContext::GetIndexOfChildMemberWithName(
+ lldb::opaque_compiler_type_t type, const char *name,
+ bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
+ if (type && name && name[0]) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+
+ assert(record_decl);
+ uint32_t child_idx = 0;
+
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+
+ // Try and find a field that matches NAME
+ clang::RecordDecl::field_iterator field, field_end;
+ llvm::StringRef name_sref(name);
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field, ++child_idx) {
+ llvm::StringRef field_name = field->getName();
+ if (field_name.empty()) {
+ CompilerType field_type(getASTContext(), field->getType());
+ child_indexes.push_back(child_idx);
+ if (field_type.GetIndexOfChildMemberWithName(
+ name, omit_empty_base_classes, child_indexes))
+ return child_indexes.size();
+ child_indexes.pop_back();
+
+ } else if (field_name.equals(name_sref)) {
+ // We have to add on the number of base classes to this index!
+ child_indexes.push_back(
+ child_idx + ClangASTContext::GetNumBaseClasses(
+ cxx_record_decl, omit_empty_base_classes));
+ return child_indexes.size();
+ }
+ }
+
+ if (cxx_record_decl) {
+ const clang::RecordDecl *parent_record_decl = cxx_record_decl;
+
+ // printf ("parent = %s\n", parent_record_decl->getNameAsCString());
+
+ // const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
+ // Didn't find things easily, lets let clang do its thang...
+ clang::IdentifierInfo &ident_ref =
+ getASTContext()->Idents.get(name_sref);
+ clang::DeclarationName decl_name(&ident_ref);
+
+ clang::CXXBasePaths paths;
+ if (cxx_record_decl->lookupInBases(
+ [decl_name](const clang::CXXBaseSpecifier *specifier,
+ clang::CXXBasePath &path) {
+ return clang::CXXRecordDecl::FindOrdinaryMember(
+ specifier, path, decl_name);
+ },
+ paths)) {
+ clang::CXXBasePaths::const_paths_iterator path,
+ path_end = paths.end();
+ for (path = paths.begin(); path != path_end; ++path) {
+ const size_t num_path_elements = path->size();
+ for (size_t e = 0; e < num_path_elements; ++e) {
+ clang::CXXBasePathElement elem = (*path)[e];
+
+ child_idx = GetIndexForRecordBase(parent_record_decl, elem.Base,
+ omit_empty_base_classes);
+ if (child_idx == UINT32_MAX) {
+ child_indexes.clear();
+ return 0;
+ } else {
+ child_indexes.push_back(child_idx);
+ parent_record_decl = llvm::cast<clang::RecordDecl>(
+ elem.Base->getType()
+ ->getAs<clang::RecordType>()
+ ->getDecl());
}
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteType(type))
- {
- llvm::StringRef name_sref(name);
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- uint32_t child_idx = 0;
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
- clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
- clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
- {
- const clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
-
- if (ivar_decl->getName().equals (name_sref))
- {
- if ((!omit_empty_base_classes && superclass_interface_decl) ||
- ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
- ++child_idx;
-
- child_indexes.push_back (child_idx);
- return child_indexes.size();
- }
- }
-
- if (superclass_interface_decl)
- {
- // The super class index is always zero for ObjC classes,
- // so we push it onto the child indexes in case we find
- // an ivar in our superclass...
- child_indexes.push_back (0);
-
- CompilerType superclass_clang_type (getASTContext(), getASTContext()->getObjCInterfaceType(superclass_interface_decl));
- if (superclass_clang_type.GetIndexOfChildMemberWithName (name,
- omit_empty_base_classes,
- child_indexes))
- {
- // We did find an ivar in a superclass so just
- // return the results!
- return child_indexes.size();
- }
-
- // We didn't find an ivar matching "name" in our
- // superclass, pop the superclass zero index that
- // we pushed on above.
- child_indexes.pop_back();
- }
- }
- }
+ }
+ for (clang::NamedDecl *path_decl : path->Decls) {
+ child_idx = GetIndexForRecordChild(
+ parent_record_decl, path_decl, omit_empty_base_classes);
+ if (child_idx == UINT32_MAX) {
+ child_indexes.clear();
+ return 0;
+ } else {
+ child_indexes.push_back(child_idx);
}
- break;
-
- case clang::Type::ObjCObjectPointer:
- {
- CompilerType objc_object_clang_type (getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
- return objc_object_clang_type.GetIndexOfChildMemberWithName (name,
- omit_empty_base_classes,
- child_indexes);
- }
- break;
-
-
- case clang::Type::ConstantArray:
- {
- // const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
- // const uint64_t element_count = array->getSize().getLimitedValue();
- //
- // if (idx < element_count)
- // {
- // std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
- //
- // char element_name[32];
- // ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
- //
- // child_name.assign(element_name);
- // assert(field_type_info.first % 8 == 0);
- // child_byte_size = field_type_info.first / 8;
- // child_byte_offset = idx * child_byte_size;
- // return array->getElementType().getAsOpaquePtr();
- // }
+ }
}
- break;
-
- // case clang::Type::MemberPointerType:
- // {
- // MemberPointerType *mem_ptr_type = llvm::cast<MemberPointerType>(qual_type.getTypePtr());
- // clang::QualType pointee_type = mem_ptr_type->getPointeeType();
- //
- // if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
- // {
- // return GetIndexOfChildWithName (ast,
- // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
- // name);
- // }
- // }
- // break;
- //
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
- clang::QualType pointee_type(reference_type->getPointeeType());
- CompilerType pointee_clang_type (getASTContext(), pointee_type);
-
- if (pointee_clang_type.IsAggregateType ())
- {
- return pointee_clang_type.GetIndexOfChildMemberWithName (name,
- omit_empty_base_classes,
- child_indexes);
- }
+ return child_indexes.size();
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ llvm::StringRef name_sref(name);
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ uint32_t child_idx = 0;
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+ clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
+ ivar_end = class_interface_decl->ivar_end();
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+
+ for (ivar_pos = class_interface_decl->ivar_begin();
+ ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
+ const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
+
+ if (ivar_decl->getName().equals(name_sref)) {
+ if ((!omit_empty_base_classes && superclass_interface_decl) ||
+ (omit_empty_base_classes &&
+ ObjCDeclHasIVars(superclass_interface_decl, true)))
+ ++child_idx;
+
+ child_indexes.push_back(child_idx);
+ return child_indexes.size();
+ }
}
- break;
-
- case clang::Type::Pointer:
- {
- CompilerType pointee_clang_type (GetPointeeType(type));
-
- if (pointee_clang_type.IsAggregateType ())
- {
- return pointee_clang_type.GetIndexOfChildMemberWithName (name,
- omit_empty_base_classes,
- child_indexes);
- }
+
+ if (superclass_interface_decl) {
+ // The super class index is always zero for ObjC classes,
+ // so we push it onto the child indexes in case we find
+ // an ivar in our superclass...
+ child_indexes.push_back(0);
+
+ CompilerType superclass_clang_type(
+ getASTContext(), getASTContext()->getObjCInterfaceType(
+ superclass_interface_decl));
+ if (superclass_clang_type.GetIndexOfChildMemberWithName(
+ name, omit_empty_base_classes, child_indexes)) {
+ // We did find an ivar in a superclass so just
+ // return the results!
+ return child_indexes.size();
+ }
+
+ // We didn't find an ivar matching "name" in our
+ // superclass, pop the superclass zero index that
+ // we pushed on above.
+ child_indexes.pop_back();
}
- break;
-
- case clang::Type::Typedef:
- return CompilerType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildMemberWithName (name,
- omit_empty_base_classes,
- child_indexes);
-
- case clang::Type::Auto:
- return CompilerType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetIndexOfChildMemberWithName (name,
- omit_empty_base_classes,
- child_indexes);
-
- case clang::Type::Elaborated:
- return CompilerType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildMemberWithName (name,
- omit_empty_base_classes,
- child_indexes);
-
- case clang::Type::Paren:
- return CompilerType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildMemberWithName (name,
- omit_empty_base_classes,
- child_indexes);
-
- default:
- break;
+ }
}
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ CompilerType objc_object_clang_type(
+ getASTContext(),
+ llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
+ ->getPointeeType());
+ return objc_object_clang_type.GetIndexOfChildMemberWithName(
+ name, omit_empty_base_classes, child_indexes);
+ } break;
+
+ case clang::Type::ConstantArray: {
+ // const clang::ConstantArrayType *array =
+ // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
+ // const uint64_t element_count =
+ // array->getSize().getLimitedValue();
+ //
+ // if (idx < element_count)
+ // {
+ // std::pair<uint64_t, unsigned> field_type_info =
+ // ast->getTypeInfo(array->getElementType());
+ //
+ // char element_name[32];
+ // ::snprintf (element_name, sizeof (element_name),
+ // "%s[%u]", parent_name ? parent_name : "", idx);
+ //
+ // child_name.assign(element_name);
+ // assert(field_type_info.first % 8 == 0);
+ // child_byte_size = field_type_info.first / 8;
+ // child_byte_offset = idx * child_byte_size;
+ // return array->getElementType().getAsOpaquePtr();
+ // }
+ } break;
+
+ // case clang::Type::MemberPointerType:
+ // {
+ // MemberPointerType *mem_ptr_type =
+ // llvm::cast<MemberPointerType>(qual_type.getTypePtr());
+ // clang::QualType pointee_type =
+ // mem_ptr_type->getPointeeType();
+ //
+ // if (ClangASTContext::IsAggregateType
+ // (pointee_type.getAsOpaquePtr()))
+ // {
+ // return GetIndexOfChildWithName (ast,
+ // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
+ // name);
+ // }
+ // }
+ // break;
+ //
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ clang::QualType pointee_type(reference_type->getPointeeType());
+ CompilerType pointee_clang_type(getASTContext(), pointee_type);
+
+ if (pointee_clang_type.IsAggregateType()) {
+ return pointee_clang_type.GetIndexOfChildMemberWithName(
+ name, omit_empty_base_classes, child_indexes);
+ }
+ } break;
+
+ case clang::Type::Pointer: {
+ CompilerType pointee_clang_type(GetPointeeType(type));
+
+ if (pointee_clang_type.IsAggregateType()) {
+ return pointee_clang_type.GetIndexOfChildMemberWithName(
+ name, omit_empty_base_classes, child_indexes);
+ }
+ } break;
+
+ case clang::Type::Typedef:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
+ child_indexes);
+
+ case clang::Type::Auto:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
+ child_indexes);
+
+ case clang::Type::Elaborated:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
+ child_indexes);
+
+ case clang::Type::Paren:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar())
+ .GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
+ child_indexes);
+
+ default:
+ break;
}
- return 0;
+ }
+ return 0;
}
-
// Get the index of the child of "clang_type" whose name matches. This function
// doesn't descend into the children, but only looks one level deep and name
// matches can include base class names.
uint32_t
-ClangASTContext::GetIndexOfChildWithName (lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes)
-{
- if (type && name && name[0])
- {
- clang::QualType qual_type(GetCanonicalQualType(type));
-
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
-
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
- const clang::RecordDecl *record_decl = record_type->getDecl();
-
- assert(record_decl);
- uint32_t child_idx = 0;
-
- const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
-
- if (cxx_record_decl)
- {
- clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
- {
- // Skip empty base classes
- clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
- if (omit_empty_base_classes && ClangASTContext::RecordHasFields(base_class_decl) == false)
- continue;
-
- CompilerType base_class_clang_type (getASTContext(), base_class->getType());
- std::string base_class_type_name (base_class_clang_type.GetTypeName().AsCString(""));
- if (base_class_type_name.compare (name) == 0)
- return child_idx;
- ++child_idx;
- }
- }
-
- // Try and find a field that matches NAME
- clang::RecordDecl::field_iterator field, field_end;
- llvm::StringRef name_sref(name);
- for (field = record_decl->field_begin(), field_end = record_decl->field_end();
- field != field_end;
- ++field, ++child_idx)
- {
- if (field->getName().equals (name_sref))
- return child_idx;
- }
-
- }
- break;
-
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteType(type))
- {
- llvm::StringRef name_sref(name);
- const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
- {
- uint32_t child_idx = 0;
- clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
- {
- clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
- clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
- {
- const clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
-
- if (ivar_decl->getName().equals (name_sref))
- {
- if ((!omit_empty_base_classes && superclass_interface_decl) ||
- ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
- ++child_idx;
-
- return child_idx;
- }
- }
-
- if (superclass_interface_decl)
- {
- if (superclass_interface_decl->getName().equals (name_sref))
- return 0;
- }
- }
- }
- }
- break;
-
- case clang::Type::ObjCObjectPointer:
- {
- CompilerType pointee_clang_type (getASTContext(), llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
- return pointee_clang_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
- }
- break;
-
- case clang::Type::ConstantArray:
- {
- // const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
- // const uint64_t element_count = array->getSize().getLimitedValue();
- //
- // if (idx < element_count)
- // {
- // std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
- //
- // char element_name[32];
- // ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
- //
- // child_name.assign(element_name);
- // assert(field_type_info.first % 8 == 0);
- // child_byte_size = field_type_info.first / 8;
- // child_byte_offset = idx * child_byte_size;
- // return array->getElementType().getAsOpaquePtr();
- // }
- }
- break;
-
- // case clang::Type::MemberPointerType:
- // {
- // MemberPointerType *mem_ptr_type = llvm::cast<MemberPointerType>(qual_type.getTypePtr());
- // clang::QualType pointee_type = mem_ptr_type->getPointeeType();
- //
- // if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
- // {
- // return GetIndexOfChildWithName (ast,
- // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
- // name);
- // }
- // }
- // break;
- //
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
- {
- const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
- CompilerType pointee_type (getASTContext(), reference_type->getPointeeType());
-
- if (pointee_type.IsAggregateType ())
- {
- return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
- }
- }
- break;
-
- case clang::Type::Pointer:
- {
- const clang::PointerType *pointer_type = llvm::cast<clang::PointerType>(qual_type.getTypePtr());
- CompilerType pointee_type (getASTContext(), pointer_type->getPointeeType());
-
- if (pointee_type.IsAggregateType ())
- {
- return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
- }
- else
- {
- // if (parent_name)
- // {
- // child_name.assign(1, '*');
- // child_name += parent_name;
- // }
- //
- // // We have a pointer to an simple type
- // if (idx == 0)
- // {
- // std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- // assert(clang_type_info.first % 8 == 0);
- // child_byte_size = clang_type_info.first / 8;
- // child_byte_offset = 0;
- // return pointee_type.getAsOpaquePtr();
- // }
- }
- }
- break;
+ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
+ const char *name,
+ bool omit_empty_base_classes) {
+ if (type && name && name[0]) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
- case clang::Type::Auto:
- return CompilerType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
-
- case clang::Type::Elaborated:
- return CompilerType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
-
- case clang::Type::Paren:
- return CompilerType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildWithName (name, omit_empty_base_classes);
-
- case clang::Type::Typedef:
- return CompilerType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
-
- default:
- break;
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+
+ switch (type_class) {
+ case clang::Type::Record:
+ if (GetCompleteType(type)) {
+ const clang::RecordType *record_type =
+ llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+ const clang::RecordDecl *record_decl = record_type->getDecl();
+
+ assert(record_decl);
+ uint32_t child_idx = 0;
+
+ const clang::CXXRecordDecl *cxx_record_decl =
+ llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+
+ if (cxx_record_decl) {
+ clang::CXXRecordDecl::base_class_const_iterator base_class,
+ base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(),
+ base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end; ++base_class) {
+ // Skip empty base classes
+ clang::CXXRecordDecl *base_class_decl =
+ llvm::cast<clang::CXXRecordDecl>(
+ base_class->getType()
+ ->getAs<clang::RecordType>()
+ ->getDecl());
+ if (omit_empty_base_classes &&
+ ClangASTContext::RecordHasFields(base_class_decl) == false)
+ continue;
+
+ CompilerType base_class_clang_type(getASTContext(),
+ base_class->getType());
+ std::string base_class_type_name(
+ base_class_clang_type.GetTypeName().AsCString(""));
+ if (base_class_type_name.compare(name) == 0)
+ return child_idx;
+ ++child_idx;
+ }
}
- }
- return UINT32_MAX;
-}
+ // Try and find a field that matches NAME
+ clang::RecordDecl::field_iterator field, field_end;
+ llvm::StringRef name_sref(name);
+ for (field = record_decl->field_begin(),
+ field_end = record_decl->field_end();
+ field != field_end; ++field, ++child_idx) {
+ if (field->getName().equals(name_sref))
+ return child_idx;
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (GetCompleteType(type)) {
+ llvm::StringRef name_sref(name);
+ const clang::ObjCObjectType *objc_class_type =
+ llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+ assert(objc_class_type);
+ if (objc_class_type) {
+ uint32_t child_idx = 0;
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ objc_class_type->getInterface();
+
+ if (class_interface_decl) {
+ clang::ObjCInterfaceDecl::ivar_iterator ivar_pos,
+ ivar_end = class_interface_decl->ivar_end();
+ clang::ObjCInterfaceDecl *superclass_interface_decl =
+ class_interface_decl->getSuperClass();
+
+ for (ivar_pos = class_interface_decl->ivar_begin();
+ ivar_pos != ivar_end; ++ivar_pos, ++child_idx) {
+ const clang::ObjCIvarDecl *ivar_decl = *ivar_pos;
+
+ if (ivar_decl->getName().equals(name_sref)) {
+ if ((!omit_empty_base_classes && superclass_interface_decl) ||
+ (omit_empty_base_classes &&
+ ObjCDeclHasIVars(superclass_interface_decl, true)))
+ ++child_idx;
-size_t
-ClangASTContext::GetNumTemplateArguments (lldb::opaque_compiler_type_t type)
-{
- if (!type)
- return 0;
+ return child_idx;
+ }
+ }
- clang::QualType qual_type (GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
- if (cxx_record_decl)
- {
- const clang::ClassTemplateSpecializationDecl *template_decl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(cxx_record_decl);
- if (template_decl)
- return template_decl->getTemplateArgs().size();
- }
+ if (superclass_interface_decl) {
+ if (superclass_interface_decl->getName().equals(name_sref))
+ return 0;
}
- break;
-
- case clang::Type::Typedef:
- return (CompilerType (getASTContext(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType())).GetNumTemplateArguments();
-
- case clang::Type::Auto:
- return (CompilerType (getASTContext(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType())).GetNumTemplateArguments();
-
- case clang::Type::Elaborated:
- return (CompilerType (getASTContext(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())).GetNumTemplateArguments();
-
- case clang::Type::Paren:
- return (CompilerType (getASTContext(), llvm::cast<clang::ParenType>(qual_type)->desugar())).GetNumTemplateArguments();
-
- default:
- break;
- }
+ }
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer: {
+ CompilerType pointee_clang_type(
+ getASTContext(),
+ llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
+ ->getPointeeType());
+ return pointee_clang_type.GetIndexOfChildWithName(
+ name, omit_empty_base_classes);
+ } break;
+
+ case clang::Type::ConstantArray: {
+ // const clang::ConstantArrayType *array =
+ // llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
+ // const uint64_t element_count =
+ // array->getSize().getLimitedValue();
+ //
+ // if (idx < element_count)
+ // {
+ // std::pair<uint64_t, unsigned> field_type_info =
+ // ast->getTypeInfo(array->getElementType());
+ //
+ // char element_name[32];
+ // ::snprintf (element_name, sizeof (element_name),
+ // "%s[%u]", parent_name ? parent_name : "", idx);
+ //
+ // child_name.assign(element_name);
+ // assert(field_type_info.first % 8 == 0);
+ // child_byte_size = field_type_info.first / 8;
+ // child_byte_offset = idx * child_byte_size;
+ // return array->getElementType().getAsOpaquePtr();
+ // }
+ } break;
+
+ // case clang::Type::MemberPointerType:
+ // {
+ // MemberPointerType *mem_ptr_type =
+ // llvm::cast<MemberPointerType>(qual_type.getTypePtr());
+ // clang::QualType pointee_type =
+ // mem_ptr_type->getPointeeType();
+ //
+ // if (ClangASTContext::IsAggregateType
+ // (pointee_type.getAsOpaquePtr()))
+ // {
+ // return GetIndexOfChildWithName (ast,
+ // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
+ // name);
+ // }
+ // }
+ // break;
+ //
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference: {
+ const clang::ReferenceType *reference_type =
+ llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
+ CompilerType pointee_type(getASTContext(),
+ reference_type->getPointeeType());
+
+ if (pointee_type.IsAggregateType()) {
+ return pointee_type.GetIndexOfChildWithName(name,
+ omit_empty_base_classes);
+ }
+ } break;
+
+ case clang::Type::Pointer: {
+ const clang::PointerType *pointer_type =
+ llvm::cast<clang::PointerType>(qual_type.getTypePtr());
+ CompilerType pointee_type(getASTContext(),
+ pointer_type->getPointeeType());
+
+ if (pointee_type.IsAggregateType()) {
+ return pointee_type.GetIndexOfChildWithName(name,
+ omit_empty_base_classes);
+ } else {
+ // if (parent_name)
+ // {
+ // child_name.assign(1, '*');
+ // child_name += parent_name;
+ // }
+ //
+ // // We have a pointer to an simple type
+ // if (idx == 0)
+ // {
+ // std::pair<uint64_t, unsigned> clang_type_info
+ // = ast->getTypeInfo(pointee_type);
+ // assert(clang_type_info.first % 8 == 0);
+ // child_byte_size = clang_type_info.first / 8;
+ // child_byte_offset = 0;
+ // return pointee_type.getAsOpaquePtr();
+ // }
+ }
+ } break;
+
+ case clang::Type::Auto:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType())
+ .GetIndexOfChildWithName(name, omit_empty_base_classes);
+
+ case clang::Type::Elaborated:
+ return CompilerType(
+ getASTContext(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType())
+ .GetIndexOfChildWithName(name, omit_empty_base_classes);
+
+ case clang::Type::Paren:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar())
+ .GetIndexOfChildWithName(name, omit_empty_base_classes);
+
+ case clang::Type::Typedef:
+ return CompilerType(getASTContext(),
+ llvm::cast<clang::TypedefType>(qual_type)
+ ->getDecl()
+ ->getUnderlyingType())
+ .GetIndexOfChildWithName(name, omit_empty_base_classes);
- return 0;
+ default:
+ break;
+ }
+ }
+ return UINT32_MAX;
}
-CompilerType
-ClangASTContext::GetTemplateArgument (lldb::opaque_compiler_type_t type, size_t arg_idx, lldb::TemplateArgumentKind &kind)
-{
- if (!type)
- return CompilerType();
+size_t
+ClangASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
+ if (!type)
+ return 0;
- clang::QualType qual_type (GetCanonicalQualType(type));
- const clang::Type::TypeClass type_class = qual_type->getTypeClass();
- switch (type_class)
- {
- case clang::Type::Record:
- if (GetCompleteType(type))
- {
- const clang::CXXRecord