@@ -2574,6 +2574,128 @@ TypeSystemClang::GetDeclContextForType(clang::QualType type) {
2574
2574
return nullptr ;
2575
2575
}
2576
2576
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
+
2577
2699
static bool GetCompleteQualType (clang::ASTContext *ast,
2578
2700
clang::QualType qual_type,
2579
2701
bool allow_completion = true ) {
@@ -2591,92 +2713,26 @@ static bool GetCompleteQualType(clang::ASTContext *ast,
2591
2713
allow_completion);
2592
2714
} break ;
2593
2715
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 ();
2602
2719
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 ;
2622
2721
} break ;
2623
2722
2624
2723
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 ();
2649
2726
2727
+ return false ;
2650
2728
} break ;
2651
2729
case clang::Type::ObjCObject:
2652
2730
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 ();
2666
2734
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 ;
2680
2736
} break ;
2681
2737
2682
2738
case clang::Type::Attributed:
0 commit comments