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:
Greg Clayton 2010-07-28 02:04:09 +00:00
parent e1270c64e3
commit 9e40956aea
15 changed files with 494 additions and 126 deletions

View File

@ -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.
};
//--------------------------------------------------------------

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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\

View File

@ -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;
}

View File

@ -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

View File

@ -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,

View File

@ -495,7 +495,7 @@ SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
NULL,
so_symbol->GetMangled().GetName().AsCString(),
cu_idx,
Language::Unknown));
eLanguageTypeUnknown));
}
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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:
{

View File

@ -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),

View File

@ -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() << ')';
}
}
}