@@ -644,8 +644,24 @@ llvm::DIDescriptor CGDebugInfo::createContextChain(const Decl *Context) {
644
644
645
645
if (const RecordDecl *RD = dyn_cast<RecordDecl>(Context)) {
646
646
if (!RD->isDependentType ()) {
647
- llvm::DIType Ty = getOrCreateLimitedType (
648
- CGM.getContext ().getRecordType (RD)->castAs <RecordType>(), getOrCreateMainFile ());
647
+ llvm::DICompositeType T (getTypeOrNull (CGM.getContext ().getRecordType (RD)));
648
+ llvm::DICompositeType Ty (getOrCreateLimitedType (
649
+ CGM.getContext ().getRecordType (RD)->castAs <RecordType>(),
650
+ getOrCreateMainFile ()));
651
+ if (!Ty.getTypeArray ().getNumElements ()) {
652
+ if (T) {
653
+ llvm::DIArray PrevMem = T.getTypeArray ();
654
+ unsigned NumElements = PrevMem.getNumElements ();
655
+ if (NumElements == 1 && !PrevMem.getElement (0 ))
656
+ NumElements = 0 ;
657
+ SmallVector<llvm::Value *, 16 > EltTys;
658
+ EltTys.reserve (NumElements);
659
+ for (unsigned i = 0 ; i != NumElements; ++i)
660
+ EltTys.push_back (PrevMem.getElement (i));
661
+ llvm::DIArray Elements = DBuilder.getOrCreateArray (EltTys);
662
+ Ty.setTypeArray (Elements);
663
+ }
664
+ }
649
665
return llvm::DIDescriptor (Ty);
650
666
}
651
667
}
@@ -865,7 +881,7 @@ CollectRecordLambdaFields(const CXXRecordDecl *CXXDecl,
865
881
}
866
882
}
867
883
868
- // / CollectRecordStaticField - Helper for CollectRecordFields.
884
+ // / Helper for CollectRecordFields.
869
885
llvm::DIDerivedType
870
886
CGDebugInfo::CreateRecordStaticField (const VarDecl *Var,
871
887
llvm::DIType RecordTy) {
@@ -948,7 +964,7 @@ void CGDebugInfo::CollectRecordFields(const RecordDecl *record,
948
964
for (RecordDecl::decl_iterator I = record->decls_begin (),
949
965
E = record->decls_end (); I != E; ++I)
950
966
if (const VarDecl *V = dyn_cast<VarDecl>(*I))
951
- elements.push_back (CreateRecordStaticField (V, RecordTy));
967
+ elements.push_back (getOrCreateStaticDataMemberDeclaration (V, RecordTy));
952
968
else if (FieldDecl *field = dyn_cast<FieldDecl>(*I)) {
953
969
CollectRecordNormalField (field, layout.getFieldOffset (fieldNo),
954
970
tunit, elements, RecordTy);
@@ -1123,8 +1139,14 @@ CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit,
1123
1139
if (D->isImplicit ())
1124
1140
continue ;
1125
1141
1126
- if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
1127
- EltTys.push_back (CreateCXXMemberFunction (Method, Unit, RecordTy));
1142
+ if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
1143
+ llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator MI =
1144
+ SPCache.find (Method->getCanonicalDecl ());
1145
+ if (MI == SPCache.end ())
1146
+ EltTys.push_back (CreateCXXMemberFunction (Method, Unit, RecordTy));
1147
+ else
1148
+ EltTys.push_back (MI->second );
1149
+ }
1128
1150
}
1129
1151
}
1130
1152
@@ -1408,10 +1430,20 @@ void CGDebugInfo::completeType(const RecordDecl *RD) {
1408
1430
}
1409
1431
1410
1432
void CGDebugInfo::completeRequiredType (const RecordDecl *RD) {
1433
+ if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
1434
+ if (CXXDecl->isDynamicClass ())
1435
+ return ;
1436
+
1411
1437
QualType Ty = CGM.getContext ().getRecordType (RD);
1412
1438
llvm::DIType T = getTypeOrNull (Ty);
1413
- if (!T || !T.isForwardDecl ())
1439
+ if (T && T.isForwardDecl ())
1440
+ completeClassData (RD);
1441
+ }
1442
+
1443
+ void CGDebugInfo::completeClassData (const RecordDecl *RD) {
1444
+ if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
1414
1445
return ;
1446
+ QualType Ty = CGM.getContext ().getRecordType (RD);
1415
1447
void * TyPtr = Ty.getAsOpaquePtr ();
1416
1448
if (CompletedTypeCache.count (TyPtr))
1417
1449
return ;
@@ -1424,14 +1456,23 @@ void CGDebugInfo::completeRequiredType(const RecordDecl *RD) {
1424
1456
// / CreateType - get structure or union type.
1425
1457
llvm::DIType CGDebugInfo::CreateType (const RecordType *Ty, bool Declaration) {
1426
1458
RecordDecl *RD = Ty->getDecl ();
1459
+ const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
1427
1460
// Limited debug info should only remove struct definitions that can
1428
1461
// safely be replaced by a forward declaration in the source code.
1429
- if (DebugKind <= CodeGenOptions::LimitedDebugInfo && Declaration &&
1430
- !RD->isCompleteDefinitionRequired () && CGM.getLangOpts ().CPlusPlus ) {
1462
+ if ((DebugKind <= CodeGenOptions::LimitedDebugInfo && Declaration &&
1463
+ !RD->isCompleteDefinitionRequired () && CGM.getLangOpts ().CPlusPlus ) ||
1464
+ (CXXDecl && CXXDecl->hasDefinition () && CXXDecl->isDynamicClass ())) {
1431
1465
llvm::DIDescriptor FDContext =
1432
1466
getContextDescriptor (cast<Decl>(RD->getDeclContext ()));
1433
1467
llvm::DIType RetTy = getOrCreateRecordFwdDecl (RD, FDContext);
1434
- return RetTy;
1468
+ // FIXME: This is conservatively correct. If we return a non-forward decl
1469
+ // that's not a full definition (such as those created by
1470
+ // createContextChain) then getOrCreateType will record is as a complete
1471
+ // type and we'll never record all its members. But this means we're
1472
+ // emitting full debug info in TUs where GCC successfully emits a partial
1473
+ // definition of the type.
1474
+ if (RetTy.isForwardDecl ())
1475
+ return RetTy;
1435
1476
}
1436
1477
1437
1478
return CreateTypeDefinition (Ty);
@@ -1469,6 +1510,7 @@ llvm::DIType CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
1469
1510
1470
1511
// Convert all the elements.
1471
1512
SmallVector<llvm::Value *, 16 > EltTys;
1513
+ // what about nested types?
1472
1514
1473
1515
// Note: The split of CXXDecl information here is intentional, the
1474
1516
// gdb tests will depend on a certain ordering at printout. The debug
@@ -2310,7 +2352,7 @@ llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) {
2310
2352
llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
2311
2353
MI = SPCache.find (FD->getCanonicalDecl ());
2312
2354
if (MI == SPCache.end ()) {
2313
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
2355
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD-> getCanonicalDecl () )) {
2314
2356
llvm::DICompositeType T (S);
2315
2357
llvm::DISubprogram SP = CreateCXXMemberFunction (MD, getOrCreateFile (MD->getLocation ()), T);
2316
2358
T.addMember (SP);
@@ -3025,19 +3067,35 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
3025
3067
DbgDecl->setDebugLoc (llvm::DebugLoc::get (line, column, scope));
3026
3068
}
3027
3069
3028
- // / getStaticDataMemberDeclaration - If D is an out-of-class definition of
3029
- // / a static data member of a class, find its corresponding in-class
3030
- // / declaration.
3031
- llvm::DIDerivedType CGDebugInfo::getStaticDataMemberDeclaration (const VarDecl *D) {
3032
- if (D->isStaticDataMember ()) {
3033
- llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator
3034
- MI = StaticDataMemberCache.find (D->getCanonicalDecl ());
3035
- if (MI != StaticDataMemberCache.end ())
3036
- // Verify the info still exists.
3037
- if (llvm::Value *V = MI->second )
3038
- return llvm::DIDerivedType (cast<llvm::MDNode>(V));
3070
+ // / If D is an out-of-class definition of a static data member of a class, find
3071
+ // / its corresponding in-class declaration.
3072
+ llvm::DIDerivedType
3073
+ CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull (const VarDecl *D) {
3074
+ if (!D->isStaticDataMember ())
3075
+ return llvm::DIDerivedType ();
3076
+ llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator MI =
3077
+ StaticDataMemberCache.find (D->getCanonicalDecl ());
3078
+ if (MI != StaticDataMemberCache.end ()) {
3079
+ assert (MI->second && " Static data member declaration should still exist" );
3080
+ return llvm::DIDerivedType (cast<llvm::MDNode>(MI->second ));
3081
+ }
3082
+ llvm::DICompositeType Ctxt (
3083
+ getContextDescriptor (cast<Decl>(D->getDeclContext ())));
3084
+ llvm::DIDerivedType T = CreateRecordStaticField (D, Ctxt);
3085
+ Ctxt.addMember (T);
3086
+ return T;
3087
+ }
3088
+
3089
+ llvm::DIDerivedType
3090
+ CGDebugInfo::getOrCreateStaticDataMemberDeclaration (const VarDecl *D,
3091
+ llvm::DICompositeType Ctxt) {
3092
+ llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator MI =
3093
+ StaticDataMemberCache.find (D->getCanonicalDecl ());
3094
+ if (MI != StaticDataMemberCache.end ()) {
3095
+ assert (MI->second && " Static data member declaration should still exist" );
3096
+ return llvm::DIDerivedType (cast<llvm::MDNode>(MI->second ));
3039
3097
}
3040
- return llvm::DIDerivedType ( );
3098
+ return CreateRecordStaticField (D, Ctxt );
3041
3099
}
3042
3100
3043
3101
// / EmitGlobalVariable - Emit information about a global variable.
@@ -3069,11 +3127,10 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
3069
3127
LinkageName = StringRef ();
3070
3128
llvm::DIDescriptor DContext =
3071
3129
getContextDescriptor (dyn_cast<Decl>(D->getDeclContext ()));
3072
- llvm::DIGlobalVariable GV =
3073
- DBuilder.createStaticVariable (DContext, DeclName, LinkageName, Unit,
3074
- LineNo, getOrCreateType (T, Unit),
3075
- Var->hasInternalLinkage (), Var,
3076
- getStaticDataMemberDeclaration (D));
3130
+ llvm::DIGlobalVariable GV = DBuilder.createStaticVariable (
3131
+ DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType (T, Unit),
3132
+ Var->hasInternalLinkage (), Var,
3133
+ getOrCreateStaticDataMemberDeclarationOrNull (D));
3077
3134
DeclCache.insert (std::make_pair (D->getCanonicalDecl (), llvm::WeakVH (GV)));
3078
3135
}
3079
3136
@@ -3121,7 +3178,7 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD,
3121
3178
return ;
3122
3179
llvm::DIGlobalVariable GV = DBuilder.createStaticVariable (
3123
3180
Unit, Name, Name, Unit, getLineNumber (VD->getLocation ()), Ty, true , Init,
3124
- getStaticDataMemberDeclaration (cast<VarDecl>(VD)));
3181
+ getOrCreateStaticDataMemberDeclarationOrNull (cast<VarDecl>(VD)));
3125
3182
DeclCache.insert (std::make_pair (VD->getCanonicalDecl (), llvm::WeakVH (GV)));
3126
3183
}
3127
3184
0 commit comments