Skip to content

Commit 0335368

Browse files
committed
[lldb][TypeSystemClang][NFCI] Factor completion logic out of GetCompleteQualType
(cherry picked from commit a1202f476ab7327e522d06d55737eb5f6a690811)
1 parent 0c17fe0 commit 0335368

File tree

1 file changed

+111
-77
lines changed

1 file changed

+111
-77
lines changed

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Lines changed: 111 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,6 +2705,105 @@ TypeSystemClang::GetDeclContextForType(clang::QualType type) {
27052705
return nullptr;
27062706
}
27072707

2708+
static clang::Type const *GetCompleteRecordType(clang::ASTContext *ast,
2709+
clang::QualType qual_type,
2710+
bool allow_completion = true) {
2711+
clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2712+
if (!cxx_record_decl)
2713+
return nullptr;
2714+
2715+
if (cxx_record_decl->hasExternalLexicalStorage()) {
2716+
const bool is_complete = cxx_record_decl->isCompleteDefinition();
2717+
const bool fields_loaded =
2718+
cxx_record_decl->hasLoadedFieldsFromExternalStorage();
2719+
if (is_complete && fields_loaded)
2720+
return qual_type.getTypePtr();
2721+
2722+
if (!allow_completion)
2723+
return nullptr;
2724+
2725+
// Call the field_begin() accessor to for it to use the external source
2726+
// to load the fields...
2727+
clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2728+
if (external_ast_source) {
2729+
external_ast_source->CompleteType(cxx_record_decl);
2730+
if (cxx_record_decl->isCompleteDefinition()) {
2731+
cxx_record_decl->field_begin();
2732+
cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
2733+
}
2734+
}
2735+
2736+
return qual_type.getTypePtr();
2737+
}
2738+
2739+
return qual_type.getTypePtr();
2740+
}
2741+
2742+
static clang::Type const *GetCompleteEnumType(clang::ASTContext *ast,
2743+
clang::QualType qual_type,
2744+
bool allow_completion = true) {
2745+
const clang::TagType *tag_type =
2746+
llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
2747+
if (!tag_type)
2748+
return nullptr;
2749+
2750+
clang::TagDecl *tag_decl = tag_type->getDecl();
2751+
if (!tag_decl)
2752+
return nullptr;
2753+
2754+
if (tag_decl->getDefinition())
2755+
return tag_type;
2756+
2757+
if (!allow_completion)
2758+
return nullptr;
2759+
2760+
if (tag_decl->hasExternalLexicalStorage()) {
2761+
if (ast) {
2762+
clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2763+
if (external_ast_source) {
2764+
external_ast_source->CompleteType(tag_decl);
2765+
return tag_type;
2766+
}
2767+
}
2768+
}
2769+
2770+
return tag_type;
2771+
}
2772+
2773+
static clang::Type const *
2774+
GetCompleteObjCInterfaceType(clang::ASTContext *ast, clang::QualType qual_type,
2775+
bool allow_completion = true) {
2776+
const clang::ObjCObjectType *objc_class_type =
2777+
llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
2778+
if (!objc_class_type)
2779+
return nullptr;
2780+
2781+
clang::ObjCInterfaceDecl *class_interface_decl =
2782+
objc_class_type->getInterface();
2783+
// We currently can't complete objective C types through the newly added
2784+
// ASTContext because it only supports TagDecl objects right now...
2785+
if (!class_interface_decl)
2786+
return objc_class_type;
2787+
2788+
if (class_interface_decl->getDefinition())
2789+
return objc_class_type;
2790+
2791+
if (!allow_completion)
2792+
return nullptr;
2793+
2794+
if (class_interface_decl->hasExternalLexicalStorage()) {
2795+
if (ast) {
2796+
clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2797+
if (external_ast_source) {
2798+
external_ast_source->CompleteType(class_interface_decl);
2799+
return objc_class_type;
2800+
}
2801+
}
2802+
}
2803+
2804+
return nullptr;
2805+
}
2806+
27082807
static bool GetCompleteQualType(clang::ASTContext *ast,
27092808
clang::QualType qual_type,
27102809
bool allow_completion = true) {
@@ -2722,92 +2821,27 @@ static bool GetCompleteQualType(clang::ASTContext *ast,
27222821
allow_completion);
27232822
} break;
27242823
case clang::Type::Record: {
2725-
clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2726-
if (cxx_record_decl) {
2727-
if (cxx_record_decl->hasExternalLexicalStorage()) {
2728-
const bool is_complete = cxx_record_decl->isCompleteDefinition();
2729-
const bool fields_loaded =
2730-
cxx_record_decl->hasLoadedFieldsFromExternalStorage();
2731-
if (is_complete && fields_loaded)
2732-
return true;
2824+
if (auto const *ty = llvm::dyn_cast_or_null<RecordType>(
2825+
GetCompleteRecordType(ast, qual_type, allow_completion)))
2826+
return !ty->isIncompleteType();
27332827

2734-
if (!allow_completion)
2735-
return false;
2736-
2737-
// Call the field_begin() accessor to for it to use the external source
2738-
// to load the fields...
2739-
clang::ExternalASTSource *external_ast_source =
2740-
ast->getExternalSource();
2741-
if (external_ast_source) {
2742-
external_ast_source->CompleteType(cxx_record_decl);
2743-
if (cxx_record_decl->isCompleteDefinition()) {
2744-
cxx_record_decl->field_begin();
2745-
cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
2746-
}
2747-
}
2748-
}
2749-
}
2750-
const clang::TagType *tag_type =
2751-
llvm::cast<clang::TagType>(qual_type.getTypePtr());
2752-
return !tag_type->isIncompleteType();
2828+
return false;
27532829
} break;
27542830

27552831
case clang::Type::Enum: {
2756-
const clang::TagType *tag_type =
2757-
llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
2758-
if (tag_type) {
2759-
clang::TagDecl *tag_decl = tag_type->getDecl();
2760-
if (tag_decl) {
2761-
if (tag_decl->getDefinition())
2762-
return true;
2763-
2764-
if (!allow_completion)
2765-
return false;
2766-
2767-
if (tag_decl->hasExternalLexicalStorage()) {
2768-
if (ast) {
2769-
clang::ExternalASTSource *external_ast_source =
2770-
ast->getExternalSource();
2771-
if (external_ast_source) {
2772-
external_ast_source->CompleteType(tag_decl);
2773-
return !tag_type->isIncompleteType();
2774-
}
2775-
}
2776-
}
2777-
return false;
2778-
}
2779-
}
2832+
if (auto const *ty = llvm::dyn_cast_or_null<EnumType>(
2833+
GetCompleteEnumType(ast, qual_type, allow_completion)))
2834+
return !ty->isIncompleteType();
27802835

2836+
return false;
27812837
} break;
27822838
case clang::Type::ObjCObject:
27832839
case clang::Type::ObjCInterface: {
2784-
const clang::ObjCObjectType *objc_class_type =
2785-
llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
2786-
if (objc_class_type) {
2787-
clang::ObjCInterfaceDecl *class_interface_decl =
2788-
objc_class_type->getInterface();
2789-
// We currently can't complete objective C types through the newly added
2790-
// ASTContext because it only supports TagDecl objects right now...
2791-
if (class_interface_decl) {
2792-
if (class_interface_decl->getDefinition())
2793-
return true;
2794-
2795-
if (!allow_completion)
2796-
return false;
2840+
if (auto const *ty = llvm::dyn_cast_or_null<ObjCInterfaceType>(
2841+
GetCompleteObjCInterfaceType(ast, qual_type, allow_completion)))
2842+
return !ty->isIncompleteType();
27972843

2798-
if (class_interface_decl->hasExternalLexicalStorage()) {
2799-
if (ast) {
2800-
clang::ExternalASTSource *external_ast_source =
2801-
ast->getExternalSource();
2802-
if (external_ast_source) {
2803-
external_ast_source->CompleteType(class_interface_decl);
2804-
return !objc_class_type->isIncompleteType();
2805-
}
2806-
}
2807-
}
2808-
return false;
2809-
}
2810-
}
2844+
return false;
28112845
} break;
28122846

28132847
case clang::Type::Attributed:

0 commit comments

Comments
 (0)