Changeset View
Changeset View
Standalone View
Standalone View
source/Symbol/ClangASTContext.cpp
Context not available. | |||||
#include "llvm/Support/Signals.h" | #include "llvm/Support/Signals.h" | ||||
#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h" | |||||
#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h" | |||||
#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h" | |||||
#include "lldb/Core/ArchSpec.h" | #include "lldb/Core/ArchSpec.h" | ||||
#include "lldb/Core/Flags.h" | #include "lldb/Core/Flags.h" | ||||
#include "lldb/Core/Log.h" | #include "lldb/Core/Log.h" | ||||
Context not available. | |||||
#include "lldb/Core/StreamFile.h" | #include "lldb/Core/StreamFile.h" | ||||
#include "lldb/Core/ThreadSafeDenseMap.h" | #include "lldb/Core/ThreadSafeDenseMap.h" | ||||
#include "lldb/Core/UniqueCStringMap.h" | #include "lldb/Core/UniqueCStringMap.h" | ||||
#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h" | |||||
#include "Plugins/ExpressionParser/Clang/ClangFunctionCaller.h" | |||||
#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h" | |||||
#include "lldb/Symbol/ClangASTContext.h" | #include "lldb/Symbol/ClangASTContext.h" | ||||
#include "lldb/Symbol/ClangASTImporter.h" | |||||
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" | #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" | ||||
#include "lldb/Symbol/ClangExternalASTSourceCommon.h" | #include "lldb/Symbol/ClangExternalASTSourceCommon.h" | ||||
#include "lldb/Symbol/ClangUtil.h" | |||||
#include "lldb/Symbol/ObjectFile.h" | #include "lldb/Symbol/ObjectFile.h" | ||||
#include "lldb/Symbol/SymbolFile.h" | #include "lldb/Symbol/SymbolFile.h" | ||||
#include "lldb/Symbol/VerifyDecl.h" | #include "lldb/Symbol/VerifyDecl.h" | ||||
Context not available. | |||||
if (::strstr(type_name, "complex")) | if (::strstr(type_name, "complex")) | ||||
{ | { | ||||
CompilerType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2); | CompilerType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2); | ||||
return CompilerType (ast, ast->getComplexType (GetQualType(complex_int_clang_type))); | return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_int_clang_type))); | ||||
} | } | ||||
} | } | ||||
break; | break; | ||||
Context not available. | |||||
else | else | ||||
{ | { | ||||
CompilerType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2); | CompilerType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2); | ||||
return CompilerType (ast, ast->getComplexType (GetQualType(complex_float_clang_type))); | return CompilerType(ast, ast->getComplexType(ClangUtil::GetQualType(complex_float_clang_type))); | ||||
} | } | ||||
break; | break; | ||||
Context not available. | |||||
if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType()) | if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType()) | ||||
return true; | return true; | ||||
QualType type1_qual = GetQualType(type1); | QualType type1_qual = ClangUtil::GetQualType(type1); | ||||
QualType type2_qual = GetQualType(type2); | QualType type2_qual = ClangUtil::GetQualType(type2); | ||||
if (ignore_qualifiers) | if (ignore_qualifiers) | ||||
{ | { | ||||
type1_qual = type1_qual.getUnqualifiedType(); | type1_qual = type1_qual.getUnqualifiedType(); | ||||
Context not available. | |||||
if (name && name[0]) | if (name && name[0]) | ||||
{ | { | ||||
func_decl = FunctionDecl::Create (*ast, | func_decl = FunctionDecl::Create( | ||||
decl_ctx, | *ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(&ast->Idents.get(name)), | ||||
SourceLocation(), | ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline, | ||||
SourceLocation(), | hasWrittenPrototype, isConstexprSpecified); | ||||
DeclarationName (&ast->Idents.get(name)), | |||||
GetQualType(function_clang_type), | |||||
nullptr, | |||||
(clang::StorageClass)storage, | |||||
is_inline, | |||||
hasWrittenPrototype, | |||||
isConstexprSpecified); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
func_decl = FunctionDecl::Create (*ast, | func_decl = | ||||
decl_ctx, | FunctionDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(), | ||||
SourceLocation(), | ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, | ||||
SourceLocation(), | is_inline, hasWrittenPrototype, isConstexprSpecified); | ||||
DeclarationName (), | |||||
GetQualType(function_clang_type), | |||||
nullptr, | |||||
(clang::StorageClass)storage, | |||||
is_inline, | |||||
hasWrittenPrototype, | |||||
isConstexprSpecified); | |||||
} | } | ||||
if (func_decl) | if (func_decl) | ||||
decl_ctx->addDecl (func_decl); | decl_ctx->addDecl (func_decl); | ||||
Context not available. | |||||
assert (ast != nullptr); | assert (ast != nullptr); | ||||
std::vector<QualType> qual_type_args; | std::vector<QualType> qual_type_args; | ||||
for (unsigned i=0; i<num_args; ++i) | for (unsigned i=0; i<num_args; ++i) | ||||
qual_type_args.push_back (GetQualType(args[i])); | qual_type_args.push_back(ClangUtil::GetQualType(args[i])); | ||||
// TODO: Detect calling convention in DWARF? | // TODO: Detect calling convention in DWARF? | ||||
FunctionProtoType::ExtProtoInfo proto_info; | FunctionProtoType::ExtProtoInfo proto_info; | ||||
Context not available. | |||||
proto_info.TypeQuals = type_quals; | proto_info.TypeQuals = type_quals; | ||||
proto_info.RefQualifier = RQ_None; | proto_info.RefQualifier = RQ_None; | ||||
return CompilerType (ast, ast->getFunctionType (GetQualType(result_type), | return CompilerType(ast, ast->getFunctionType(ClangUtil::GetQualType(result_type), qual_type_args, proto_info)); | ||||
qual_type_args, | |||||
proto_info)); | |||||
} | } | ||||
ParmVarDecl * | ParmVarDecl * | ||||
Context not available. | |||||
{ | { | ||||
ASTContext *ast = getASTContext(); | ASTContext *ast = getASTContext(); | ||||
assert (ast != nullptr); | assert (ast != nullptr); | ||||
return ParmVarDecl::Create(*ast, | return ParmVarDecl::Create(*ast, ast->getTranslationUnitDecl(), SourceLocation(), SourceLocation(), | ||||
ast->getTranslationUnitDecl(), | name && name[0] ? &ast->Idents.get(name) : nullptr, ClangUtil::GetQualType(param_type), | ||||
SourceLocation(), | nullptr, (clang::StorageClass)storage, nullptr); | ||||
SourceLocation(), | |||||
name && name[0] ? &ast->Idents.get(name) : nullptr, | |||||
GetQualType(param_type), | |||||
nullptr, | |||||
(clang::StorageClass)storage, | |||||
nullptr); | |||||
} | } | ||||
void | void | ||||
Context not available. | |||||
if (is_vector) | if (is_vector) | ||||
{ | { | ||||
return CompilerType (ast, ast->getExtVectorType(GetQualType(element_type), element_count)); | return CompilerType(ast, ast->getExtVectorType(ClangUtil::GetQualType(element_type), element_count)); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
Context not available. | |||||
llvm::APInt ap_element_count (64, element_count); | llvm::APInt ap_element_count (64, element_count); | ||||
if (element_count == 0) | if (element_count == 0) | ||||
{ | { | ||||
return CompilerType (ast, ast->getIncompleteArrayType (GetQualType(element_type), | return CompilerType(ast, ast->getIncompleteArrayType(ClangUtil::GetQualType(element_type), | ||||
clang::ArrayType::Normal, | clang::ArrayType::Normal, 0)); | ||||
0)); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
return CompilerType (ast, ast->getConstantArrayType (GetQualType(element_type), | return CompilerType(ast, ast->getConstantArrayType(ClangUtil::GetQualType(element_type), | ||||
ap_element_count, | ap_element_count, clang::ArrayType::Normal, 0)); | ||||
clang::ArrayType::Normal, | |||||
0)); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
Context not available. | |||||
if (enum_decl) | if (enum_decl) | ||||
{ | { | ||||
// TODO: check if we should be setting the promotion type too? | // TODO: check if we should be setting the promotion type too? | ||||
enum_decl->setIntegerType(GetQualType(integer_clang_type)); | enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type)); | ||||
enum_decl->setAccess(AS_public); // TODO respect what's in the debug info | enum_decl->setAccess(AS_public); // TODO respect what's in the debug info | ||||
return CompilerType (ast, ast->getTagDeclType(enum_decl)); | return CompilerType (ast, ast->getTagDeclType(enum_decl)); | ||||
Context not available. | |||||
clang::DeclContext * | clang::DeclContext * | ||||
ClangASTContext::GetDeclContextForType (const CompilerType& type) | ClangASTContext::GetDeclContextForType (const CompilerType& type) | ||||
{ | { | ||||
return GetDeclContextForType(GetQualType(type)); | return GetDeclContextForType(ClangUtil::GetQualType(type)); | ||||
} | } | ||||
clang::DeclContext * | clang::DeclContext * | ||||
Context not available. | |||||
{ | { | ||||
if (type) | if (type) | ||||
{ | { | ||||
clang::QualType qual_type (GetCanonicalQualType(type)); | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); | ||||
const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type); | const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type); | ||||
if (obj_pointer_type) | if (obj_pointer_type) | ||||
Context not available. | |||||
bool | bool | ||||
ClangASTContext::IsObjCObjectOrInterfaceType (const CompilerType& type) | ClangASTContext::IsObjCObjectOrInterfaceType (const CompilerType& type) | ||||
{ | { | ||||
if (IsClangType(type)) | if (ClangUtil::IsClangType(type)) | ||||
return GetCanonicalQualType(type)->isObjCObjectOrInterfaceType(); | return ClangUtil::GetCanonicalQualType(type)->isObjCObjectOrInterfaceType(); | ||||
return false; | return false; | ||||
} | } | ||||
Context not available. | |||||
{ | { | ||||
if (type) | if (type) | ||||
{ | { | ||||
clang::QualType qual_type (GetCanonicalQualType(type)); | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); | ||||
if (!qual_type.isNull()) | if (!qual_type.isNull()) | ||||
{ | { | ||||
clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); | clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); | ||||
Context not available. | |||||
{ | { | ||||
if (!type) | if (!type) | ||||
return false; | return false; | ||||
clang::QualType qual_type (GetCanonicalQualType(type)); | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); | ||||
if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr) | if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr) | ||||
return true; | return true; | ||||
return false; | return false; | ||||
Context not available. | |||||
if (!type) | if (!type) | ||||
return false; | return false; | ||||
clang::QualType qual_type (GetCanonicalQualType(type)); | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); | ||||
if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) | if (!qual_type.isNull() && qual_type->isObjCObjectPointerType()) | ||||
{ | { | ||||
Context not available. | |||||
{ | { | ||||
if (!type) | if (!type) | ||||
return false; | return false; | ||||
clang::QualType qual_type (GetCanonicalQualType(type)); | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); | ||||
const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); | const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); | ||||
if (object_type) | if (object_type) | ||||
{ | { | ||||
Context not available. | |||||
if (!ast) | if (!ast) | ||||
return CompilerType(); | return CompilerType(); | ||||
clang::ASTContext* clang_ast = ast->getASTContext(); | clang::ASTContext* clang_ast = ast->getASTContext(); | ||||
clang::QualType qual_type (GetQualType(type)); | clang::QualType qual_type(ClangUtil::GetQualType(type)); | ||||
clang::DeclContext *decl_ctx = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx); | clang::DeclContext *decl_ctx = ClangASTContext::DeclContextGetAsDeclContext(compiler_decl_ctx); | ||||
if (decl_ctx == nullptr) | if (decl_ctx == nullptr) | ||||
Context not available. | |||||
return CompilerType(); | return CompilerType(); | ||||
} | } | ||||
CompilerType | |||||
ClangASTContext::RemoveFastQualifiers (const CompilerType& type) | |||||
{ | |||||
if (IsClangType(type)) | |||||
{ | |||||
clang::QualType qual_type(GetQualType(type)); | |||||
qual_type.getQualifiers().removeFastQualifiers(); | |||||
return CompilerType (type.GetTypeSystem(), qual_type.getAsOpaquePtr()); | |||||
} | |||||
return type; | |||||
} | |||||
//---------------------------------------------------------------------- | //---------------------------------------------------------------------- | ||||
// Create related types using the current type's AST | // Create related types using the current type's AST | ||||
Context not available. | |||||
ClangASTContext::GetTypeForFormatters (void* type) | ClangASTContext::GetTypeForFormatters (void* type) | ||||
{ | { | ||||
if (type) | if (type) | ||||
return RemoveFastQualifiers(CompilerType(this, type)); | return ClangUtil::RemoveFastQualifiers(CompilerType(this, type)); | ||||
return CompilerType(); | return CompilerType(); | ||||
} | } | ||||
Context not available. | |||||
clang::EnumDecl * | clang::EnumDecl * | ||||
ClangASTContext::GetAsEnumDecl (const CompilerType& type) | ClangASTContext::GetAsEnumDecl (const CompilerType& type) | ||||
{ | { | ||||
const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type)); | const clang::EnumType *enutype = llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type)); | ||||
if (enutype) | if (enutype) | ||||
return enutype->getDecl(); | return enutype->getDecl(); | ||||
return NULL; | return NULL; | ||||
Context not available. | |||||
clang::RecordDecl * | clang::RecordDecl * | ||||
ClangASTContext::GetAsRecordDecl (const CompilerType& type) | ClangASTContext::GetAsRecordDecl (const CompilerType& type) | ||||
{ | { | ||||
const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(GetCanonicalQualType(type)); | const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(ClangUtil::GetCanonicalQualType(type)); | ||||
if (record_type) | if (record_type) | ||||
return record_type->getDecl(); | return record_type->getDecl(); | ||||
return nullptr; | return nullptr; | ||||
Context not available. | |||||
clang::TagDecl * | clang::TagDecl * | ||||
ClangASTContext::GetAsTagDecl (const CompilerType& type) | ClangASTContext::GetAsTagDecl (const CompilerType& type) | ||||
{ | { | ||||
clang::QualType qual_type = GetCanonicalQualType(type); | clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type); | ||||
if (qual_type.isNull()) | if (qual_type.isNull()) | ||||
return nullptr; | return nullptr; | ||||
else | else | ||||
Context not available. | |||||
clang::ObjCInterfaceDecl * | clang::ObjCInterfaceDecl * | ||||
ClangASTContext::GetAsObjCInterfaceDecl (const CompilerType& type) | ClangASTContext::GetAsObjCInterfaceDecl (const CompilerType& type) | ||||
{ | { | ||||
const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(GetCanonicalQualType(type)); | const clang::ObjCObjectType *objc_class_type = | ||||
llvm::dyn_cast<clang::ObjCObjectType>(ClangUtil::GetCanonicalQualType(type)); | |||||
if (objc_class_type) | if (objc_class_type) | ||||
return objc_class_type->getInterface(); | return objc_class_type->getInterface(); | ||||
return nullptr; | return nullptr; | ||||
Context not available. | |||||
clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type); | clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type); | ||||
if (record_decl) | if (record_decl) | ||||
{ | { | ||||
field = clang::FieldDecl::Create (*clang_ast, | field = clang::FieldDecl::Create(*clang_ast, record_decl, clang::SourceLocation(), clang::SourceLocation(), | ||||
record_decl, | name ? &clang_ast->Idents.get(name) : nullptr, // Identifier | ||||
clang::SourceLocation(), | ClangUtil::GetQualType(field_clang_type), // Field type | ||||
clang::SourceLocation(), | nullptr, // TInfo * | ||||
name ? &clang_ast->Idents.get(name) : nullptr, // Identifier | bit_width, // BitWidth | ||||
GetQualType(field_clang_type), // Field type | false, // Mutable | ||||
nullptr, // TInfo * | clang::ICIS_NoInit); // HasInit | ||||
bit_width, // BitWidth | |||||
false, // Mutable | |||||
clang::ICIS_NoInit); // HasInit | |||||
if (!name) | if (!name) | ||||
{ | { | ||||
// Determine whether this field corresponds to an anonymous | // Determine whether this field corresponds to an anonymous | ||||
Context not available. | |||||
const bool is_synthesized = false; | const bool is_synthesized = false; | ||||
field_clang_type.GetCompleteType(); | field_clang_type.GetCompleteType(); | ||||
field = clang::ObjCIvarDecl::Create (*clang_ast, | field = clang::ObjCIvarDecl::Create( | ||||
class_interface_decl, | *clang_ast, class_interface_decl, clang::SourceLocation(), clang::SourceLocation(), | ||||
clang::SourceLocation(), | name ? &clang_ast->Idents.get(name) : nullptr, // Identifier | ||||
clang::SourceLocation(), | ClangUtil::GetQualType(field_clang_type), // Field type | ||||
name ? &clang_ast->Idents.get(name) : nullptr, // Identifier | nullptr, // TypeSourceInfo * | ||||
GetQualType(field_clang_type), // Field type | ConvertAccessTypeToObjCIvarAccessControl(access), bit_width, is_synthesized); | ||||
nullptr, // TypeSourceInfo * | |||||
ConvertAccessTypeToObjCIvarAccessControl (access), | |||||
bit_width, | |||||
is_synthesized); | |||||
if (field) | if (field) | ||||
{ | { | ||||
class_interface_decl->addDecl(field); | class_interface_decl->addDecl(field); | ||||
Context not available. | |||||
clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type); | clang::RecordDecl *record_decl = ast->GetAsRecordDecl (type); | ||||
if (record_decl) | if (record_decl) | ||||
{ | { | ||||
var_decl = clang::VarDecl::Create (*ast->getASTContext(), // ASTContext & | var_decl = | ||||
record_decl, // DeclContext * | clang::VarDecl::Create(*ast->getASTContext(), // ASTContext & | ||||
clang::SourceLocation(), // clang::SourceLocation StartLoc | record_decl, // DeclContext * | ||||
clang::SourceLocation(), // clang::SourceLocation IdLoc | clang::SourceLocation(), // clang::SourceLocation StartLoc | ||||
name ? &ast->getASTContext()->Idents.get(name) : nullptr, // clang::IdentifierInfo * | clang::SourceLocation(), // clang::SourceLocation IdLoc | ||||
GetQualType(var_type), // Variable clang::QualType | name ? &ast->getASTContext()->Idents.get(name) : nullptr, // clang::IdentifierInfo * | ||||
nullptr, // TypeSourceInfo * | ClangUtil::GetQualType(var_type), // Variable clang::QualType | ||||
clang::SC_Static); // StorageClass | nullptr, // TypeSourceInfo * | ||||
clang::SC_Static); // StorageClass | |||||
if (var_decl) | if (var_decl) | ||||
{ | { | ||||
var_decl->setAccess(ClangASTContext::ConvertAccessTypeToAccessSpecifier (access)); | var_decl->setAccess(ClangASTContext::ConvertAccessTypeToAccessSpecifier (access)); | ||||
Context not available. | |||||
if (cxx_record_decl == nullptr) | if (cxx_record_decl == nullptr) | ||||
return nullptr; | return nullptr; | ||||
clang::QualType method_qual_type (GetQualType(method_clang_type)); | clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type)); | ||||
clang::CXXMethodDecl *cxx_method_decl = nullptr; | clang::CXXMethodDecl *cxx_method_decl = nullptr; | ||||
clang::DeclarationName decl_name (&getASTContext()->Idents.get(name)); | clang::DeclarationName decl_name (&getASTContext()->Idents.get(name)); | ||||
Context not available. | |||||
if (ivar_decl) | if (ivar_decl) | ||||
prop_type_source = clang_ast->getTrivialTypeSourceInfo (ivar_decl->getType()); | prop_type_source = clang_ast->getTrivialTypeSourceInfo (ivar_decl->getType()); | ||||
else | else | ||||
prop_type_source = clang_ast->getTrivialTypeSourceInfo (GetQualType(property_clang_type)); | prop_type_source = clang_ast->getTrivialTypeSourceInfo(ClangUtil::GetQualType(property_clang_type)); | ||||
clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create (*clang_ast, | clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create( | ||||
class_interface_decl, | *clang_ast, class_interface_decl, | ||||
clang::SourceLocation(), // Source Location | clang::SourceLocation(), // Source Location | ||||
&clang_ast->Idents.get(property_name), | &clang_ast->Idents.get(property_name), | ||||
clang::SourceLocation(), //Source Location for AT | clang::SourceLocation(), // Source Location for AT | ||||
clang::SourceLocation(), //Source location for ( | clang::SourceLocation(), // Source location for ( | ||||
ivar_decl ? ivar_decl->getType() : ClangASTContext::GetQualType(property_clang_type), | ivar_decl ? ivar_decl->getType() : ClangUtil::GetQualType(property_clang_type), prop_type_source); | ||||
prop_type_source); | |||||
if (property_decl) | if (property_decl) | ||||
{ | { | ||||
if (metadata) | if (metadata) | ||||
Context not available. | |||||
const bool isDefined = false; | const bool isDefined = false; | ||||
const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None; | const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None; | ||||
const bool HasRelatedResultType = false; | const bool HasRelatedResultType = false; | ||||
clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create (*clang_ast, | clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create( | ||||
clang::SourceLocation(), | *clang_ast, clang::SourceLocation(), clang::SourceLocation(), getter_sel, | ||||
clang::SourceLocation(), | ClangUtil::GetQualType(property_clang_type_to_access), nullptr, class_interface_decl, | ||||
getter_sel, | isInstance, isVariadic, isSynthesized, isImplicitlyDeclared, isDefined, impControl, | ||||
GetQualType(property_clang_type_to_access), | HasRelatedResultType); | ||||
nullptr, | |||||
class_interface_decl, | |||||
isInstance, | |||||
isVariadic, | |||||
isSynthesized, | |||||
isImplicitlyDeclared, | |||||
isDefined, | |||||
impControl, | |||||
HasRelatedResultType); | |||||
if (getter && metadata) | if (getter && metadata) | ||||
ClangASTContext::SetMetadata(clang_ast, getter, *metadata); | ClangASTContext::SetMetadata(clang_ast, getter, *metadata); | ||||
Context not available. | |||||
ClangASTContext::SetMetadata(clang_ast, setter, *metadata); | ClangASTContext::SetMetadata(clang_ast, setter, *metadata); | ||||
llvm::SmallVector<clang::ParmVarDecl *, 1> params; | llvm::SmallVector<clang::ParmVarDecl *, 1> params; | ||||
params.push_back (clang::ParmVarDecl::Create (*clang_ast, | params.push_back(clang::ParmVarDecl::Create( | ||||
setter, | *clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(), | ||||
clang::SourceLocation(), | nullptr, // anonymous | ||||
clang::SourceLocation(), | ClangUtil::GetQualType(property_clang_type_to_access), nullptr, clang::SC_Auto, nullptr)); | ||||
nullptr, // anonymous | |||||
GetQualType(property_clang_type_to_access), | |||||
nullptr, | |||||
clang::SC_Auto, | |||||
nullptr)); | |||||
if (setter) | if (setter) | ||||
{ | { | ||||
setter->setMethodParams(*clang_ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::SourceLocation>()); | setter->setMethodParams(*clang_ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::SourceLocation>()); | ||||
Context not available. | |||||
clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, | clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, | ||||
selector_idents.data()); | selector_idents.data()); | ||||
clang::QualType method_qual_type (GetQualType(method_clang_type)); | clang::QualType method_qual_type(ClangUtil::GetQualType(method_clang_type)); | ||||
// Populate the method decl with parameter decls | // Populate the method decl with parameter decls | ||||
const clang::Type *method_type(method_qual_type.getTypePtr()); | const clang::Type *method_type(method_qual_type.getTypePtr()); | ||||
Context not available. | |||||
if (num_args != num_selectors_with_args) | if (num_args != num_selectors_with_args) | ||||
return nullptr; // some debug information is corrupt. We are not going to deal with it. | return nullptr; // some debug information is corrupt. We are not going to deal with it. | ||||
clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create (*ast, | clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create( | ||||
clang::SourceLocation(), // beginLoc, | *ast, | ||||
clang::SourceLocation(), // endLoc, | clang::SourceLocation(), // beginLoc, | ||||
method_selector, | clang::SourceLocation(), // endLoc, | ||||
method_function_prototype->getReturnType(), | method_selector, method_function_prototype->getReturnType(), | ||||
nullptr, // TypeSourceInfo *ResultTInfo, | nullptr, // TypeSourceInfo *ResultTInfo, | ||||
ClangASTContext::GetASTContext(ast)->GetDeclContextForType(GetQualType(type)), | ClangASTContext::GetASTContext(ast)->GetDeclContextForType(ClangUtil::GetQualType(type)), name[0] == '-', | ||||
name[0] == '-', | is_variadic, is_synthesized, | ||||
is_variadic, | true, // is_implicitly_declared; we force this to true because we don't have source locations | ||||
is_synthesized, | is_defined, imp_control, false /*has_related_result_type*/); | ||||
true, // is_implicitly_declared; we force this to true because we don't have source locations | |||||
is_defined, | |||||
imp_control, | |||||
false /*has_related_result_type*/); | |||||
if (objc_method_decl == nullptr) | if (objc_method_decl == nullptr) | ||||
return nullptr; | return nullptr; | ||||
Context not available. | |||||
bool | bool | ||||
ClangASTContext::GetHasExternalStorage (const CompilerType &type) | ClangASTContext::GetHasExternalStorage (const CompilerType &type) | ||||
{ | { | ||||
if (IsClangType(type)) | if (ClangUtil::IsClangType(type)) | ||||
return false; | return false; | ||||
clang::QualType qual_type (GetCanonicalQualType(type)); | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); | ||||
const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||
switch (type_class) | switch (type_class) | ||||
Context not available. | |||||
} | } | ||||
bool | |||||
ClangASTContext::CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer) | |||||
{ | |||||
if (IsClangType(type)) | |||||
{ | |||||
// TODO: remove external completion BOOL | |||||
// CompleteAndFetchChildren should get the Decl out and check for the | |||||
clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type))); | |||||
const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | |||||
switch (type_class) | |||||
{ | |||||
case clang::Type::Record: | |||||
{ | |||||
const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); | |||||
if (cxx_record_decl) | |||||
{ | |||||
if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL)) | |||||
return true; | |||||
} | |||||
} | |||||
break; | |||||
case clang::Type::Enum: | |||||
{ | |||||
clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); | |||||
if (enum_decl) | |||||
{ | |||||
if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL)) | |||||
return true; | |||||
} | |||||
} | |||||
break; | |||||
case clang::Type::ObjCObject: | |||||
case clang::Type::ObjCInterface: | |||||
{ | |||||
const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); | |||||
if (objc_class_type) | |||||
{ | |||||
clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); | |||||
// We currently can't complete objective C types through the newly added ASTContext | |||||
// because it only supports TagDecl objects right now... | |||||
if (class_interface_decl) | |||||
{ | |||||
if (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL)) | |||||
return true; | |||||
} | |||||
} | |||||
} | |||||
break; | |||||
case clang::Type::Typedef: | |||||
return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer); | |||||
case clang::Type::Auto: | |||||
return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()), importer); | |||||
case clang::Type::Elaborated: | |||||
return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer); | |||||
case clang::Type::Paren: | |||||
return CanImport(CompilerType (type.GetTypeSystem(), llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer); | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
bool | |||||
ClangASTContext::Import (const CompilerType &type, lldb_private::ClangASTImporter &importer) | |||||
{ | |||||
if (IsClangType(type)) | |||||
{ | |||||
// TODO: remove external completion BOOL | |||||
// CompleteAndFetchChildren should get the Decl out and check for the | |||||
clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type))); | |||||
const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | |||||
switch (type_class) | |||||
{ | |||||
case clang::Type::Record: | |||||
{ | |||||
const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); | |||||
if (cxx_record_decl) | |||||
{ | |||||
if (importer.ResolveDeclOrigin (cxx_record_decl, NULL, NULL)) | |||||
return importer.CompleteAndFetchChildren(qual_type); | |||||
} | |||||
} | |||||
break; | |||||
case clang::Type::Enum: | |||||
{ | |||||
clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); | |||||
if (enum_decl) | |||||
{ | |||||
if (importer.ResolveDeclOrigin (enum_decl, NULL, NULL)) | |||||
return importer.CompleteAndFetchChildren(qual_type); | |||||
} | |||||
} | |||||
break; | |||||
case clang::Type::ObjCObject: | |||||
case clang::Type::ObjCInterface: | |||||
{ | |||||
const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type); | |||||
if (objc_class_type) | |||||
{ | |||||
clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); | |||||
// We currently can't complete objective C types through the newly added ASTContext | |||||
// because it only supports TagDecl objects right now... | |||||
if (class_interface_decl) | |||||
{ | |||||
if (importer.ResolveDeclOrigin (class_interface_decl, NULL, NULL)) | |||||
return importer.CompleteAndFetchChildren(qual_type); | |||||
} | |||||
} | |||||
} | |||||
break; | |||||
case clang::Type::Typedef: | |||||
return Import (CompilerType(type.GetTypeSystem(), llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()), importer); | |||||
case clang::Type::Auto: | |||||
return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()), importer); | |||||
case clang::Type::Elaborated: | |||||
return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()), importer); | |||||
case clang::Type::Paren: | |||||
return Import (CompilerType(type.GetTypeSystem(),llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()), importer); | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
#pragma mark TagDecl | #pragma mark TagDecl | ||||
bool | bool | ||||
ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type) | ClangASTContext::StartTagDeclarationDefinition (const CompilerType &type) | ||||
{ | { | ||||
clang::QualType qual_type (ClangASTContext::GetQualType(type)); | clang::QualType qual_type(ClangUtil::GetQualType(type)); | ||||
if (!qual_type.isNull()) | if (!qual_type.isNull()) | ||||
{ | { | ||||
const clang::TagType *tag_type = qual_type->getAs<clang::TagType>(); | const clang::TagType *tag_type = qual_type->getAs<clang::TagType>(); | ||||
Context not available. | |||||
bool | bool | ||||
ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type) | ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type) | ||||
{ | { | ||||
clang::QualType qual_type (ClangASTContext::GetQualType(type)); | clang::QualType qual_type(ClangUtil::GetQualType(type)); | ||||
if (!qual_type.isNull()) | if (!qual_type.isNull()) | ||||
{ | { | ||||
clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); | clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); | ||||
Context not available. | |||||
{ | { | ||||
llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed); | llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed); | ||||
enum_llvm_apsint = enum_value; | enum_llvm_apsint = enum_value; | ||||
clang::EnumConstantDecl *enumerator_decl = | clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create( | ||||
clang::EnumConstantDecl::Create (*getASTContext(), | *getASTContext(), enutype->getDecl(), clang::SourceLocation(), | ||||
enutype->getDecl(), | name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier | ||||
clang::SourceLocation(), | ClangUtil::GetQualType(enumerator_clang_type), nullptr, enum_llvm_apsint); | ||||
name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier | |||||
GetQualType(enumerator_clang_type), | |||||
nullptr, | |||||
enum_llvm_apsint); | |||||
if (enumerator_decl) | if (enumerator_decl) | ||||
{ | { | ||||
enutype->getDecl()->addDecl(enumerator_decl); | enutype->getDecl()->addDecl(enumerator_decl); | ||||
Context not available. | |||||
ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); | ClangASTContext *ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); | ||||
if (!ast) | if (!ast) | ||||
return CompilerType(); | return CompilerType(); | ||||
return CompilerType (ast->getASTContext(), | return CompilerType(ast->getASTContext(), | ||||
ast->getASTContext()->getMemberPointerType (GetQualType(pointee_type), | ast->getASTContext()->getMemberPointerType(ClangUtil::GetQualType(pointee_type), | ||||
GetQualType(type).getTypePtr())); | ClangUtil::GetQualType(type).getTypePtr())); | ||||
} | } | ||||
return CompilerType(); | return CompilerType(); | ||||
} | } | ||||
Context not available. | |||||
void | void | ||||
ClangASTContext::DumpTypeName (const CompilerType &type) | ClangASTContext::DumpTypeName (const CompilerType &type) | ||||
{ | { | ||||
if (IsClangType(type)) | if (ClangUtil::IsClangType(type)) | ||||
{ | { | ||||
clang::QualType qual_type(GetCanonicalQualType(RemoveFastQualifiers(type))); | clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type))); | ||||
const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | const clang::Type::TypeClass type_class = qual_type->getTypeClass(); | ||||
switch (type_class) | switch (type_class) | ||||
Context not available. | |||||
} | } | ||||
} | } | ||||
DWARFASTParser * | DWARFASTParser * | ||||
ClangASTContext::GetDWARFParser () | ClangASTContext::GetDWARFParser() | ||||
{ | { | ||||
if (!m_dwarf_ast_parser_ap) | if (!m_dwarf_ast_parser_ap) | ||||
m_dwarf_ast_parser_ap.reset(new DWARFASTParserClang(*this)); | m_dwarf_ast_parser_ap.reset(new DWARFASTParserClang(*this)); | ||||
Context not available. | |||||
{ | { | ||||
ClangASTContext *ast = (ClangASTContext *)baton; | ClangASTContext *ast = (ClangASTContext *)baton; | ||||
DWARFASTParserClang *dwarf_ast_parser = (DWARFASTParserClang *)ast->GetDWARFParser(); | DWARFASTParserClang *dwarf_ast_parser = (DWARFASTParserClang *)ast->GetDWARFParser(); | ||||
return dwarf_ast_parser->LayoutRecordType(record_decl, bit_size, alignment, field_offsets, base_offsets, vbase_offsets); | return dwarf_ast_parser->GetClangASTImporter().LayoutRecordType(record_decl, bit_size, alignment, field_offsets, | ||||
base_offsets, vbase_offsets); | |||||
} | } | ||||
//---------------------------------------------------------------------- | //---------------------------------------------------------------------- | ||||
Context not available. |