@@ -820,6 +820,67 @@ Class* Parser::WalkRecordCXX(const clang::CXXRecordDecl* Record)
820
820
821
821
static int I = 0 ;
822
822
823
+ static bool IsRecordValid (const clang::RecordDecl* RC,
824
+ std::vector<const clang::RecordDecl*>& Visited)
825
+ {
826
+ using namespace clang ;
827
+
828
+ if (std::find (Visited.begin (), Visited.end (), RC) != Visited.end ())
829
+ return true ;
830
+
831
+ Visited.push_back (RC);
832
+ if (RC->isInvalidDecl ())
833
+ return false ;
834
+ for (auto Field : RC->fields ())
835
+ {
836
+ auto Type = Field->getType ()->getUnqualifiedDesugaredType ();
837
+ const auto * RD = const_cast <CXXRecordDecl*>(Type->getAsCXXRecordDecl ());
838
+ if (!RD)
839
+ RD = Type->getPointeeCXXRecordDecl ();
840
+ if (RD && !IsRecordValid (RD, Visited))
841
+ return false ;
842
+ }
843
+ return true ;
844
+ }
845
+
846
+ static bool IsRecordValid (const clang::RecordDecl* RC)
847
+ {
848
+ std::vector<const clang::RecordDecl*> Visited;
849
+ return IsRecordValid (RC, Visited);
850
+ }
851
+
852
+ static clang::CXXRecordDecl* GetCXXRecordDeclFromBaseType (const clang::QualType& Ty) {
853
+ using namespace clang ;
854
+
855
+ if (auto RT = Ty->getAs <clang::RecordType>())
856
+ return dyn_cast<clang::CXXRecordDecl>(RT->getDecl ());
857
+ else if (auto TST = Ty->getAs <clang::TemplateSpecializationType>())
858
+ return dyn_cast<clang::CXXRecordDecl>(
859
+ TST->getTemplateName ().getAsTemplateDecl ()->getTemplatedDecl ());
860
+ else if (auto Injected = Ty->getAs <clang::InjectedClassNameType>())
861
+ return Injected->getDecl ();
862
+
863
+ assert (" Could not get base CXX record from type" );
864
+ return nullptr ;
865
+ }
866
+
867
+ static bool HasLayout (const clang::RecordDecl* Record)
868
+ {
869
+ if (Record->isDependentType () || !Record->getDefinition () ||
870
+ !IsRecordValid (Record))
871
+ return false ;
872
+
873
+ if (auto CXXRecord = llvm::dyn_cast<clang::CXXRecordDecl>(Record))
874
+ for (auto Base : CXXRecord->bases ())
875
+ {
876
+ auto CXXBase = GetCXXRecordDeclFromBaseType (Base.getType ());
877
+ if (!CXXBase || !HasLayout (CXXBase))
878
+ return false ;
879
+ }
880
+
881
+ return true ;
882
+ }
883
+
823
884
void Parser::WalkRecord (const clang::RecordDecl* Record, Class* RC)
824
885
{
825
886
using namespace clang ;
@@ -846,7 +907,7 @@ void Parser::WalkRecord(const clang::RecordDecl* Record, Class* RC)
846
907
RC->isDependent = Record->isDependentType ();
847
908
RC->isExternCContext = Record->isExternCContext ();
848
909
849
- bool hasLayout = !Record-> isDependentType () && ! Record-> isInvalidDecl ( );
910
+ bool hasLayout = HasLayout ( Record);
850
911
851
912
if (hasLayout)
852
913
{
@@ -926,21 +987,6 @@ void Parser::WalkRecord(const clang::RecordDecl* Record, Class* RC)
926
987
}
927
988
}
928
989
929
- static clang::CXXRecordDecl* GetCXXRecordDeclFromBaseType (const clang::Type* Ty) {
930
- using namespace clang ;
931
-
932
- if (auto RT = Ty->getAs <clang::RecordType>())
933
- return dyn_cast<clang::CXXRecordDecl>(RT->getDecl ());
934
- else if (auto TST = Ty->getAs <clang::TemplateSpecializationType>())
935
- return dyn_cast<clang::CXXRecordDecl>(
936
- TST->getTemplateName ().getAsTemplateDecl ()->getTemplatedDecl ());
937
- else if (auto Injected = Ty->getAs <clang::InjectedClassNameType>())
938
- return Injected->getDecl ();
939
-
940
- assert (" Could not get base CXX record from type" );
941
- return nullptr ;
942
- }
943
-
944
990
void Parser::WalkRecordCXX (const clang::CXXRecordDecl* Record, Class* RC)
945
991
{
946
992
using namespace clang ;
@@ -961,7 +1007,7 @@ void Parser::WalkRecordCXX(const clang::CXXRecordDecl* Record, Class* RC)
961
1007
RC->hasNonTrivialCopyConstructor = Record->hasNonTrivialCopyConstructor ();
962
1008
RC->hasNonTrivialDestructor = Record->hasNonTrivialDestructor ();
963
1009
964
- bool hasLayout = !Record-> isDependentType () && ! Record-> isInvalidDecl ( ) &&
1010
+ bool hasLayout = HasLayout ( Record) &&
965
1011
Record->getDeclName () != c->getSema ().VAListTagName ;
966
1012
967
1013
// Get the record layout information.
@@ -976,18 +1022,16 @@ void Parser::WalkRecordCXX(const clang::CXXRecordDecl* Record, Class* RC)
976
1022
}
977
1023
978
1024
// Iterate through the record bases.
979
- for (auto it = Record->bases_begin (); it != Record-> bases_end (); ++it )
1025
+ for (auto BS : Record->bases () )
980
1026
{
981
- auto & BS = *it;
982
-
983
1027
BaseClassSpecifier* Base = new BaseClassSpecifier ();
984
1028
Base->access = ConvertToAccess (BS.getAccessSpecifier ());
985
1029
Base->isVirtual = BS.isVirtual ();
986
1030
987
1031
auto BSTL = BS.getTypeSourceInfo ()->getTypeLoc ();
988
1032
Base->type = WalkType (BS.getType (), &BSTL);
989
1033
990
- auto BaseDecl = GetCXXRecordDeclFromBaseType (BS.getType (). getTypePtr () );
1034
+ auto BaseDecl = GetCXXRecordDeclFromBaseType (BS.getType ());
991
1035
if (BaseDecl && Layout)
992
1036
{
993
1037
auto Offset = BS.isVirtual () ? Layout->getVBaseClassOffset (BaseDecl)
@@ -2784,7 +2828,7 @@ bool Parser::CanCheckCodeGenInfo(clang::Sema& S, const clang::Type* Ty)
2784
2828
return false ;
2785
2829
2786
2830
if (auto RT = FinalType->getAs <clang::RecordType>())
2787
- return RT->getDecl ()-> getDefinition () != 0 ;
2831
+ return HasLayout ( RT->getDecl ()) ;
2788
2832
2789
2833
// Lock in the MS inheritance model if we have a member pointer to a class,
2790
2834
// else we get an assertion error inside Clang's codegen machinery.
@@ -2985,7 +3029,7 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F,
2985
3029
2986
3030
const CXXMethodDecl* MD;
2987
3031
if ((MD = dyn_cast<CXXMethodDecl>(FD)) && !MD->isStatic () &&
2988
- !CanCheckCodeGenInfo (c-> getSema (), MD->getThisType (c-> getASTContext ()). getTypePtr ( )))
3032
+ !HasLayout (cast<CXXRecordDecl>( MD->getDeclContext () )))
2989
3033
return ;
2990
3034
2991
3035
if (!CanCheckCodeGenInfo (c->getSema (), FD->getReturnType ().getTypePtr ()))
0 commit comments