1 //===-- SBType.cpp ----------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <string.h> 11 12 #include "clang/AST/ASTContext.h" 13 #include "clang/AST/TemplateBase.h" 14 #include "clang/AST/Type.h" 15 16 #include "lldb/API/SBDefines.h" 17 #include "lldb/API/SBType.h" 18 #include "lldb/API/SBStream.h" 19 #include "lldb/Core/ConstString.h" 20 #include "lldb/Core/Log.h" 21 #include "lldb/Symbol/ClangASTContext.h" 22 #include "lldb/Symbol/ClangASTType.h" 23 #include "lldb/Symbol/Type.h" 24 25 using namespace lldb; 26 using namespace lldb_private; 27 using namespace clang; 28 29 SBType::SBType() : 30 m_opaque_sp() 31 { 32 } 33 34 SBType::SBType (const lldb_private::ClangASTType &type) : 35 m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(), 36 type.GetOpaqueQualType()))) 37 { 38 } 39 40 SBType::SBType (const lldb::TypeSP &type_sp) : 41 m_opaque_sp(new TypeImpl(type_sp)) 42 { 43 } 44 45 SBType::SBType (const lldb::TypeImplSP &type_impl_sp) : 46 m_opaque_sp(type_impl_sp) 47 { 48 } 49 50 51 SBType::SBType (const SBType &rhs) : 52 m_opaque_sp() 53 { 54 if (this != &rhs) 55 { 56 m_opaque_sp = rhs.m_opaque_sp; 57 } 58 } 59 60 61 //SBType::SBType (TypeImpl* impl) : 62 // m_opaque_ap(impl) 63 //{} 64 // 65 bool 66 SBType::operator == (const lldb::SBType &rhs) const 67 { 68 if (IsValid() == false) 69 return !rhs.IsValid(); 70 71 return (rhs.m_opaque_sp->GetASTContext() == m_opaque_sp->GetASTContext()) && 72 (rhs.m_opaque_sp->GetOpaqueQualType() == m_opaque_sp->GetOpaqueQualType()); 73 } 74 75 bool 76 SBType::operator != (const lldb::SBType &rhs) const 77 { 78 if (IsValid() == false) 79 return rhs.IsValid(); 80 81 return (rhs.m_opaque_sp->GetASTContext() != m_opaque_sp->GetASTContext()) || 82 (rhs.m_opaque_sp->GetOpaqueQualType() != m_opaque_sp->GetOpaqueQualType()); 83 } 84 85 86 const lldb::SBType & 87 SBType::operator = (const lldb::SBType &rhs) 88 { 89 if (*this != rhs) 90 { 91 m_opaque_sp = rhs.m_opaque_sp; 92 } 93 return *this; 94 } 95 96 SBType::~SBType () 97 {} 98 99 lldb_private::TypeImpl & 100 SBType::ref () 101 { 102 if (m_opaque_sp.get() == NULL) 103 m_opaque_sp.reset (new lldb_private::TypeImpl()); 104 return *m_opaque_sp; 105 } 106 107 const lldb_private::TypeImpl & 108 SBType::ref () const 109 { 110 // "const SBAddress &addr" should already have checked "addr.IsValid()" 111 // prior to calling this function. In case you didn't we will assert 112 // and die to let you know. 113 assert (m_opaque_sp.get()); 114 return *m_opaque_sp; 115 } 116 117 bool 118 SBType::IsValid() const 119 { 120 if (m_opaque_sp.get() == NULL) 121 return false; 122 123 return m_opaque_sp->IsValid(); 124 } 125 126 size_t 127 SBType::GetByteSize() const 128 { 129 if (!IsValid()) 130 return 0; 131 132 return ClangASTType::GetTypeByteSize(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 133 134 } 135 136 bool 137 SBType::IsPointerType() const 138 { 139 if (!IsValid()) 140 return false; 141 142 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 143 const clang::Type* typePtr = qt.getTypePtrOrNull(); 144 145 if (typePtr) 146 return typePtr->isAnyPointerType(); 147 return false; 148 } 149 150 bool 151 SBType::IsReferenceType() const 152 { 153 if (!IsValid()) 154 return false; 155 156 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 157 const clang::Type* typePtr = qt.getTypePtrOrNull(); 158 159 if (typePtr) 160 return typePtr->isReferenceType(); 161 return false; 162 } 163 164 SBType 165 SBType::GetPointerType() const 166 { 167 if (!IsValid()) 168 return SBType(); 169 170 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), 171 ClangASTContext::CreatePointerType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()))); 172 } 173 174 SBType 175 SBType::GetPointeeType() const 176 { 177 if (!IsValid()) 178 return SBType(); 179 180 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 181 const clang::Type* typePtr = qt.getTypePtrOrNull(); 182 183 if (typePtr) 184 return SBType(ClangASTType(m_opaque_sp->GetASTContext(),typePtr->getPointeeType().getAsOpaquePtr())); 185 return SBType(); 186 } 187 188 SBType 189 SBType::GetReferenceType() const 190 { 191 if (!IsValid()) 192 return SBType(); 193 194 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), 195 ClangASTContext::CreateLValueReferenceType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()))); 196 } 197 198 SBType 199 SBType::GetDereferencedType() const 200 { 201 if (!IsValid()) 202 return SBType(); 203 204 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 205 206 return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getNonReferenceType().getAsOpaquePtr())); 207 } 208 209 SBType 210 SBType::GetBasicType(lldb::BasicType type) const 211 { 212 213 if (!IsValid()) 214 return SBType(); 215 216 clang::CanQualType base_type_qual; 217 218 switch (type) 219 { 220 case eBasicTypeChar: 221 base_type_qual = m_opaque_sp->GetASTContext()->CharTy; 222 break; 223 case eBasicTypeSignedChar: 224 base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy; 225 break; 226 case eBasicTypeShort: 227 base_type_qual = m_opaque_sp->GetASTContext()->ShortTy; 228 break; 229 case eBasicTypeUnsignedShort: 230 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy; 231 break; 232 case eBasicTypeInt: 233 base_type_qual = m_opaque_sp->GetASTContext()->IntTy; 234 break; 235 case eBasicTypeUnsignedInt: 236 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy; 237 break; 238 case eBasicTypeLong: 239 base_type_qual = m_opaque_sp->GetASTContext()->LongTy; 240 break; 241 case eBasicTypeUnsignedLong: 242 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy; 243 break; 244 case eBasicTypeBool: 245 base_type_qual = m_opaque_sp->GetASTContext()->BoolTy; 246 break; 247 case eBasicTypeFloat: 248 base_type_qual = m_opaque_sp->GetASTContext()->FloatTy; 249 break; 250 case eBasicTypeDouble: 251 base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy; 252 break; 253 case eBasicTypeObjCID: 254 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy; 255 break; 256 case eBasicTypeVoid: 257 base_type_qual = m_opaque_sp->GetASTContext()->VoidTy; 258 break; 259 case eBasicTypeWChar: 260 base_type_qual = m_opaque_sp->GetASTContext()->WCharTy; 261 break; 262 case eBasicTypeChar16: 263 base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty; 264 break; 265 case eBasicTypeChar32: 266 base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty; 267 break; 268 case eBasicTypeLongLong: 269 base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy; 270 break; 271 case eBasicTypeUnsignedLongLong: 272 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy; 273 break; 274 case eBasicTypeInt128: 275 base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty; 276 break; 277 case eBasicTypeUnsignedInt128: 278 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty; 279 break; 280 case eBasicTypeLongDouble: 281 base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy; 282 break; 283 case eBasicTypeFloatComplex: 284 base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy; 285 break; 286 case eBasicTypeDoubleComplex: 287 base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy; 288 break; 289 case eBasicTypeLongDoubleComplex: 290 base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy; 291 break; 292 case eBasicTypeObjCClass: 293 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy; 294 break; 295 case eBasicTypeObjCSel: 296 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy; 297 break; 298 default: 299 return SBType(); 300 } 301 302 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr())); 303 } 304 305 const char* 306 SBType::GetName() 307 { 308 if (!IsValid()) 309 return ""; 310 311 return ClangASTType::GetConstTypeName(m_opaque_sp->GetOpaqueQualType()).GetCString(); 312 } 313 314 SBTypeList::SBTypeList() : 315 m_opaque_ap(new TypeListImpl()) 316 { 317 } 318 319 SBTypeList::SBTypeList(const SBTypeList& rhs) : 320 m_opaque_ap(new TypeListImpl()) 321 { 322 for (uint32_t i = 0, rhs_size = rhs.GetSize(); i < rhs_size; i++) 323 Append(rhs.GetTypeAtIndex(i)); 324 } 325 326 bool 327 SBTypeList::IsValid () const 328 { 329 return (m_opaque_ap.get() != NULL); 330 } 331 332 SBTypeList& 333 SBTypeList::operator = (const SBTypeList& rhs) 334 { 335 if (this != &rhs && m_opaque_ap.get() != rhs.m_opaque_ap.get()) 336 { 337 m_opaque_ap.reset(new TypeListImpl()); 338 for (uint32_t i = 0, rhs_size = rhs.GetSize(); i < rhs_size; i++) 339 Append(rhs.GetTypeAtIndex(i)); 340 } 341 return *this; 342 } 343 344 void 345 SBTypeList::Append (const SBType& type) 346 { 347 if (type.IsValid()) 348 m_opaque_ap->Append (type.m_opaque_sp); 349 } 350 351 SBType 352 SBTypeList::GetTypeAtIndex(int index) const 353 { 354 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 355 } 356 357 int 358 SBTypeList::GetSize() const 359 { 360 return m_opaque_ap->GetSize(); 361 } 362 363 SBTypeList::~SBTypeList() 364 { 365 } 366 367 bool 368 SBType::IsPointerType (void *opaque_type) 369 { 370 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 371 372 bool ret_value = ClangASTContext::IsPointerType (opaque_type); 373 374 if (log) 375 log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false")); 376 377 return ret_value; 378 } 379