| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1 | //===-- DWARFASTParserClang.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 "DWARFASTParserClang.h" | 
|  | 11 | #include "DWARFCompileUnit.h" | 
|  | 12 | #include "DWARFDebugInfo.h" | 
|  | 13 | #include "DWARFDeclContext.h" | 
|  | 14 | #include "DWARFDefines.h" | 
|  | 15 | #include "DWARFDIE.h" | 
|  | 16 | #include "DWARFDIECollection.h" | 
|  | 17 | #include "SymbolFileDWARF.h" | 
|  | 18 | #include "SymbolFileDWARFDebugMap.h" | 
|  | 19 | #include "UniqueDWARFASTType.h" | 
|  | 20 |  | 
| Jim Ingham | aa816b8 | 2015-09-02 01:59:14 +0000 | [diff] [blame] | 21 | #include "lldb/Interpreter/Args.h" | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 22 | #include "lldb/Core/Log.h" | 
|  | 23 | #include "lldb/Core/Module.h" | 
| Jim Ingham | aa816b8 | 2015-09-02 01:59:14 +0000 | [diff] [blame] | 24 | #include "lldb/Core/StreamString.h" | 
|  | 25 | #include "lldb/Core/Value.h" | 
|  | 26 | #include "lldb/Host/Host.h" | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 27 | #include "lldb/Symbol/ClangASTImporter.h" | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 28 | #include "lldb/Symbol/ClangExternalASTSourceCommon.h" | 
|  | 29 | #include "lldb/Symbol/CompileUnit.h" | 
|  | 30 | #include "lldb/Symbol/Function.h" | 
|  | 31 | #include "lldb/Symbol/ObjectFile.h" | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 32 | #include "lldb/Symbol/SymbolVendor.h" | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 33 | #include "lldb/Symbol/TypeList.h" | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 34 | #include "lldb/Symbol/TypeMap.h" | 
| Jim Ingham | 0e0984e | 2015-09-02 01:06:46 +0000 | [diff] [blame] | 35 | #include "lldb/Target/Language.h" | 
| Jim Ingham | aa816b8 | 2015-09-02 01:59:14 +0000 | [diff] [blame] | 36 | #include "Plugins/Language/ObjC/ObjCLanguage.h" | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 37 |  | 
|  | 38 | #include "clang/AST/DeclCXX.h" | 
|  | 39 | #include "clang/AST/DeclObjC.h" | 
|  | 40 |  | 
| Paul Herman | ea188fc | 2015-09-16 18:48:30 +0000 | [diff] [blame] | 41 | #include <map> | 
|  | 42 | #include <vector> | 
|  | 43 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 44 | //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN | 
|  | 45 |  | 
|  | 46 | #ifdef ENABLE_DEBUG_PRINTF | 
|  | 47 | #include <stdio.h> | 
|  | 48 | #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__) | 
|  | 49 | #else | 
|  | 50 | #define DEBUG_PRINTF(fmt, ...) | 
|  | 51 | #endif | 
|  | 52 |  | 
|  | 53 |  | 
|  | 54 | using namespace lldb; | 
|  | 55 | using namespace lldb_private; | 
|  | 56 | DWARFASTParserClang::DWARFASTParserClang (ClangASTContext &ast) : | 
|  | 57 | m_ast (ast), | 
|  | 58 | m_die_to_decl_ctx (), | 
|  | 59 | m_decl_ctx_to_die () | 
|  | 60 | { | 
|  | 61 | } | 
|  | 62 |  | 
|  | 63 | DWARFASTParserClang::~DWARFASTParserClang () | 
|  | 64 | { | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 |  | 
|  | 68 | static AccessType | 
|  | 69 | DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility) | 
|  | 70 | { | 
|  | 71 | switch (dwarf_accessibility) | 
|  | 72 | { | 
|  | 73 | case DW_ACCESS_public:      return eAccessPublic; | 
|  | 74 | case DW_ACCESS_private:     return eAccessPrivate; | 
|  | 75 | case DW_ACCESS_protected:   return eAccessProtected; | 
|  | 76 | default:                    break; | 
|  | 77 | } | 
|  | 78 | return eAccessNone; | 
|  | 79 | } | 
|  | 80 |  | 
|  | 81 | static bool | 
|  | 82 | DeclKindIsCXXClass (clang::Decl::Kind decl_kind) | 
|  | 83 | { | 
|  | 84 | switch (decl_kind) | 
|  | 85 | { | 
|  | 86 | case clang::Decl::CXXRecord: | 
|  | 87 | case clang::Decl::ClassTemplateSpecialization: | 
|  | 88 | return true; | 
|  | 89 | default: | 
|  | 90 | break; | 
|  | 91 | } | 
|  | 92 | return false; | 
|  | 93 | } | 
|  | 94 |  | 
|  | 95 | struct BitfieldInfo | 
|  | 96 | { | 
|  | 97 | uint64_t bit_size; | 
|  | 98 | uint64_t bit_offset; | 
|  | 99 |  | 
|  | 100 | BitfieldInfo () : | 
|  | 101 | bit_size (LLDB_INVALID_ADDRESS), | 
|  | 102 | bit_offset (LLDB_INVALID_ADDRESS) | 
|  | 103 | { | 
|  | 104 | } | 
|  | 105 |  | 
|  | 106 | void | 
|  | 107 | Clear() | 
|  | 108 | { | 
|  | 109 | bit_size = LLDB_INVALID_ADDRESS; | 
|  | 110 | bit_offset = LLDB_INVALID_ADDRESS; | 
|  | 111 | } | 
|  | 112 |  | 
|  | 113 | bool IsValid () | 
|  | 114 | { | 
|  | 115 | return (bit_size != LLDB_INVALID_ADDRESS) && | 
|  | 116 | (bit_offset != LLDB_INVALID_ADDRESS); | 
|  | 117 | } | 
|  | 118 | }; | 
|  | 119 |  | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 120 |  | 
|  | 121 | ClangASTImporter & | 
|  | 122 | DWARFASTParserClang::GetClangASTImporter() | 
|  | 123 | { | 
|  | 124 | if (!m_clang_ast_importer_ap) | 
|  | 125 | { | 
|  | 126 | m_clang_ast_importer_ap.reset (new ClangASTImporter); | 
|  | 127 | } | 
|  | 128 | return *m_clang_ast_importer_ap; | 
|  | 129 | } | 
|  | 130 |  | 
|  | 131 |  | 
|  | 132 | TypeSP | 
|  | 133 | DWARFASTParserClang::ParseTypeFromDWO (const DWARFDIE &die, Log *log) | 
|  | 134 | { | 
|  | 135 | ModuleSP dwo_module_sp = die.GetContainingDWOModule(); | 
|  | 136 | if (dwo_module_sp) | 
|  | 137 | { | 
|  | 138 | // This type comes from an external DWO module | 
|  | 139 | std::vector<CompilerContext> dwo_context; | 
|  | 140 | die.GetDWOContext(dwo_context); | 
|  | 141 | TypeMap dwo_types; | 
|  | 142 | if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, dwo_types)) | 
|  | 143 | { | 
|  | 144 | const size_t num_dwo_types = dwo_types.GetSize(); | 
|  | 145 | if (num_dwo_types == 1) | 
|  | 146 | { | 
|  | 147 | // We found a real definition for this type elsewhere | 
|  | 148 | // so lets use it and cache the fact that we found | 
|  | 149 | // a complete type for this die | 
|  | 150 | TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0); | 
|  | 151 | if (dwo_type_sp) | 
|  | 152 | { | 
|  | 153 | lldb_private::CompilerType dwo_type = dwo_type_sp->GetForwardCompilerType(); | 
|  | 154 |  | 
|  | 155 | lldb_private::CompilerType type = GetClangASTImporter().CopyType (m_ast, dwo_type); | 
|  | 156 |  | 
|  | 157 | //printf ("copied_qual_type: ast = %p, clang_type = %p, name = '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(), external_type->GetName().GetCString()); | 
|  | 158 | if (type) | 
|  | 159 | { | 
|  | 160 | SymbolFileDWARF *dwarf = die.GetDWARF(); | 
|  | 161 | TypeSP type_sp (new Type (die.GetID(), | 
|  | 162 | dwarf, | 
|  | 163 | dwo_type_sp->GetName(), | 
|  | 164 | dwo_type_sp->GetByteSize(), | 
|  | 165 | NULL, | 
|  | 166 | LLDB_INVALID_UID, | 
|  | 167 | Type::eEncodingInvalid, | 
|  | 168 | &dwo_type_sp->GetDeclaration(), | 
|  | 169 | type, | 
|  | 170 | Type::eResolveStateForward)); | 
|  | 171 |  | 
|  | 172 | dwarf->GetTypeList()->Insert(type_sp); | 
|  | 173 | dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); | 
|  | 174 | clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type); | 
|  | 175 | if (tag_decl) | 
|  | 176 | LinkDeclContextToDIE(tag_decl, die); | 
|  | 177 | else | 
|  | 178 | { | 
|  | 179 | clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die); | 
|  | 180 | if (defn_decl_ctx) | 
|  | 181 | LinkDeclContextToDIE(defn_decl_ctx, die); | 
|  | 182 | } | 
|  | 183 | return type_sp; | 
|  | 184 | } | 
|  | 185 | } | 
|  | 186 | } | 
|  | 187 | } | 
|  | 188 | } | 
|  | 189 | return TypeSP(); | 
|  | 190 | } | 
|  | 191 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 192 | TypeSP | 
|  | 193 | DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, | 
|  | 194 | const DWARFDIE &die, | 
|  | 195 | Log *log, | 
|  | 196 | bool *type_is_new_ptr) | 
|  | 197 | { | 
|  | 198 | TypeSP type_sp; | 
|  | 199 |  | 
|  | 200 | if (type_is_new_ptr) | 
|  | 201 | *type_is_new_ptr = false; | 
|  | 202 |  | 
|  | 203 | AccessType accessibility = eAccessNone; | 
|  | 204 | if (die) | 
|  | 205 | { | 
|  | 206 | SymbolFileDWARF *dwarf = die.GetDWARF(); | 
|  | 207 | if (log) | 
|  | 208 | { | 
|  | 209 | DWARFDIE context_die; | 
|  | 210 | clang::DeclContext *context = GetClangDeclContextContainingDIE (die, &context_die); | 
|  | 211 |  | 
|  | 212 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')", | 
|  | 213 | die.GetOffset(), | 
|  | 214 | static_cast<void*>(context), | 
|  | 215 | context_die.GetOffset(), | 
|  | 216 | die.GetTagAsCString(), | 
|  | 217 | die.GetName()); | 
|  | 218 |  | 
|  | 219 | } | 
|  | 220 | // | 
|  | 221 | //        Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); | 
|  | 222 | //        if (log && dwarf_cu) | 
|  | 223 | //        { | 
|  | 224 | //            StreamString s; | 
|  | 225 | //            die->DumpLocation (this, dwarf_cu, s); | 
|  | 226 | //            dwarf->GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData()); | 
|  | 227 | // | 
|  | 228 | //        } | 
|  | 229 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 230 | Type *type_ptr = dwarf->GetDIEToType().lookup (die.GetDIE()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 231 | TypeList* type_list = dwarf->GetTypeList(); | 
|  | 232 | if (type_ptr == NULL) | 
|  | 233 | { | 
|  | 234 | if (type_is_new_ptr) | 
|  | 235 | *type_is_new_ptr = true; | 
|  | 236 |  | 
|  | 237 | const dw_tag_t tag = die.Tag(); | 
|  | 238 |  | 
|  | 239 | bool is_forward_declaration = false; | 
|  | 240 | DWARFAttributes attributes; | 
|  | 241 | const char *type_name_cstr = NULL; | 
|  | 242 | ConstString type_name_const_str; | 
|  | 243 | Type::ResolveState resolve_state = Type::eResolveStateUnresolved; | 
|  | 244 | uint64_t byte_size = 0; | 
|  | 245 | Declaration decl; | 
|  | 246 |  | 
|  | 247 | Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; | 
|  | 248 | CompilerType clang_type; | 
|  | 249 | DWARFFormValue form_value; | 
|  | 250 |  | 
|  | 251 | dw_attr_t attr; | 
|  | 252 |  | 
|  | 253 | switch (tag) | 
|  | 254 | { | 
| Greg Clayton | a5d1f62 | 2016-01-21 22:26:13 +0000 | [diff] [blame] | 255 | case DW_TAG_typedef: | 
|  | 256 | // Try to parse a typedef from the DWO file first as modules | 
|  | 257 | // can contain typedef'ed structures that have no names like: | 
|  | 258 | // | 
|  | 259 | //  typedef struct { int a; } Foo; | 
|  | 260 | // | 
|  | 261 | // In this case we will have a structure with no name and a | 
|  | 262 | // typedef named "Foo" that points to this unnamed structure. | 
|  | 263 | // The name in the typedef is the only identifier for the struct, | 
|  | 264 | // so always try to get typedefs from DWO files if possible. | 
|  | 265 | // | 
|  | 266 | // The type_sp returned will be empty if the typedef doesn't exist | 
|  | 267 | // in a DWO file, so it is cheap to call this function just to check. | 
|  | 268 | // | 
|  | 269 | // If we don't do this we end up creating a TypeSP that says this | 
|  | 270 | // is a typedef to type 0x123 (the DW_AT_type value would be 0x123 | 
|  | 271 | // in the DW_TAG_typedef), and this is the unnamed structure type. | 
|  | 272 | // We will have a hard time tracking down an unnammed structure | 
|  | 273 | // type in the module DWO file, so we make sure we don't get into | 
|  | 274 | // this situation by always resolving typedefs from the DWO file. | 
|  | 275 | type_sp = ParseTypeFromDWO(die, log); | 
|  | 276 | if (type_sp) | 
|  | 277 | return type_sp; | 
|  | 278 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 279 | case DW_TAG_base_type: | 
|  | 280 | case DW_TAG_pointer_type: | 
|  | 281 | case DW_TAG_reference_type: | 
|  | 282 | case DW_TAG_rvalue_reference_type: | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 283 | case DW_TAG_const_type: | 
|  | 284 | case DW_TAG_restrict_type: | 
|  | 285 | case DW_TAG_volatile_type: | 
|  | 286 | case DW_TAG_unspecified_type: | 
|  | 287 | { | 
|  | 288 | // Set a bit that lets us know that we are currently parsing this | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 289 | dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 290 |  | 
|  | 291 | const size_t num_attributes = die.GetAttributes (attributes); | 
|  | 292 | uint32_t encoding = 0; | 
|  | 293 | lldb::user_id_t encoding_uid = LLDB_INVALID_UID; | 
|  | 294 |  | 
|  | 295 | if (num_attributes > 0) | 
|  | 296 | { | 
|  | 297 | uint32_t i; | 
|  | 298 | for (i=0; i<num_attributes; ++i) | 
|  | 299 | { | 
|  | 300 | attr = attributes.AttributeAtIndex(i); | 
|  | 301 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 302 | { | 
|  | 303 | switch (attr) | 
|  | 304 | { | 
|  | 305 | case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; | 
|  | 306 | case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break; | 
|  | 307 | case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; | 
|  | 308 | case DW_AT_name: | 
|  | 309 |  | 
|  | 310 | type_name_cstr = form_value.AsCString(); | 
|  | 311 | // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't | 
|  | 312 | // include the "&"... | 
|  | 313 | if (tag == DW_TAG_reference_type) | 
|  | 314 | { | 
|  | 315 | if (strchr (type_name_cstr, '&') == NULL) | 
|  | 316 | type_name_cstr = NULL; | 
|  | 317 | } | 
|  | 318 | if (type_name_cstr) | 
|  | 319 | type_name_const_str.SetCString(type_name_cstr); | 
|  | 320 | break; | 
|  | 321 | case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break; | 
|  | 322 | case DW_AT_encoding:    encoding = form_value.Unsigned(); break; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 323 | case DW_AT_type:        encoding_uid = DIERef(form_value).GetUID(); break; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 324 | default: | 
|  | 325 | case DW_AT_sibling: | 
|  | 326 | break; | 
|  | 327 | } | 
|  | 328 | } | 
|  | 329 | } | 
|  | 330 | } | 
|  | 331 |  | 
|  | 332 | DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid); | 
|  | 333 |  | 
|  | 334 | switch (tag) | 
|  | 335 | { | 
|  | 336 | default: | 
|  | 337 | break; | 
|  | 338 |  | 
|  | 339 | case DW_TAG_unspecified_type: | 
|  | 340 | if (strcmp(type_name_cstr, "nullptr_t") == 0 || | 
|  | 341 | strcmp(type_name_cstr, "decltype(nullptr)") == 0 ) | 
|  | 342 | { | 
|  | 343 | resolve_state = Type::eResolveStateFull; | 
|  | 344 | clang_type = m_ast.GetBasicType(eBasicTypeNullPtr); | 
|  | 345 | break; | 
|  | 346 | } | 
|  | 347 | // Fall through to base type below in case we can handle the type there... | 
|  | 348 |  | 
|  | 349 | case DW_TAG_base_type: | 
|  | 350 | resolve_state = Type::eResolveStateFull; | 
|  | 351 | clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, | 
|  | 352 | encoding, | 
|  | 353 | byte_size * 8); | 
|  | 354 | break; | 
|  | 355 |  | 
|  | 356 | case DW_TAG_pointer_type:           encoding_data_type = Type::eEncodingIsPointerUID;           break; | 
|  | 357 | case DW_TAG_reference_type:         encoding_data_type = Type::eEncodingIsLValueReferenceUID;   break; | 
|  | 358 | case DW_TAG_rvalue_reference_type:  encoding_data_type = Type::eEncodingIsRValueReferenceUID;   break; | 
|  | 359 | case DW_TAG_typedef:                encoding_data_type = Type::eEncodingIsTypedefUID;           break; | 
|  | 360 | case DW_TAG_const_type:             encoding_data_type = Type::eEncodingIsConstUID;             break; | 
|  | 361 | case DW_TAG_restrict_type:          encoding_data_type = Type::eEncodingIsRestrictUID;          break; | 
|  | 362 | case DW_TAG_volatile_type:          encoding_data_type = Type::eEncodingIsVolatileUID;          break; | 
|  | 363 | } | 
|  | 364 |  | 
|  | 365 | if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL) | 
|  | 366 | { | 
|  | 367 | bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus); | 
|  | 368 |  | 
|  | 369 | if (translation_unit_is_objc) | 
|  | 370 | { | 
|  | 371 | if (type_name_cstr != NULL) | 
|  | 372 | { | 
|  | 373 | static ConstString g_objc_type_name_id("id"); | 
|  | 374 | static ConstString g_objc_type_name_Class("Class"); | 
|  | 375 | static ConstString g_objc_type_name_selector("SEL"); | 
|  | 376 |  | 
|  | 377 | if (type_name_const_str == g_objc_type_name_id) | 
|  | 378 | { | 
|  | 379 | if (log) | 
|  | 380 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, | 
|  | 381 | "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.", | 
|  | 382 | die.GetOffset(), | 
|  | 383 | die.GetTagAsCString(), | 
|  | 384 | die.GetName()); | 
|  | 385 | clang_type = m_ast.GetBasicType(eBasicTypeObjCID); | 
|  | 386 | encoding_data_type = Type::eEncodingIsUID; | 
|  | 387 | encoding_uid = LLDB_INVALID_UID; | 
|  | 388 | resolve_state = Type::eResolveStateFull; | 
|  | 389 |  | 
|  | 390 | } | 
|  | 391 | else if (type_name_const_str == g_objc_type_name_Class) | 
|  | 392 | { | 
|  | 393 | if (log) | 
|  | 394 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, | 
|  | 395 | "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.", | 
|  | 396 | die.GetOffset(), | 
|  | 397 | die.GetTagAsCString(), | 
|  | 398 | die.GetName()); | 
|  | 399 | clang_type = m_ast.GetBasicType(eBasicTypeObjCClass); | 
|  | 400 | encoding_data_type = Type::eEncodingIsUID; | 
|  | 401 | encoding_uid = LLDB_INVALID_UID; | 
|  | 402 | resolve_state = Type::eResolveStateFull; | 
|  | 403 | } | 
|  | 404 | else if (type_name_const_str == g_objc_type_name_selector) | 
|  | 405 | { | 
|  | 406 | if (log) | 
|  | 407 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, | 
|  | 408 | "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.", | 
|  | 409 | die.GetOffset(), | 
|  | 410 | die.GetTagAsCString(), | 
|  | 411 | die.GetName()); | 
|  | 412 | clang_type = m_ast.GetBasicType(eBasicTypeObjCSel); | 
|  | 413 | encoding_data_type = Type::eEncodingIsUID; | 
|  | 414 | encoding_uid = LLDB_INVALID_UID; | 
|  | 415 | resolve_state = Type::eResolveStateFull; | 
|  | 416 | } | 
|  | 417 | } | 
|  | 418 | else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID) | 
|  | 419 | { | 
|  | 420 | // Clang sometimes erroneously emits id as objc_object*.  In that case we fix up the type to "id". | 
|  | 421 |  | 
|  | 422 | const DWARFDIE encoding_die = die.GetDIE(encoding_uid); | 
|  | 423 |  | 
|  | 424 | if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) | 
|  | 425 | { | 
|  | 426 | if (const char *struct_name = encoding_die.GetName()) | 
|  | 427 | { | 
|  | 428 | if (!strcmp(struct_name, "objc_object")) | 
|  | 429 | { | 
|  | 430 | if (log) | 
|  | 431 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, | 
|  | 432 | "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is 'objc_object*', which we overrode to 'id'.", | 
|  | 433 | die.GetOffset(), | 
|  | 434 | die.GetTagAsCString(), | 
|  | 435 | die.GetName()); | 
|  | 436 | clang_type = m_ast.GetBasicType(eBasicTypeObjCID); | 
|  | 437 | encoding_data_type = Type::eEncodingIsUID; | 
|  | 438 | encoding_uid = LLDB_INVALID_UID; | 
|  | 439 | resolve_state = Type::eResolveStateFull; | 
|  | 440 | } | 
|  | 441 | } | 
|  | 442 | } | 
|  | 443 | } | 
|  | 444 | } | 
|  | 445 | } | 
|  | 446 |  | 
|  | 447 | type_sp.reset( new Type (die.GetID(), | 
|  | 448 | dwarf, | 
|  | 449 | type_name_const_str, | 
|  | 450 | byte_size, | 
|  | 451 | NULL, | 
|  | 452 | encoding_uid, | 
|  | 453 | encoding_data_type, | 
|  | 454 | &decl, | 
|  | 455 | clang_type, | 
|  | 456 | resolve_state)); | 
|  | 457 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 458 | dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 459 |  | 
|  | 460 | //                  Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false); | 
|  | 461 | //                  if (encoding_type != NULL) | 
|  | 462 | //                  { | 
|  | 463 | //                      if (encoding_type != DIE_IS_BEING_PARSED) | 
|  | 464 | //                          type_sp->SetEncodingType(encoding_type); | 
|  | 465 | //                      else | 
|  | 466 | //                          m_indirect_fixups.push_back(type_sp.get()); | 
|  | 467 | //                  } | 
|  | 468 | } | 
|  | 469 | break; | 
|  | 470 |  | 
|  | 471 | case DW_TAG_structure_type: | 
|  | 472 | case DW_TAG_union_type: | 
|  | 473 | case DW_TAG_class_type: | 
|  | 474 | { | 
|  | 475 | // Set a bit that lets us know that we are currently parsing this | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 476 | dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 477 | bool byte_size_valid = false; | 
|  | 478 |  | 
|  | 479 | LanguageType class_language = eLanguageTypeUnknown; | 
|  | 480 | bool is_complete_objc_class = false; | 
|  | 481 | //bool struct_is_class = false; | 
|  | 482 | const size_t num_attributes = die.GetAttributes (attributes); | 
|  | 483 | if (num_attributes > 0) | 
|  | 484 | { | 
|  | 485 | uint32_t i; | 
|  | 486 | for (i=0; i<num_attributes; ++i) | 
|  | 487 | { | 
|  | 488 | attr = attributes.AttributeAtIndex(i); | 
|  | 489 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 490 | { | 
|  | 491 | switch (attr) | 
|  | 492 | { | 
|  | 493 | case DW_AT_decl_file: | 
|  | 494 | if (die.GetCU()->DW_AT_decl_file_attributes_are_invalid()) | 
|  | 495 | { | 
|  | 496 | // llvm-gcc outputs invalid DW_AT_decl_file attributes that always | 
|  | 497 | // point to the compile unit file, so we clear this invalid value | 
|  | 498 | // so that we can still unique types efficiently. | 
|  | 499 | decl.SetFile(FileSpec ("<invalid>", false)); | 
|  | 500 | } | 
|  | 501 | else | 
|  | 502 | decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); | 
|  | 503 | break; | 
|  | 504 |  | 
|  | 505 | case DW_AT_decl_line: | 
|  | 506 | decl.SetLine(form_value.Unsigned()); | 
|  | 507 | break; | 
|  | 508 |  | 
|  | 509 | case DW_AT_decl_column: | 
|  | 510 | decl.SetColumn(form_value.Unsigned()); | 
|  | 511 | break; | 
|  | 512 |  | 
|  | 513 | case DW_AT_name: | 
|  | 514 | type_name_cstr = form_value.AsCString(); | 
|  | 515 | type_name_const_str.SetCString(type_name_cstr); | 
|  | 516 | break; | 
|  | 517 |  | 
|  | 518 | case DW_AT_byte_size: | 
|  | 519 | byte_size = form_value.Unsigned(); | 
|  | 520 | byte_size_valid = true; | 
|  | 521 | break; | 
|  | 522 |  | 
|  | 523 | case DW_AT_accessibility: | 
|  | 524 | accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); | 
|  | 525 | break; | 
|  | 526 |  | 
|  | 527 | case DW_AT_declaration: | 
|  | 528 | is_forward_declaration = form_value.Boolean(); | 
|  | 529 | break; | 
|  | 530 |  | 
|  | 531 | case DW_AT_APPLE_runtime_class: | 
|  | 532 | class_language = (LanguageType)form_value.Signed(); | 
|  | 533 | break; | 
|  | 534 |  | 
|  | 535 | case DW_AT_APPLE_objc_complete_type: | 
|  | 536 | is_complete_objc_class = form_value.Signed(); | 
|  | 537 | break; | 
|  | 538 |  | 
|  | 539 | case DW_AT_allocated: | 
|  | 540 | case DW_AT_associated: | 
|  | 541 | case DW_AT_data_location: | 
|  | 542 | case DW_AT_description: | 
|  | 543 | case DW_AT_start_scope: | 
|  | 544 | case DW_AT_visibility: | 
|  | 545 | default: | 
|  | 546 | case DW_AT_sibling: | 
|  | 547 | break; | 
|  | 548 | } | 
|  | 549 | } | 
|  | 550 | } | 
|  | 551 | } | 
|  | 552 |  | 
|  | 553 | // UniqueDWARFASTType is large, so don't create a local variables on the | 
|  | 554 | // stack, put it on the heap. This function is often called recursively | 
|  | 555 | // and clang isn't good and sharing the stack space for variables in different blocks. | 
|  | 556 | std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType()); | 
|  | 557 |  | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 558 | ConstString unique_typename(type_name_const_str); | 
|  | 559 | Declaration unique_decl(decl); | 
|  | 560 |  | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 561 | if (type_name_const_str) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 562 | { | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 563 | LanguageType die_language = die.GetLanguage(); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 564 | if (Language::LanguageIsCPlusPlus(die_language)) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 565 | { | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 566 | // For C++, we rely solely upon the one definition rule that says only | 
|  | 567 | // one thing can exist at a given decl context. We ignore the file and | 
|  | 568 | // line that things are declared on. | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 569 | std::string qualified_name; | 
|  | 570 | if (die.GetQualifiedName(qualified_name)) | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 571 | unique_typename = ConstString(qualified_name); | 
|  | 572 | unique_decl.Clear(); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 573 | } | 
|  | 574 |  | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 575 | if (dwarf->GetUniqueDWARFASTTypeMap().Find(unique_typename, die, unique_decl, | 
|  | 576 | byte_size_valid ? byte_size : -1, | 
|  | 577 | *unique_ast_entry_ap)) | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 578 | { | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 579 | type_sp = unique_ast_entry_ap->m_type_sp; | 
|  | 580 | if (type_sp) | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 581 | { | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 582 | dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); | 
|  | 583 | return type_sp; | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 584 | } | 
|  | 585 | } | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 586 | } | 
|  | 587 |  | 
|  | 588 | DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); | 
|  | 589 |  | 
|  | 590 | int tag_decl_kind = -1; | 
|  | 591 | AccessType default_accessibility = eAccessNone; | 
|  | 592 | if (tag == DW_TAG_structure_type) | 
|  | 593 | { | 
|  | 594 | tag_decl_kind = clang::TTK_Struct; | 
|  | 595 | default_accessibility = eAccessPublic; | 
|  | 596 | } | 
|  | 597 | else if (tag == DW_TAG_union_type) | 
|  | 598 | { | 
|  | 599 | tag_decl_kind = clang::TTK_Union; | 
|  | 600 | default_accessibility = eAccessPublic; | 
|  | 601 | } | 
|  | 602 | else if (tag == DW_TAG_class_type) | 
|  | 603 | { | 
|  | 604 | tag_decl_kind = clang::TTK_Class; | 
|  | 605 | default_accessibility = eAccessPrivate; | 
|  | 606 | } | 
|  | 607 |  | 
|  | 608 | if (byte_size_valid && byte_size == 0 && type_name_cstr && | 
|  | 609 | die.HasChildren() == false && | 
|  | 610 | sc.comp_unit->GetLanguage() == eLanguageTypeObjC) | 
|  | 611 | { | 
|  | 612 | // Work around an issue with clang at the moment where | 
|  | 613 | // forward declarations for objective C classes are emitted | 
|  | 614 | // as: | 
|  | 615 | //  DW_TAG_structure_type [2] | 
|  | 616 | //  DW_AT_name( "ForwardObjcClass" ) | 
|  | 617 | //  DW_AT_byte_size( 0x00 ) | 
|  | 618 | //  DW_AT_decl_file( "..." ) | 
|  | 619 | //  DW_AT_decl_line( 1 ) | 
|  | 620 | // | 
|  | 621 | // Note that there is no DW_AT_declaration and there are | 
|  | 622 | // no children, and the byte size is zero. | 
|  | 623 | is_forward_declaration = true; | 
|  | 624 | } | 
|  | 625 |  | 
|  | 626 | if (class_language == eLanguageTypeObjC || | 
|  | 627 | class_language == eLanguageTypeObjC_plus_plus) | 
|  | 628 | { | 
|  | 629 | if (!is_complete_objc_class && die.Supports_DW_AT_APPLE_objc_complete_type()) | 
|  | 630 | { | 
|  | 631 | // We have a valid eSymbolTypeObjCClass class symbol whose | 
|  | 632 | // name matches the current objective C class that we | 
|  | 633 | // are trying to find and this DIE isn't the complete | 
|  | 634 | // definition (we checked is_complete_objc_class above and | 
|  | 635 | // know it is false), so the real definition is in here somewhere | 
|  | 636 | type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true); | 
|  | 637 |  | 
|  | 638 | if (!type_sp) | 
|  | 639 | { | 
|  | 640 | SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile(); | 
|  | 641 | if (debug_map_symfile) | 
|  | 642 | { | 
|  | 643 | // We weren't able to find a full declaration in | 
|  | 644 | // this DWARF, see if we have a declaration anywhere | 
|  | 645 | // else... | 
|  | 646 | type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true); | 
|  | 647 | } | 
|  | 648 | } | 
|  | 649 |  | 
|  | 650 | if (type_sp) | 
|  | 651 | { | 
|  | 652 | if (log) | 
|  | 653 | { | 
|  | 654 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, | 
|  | 655 | "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8" PRIx64, | 
|  | 656 | static_cast<void*>(this), | 
|  | 657 | die.GetOffset(), | 
|  | 658 | DW_TAG_value_to_name(tag), | 
|  | 659 | type_name_cstr, | 
|  | 660 | type_sp->GetID()); | 
|  | 661 | } | 
|  | 662 |  | 
|  | 663 | // We found a real definition for this type elsewhere | 
|  | 664 | // so lets use it and cache the fact that we found | 
|  | 665 | // a complete type for this die | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 666 | dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 667 | return type_sp; | 
|  | 668 | } | 
|  | 669 | } | 
|  | 670 | } | 
|  | 671 |  | 
|  | 672 |  | 
|  | 673 | if (is_forward_declaration) | 
|  | 674 | { | 
|  | 675 | // We have a forward declaration to a type and we need | 
|  | 676 | // to try and find a full declaration. We look in the | 
|  | 677 | // current type index just in case we have a forward | 
|  | 678 | // declaration followed by an actual declarations in the | 
|  | 679 | // DWARF. If this fails, we need to look elsewhere... | 
|  | 680 | if (log) | 
|  | 681 | { | 
|  | 682 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, | 
|  | 683 | "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type", | 
|  | 684 | static_cast<void*>(this), | 
|  | 685 | die.GetOffset(), | 
|  | 686 | DW_TAG_value_to_name(tag), | 
|  | 687 | type_name_cstr); | 
|  | 688 | } | 
|  | 689 |  | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 690 | // See if the type comes from a DWO module and if so, track down that type. | 
|  | 691 | type_sp = ParseTypeFromDWO(die, log); | 
|  | 692 | if (type_sp) | 
|  | 693 | return type_sp; | 
|  | 694 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 695 | DWARFDeclContext die_decl_ctx; | 
|  | 696 | die.GetDWARFDeclContext(die_decl_ctx); | 
|  | 697 |  | 
|  | 698 | //type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); | 
|  | 699 | type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); | 
|  | 700 |  | 
|  | 701 | if (!type_sp) | 
|  | 702 | { | 
|  | 703 | SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile(); | 
|  | 704 | if (debug_map_symfile) | 
|  | 705 | { | 
|  | 706 | // We weren't able to find a full declaration in | 
|  | 707 | // this DWARF, see if we have a declaration anywhere | 
|  | 708 | // else... | 
|  | 709 | type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); | 
|  | 710 | } | 
|  | 711 | } | 
|  | 712 |  | 
|  | 713 | if (type_sp) | 
|  | 714 | { | 
|  | 715 | if (log) | 
|  | 716 | { | 
|  | 717 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, | 
|  | 718 | "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64, | 
|  | 719 | static_cast<void*>(this), | 
|  | 720 | die.GetOffset(), | 
|  | 721 | DW_TAG_value_to_name(tag), | 
|  | 722 | type_name_cstr, | 
|  | 723 | type_sp->GetID()); | 
|  | 724 | } | 
|  | 725 |  | 
|  | 726 | // We found a real definition for this type elsewhere | 
|  | 727 | // so lets use it and cache the fact that we found | 
|  | 728 | // a complete type for this die | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 729 | dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 730 | clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE( | 
|  | 731 | dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID()))); | 
|  | 732 | if (defn_decl_ctx) | 
|  | 733 | LinkDeclContextToDIE(defn_decl_ctx, die); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 734 | return type_sp; | 
|  | 735 | } | 
|  | 736 | } | 
|  | 737 | assert (tag_decl_kind != -1); | 
|  | 738 | bool clang_type_was_created = false; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 739 | clang_type.SetCompilerType(&m_ast, dwarf->GetForwardDeclDieToClangType().lookup (die.GetDIE())); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 740 | if (!clang_type) | 
|  | 741 | { | 
|  | 742 | clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (die, nullptr); | 
|  | 743 | if (accessibility == eAccessNone && decl_ctx) | 
|  | 744 | { | 
|  | 745 | // Check the decl context that contains this class/struct/union. | 
|  | 746 | // If it is a class we must give it an accessibility. | 
|  | 747 | const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind(); | 
|  | 748 | if (DeclKindIsCXXClass (containing_decl_kind)) | 
|  | 749 | accessibility = default_accessibility; | 
|  | 750 | } | 
|  | 751 |  | 
|  | 752 | ClangASTMetadata metadata; | 
|  | 753 | metadata.SetUserID(die.GetID()); | 
|  | 754 | metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual (die)); | 
|  | 755 |  | 
|  | 756 | if (type_name_cstr && strchr (type_name_cstr, '<')) | 
|  | 757 | { | 
|  | 758 | ClangASTContext::TemplateParameterInfos template_param_infos; | 
|  | 759 | if (ParseTemplateParameterInfos (die, template_param_infos)) | 
|  | 760 | { | 
|  | 761 | clang::ClassTemplateDecl *class_template_decl = m_ast.ParseClassTemplateDecl (decl_ctx, | 
|  | 762 | accessibility, | 
|  | 763 | type_name_cstr, | 
|  | 764 | tag_decl_kind, | 
|  | 765 | template_param_infos); | 
|  | 766 |  | 
|  | 767 | clang::ClassTemplateSpecializationDecl *class_specialization_decl = m_ast.CreateClassTemplateSpecializationDecl (decl_ctx, | 
|  | 768 | class_template_decl, | 
|  | 769 | tag_decl_kind, | 
|  | 770 | template_param_infos); | 
|  | 771 | clang_type = m_ast.CreateClassTemplateSpecializationType (class_specialization_decl); | 
|  | 772 | clang_type_was_created = true; | 
|  | 773 |  | 
|  | 774 | m_ast.SetMetadata (class_template_decl, metadata); | 
|  | 775 | m_ast.SetMetadata (class_specialization_decl, metadata); | 
|  | 776 | } | 
|  | 777 | } | 
|  | 778 |  | 
|  | 779 | if (!clang_type_was_created) | 
|  | 780 | { | 
|  | 781 | clang_type_was_created = true; | 
|  | 782 | clang_type = m_ast.CreateRecordType (decl_ctx, | 
|  | 783 | accessibility, | 
|  | 784 | type_name_cstr, | 
|  | 785 | tag_decl_kind, | 
|  | 786 | class_language, | 
|  | 787 | &metadata); | 
|  | 788 | } | 
|  | 789 | } | 
|  | 790 |  | 
|  | 791 | // Store a forward declaration to this class type in case any | 
|  | 792 | // parameters in any class methods need it for the clang | 
|  | 793 | // types for function prototypes. | 
|  | 794 | LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die); | 
|  | 795 | type_sp.reset (new Type (die.GetID(), | 
|  | 796 | dwarf, | 
|  | 797 | type_name_const_str, | 
|  | 798 | byte_size, | 
|  | 799 | NULL, | 
|  | 800 | LLDB_INVALID_UID, | 
|  | 801 | Type::eEncodingIsUID, | 
|  | 802 | &decl, | 
|  | 803 | clang_type, | 
|  | 804 | Type::eResolveStateForward)); | 
|  | 805 |  | 
|  | 806 | type_sp->SetIsCompleteObjCClass(is_complete_objc_class); | 
|  | 807 |  | 
|  | 808 |  | 
|  | 809 | // Add our type to the unique type map so we don't | 
|  | 810 | // end up creating many copies of the same type over | 
|  | 811 | // and over in the ASTContext for our module | 
|  | 812 | unique_ast_entry_ap->m_type_sp = type_sp; | 
|  | 813 | unique_ast_entry_ap->m_die = die; | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 814 | unique_ast_entry_ap->m_declaration = unique_decl; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 815 | unique_ast_entry_ap->m_byte_size = byte_size; | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 816 | dwarf->GetUniqueDWARFASTTypeMap().Insert (unique_typename, | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 817 | *unique_ast_entry_ap); | 
|  | 818 |  | 
|  | 819 | if (is_forward_declaration && die.HasChildren()) | 
|  | 820 | { | 
|  | 821 | // Check to see if the DIE actually has a definition, some version of GCC will | 
|  | 822 | // emit DIEs with DW_AT_declaration set to true, but yet still have subprogram, | 
|  | 823 | // members, or inheritance, so we can't trust it | 
|  | 824 | DWARFDIE child_die = die.GetFirstChild(); | 
|  | 825 | while (child_die) | 
|  | 826 | { | 
|  | 827 | switch (child_die.Tag()) | 
|  | 828 | { | 
|  | 829 | case DW_TAG_inheritance: | 
|  | 830 | case DW_TAG_subprogram: | 
|  | 831 | case DW_TAG_member: | 
|  | 832 | case DW_TAG_APPLE_property: | 
|  | 833 | case DW_TAG_class_type: | 
|  | 834 | case DW_TAG_structure_type: | 
|  | 835 | case DW_TAG_enumeration_type: | 
|  | 836 | case DW_TAG_typedef: | 
|  | 837 | case DW_TAG_union_type: | 
|  | 838 | child_die.Clear(); | 
|  | 839 | is_forward_declaration = false; | 
|  | 840 | break; | 
|  | 841 | default: | 
|  | 842 | child_die = child_die.GetSibling(); | 
|  | 843 | break; | 
|  | 844 | } | 
|  | 845 | } | 
|  | 846 | } | 
|  | 847 |  | 
|  | 848 | if (!is_forward_declaration) | 
|  | 849 | { | 
|  | 850 | // Always start the definition for a class type so that | 
|  | 851 | // if the class has child classes or types that require | 
|  | 852 | // the class to be created for use as their decl contexts | 
|  | 853 | // the class will be ready to accept these child definitions. | 
|  | 854 | if (die.HasChildren() == false) | 
|  | 855 | { | 
|  | 856 | // No children for this struct/union/class, lets finish it | 
|  | 857 | ClangASTContext::StartTagDeclarationDefinition (clang_type); | 
|  | 858 | ClangASTContext::CompleteTagDeclarationDefinition (clang_type); | 
|  | 859 |  | 
|  | 860 | if (tag == DW_TAG_structure_type) // this only applies in C | 
|  | 861 | { | 
|  | 862 | clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(clang_type); | 
|  | 863 |  | 
|  | 864 | if (record_decl) | 
|  | 865 | m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo())); | 
|  | 866 | } | 
|  | 867 | } | 
|  | 868 | else if (clang_type_was_created) | 
|  | 869 | { | 
|  | 870 | // Start the definition if the class is not objective C since | 
|  | 871 | // the underlying decls respond to isCompleteDefinition(). Objective | 
|  | 872 | // C decls don't respond to isCompleteDefinition() so we can't | 
|  | 873 | // start the declaration definition right away. For C++ class/union/structs | 
|  | 874 | // we want to start the definition in case the class is needed as the | 
|  | 875 | // declaration context for a contained class or type without the need | 
|  | 876 | // to complete that type.. | 
|  | 877 |  | 
|  | 878 | if (class_language != eLanguageTypeObjC && | 
|  | 879 | class_language != eLanguageTypeObjC_plus_plus) | 
|  | 880 | ClangASTContext::StartTagDeclarationDefinition (clang_type); | 
|  | 881 |  | 
|  | 882 | // Leave this as a forward declaration until we need | 
|  | 883 | // to know the details of the type. lldb_private::Type | 
|  | 884 | // will automatically call the SymbolFile virtual function | 
|  | 885 | // "SymbolFileDWARF::CompleteType(Type *)" | 
|  | 886 | // When the definition needs to be defined. | 
| Tamas Berghammer | 69d0b33 | 2015-10-09 12:43:08 +0000 | [diff] [blame] | 887 | assert(!dwarf->GetForwardDeclClangTypeToDie().count(ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) && | 
|  | 888 | "Type already in the forward declaration map!"); | 
| Greg Clayton | 565aaf6 | 2016-02-11 23:36:57 +0000 | [diff] [blame] | 889 | // Can't assume m_ast.GetSymbolFile() is actually a SymbolFileDWARF, it can be a | 
|  | 890 | // SymbolFileDWARFDebugMap for Apple binaries. | 
|  | 891 | //assert(((SymbolFileDWARF*)m_ast.GetSymbolFile())->UserIDMatches(die.GetDIERef().GetUID()) && | 
|  | 892 | //       "Adding incorrect type to forward declaration map"); | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 893 | dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = clang_type.GetOpaqueQualType(); | 
|  | 894 | dwarf->GetForwardDeclClangTypeToDie()[ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] = die.GetDIERef(); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 895 | m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), true); | 
|  | 896 | } | 
|  | 897 | } | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 898 | } | 
|  | 899 | break; | 
|  | 900 |  | 
|  | 901 | case DW_TAG_enumeration_type: | 
|  | 902 | { | 
|  | 903 | // Set a bit that lets us know that we are currently parsing this | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 904 | dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 905 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 906 | DWARFFormValue encoding_form; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 907 |  | 
|  | 908 | const size_t num_attributes = die.GetAttributes (attributes); | 
|  | 909 | if (num_attributes > 0) | 
|  | 910 | { | 
|  | 911 | uint32_t i; | 
|  | 912 |  | 
|  | 913 | for (i=0; i<num_attributes; ++i) | 
|  | 914 | { | 
|  | 915 | attr = attributes.AttributeAtIndex(i); | 
|  | 916 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 917 | { | 
|  | 918 | switch (attr) | 
|  | 919 | { | 
|  | 920 | case DW_AT_decl_file:       decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; | 
|  | 921 | case DW_AT_decl_line:       decl.SetLine(form_value.Unsigned()); break; | 
|  | 922 | case DW_AT_decl_column:     decl.SetColumn(form_value.Unsigned()); break; | 
|  | 923 | case DW_AT_name: | 
|  | 924 | type_name_cstr = form_value.AsCString(); | 
|  | 925 | type_name_const_str.SetCString(type_name_cstr); | 
|  | 926 | break; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 927 | case DW_AT_type:            encoding_form = form_value; break; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 928 | case DW_AT_byte_size:       byte_size = form_value.Unsigned(); break; | 
|  | 929 | case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 930 | case DW_AT_declaration:     is_forward_declaration = form_value.Boolean(); break; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 931 | case DW_AT_allocated: | 
|  | 932 | case DW_AT_associated: | 
|  | 933 | case DW_AT_bit_stride: | 
|  | 934 | case DW_AT_byte_stride: | 
|  | 935 | case DW_AT_data_location: | 
|  | 936 | case DW_AT_description: | 
|  | 937 | case DW_AT_start_scope: | 
|  | 938 | case DW_AT_visibility: | 
|  | 939 | case DW_AT_specification: | 
|  | 940 | case DW_AT_abstract_origin: | 
|  | 941 | case DW_AT_sibling: | 
|  | 942 | break; | 
|  | 943 | } | 
|  | 944 | } | 
|  | 945 | } | 
|  | 946 |  | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 947 | if (is_forward_declaration) | 
|  | 948 | { | 
|  | 949 | type_sp = ParseTypeFromDWO(die, log); | 
|  | 950 | if (type_sp) | 
|  | 951 | return type_sp; | 
|  | 952 |  | 
|  | 953 | DWARFDeclContext die_decl_ctx; | 
|  | 954 | die.GetDWARFDeclContext(die_decl_ctx); | 
|  | 955 |  | 
|  | 956 | type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); | 
|  | 957 |  | 
|  | 958 | if (!type_sp) | 
|  | 959 | { | 
|  | 960 | SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile(); | 
|  | 961 | if (debug_map_symfile) | 
|  | 962 | { | 
|  | 963 | // We weren't able to find a full declaration in | 
|  | 964 | // this DWARF, see if we have a declaration anywhere | 
|  | 965 | // else... | 
|  | 966 | type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); | 
|  | 967 | } | 
|  | 968 | } | 
|  | 969 |  | 
|  | 970 | if (type_sp) | 
|  | 971 | { | 
|  | 972 | if (log) | 
|  | 973 | { | 
|  | 974 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, | 
|  | 975 | "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64, | 
|  | 976 | static_cast<void*>(this), | 
|  | 977 | die.GetOffset(), | 
|  | 978 | DW_TAG_value_to_name(tag), | 
|  | 979 | type_name_cstr, | 
|  | 980 | type_sp->GetID()); | 
|  | 981 | } | 
|  | 982 |  | 
|  | 983 | // We found a real definition for this type elsewhere | 
|  | 984 | // so lets use it and cache the fact that we found | 
|  | 985 | // a complete type for this die | 
|  | 986 | dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); | 
|  | 987 | clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE( | 
|  | 988 | dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID()))); | 
|  | 989 | if (defn_decl_ctx) | 
|  | 990 | LinkDeclContextToDIE(defn_decl_ctx, die); | 
|  | 991 | return type_sp; | 
|  | 992 | } | 
|  | 993 |  | 
|  | 994 | } | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 995 | DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); | 
|  | 996 |  | 
|  | 997 | CompilerType enumerator_clang_type; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 998 | clang_type.SetCompilerType (&m_ast, dwarf->GetForwardDeclDieToClangType().lookup (die.GetDIE())); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 999 | if (!clang_type) | 
|  | 1000 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1001 | if (encoding_form.IsValid()) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1002 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1003 | Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(encoding_form).GetUID()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1004 | if (enumerator_type) | 
|  | 1005 | enumerator_clang_type = enumerator_type->GetFullCompilerType (); | 
|  | 1006 | } | 
|  | 1007 |  | 
|  | 1008 | if (!enumerator_clang_type) | 
|  | 1009 | enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, | 
|  | 1010 | DW_ATE_signed, | 
|  | 1011 | byte_size * 8); | 
|  | 1012 |  | 
|  | 1013 | clang_type = m_ast.CreateEnumerationType (type_name_cstr, | 
|  | 1014 | GetClangDeclContextContainingDIE (die, nullptr), | 
|  | 1015 | decl, | 
|  | 1016 | enumerator_clang_type); | 
|  | 1017 | } | 
|  | 1018 | else | 
|  | 1019 | { | 
|  | 1020 | enumerator_clang_type = m_ast.GetEnumerationIntegerType (clang_type.GetOpaqueQualType()); | 
|  | 1021 | } | 
|  | 1022 |  | 
|  | 1023 | LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); | 
|  | 1024 |  | 
|  | 1025 | type_sp.reset( new Type (die.GetID(), | 
|  | 1026 | dwarf, | 
|  | 1027 | type_name_const_str, | 
|  | 1028 | byte_size, | 
|  | 1029 | NULL, | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1030 | DIERef(encoding_form).GetUID(), | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1031 | Type::eEncodingIsUID, | 
|  | 1032 | &decl, | 
|  | 1033 | clang_type, | 
|  | 1034 | Type::eResolveStateForward)); | 
|  | 1035 |  | 
|  | 1036 | ClangASTContext::StartTagDeclarationDefinition (clang_type); | 
|  | 1037 | if (die.HasChildren()) | 
|  | 1038 | { | 
|  | 1039 | SymbolContext cu_sc(die.GetLLDBCompileUnit()); | 
|  | 1040 | bool is_signed = false; | 
|  | 1041 | enumerator_clang_type.IsIntegerType(is_signed); | 
|  | 1042 | ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), die); | 
|  | 1043 | } | 
|  | 1044 | ClangASTContext::CompleteTagDeclarationDefinition (clang_type); | 
|  | 1045 | } | 
|  | 1046 | } | 
|  | 1047 | break; | 
|  | 1048 |  | 
|  | 1049 | case DW_TAG_inlined_subroutine: | 
|  | 1050 | case DW_TAG_subprogram: | 
|  | 1051 | case DW_TAG_subroutine_type: | 
|  | 1052 | { | 
|  | 1053 | // Set a bit that lets us know that we are currently parsing this | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1054 | dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1055 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1056 | DWARFFormValue type_die_form; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1057 | bool is_variadic = false; | 
|  | 1058 | bool is_inline = false; | 
|  | 1059 | bool is_static = false; | 
|  | 1060 | bool is_virtual = false; | 
|  | 1061 | bool is_explicit = false; | 
|  | 1062 | bool is_artificial = false; | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 1063 | bool has_template_params = false; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1064 | DWARFFormValue specification_die_form; | 
|  | 1065 | DWARFFormValue abstract_origin_die_form; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1066 | dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET; | 
|  | 1067 |  | 
|  | 1068 | unsigned type_quals = 0; | 
|  | 1069 | clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern | 
|  | 1070 |  | 
|  | 1071 |  | 
|  | 1072 | const size_t num_attributes = die.GetAttributes (attributes); | 
|  | 1073 | if (num_attributes > 0) | 
|  | 1074 | { | 
|  | 1075 | uint32_t i; | 
|  | 1076 | for (i=0; i<num_attributes; ++i) | 
|  | 1077 | { | 
|  | 1078 | attr = attributes.AttributeAtIndex(i); | 
|  | 1079 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 1080 | { | 
|  | 1081 | switch (attr) | 
|  | 1082 | { | 
|  | 1083 | case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; | 
|  | 1084 | case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break; | 
|  | 1085 | case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; | 
|  | 1086 | case DW_AT_name: | 
|  | 1087 | type_name_cstr = form_value.AsCString(); | 
|  | 1088 | type_name_const_str.SetCString(type_name_cstr); | 
|  | 1089 | break; | 
|  | 1090 |  | 
|  | 1091 | case DW_AT_linkage_name: | 
|  | 1092 | case DW_AT_MIPS_linkage_name:   break; // mangled = form_value.AsCString(&dwarf->get_debug_str_data()); break; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1093 | case DW_AT_type:                type_die_form = form_value; break; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1094 | case DW_AT_accessibility:       accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; | 
|  | 1095 | case DW_AT_declaration:         break; // is_forward_declaration = form_value.Boolean(); break; | 
|  | 1096 | case DW_AT_inline:              is_inline = form_value.Boolean(); break; | 
|  | 1097 | case DW_AT_virtuality:          is_virtual = form_value.Boolean();  break; | 
|  | 1098 | case DW_AT_explicit:            is_explicit = form_value.Boolean();  break; | 
|  | 1099 | case DW_AT_artificial:          is_artificial = form_value.Boolean();  break; | 
|  | 1100 |  | 
|  | 1101 |  | 
|  | 1102 | case DW_AT_external: | 
|  | 1103 | if (form_value.Unsigned()) | 
|  | 1104 | { | 
|  | 1105 | if (storage == clang::SC_None) | 
|  | 1106 | storage = clang::SC_Extern; | 
|  | 1107 | else | 
|  | 1108 | storage = clang::SC_PrivateExtern; | 
|  | 1109 | } | 
|  | 1110 | break; | 
|  | 1111 |  | 
|  | 1112 | case DW_AT_specification: | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1113 | specification_die_form = form_value; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1114 | break; | 
|  | 1115 |  | 
|  | 1116 | case DW_AT_abstract_origin: | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1117 | abstract_origin_die_form = form_value; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1118 | break; | 
|  | 1119 |  | 
|  | 1120 | case DW_AT_object_pointer: | 
|  | 1121 | object_pointer_die_offset = form_value.Reference(); | 
|  | 1122 | break; | 
|  | 1123 |  | 
|  | 1124 | case DW_AT_allocated: | 
|  | 1125 | case DW_AT_associated: | 
|  | 1126 | case DW_AT_address_class: | 
|  | 1127 | case DW_AT_calling_convention: | 
|  | 1128 | case DW_AT_data_location: | 
|  | 1129 | case DW_AT_elemental: | 
|  | 1130 | case DW_AT_entry_pc: | 
|  | 1131 | case DW_AT_frame_base: | 
|  | 1132 | case DW_AT_high_pc: | 
|  | 1133 | case DW_AT_low_pc: | 
|  | 1134 | case DW_AT_prototyped: | 
|  | 1135 | case DW_AT_pure: | 
|  | 1136 | case DW_AT_ranges: | 
|  | 1137 | case DW_AT_recursive: | 
|  | 1138 | case DW_AT_return_addr: | 
|  | 1139 | case DW_AT_segment: | 
|  | 1140 | case DW_AT_start_scope: | 
|  | 1141 | case DW_AT_static_link: | 
|  | 1142 | case DW_AT_trampoline: | 
|  | 1143 | case DW_AT_visibility: | 
|  | 1144 | case DW_AT_vtable_elem_location: | 
|  | 1145 | case DW_AT_description: | 
|  | 1146 | case DW_AT_sibling: | 
|  | 1147 | break; | 
|  | 1148 | } | 
|  | 1149 | } | 
|  | 1150 | } | 
|  | 1151 | } | 
|  | 1152 |  | 
|  | 1153 | std::string object_pointer_name; | 
|  | 1154 | if (object_pointer_die_offset != DW_INVALID_OFFSET) | 
|  | 1155 | { | 
|  | 1156 | DWARFDIE object_pointer_die = die.GetDIE (object_pointer_die_offset); | 
|  | 1157 | if (object_pointer_die) | 
|  | 1158 | { | 
|  | 1159 | const char *object_pointer_name_cstr = object_pointer_die.GetName(); | 
|  | 1160 | if (object_pointer_name_cstr) | 
|  | 1161 | object_pointer_name = object_pointer_name_cstr; | 
|  | 1162 | } | 
|  | 1163 | } | 
|  | 1164 |  | 
|  | 1165 | DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); | 
|  | 1166 |  | 
|  | 1167 | CompilerType return_clang_type; | 
|  | 1168 | Type *func_type = NULL; | 
|  | 1169 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1170 | if (type_die_form.IsValid()) | 
|  | 1171 | func_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1172 |  | 
|  | 1173 | if (func_type) | 
|  | 1174 | return_clang_type = func_type->GetForwardCompilerType (); | 
|  | 1175 | else | 
|  | 1176 | return_clang_type = m_ast.GetBasicType(eBasicTypeVoid); | 
|  | 1177 |  | 
|  | 1178 |  | 
|  | 1179 | std::vector<CompilerType> function_param_types; | 
|  | 1180 | std::vector<clang::ParmVarDecl*> function_param_decls; | 
|  | 1181 |  | 
|  | 1182 | // Parse the function children for the parameters | 
|  | 1183 |  | 
|  | 1184 | DWARFDIE decl_ctx_die; | 
|  | 1185 | clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, &decl_ctx_die); | 
|  | 1186 | const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind(); | 
|  | 1187 |  | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 1188 | bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1189 | // Start off static. This will be set to false in ParseChildParameters(...) | 
|  | 1190 | // if we find a "this" parameters as the first parameter | 
|  | 1191 | if (is_cxx_method) | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 1192 | { | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1193 | is_static = true; | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 1194 | } | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1195 |  | 
|  | 1196 | if (die.HasChildren()) | 
|  | 1197 | { | 
|  | 1198 | bool skip_artificial = true; | 
|  | 1199 | ParseChildParameters (sc, | 
|  | 1200 | containing_decl_ctx, | 
|  | 1201 | die, | 
|  | 1202 | skip_artificial, | 
|  | 1203 | is_static, | 
|  | 1204 | is_variadic, | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 1205 | has_template_params, | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1206 | function_param_types, | 
|  | 1207 | function_param_decls, | 
|  | 1208 | type_quals); | 
|  | 1209 | } | 
|  | 1210 |  | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 1211 | bool ignore_containing_context = false; | 
|  | 1212 | // Check for templatized class member functions. If we had any DW_TAG_template_type_parameter | 
|  | 1213 | // or DW_TAG_template_value_parameter the DW_TAG_subprogram DIE, then we can't let this become | 
|  | 1214 | // a method in a class. Why? Because templatized functions are only emitted if one of the | 
|  | 1215 | // templatized methods is used in the current compile unit and we will end up with classes | 
|  | 1216 | // that may or may not include these member functions and this means one class won't match another | 
|  | 1217 | // class definition and it affects our ability to use a class in the clang expression parser. So | 
|  | 1218 | // for the greater good, we currently must not allow any template member functions in a class definition. | 
| Greg Clayton | 343f898 | 2016-02-09 23:25:54 +0000 | [diff] [blame] | 1219 | if (is_cxx_method && has_template_params) | 
|  | 1220 | { | 
|  | 1221 | ignore_containing_context = true; | 
|  | 1222 | is_cxx_method = false; | 
|  | 1223 | } | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 1224 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1225 | // clang_type will get the function prototype clang type after this call | 
|  | 1226 | clang_type = m_ast.CreateFunctionType (return_clang_type, | 
|  | 1227 | function_param_types.data(), | 
|  | 1228 | function_param_types.size(), | 
|  | 1229 | is_variadic, | 
|  | 1230 | type_quals); | 
|  | 1231 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1232 |  | 
|  | 1233 | if (type_name_cstr) | 
|  | 1234 | { | 
|  | 1235 | bool type_handled = false; | 
|  | 1236 | if (tag == DW_TAG_subprogram || | 
|  | 1237 | tag == DW_TAG_inlined_subroutine) | 
|  | 1238 | { | 
| Jim Ingham | aa816b8 | 2015-09-02 01:59:14 +0000 | [diff] [blame] | 1239 | ObjCLanguage::MethodName objc_method (type_name_cstr, true); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1240 | if (objc_method.IsValid(true)) | 
|  | 1241 | { | 
|  | 1242 | CompilerType class_opaque_type; | 
|  | 1243 | ConstString class_name(objc_method.GetClassName()); | 
|  | 1244 | if (class_name) | 
|  | 1245 | { | 
|  | 1246 | TypeSP complete_objc_class_type_sp (dwarf->FindCompleteObjCDefinitionTypeForDIE (DWARFDIE(), class_name, false)); | 
|  | 1247 |  | 
|  | 1248 | if (complete_objc_class_type_sp) | 
|  | 1249 | { | 
|  | 1250 | CompilerType type_clang_forward_type = complete_objc_class_type_sp->GetForwardCompilerType (); | 
|  | 1251 | if (ClangASTContext::IsObjCObjectOrInterfaceType(type_clang_forward_type)) | 
|  | 1252 | class_opaque_type = type_clang_forward_type; | 
|  | 1253 | } | 
|  | 1254 | } | 
|  | 1255 |  | 
|  | 1256 | if (class_opaque_type) | 
|  | 1257 | { | 
|  | 1258 | // If accessibility isn't set to anything valid, assume public for | 
|  | 1259 | // now... | 
|  | 1260 | if (accessibility == eAccessNone) | 
|  | 1261 | accessibility = eAccessPublic; | 
|  | 1262 |  | 
|  | 1263 | clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType (class_opaque_type, | 
|  | 1264 | type_name_cstr, | 
|  | 1265 | clang_type, | 
|  | 1266 | accessibility, | 
|  | 1267 | is_artificial); | 
|  | 1268 | type_handled = objc_method_decl != NULL; | 
|  | 1269 | if (type_handled) | 
|  | 1270 | { | 
|  | 1271 | LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die); | 
|  | 1272 | m_ast.SetMetadataAsUserID (objc_method_decl, die.GetID()); | 
|  | 1273 | } | 
|  | 1274 | else | 
|  | 1275 | { | 
|  | 1276 | dwarf->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), please file a bug and attach the file at the start of this error message", | 
|  | 1277 | die.GetOffset(), | 
|  | 1278 | tag, | 
|  | 1279 | DW_TAG_value_to_name(tag)); | 
|  | 1280 | } | 
|  | 1281 | } | 
|  | 1282 | } | 
|  | 1283 | else if (is_cxx_method) | 
|  | 1284 | { | 
|  | 1285 | // Look at the parent of this DIE and see if is is | 
|  | 1286 | // a class or struct and see if this is actually a | 
|  | 1287 | // C++ method | 
|  | 1288 | Type *class_type = dwarf->ResolveType (decl_ctx_die); | 
|  | 1289 | if (class_type) | 
|  | 1290 | { | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1291 | bool alternate_defn = false; | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 1292 | if (class_type->GetID() != decl_ctx_die.GetID() || decl_ctx_die.GetContainingDWOModuleDIE()) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1293 | { | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1294 | alternate_defn = true; | 
|  | 1295 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1296 | // We uniqued the parent class of this function to another class | 
|  | 1297 | // so we now need to associate all dies under "decl_ctx_die" to | 
|  | 1298 | // DIEs in the DIE for "class_type"... | 
|  | 1299 | SymbolFileDWARF *class_symfile = NULL; | 
|  | 1300 | DWARFDIE class_type_die; | 
|  | 1301 |  | 
|  | 1302 | SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile(); | 
|  | 1303 | if (debug_map_symfile) | 
|  | 1304 | { | 
|  | 1305 | class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID())); | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1306 | class_type_die = class_symfile->DebugInfo()->GetDIE (DIERef(class_type->GetID())); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1307 | } | 
|  | 1308 | else | 
|  | 1309 | { | 
|  | 1310 | class_symfile = dwarf; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1311 | class_type_die = dwarf->DebugInfo()->GetDIE (DIERef(class_type->GetID())); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1312 | } | 
|  | 1313 | if (class_type_die) | 
|  | 1314 | { | 
|  | 1315 | DWARFDIECollection failures; | 
|  | 1316 |  | 
|  | 1317 | CopyUniqueClassMethodTypes (decl_ctx_die, | 
|  | 1318 | class_type_die, | 
|  | 1319 | class_type, | 
|  | 1320 | failures); | 
|  | 1321 |  | 
|  | 1322 | // FIXME do something with these failures that's smarter than | 
|  | 1323 | // just dropping them on the ground.  Unfortunately classes don't | 
|  | 1324 | // like having stuff added to them after their definitions are | 
|  | 1325 | // complete... | 
|  | 1326 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1327 | type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1328 | if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) | 
|  | 1329 | { | 
|  | 1330 | type_sp = type_ptr->shared_from_this(); | 
|  | 1331 | break; | 
|  | 1332 | } | 
|  | 1333 | } | 
|  | 1334 | } | 
|  | 1335 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1336 | if (specification_die_form.IsValid()) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1337 | { | 
|  | 1338 | // We have a specification which we are going to base our function | 
|  | 1339 | // prototype off of, so we need this type to be completed so that the | 
|  | 1340 | // m_die_to_decl_ctx for the method in the specification has a valid | 
|  | 1341 | // clang decl context. | 
|  | 1342 | class_type->GetForwardCompilerType (); | 
|  | 1343 | // If we have a specification, then the function type should have been | 
|  | 1344 | // made with the specification and not with this die. | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1345 | DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(DIERef(specification_die_form)); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1346 | clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (spec_die); | 
|  | 1347 | if (spec_clang_decl_ctx) | 
|  | 1348 | { | 
|  | 1349 | LinkDeclContextToDIE(spec_clang_decl_ctx, die); | 
|  | 1350 | } | 
|  | 1351 | else | 
|  | 1352 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1353 | dwarf->GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8" PRIx64 ") has no decl\n", | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1354 | die.GetID(), | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1355 | specification_die_form.Reference()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1356 | } | 
|  | 1357 | type_handled = true; | 
|  | 1358 | } | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1359 | else if (abstract_origin_die_form.IsValid()) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1360 | { | 
|  | 1361 | // We have a specification which we are going to base our function | 
|  | 1362 | // prototype off of, so we need this type to be completed so that the | 
|  | 1363 | // m_die_to_decl_ctx for the method in the abstract origin has a valid | 
|  | 1364 | // clang decl context. | 
|  | 1365 | class_type->GetForwardCompilerType (); | 
|  | 1366 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1367 | DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (DIERef(abstract_origin_die_form)); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1368 | clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (abs_die); | 
|  | 1369 | if (abs_clang_decl_ctx) | 
|  | 1370 | { | 
|  | 1371 | LinkDeclContextToDIE (abs_clang_decl_ctx, die); | 
|  | 1372 | } | 
|  | 1373 | else | 
|  | 1374 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1375 | dwarf->GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8" PRIx64 ") has no decl\n", | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1376 | die.GetID(), | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1377 | abstract_origin_die_form.Reference()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1378 | } | 
|  | 1379 | type_handled = true; | 
|  | 1380 | } | 
|  | 1381 | else | 
|  | 1382 | { | 
|  | 1383 | CompilerType class_opaque_type = class_type->GetForwardCompilerType (); | 
|  | 1384 | if (ClangASTContext::IsCXXClassType(class_opaque_type)) | 
|  | 1385 | { | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1386 | if (class_opaque_type.IsBeingDefined () || alternate_defn) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1387 | { | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1388 | if (!is_static && !die.HasChildren()) | 
|  | 1389 | { | 
|  | 1390 | // We have a C++ member function with no children (this pointer!) | 
|  | 1391 | // and clang will get mad if we try and make a function that isn't | 
|  | 1392 | // well formed in the DWARF, so we will just skip it... | 
|  | 1393 | type_handled = true; | 
|  | 1394 | } | 
|  | 1395 | else | 
|  | 1396 | { | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1397 | bool add_method = true; | 
|  | 1398 | if (alternate_defn) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1399 | { | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1400 | // If an alternate definition for the class exists, then add the method only if an | 
|  | 1401 | // equivalent is not already present. | 
|  | 1402 | clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(class_opaque_type.GetOpaqueQualType()); | 
|  | 1403 | if (record_decl) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1404 | { | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1405 | for (auto method_iter = record_decl->method_begin(); | 
|  | 1406 | method_iter != record_decl->method_end(); | 
|  | 1407 | method_iter++) | 
|  | 1408 | { | 
|  | 1409 | clang::CXXMethodDecl *method_decl = *method_iter; | 
|  | 1410 | if (method_decl->getNameInfo().getAsString() == std::string(type_name_cstr)) | 
|  | 1411 | { | 
|  | 1412 | if (method_decl->getType() == ClangASTContext::GetQualType(clang_type)) | 
|  | 1413 | { | 
|  | 1414 | add_method = false; | 
|  | 1415 | LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(method_decl), die); | 
|  | 1416 | type_handled = true; | 
|  | 1417 |  | 
|  | 1418 | break; | 
|  | 1419 | } | 
|  | 1420 | } | 
|  | 1421 | } | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1422 | } | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1423 | } | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1424 |  | 
|  | 1425 | if (add_method) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1426 | { | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1427 | // REMOVE THE CRASH DESCRIPTION BELOW | 
|  | 1428 | Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8" PRIx64 " from %s", | 
|  | 1429 | type_name_cstr, | 
|  | 1430 | class_type->GetName().GetCString(), | 
|  | 1431 | die.GetID(), | 
|  | 1432 | dwarf->GetObjectFile()->GetFileSpec().GetPath().c_str()); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1433 |  | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1434 | const bool is_attr_used = false; | 
|  | 1435 | // Neither GCC 4.2 nor clang++ currently set a valid accessibility | 
|  | 1436 | // in the DWARF for C++ methods... Default to public for now... | 
|  | 1437 | if (accessibility == eAccessNone) | 
|  | 1438 | accessibility = eAccessPublic; | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1439 |  | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1440 | clang::CXXMethodDecl *cxx_method_decl; | 
|  | 1441 | cxx_method_decl = m_ast.AddMethodToCXXRecordType (class_opaque_type.GetOpaqueQualType(), | 
|  | 1442 | type_name_cstr, | 
|  | 1443 | clang_type, | 
|  | 1444 | accessibility, | 
|  | 1445 | is_virtual, | 
|  | 1446 | is_static, | 
|  | 1447 | is_inline, | 
|  | 1448 | is_explicit, | 
|  | 1449 | is_attr_used, | 
|  | 1450 | is_artificial); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1451 |  | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1452 | type_handled = cxx_method_decl != NULL; | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1453 |  | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1454 | if (type_handled) | 
|  | 1455 | { | 
|  | 1456 | LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1457 |  | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1458 | Host::SetCrashDescription (NULL); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1459 |  | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1460 | ClangASTMetadata metadata; | 
|  | 1461 | metadata.SetUserID(die.GetID()); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1462 |  | 
| Siva Chandra | 27e33a8 | 2015-10-07 22:11:52 +0000 | [diff] [blame] | 1463 | if (!object_pointer_name.empty()) | 
|  | 1464 | { | 
|  | 1465 | metadata.SetObjectPtrName(object_pointer_name.c_str()); | 
|  | 1466 | if (log) | 
|  | 1467 | log->Printf ("Setting object pointer name: %s on method object %p.\n", | 
|  | 1468 | object_pointer_name.c_str(), | 
|  | 1469 | static_cast<void*>(cxx_method_decl)); | 
|  | 1470 | } | 
|  | 1471 | m_ast.SetMetadata (cxx_method_decl, metadata); | 
|  | 1472 | } | 
|  | 1473 | else | 
|  | 1474 | { | 
|  | 1475 | ignore_containing_context = true; | 
|  | 1476 | } | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1477 | } | 
|  | 1478 | } | 
|  | 1479 | } | 
|  | 1480 | else | 
|  | 1481 | { | 
|  | 1482 | // We were asked to parse the type for a method in a class, yet the | 
|  | 1483 | // class hasn't been asked to complete itself through the | 
|  | 1484 | // clang::ExternalASTSource protocol, so we need to just have the | 
|  | 1485 | // class complete itself and do things the right way, then our | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1486 | // DIE should then have an entry in the dwarf->GetDIEToType() map. First | 
|  | 1487 | // we need to modify the dwarf->GetDIEToType() so it doesn't think we are | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1488 | // trying to parse this DIE anymore... | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1489 | dwarf->GetDIEToType()[die.GetDIE()] = NULL; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1490 |  | 
|  | 1491 | // Now we get the full type to force our class type to complete itself | 
|  | 1492 | // using the clang::ExternalASTSource protocol which will parse all | 
|  | 1493 | // base classes and all methods (including the method for this DIE). | 
|  | 1494 | class_type->GetFullCompilerType (); | 
|  | 1495 |  | 
|  | 1496 | // The type for this DIE should have been filled in the function call above | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1497 | type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1498 | if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) | 
|  | 1499 | { | 
|  | 1500 | type_sp = type_ptr->shared_from_this(); | 
|  | 1501 | break; | 
|  | 1502 | } | 
|  | 1503 |  | 
|  | 1504 | // FIXME This is fixing some even uglier behavior but we really need to | 
|  | 1505 | // uniq the methods of each class as well as the class itself. | 
|  | 1506 | // <rdar://problem/11240464> | 
|  | 1507 | type_handled = true; | 
|  | 1508 | } | 
|  | 1509 | } | 
|  | 1510 | } | 
|  | 1511 | } | 
|  | 1512 | } | 
|  | 1513 | } | 
|  | 1514 |  | 
|  | 1515 | if (!type_handled) | 
|  | 1516 | { | 
|  | 1517 | // We just have a function that isn't part of a class | 
|  | 1518 | clang::FunctionDecl *function_decl = m_ast.CreateFunctionDeclaration (ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, | 
|  | 1519 | type_name_cstr, | 
|  | 1520 | clang_type, | 
|  | 1521 | storage, | 
|  | 1522 | is_inline); | 
|  | 1523 |  | 
|  | 1524 | //                            if (template_param_infos.GetSize() > 0) | 
|  | 1525 | //                            { | 
|  | 1526 | //                                clang::FunctionTemplateDecl *func_template_decl = CreateFunctionTemplateDecl (containing_decl_ctx, | 
|  | 1527 | //                                                                                                              function_decl, | 
|  | 1528 | //                                                                                                              type_name_cstr, | 
|  | 1529 | //                                                                                                              template_param_infos); | 
|  | 1530 | // | 
|  | 1531 | //                                CreateFunctionTemplateSpecializationInfo (function_decl, | 
|  | 1532 | //                                                                          func_template_decl, | 
|  | 1533 | //                                                                          template_param_infos); | 
|  | 1534 | //                            } | 
|  | 1535 | // Add the decl to our DIE to decl context map | 
|  | 1536 | assert (function_decl); | 
|  | 1537 | LinkDeclContextToDIE(function_decl, die); | 
|  | 1538 | if (!function_param_decls.empty()) | 
|  | 1539 | m_ast.SetFunctionParameters (function_decl, | 
|  | 1540 | &function_param_decls.front(), | 
|  | 1541 | function_param_decls.size()); | 
|  | 1542 |  | 
|  | 1543 | ClangASTMetadata metadata; | 
|  | 1544 | metadata.SetUserID(die.GetID()); | 
|  | 1545 |  | 
|  | 1546 | if (!object_pointer_name.empty()) | 
|  | 1547 | { | 
|  | 1548 | metadata.SetObjectPtrName(object_pointer_name.c_str()); | 
|  | 1549 | if (log) | 
|  | 1550 | log->Printf ("Setting object pointer name: %s on function object %p.", | 
|  | 1551 | object_pointer_name.c_str(), | 
|  | 1552 | static_cast<void*>(function_decl)); | 
|  | 1553 | } | 
|  | 1554 | m_ast.SetMetadata (function_decl, metadata); | 
|  | 1555 | } | 
|  | 1556 | } | 
|  | 1557 | type_sp.reset( new Type (die.GetID(), | 
|  | 1558 | dwarf, | 
|  | 1559 | type_name_const_str, | 
|  | 1560 | 0, | 
|  | 1561 | NULL, | 
|  | 1562 | LLDB_INVALID_UID, | 
|  | 1563 | Type::eEncodingIsUID, | 
|  | 1564 | &decl, | 
|  | 1565 | clang_type, | 
|  | 1566 | Type::eResolveStateFull)); | 
|  | 1567 | assert(type_sp.get()); | 
|  | 1568 | } | 
|  | 1569 | break; | 
|  | 1570 |  | 
|  | 1571 | case DW_TAG_array_type: | 
|  | 1572 | { | 
|  | 1573 | // Set a bit that lets us know that we are currently parsing this | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1574 | dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1575 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1576 | DWARFFormValue type_die_form; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1577 | int64_t first_index = 0; | 
|  | 1578 | uint32_t byte_stride = 0; | 
|  | 1579 | uint32_t bit_stride = 0; | 
|  | 1580 | bool is_vector = false; | 
|  | 1581 | const size_t num_attributes = die.GetAttributes (attributes); | 
|  | 1582 |  | 
|  | 1583 | if (num_attributes > 0) | 
|  | 1584 | { | 
|  | 1585 | uint32_t i; | 
|  | 1586 | for (i=0; i<num_attributes; ++i) | 
|  | 1587 | { | 
|  | 1588 | attr = attributes.AttributeAtIndex(i); | 
|  | 1589 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 1590 | { | 
|  | 1591 | switch (attr) | 
|  | 1592 | { | 
|  | 1593 | case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; | 
|  | 1594 | case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break; | 
|  | 1595 | case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; | 
|  | 1596 | case DW_AT_name: | 
|  | 1597 | type_name_cstr = form_value.AsCString(); | 
|  | 1598 | type_name_const_str.SetCString(type_name_cstr); | 
|  | 1599 | break; | 
|  | 1600 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1601 | case DW_AT_type:            type_die_form = form_value; break; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1602 | case DW_AT_byte_size:       break; // byte_size = form_value.Unsigned(); break; | 
|  | 1603 | case DW_AT_byte_stride:     byte_stride = form_value.Unsigned(); break; | 
|  | 1604 | case DW_AT_bit_stride:      bit_stride = form_value.Unsigned(); break; | 
|  | 1605 | case DW_AT_GNU_vector:      is_vector = form_value.Boolean(); break; | 
|  | 1606 | case DW_AT_accessibility:   break; // accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; | 
|  | 1607 | case DW_AT_declaration:     break; // is_forward_declaration = form_value.Boolean(); break; | 
|  | 1608 | case DW_AT_allocated: | 
|  | 1609 | case DW_AT_associated: | 
|  | 1610 | case DW_AT_data_location: | 
|  | 1611 | case DW_AT_description: | 
|  | 1612 | case DW_AT_ordering: | 
|  | 1613 | case DW_AT_start_scope: | 
|  | 1614 | case DW_AT_visibility: | 
|  | 1615 | case DW_AT_specification: | 
|  | 1616 | case DW_AT_abstract_origin: | 
|  | 1617 | case DW_AT_sibling: | 
|  | 1618 | break; | 
|  | 1619 | } | 
|  | 1620 | } | 
|  | 1621 | } | 
|  | 1622 |  | 
|  | 1623 | DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr); | 
|  | 1624 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1625 | Type *element_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1626 |  | 
|  | 1627 | if (element_type) | 
|  | 1628 | { | 
|  | 1629 | std::vector<uint64_t> element_orders; | 
|  | 1630 | ParseChildArrayInfo(sc, die, first_index, element_orders, byte_stride, bit_stride); | 
|  | 1631 | if (byte_stride == 0 && bit_stride == 0) | 
|  | 1632 | byte_stride = element_type->GetByteSize(); | 
|  | 1633 | CompilerType array_element_type = element_type->GetForwardCompilerType (); | 
|  | 1634 | uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; | 
|  | 1635 | if (element_orders.size() > 0) | 
|  | 1636 | { | 
|  | 1637 | uint64_t num_elements = 0; | 
|  | 1638 | std::vector<uint64_t>::const_reverse_iterator pos; | 
|  | 1639 | std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend(); | 
|  | 1640 | for (pos = element_orders.rbegin(); pos != end; ++pos) | 
|  | 1641 | { | 
|  | 1642 | num_elements = *pos; | 
|  | 1643 | clang_type = m_ast.CreateArrayType (array_element_type, | 
|  | 1644 | num_elements, | 
|  | 1645 | is_vector); | 
|  | 1646 | array_element_type = clang_type; | 
|  | 1647 | array_element_bit_stride = num_elements ? | 
|  | 1648 | array_element_bit_stride * num_elements : | 
|  | 1649 | array_element_bit_stride; | 
|  | 1650 | } | 
|  | 1651 | } | 
|  | 1652 | else | 
|  | 1653 | { | 
|  | 1654 | clang_type = m_ast.CreateArrayType (array_element_type, 0, is_vector); | 
|  | 1655 | } | 
|  | 1656 | ConstString empty_name; | 
|  | 1657 | type_sp.reset( new Type (die.GetID(), | 
|  | 1658 | dwarf, | 
|  | 1659 | empty_name, | 
|  | 1660 | array_element_bit_stride / 8, | 
|  | 1661 | NULL, | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1662 | DIERef(type_die_form).GetUID(), | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1663 | Type::eEncodingIsUID, | 
|  | 1664 | &decl, | 
|  | 1665 | clang_type, | 
|  | 1666 | Type::eResolveStateFull)); | 
|  | 1667 | type_sp->SetEncodingType (element_type); | 
|  | 1668 | } | 
|  | 1669 | } | 
|  | 1670 | } | 
|  | 1671 | break; | 
|  | 1672 |  | 
|  | 1673 | case DW_TAG_ptr_to_member_type: | 
|  | 1674 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1675 | DWARFFormValue type_die_form; | 
|  | 1676 | DWARFFormValue containing_type_die_form; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1677 |  | 
|  | 1678 | const size_t num_attributes = die.GetAttributes (attributes); | 
|  | 1679 |  | 
|  | 1680 | if (num_attributes > 0) { | 
|  | 1681 | uint32_t i; | 
|  | 1682 | for (i=0; i<num_attributes; ++i) | 
|  | 1683 | { | 
|  | 1684 | attr = attributes.AttributeAtIndex(i); | 
|  | 1685 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 1686 | { | 
|  | 1687 | switch (attr) | 
|  | 1688 | { | 
|  | 1689 | case DW_AT_type: | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1690 | type_die_form = form_value; break; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1691 | case DW_AT_containing_type: | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1692 | containing_type_die_form = form_value; break; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1693 | } | 
|  | 1694 | } | 
|  | 1695 | } | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1696 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1697 | Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID()); | 
|  | 1698 | Type *class_type = dwarf->ResolveTypeUID(DIERef(containing_type_die_form).GetUID()); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1699 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1700 | CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType (); | 
|  | 1701 | CompilerType class_clang_type = class_type->GetLayoutCompilerType (); | 
|  | 1702 |  | 
| Tamas Berghammer | c9eb2fc | 2015-10-26 18:10:55 +0000 | [diff] [blame] | 1703 | clang_type = ClangASTContext::CreateMemberPointerType(class_clang_type, pointee_clang_type); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1704 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1705 | byte_size = clang_type.GetByteSize(nullptr); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1706 |  | 
|  | 1707 | type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, byte_size, NULL, | 
|  | 1708 | LLDB_INVALID_UID, Type::eEncodingIsUID, NULL, clang_type, | 
|  | 1709 | Type::eResolveStateForward)); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1710 | } | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1711 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1712 | break; | 
|  | 1713 | } | 
|  | 1714 | default: | 
|  | 1715 | dwarf->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: unhandled type tag 0x%4.4x (%s), please file a bug and attach the file at the start of this error message", | 
|  | 1716 | die.GetOffset(), | 
|  | 1717 | tag, | 
|  | 1718 | DW_TAG_value_to_name(tag)); | 
|  | 1719 | break; | 
|  | 1720 | } | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1721 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1722 | if (type_sp.get()) | 
|  | 1723 | { | 
|  | 1724 | DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die); | 
|  | 1725 | dw_tag_t sc_parent_tag = sc_parent_die.Tag(); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1726 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1727 | SymbolContextScope * symbol_context_scope = NULL; | 
|  | 1728 | if (sc_parent_tag == DW_TAG_compile_unit) | 
|  | 1729 | { | 
|  | 1730 | symbol_context_scope = sc.comp_unit; | 
|  | 1731 | } | 
|  | 1732 | else if (sc.function != NULL && sc_parent_die) | 
|  | 1733 | { | 
|  | 1734 | symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); | 
|  | 1735 | if (symbol_context_scope == NULL) | 
|  | 1736 | symbol_context_scope = sc.function; | 
|  | 1737 | } | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1738 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1739 | if (symbol_context_scope != NULL) | 
|  | 1740 | { | 
|  | 1741 | type_sp->SetSymbolContextScope(symbol_context_scope); | 
|  | 1742 | } | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1743 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1744 | // We are ready to put this type into the uniqued list up at the module level | 
|  | 1745 | type_list->Insert (type_sp); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 1746 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1747 | dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1748 | } | 
|  | 1749 | } | 
|  | 1750 | else if (type_ptr != DIE_IS_BEING_PARSED) | 
|  | 1751 | { | 
|  | 1752 | type_sp = type_ptr->shared_from_this(); | 
|  | 1753 | } | 
|  | 1754 | } | 
|  | 1755 | return type_sp; | 
|  | 1756 | } | 
|  | 1757 |  | 
|  | 1758 | // DWARF parsing functions | 
|  | 1759 |  | 
|  | 1760 | class DWARFASTParserClang::DelayedAddObjCClassProperty | 
|  | 1761 | { | 
|  | 1762 | public: | 
|  | 1763 | DelayedAddObjCClassProperty(const CompilerType     &class_opaque_type, | 
|  | 1764 | const char             *property_name, | 
|  | 1765 | const CompilerType     &property_opaque_type,  // The property type is only required if you don't have an ivar decl | 
|  | 1766 | clang::ObjCIvarDecl    *ivar_decl, | 
|  | 1767 | const char             *property_setter_name, | 
|  | 1768 | const char             *property_getter_name, | 
|  | 1769 | uint32_t                property_attributes, | 
|  | 1770 | const ClangASTMetadata *metadata) : | 
|  | 1771 | m_class_opaque_type     (class_opaque_type), | 
|  | 1772 | m_property_name         (property_name), | 
|  | 1773 | m_property_opaque_type  (property_opaque_type), | 
|  | 1774 | m_ivar_decl             (ivar_decl), | 
|  | 1775 | m_property_setter_name  (property_setter_name), | 
|  | 1776 | m_property_getter_name  (property_getter_name), | 
|  | 1777 | m_property_attributes   (property_attributes) | 
|  | 1778 | { | 
|  | 1779 | if (metadata != NULL) | 
|  | 1780 | { | 
|  | 1781 | m_metadata_ap.reset(new ClangASTMetadata()); | 
|  | 1782 | *m_metadata_ap = *metadata; | 
|  | 1783 | } | 
|  | 1784 | } | 
|  | 1785 |  | 
|  | 1786 | DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs) | 
|  | 1787 | { | 
|  | 1788 | *this = rhs; | 
|  | 1789 | } | 
|  | 1790 |  | 
|  | 1791 | DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs) | 
|  | 1792 | { | 
|  | 1793 | m_class_opaque_type    = rhs.m_class_opaque_type; | 
|  | 1794 | m_property_name        = rhs.m_property_name; | 
|  | 1795 | m_property_opaque_type = rhs.m_property_opaque_type; | 
|  | 1796 | m_ivar_decl            = rhs.m_ivar_decl; | 
|  | 1797 | m_property_setter_name = rhs.m_property_setter_name; | 
|  | 1798 | m_property_getter_name = rhs.m_property_getter_name; | 
|  | 1799 | m_property_attributes  = rhs.m_property_attributes; | 
|  | 1800 |  | 
|  | 1801 | if (rhs.m_metadata_ap.get()) | 
|  | 1802 | { | 
|  | 1803 | m_metadata_ap.reset (new ClangASTMetadata()); | 
|  | 1804 | *m_metadata_ap = *rhs.m_metadata_ap; | 
|  | 1805 | } | 
|  | 1806 | return *this; | 
|  | 1807 | } | 
|  | 1808 |  | 
|  | 1809 | bool | 
|  | 1810 | Finalize() | 
|  | 1811 | { | 
| Zachary Turner | 89a7938 | 2015-10-02 22:47:14 +0000 | [diff] [blame] | 1812 | return ClangASTContext::AddObjCClassProperty (m_class_opaque_type, | 
|  | 1813 | m_property_name, | 
|  | 1814 | m_property_opaque_type, | 
|  | 1815 | m_ivar_decl, | 
|  | 1816 | m_property_setter_name, | 
|  | 1817 | m_property_getter_name, | 
|  | 1818 | m_property_attributes, | 
|  | 1819 | m_metadata_ap.get()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1820 | } | 
|  | 1821 |  | 
|  | 1822 | private: | 
|  | 1823 | CompilerType            m_class_opaque_type; | 
|  | 1824 | const char             *m_property_name; | 
|  | 1825 | CompilerType            m_property_opaque_type; | 
|  | 1826 | clang::ObjCIvarDecl    *m_ivar_decl; | 
|  | 1827 | const char             *m_property_setter_name; | 
|  | 1828 | const char             *m_property_getter_name; | 
|  | 1829 | uint32_t                m_property_attributes; | 
|  | 1830 | std::unique_ptr<ClangASTMetadata> m_metadata_ap; | 
|  | 1831 | }; | 
|  | 1832 |  | 
|  | 1833 | bool | 
|  | 1834 | DWARFASTParserClang::ParseTemplateDIE (const DWARFDIE &die, | 
|  | 1835 | ClangASTContext::TemplateParameterInfos &template_param_infos) | 
|  | 1836 | { | 
|  | 1837 | const dw_tag_t tag = die.Tag(); | 
|  | 1838 |  | 
|  | 1839 | switch (tag) | 
|  | 1840 | { | 
|  | 1841 | case DW_TAG_template_type_parameter: | 
|  | 1842 | case DW_TAG_template_value_parameter: | 
|  | 1843 | { | 
|  | 1844 | DWARFAttributes attributes; | 
|  | 1845 | const size_t num_attributes = die.GetAttributes (attributes); | 
|  | 1846 | const char *name = NULL; | 
|  | 1847 | Type *lldb_type = NULL; | 
|  | 1848 | CompilerType clang_type; | 
|  | 1849 | uint64_t uval64 = 0; | 
|  | 1850 | bool uval64_valid = false; | 
|  | 1851 | if (num_attributes > 0) | 
|  | 1852 | { | 
|  | 1853 | DWARFFormValue form_value; | 
|  | 1854 | for (size_t i=0; i<num_attributes; ++i) | 
|  | 1855 | { | 
|  | 1856 | const dw_attr_t attr = attributes.AttributeAtIndex(i); | 
|  | 1857 |  | 
|  | 1858 | switch (attr) | 
|  | 1859 | { | 
|  | 1860 | case DW_AT_name: | 
|  | 1861 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 1862 | name = form_value.AsCString(); | 
|  | 1863 | break; | 
|  | 1864 |  | 
|  | 1865 | case DW_AT_type: | 
|  | 1866 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 1867 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 1868 | lldb_type = die.ResolveTypeUID(DIERef(form_value).GetUID()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1869 | if (lldb_type) | 
|  | 1870 | clang_type = lldb_type->GetForwardCompilerType (); | 
|  | 1871 | } | 
|  | 1872 | break; | 
|  | 1873 |  | 
|  | 1874 | case DW_AT_const_value: | 
|  | 1875 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 1876 | { | 
|  | 1877 | uval64_valid = true; | 
|  | 1878 | uval64 = form_value.Unsigned(); | 
|  | 1879 | } | 
|  | 1880 | break; | 
|  | 1881 | default: | 
|  | 1882 | break; | 
|  | 1883 | } | 
|  | 1884 | } | 
|  | 1885 |  | 
|  | 1886 | clang::ASTContext *ast = m_ast.getASTContext(); | 
|  | 1887 | if (!clang_type) | 
|  | 1888 | clang_type = m_ast.GetBasicType(eBasicTypeVoid); | 
|  | 1889 |  | 
|  | 1890 | if (clang_type) | 
|  | 1891 | { | 
|  | 1892 | bool is_signed = false; | 
|  | 1893 | if (name && name[0]) | 
|  | 1894 | template_param_infos.names.push_back(name); | 
|  | 1895 | else | 
|  | 1896 | template_param_infos.names.push_back(NULL); | 
|  | 1897 |  | 
|  | 1898 | if (tag == DW_TAG_template_value_parameter && | 
|  | 1899 | lldb_type != NULL && | 
|  | 1900 | clang_type.IsIntegerType (is_signed) && | 
|  | 1901 | uval64_valid) | 
|  | 1902 | { | 
|  | 1903 | llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed); | 
|  | 1904 | template_param_infos.args.push_back (clang::TemplateArgument (*ast, | 
|  | 1905 | llvm::APSInt(apint), | 
|  | 1906 | ClangASTContext::GetQualType(clang_type))); | 
|  | 1907 | } | 
|  | 1908 | else | 
|  | 1909 | { | 
|  | 1910 | template_param_infos.args.push_back (clang::TemplateArgument (ClangASTContext::GetQualType(clang_type))); | 
|  | 1911 | } | 
|  | 1912 | } | 
|  | 1913 | else | 
|  | 1914 | { | 
|  | 1915 | return false; | 
|  | 1916 | } | 
|  | 1917 |  | 
|  | 1918 | } | 
|  | 1919 | } | 
|  | 1920 | return true; | 
|  | 1921 |  | 
|  | 1922 | default: | 
|  | 1923 | break; | 
|  | 1924 | } | 
|  | 1925 | return false; | 
|  | 1926 | } | 
|  | 1927 |  | 
|  | 1928 | bool | 
|  | 1929 | DWARFASTParserClang::ParseTemplateParameterInfos (const DWARFDIE &parent_die, | 
|  | 1930 | ClangASTContext::TemplateParameterInfos &template_param_infos) | 
|  | 1931 | { | 
|  | 1932 |  | 
|  | 1933 | if (!parent_die) | 
|  | 1934 | return false; | 
|  | 1935 |  | 
|  | 1936 | Args template_parameter_names; | 
|  | 1937 | for (DWARFDIE die = parent_die.GetFirstChild(); | 
|  | 1938 | die.IsValid(); | 
|  | 1939 | die = die.GetSibling()) | 
|  | 1940 | { | 
|  | 1941 | const dw_tag_t tag = die.Tag(); | 
|  | 1942 |  | 
|  | 1943 | switch (tag) | 
|  | 1944 | { | 
|  | 1945 | case DW_TAG_template_type_parameter: | 
|  | 1946 | case DW_TAG_template_value_parameter: | 
|  | 1947 | ParseTemplateDIE (die, template_param_infos); | 
|  | 1948 | break; | 
|  | 1949 |  | 
|  | 1950 | default: | 
|  | 1951 | break; | 
|  | 1952 | } | 
|  | 1953 | } | 
|  | 1954 | if (template_param_infos.args.empty()) | 
|  | 1955 | return false; | 
|  | 1956 | return template_param_infos.args.size() == template_param_infos.names.size(); | 
|  | 1957 | } | 
|  | 1958 |  | 
|  | 1959 | bool | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 1960 | DWARFASTParserClang::CanCompleteType (const lldb_private::CompilerType &compiler_type) | 
|  | 1961 | { | 
|  | 1962 | if (m_clang_ast_importer_ap) | 
|  | 1963 | return ClangASTContext::CanImport(compiler_type, GetClangASTImporter()); | 
|  | 1964 | else | 
|  | 1965 | return false; | 
|  | 1966 | } | 
|  | 1967 |  | 
|  | 1968 | bool | 
|  | 1969 | DWARFASTParserClang::CompleteType (const lldb_private::CompilerType &compiler_type) | 
|  | 1970 | { | 
|  | 1971 | if (CanCompleteType(compiler_type)) | 
|  | 1972 | { | 
|  | 1973 | if (ClangASTContext::Import(compiler_type, GetClangASTImporter())) | 
|  | 1974 | { | 
|  | 1975 | ClangASTContext::CompleteTagDeclarationDefinition(compiler_type); | 
|  | 1976 | return true; | 
|  | 1977 | } | 
|  | 1978 | else | 
|  | 1979 | { | 
|  | 1980 | ClangASTContext::SetHasExternalStorage (compiler_type.GetOpaqueQualType(), false); | 
|  | 1981 | } | 
|  | 1982 | } | 
|  | 1983 | return false; | 
|  | 1984 | } | 
|  | 1985 |  | 
|  | 1986 | bool | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1987 | DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die, | 
|  | 1988 | lldb_private::Type *type, | 
|  | 1989 | CompilerType &clang_type) | 
|  | 1990 | { | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 1991 | SymbolFileDWARF *dwarf = die.GetDWARF(); | 
|  | 1992 |  | 
|  | 1993 | lldb_private::Mutex::Locker locker(dwarf->GetObjectFile()->GetModule()->GetMutex()); | 
|  | 1994 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 1995 | // Disable external storage for this type so we don't get anymore | 
|  | 1996 | // clang::ExternalASTSource queries for this type. | 
|  | 1997 | m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), false); | 
|  | 1998 |  | 
|  | 1999 | if (!die) | 
|  | 2000 | return false; | 
|  | 2001 |  | 
|  | 2002 | const dw_tag_t tag = die.Tag(); | 
|  | 2003 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2004 | Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION)); | 
|  | 2005 | if (log) | 
|  | 2006 | dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log, | 
|  | 2007 | "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", | 
|  | 2008 | die.GetID(), | 
|  | 2009 | die.GetTagAsCString(), | 
|  | 2010 | type->GetName().AsCString()); | 
|  | 2011 | assert (clang_type); | 
|  | 2012 | DWARFAttributes attributes; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2013 | switch (tag) | 
|  | 2014 | { | 
|  | 2015 | case DW_TAG_structure_type: | 
|  | 2016 | case DW_TAG_union_type: | 
|  | 2017 | case DW_TAG_class_type: | 
|  | 2018 | { | 
|  | 2019 | LayoutInfo layout_info; | 
|  | 2020 |  | 
|  | 2021 | { | 
|  | 2022 | if (die.HasChildren()) | 
|  | 2023 | { | 
|  | 2024 | LanguageType class_language = eLanguageTypeUnknown; | 
|  | 2025 | if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type)) | 
|  | 2026 | { | 
|  | 2027 | class_language = eLanguageTypeObjC; | 
|  | 2028 | // For objective C we don't start the definition when | 
|  | 2029 | // the class is created. | 
|  | 2030 | ClangASTContext::StartTagDeclarationDefinition (clang_type); | 
|  | 2031 | } | 
|  | 2032 |  | 
|  | 2033 | int tag_decl_kind = -1; | 
|  | 2034 | AccessType default_accessibility = eAccessNone; | 
|  | 2035 | if (tag == DW_TAG_structure_type) | 
|  | 2036 | { | 
|  | 2037 | tag_decl_kind = clang::TTK_Struct; | 
|  | 2038 | default_accessibility = eAccessPublic; | 
|  | 2039 | } | 
|  | 2040 | else if (tag == DW_TAG_union_type) | 
|  | 2041 | { | 
|  | 2042 | tag_decl_kind = clang::TTK_Union; | 
|  | 2043 | default_accessibility = eAccessPublic; | 
|  | 2044 | } | 
|  | 2045 | else if (tag == DW_TAG_class_type) | 
|  | 2046 | { | 
|  | 2047 | tag_decl_kind = clang::TTK_Class; | 
|  | 2048 | default_accessibility = eAccessPrivate; | 
|  | 2049 | } | 
|  | 2050 |  | 
|  | 2051 | SymbolContext sc(die.GetLLDBCompileUnit()); | 
|  | 2052 | std::vector<clang::CXXBaseSpecifier *> base_classes; | 
|  | 2053 | std::vector<int> member_accessibilities; | 
|  | 2054 | bool is_a_class = false; | 
|  | 2055 | // Parse members and base classes first | 
|  | 2056 | DWARFDIECollection member_function_dies; | 
|  | 2057 |  | 
|  | 2058 | DelayedPropertyList delayed_properties; | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 2059 | ParseChildMembers (sc, | 
|  | 2060 | die, | 
|  | 2061 | clang_type, | 
|  | 2062 | class_language, | 
|  | 2063 | base_classes, | 
|  | 2064 | member_accessibilities, | 
|  | 2065 | member_function_dies, | 
|  | 2066 | delayed_properties, | 
|  | 2067 | default_accessibility, | 
|  | 2068 | is_a_class, | 
|  | 2069 | layout_info); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2070 |  | 
|  | 2071 | // Now parse any methods if there were any... | 
|  | 2072 | size_t num_functions = member_function_dies.Size(); | 
|  | 2073 | if (num_functions > 0) | 
|  | 2074 | { | 
|  | 2075 | for (size_t i=0; i<num_functions; ++i) | 
|  | 2076 | { | 
|  | 2077 | dwarf->ResolveType(member_function_dies.GetDIEAtIndex(i)); | 
|  | 2078 | } | 
|  | 2079 | } | 
|  | 2080 |  | 
|  | 2081 | if (class_language == eLanguageTypeObjC) | 
|  | 2082 | { | 
|  | 2083 | ConstString class_name (clang_type.GetTypeName()); | 
|  | 2084 | if (class_name) | 
|  | 2085 | { | 
|  | 2086 | DIEArray method_die_offsets; | 
|  | 2087 | dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets); | 
|  | 2088 |  | 
|  | 2089 | if (!method_die_offsets.empty()) | 
|  | 2090 | { | 
|  | 2091 | DWARFDebugInfo* debug_info = dwarf->DebugInfo(); | 
|  | 2092 |  | 
|  | 2093 | const size_t num_matches = method_die_offsets.size(); | 
|  | 2094 | for (size_t i=0; i<num_matches; ++i) | 
|  | 2095 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 2096 | const DIERef& die_ref = method_die_offsets[i]; | 
|  | 2097 | DWARFDIE method_die = debug_info->GetDIE (die_ref); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2098 |  | 
|  | 2099 | if (method_die) | 
|  | 2100 | method_die.ResolveType (); | 
|  | 2101 | } | 
|  | 2102 | } | 
|  | 2103 |  | 
|  | 2104 | for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end(); | 
|  | 2105 | pi != pe; | 
|  | 2106 | ++pi) | 
|  | 2107 | pi->Finalize(); | 
|  | 2108 | } | 
|  | 2109 | } | 
|  | 2110 |  | 
|  | 2111 | // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we | 
|  | 2112 | // need to tell the clang type it is actually a class. | 
|  | 2113 | if (class_language != eLanguageTypeObjC) | 
|  | 2114 | { | 
|  | 2115 | if (is_a_class && tag_decl_kind != clang::TTK_Class) | 
|  | 2116 | m_ast.SetTagTypeKind (ClangASTContext::GetQualType(clang_type), clang::TTK_Class); | 
|  | 2117 | } | 
|  | 2118 |  | 
|  | 2119 | // Since DW_TAG_structure_type gets used for both classes | 
|  | 2120 | // and structures, we may need to set any DW_TAG_member | 
|  | 2121 | // fields to have a "private" access if none was specified. | 
|  | 2122 | // When we parsed the child members we tracked that actual | 
|  | 2123 | // accessibility value for each DW_TAG_member in the | 
|  | 2124 | // "member_accessibilities" array. If the value for the | 
|  | 2125 | // member is zero, then it was set to the "default_accessibility" | 
|  | 2126 | // which for structs was "public". Below we correct this | 
|  | 2127 | // by setting any fields to "private" that weren't correctly | 
|  | 2128 | // set. | 
|  | 2129 | if (is_a_class && !member_accessibilities.empty()) | 
|  | 2130 | { | 
|  | 2131 | // This is a class and all members that didn't have | 
|  | 2132 | // their access specified are private. | 
|  | 2133 | m_ast.SetDefaultAccessForRecordFields (m_ast.GetAsRecordDecl(clang_type), | 
|  | 2134 | eAccessPrivate, | 
|  | 2135 | &member_accessibilities.front(), | 
|  | 2136 | member_accessibilities.size()); | 
|  | 2137 | } | 
|  | 2138 |  | 
|  | 2139 | if (!base_classes.empty()) | 
|  | 2140 | { | 
|  | 2141 | // Make sure all base classes refer to complete types and not | 
|  | 2142 | // forward declarations. If we don't do this, clang will crash | 
|  | 2143 | // with an assertion in the call to clang_type.SetBaseClassesForClassType() | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2144 | for (auto &base_class : base_classes) | 
|  | 2145 | { | 
|  | 2146 | clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo(); | 
|  | 2147 | if (type_source_info) | 
|  | 2148 | { | 
|  | 2149 | CompilerType base_class_type (&m_ast, type_source_info->getType().getAsOpaquePtr()); | 
|  | 2150 | if (base_class_type.GetCompleteType() == false) | 
|  | 2151 | { | 
| Siva Chandra | cebabb9 | 2015-09-23 17:47:08 +0000 | [diff] [blame] | 2152 | auto module = dwarf->GetObjectFile()->GetModule(); | 
|  | 2153 | module->ReportError ( | 
|  | 2154 | ":: Class '%s' has a base class '%s' which does not have a complete definition.", | 
|  | 2155 | die.GetName(), | 
|  | 2156 | base_class_type.GetTypeName().GetCString()); | 
|  | 2157 | if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang) | 
|  | 2158 | module->ReportError (":: Try compiling the source file with -fno-limit-debug-info."); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2159 |  | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 2160 | // We have no choice other than to pretend that the base class | 
|  | 2161 | // is complete. If we don't do this, clang will crash when we | 
|  | 2162 | // call setBases() inside of "clang_type.SetBaseClassesForClassType()" | 
|  | 2163 | // below. Since we provide layout assistance, all ivars in this | 
|  | 2164 | // class and other classes will be fine, this is the best we can do | 
|  | 2165 | // short of crashing. | 
|  | 2166 | ClangASTContext::StartTagDeclarationDefinition (base_class_type); | 
|  | 2167 | ClangASTContext::CompleteTagDeclarationDefinition (base_class_type); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2168 | } | 
|  | 2169 | } | 
|  | 2170 | } | 
|  | 2171 | m_ast.SetBaseClassesForClassType (clang_type.GetOpaqueQualType(), | 
|  | 2172 | &base_classes.front(), | 
|  | 2173 | base_classes.size()); | 
|  | 2174 |  | 
|  | 2175 | // Clang will copy each CXXBaseSpecifier in "base_classes" | 
|  | 2176 | // so we have to free them all. | 
|  | 2177 | ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), | 
|  | 2178 | base_classes.size()); | 
|  | 2179 | } | 
|  | 2180 | } | 
|  | 2181 | } | 
|  | 2182 |  | 
|  | 2183 | ClangASTContext::BuildIndirectFields (clang_type); | 
|  | 2184 | ClangASTContext::CompleteTagDeclarationDefinition (clang_type); | 
|  | 2185 |  | 
|  | 2186 | if (!layout_info.field_offsets.empty() || | 
|  | 2187 | !layout_info.base_offsets.empty()  || | 
|  | 2188 | !layout_info.vbase_offsets.empty() ) | 
|  | 2189 | { | 
|  | 2190 | if (type) | 
|  | 2191 | layout_info.bit_size = type->GetByteSize() * 8; | 
|  | 2192 | if (layout_info.bit_size == 0) | 
|  | 2193 | layout_info.bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8; | 
|  | 2194 |  | 
|  | 2195 | clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType()); | 
|  | 2196 | if (record_decl) | 
|  | 2197 | { | 
|  | 2198 | if (log) | 
|  | 2199 | { | 
|  | 2200 | ModuleSP module_sp = dwarf->GetObjectFile()->GetModule(); | 
|  | 2201 |  | 
|  | 2202 | if (module_sp) | 
|  | 2203 | { | 
|  | 2204 | module_sp->LogMessage (log, | 
|  | 2205 | "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])", | 
|  | 2206 | static_cast<void*>(clang_type.GetOpaqueQualType()), | 
|  | 2207 | static_cast<void*>(record_decl), | 
|  | 2208 | layout_info.bit_size, | 
|  | 2209 | layout_info.alignment, | 
|  | 2210 | static_cast<uint32_t>(layout_info.field_offsets.size()), | 
|  | 2211 | static_cast<uint32_t>(layout_info.base_offsets.size()), | 
|  | 2212 | static_cast<uint32_t>(layout_info.vbase_offsets.size())); | 
|  | 2213 |  | 
|  | 2214 | uint32_t idx; | 
|  | 2215 | { | 
|  | 2216 | llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator pos, | 
|  | 2217 | end = layout_info.field_offsets.end(); | 
|  | 2218 | for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx) | 
|  | 2219 | { | 
|  | 2220 | module_sp->LogMessage(log, | 
|  | 2221 | "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }", | 
|  | 2222 | static_cast<void *>(clang_type.GetOpaqueQualType()), | 
|  | 2223 | idx, | 
|  | 2224 | static_cast<uint32_t>(pos->second), | 
|  | 2225 | pos->first->getNameAsString().c_str()); | 
|  | 2226 | } | 
|  | 2227 | } | 
|  | 2228 |  | 
|  | 2229 | { | 
|  | 2230 | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos, | 
|  | 2231 | base_end = layout_info.base_offsets.end(); | 
|  | 2232 | for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end; ++base_pos, ++idx) | 
|  | 2233 | { | 
|  | 2234 | module_sp->LogMessage(log, | 
|  | 2235 | "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }", | 
|  | 2236 | clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(), | 
|  | 2237 | base_pos->first->getNameAsString().c_str()); | 
|  | 2238 | } | 
|  | 2239 | } | 
|  | 2240 | { | 
|  | 2241 | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos, | 
|  | 2242 | vbase_end = layout_info.vbase_offsets.end(); | 
|  | 2243 | for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end; ++vbase_pos, ++idx) | 
|  | 2244 | { | 
|  | 2245 | module_sp->LogMessage(log, | 
|  | 2246 | "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }", | 
|  | 2247 | static_cast<void *>(clang_type.GetOpaqueQualType()), idx, | 
|  | 2248 | static_cast<uint32_t>(vbase_pos->second.getQuantity()), | 
|  | 2249 | vbase_pos->first->getNameAsString().c_str()); | 
|  | 2250 | } | 
|  | 2251 | } | 
|  | 2252 |  | 
|  | 2253 | } | 
|  | 2254 | } | 
|  | 2255 | m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info)); | 
|  | 2256 | } | 
|  | 2257 | } | 
|  | 2258 | } | 
|  | 2259 |  | 
|  | 2260 | return (bool)clang_type; | 
|  | 2261 |  | 
|  | 2262 | case DW_TAG_enumeration_type: | 
|  | 2263 | ClangASTContext::StartTagDeclarationDefinition (clang_type); | 
|  | 2264 | if (die.HasChildren()) | 
|  | 2265 | { | 
|  | 2266 | SymbolContext sc(die.GetLLDBCompileUnit()); | 
|  | 2267 | bool is_signed = false; | 
|  | 2268 | clang_type.IsIntegerType(is_signed); | 
|  | 2269 | ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), die); | 
|  | 2270 | } | 
|  | 2271 | ClangASTContext::CompleteTagDeclarationDefinition (clang_type); | 
|  | 2272 | return (bool)clang_type; | 
|  | 2273 |  | 
|  | 2274 | default: | 
|  | 2275 | assert(false && "not a forward clang type decl!"); | 
|  | 2276 | break; | 
|  | 2277 | } | 
|  | 2278 |  | 
|  | 2279 | return false; | 
|  | 2280 | } | 
|  | 2281 |  | 
| Paul Herman | ea188fc | 2015-09-16 18:48:30 +0000 | [diff] [blame] | 2282 | std::vector<DWARFDIE> | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 2283 | DWARFASTParserClang::GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) | 
| Paul Herman | ea188fc | 2015-09-16 18:48:30 +0000 | [diff] [blame] | 2284 | { | 
|  | 2285 | std::vector<DWARFDIE> result; | 
|  | 2286 | for (auto it = m_decl_ctx_to_die.find((clang::DeclContext *)decl_context.GetOpaqueDeclContext()); it != m_decl_ctx_to_die.end(); it++) | 
|  | 2287 | result.push_back(it->second); | 
|  | 2288 | return result; | 
|  | 2289 | } | 
|  | 2290 |  | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 2291 | CompilerDecl | 
|  | 2292 | DWARFASTParserClang::GetDeclForUIDFromDWARF (const DWARFDIE &die) | 
|  | 2293 | { | 
|  | 2294 | clang::Decl *clang_decl = GetClangDeclForDIE(die); | 
|  | 2295 | if (clang_decl != nullptr) | 
|  | 2296 | return CompilerDecl(&m_ast, clang_decl); | 
|  | 2297 | return CompilerDecl(); | 
|  | 2298 | } | 
|  | 2299 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2300 | CompilerDeclContext | 
|  | 2301 | DWARFASTParserClang::GetDeclContextForUIDFromDWARF (const DWARFDIE &die) | 
|  | 2302 | { | 
|  | 2303 | clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE (die); | 
|  | 2304 | if (clang_decl_ctx) | 
|  | 2305 | return CompilerDeclContext(&m_ast, clang_decl_ctx); | 
|  | 2306 | return CompilerDeclContext(); | 
|  | 2307 | } | 
|  | 2308 |  | 
|  | 2309 | CompilerDeclContext | 
|  | 2310 | DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) | 
|  | 2311 | { | 
|  | 2312 | clang::DeclContext *clang_decl_ctx = GetClangDeclContextContainingDIE (die, nullptr); | 
|  | 2313 | if (clang_decl_ctx) | 
|  | 2314 | return CompilerDeclContext(&m_ast, clang_decl_ctx); | 
|  | 2315 | return CompilerDeclContext(); | 
|  | 2316 | } | 
|  | 2317 |  | 
|  | 2318 | size_t | 
|  | 2319 | DWARFASTParserClang::ParseChildEnumerators (const SymbolContext& sc, | 
|  | 2320 | lldb_private::CompilerType &clang_type, | 
|  | 2321 | bool is_signed, | 
|  | 2322 | uint32_t enumerator_byte_size, | 
|  | 2323 | const DWARFDIE &parent_die) | 
|  | 2324 | { | 
|  | 2325 | if (!parent_die) | 
|  | 2326 | return 0; | 
|  | 2327 |  | 
|  | 2328 | size_t enumerators_added = 0; | 
|  | 2329 |  | 
|  | 2330 | for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) | 
|  | 2331 | { | 
|  | 2332 | const dw_tag_t tag = die.Tag(); | 
|  | 2333 | if (tag == DW_TAG_enumerator) | 
|  | 2334 | { | 
|  | 2335 | DWARFAttributes attributes; | 
|  | 2336 | const size_t num_child_attributes = die.GetAttributes(attributes); | 
|  | 2337 | if (num_child_attributes > 0) | 
|  | 2338 | { | 
|  | 2339 | const char *name = NULL; | 
|  | 2340 | bool got_value = false; | 
|  | 2341 | int64_t enum_value = 0; | 
|  | 2342 | Declaration decl; | 
|  | 2343 |  | 
|  | 2344 | uint32_t i; | 
|  | 2345 | for (i=0; i<num_child_attributes; ++i) | 
|  | 2346 | { | 
|  | 2347 | const dw_attr_t attr = attributes.AttributeAtIndex(i); | 
|  | 2348 | DWARFFormValue form_value; | 
|  | 2349 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 2350 | { | 
|  | 2351 | switch (attr) | 
|  | 2352 | { | 
|  | 2353 | case DW_AT_const_value: | 
|  | 2354 | got_value = true; | 
|  | 2355 | if (is_signed) | 
|  | 2356 | enum_value = form_value.Signed(); | 
|  | 2357 | else | 
|  | 2358 | enum_value = form_value.Unsigned(); | 
|  | 2359 | break; | 
|  | 2360 |  | 
|  | 2361 | case DW_AT_name: | 
|  | 2362 | name = form_value.AsCString(); | 
|  | 2363 | break; | 
|  | 2364 |  | 
|  | 2365 | case DW_AT_description: | 
|  | 2366 | default: | 
|  | 2367 | case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; | 
|  | 2368 | case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break; | 
|  | 2369 | case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; | 
|  | 2370 | case DW_AT_sibling: | 
|  | 2371 | break; | 
|  | 2372 | } | 
|  | 2373 | } | 
|  | 2374 | } | 
|  | 2375 |  | 
|  | 2376 | if (name && name[0] && got_value) | 
|  | 2377 | { | 
|  | 2378 | m_ast.AddEnumerationValueToEnumerationType (clang_type.GetOpaqueQualType(), | 
|  | 2379 | m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType()), | 
|  | 2380 | decl, | 
|  | 2381 | name, | 
|  | 2382 | enum_value, | 
|  | 2383 | enumerator_byte_size * 8); | 
|  | 2384 | ++enumerators_added; | 
|  | 2385 | } | 
|  | 2386 | } | 
|  | 2387 | } | 
|  | 2388 | } | 
|  | 2389 | return enumerators_added; | 
|  | 2390 | } | 
|  | 2391 |  | 
|  | 2392 | #if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) | 
|  | 2393 |  | 
|  | 2394 | class DIEStack | 
|  | 2395 | { | 
|  | 2396 | public: | 
|  | 2397 |  | 
|  | 2398 | void Push (const DWARFDIE &die) | 
|  | 2399 | { | 
|  | 2400 | m_dies.push_back (die); | 
|  | 2401 | } | 
|  | 2402 |  | 
|  | 2403 |  | 
|  | 2404 | void LogDIEs (Log *log) | 
|  | 2405 | { | 
|  | 2406 | StreamString log_strm; | 
|  | 2407 | const size_t n = m_dies.size(); | 
|  | 2408 | log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n); | 
|  | 2409 | for (size_t i=0; i<n; i++) | 
|  | 2410 | { | 
|  | 2411 | std::string qualified_name; | 
|  | 2412 | const DWARFDIE &die = m_dies[i]; | 
|  | 2413 | die.GetQualifiedName(qualified_name); | 
|  | 2414 | log_strm.Printf ("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n", | 
|  | 2415 | (uint64_t)i, | 
|  | 2416 | die.GetOffset(), | 
|  | 2417 | die.GetTagAsCString(), | 
|  | 2418 | qualified_name.c_str()); | 
|  | 2419 | } | 
|  | 2420 | log->PutCString(log_strm.GetData()); | 
|  | 2421 | } | 
|  | 2422 | void Pop () | 
|  | 2423 | { | 
|  | 2424 | m_dies.pop_back(); | 
|  | 2425 | } | 
|  | 2426 |  | 
|  | 2427 | class ScopedPopper | 
|  | 2428 | { | 
|  | 2429 | public: | 
|  | 2430 | ScopedPopper (DIEStack &die_stack) : | 
|  | 2431 | m_die_stack (die_stack), | 
|  | 2432 | m_valid (false) | 
|  | 2433 | { | 
|  | 2434 | } | 
|  | 2435 |  | 
|  | 2436 | void | 
|  | 2437 | Push (const DWARFDIE &die) | 
|  | 2438 | { | 
|  | 2439 | m_valid = true; | 
|  | 2440 | m_die_stack.Push (die); | 
|  | 2441 | } | 
|  | 2442 |  | 
|  | 2443 | ~ScopedPopper () | 
|  | 2444 | { | 
|  | 2445 | if (m_valid) | 
|  | 2446 | m_die_stack.Pop(); | 
|  | 2447 | } | 
|  | 2448 |  | 
|  | 2449 |  | 
|  | 2450 |  | 
|  | 2451 | protected: | 
|  | 2452 | DIEStack &m_die_stack; | 
|  | 2453 | bool m_valid; | 
|  | 2454 | }; | 
|  | 2455 |  | 
|  | 2456 | protected: | 
|  | 2457 | typedef std::vector<DWARFDIE> Stack; | 
|  | 2458 | Stack m_dies; | 
|  | 2459 | }; | 
|  | 2460 | #endif | 
|  | 2461 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2462 | Function * | 
|  | 2463 | DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc, | 
|  | 2464 | const DWARFDIE &die) | 
|  | 2465 | { | 
|  | 2466 | DWARFRangeList func_ranges; | 
|  | 2467 | const char *name = NULL; | 
|  | 2468 | const char *mangled = NULL; | 
|  | 2469 | int decl_file = 0; | 
|  | 2470 | int decl_line = 0; | 
|  | 2471 | int decl_column = 0; | 
|  | 2472 | int call_file = 0; | 
|  | 2473 | int call_line = 0; | 
|  | 2474 | int call_column = 0; | 
|  | 2475 | DWARFExpression frame_base(die.GetCU()); | 
|  | 2476 |  | 
|  | 2477 | const dw_tag_t tag = die.Tag(); | 
|  | 2478 |  | 
|  | 2479 | if (tag != DW_TAG_subprogram) | 
|  | 2480 | return NULL; | 
|  | 2481 |  | 
|  | 2482 | if (die.GetDIENamesAndRanges (name, | 
|  | 2483 | mangled, | 
|  | 2484 | func_ranges, | 
|  | 2485 | decl_file, | 
|  | 2486 | decl_line, | 
|  | 2487 | decl_column, | 
|  | 2488 | call_file, | 
|  | 2489 | call_line, | 
|  | 2490 | call_column, | 
|  | 2491 | &frame_base)) | 
|  | 2492 | { | 
|  | 2493 |  | 
|  | 2494 | // Union of all ranges in the function DIE (if the function is discontiguous) | 
|  | 2495 | AddressRange func_range; | 
|  | 2496 | lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0); | 
|  | 2497 | lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0); | 
|  | 2498 | if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr) | 
|  | 2499 | { | 
|  | 2500 | ModuleSP module_sp (die.GetModule()); | 
|  | 2501 | func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, module_sp->GetSectionList()); | 
|  | 2502 | if (func_range.GetBaseAddress().IsValid()) | 
|  | 2503 | func_range.SetByteSize(highest_func_addr - lowest_func_addr); | 
|  | 2504 | } | 
|  | 2505 |  | 
|  | 2506 | if (func_range.GetBaseAddress().IsValid()) | 
|  | 2507 | { | 
|  | 2508 | Mangled func_name; | 
|  | 2509 | if (mangled) | 
|  | 2510 | func_name.SetValue(ConstString(mangled), true); | 
|  | 2511 | else if (die.GetParent().Tag() == DW_TAG_compile_unit && | 
| Jim Ingham | 0e0984e | 2015-09-02 01:06:46 +0000 | [diff] [blame] | 2512 | Language::LanguageIsCPlusPlus(die.GetLanguage()) && | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2513 | name && strcmp(name, "main") != 0) | 
|  | 2514 | { | 
|  | 2515 | // If the mangled name is not present in the DWARF, generate the demangled name | 
|  | 2516 | // using the decl context. We skip if the function is "main" as its name is | 
|  | 2517 | // never mangled. | 
|  | 2518 | bool is_static = false; | 
|  | 2519 | bool is_variadic = false; | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 2520 | bool has_template_params = false; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2521 | unsigned type_quals = 0; | 
|  | 2522 | std::vector<CompilerType> param_types; | 
|  | 2523 | std::vector<clang::ParmVarDecl*> param_decls; | 
|  | 2524 | DWARFDeclContext decl_ctx; | 
|  | 2525 | StreamString sstr; | 
|  | 2526 |  | 
|  | 2527 | die.GetDWARFDeclContext(decl_ctx); | 
|  | 2528 | sstr << decl_ctx.GetQualifiedName(); | 
|  | 2529 |  | 
|  | 2530 | clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(die, nullptr); | 
|  | 2531 | ParseChildParameters(sc, | 
|  | 2532 | containing_decl_ctx, | 
|  | 2533 | die, | 
|  | 2534 | true, | 
|  | 2535 | is_static, | 
|  | 2536 | is_variadic, | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 2537 | has_template_params, | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2538 | param_types, | 
|  | 2539 | param_decls, | 
|  | 2540 | type_quals); | 
|  | 2541 | sstr << "("; | 
|  | 2542 | for (size_t i = 0; i < param_types.size(); i++) | 
|  | 2543 | { | 
|  | 2544 | if (i > 0) | 
|  | 2545 | sstr << ", "; | 
|  | 2546 | sstr << param_types[i].GetTypeName(); | 
|  | 2547 | } | 
|  | 2548 | if (is_variadic) | 
|  | 2549 | sstr << ", ..."; | 
|  | 2550 | sstr << ")"; | 
|  | 2551 | if (type_quals & clang::Qualifiers::Const) | 
|  | 2552 | sstr << " const"; | 
|  | 2553 |  | 
|  | 2554 | func_name.SetValue(ConstString(sstr.GetData()), false); | 
|  | 2555 | } | 
|  | 2556 | else | 
|  | 2557 | func_name.SetValue(ConstString(name), false); | 
|  | 2558 |  | 
|  | 2559 | FunctionSP func_sp; | 
|  | 2560 | std::unique_ptr<Declaration> decl_ap; | 
|  | 2561 | if (decl_file != 0 || decl_line != 0 || decl_column != 0) | 
|  | 2562 | decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), | 
|  | 2563 | decl_line, | 
|  | 2564 | decl_column)); | 
|  | 2565 |  | 
|  | 2566 | SymbolFileDWARF *dwarf = die.GetDWARF(); | 
|  | 2567 | // Supply the type _only_ if it has already been parsed | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 2568 | Type *func_type = dwarf->GetDIEToType().lookup (die.GetDIE()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2569 |  | 
|  | 2570 | assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); | 
|  | 2571 |  | 
|  | 2572 | if (dwarf->FixupAddress (func_range.GetBaseAddress())) | 
|  | 2573 | { | 
|  | 2574 | const user_id_t func_user_id = die.GetID(); | 
|  | 2575 | func_sp.reset(new Function (sc.comp_unit, | 
|  | 2576 | func_user_id,       // UserID is the DIE offset | 
|  | 2577 | func_user_id, | 
|  | 2578 | func_name, | 
|  | 2579 | func_type, | 
|  | 2580 | func_range));           // first address range | 
|  | 2581 |  | 
|  | 2582 | if (func_sp.get() != NULL) | 
|  | 2583 | { | 
|  | 2584 | if (frame_base.IsValid()) | 
|  | 2585 | func_sp->GetFrameBaseExpression() = frame_base; | 
|  | 2586 | sc.comp_unit->AddFunction(func_sp); | 
|  | 2587 | return func_sp.get(); | 
|  | 2588 | } | 
|  | 2589 | } | 
|  | 2590 | } | 
|  | 2591 | } | 
|  | 2592 | return NULL; | 
|  | 2593 | } | 
|  | 2594 |  | 
|  | 2595 |  | 
| Siva Chandra | cebabb9 | 2015-09-23 17:47:08 +0000 | [diff] [blame] | 2596 | bool | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2597 | DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc, | 
|  | 2598 | const DWARFDIE &parent_die, | 
|  | 2599 | CompilerType &class_clang_type, | 
|  | 2600 | const LanguageType class_language, | 
|  | 2601 | std::vector<clang::CXXBaseSpecifier *>& base_classes, | 
|  | 2602 | std::vector<int>& member_accessibilities, | 
|  | 2603 | DWARFDIECollection& member_function_dies, | 
|  | 2604 | DelayedPropertyList& delayed_properties, | 
|  | 2605 | AccessType& default_accessibility, | 
|  | 2606 | bool &is_a_class, | 
|  | 2607 | LayoutInfo &layout_info) | 
|  | 2608 | { | 
|  | 2609 | if (!parent_die) | 
|  | 2610 | return 0; | 
|  | 2611 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2612 | uint32_t member_idx = 0; | 
|  | 2613 | BitfieldInfo last_field_info; | 
|  | 2614 |  | 
|  | 2615 | ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); | 
| Greg Clayton | f73034f | 2015-09-08 18:15:05 +0000 | [diff] [blame] | 2616 | ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(class_clang_type.GetTypeSystem()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2617 | if (ast == nullptr) | 
|  | 2618 | return 0; | 
|  | 2619 |  | 
|  | 2620 | for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) | 
|  | 2621 | { | 
|  | 2622 | dw_tag_t tag = die.Tag(); | 
|  | 2623 |  | 
|  | 2624 | switch (tag) | 
|  | 2625 | { | 
|  | 2626 | case DW_TAG_member: | 
|  | 2627 | case DW_TAG_APPLE_property: | 
|  | 2628 | { | 
|  | 2629 | DWARFAttributes attributes; | 
|  | 2630 | const size_t num_attributes = die.GetAttributes (attributes); | 
|  | 2631 | if (num_attributes > 0) | 
|  | 2632 | { | 
|  | 2633 | Declaration decl; | 
|  | 2634 | //DWARFExpression location; | 
|  | 2635 | const char *name = NULL; | 
|  | 2636 | const char *prop_name = NULL; | 
|  | 2637 | const char *prop_getter_name = NULL; | 
|  | 2638 | const char *prop_setter_name = NULL; | 
|  | 2639 | uint32_t prop_attributes = 0; | 
|  | 2640 |  | 
|  | 2641 |  | 
|  | 2642 | bool is_artificial = false; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 2643 | DWARFFormValue encoding_form; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2644 | AccessType accessibility = eAccessNone; | 
|  | 2645 | uint32_t member_byte_offset = UINT32_MAX; | 
|  | 2646 | size_t byte_size = 0; | 
|  | 2647 | size_t bit_offset = 0; | 
|  | 2648 | size_t bit_size = 0; | 
|  | 2649 | bool is_external = false; // On DW_TAG_members, this means the member is static | 
|  | 2650 | uint32_t i; | 
|  | 2651 | for (i=0; i<num_attributes && !is_artificial; ++i) | 
|  | 2652 | { | 
|  | 2653 | const dw_attr_t attr = attributes.AttributeAtIndex(i); | 
|  | 2654 | DWARFFormValue form_value; | 
|  | 2655 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 2656 | { | 
|  | 2657 | switch (attr) | 
|  | 2658 | { | 
|  | 2659 | case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; | 
|  | 2660 | case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break; | 
|  | 2661 | case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; | 
|  | 2662 | case DW_AT_name:        name = form_value.AsCString(); break; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 2663 | case DW_AT_type:        encoding_form = form_value; break; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2664 | case DW_AT_bit_offset:  bit_offset = form_value.Unsigned(); break; | 
|  | 2665 | case DW_AT_bit_size:    bit_size = form_value.Unsigned(); break; | 
|  | 2666 | case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break; | 
|  | 2667 | case DW_AT_data_member_location: | 
|  | 2668 | if (form_value.BlockData()) | 
|  | 2669 | { | 
|  | 2670 | Value initialValue(0); | 
|  | 2671 | Value memberOffset(0); | 
|  | 2672 | const DWARFDataExtractor& debug_info_data = die.GetDWARF()->get_debug_info_data(); | 
|  | 2673 | uint32_t block_length = form_value.Unsigned(); | 
|  | 2674 | uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); | 
|  | 2675 | if (DWARFExpression::Evaluate(NULL, // ExecutionContext * | 
|  | 2676 | NULL, // ClangExpressionVariableList * | 
|  | 2677 | NULL, // ClangExpressionDeclMap * | 
|  | 2678 | NULL, // RegisterContext * | 
|  | 2679 | module_sp, | 
|  | 2680 | debug_info_data, | 
|  | 2681 | die.GetCU(), | 
|  | 2682 | block_offset, | 
|  | 2683 | block_length, | 
|  | 2684 | eRegisterKindDWARF, | 
|  | 2685 | &initialValue, | 
|  | 2686 | memberOffset, | 
|  | 2687 | NULL)) | 
|  | 2688 | { | 
|  | 2689 | member_byte_offset = memberOffset.ResolveValue(NULL).UInt(); | 
|  | 2690 | } | 
|  | 2691 | } | 
|  | 2692 | else | 
|  | 2693 | { | 
|  | 2694 | // With DWARF 3 and later, if the value is an integer constant, | 
|  | 2695 | // this form value is the offset in bytes from the beginning | 
|  | 2696 | // of the containing entity. | 
|  | 2697 | member_byte_offset = form_value.Unsigned(); | 
|  | 2698 | } | 
|  | 2699 | break; | 
|  | 2700 |  | 
|  | 2701 | case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break; | 
|  | 2702 | case DW_AT_artificial: is_artificial = form_value.Boolean(); break; | 
|  | 2703 | case DW_AT_APPLE_property_name:      prop_name = form_value.AsCString(); | 
|  | 2704 | break; | 
|  | 2705 | case DW_AT_APPLE_property_getter:    prop_getter_name = form_value.AsCString(); | 
|  | 2706 | break; | 
|  | 2707 | case DW_AT_APPLE_property_setter:    prop_setter_name = form_value.AsCString(); | 
|  | 2708 | break; | 
|  | 2709 | case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break; | 
|  | 2710 | case DW_AT_external:                 is_external = form_value.Boolean(); break; | 
|  | 2711 |  | 
|  | 2712 | default: | 
|  | 2713 | case DW_AT_declaration: | 
|  | 2714 | case DW_AT_description: | 
|  | 2715 | case DW_AT_mutable: | 
|  | 2716 | case DW_AT_visibility: | 
|  | 2717 | case DW_AT_sibling: | 
|  | 2718 | break; | 
|  | 2719 | } | 
|  | 2720 | } | 
|  | 2721 | } | 
|  | 2722 |  | 
|  | 2723 | if (prop_name) | 
|  | 2724 | { | 
|  | 2725 | ConstString fixed_getter; | 
|  | 2726 | ConstString fixed_setter; | 
|  | 2727 |  | 
|  | 2728 | // Check if the property getter/setter were provided as full | 
|  | 2729 | // names.  We want basenames, so we extract them. | 
|  | 2730 |  | 
|  | 2731 | if (prop_getter_name && prop_getter_name[0] == '-') | 
|  | 2732 | { | 
| Jim Ingham | aa816b8 | 2015-09-02 01:59:14 +0000 | [diff] [blame] | 2733 | ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2734 | prop_getter_name = prop_getter_method.GetSelector().GetCString(); | 
|  | 2735 | } | 
|  | 2736 |  | 
|  | 2737 | if (prop_setter_name && prop_setter_name[0] == '-') | 
|  | 2738 | { | 
| Jim Ingham | aa816b8 | 2015-09-02 01:59:14 +0000 | [diff] [blame] | 2739 | ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2740 | prop_setter_name = prop_setter_method.GetSelector().GetCString(); | 
|  | 2741 | } | 
|  | 2742 |  | 
|  | 2743 | // If the names haven't been provided, they need to be | 
|  | 2744 | // filled in. | 
|  | 2745 |  | 
|  | 2746 | if (!prop_getter_name) | 
|  | 2747 | { | 
|  | 2748 | prop_getter_name = prop_name; | 
|  | 2749 | } | 
|  | 2750 | if (!prop_setter_name && prop_name[0] && !(prop_attributes & DW_APPLE_PROPERTY_readonly)) | 
|  | 2751 | { | 
|  | 2752 | StreamString ss; | 
|  | 2753 |  | 
|  | 2754 | ss.Printf("set%c%s:", | 
|  | 2755 | toupper(prop_name[0]), | 
|  | 2756 | &prop_name[1]); | 
|  | 2757 |  | 
|  | 2758 | fixed_setter.SetCString(ss.GetData()); | 
|  | 2759 | prop_setter_name = fixed_setter.GetCString(); | 
|  | 2760 | } | 
|  | 2761 | } | 
|  | 2762 |  | 
|  | 2763 | // Clang has a DWARF generation bug where sometimes it | 
|  | 2764 | // represents fields that are references with bad byte size | 
|  | 2765 | // and bit size/offset information such as: | 
|  | 2766 | // | 
|  | 2767 | //  DW_AT_byte_size( 0x00 ) | 
|  | 2768 | //  DW_AT_bit_size( 0x40 ) | 
|  | 2769 | //  DW_AT_bit_offset( 0xffffffffffffffc0 ) | 
|  | 2770 | // | 
|  | 2771 | // So check the bit offset to make sure it is sane, and if | 
|  | 2772 | // the values are not sane, remove them. If we don't do this | 
|  | 2773 | // then we will end up with a crash if we try to use this | 
|  | 2774 | // type in an expression when clang becomes unhappy with its | 
|  | 2775 | // recycled debug info. | 
|  | 2776 |  | 
|  | 2777 | if (bit_offset > 128) | 
|  | 2778 | { | 
|  | 2779 | bit_size = 0; | 
|  | 2780 | bit_offset = 0; | 
|  | 2781 | } | 
|  | 2782 |  | 
|  | 2783 | // FIXME: Make Clang ignore Objective-C accessibility for expressions | 
|  | 2784 | if (class_language == eLanguageTypeObjC || | 
|  | 2785 | class_language == eLanguageTypeObjC_plus_plus) | 
|  | 2786 | accessibility = eAccessNone; | 
|  | 2787 |  | 
|  | 2788 | if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name)) | 
|  | 2789 | { | 
|  | 2790 | // Not all compilers will mark the vtable pointer | 
|  | 2791 | // member as artificial (llvm-gcc). We can't have | 
|  | 2792 | // the virtual members in our classes otherwise it | 
|  | 2793 | // throws off all child offsets since we end up | 
|  | 2794 | // having and extra pointer sized member in our | 
|  | 2795 | // class layouts. | 
|  | 2796 | is_artificial = true; | 
|  | 2797 | } | 
|  | 2798 |  | 
|  | 2799 | // Handle static members | 
|  | 2800 | if (is_external && member_byte_offset == UINT32_MAX) | 
|  | 2801 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 2802 | Type *var_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2803 |  | 
|  | 2804 | if (var_type) | 
|  | 2805 | { | 
|  | 2806 | if (accessibility == eAccessNone) | 
|  | 2807 | accessibility = eAccessPublic; | 
|  | 2808 | ClangASTContext::AddVariableToRecordType (class_clang_type, | 
|  | 2809 | name, | 
|  | 2810 | var_type->GetLayoutCompilerType (), | 
|  | 2811 | accessibility); | 
|  | 2812 | } | 
|  | 2813 | break; | 
|  | 2814 | } | 
|  | 2815 |  | 
|  | 2816 | if (is_artificial == false) | 
|  | 2817 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 2818 | Type *member_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2819 |  | 
|  | 2820 | clang::FieldDecl *field_decl = NULL; | 
|  | 2821 | if (tag == DW_TAG_member) | 
|  | 2822 | { | 
|  | 2823 | if (member_type) | 
|  | 2824 | { | 
|  | 2825 | if (accessibility == eAccessNone) | 
|  | 2826 | accessibility = default_accessibility; | 
|  | 2827 | member_accessibilities.push_back(accessibility); | 
|  | 2828 |  | 
|  | 2829 | uint64_t field_bit_offset = (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8)); | 
|  | 2830 | if (bit_size > 0) | 
|  | 2831 | { | 
|  | 2832 |  | 
|  | 2833 | BitfieldInfo this_field_info; | 
|  | 2834 | this_field_info.bit_offset = field_bit_offset; | 
|  | 2835 | this_field_info.bit_size = bit_size; | 
|  | 2836 |  | 
|  | 2837 | ///////////////////////////////////////////////////////////// | 
|  | 2838 | // How to locate a field given the DWARF debug information | 
|  | 2839 | // | 
|  | 2840 | // AT_byte_size indicates the size of the word in which the | 
|  | 2841 | // bit offset must be interpreted. | 
|  | 2842 | // | 
|  | 2843 | // AT_data_member_location indicates the byte offset of the | 
|  | 2844 | // word from the base address of the structure. | 
|  | 2845 | // | 
|  | 2846 | // AT_bit_offset indicates how many bits into the word | 
|  | 2847 | // (according to the host endianness) the low-order bit of | 
|  | 2848 | // the field starts.  AT_bit_offset can be negative. | 
|  | 2849 | // | 
|  | 2850 | // AT_bit_size indicates the size of the field in bits. | 
|  | 2851 | ///////////////////////////////////////////////////////////// | 
|  | 2852 |  | 
|  | 2853 | if (byte_size == 0) | 
|  | 2854 | byte_size = member_type->GetByteSize(); | 
|  | 2855 |  | 
|  | 2856 | if (die.GetDWARF()->GetObjectFile()->GetByteOrder() == eByteOrderLittle) | 
|  | 2857 | { | 
|  | 2858 | this_field_info.bit_offset += byte_size * 8; | 
|  | 2859 | this_field_info.bit_offset -= (bit_offset + bit_size); | 
|  | 2860 | } | 
|  | 2861 | else | 
|  | 2862 | { | 
|  | 2863 | this_field_info.bit_offset += bit_offset; | 
|  | 2864 | } | 
|  | 2865 |  | 
|  | 2866 | // Update the field bit offset we will report for layout | 
|  | 2867 | field_bit_offset = this_field_info.bit_offset; | 
|  | 2868 |  | 
|  | 2869 | // If the member to be emitted did not start on a character boundary and there is | 
|  | 2870 | // empty space between the last field and this one, then we need to emit an | 
|  | 2871 | // anonymous member filling up the space up to its start.  There are three cases | 
|  | 2872 | // here: | 
|  | 2873 | // | 
|  | 2874 | // 1 If the previous member ended on a character boundary, then we can emit an | 
|  | 2875 | //   anonymous member starting at the most recent character boundary. | 
|  | 2876 | // | 
|  | 2877 | // 2 If the previous member did not end on a character boundary and the distance | 
|  | 2878 | //   from the end of the previous member to the current member is less than a | 
|  | 2879 | //   word width, then we can emit an anonymous member starting right after the | 
|  | 2880 | //   previous member and right before this member. | 
|  | 2881 | // | 
|  | 2882 | // 3 If the previous member did not end on a character boundary and the distance | 
|  | 2883 | //   from the end of the previous member to the current member is greater than | 
|  | 2884 | //   or equal a word width, then we act as in Case 1. | 
|  | 2885 |  | 
|  | 2886 | const uint64_t character_width = 8; | 
|  | 2887 | const uint64_t word_width = 32; | 
|  | 2888 |  | 
|  | 2889 | // Objective-C has invalid DW_AT_bit_offset values in older versions | 
|  | 2890 | // of clang, so we have to be careful and only insert unnamed bitfields | 
|  | 2891 | // if we have a new enough clang. | 
|  | 2892 | bool detect_unnamed_bitfields = true; | 
|  | 2893 |  | 
|  | 2894 | if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus) | 
|  | 2895 | detect_unnamed_bitfields = die.GetCU()->Supports_unnamed_objc_bitfields (); | 
|  | 2896 |  | 
|  | 2897 | if (detect_unnamed_bitfields) | 
|  | 2898 | { | 
|  | 2899 | BitfieldInfo anon_field_info; | 
|  | 2900 |  | 
|  | 2901 | if ((this_field_info.bit_offset % character_width) != 0) // not char aligned | 
|  | 2902 | { | 
|  | 2903 | uint64_t last_field_end = 0; | 
|  | 2904 |  | 
|  | 2905 | if (last_field_info.IsValid()) | 
|  | 2906 | last_field_end = last_field_info.bit_offset + last_field_info.bit_size; | 
|  | 2907 |  | 
|  | 2908 | if (this_field_info.bit_offset != last_field_end) | 
|  | 2909 | { | 
|  | 2910 | if (((last_field_end % character_width) == 0) ||                    // case 1 | 
|  | 2911 | (this_field_info.bit_offset - last_field_end >= word_width))    // case 3 | 
|  | 2912 | { | 
|  | 2913 | anon_field_info.bit_size = this_field_info.bit_offset % character_width; | 
|  | 2914 | anon_field_info.bit_offset = this_field_info.bit_offset - anon_field_info.bit_size; | 
|  | 2915 | } | 
|  | 2916 | else                                                                // case 2 | 
|  | 2917 | { | 
|  | 2918 | anon_field_info.bit_size = this_field_info.bit_offset - last_field_end; | 
|  | 2919 | anon_field_info.bit_offset = last_field_end; | 
|  | 2920 | } | 
|  | 2921 | } | 
|  | 2922 | } | 
|  | 2923 |  | 
|  | 2924 | if (anon_field_info.IsValid()) | 
|  | 2925 | { | 
|  | 2926 | clang::FieldDecl *unnamed_bitfield_decl = | 
|  | 2927 | ClangASTContext::AddFieldToRecordType (class_clang_type, | 
|  | 2928 | NULL, | 
|  | 2929 | m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width), | 
|  | 2930 | accessibility, | 
|  | 2931 | anon_field_info.bit_size); | 
|  | 2932 |  | 
|  | 2933 | layout_info.field_offsets.insert( | 
|  | 2934 | std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset)); | 
|  | 2935 | } | 
|  | 2936 | } | 
|  | 2937 | last_field_info = this_field_info; | 
|  | 2938 | } | 
|  | 2939 | else | 
|  | 2940 | { | 
|  | 2941 | last_field_info.Clear(); | 
|  | 2942 | } | 
|  | 2943 |  | 
|  | 2944 | CompilerType member_clang_type = member_type->GetLayoutCompilerType (); | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 2945 | if (!member_clang_type.IsCompleteType()) | 
|  | 2946 | member_clang_type.GetCompleteType(); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2947 |  | 
|  | 2948 | { | 
|  | 2949 | // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>). | 
|  | 2950 | // If the current field is at the end of the structure, then there is definitely no room for extra | 
|  | 2951 | // elements and we override the type to array[0]. | 
|  | 2952 |  | 
|  | 2953 | CompilerType member_array_element_type; | 
|  | 2954 | uint64_t member_array_size; | 
|  | 2955 | bool member_array_is_incomplete; | 
|  | 2956 |  | 
|  | 2957 | if (member_clang_type.IsArrayType(&member_array_element_type, | 
|  | 2958 | &member_array_size, | 
|  | 2959 | &member_array_is_incomplete) && | 
|  | 2960 | !member_array_is_incomplete) | 
|  | 2961 | { | 
|  | 2962 | uint64_t parent_byte_size = parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX); | 
|  | 2963 |  | 
|  | 2964 | if (member_byte_offset >= parent_byte_size) | 
|  | 2965 | { | 
| Tamas Berghammer | 808ff18 | 2016-01-13 14:58:48 +0000 | [diff] [blame] | 2966 | if (member_array_size != 1 && (member_array_size != 0 || member_byte_offset > parent_byte_size)) | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2967 | { | 
|  | 2968 | module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which extends beyond the bounds of 0x%8.8" PRIx64, | 
|  | 2969 | die.GetID(), | 
|  | 2970 | name, | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 2971 | encoding_form.Reference(), | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 2972 | parent_die.GetID()); | 
|  | 2973 | } | 
|  | 2974 |  | 
|  | 2975 | member_clang_type = m_ast.CreateArrayType(member_array_element_type, 0, false); | 
|  | 2976 | } | 
|  | 2977 | } | 
|  | 2978 | } | 
|  | 2979 |  | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 2980 | if (ClangASTContext::IsCXXClassType(member_clang_type) && member_clang_type.GetCompleteType() == false) | 
|  | 2981 | { | 
|  | 2982 | if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang) | 
|  | 2983 | module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nTry compiling the source file with -fno-limit-debug-info", | 
|  | 2984 | parent_die.GetOffset(), | 
|  | 2985 | parent_die.GetName(), | 
|  | 2986 | die.GetOffset(), | 
|  | 2987 | name); | 
|  | 2988 | else | 
|  | 2989 | module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s", | 
|  | 2990 | parent_die.GetOffset(), | 
|  | 2991 | parent_die.GetName(), | 
|  | 2992 | die.GetOffset(), | 
|  | 2993 | name, | 
|  | 2994 | sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file"); | 
|  | 2995 | // We have no choice other than to pretend that the member class | 
|  | 2996 | // is complete. If we don't do this, clang will crash when trying | 
|  | 2997 | // to layout the class. Since we provide layout assistance, all | 
|  | 2998 | // ivars in this class and other classes will be fine, this is | 
|  | 2999 | // the best we can do short of crashing. | 
|  | 3000 | ClangASTContext::StartTagDeclarationDefinition(member_clang_type); | 
|  | 3001 | ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type); | 
|  | 3002 | } | 
|  | 3003 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3004 | field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type, | 
|  | 3005 | name, | 
|  | 3006 | member_clang_type, | 
|  | 3007 | accessibility, | 
|  | 3008 | bit_size); | 
|  | 3009 |  | 
|  | 3010 | m_ast.SetMetadataAsUserID (field_decl, die.GetID()); | 
|  | 3011 |  | 
|  | 3012 | layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset)); | 
|  | 3013 | } | 
|  | 3014 | else | 
|  | 3015 | { | 
|  | 3016 | if (name) | 
|  | 3017 | module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which was unable to be parsed", | 
|  | 3018 | die.GetID(), | 
|  | 3019 | name, | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3020 | encoding_form.Reference()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3021 | else | 
|  | 3022 | module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8" PRIx64 " which was unable to be parsed", | 
|  | 3023 | die.GetID(), | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3024 | encoding_form.Reference()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3025 | } | 
|  | 3026 | } | 
|  | 3027 |  | 
|  | 3028 | if (prop_name != NULL && member_type) | 
|  | 3029 | { | 
|  | 3030 | clang::ObjCIvarDecl *ivar_decl = NULL; | 
|  | 3031 |  | 
|  | 3032 | if (field_decl) | 
|  | 3033 | { | 
|  | 3034 | ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl); | 
|  | 3035 | assert (ivar_decl != NULL); | 
|  | 3036 | } | 
|  | 3037 |  | 
|  | 3038 | ClangASTMetadata metadata; | 
|  | 3039 | metadata.SetUserID (die.GetID()); | 
|  | 3040 | delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type, | 
|  | 3041 | prop_name, | 
|  | 3042 | member_type->GetLayoutCompilerType (), | 
|  | 3043 | ivar_decl, | 
|  | 3044 | prop_setter_name, | 
|  | 3045 | prop_getter_name, | 
|  | 3046 | prop_attributes, | 
|  | 3047 | &metadata)); | 
|  | 3048 |  | 
|  | 3049 | if (ivar_decl) | 
|  | 3050 | m_ast.SetMetadataAsUserID (ivar_decl, die.GetID()); | 
|  | 3051 | } | 
|  | 3052 | } | 
|  | 3053 | } | 
|  | 3054 | ++member_idx; | 
|  | 3055 | } | 
|  | 3056 | break; | 
|  | 3057 |  | 
|  | 3058 | case DW_TAG_subprogram: | 
|  | 3059 | // Let the type parsing code handle this one for us. | 
|  | 3060 | member_function_dies.Append (die); | 
|  | 3061 | break; | 
|  | 3062 |  | 
|  | 3063 | case DW_TAG_inheritance: | 
|  | 3064 | { | 
|  | 3065 | is_a_class = true; | 
|  | 3066 | if (default_accessibility == eAccessNone) | 
|  | 3067 | default_accessibility = eAccessPrivate; | 
|  | 3068 | // TODO: implement DW_TAG_inheritance type parsing | 
|  | 3069 | DWARFAttributes attributes; | 
|  | 3070 | const size_t num_attributes = die.GetAttributes (attributes); | 
|  | 3071 | if (num_attributes > 0) | 
|  | 3072 | { | 
|  | 3073 | Declaration decl; | 
|  | 3074 | DWARFExpression location(die.GetCU()); | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3075 | DWARFFormValue encoding_form; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3076 | AccessType accessibility = default_accessibility; | 
|  | 3077 | bool is_virtual = false; | 
|  | 3078 | bool is_base_of_class = true; | 
|  | 3079 | off_t member_byte_offset = 0; | 
|  | 3080 | uint32_t i; | 
|  | 3081 | for (i=0; i<num_attributes; ++i) | 
|  | 3082 | { | 
|  | 3083 | const dw_attr_t attr = attributes.AttributeAtIndex(i); | 
|  | 3084 | DWARFFormValue form_value; | 
|  | 3085 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 3086 | { | 
|  | 3087 | switch (attr) | 
|  | 3088 | { | 
|  | 3089 | case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; | 
|  | 3090 | case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break; | 
|  | 3091 | case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3092 | case DW_AT_type:        encoding_form = form_value; break; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3093 | case DW_AT_data_member_location: | 
|  | 3094 | if (form_value.BlockData()) | 
|  | 3095 | { | 
|  | 3096 | Value initialValue(0); | 
|  | 3097 | Value memberOffset(0); | 
|  | 3098 | const DWARFDataExtractor& debug_info_data = die.GetDWARF()->get_debug_info_data(); | 
|  | 3099 | uint32_t block_length = form_value.Unsigned(); | 
|  | 3100 | uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); | 
|  | 3101 | if (DWARFExpression::Evaluate (NULL, | 
|  | 3102 | NULL, | 
|  | 3103 | NULL, | 
|  | 3104 | NULL, | 
|  | 3105 | module_sp, | 
|  | 3106 | debug_info_data, | 
|  | 3107 | die.GetCU(), | 
|  | 3108 | block_offset, | 
|  | 3109 | block_length, | 
|  | 3110 | eRegisterKindDWARF, | 
|  | 3111 | &initialValue, | 
|  | 3112 | memberOffset, | 
|  | 3113 | NULL)) | 
|  | 3114 | { | 
|  | 3115 | member_byte_offset = memberOffset.ResolveValue(NULL).UInt(); | 
|  | 3116 | } | 
|  | 3117 | } | 
|  | 3118 | else | 
|  | 3119 | { | 
|  | 3120 | // With DWARF 3 and later, if the value is an integer constant, | 
|  | 3121 | // this form value is the offset in bytes from the beginning | 
|  | 3122 | // of the containing entity. | 
|  | 3123 | member_byte_offset = form_value.Unsigned(); | 
|  | 3124 | } | 
|  | 3125 | break; | 
|  | 3126 |  | 
|  | 3127 | case DW_AT_accessibility: | 
|  | 3128 | accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); | 
|  | 3129 | break; | 
|  | 3130 |  | 
|  | 3131 | case DW_AT_virtuality: | 
|  | 3132 | is_virtual = form_value.Boolean(); | 
|  | 3133 | break; | 
|  | 3134 |  | 
|  | 3135 | case DW_AT_sibling: | 
|  | 3136 | break; | 
|  | 3137 |  | 
|  | 3138 | default: | 
|  | 3139 | break; | 
|  | 3140 | } | 
|  | 3141 | } | 
|  | 3142 | } | 
|  | 3143 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3144 | Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3145 | if (base_class_type == NULL) | 
|  | 3146 | { | 
|  | 3147 | module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to resolve the base class at 0x%8.8" PRIx64 " from enclosing type 0x%8.8x. \nPlease file a bug and attach the file at the start of this error message", | 
|  | 3148 | die.GetOffset(), | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3149 | encoding_form.Reference(), | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3150 | parent_die.GetOffset()); | 
|  | 3151 | break; | 
|  | 3152 | } | 
|  | 3153 |  | 
|  | 3154 | CompilerType base_class_clang_type = base_class_type->GetFullCompilerType (); | 
|  | 3155 | assert (base_class_clang_type); | 
|  | 3156 | if (class_language == eLanguageTypeObjC) | 
|  | 3157 | { | 
|  | 3158 | ast->SetObjCSuperClass(class_clang_type, base_class_clang_type); | 
|  | 3159 | } | 
|  | 3160 | else | 
|  | 3161 | { | 
|  | 3162 | base_classes.push_back (ast->CreateBaseClassSpecifier (base_class_clang_type.GetOpaqueQualType(), | 
|  | 3163 | accessibility, | 
|  | 3164 | is_virtual, | 
|  | 3165 | is_base_of_class)); | 
|  | 3166 |  | 
|  | 3167 | if (is_virtual) | 
|  | 3168 | { | 
|  | 3169 | // Do not specify any offset for virtual inheritance. The DWARF produced by clang doesn't | 
|  | 3170 | // give us a constant offset, but gives us a DWARF expressions that requires an actual object | 
|  | 3171 | // in memory. the DW_AT_data_member_location for a virtual base class looks like: | 
|  | 3172 | //      DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, DW_OP_plus ) | 
|  | 3173 | // Given this, there is really no valid response we can give to clang for virtual base | 
|  | 3174 | // class offsets, and this should eventually be removed from LayoutRecordType() in the external | 
|  | 3175 | // AST source in clang. | 
|  | 3176 | } | 
|  | 3177 | else | 
|  | 3178 | { | 
|  | 3179 | layout_info.base_offsets.insert( | 
|  | 3180 | std::make_pair(ast->GetAsCXXRecordDecl(base_class_clang_type.GetOpaqueQualType()), | 
|  | 3181 | clang::CharUnits::fromQuantity(member_byte_offset))); | 
|  | 3182 | } | 
|  | 3183 | } | 
|  | 3184 | } | 
|  | 3185 | } | 
|  | 3186 | break; | 
|  | 3187 |  | 
|  | 3188 | default: | 
|  | 3189 | break; | 
|  | 3190 | } | 
|  | 3191 | } | 
|  | 3192 |  | 
| Greg Clayton | e6b36cd | 2015-12-08 01:02:08 +0000 | [diff] [blame] | 3193 | return true; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3194 | } | 
|  | 3195 |  | 
|  | 3196 |  | 
|  | 3197 | size_t | 
|  | 3198 | DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc, | 
|  | 3199 | clang::DeclContext *containing_decl_ctx, | 
|  | 3200 | const DWARFDIE &parent_die, | 
|  | 3201 | bool skip_artificial, | 
|  | 3202 | bool &is_static, | 
|  | 3203 | bool &is_variadic, | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 3204 | bool &has_template_params, | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3205 | std::vector<CompilerType>& function_param_types, | 
|  | 3206 | std::vector<clang::ParmVarDecl*>& function_param_decls, | 
|  | 3207 | unsigned &type_quals) | 
|  | 3208 | { | 
|  | 3209 | if (!parent_die) | 
|  | 3210 | return 0; | 
|  | 3211 |  | 
|  | 3212 | size_t arg_idx = 0; | 
|  | 3213 | for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) | 
|  | 3214 | { | 
|  | 3215 | const dw_tag_t tag = die.Tag(); | 
|  | 3216 | switch (tag) | 
|  | 3217 | { | 
|  | 3218 | case DW_TAG_formal_parameter: | 
|  | 3219 | { | 
|  | 3220 | DWARFAttributes attributes; | 
|  | 3221 | const size_t num_attributes = die.GetAttributes(attributes); | 
|  | 3222 | if (num_attributes > 0) | 
|  | 3223 | { | 
|  | 3224 | const char *name = NULL; | 
|  | 3225 | Declaration decl; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3226 | DWARFFormValue param_type_die_form; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3227 | bool is_artificial = false; | 
|  | 3228 | // one of None, Auto, Register, Extern, Static, PrivateExtern | 
|  | 3229 |  | 
|  | 3230 | clang::StorageClass storage = clang::SC_None; | 
|  | 3231 | uint32_t i; | 
|  | 3232 | for (i=0; i<num_attributes; ++i) | 
|  | 3233 | { | 
|  | 3234 | const dw_attr_t attr = attributes.AttributeAtIndex(i); | 
|  | 3235 | DWARFFormValue form_value; | 
|  | 3236 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 3237 | { | 
|  | 3238 | switch (attr) | 
|  | 3239 | { | 
|  | 3240 | case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; | 
|  | 3241 | case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break; | 
|  | 3242 | case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; | 
|  | 3243 | case DW_AT_name:        name = form_value.AsCString(); | 
|  | 3244 | break; | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3245 | case DW_AT_type:        param_type_die_form = form_value; break; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3246 | case DW_AT_artificial:  is_artificial = form_value.Boolean(); break; | 
|  | 3247 | case DW_AT_location: | 
|  | 3248 | //                          if (form_value.BlockData()) | 
|  | 3249 | //                          { | 
|  | 3250 | //                              const DWARFDataExtractor& debug_info_data = debug_info(); | 
|  | 3251 | //                              uint32_t block_length = form_value.Unsigned(); | 
|  | 3252 | //                              DWARFDataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length); | 
|  | 3253 | //                          } | 
|  | 3254 | //                          else | 
|  | 3255 | //                          { | 
|  | 3256 | //                          } | 
|  | 3257 | //                          break; | 
|  | 3258 | case DW_AT_const_value: | 
|  | 3259 | case DW_AT_default_value: | 
|  | 3260 | case DW_AT_description: | 
|  | 3261 | case DW_AT_endianity: | 
|  | 3262 | case DW_AT_is_optional: | 
|  | 3263 | case DW_AT_segment: | 
|  | 3264 | case DW_AT_variable_parameter: | 
|  | 3265 | default: | 
|  | 3266 | case DW_AT_abstract_origin: | 
|  | 3267 | case DW_AT_sibling: | 
|  | 3268 | break; | 
|  | 3269 | } | 
|  | 3270 | } | 
|  | 3271 | } | 
|  | 3272 |  | 
|  | 3273 | bool skip = false; | 
|  | 3274 | if (skip_artificial) | 
|  | 3275 | { | 
|  | 3276 | if (is_artificial) | 
|  | 3277 | { | 
|  | 3278 | // In order to determine if a C++ member function is | 
|  | 3279 | // "const" we have to look at the const-ness of "this"... | 
|  | 3280 | // Ugly, but that | 
|  | 3281 | if (arg_idx == 0) | 
|  | 3282 | { | 
|  | 3283 | if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind())) | 
|  | 3284 | { | 
|  | 3285 | // Often times compilers omit the "this" name for the | 
|  | 3286 | // specification DIEs, so we can't rely upon the name | 
|  | 3287 | // being in the formal parameter DIE... | 
|  | 3288 | if (name == NULL || ::strcmp(name, "this")==0) | 
|  | 3289 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3290 | Type *this_type = die.ResolveTypeUID (DIERef(param_type_die_form).GetUID()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3291 | if (this_type) | 
|  | 3292 | { | 
|  | 3293 | uint32_t encoding_mask = this_type->GetEncodingMask(); | 
|  | 3294 | if (encoding_mask & Type::eEncodingIsPointerUID) | 
|  | 3295 | { | 
|  | 3296 | is_static = false; | 
|  | 3297 |  | 
|  | 3298 | if (encoding_mask & (1u << Type::eEncodingIsConstUID)) | 
|  | 3299 | type_quals |= clang::Qualifiers::Const; | 
|  | 3300 | if (encoding_mask & (1u << Type::eEncodingIsVolatileUID)) | 
|  | 3301 | type_quals |= clang::Qualifiers::Volatile; | 
|  | 3302 | } | 
|  | 3303 | } | 
|  | 3304 | } | 
|  | 3305 | } | 
|  | 3306 | } | 
|  | 3307 | skip = true; | 
|  | 3308 | } | 
|  | 3309 | else | 
|  | 3310 | { | 
|  | 3311 |  | 
|  | 3312 | // HACK: Objective C formal parameters "self" and "_cmd" | 
|  | 3313 | // are not marked as artificial in the DWARF... | 
|  | 3314 | CompileUnit *comp_unit = die.GetLLDBCompileUnit(); | 
|  | 3315 | if (comp_unit) | 
|  | 3316 | { | 
|  | 3317 | switch (comp_unit->GetLanguage()) | 
|  | 3318 | { | 
|  | 3319 | case eLanguageTypeObjC: | 
|  | 3320 | case eLanguageTypeObjC_plus_plus: | 
|  | 3321 | if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0)) | 
|  | 3322 | skip = true; | 
|  | 3323 | break; | 
|  | 3324 | default: | 
|  | 3325 | break; | 
|  | 3326 | } | 
|  | 3327 | } | 
|  | 3328 | } | 
|  | 3329 | } | 
|  | 3330 |  | 
|  | 3331 | if (!skip) | 
|  | 3332 | { | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3333 | Type *type = die.ResolveTypeUID(DIERef(param_type_die_form).GetUID()); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3334 | if (type) | 
|  | 3335 | { | 
|  | 3336 | function_param_types.push_back (type->GetForwardCompilerType ()); | 
|  | 3337 |  | 
|  | 3338 | clang::ParmVarDecl *param_var_decl = m_ast.CreateParameterDeclaration (name, | 
|  | 3339 | type->GetForwardCompilerType (), | 
|  | 3340 | storage); | 
|  | 3341 | assert(param_var_decl); | 
|  | 3342 | function_param_decls.push_back(param_var_decl); | 
|  | 3343 |  | 
|  | 3344 | m_ast.SetMetadataAsUserID (param_var_decl, die.GetID()); | 
|  | 3345 | } | 
|  | 3346 | } | 
|  | 3347 | } | 
|  | 3348 | arg_idx++; | 
|  | 3349 | } | 
|  | 3350 | break; | 
|  | 3351 |  | 
|  | 3352 | case DW_TAG_unspecified_parameters: | 
|  | 3353 | is_variadic = true; | 
|  | 3354 | break; | 
|  | 3355 |  | 
|  | 3356 | case DW_TAG_template_type_parameter: | 
|  | 3357 | case DW_TAG_template_value_parameter: | 
|  | 3358 | // The one caller of this was never using the template_param_infos, | 
|  | 3359 | // and the local variable was taking up a large amount of stack space | 
|  | 3360 | // in SymbolFileDWARF::ParseType() so this was removed. If we ever need | 
|  | 3361 | // the template params back, we can add them back. | 
|  | 3362 | // ParseTemplateDIE (dwarf_cu, die, template_param_infos); | 
| Greg Clayton | fb85e62 | 2016-02-09 22:36:24 +0000 | [diff] [blame] | 3363 | has_template_params = true; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3364 | break; | 
|  | 3365 |  | 
|  | 3366 | default: | 
|  | 3367 | break; | 
|  | 3368 | } | 
|  | 3369 | } | 
|  | 3370 | return arg_idx; | 
|  | 3371 | } | 
|  | 3372 |  | 
|  | 3373 | void | 
|  | 3374 | DWARFASTParserClang::ParseChildArrayInfo (const SymbolContext& sc, | 
|  | 3375 | const DWARFDIE &parent_die, | 
|  | 3376 | int64_t& first_index, | 
|  | 3377 | std::vector<uint64_t>& element_orders, | 
|  | 3378 | uint32_t& byte_stride, | 
|  | 3379 | uint32_t& bit_stride) | 
|  | 3380 | { | 
|  | 3381 | if (!parent_die) | 
|  | 3382 | return; | 
|  | 3383 |  | 
|  | 3384 | for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) | 
|  | 3385 | { | 
|  | 3386 | const dw_tag_t tag = die.Tag(); | 
|  | 3387 | switch (tag) | 
|  | 3388 | { | 
|  | 3389 | case DW_TAG_subrange_type: | 
|  | 3390 | { | 
|  | 3391 | DWARFAttributes attributes; | 
|  | 3392 | const size_t num_child_attributes = die.GetAttributes(attributes); | 
|  | 3393 | if (num_child_attributes > 0) | 
|  | 3394 | { | 
|  | 3395 | uint64_t num_elements = 0; | 
|  | 3396 | uint64_t lower_bound = 0; | 
|  | 3397 | uint64_t upper_bound = 0; | 
|  | 3398 | bool upper_bound_valid = false; | 
|  | 3399 | uint32_t i; | 
|  | 3400 | for (i=0; i<num_child_attributes; ++i) | 
|  | 3401 | { | 
|  | 3402 | const dw_attr_t attr = attributes.AttributeAtIndex(i); | 
|  | 3403 | DWARFFormValue form_value; | 
|  | 3404 | if (attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 3405 | { | 
|  | 3406 | switch (attr) | 
|  | 3407 | { | 
|  | 3408 | case DW_AT_name: | 
|  | 3409 | break; | 
|  | 3410 |  | 
|  | 3411 | case DW_AT_count: | 
|  | 3412 | num_elements = form_value.Unsigned(); | 
|  | 3413 | break; | 
|  | 3414 |  | 
|  | 3415 | case DW_AT_bit_stride: | 
|  | 3416 | bit_stride = form_value.Unsigned(); | 
|  | 3417 | break; | 
|  | 3418 |  | 
|  | 3419 | case DW_AT_byte_stride: | 
|  | 3420 | byte_stride = form_value.Unsigned(); | 
|  | 3421 | break; | 
|  | 3422 |  | 
|  | 3423 | case DW_AT_lower_bound: | 
|  | 3424 | lower_bound = form_value.Unsigned(); | 
|  | 3425 | break; | 
|  | 3426 |  | 
|  | 3427 | case DW_AT_upper_bound: | 
|  | 3428 | upper_bound_valid = true; | 
|  | 3429 | upper_bound = form_value.Unsigned(); | 
|  | 3430 | break; | 
|  | 3431 |  | 
|  | 3432 | default: | 
|  | 3433 | case DW_AT_abstract_origin: | 
|  | 3434 | case DW_AT_accessibility: | 
|  | 3435 | case DW_AT_allocated: | 
|  | 3436 | case DW_AT_associated: | 
|  | 3437 | case DW_AT_data_location: | 
|  | 3438 | case DW_AT_declaration: | 
|  | 3439 | case DW_AT_description: | 
|  | 3440 | case DW_AT_sibling: | 
|  | 3441 | case DW_AT_threads_scaled: | 
|  | 3442 | case DW_AT_type: | 
|  | 3443 | case DW_AT_visibility: | 
|  | 3444 | break; | 
|  | 3445 | } | 
|  | 3446 | } | 
|  | 3447 | } | 
|  | 3448 |  | 
|  | 3449 | if (num_elements == 0) | 
|  | 3450 | { | 
|  | 3451 | if (upper_bound_valid && upper_bound >= lower_bound) | 
|  | 3452 | num_elements = upper_bound - lower_bound + 1; | 
|  | 3453 | } | 
|  | 3454 |  | 
|  | 3455 | element_orders.push_back (num_elements); | 
|  | 3456 | } | 
|  | 3457 | } | 
|  | 3458 | break; | 
|  | 3459 | } | 
|  | 3460 | } | 
|  | 3461 | } | 
|  | 3462 |  | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 3463 | Type * | 
|  | 3464 | DWARFASTParserClang::GetTypeForDIE (const DWARFDIE &die) | 
|  | 3465 | { | 
|  | 3466 | if (die) | 
|  | 3467 | { | 
|  | 3468 | SymbolFileDWARF *dwarf = die.GetDWARF(); | 
|  | 3469 | DWARFAttributes attributes; | 
|  | 3470 | const size_t num_attributes = die.GetAttributes(attributes); | 
|  | 3471 | if (num_attributes > 0) | 
|  | 3472 | { | 
|  | 3473 | DWARFFormValue type_die_form; | 
|  | 3474 | for (size_t i = 0; i < num_attributes; ++i) | 
|  | 3475 | { | 
|  | 3476 | dw_attr_t attr = attributes.AttributeAtIndex(i); | 
|  | 3477 | DWARFFormValue form_value; | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 3478 |  | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 3479 | if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value)) | 
|  | 3480 | return dwarf->ResolveTypeUID(DIERef(form_value).GetUID()); | 
|  | 3481 | } | 
|  | 3482 | } | 
|  | 3483 | } | 
|  | 3484 |  | 
|  | 3485 | return nullptr; | 
|  | 3486 | } | 
|  | 3487 |  | 
|  | 3488 | clang::Decl * | 
|  | 3489 | DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die) | 
|  | 3490 | { | 
|  | 3491 | if (!die) | 
|  | 3492 | return nullptr; | 
|  | 3493 |  | 
| Paul Herman | f6681b4 | 2015-09-17 19:32:02 +0000 | [diff] [blame] | 3494 | switch (die.Tag()) | 
|  | 3495 | { | 
|  | 3496 | case DW_TAG_variable: | 
|  | 3497 | case DW_TAG_constant: | 
|  | 3498 | case DW_TAG_formal_parameter: | 
|  | 3499 | case DW_TAG_imported_declaration: | 
|  | 3500 | case DW_TAG_imported_module: | 
|  | 3501 | break; | 
|  | 3502 | default: | 
|  | 3503 | return nullptr; | 
|  | 3504 | } | 
| Paul Herman | ea188fc | 2015-09-16 18:48:30 +0000 | [diff] [blame] | 3505 |  | 
| Paul Herman | f6681b4 | 2015-09-17 19:32:02 +0000 | [diff] [blame] | 3506 | DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE()); | 
|  | 3507 | if (cache_pos != m_die_to_decl.end()) | 
|  | 3508 | return cache_pos->second; | 
|  | 3509 |  | 
|  | 3510 | if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) | 
|  | 3511 | { | 
|  | 3512 | clang::Decl *decl = GetClangDeclForDIE(spec_die); | 
|  | 3513 | m_die_to_decl[die.GetDIE()] = decl; | 
|  | 3514 | m_decl_to_die[decl].insert(die.GetDIE()); | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 3515 | return decl; | 
| Paul Herman | f6681b4 | 2015-09-17 19:32:02 +0000 | [diff] [blame] | 3516 | } | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 3517 |  | 
| Paul Herman | f6681b4 | 2015-09-17 19:32:02 +0000 | [diff] [blame] | 3518 | clang::Decl *decl = nullptr; | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 3519 | switch (die.Tag()) | 
|  | 3520 | { | 
|  | 3521 | case DW_TAG_variable: | 
|  | 3522 | case DW_TAG_constant: | 
|  | 3523 | case DW_TAG_formal_parameter: | 
|  | 3524 | { | 
|  | 3525 | SymbolFileDWARF *dwarf = die.GetDWARF(); | 
|  | 3526 | Type *type = GetTypeForDIE(die); | 
|  | 3527 | const char *name = die.GetName(); | 
|  | 3528 | clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID())); | 
|  | 3529 | decl = m_ast.CreateVariableDeclaration( | 
|  | 3530 | decl_context, | 
|  | 3531 | name, | 
|  | 3532 | ClangASTContext::GetQualType(type->GetForwardCompilerType())); | 
|  | 3533 | break; | 
|  | 3534 | } | 
|  | 3535 | case DW_TAG_imported_declaration: | 
|  | 3536 | { | 
|  | 3537 | SymbolFileDWARF *dwarf = die.GetDWARF(); | 
|  | 3538 | lldb::user_id_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET); | 
|  | 3539 |  | 
|  | 3540 | if (dwarf->UserIDMatches(imported_uid)) | 
|  | 3541 | { | 
|  | 3542 | CompilerDecl imported_decl = dwarf->GetDeclForUID(imported_uid); | 
|  | 3543 | if (imported_decl) | 
|  | 3544 | { | 
|  | 3545 | clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID())); | 
|  | 3546 | if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)imported_decl.GetOpaqueDecl())) | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 3547 | decl = m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl); | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 3548 | } | 
|  | 3549 | } | 
|  | 3550 | break; | 
|  | 3551 | } | 
|  | 3552 | case DW_TAG_imported_module: | 
|  | 3553 | { | 
|  | 3554 | SymbolFileDWARF *dwarf = die.GetDWARF(); | 
|  | 3555 | lldb::user_id_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET); | 
|  | 3556 |  | 
|  | 3557 | if (dwarf->UserIDMatches(imported_uid)) | 
|  | 3558 | { | 
|  | 3559 | CompilerDeclContext imported_decl = dwarf->GetDeclContextForUID(imported_uid); | 
|  | 3560 | if (imported_decl) | 
|  | 3561 | { | 
|  | 3562 | clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID())); | 
| Paul Herman | ea188fc | 2015-09-16 18:48:30 +0000 | [diff] [blame] | 3563 | if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(imported_decl)) | 
|  | 3564 | decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl); | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 3565 | } | 
|  | 3566 | } | 
|  | 3567 | break; | 
|  | 3568 | } | 
|  | 3569 | default: | 
|  | 3570 | break; | 
|  | 3571 | } | 
|  | 3572 |  | 
|  | 3573 | m_die_to_decl[die.GetDIE()] = decl; | 
|  | 3574 | m_decl_to_die[decl].insert(die.GetDIE()); | 
|  | 3575 |  | 
|  | 3576 | return decl; | 
|  | 3577 | } | 
|  | 3578 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3579 | clang::DeclContext * | 
|  | 3580 | DWARFASTParserClang::GetClangDeclContextForDIE (const DWARFDIE &die) | 
|  | 3581 | { | 
|  | 3582 | if (die) | 
|  | 3583 | { | 
|  | 3584 | clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE (die); | 
|  | 3585 | if (decl_ctx) | 
|  | 3586 | return decl_ctx; | 
|  | 3587 |  | 
|  | 3588 | bool try_parsing_type = true; | 
|  | 3589 | switch (die.Tag()) | 
|  | 3590 | { | 
|  | 3591 | case DW_TAG_compile_unit: | 
|  | 3592 | decl_ctx = m_ast.GetTranslationUnitDecl(); | 
|  | 3593 | try_parsing_type = false; | 
|  | 3594 | break; | 
|  | 3595 |  | 
|  | 3596 | case DW_TAG_namespace: | 
|  | 3597 | decl_ctx = ResolveNamespaceDIE (die); | 
|  | 3598 | try_parsing_type = false; | 
|  | 3599 | break; | 
|  | 3600 |  | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 3601 | case DW_TAG_lexical_block: | 
|  | 3602 | decl_ctx = (clang::DeclContext *)ResolveBlockDIE(die); | 
|  | 3603 | try_parsing_type = false; | 
|  | 3604 | break; | 
|  | 3605 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3606 | default: | 
|  | 3607 | break; | 
|  | 3608 | } | 
|  | 3609 |  | 
|  | 3610 | if (decl_ctx == nullptr && try_parsing_type) | 
|  | 3611 | { | 
|  | 3612 | Type* type = die.GetDWARF()->ResolveType (die); | 
|  | 3613 | if (type) | 
|  | 3614 | decl_ctx = GetCachedClangDeclContextForDIE (die); | 
|  | 3615 | } | 
|  | 3616 |  | 
|  | 3617 | if (decl_ctx) | 
|  | 3618 | { | 
|  | 3619 | LinkDeclContextToDIE (decl_ctx, die); | 
|  | 3620 | return decl_ctx; | 
|  | 3621 | } | 
|  | 3622 | } | 
|  | 3623 | return nullptr; | 
|  | 3624 | } | 
|  | 3625 |  | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 3626 | clang::BlockDecl * | 
|  | 3627 | DWARFASTParserClang::ResolveBlockDIE (const DWARFDIE &die) | 
|  | 3628 | { | 
|  | 3629 | if (die && die.Tag() == DW_TAG_lexical_block) | 
|  | 3630 | { | 
|  | 3631 | clang::BlockDecl *decl = llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 3632 |  | 
| Paul Herman | d628cbb | 2015-09-15 23:44:17 +0000 | [diff] [blame] | 3633 | if (!decl) | 
|  | 3634 | { | 
|  | 3635 | DWARFDIE decl_context_die; | 
|  | 3636 | clang::DeclContext *decl_context = GetClangDeclContextContainingDIE(die, &decl_context_die); | 
|  | 3637 | decl = m_ast.CreateBlockDeclaration(decl_context); | 
|  | 3638 |  | 
|  | 3639 | if (decl) | 
|  | 3640 | LinkDeclContextToDIE((clang::DeclContext *)decl, die); | 
|  | 3641 | } | 
|  | 3642 |  | 
|  | 3643 | return decl; | 
|  | 3644 | } | 
|  | 3645 | return nullptr; | 
|  | 3646 | } | 
|  | 3647 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3648 | clang::NamespaceDecl * | 
|  | 3649 | DWARFASTParserClang::ResolveNamespaceDIE (const DWARFDIE &die) | 
|  | 3650 | { | 
|  | 3651 | if (die && die.Tag() == DW_TAG_namespace) | 
|  | 3652 | { | 
|  | 3653 | // See if we already parsed this namespace DIE and associated it with a | 
|  | 3654 | // uniqued namespace declaration | 
|  | 3655 | clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]); | 
|  | 3656 | if (namespace_decl) | 
|  | 3657 | return namespace_decl; | 
|  | 3658 | else | 
|  | 3659 | { | 
|  | 3660 | const char *namespace_name = die.GetName(); | 
|  | 3661 | clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, nullptr); | 
|  | 3662 | namespace_decl = m_ast.GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx); | 
|  | 3663 | Log *log = nullptr;// (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); | 
|  | 3664 | if (log) | 
|  | 3665 | { | 
|  | 3666 | SymbolFileDWARF *dwarf = die.GetDWARF(); | 
|  | 3667 | if (namespace_name) | 
|  | 3668 | { | 
|  | 3669 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, | 
|  | 3670 | "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)", | 
|  | 3671 | static_cast<void*>(m_ast.getASTContext()), | 
|  | 3672 | die.GetID(), | 
|  | 3673 | namespace_name, | 
|  | 3674 | static_cast<void*>(namespace_decl), | 
|  | 3675 | static_cast<void*>(namespace_decl->getOriginalNamespace())); | 
|  | 3676 | } | 
|  | 3677 | else | 
|  | 3678 | { | 
|  | 3679 | dwarf->GetObjectFile()->GetModule()->LogMessage (log, | 
|  | 3680 | "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)", | 
|  | 3681 | static_cast<void*>(m_ast.getASTContext()), | 
|  | 3682 | die.GetID(), | 
|  | 3683 | static_cast<void*>(namespace_decl), | 
|  | 3684 | static_cast<void*>(namespace_decl->getOriginalNamespace())); | 
|  | 3685 | } | 
|  | 3686 | } | 
|  | 3687 |  | 
|  | 3688 | if (namespace_decl) | 
|  | 3689 | LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); | 
|  | 3690 | return namespace_decl; | 
|  | 3691 | } | 
|  | 3692 | } | 
|  | 3693 | return nullptr; | 
|  | 3694 | } | 
|  | 3695 |  | 
|  | 3696 | clang::DeclContext * | 
|  | 3697 | DWARFASTParserClang::GetClangDeclContextContainingDIE (const DWARFDIE &die, | 
|  | 3698 | DWARFDIE *decl_ctx_die_copy) | 
|  | 3699 | { | 
|  | 3700 | SymbolFileDWARF *dwarf = die.GetDWARF(); | 
|  | 3701 |  | 
|  | 3702 | DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE (die); | 
|  | 3703 |  | 
|  | 3704 | if (decl_ctx_die_copy) | 
|  | 3705 | *decl_ctx_die_copy = decl_ctx_die; | 
|  | 3706 |  | 
|  | 3707 | if (decl_ctx_die) | 
|  | 3708 | { | 
|  | 3709 | clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE (decl_ctx_die); | 
|  | 3710 | if (clang_decl_ctx) | 
|  | 3711 | return clang_decl_ctx; | 
|  | 3712 | } | 
|  | 3713 | return m_ast.GetTranslationUnitDecl(); | 
|  | 3714 | } | 
|  | 3715 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3716 | clang::DeclContext * | 
|  | 3717 | DWARFASTParserClang::GetCachedClangDeclContextForDIE (const DWARFDIE &die) | 
|  | 3718 | { | 
|  | 3719 | if (die) | 
|  | 3720 | { | 
|  | 3721 | DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE()); | 
|  | 3722 | if (pos != m_die_to_decl_ctx.end()) | 
|  | 3723 | return pos->second; | 
|  | 3724 | } | 
|  | 3725 | return nullptr; | 
|  | 3726 | } | 
|  | 3727 |  | 
|  | 3728 | void | 
|  | 3729 | DWARFASTParserClang::LinkDeclContextToDIE (clang::DeclContext *decl_ctx, const DWARFDIE &die) | 
|  | 3730 | { | 
|  | 3731 | m_die_to_decl_ctx[die.GetDIE()] = decl_ctx; | 
|  | 3732 | // There can be many DIEs for a single decl context | 
| Paul Herman | ea188fc | 2015-09-16 18:48:30 +0000 | [diff] [blame] | 3733 | //m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE()); | 
|  | 3734 | m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die)); | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3735 | } | 
|  | 3736 |  | 
|  | 3737 | bool | 
|  | 3738 | DWARFASTParserClang::CopyUniqueClassMethodTypes (const DWARFDIE &src_class_die, | 
|  | 3739 | const DWARFDIE &dst_class_die, | 
|  | 3740 | lldb_private::Type *class_type, | 
|  | 3741 | DWARFDIECollection &failures) | 
|  | 3742 | { | 
|  | 3743 | if (!class_type || !src_class_die || !dst_class_die) | 
|  | 3744 | return false; | 
|  | 3745 | if (src_class_die.Tag() != dst_class_die.Tag()) | 
|  | 3746 | return false; | 
|  | 3747 |  | 
|  | 3748 | // We need to complete the class type so we can get all of the method types | 
|  | 3749 | // parsed so we can then unique those types to their equivalent counterparts | 
|  | 3750 | // in "dst_cu" and "dst_class_die" | 
|  | 3751 | class_type->GetFullCompilerType (); | 
|  | 3752 |  | 
|  | 3753 | DWARFDIE src_die; | 
|  | 3754 | DWARFDIE dst_die; | 
|  | 3755 | UniqueCStringMap<DWARFDIE> src_name_to_die; | 
|  | 3756 | UniqueCStringMap<DWARFDIE> dst_name_to_die; | 
|  | 3757 | UniqueCStringMap<DWARFDIE> src_name_to_die_artificial; | 
|  | 3758 | UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial; | 
|  | 3759 | for (src_die = src_class_die.GetFirstChild(); src_die.IsValid(); src_die = src_die.GetSibling()) | 
|  | 3760 | { | 
|  | 3761 | if (src_die.Tag() == DW_TAG_subprogram) | 
|  | 3762 | { | 
|  | 3763 | // Make sure this is a declaration and not a concrete instance by looking | 
|  | 3764 | // for DW_AT_declaration set to 1. Sometimes concrete function instances | 
|  | 3765 | // are placed inside the class definitions and shouldn't be included in | 
|  | 3766 | // the list of things are are tracking here. | 
|  | 3767 | if (src_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) | 
|  | 3768 | { | 
|  | 3769 | const char *src_name = src_die.GetMangledName (); | 
|  | 3770 | if (src_name) | 
|  | 3771 | { | 
|  | 3772 | ConstString src_const_name(src_name); | 
|  | 3773 | if (src_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) | 
|  | 3774 | src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die); | 
|  | 3775 | else | 
|  | 3776 | src_name_to_die.Append(src_const_name.GetCString(), src_die); | 
|  | 3777 | } | 
|  | 3778 | } | 
|  | 3779 | } | 
|  | 3780 | } | 
|  | 3781 | for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); dst_die = dst_die.GetSibling()) | 
|  | 3782 | { | 
|  | 3783 | if (dst_die.Tag() == DW_TAG_subprogram) | 
|  | 3784 | { | 
|  | 3785 | // Make sure this is a declaration and not a concrete instance by looking | 
|  | 3786 | // for DW_AT_declaration set to 1. Sometimes concrete function instances | 
|  | 3787 | // are placed inside the class definitions and shouldn't be included in | 
|  | 3788 | // the list of things are are tracking here. | 
|  | 3789 | if (dst_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) | 
|  | 3790 | { | 
|  | 3791 | const char *dst_name =  dst_die.GetMangledName (); | 
|  | 3792 | if (dst_name) | 
|  | 3793 | { | 
|  | 3794 | ConstString dst_const_name(dst_name); | 
|  | 3795 | if ( dst_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) | 
|  | 3796 | dst_name_to_die_artificial.Append(dst_const_name.GetCString(), dst_die); | 
|  | 3797 | else | 
|  | 3798 | dst_name_to_die.Append(dst_const_name.GetCString(), dst_die); | 
|  | 3799 | } | 
|  | 3800 | } | 
|  | 3801 | } | 
|  | 3802 | } | 
|  | 3803 | const uint32_t src_size = src_name_to_die.GetSize (); | 
|  | 3804 | const uint32_t dst_size = dst_name_to_die.GetSize (); | 
|  | 3805 | Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION)); | 
|  | 3806 |  | 
|  | 3807 | // Is everything kosher so we can go through the members at top speed? | 
|  | 3808 | bool fast_path = true; | 
|  | 3809 |  | 
|  | 3810 | if (src_size != dst_size) | 
|  | 3811 | { | 
|  | 3812 | if (src_size != 0 && dst_size != 0) | 
|  | 3813 | { | 
|  | 3814 | if (log) | 
|  | 3815 | log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)", | 
|  | 3816 | src_class_die.GetOffset(), | 
|  | 3817 | dst_class_die.GetOffset(), | 
|  | 3818 | src_size, | 
|  | 3819 | dst_size); | 
|  | 3820 | } | 
|  | 3821 |  | 
|  | 3822 | fast_path = false; | 
|  | 3823 | } | 
|  | 3824 |  | 
|  | 3825 | uint32_t idx; | 
|  | 3826 |  | 
|  | 3827 | if (fast_path) | 
|  | 3828 | { | 
|  | 3829 | for (idx = 0; idx < src_size; ++idx) | 
|  | 3830 | { | 
|  | 3831 | src_die = src_name_to_die.GetValueAtIndexUnchecked (idx); | 
|  | 3832 | dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx); | 
|  | 3833 |  | 
|  | 3834 | if (src_die.Tag() != dst_die.Tag()) | 
|  | 3835 | { | 
|  | 3836 | if (log) | 
|  | 3837 | log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)", | 
|  | 3838 | src_class_die.GetOffset(), | 
|  | 3839 | dst_class_die.GetOffset(), | 
|  | 3840 | src_die.GetOffset(), | 
|  | 3841 | src_die.GetTagAsCString(), | 
|  | 3842 | dst_die.GetOffset(), | 
|  | 3843 | dst_die.GetTagAsCString()); | 
|  | 3844 | fast_path = false; | 
|  | 3845 | } | 
|  | 3846 |  | 
|  | 3847 | const char *src_name = src_die.GetMangledName (); | 
|  | 3848 | const char *dst_name = dst_die.GetMangledName (); | 
|  | 3849 |  | 
|  | 3850 | // Make sure the names match | 
|  | 3851 | if (src_name == dst_name || (strcmp (src_name, dst_name) == 0)) | 
|  | 3852 | continue; | 
|  | 3853 |  | 
|  | 3854 | if (log) | 
|  | 3855 | log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)", | 
|  | 3856 | src_class_die.GetOffset(), | 
|  | 3857 | dst_class_die.GetOffset(), | 
|  | 3858 | src_die.GetOffset(), | 
|  | 3859 | src_name, | 
|  | 3860 | dst_die.GetOffset(), | 
|  | 3861 | dst_name); | 
|  | 3862 |  | 
|  | 3863 | fast_path = false; | 
|  | 3864 | } | 
|  | 3865 | } | 
|  | 3866 |  | 
|  | 3867 | DWARFASTParserClang *src_dwarf_ast_parser = (DWARFASTParserClang *)src_die.GetDWARFParser(); | 
|  | 3868 | DWARFASTParserClang *dst_dwarf_ast_parser = (DWARFASTParserClang *)dst_die.GetDWARFParser(); | 
|  | 3869 |  | 
|  | 3870 | // Now do the work of linking the DeclContexts and Types. | 
|  | 3871 | if (fast_path) | 
|  | 3872 | { | 
|  | 3873 | // We can do this quickly.  Just run across the tables index-for-index since | 
|  | 3874 | // we know each node has matching names and tags. | 
|  | 3875 | for (idx = 0; idx < src_size; ++idx) | 
|  | 3876 | { | 
|  | 3877 | src_die = src_name_to_die.GetValueAtIndexUnchecked (idx); | 
|  | 3878 | dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx); | 
|  | 3879 |  | 
|  | 3880 | clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; | 
|  | 3881 | if (src_decl_ctx) | 
|  | 3882 | { | 
|  | 3883 | if (log) | 
|  | 3884 | log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", | 
|  | 3885 | static_cast<void*>(src_decl_ctx), | 
|  | 3886 | src_die.GetOffset(), dst_die.GetOffset()); | 
|  | 3887 | dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die); | 
|  | 3888 | } | 
|  | 3889 | else | 
|  | 3890 | { | 
|  | 3891 | if (log) | 
|  | 3892 | log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", | 
|  | 3893 | src_die.GetOffset(), dst_die.GetOffset()); | 
|  | 3894 | } | 
|  | 3895 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3896 | Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3897 | if (src_child_type) | 
|  | 3898 | { | 
|  | 3899 | if (log) | 
|  | 3900 | log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", | 
|  | 3901 | static_cast<void*>(src_child_type), | 
|  | 3902 | src_child_type->GetID(), | 
|  | 3903 | src_die.GetOffset(), dst_die.GetOffset()); | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3904 | dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3905 | } | 
|  | 3906 | else | 
|  | 3907 | { | 
|  | 3908 | if (log) | 
|  | 3909 | log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset()); | 
|  | 3910 | } | 
|  | 3911 | } | 
|  | 3912 | } | 
|  | 3913 | else | 
|  | 3914 | { | 
|  | 3915 | // We must do this slowly.  For each member of the destination, look | 
|  | 3916 | // up a member in the source with the same name, check its tag, and | 
|  | 3917 | // unique them if everything matches up.  Report failures. | 
|  | 3918 |  | 
|  | 3919 | if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty()) | 
|  | 3920 | { | 
|  | 3921 | src_name_to_die.Sort(); | 
|  | 3922 |  | 
|  | 3923 | for (idx = 0; idx < dst_size; ++idx) | 
|  | 3924 | { | 
|  | 3925 | const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx); | 
|  | 3926 | dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); | 
|  | 3927 | src_die = src_name_to_die.Find(dst_name, DWARFDIE()); | 
|  | 3928 |  | 
|  | 3929 | if (src_die && (src_die.Tag() == dst_die.Tag())) | 
|  | 3930 | { | 
|  | 3931 | clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; | 
|  | 3932 | if (src_decl_ctx) | 
|  | 3933 | { | 
|  | 3934 | if (log) | 
|  | 3935 | log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", | 
|  | 3936 | static_cast<void*>(src_decl_ctx), | 
|  | 3937 | src_die.GetOffset(), | 
|  | 3938 | dst_die.GetOffset()); | 
|  | 3939 | dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die); | 
|  | 3940 | } | 
|  | 3941 | else | 
|  | 3942 | { | 
|  | 3943 | if (log) | 
|  | 3944 | log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset()); | 
|  | 3945 | } | 
|  | 3946 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3947 | Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3948 | if (src_child_type) | 
|  | 3949 | { | 
|  | 3950 | if (log) | 
|  | 3951 | log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", | 
|  | 3952 | static_cast<void*>(src_child_type), | 
|  | 3953 | src_child_type->GetID(), | 
|  | 3954 | src_die.GetOffset(), | 
|  | 3955 | dst_die.GetOffset()); | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 3956 | dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3957 | } | 
|  | 3958 | else | 
|  | 3959 | { | 
|  | 3960 | if (log) | 
|  | 3961 | log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset()); | 
|  | 3962 | } | 
|  | 3963 | } | 
|  | 3964 | else | 
|  | 3965 | { | 
|  | 3966 | if (log) | 
|  | 3967 | log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die.GetOffset()); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 3968 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3969 | failures.Append(dst_die); | 
|  | 3970 | } | 
|  | 3971 | } | 
|  | 3972 | } | 
|  | 3973 | } | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 3974 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3975 | const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize (); | 
|  | 3976 | const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize (); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 3977 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3978 | if (src_size_artificial && dst_size_artificial) | 
|  | 3979 | { | 
|  | 3980 | dst_name_to_die_artificial.Sort(); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 3981 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3982 | for (idx = 0; idx < src_size_artificial; ++idx) | 
|  | 3983 | { | 
|  | 3984 | const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx); | 
|  | 3985 | src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked (idx); | 
|  | 3986 | dst_die = dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE()); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 3987 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 3988 | if (dst_die) | 
|  | 3989 | { | 
|  | 3990 | // Both classes have the artificial types, link them | 
|  | 3991 | clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; | 
|  | 3992 | if (src_decl_ctx) | 
|  | 3993 | { | 
|  | 3994 | if (log) | 
|  | 3995 | log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", | 
|  | 3996 | static_cast<void*>(src_decl_ctx), | 
|  | 3997 | src_die.GetOffset(), dst_die.GetOffset()); | 
|  | 3998 | dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die); | 
|  | 3999 | } | 
|  | 4000 | else | 
|  | 4001 | { | 
|  | 4002 | if (log) | 
|  | 4003 | log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset()); | 
|  | 4004 | } | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 4005 |  | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 4006 | Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 4007 | if (src_child_type) | 
|  | 4008 | { | 
|  | 4009 | if (log) | 
|  | 4010 | log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", | 
|  | 4011 | static_cast<void*>(src_child_type), | 
|  | 4012 | src_child_type->GetID(), | 
|  | 4013 | src_die.GetOffset(), dst_die.GetOffset()); | 
| Tamas Berghammer | eb882fc | 2015-09-09 10:20:48 +0000 | [diff] [blame] | 4014 | dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 4015 | } | 
|  | 4016 | else | 
|  | 4017 | { | 
|  | 4018 | if (log) | 
|  | 4019 | log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset()); | 
|  | 4020 | } | 
|  | 4021 | } | 
|  | 4022 | } | 
|  | 4023 | } | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 4024 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 4025 | if (dst_size_artificial) | 
|  | 4026 | { | 
|  | 4027 | for (idx = 0; idx < dst_size_artificial; ++idx) | 
|  | 4028 | { | 
|  | 4029 | const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx); | 
|  | 4030 | dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx); | 
|  | 4031 | if (log) | 
|  | 4032 | log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die.GetOffset(), dst_name_artificial); | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 4033 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 4034 | failures.Append(dst_die); | 
|  | 4035 | } | 
|  | 4036 | } | 
| Ramkumar Ramachandra | 314b752 | 2015-11-12 14:44:24 +0000 | [diff] [blame] | 4037 |  | 
| Greg Clayton | 261ac3f | 2015-08-28 01:01:03 +0000 | [diff] [blame] | 4038 | return (failures.Size() != 0); | 
|  | 4039 | } | 
|  | 4040 |  | 
|  | 4041 |  | 
|  | 4042 | bool | 
|  | 4043 | DWARFASTParserClang::LayoutRecordType(const clang::RecordDecl *record_decl, | 
|  | 4044 | uint64_t &bit_size, | 
|  | 4045 | uint64_t &alignment, | 
|  | 4046 | llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, | 
|  | 4047 | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, | 
|  | 4048 | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) | 
|  | 4049 | { | 
|  | 4050 | RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl); | 
|  | 4051 | bool success = false; | 
|  | 4052 | base_offsets.clear(); | 
|  | 4053 | vbase_offsets.clear(); | 
|  | 4054 | if (pos != m_record_decl_to_layout_map.end()) | 
|  | 4055 | { | 
|  | 4056 | bit_size = pos->second.bit_size; | 
|  | 4057 | alignment = pos->second.alignment; | 
|  | 4058 | field_offsets.swap(pos->second.field_offsets); | 
|  | 4059 | base_offsets.swap (pos->second.base_offsets); | 
|  | 4060 | vbase_offsets.swap (pos->second.vbase_offsets); | 
|  | 4061 | m_record_decl_to_layout_map.erase(pos); | 
|  | 4062 | success = true; | 
|  | 4063 | } | 
|  | 4064 | else | 
|  | 4065 | { | 
|  | 4066 | bit_size = 0; | 
|  | 4067 | alignment = 0; | 
|  | 4068 | field_offsets.clear(); | 
|  | 4069 | } | 
|  | 4070 | return success; | 
|  | 4071 | } |