forked from OSchip/llvm-project
Created lldb::LanguageType by moving an enumeration from the
lldb_private::Language class into the enumerations header so it can be freely used by other interfaces. Added correct objective C class support to the DWARF symbol parser. Prior to this fix we were parsing objective C classes as C++ classes and now that the expression parser is ready to call functions we need to make sure the objective C classes have correct AST types. llvm-svn: 109574
This commit is contained in:
parent
e1270c64e3
commit
9e40956aea
|
@ -26,42 +26,10 @@ namespace lldb_private {
|
|||
class Language
|
||||
{
|
||||
public:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Programming language type.
|
||||
///
|
||||
/// These enumerations use the same language enumerations as the
|
||||
/// DWARF specification for ease of use and consistency.
|
||||
//------------------------------------------------------------------
|
||||
typedef enum
|
||||
{
|
||||
Unknown = 0x0000, ///< Unknown or invalid language value.
|
||||
C89 = 0x0001, ///< ISO C:1989.
|
||||
C = 0x0002, ///< Non-standardized C, such as K&R.
|
||||
Ada83 = 0x0003, ///< ISO Ada:1983.
|
||||
C_plus_plus = 0x0004, ///< ISO C++:1998.
|
||||
Cobol74 = 0x0005, ///< ISO Cobol:1974.
|
||||
Cobol85 = 0x0006, ///< ISO Cobol:1985.
|
||||
Fortran77 = 0x0007, ///< ISO Fortran 77.
|
||||
Fortran90 = 0x0008, ///< ISO Fortran 90.
|
||||
Pascal83 = 0x0009, ///< ISO Pascal:1983.
|
||||
Modula2 = 0x000a, ///< ISO Modula-2:1996.
|
||||
Java = 0x000b, ///< Java.
|
||||
C99 = 0x000c, ///< ISO C:1999.
|
||||
Ada95 = 0x000d, ///< ISO Ada:1995.
|
||||
Fortran95 = 0x000e, ///< ISO Fortran 95.
|
||||
PLI = 0x000f, ///< ANSI PL/I:1976.
|
||||
ObjC = 0x0010, ///< Objective-C.
|
||||
ObjC_plus_plus = 0x0011, ///< Objective-C++.
|
||||
UPC = 0x0012, ///< Unified Parallel C.
|
||||
D = 0x0013, ///< D.
|
||||
Python = 0x0014 ///< Python.
|
||||
} Type;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Construct with optional language enumeration.
|
||||
//------------------------------------------------------------------
|
||||
Language(Language::Type language = Unknown);
|
||||
Language(lldb::LanguageType language = lldb::eLanguageTypeUnknown);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Destructor.
|
||||
|
@ -78,7 +46,7 @@ public:
|
|||
/// The C string representation of the language. The returned
|
||||
/// string does not need to be freed as it comes from constant
|
||||
/// strings. NULL can be returned when the language is set to
|
||||
/// a value that doesn't match of of the Language::Type
|
||||
/// a value that doesn't match of of the lldb::LanguageType
|
||||
/// enumerations.
|
||||
//------------------------------------------------------------------
|
||||
const char *
|
||||
|
@ -106,7 +74,7 @@ public:
|
|||
/// The enumeration value that describes the programming
|
||||
/// language that an object is associated with.
|
||||
//------------------------------------------------------------------
|
||||
Language::Type
|
||||
lldb::LanguageType
|
||||
GetLanguage() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
@ -117,7 +85,7 @@ public:
|
|||
/// language that an object is associated with.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetLanguage(Language::Type language);
|
||||
SetLanguage(lldb::LanguageType language);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set accessor for the language.
|
||||
|
@ -133,9 +101,9 @@ protected:
|
|||
//------------------------------------------------------------------
|
||||
// Member variables
|
||||
//------------------------------------------------------------------
|
||||
Language::Type m_language; ///< The programming language enumeration value.
|
||||
///< The enumeration values are the same as the
|
||||
///< latest DWARF specification.
|
||||
lldb::LanguageType m_language; ///< The programming language enumeration value.
|
||||
///< The enumeration values are the same as the
|
||||
///< latest DWARF specification.
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
|
|
@ -157,7 +157,8 @@ public:
|
|||
void *
|
||||
CreateRecordType (const char *name,
|
||||
int kind,
|
||||
clang::DeclContext *decl_ctx);
|
||||
clang::DeclContext *decl_ctx,
|
||||
lldb::LanguageType language);
|
||||
|
||||
bool
|
||||
AddFieldToRecordType (void * record_qual_type,
|
||||
|
@ -201,6 +202,14 @@ public:
|
|||
bool
|
||||
SetObjCSuperClass (void *class_clang_type,
|
||||
void *superclass_clang_type);
|
||||
|
||||
static bool
|
||||
ObjCTypeHasIVars (void *class_clang_type, bool check_superclass);
|
||||
|
||||
static bool
|
||||
ObjCDeclHasIVars (clang::ObjCInterfaceDecl *class_interface_decl,
|
||||
bool check_superclass);
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Aggregate Types
|
||||
|
|
|
@ -66,9 +66,9 @@ public:
|
|||
/// A language enumeration type that describes the main language
|
||||
/// of this compile unit.
|
||||
///
|
||||
/// @see Language::Type
|
||||
/// @see lldb::LanguageType
|
||||
//------------------------------------------------------------------
|
||||
CompileUnit(Module *module, void *user_data, const char *pathname, lldb::user_id_t uid, Language::Type language);
|
||||
CompileUnit(Module *module, void *user_data, const char *pathname, lldb::user_id_t uid, lldb::LanguageType language);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Construct with a module, file spec, UID and language.
|
||||
|
@ -98,9 +98,9 @@ public:
|
|||
/// A language enumeration type that describes the main language
|
||||
/// of this compile unit.
|
||||
///
|
||||
/// @see Language::Type
|
||||
/// @see lldb::LanguageType
|
||||
//------------------------------------------------------------------
|
||||
CompileUnit(Module *module, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, Language::Type language);
|
||||
CompileUnit(Module *module, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, lldb::LanguageType language);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Destructor
|
||||
|
|
|
@ -225,7 +225,7 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
// Member variables
|
||||
//------------------------------------------------------------------
|
||||
lldb::TargetSP target_sp; ///< The Target for a given query
|
||||
lldb::TargetSP target_sp; ///< The Target for a given query
|
||||
lldb::ModuleSP module_sp; ///< The Module for a given query
|
||||
CompileUnit * comp_unit; ///< The CompileUnit for a given query
|
||||
Function * function; ///< The Function for a given query
|
||||
|
|
|
@ -428,6 +428,38 @@ typedef enum BreakpointEventType
|
|||
} BreakpointEventType;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Programming language type.
|
||||
///
|
||||
/// These enumerations use the same language enumerations as the DWARF
|
||||
/// specification for ease of use and consistency.
|
||||
//----------------------------------------------------------------------
|
||||
typedef enum LanguageType
|
||||
{
|
||||
eLanguageTypeUnknown = 0x0000, ///< Unknown or invalid language value.
|
||||
eLanguageTypeC89 = 0x0001, ///< ISO C:1989.
|
||||
eLanguageTypeC = 0x0002, ///< Non-standardized C, such as K&R.
|
||||
eLanguageTypeAda83 = 0x0003, ///< ISO Ada:1983.
|
||||
eLanguageTypeC_plus_plus = 0x0004, ///< ISO C++:1998.
|
||||
eLanguageTypeCobol74 = 0x0005, ///< ISO Cobol:1974.
|
||||
eLanguageTypeCobol85 = 0x0006, ///< ISO Cobol:1985.
|
||||
eLanguageTypeFortran77 = 0x0007, ///< ISO Fortran 77.
|
||||
eLanguageTypeFortran90 = 0x0008, ///< ISO Fortran 90.
|
||||
eLanguageTypePascal83 = 0x0009, ///< ISO Pascal:1983.
|
||||
eLanguageTypeModula2 = 0x000a, ///< ISO Modula-2:1996.
|
||||
eLanguageTypeJava = 0x000b, ///< Java.
|
||||
eLanguageTypeC99 = 0x000c, ///< ISO C:1999.
|
||||
eLanguageTypeAda95 = 0x000d, ///< ISO Ada:1995.
|
||||
eLanguageTypeFortran95 = 0x000e, ///< ISO Fortran 95.
|
||||
eLanguageTypePLI = 0x000f, ///< ANSI PL/I:1976.
|
||||
eLanguageTypeObjC = 0x0010, ///< Objective-C.
|
||||
eLanguageTypeObjC_plus_plus = 0x0011, ///< Objective-C++.
|
||||
eLanguageTypeUPC = 0x0012, ///< Unified Parallel C.
|
||||
eLanguageTypeD = 0x0013, ///< D.
|
||||
eLanguageTypePython = 0x0014 ///< Python.
|
||||
} LanguageType;
|
||||
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
|
||||
|
|
|
@ -146,21 +146,21 @@ public:
|
|||
"'alias' allows the user to create a short-cut or abbreviation for long \n\
|
||||
commands, multi-word commands, and commands that take particular options. \n\
|
||||
Below are some simple examples of how one might use the 'alias' command: \n\
|
||||
\n 'alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
|
||||
\n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
|
||||
// command. \n\
|
||||
'alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
|
||||
'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
|
||||
// command. Since breakpoint commands are two-word \n\
|
||||
// commands, the user will still need to enter the \n\
|
||||
// second word after 'bp', e.g. 'bp enable' or \n\
|
||||
// 'bp delete'. \n\
|
||||
'alias bpi breakpoint list' // Creates the abbreviation 'bpi' for the \n\
|
||||
'command alias bpi breakpoint list' // Creates the abbreviation 'bpi' for the \n\
|
||||
// two-word command 'breakpoint list'. \n\
|
||||
\nAn alias can include some options for the command, with the values either \n\
|
||||
filled in at the time the alias is created, or specified as positional \n\
|
||||
arguments, to be filled in when the alias is invoked. The following example \n\
|
||||
shows how to create aliases with options: \n\
|
||||
\n\
|
||||
'alias bfl breakpoint set -f %1 -l %2' \n\
|
||||
'command alias bfl breakpoint set -f %1 -l %2' \n\
|
||||
\nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
|
||||
options already part of the alias. So if the user wants to set a breakpoint \n\
|
||||
by file and line without explicitly having to use the -f and -l options, the \n\
|
||||
|
|
|
@ -51,7 +51,7 @@ g_languages[] =
|
|||
static const size_t
|
||||
g_num_languages = sizeof(g_languages)/sizeof(LanguageStrings);
|
||||
|
||||
Language::Language(Language::Type language) :
|
||||
Language::Language(LanguageType language) :
|
||||
m_language (language)
|
||||
{
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ Language::~Language()
|
|||
{
|
||||
}
|
||||
|
||||
Language::Type
|
||||
LanguageType
|
||||
Language::GetLanguage() const
|
||||
{
|
||||
return m_language;
|
||||
|
@ -69,11 +69,11 @@ Language::GetLanguage() const
|
|||
void
|
||||
Language::Clear ()
|
||||
{
|
||||
m_language = Unknown;
|
||||
m_language = eLanguageTypeUnknown;
|
||||
}
|
||||
|
||||
void
|
||||
Language::SetLanguage(Language::Type language)
|
||||
Language::SetLanguage(LanguageType language)
|
||||
{
|
||||
m_language = language;
|
||||
}
|
||||
|
@ -95,13 +95,13 @@ Language::SetLanguageFromCString(const char *language_cstr)
|
|||
|
||||
if (::strcasecmp (language_cstr, name) == 0)
|
||||
{
|
||||
m_language = (Language::Type)i;
|
||||
m_language = (LanguageType)i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_language = Unknown;
|
||||
m_language = eLanguageTypeUnknown;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -644,12 +644,12 @@ SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit
|
|||
{
|
||||
const char * cu_die_name = cu_die->GetName(this, cu);
|
||||
const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
|
||||
Language::Type language = (Language::Type)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0);
|
||||
LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0);
|
||||
if (cu_die_name)
|
||||
{
|
||||
if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
|
||||
{
|
||||
compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_die_name, cu->GetOffset(), language));
|
||||
compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_die_name, cu->GetOffset(), class_language));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -658,7 +658,7 @@ SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit
|
|||
fullpath += '/';
|
||||
fullpath += cu_die_name;
|
||||
|
||||
compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, fullpath.c_str(), cu->GetOffset(), language));
|
||||
compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, fullpath.c_str(), cu->GetOffset(), class_language));
|
||||
}
|
||||
|
||||
if (compile_unit_sp.get())
|
||||
|
@ -1211,6 +1211,8 @@ SymbolFileDWARF::ParseChildMembers
|
|||
TypeSP& type_sp,
|
||||
const DWARFCompileUnit* dwarf_cu,
|
||||
const DWARFDebugInfoEntry *parent_die,
|
||||
void *class_clang_type,
|
||||
const LanguageType class_language,
|
||||
std::vector<clang::CXXBaseSpecifier *>& base_classes,
|
||||
std::vector<int>& member_accessibilities,
|
||||
ClangASTContext::AccessType& default_accessibility,
|
||||
|
@ -1376,8 +1378,16 @@ SymbolFileDWARF::ParseChildMembers
|
|||
|
||||
Type *base_class_dctype = ResolveTypeUID(encoding_uid);
|
||||
assert(base_class_dctype);
|
||||
base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class));
|
||||
assert(base_classes.back());
|
||||
|
||||
if (class_language == eLanguageTypeObjC)
|
||||
{
|
||||
type_list->GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_dctype->GetOpaqueClangQualType());
|
||||
}
|
||||
else
|
||||
{
|
||||
base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class));
|
||||
assert(base_classes.back());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2707,6 +2717,7 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
|
|||
const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
|
||||
|
||||
size_t byte_size = 0;
|
||||
LanguageType class_language = eLanguageTypeUnknown;
|
||||
//bool struct_is_class = false;
|
||||
Declaration decl;
|
||||
const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
|
||||
|
@ -2721,16 +2732,39 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
|
|||
{
|
||||
switch (attr)
|
||||
{
|
||||
case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
|
||||
case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
|
||||
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
|
||||
case DW_AT_decl_file:
|
||||
decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
|
||||
break;
|
||||
|
||||
case DW_AT_decl_line:
|
||||
decl.SetLine(form_value.Unsigned());
|
||||
break;
|
||||
|
||||
case DW_AT_decl_column:
|
||||
decl.SetColumn(form_value.Unsigned());
|
||||
break;
|
||||
|
||||
case DW_AT_name:
|
||||
type_name_cstr = form_value.AsCString(&get_debug_str_data());
|
||||
type_name_dbstr.SetCString(type_name_cstr);
|
||||
break;
|
||||
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
|
||||
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; break;
|
||||
case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
|
||||
|
||||
case DW_AT_byte_size:
|
||||
byte_size = form_value.Unsigned();
|
||||
break;
|
||||
|
||||
case DW_AT_accessibility:
|
||||
accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
|
||||
break;
|
||||
|
||||
case DW_AT_declaration:
|
||||
is_forward_declaration = form_value.Unsigned() != 0;
|
||||
break;
|
||||
|
||||
case DW_AT_APPLE_runtime_class:
|
||||
class_language = (LanguageType)form_value.Signed();
|
||||
break;
|
||||
|
||||
case DW_AT_allocated:
|
||||
case DW_AT_associated:
|
||||
case DW_AT_data_location:
|
||||
|
@ -2764,7 +2798,7 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
|
|||
}
|
||||
|
||||
assert (tag_decl_kind != -1);
|
||||
clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die));
|
||||
clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die), class_language);
|
||||
|
||||
m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
|
||||
type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
|
||||
|
@ -2781,11 +2815,24 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
|
|||
std::vector<clang::CXXBaseSpecifier *> base_classes;
|
||||
std::vector<int> member_accessibilities;
|
||||
bool is_a_class = false;
|
||||
ParseChildMembers(sc, type_sp, dwarf_cu, die, base_classes, member_accessibilities, default_accessibility, is_a_class);
|
||||
ParseChildMembers (sc,
|
||||
type_sp,
|
||||
dwarf_cu,
|
||||
die,
|
||||
clang_type,
|
||||
class_language,
|
||||
base_classes,
|
||||
member_accessibilities,
|
||||
default_accessibility,
|
||||
is_a_class);
|
||||
|
||||
// If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
|
||||
// need to tell the clang type it is actually a class.
|
||||
if (is_a_class && tag_decl_kind != clang::TTK_Class)
|
||||
type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
|
||||
if (class_language != eLanguageTypeObjC)
|
||||
{
|
||||
if (is_a_class && tag_decl_kind != clang::TTK_Class)
|
||||
type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
|
||||
}
|
||||
|
||||
// Since DW_TAG_structure_type gets used for both classes
|
||||
// and structures, we may need to set any DW_TAG_member
|
||||
|
|
|
@ -249,6 +249,8 @@ protected:
|
|||
lldb::TypeSP& type_sp,
|
||||
const DWARFCompileUnit* dwarf_cu,
|
||||
const DWARFDebugInfoEntry *die,
|
||||
void *class_clang_type,
|
||||
const lldb::LanguageType class_language,
|
||||
std::vector<clang::CXXBaseSpecifier *>& base_classes,
|
||||
std::vector<int>& member_accessibilities,
|
||||
lldb_private::ClangASTContext::AccessType &default_accessibility,
|
||||
|
|
|
@ -495,7 +495,7 @@ SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
|
|||
NULL,
|
||||
so_symbol->GetMangled().GetName().AsCString(),
|
||||
cu_idx,
|
||||
Language::Unknown));
|
||||
eLanguageTypeUnknown));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,14 +140,14 @@ SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
|
|||
{
|
||||
const FileSpec &obj_file_spec = m_obj_file->GetFileSpec();
|
||||
if (obj_file_spec)
|
||||
cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, Language::Unknown));
|
||||
cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, eLanguageTypeUnknown));
|
||||
|
||||
}
|
||||
else if (idx < m_source_indexes.size())
|
||||
{
|
||||
const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
|
||||
if (cu_symbol)
|
||||
cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, Language::Unknown));
|
||||
cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown));
|
||||
}
|
||||
return cu_sp;
|
||||
}
|
||||
|
|
|
@ -753,7 +753,7 @@ ClangASTContext::AddVolatileModifier (void *clang_type)
|
|||
#pragma mark Structure, Unions, Classes
|
||||
|
||||
void *
|
||||
ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx)
|
||||
ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, lldb::LanguageType language)
|
||||
{
|
||||
ASTContext *ast_context = getASTContext();
|
||||
assert (ast_context != NULL);
|
||||
|
@ -761,6 +761,14 @@ ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl
|
|||
if (decl_ctx == NULL)
|
||||
decl_ctx = ast_context->getTranslationUnitDecl();
|
||||
|
||||
|
||||
if (language == lldb::eLanguageTypeObjC)
|
||||
{
|
||||
bool isForwardDecl = false;
|
||||
bool isInternal = false;
|
||||
return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal);
|
||||
}
|
||||
|
||||
// NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
|
||||
// we will need to update this code. I was told to currently always use
|
||||
// the CXXRecordDecl class since we often don't know from debug information
|
||||
|
@ -832,6 +840,20 @@ ClangASTContext::AddFieldToRecordType
|
|||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
|
||||
if (objc_class_type)
|
||||
{
|
||||
bool isSynthesized = false;
|
||||
ClangASTContext::AddObjCClassIVar (record_clang_type,
|
||||
name,
|
||||
field_type,
|
||||
access,
|
||||
bitfield_bit_size,
|
||||
isSynthesized);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -998,8 +1020,8 @@ ClangASTContext::CreateObjCClass
|
|||
SourceLocation(),
|
||||
isForwardDecl,
|
||||
isInternal);
|
||||
|
||||
return QualType (decl->getTypeForDecl(), 0).getAsOpaquePtr();
|
||||
|
||||
return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1071,27 +1093,61 @@ ClangASTContext::AddObjCClassIVar
|
|||
bit_width = new (*ast_context)IntegerLiteral (bitfield_bit_size_apint, ast_context->IntTy, SourceLocation());
|
||||
}
|
||||
|
||||
//ObjCIvarDecl *field =
|
||||
ObjCIvarDecl::Create (*ast_context,
|
||||
class_interface_decl,
|
||||
SourceLocation(),
|
||||
&identifier_table->get(name), // Identifier
|
||||
QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
|
||||
NULL, // TypeSourceInfo *
|
||||
ConvertAccessTypeToObjCIvarAccessControl (access),
|
||||
bit_width,
|
||||
isSynthesized);
|
||||
// TODO: Do I need to do an addDecl? I am thinking I don't since
|
||||
// I passed the "class_interface_decl" into "ObjCIvarDecl::Create"
|
||||
// above. Verify this. Also verify it is ok to pass NULL TypeSourceInfo
|
||||
// above.
|
||||
return true;
|
||||
ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context,
|
||||
class_interface_decl,
|
||||
SourceLocation(),
|
||||
&identifier_table->get(name), // Identifier
|
||||
QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
|
||||
NULL, // TypeSourceInfo *
|
||||
ConvertAccessTypeToObjCIvarAccessControl (access),
|
||||
bit_width,
|
||||
isSynthesized);
|
||||
|
||||
if (field)
|
||||
{
|
||||
class_interface_decl->addDecl(field);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ClangASTContext::ObjCTypeHasIVars (void *class_opaque_type, bool check_superclass)
|
||||
{
|
||||
QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
|
||||
|
||||
clang::Type *class_type = class_qual_type.getTypePtr();
|
||||
if (class_type)
|
||||
{
|
||||
ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
|
||||
|
||||
if (objc_class_type)
|
||||
return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
|
||||
{
|
||||
while (class_interface_decl)
|
||||
{
|
||||
if (class_interface_decl->ivar_size() > 0)
|
||||
return true;
|
||||
|
||||
if (check_superclass)
|
||||
class_interface_decl = class_interface_decl->getSuperClass();
|
||||
else
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Aggregate Types
|
||||
|
||||
bool
|
||||
|
@ -1113,6 +1169,9 @@ ClangASTContext::IsAggregateType (void *clang_type)
|
|||
case clang::Type::ExtVector:
|
||||
case clang::Type::Vector:
|
||||
case clang::Type::Record:
|
||||
case clang::Type::ObjCObject:
|
||||
case clang::Type::ObjCInterface:
|
||||
case clang::Type::ObjCObjectPointer:
|
||||
return true;
|
||||
|
||||
case clang::Type::Typedef:
|
||||
|
@ -1133,7 +1192,8 @@ ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_cla
|
|||
|
||||
uint32_t num_children = 0;
|
||||
QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type));
|
||||
switch (qual_type->getTypeClass())
|
||||
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
|
||||
switch (type_class)
|
||||
{
|
||||
case clang::Type::Record:
|
||||
{
|
||||
|
@ -1176,6 +1236,40 @@ ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_cla
|
|||
}
|
||||
break;
|
||||
|
||||
case clang::Type::ObjCObject:
|
||||
case clang::Type::ObjCInterface:
|
||||
{
|
||||
ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
|
||||
assert (objc_class_type);
|
||||
if (objc_class_type)
|
||||
{
|
||||
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
|
||||
|
||||
if (class_interface_decl)
|
||||
{
|
||||
|
||||
ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
|
||||
if (superclass_interface_decl)
|
||||
{
|
||||
if (omit_empty_base_classes)
|
||||
{
|
||||
if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
|
||||
++num_children;
|
||||
}
|
||||
else
|
||||
++num_children;
|
||||
}
|
||||
|
||||
num_children += class_interface_decl->ivar_size();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case clang::Type::ObjCObjectPointer:
|
||||
return ClangASTContext::GetNumChildren (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
|
||||
omit_empty_base_classes);
|
||||
|
||||
case clang::Type::ConstantArray:
|
||||
num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
|
||||
break;
|
||||
|
@ -1184,7 +1278,8 @@ ClangASTContext::GetNumChildren (void *clang_qual_type, bool omit_empty_base_cla
|
|||
{
|
||||
PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
|
||||
QualType pointee_type = pointer_type->getPointeeType();
|
||||
uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), omit_empty_base_classes);
|
||||
uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(),
|
||||
omit_empty_base_classes);
|
||||
// If this type points to a simple type, then it has 1 child
|
||||
if (num_pointee_children == 0)
|
||||
num_children = 1;
|
||||
|
@ -1349,6 +1444,100 @@ ClangASTContext::GetChildClangTypeAtIndex
|
|||
}
|
||||
break;
|
||||
|
||||
case clang::Type::ObjCObject:
|
||||
case clang::Type::ObjCInterface:
|
||||
{
|
||||
ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
|
||||
assert (objc_class_type);
|
||||
if (objc_class_type)
|
||||
{
|
||||
uint32_t child_idx = 0;
|
||||
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
|
||||
|
||||
if (class_interface_decl)
|
||||
{
|
||||
|
||||
const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl);
|
||||
ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
|
||||
if (superclass_interface_decl)
|
||||
{
|
||||
if (omit_empty_base_classes)
|
||||
{
|
||||
if (ClangASTContext::GetNumChildren(superclass_interface_decl, omit_empty_base_classes) > 0)
|
||||
{
|
||||
if (idx == 0)
|
||||
{
|
||||
QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl));
|
||||
|
||||
|
||||
child_name.assign(superclass_interface_decl->getNameAsString().c_str());
|
||||
|
||||
std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
|
||||
|
||||
child_byte_size = ivar_type_info.first / 8;
|
||||
|
||||
// Figure out the field offset within the current struct/union/class type
|
||||
bit_offset = interface_layout.getFieldOffset (child_idx);
|
||||
child_byte_offset = bit_offset / 8;
|
||||
|
||||
return ivar_qual_type.getAsOpaquePtr();
|
||||
}
|
||||
|
||||
++child_idx;
|
||||
}
|
||||
}
|
||||
else
|
||||
++child_idx;
|
||||
}
|
||||
|
||||
if (idx < (child_idx + class_interface_decl->ivar_size()))
|
||||
{
|
||||
ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
|
||||
|
||||
for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
|
||||
{
|
||||
if (child_idx == idx)
|
||||
{
|
||||
const ObjCIvarDecl* ivar_decl = *ivar_pos;
|
||||
|
||||
QualType ivar_qual_type(ivar_decl->getType());
|
||||
|
||||
child_name.assign(ivar_decl->getNameAsString().c_str());
|
||||
|
||||
std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr());
|
||||
|
||||
child_byte_size = ivar_type_info.first / 8;
|
||||
|
||||
// Figure out the field offset within the current struct/union/class type
|
||||
bit_offset = interface_layout.getFieldOffset (child_idx);
|
||||
child_byte_offset = bit_offset / 8;
|
||||
|
||||
return ivar_qual_type.getAsOpaquePtr();
|
||||
}
|
||||
++child_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case clang::Type::ObjCObjectPointer:
|
||||
{
|
||||
return GetChildClangTypeAtIndex (ast_context,
|
||||
parent_name,
|
||||
cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
|
||||
idx,
|
||||
transparent_pointers,
|
||||
omit_empty_base_classes,
|
||||
child_name,
|
||||
child_byte_size,
|
||||
child_byte_offset,
|
||||
child_bitfield_bit_size,
|
||||
child_bitfield_bit_offset);
|
||||
}
|
||||
break;
|
||||
|
||||
case clang::Type::ConstantArray:
|
||||
{
|
||||
const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
|
||||
|
@ -1707,6 +1896,76 @@ ClangASTContext::GetIndexOfChildMemberWithName
|
|||
}
|
||||
break;
|
||||
|
||||
case clang::Type::ObjCObject:
|
||||
case clang::Type::ObjCInterface:
|
||||
{
|
||||
StringRef name_sref(name);
|
||||
ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
|
||||
assert (objc_class_type);
|
||||
if (objc_class_type)
|
||||
{
|
||||
uint32_t child_idx = 0;
|
||||
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
|
||||
|
||||
if (class_interface_decl)
|
||||
{
|
||||
ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
|
||||
ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
|
||||
|
||||
for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
|
||||
{
|
||||
const ObjCIvarDecl* ivar_decl = *ivar_pos;
|
||||
|
||||
if (ivar_decl->getName().equals (name_sref))
|
||||
{
|
||||
if ((!omit_empty_base_classes && superclass_interface_decl) ||
|
||||
( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
|
||||
++child_idx;
|
||||
|
||||
child_indexes.push_back (child_idx);
|
||||
return child_indexes.size();
|
||||
}
|
||||
}
|
||||
|
||||
if (superclass_interface_decl)
|
||||
{
|
||||
// The super class index is always zero for ObjC classes,
|
||||
// so we push it onto the child indexes in case we find
|
||||
// an ivar in our superclass...
|
||||
child_indexes.push_back (0);
|
||||
|
||||
if (GetIndexOfChildMemberWithName (ast_context,
|
||||
ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
|
||||
name,
|
||||
omit_empty_base_classes,
|
||||
child_indexes))
|
||||
{
|
||||
// We did find an ivar in a superclass so just
|
||||
// return the results!
|
||||
return child_indexes.size();
|
||||
}
|
||||
|
||||
// We didn't find an ivar matching "name" in our
|
||||
// superclass, pop the superclass zero index that
|
||||
// we pushed on above.
|
||||
child_indexes.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case clang::Type::ObjCObjectPointer:
|
||||
{
|
||||
return GetIndexOfChildMemberWithName (ast_context,
|
||||
cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
|
||||
name,
|
||||
omit_empty_base_classes,
|
||||
child_indexes);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case clang::Type::ConstantArray:
|
||||
{
|
||||
// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
|
||||
|
@ -1824,7 +2083,10 @@ ClangASTContext::GetIndexOfChildWithName
|
|||
if (clang_type && name && name[0])
|
||||
{
|
||||
QualType qual_type(QualType::getFromOpaquePtr(clang_type));
|
||||
switch (qual_type->getTypeClass())
|
||||
|
||||
clang::Type::TypeClass qual_type_class = qual_type->getTypeClass();
|
||||
|
||||
switch (qual_type_class)
|
||||
{
|
||||
case clang::Type::Record:
|
||||
{
|
||||
|
@ -1868,6 +2130,55 @@ ClangASTContext::GetIndexOfChildWithName
|
|||
}
|
||||
break;
|
||||
|
||||
case clang::Type::ObjCObject:
|
||||
case clang::Type::ObjCInterface:
|
||||
{
|
||||
StringRef name_sref(name);
|
||||
ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
|
||||
assert (objc_class_type);
|
||||
if (objc_class_type)
|
||||
{
|
||||
uint32_t child_idx = 0;
|
||||
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
|
||||
|
||||
if (class_interface_decl)
|
||||
{
|
||||
ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
|
||||
ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
|
||||
|
||||
for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
|
||||
{
|
||||
const ObjCIvarDecl* ivar_decl = *ivar_pos;
|
||||
|
||||
if (ivar_decl->getName().equals (name_sref))
|
||||
{
|
||||
if ((!omit_empty_base_classes && superclass_interface_decl) ||
|
||||
( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
|
||||
++child_idx;
|
||||
|
||||
return child_idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (superclass_interface_decl)
|
||||
{
|
||||
if (superclass_interface_decl->getName().equals (name_sref))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case clang::Type::ObjCObjectPointer:
|
||||
{
|
||||
return GetIndexOfChildWithName (ast_context,
|
||||
cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
|
||||
name,
|
||||
omit_empty_base_classes);
|
||||
}
|
||||
break;
|
||||
|
||||
case clang::Type::ConstantArray:
|
||||
{
|
||||
// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
|
||||
|
@ -2003,34 +2314,32 @@ ClangASTContext::GetDeclContextForType (void *clang_type)
|
|||
QualType qual_type(QualType::getFromOpaquePtr(clang_type));
|
||||
switch (qual_type->getTypeClass())
|
||||
{
|
||||
case clang::Type::FunctionNoProto: break;
|
||||
case clang::Type::FunctionProto: break;
|
||||
case clang::Type::IncompleteArray: break;
|
||||
case clang::Type::VariableArray: break;
|
||||
case clang::Type::ConstantArray: break;
|
||||
case clang::Type::ExtVector: break;
|
||||
case clang::Type::Vector: break;
|
||||
case clang::Type::Builtin: break;
|
||||
case clang::Type::ObjCObjectPointer: break;
|
||||
case clang::Type::BlockPointer: break;
|
||||
case clang::Type::Pointer: break;
|
||||
case clang::Type::LValueReference: break;
|
||||
case clang::Type::RValueReference: break;
|
||||
case clang::Type::MemberPointer: break;
|
||||
case clang::Type::Complex: break;
|
||||
case clang::Type::ObjCInterface: break;
|
||||
case clang::Type::Record:
|
||||
return cast<RecordType>(qual_type)->getDecl();
|
||||
case clang::Type::Enum:
|
||||
return cast<EnumType>(qual_type)->getDecl();
|
||||
case clang::Type::Typedef:
|
||||
return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
|
||||
case clang::Type::FunctionNoProto: break;
|
||||
case clang::Type::FunctionProto: break;
|
||||
case clang::Type::IncompleteArray: break;
|
||||
case clang::Type::VariableArray: break;
|
||||
case clang::Type::ConstantArray: break;
|
||||
case clang::Type::ExtVector: break;
|
||||
case clang::Type::Vector: break;
|
||||
case clang::Type::Builtin: break;
|
||||
case clang::Type::BlockPointer: break;
|
||||
case clang::Type::Pointer: break;
|
||||
case clang::Type::LValueReference: break;
|
||||
case clang::Type::RValueReference: break;
|
||||
case clang::Type::MemberPointer: break;
|
||||
case clang::Type::Complex: break;
|
||||
case clang::Type::ObjCObject: break;
|
||||
case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
|
||||
case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
|
||||
case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl();
|
||||
case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl();
|
||||
case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
|
||||
|
||||
case clang::Type::TypeOfExpr: break;
|
||||
case clang::Type::TypeOf: break;
|
||||
case clang::Type::Decltype: break;
|
||||
//case clang::Type::QualifiedName: break;
|
||||
case clang::Type::TemplateSpecialization: break;
|
||||
case clang::Type::TypeOfExpr: break;
|
||||
case clang::Type::TypeOf: break;
|
||||
case clang::Type::Decltype: break;
|
||||
//case clang::Type::QualifiedName: break;
|
||||
case clang::Type::TemplateSpecialization: break;
|
||||
}
|
||||
// No DeclContext in this type...
|
||||
return NULL;
|
||||
|
|
|
@ -614,7 +614,8 @@ ClangASTType::DumpTypeValue
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (qual_type->getTypeClass())
|
||||
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
|
||||
switch (type_class)
|
||||
{
|
||||
case clang::Type::Enum:
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
CompileUnit::CompileUnit (Module *module, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, Language::Type language) :
|
||||
CompileUnit::CompileUnit (Module *module, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, lldb::LanguageType language) :
|
||||
ModuleChild(module),
|
||||
FileSpec (pathname),
|
||||
UserID(cu_sym_id),
|
||||
|
@ -31,7 +31,7 @@ CompileUnit::CompileUnit (Module *module, void *user_data, const char *pathname,
|
|||
assert(module != NULL);
|
||||
}
|
||||
|
||||
CompileUnit::CompileUnit (Module *module, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, Language::Type language) :
|
||||
CompileUnit::CompileUnit (Module *module, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, lldb::LanguageType language) :
|
||||
ModuleChild(module),
|
||||
FileSpec (fspec),
|
||||
UserID(cu_sym_id),
|
||||
|
|
|
@ -219,7 +219,7 @@ lldb_private::Type::Dump (Stream *s, bool show_context)
|
|||
const clang::TypedefDecl *typedef_decl = typedef_type->getDecl();
|
||||
std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString());
|
||||
if (!clang_typedef_name.empty())
|
||||
*s << " (" << clang_typedef_name.c_str() << ')';
|
||||
*s << '(' << clang_typedef_name.c_str() << ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -229,7 +229,7 @@ lldb_private::Type::Dump (Stream *s, bool show_context)
|
|||
{
|
||||
std::string clang_type_name(qual_type.getAsString());
|
||||
if (!clang_type_name.empty())
|
||||
*s << " (" << clang_type_name.c_str() << ')';
|
||||
*s << '(' << clang_type_name.c_str() << ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue