@@ -2574,6 +2574,128 @@ TypeSystemClang::GetDeclContextForType(clang::QualType type) {
25742574 return nullptr ;
25752575}
25762576
2577+ // / Returns the clang::RecordType of the specified \ref qual_type. This
2578+ // / function will try to complete the type if necessary (and allowed
2579+ // / by the specified \ref allow_completion). If we fail to return a *complete*
2580+ // / type, returns nullptr.
2581+ static const clang::RecordType *GetCompleteRecordType (clang::ASTContext *ast,
2582+ clang::QualType qual_type,
2583+ bool allow_completion) {
2584+ assert (qual_type->isRecordType ());
2585+
2586+ const auto *tag_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr ());
2587+
2588+ clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl ();
2589+
2590+ // RecordType with no way of completing it, return the plain
2591+ // TagType.
2592+ if (!cxx_record_decl || !cxx_record_decl->hasExternalLexicalStorage ())
2593+ return tag_type;
2594+
2595+ const bool is_complete = cxx_record_decl->isCompleteDefinition ();
2596+ const bool fields_loaded =
2597+ cxx_record_decl->hasLoadedFieldsFromExternalStorage ();
2598+
2599+ // Already completed this type, nothing to be done.
2600+ if (is_complete && fields_loaded)
2601+ return tag_type;
2602+
2603+ if (!allow_completion)
2604+ return nullptr ;
2605+
2606+ // Call the field_begin() accessor to for it to use the external source
2607+ // to load the fields...
2608+ //
2609+ // TODO: if we need to complete the type but have no external source,
2610+ // shouldn't we error out instead?
2611+ clang::ExternalASTSource *external_ast_source = ast->getExternalSource ();
2612+ if (external_ast_source) {
2613+ external_ast_source->CompleteType (cxx_record_decl);
2614+ if (cxx_record_decl->isCompleteDefinition ()) {
2615+ cxx_record_decl->field_begin ();
2616+ cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true );
2617+ }
2618+ }
2619+
2620+ return tag_type;
2621+ }
2622+
2623+ // / Returns the clang::EnumType of the specified \ref qual_type. This
2624+ // / function will try to complete the type if necessary (and allowed
2625+ // / by the specified \ref allow_completion). If we fail to return a *complete*
2626+ // / type, returns nullptr.
2627+ static const clang::EnumType *GetCompleteEnumType (clang::ASTContext *ast,
2628+ clang::QualType qual_type,
2629+ bool allow_completion) {
2630+ assert (qual_type->isEnumeralType ());
2631+ assert (ast);
2632+
2633+ const clang::EnumType *enum_type =
2634+ llvm::cast<clang::EnumType>(qual_type.getTypePtr ());
2635+
2636+ auto *tag_decl = enum_type->getAsTagDecl ();
2637+ assert (tag_decl);
2638+
2639+ // Already completed, nothing to be done.
2640+ if (tag_decl->getDefinition ())
2641+ return enum_type;
2642+
2643+ if (!allow_completion)
2644+ return nullptr ;
2645+
2646+ // No definition but can't complete it, error out.
2647+ if (!tag_decl->hasExternalLexicalStorage ())
2648+ return nullptr ;
2649+
2650+ // We can't complete the type without an external source.
2651+ clang::ExternalASTSource *external_ast_source = ast->getExternalSource ();
2652+ if (!external_ast_source)
2653+ return nullptr ;
2654+
2655+ external_ast_source->CompleteType (tag_decl);
2656+ return enum_type;
2657+ }
2658+
2659+ // / Returns the clang::ObjCObjectType of the specified \ref qual_type. This
2660+ // / function will try to complete the type if necessary (and allowed
2661+ // / by the specified \ref allow_completion). If we fail to return a *complete*
2662+ // / type, returns nullptr.
2663+ static const clang::ObjCObjectType *
2664+ GetCompleteObjCObjectType (clang::ASTContext *ast, QualType qual_type,
2665+ bool allow_completion) {
2666+ assert (qual_type->isObjCObjectType ());
2667+ assert (ast);
2668+
2669+ const clang::ObjCObjectType *objc_class_type =
2670+ llvm::cast<clang::ObjCObjectType>(qual_type);
2671+
2672+ clang::ObjCInterfaceDecl *class_interface_decl =
2673+ objc_class_type->getInterface ();
2674+ // We currently can't complete objective C types through the newly added
2675+ // ASTContext because it only supports TagDecl objects right now...
2676+ if (!class_interface_decl)
2677+ return objc_class_type;
2678+
2679+ // Already complete, nothing to be done.
2680+ if (class_interface_decl->getDefinition ())
2681+ return objc_class_type;
2682+
2683+ if (!allow_completion)
2684+ return nullptr ;
2685+
2686+ // No definition but can't complete it, error out.
2687+ if (!class_interface_decl->hasExternalLexicalStorage ())
2688+ return nullptr ;
2689+
2690+ // We can't complete the type without an external source.
2691+ clang::ExternalASTSource *external_ast_source = ast->getExternalSource ();
2692+ if (!external_ast_source)
2693+ return nullptr ;
2694+
2695+ external_ast_source->CompleteType (class_interface_decl);
2696+ return objc_class_type;
2697+ }
2698+
25772699static bool GetCompleteQualType (clang::ASTContext *ast,
25782700 clang::QualType qual_type,
25792701 bool allow_completion = true ) {
@@ -2591,92 +2713,26 @@ static bool GetCompleteQualType(clang::ASTContext *ast,
25912713 allow_completion);
25922714 } break ;
25932715 case clang::Type::Record: {
2594- clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl ();
2595- if (cxx_record_decl) {
2596- if (cxx_record_decl->hasExternalLexicalStorage ()) {
2597- const bool is_complete = cxx_record_decl->isCompleteDefinition ();
2598- const bool fields_loaded =
2599- cxx_record_decl->hasLoadedFieldsFromExternalStorage ();
2600- if (is_complete && fields_loaded)
2601- return true ;
2716+ if (const auto *RT =
2717+ GetCompleteRecordType (ast, qual_type, allow_completion))
2718+ return !RT->isIncompleteType ();
26022719
2603- if (!allow_completion)
2604- return false ;
2605-
2606- // Call the field_begin() accessor to for it to use the external source
2607- // to load the fields...
2608- clang::ExternalASTSource *external_ast_source =
2609- ast->getExternalSource ();
2610- if (external_ast_source) {
2611- external_ast_source->CompleteType (cxx_record_decl);
2612- if (cxx_record_decl->isCompleteDefinition ()) {
2613- cxx_record_decl->field_begin ();
2614- cxx_record_decl->setHasLoadedFieldsFromExternalStorage (true );
2615- }
2616- }
2617- }
2618- }
2619- const clang::TagType *tag_type =
2620- llvm::cast<clang::TagType>(qual_type.getTypePtr ());
2621- return !tag_type->isIncompleteType ();
2720+ return false ;
26222721 } break ;
26232722
26242723 case clang::Type::Enum: {
2625- const clang::TagType *tag_type =
2626- llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr ());
2627- if (tag_type) {
2628- clang::TagDecl *tag_decl = tag_type->getDecl ();
2629- if (tag_decl) {
2630- if (tag_decl->getDefinition ())
2631- return true ;
2632-
2633- if (!allow_completion)
2634- return false ;
2635-
2636- if (tag_decl->hasExternalLexicalStorage ()) {
2637- if (ast) {
2638- clang::ExternalASTSource *external_ast_source =
2639- ast->getExternalSource ();
2640- if (external_ast_source) {
2641- external_ast_source->CompleteType (tag_decl);
2642- return !tag_type->isIncompleteType ();
2643- }
2644- }
2645- }
2646- return false ;
2647- }
2648- }
2724+ if (const auto *ET = GetCompleteEnumType (ast, qual_type, allow_completion))
2725+ return !ET->isIncompleteType ();
26492726
2727+ return false ;
26502728 } break ;
26512729 case clang::Type::ObjCObject:
26522730 case clang::Type::ObjCInterface: {
2653- const clang::ObjCObjectType *objc_class_type =
2654- llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
2655- if (objc_class_type) {
2656- clang::ObjCInterfaceDecl *class_interface_decl =
2657- objc_class_type->getInterface ();
2658- // We currently can't complete objective C types through the newly added
2659- // ASTContext because it only supports TagDecl objects right now...
2660- if (class_interface_decl) {
2661- if (class_interface_decl->getDefinition ())
2662- return true ;
2663-
2664- if (!allow_completion)
2665- return false ;
2731+ if (const auto *OT =
2732+ GetCompleteObjCObjectType (ast, qual_type, allow_completion))
2733+ return !OT->isIncompleteType ();
26662734
2667- if (class_interface_decl->hasExternalLexicalStorage ()) {
2668- if (ast) {
2669- clang::ExternalASTSource *external_ast_source =
2670- ast->getExternalSource ();
2671- if (external_ast_source) {
2672- external_ast_source->CompleteType (class_interface_decl);
2673- return !objc_class_type->isIncompleteType ();
2674- }
2675- }
2676- }
2677- return false ;
2678- }
2679- }
2735+ return false ;
26802736 } break ;
26812737
26822738 case clang::Type::Attributed:
0 commit comments