@@ -820,6 +820,67 @@ Class* Parser::WalkRecordCXX(const clang::CXXRecordDecl* Record)
820820
821821static int I = 0 ;
822822
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+
823884void Parser::WalkRecord (const clang::RecordDecl* Record, Class* RC)
824885{
825886 using namespace clang ;
@@ -846,7 +907,7 @@ void Parser::WalkRecord(const clang::RecordDecl* Record, Class* RC)
846907 RC->isDependent = Record->isDependentType ();
847908 RC->isExternCContext = Record->isExternCContext ();
848909
849- bool hasLayout = !Record-> isDependentType () && ! Record-> isInvalidDecl ( );
910+ bool hasLayout = HasLayout ( Record);
850911
851912 if (hasLayout)
852913 {
@@ -926,21 +987,6 @@ void Parser::WalkRecord(const clang::RecordDecl* Record, Class* RC)
926987 }
927988}
928989
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-
944990void Parser::WalkRecordCXX (const clang::CXXRecordDecl* Record, Class* RC)
945991{
946992 using namespace clang ;
@@ -961,7 +1007,7 @@ void Parser::WalkRecordCXX(const clang::CXXRecordDecl* Record, Class* RC)
9611007 RC->hasNonTrivialCopyConstructor = Record->hasNonTrivialCopyConstructor ();
9621008 RC->hasNonTrivialDestructor = Record->hasNonTrivialDestructor ();
9631009
964- bool hasLayout = !Record-> isDependentType () && ! Record-> isInvalidDecl ( ) &&
1010+ bool hasLayout = HasLayout ( Record) &&
9651011 Record->getDeclName () != c->getSema ().VAListTagName ;
9661012
9671013 // Get the record layout information.
@@ -976,18 +1022,16 @@ void Parser::WalkRecordCXX(const clang::CXXRecordDecl* Record, Class* RC)
9761022 }
9771023
9781024 // Iterate through the record bases.
979- for (auto it = Record->bases_begin (); it != Record-> bases_end (); ++it )
1025+ for (auto BS : Record->bases () )
9801026 {
981- auto & BS = *it;
982-
9831027 BaseClassSpecifier* Base = new BaseClassSpecifier ();
9841028 Base->access = ConvertToAccess (BS.getAccessSpecifier ());
9851029 Base->isVirtual = BS.isVirtual ();
9861030
9871031 auto BSTL = BS.getTypeSourceInfo ()->getTypeLoc ();
9881032 Base->type = WalkType (BS.getType (), &BSTL);
9891033
990- auto BaseDecl = GetCXXRecordDeclFromBaseType (BS.getType (). getTypePtr () );
1034+ auto BaseDecl = GetCXXRecordDeclFromBaseType (BS.getType ());
9911035 if (BaseDecl && Layout)
9921036 {
9931037 auto Offset = BS.isVirtual () ? Layout->getVBaseClassOffset (BaseDecl)
@@ -2784,7 +2828,7 @@ bool Parser::CanCheckCodeGenInfo(clang::Sema& S, const clang::Type* Ty)
27842828 return false ;
27852829
27862830 if (auto RT = FinalType->getAs <clang::RecordType>())
2787- return RT->getDecl ()-> getDefinition () != 0 ;
2831+ return HasLayout ( RT->getDecl ()) ;
27882832
27892833 // Lock in the MS inheritance model if we have a member pointer to a class,
27902834 // else we get an assertion error inside Clang's codegen machinery.
@@ -2985,7 +3029,7 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F,
29853029
29863030 const CXXMethodDecl* MD;
29873031 if ((MD = dyn_cast<CXXMethodDecl>(FD)) && !MD->isStatic () &&
2988- !CanCheckCodeGenInfo (c-> getSema (), MD->getThisType (c-> getASTContext ()). getTypePtr ( )))
3032+ !HasLayout (cast<CXXRecordDecl>( MD->getDeclContext () )))
29893033 return ;
29903034
29913035 if (!CanCheckCodeGenInfo (c->getSema (), FD->getReturnType ().getTypePtr ()))
0 commit comments