Skip to content

Commit ac938b4

Browse files
committed
[lldb][TypeSystemClang][NFCI] Factor completion logic out of GetCompleteQualType
1 parent c64b7a1 commit ac938b4

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
@@ -2616,6 +2616,105 @@ TypeSystemClang::GetDeclContextForType(clang::QualType type) {
26162616
return nullptr;
26172617
}
26182618

2619+
static clang::Type const *GetCompleteRecordType(clang::ASTContext *ast,
2620+
clang::QualType qual_type,
2621+
bool allow_completion = true) {
2622+
clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2623+
if (!cxx_record_decl)
2624+
return nullptr;
2625+
2626+
if (cxx_record_decl->hasExternalLexicalStorage()) {
2627+
const bool is_complete = cxx_record_decl->isCompleteDefinition();
2628+
const bool fields_loaded =
2629+
cxx_record_decl->hasLoadedFieldsFromExternalStorage();
2630+
if (is_complete && fields_loaded)
2631+
return qual_type.getTypePtr();
2632+
2633+
if (!allow_completion)
2634+
return nullptr;
2635+
2636+
// Call the field_begin() accessor to for it to use the external source
2637+
// to load the fields...
2638+
clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2639+
if (external_ast_source) {
2640+
external_ast_source->CompleteType(cxx_record_decl);
2641+
if (cxx_record_decl->isCompleteDefinition()) {
2642+
cxx_record_decl->field_begin();
2643+
cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
2644+
}
2645+
}
2646+
2647+
return qual_type.getTypePtr();
2648+
}
2649+
2650+
return qual_type.getTypePtr();
2651+
}
2652+
2653+
static clang::Type const *GetCompleteEnumType(clang::ASTContext *ast,
2654+
clang::QualType qual_type,
2655+
bool allow_completion = true) {
2656+
const clang::TagType *tag_type =
2657+
llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
2658+
if (!tag_type)
2659+
return nullptr;
2660+
2661+
clang::TagDecl *tag_decl = tag_type->getDecl();
2662+
if (!tag_decl)
2663+
return nullptr;
2664+
2665+
if (tag_decl->getDefinition())
2666+
return tag_type;
2667+
2668+
if (!allow_completion)
2669+
return nullptr;
2670+
2671+
if (tag_decl->hasExternalLexicalStorage()) {
2672+
if (ast) {
2673+
clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2674+
if (external_ast_source) {
2675+
external_ast_source->CompleteType(tag_decl);
2676+
return tag_type;
2677+
}
2678+
}
2679+
}
2680+
2681+
return tag_type;
2682+
}
2683+
2684+
static clang::Type const *
2685+
GetCompleteObjCInterfaceType(clang::ASTContext *ast, clang::QualType qual_type,
2686+
bool allow_completion = true) {
2687+
const clang::ObjCObjectType *objc_class_type =
2688+
llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
2689+
if (!objc_class_type)
2690+
return nullptr;
2691+
2692+
clang::ObjCInterfaceDecl *class_interface_decl =
2693+
objc_class_type->getInterface();
2694+
// We currently can't complete objective C types through the newly added
2695+
// ASTContext because it only supports TagDecl objects right now...
2696+
if (!class_interface_decl)
2697+
return objc_class_type;
2698+
2699+
if (class_interface_decl->getDefinition())
2700+
return objc_class_type;
2701+
2702+
if (!allow_completion)
2703+
return nullptr;
2704+
2705+
if (class_interface_decl->hasExternalLexicalStorage()) {
2706+
if (ast) {
2707+
clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
2708+
if (external_ast_source) {
2709+
external_ast_source->CompleteType(class_interface_decl);
2710+
return objc_class_type;
2711+
}
2712+
}
2713+
}
2714+
2715+
return nullptr;
2716+
}
2717+
26192718
static bool GetCompleteQualType(clang::ASTContext *ast,
26202719
clang::QualType qual_type,
26212720
bool allow_completion = true) {
@@ -2633,92 +2732,27 @@ static bool GetCompleteQualType(clang::ASTContext *ast,
26332732
allow_completion);
26342733
} break;
26352734
case clang::Type::Record: {
2636-
clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2637-
if (cxx_record_decl) {
2638-
if (cxx_record_decl->hasExternalLexicalStorage()) {
2639-
const bool is_complete = cxx_record_decl->isCompleteDefinition();
2640-
const bool fields_loaded =
2641-
cxx_record_decl->hasLoadedFieldsFromExternalStorage();
2642-
if (is_complete && fields_loaded)
2643-
return true;
2735+
if (auto const *ty = llvm::dyn_cast_or_null<RecordType>(
2736+
GetCompleteRecordType(ast, qual_type, allow_completion)))
2737+
return !ty->isIncompleteType();
26442738

2645-
if (!allow_completion)
2646-
return false;
2647-
2648-
// Call the field_begin() accessor to for it to use the external source
2649-
// to load the fields...
2650-
clang::ExternalASTSource *external_ast_source =
2651-
ast->getExternalSource();
2652-
if (external_ast_source) {
2653-
external_ast_source->CompleteType(cxx_record_decl);
2654-
if (cxx_record_decl->isCompleteDefinition()) {
2655-
cxx_record_decl->field_begin();
2656-
cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
2657-
}
2658-
}
2659-
}
2660-
}
2661-
const clang::TagType *tag_type =
2662-
llvm::cast<clang::TagType>(qual_type.getTypePtr());
2663-
return !tag_type->isIncompleteType();
2739+
return false;
26642740
} break;
26652741

26662742
case clang::Type::Enum: {
2667-
const clang::TagType *tag_type =
2668-
llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
2669-
if (tag_type) {
2670-
clang::TagDecl *tag_decl = tag_type->getDecl();
2671-
if (tag_decl) {
2672-
if (tag_decl->getDefinition())
2673-
return true;
2674-
2675-
if (!allow_completion)
2676-
return false;
2677-
2678-
if (tag_decl->hasExternalLexicalStorage()) {
2679-
if (ast) {
2680-
clang::ExternalASTSource *external_ast_source =
2681-
ast->getExternalSource();
2682-
if (external_ast_source) {
2683-
external_ast_source->CompleteType(tag_decl);
2684-
return !tag_type->isIncompleteType();
2685-
}
2686-
}
2687-
}
2688-
return false;
2689-
}
2690-
}
2743+
if (auto const *ty = llvm::dyn_cast_or_null<EnumType>(
2744+
GetCompleteEnumType(ast, qual_type, allow_completion)))
2745+
return !ty->isIncompleteType();
26912746

2747+
return false;
26922748
} break;
26932749
case clang::Type::ObjCObject:
26942750
case clang::Type::ObjCInterface: {
2695-
const clang::ObjCObjectType *objc_class_type =
2696-
llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
2697-
if (objc_class_type) {
2698-
clang::ObjCInterfaceDecl *class_interface_decl =
2699-
objc_class_type->getInterface();
2700-
// We currently can't complete objective C types through the newly added
2701-
// ASTContext because it only supports TagDecl objects right now...
2702-
if (class_interface_decl) {
2703-
if (class_interface_decl->getDefinition())
2704-
return true;
2705-
2706-
if (!allow_completion)
2707-
return false;
2751+
if (auto const *ty = llvm::dyn_cast_or_null<ObjCInterfaceType>(
2752+
GetCompleteObjCInterfaceType(ast, qual_type, allow_completion)))
2753+
return !ty->isIncompleteType();
27082754

2709-
if (class_interface_decl->hasExternalLexicalStorage()) {
2710-
if (ast) {
2711-
clang::ExternalASTSource *external_ast_source =
2712-
ast->getExternalSource();
2713-
if (external_ast_source) {
2714-
external_ast_source->CompleteType(class_interface_decl);
2715-
return !objc_class_type->isIncompleteType();
2716-
}
2717-
}
2718-
}
2719-
return false;
2720-
}
2721-
}
2755+
return false;
27222756
} break;
27232757

27242758
case clang::Type::Attributed:

0 commit comments

Comments
 (0)