diff options
author | Eric Christopher <echristo@apple.com> | 2012-02-29 03:25:30 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2012-02-29 03:25:30 +0000 |
commit | 0a0714ddd3a5bd1a8147735ae7fe20b8c4b656fa (patch) | |
tree | 17df4b3f56a2ddcf83dee09c5d679ec2095062e0 /lib/CodeGen/CGDebugInfo.cpp | |
parent | 441b3bb6eb3b43f5ad740d5cc6ad5c27823b6681 (diff) |
Add support for handling captured variables in lambda debug info.
This currently doesn't handle capturing the 'this' pointer for any
enclosing class.
Steal the lambda-expressions.cpp testcase and debugify it and try
to use more variables to proof it against random changes.
Part of rdar://10900684
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151702 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 91 |
1 files changed, 61 insertions, 30 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 1d27c19133..b381917d7b 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -749,44 +749,75 @@ CollectRecordFields(const RecordDecl *record, llvm::DIFile tunit, SmallVectorImpl<llvm::Value *> &elements, llvm::DIType RecordTy) { unsigned fieldNo = 0; - const FieldDecl *LastFD = 0; - bool IsMsStruct = record->hasAttr<MsStructAttr>(); - const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record); - for (RecordDecl::field_iterator I = record->field_begin(), - E = record->field_end(); - I != E; ++I, ++fieldNo) { - FieldDecl *field = *I; - if (IsMsStruct) { - // Zero-length bitfields following non-bitfield members are ignored - if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD)) { - --fieldNo; - continue; + const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(record); + + // For C++11 Lambdas a Fields will be the same as a Capture, but the Capture + // has the name and the location of the variable so we should iterate over + // both concurrently. + if (CXXDecl && CXXDecl->isLambda()) { + RecordDecl::field_iterator Field = CXXDecl->field_begin(); + unsigned fieldno = 0; + for (CXXRecordDecl::capture_const_iterator I = CXXDecl->captures_begin(), + E = CXXDecl->captures_end(); I != E; ++I, ++Field, ++fieldno) { + const LambdaExpr::Capture C = *I; + // TODO: Need to handle 'this' in some way by probably renaming the + // this of the lambda class and having a field member of 'this'. + if (C.capturesVariable()) { + VarDecl *V = C.getCapturedVar(); + llvm::DIFile VUnit = getOrCreateFile(C.getLocation()); + StringRef VName = V->getName(); + uint64_t SizeInBitsOverride = 0; + if (Field->isBitField()) { + SizeInBitsOverride = Field->getBitWidthValue(CGM.getContext()); + assert(SizeInBitsOverride && "found named 0-width bitfield"); + } + llvm::DIType fieldType + = createFieldType(VName, Field->getType(), SizeInBitsOverride, C.getLocation(), + Field->getAccess(), layout.getFieldOffset(fieldno), + VUnit, RecordTy); + elements.push_back(fieldType); } - LastFD = field; } + } else { + bool IsMsStruct = record->hasAttr<MsStructAttr>(); + for (RecordDecl::field_iterator I = record->field_begin(), + E = record->field_end(); + I != E; ++I, ++fieldNo) { + FieldDecl *field = *I; + const FieldDecl *LastFD = 0; + + if (IsMsStruct) { + // Zero-length bitfields following non-bitfield members are ignored + if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD)) { + --fieldNo; + continue; + } + LastFD = field; + } - StringRef name = field->getName(); - QualType type = field->getType(); + StringRef name = field->getName(); + QualType type = field->getType(); - // Ignore unnamed fields unless they're anonymous structs/unions. - if (name.empty() && !type->isRecordType()) { - LastFD = field; - continue; - } + // Ignore unnamed fields unless they're anonymous structs/unions. + if (name.empty() && !type->isRecordType()) { + LastFD = field; + continue; + } - uint64_t SizeInBitsOverride = 0; - if (field->isBitField()) { - SizeInBitsOverride = field->getBitWidthValue(CGM.getContext()); - assert(SizeInBitsOverride && "found named 0-width bitfield"); - } + uint64_t SizeInBitsOverride = 0; + if (field->isBitField()) { + SizeInBitsOverride = field->getBitWidthValue(CGM.getContext()); + assert(SizeInBitsOverride && "found named 0-width bitfield"); + } - llvm::DIType fieldType - = createFieldType(name, type, SizeInBitsOverride, - field->getLocation(), field->getAccess(), - layout.getFieldOffset(fieldNo), tunit, RecordTy); + llvm::DIType fieldType + = createFieldType(name, type, SizeInBitsOverride, + field->getLocation(), field->getAccess(), + layout.getFieldOffset(fieldNo), tunit, RecordTy); - elements.push_back(fieldType); + elements.push_back(fieldType); + } } } |