|
26 | 26 | #include "clang/AST/DeclObjC.h"
|
27 | 27 | #include "clang/AST/DeclTemplate.h"
|
28 | 28 | #include "clang/AST/Expr.h"
|
| 29 | +#include "clang/AST/LambdaCapture.h" |
29 | 30 | #include "clang/AST/RecordLayout.h"
|
30 | 31 | #include "clang/AST/RecursiveASTVisitor.h"
|
31 | 32 | #include "clang/AST/VTableBuilder.h"
|
@@ -1903,46 +1904,59 @@ CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
|
1903 | 1904 | return SP;
|
1904 | 1905 | }
|
1905 | 1906 |
|
| 1907 | +llvm::StringRef |
| 1908 | +CGDebugInfo::GetLambdaCaptureName(const LambdaCapture &Capture) { |
| 1909 | + if (Capture.capturesThis()) |
| 1910 | + return CGM.getCodeGenOpts().EmitCodeView ? "__this" : "this"; |
| 1911 | + |
| 1912 | + assert(Capture.capturesVariable()); |
| 1913 | + |
| 1914 | + const ValueDecl *CaptureDecl = Capture.getCapturedVar(); |
| 1915 | + assert(CaptureDecl && "Expected valid decl for captured variable."); |
| 1916 | + |
| 1917 | + return CaptureDecl->getName(); |
| 1918 | +} |
| 1919 | + |
1906 | 1920 | void CGDebugInfo::CollectRecordLambdaFields(
|
1907 | 1921 | const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
|
1908 | 1922 | llvm::DIType *RecordTy) {
|
1909 | 1923 | // For C++11 Lambdas a Field will be the same as a Capture, but the Capture
|
1910 | 1924 | // has the name and the location of the variable so we should iterate over
|
1911 | 1925 | // both concurrently.
|
1912 |
| - const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(CXXDecl); |
1913 | 1926 | RecordDecl::field_iterator Field = CXXDecl->field_begin();
|
1914 | 1927 | unsigned fieldno = 0;
|
1915 | 1928 | for (CXXRecordDecl::capture_const_iterator I = CXXDecl->captures_begin(),
|
1916 | 1929 | E = CXXDecl->captures_end();
|
1917 | 1930 | I != E; ++I, ++Field, ++fieldno) {
|
1918 |
| - const LambdaCapture &C = *I; |
1919 |
| - if (C.capturesVariable()) { |
1920 |
| - SourceLocation Loc = C.getLocation(); |
1921 |
| - assert(!Field->isBitField() && "lambdas don't have bitfield members!"); |
1922 |
| - ValueDecl *V = C.getCapturedVar(); |
1923 |
| - StringRef VName = V->getName(); |
1924 |
| - llvm::DIFile *VUnit = getOrCreateFile(Loc); |
1925 |
| - auto Align = getDeclAlignIfRequired(V, CGM.getContext()); |
1926 |
| - llvm::DIType *FieldType = createFieldType( |
1927 |
| - VName, Field->getType(), Loc, Field->getAccess(), |
1928 |
| - layout.getFieldOffset(fieldno), Align, VUnit, RecordTy, CXXDecl); |
1929 |
| - elements.push_back(FieldType); |
1930 |
| - } else if (C.capturesThis()) { |
| 1931 | + const LambdaCapture &Capture = *I; |
| 1932 | + const uint64_t FieldOffset = |
| 1933 | + CGM.getContext().getASTRecordLayout(CXXDecl).getFieldOffset(fieldno); |
| 1934 | + |
| 1935 | + assert(!Field->isBitField() && "lambdas don't have bitfield members!"); |
| 1936 | + |
| 1937 | + SourceLocation Loc; |
| 1938 | + uint32_t Align = 0; |
| 1939 | + |
| 1940 | + if (Capture.capturesThis()) { |
1931 | 1941 | // TODO: Need to handle 'this' in some way by probably renaming the
|
1932 | 1942 | // this of the lambda class and having a field member of 'this' or
|
1933 | 1943 | // by using AT_object_pointer for the function and having that be
|
1934 | 1944 | // used as 'this' for semantic references.
|
1935 |
| - FieldDecl *f = *Field; |
1936 |
| - llvm::DIFile *VUnit = getOrCreateFile(f->getLocation()); |
1937 |
| - QualType type = f->getType(); |
1938 |
| - StringRef ThisName = |
1939 |
| - CGM.getCodeGenOpts().EmitCodeView ? "__this" : "this"; |
1940 |
| - llvm::DIType *fieldType = createFieldType( |
1941 |
| - ThisName, type, f->getLocation(), f->getAccess(), |
1942 |
| - layout.getFieldOffset(fieldno), VUnit, RecordTy, CXXDecl); |
1943 |
| - |
1944 |
| - elements.push_back(fieldType); |
| 1945 | + Loc = Field->getLocation(); |
| 1946 | + } else { |
| 1947 | + Loc = Capture.getLocation(); |
| 1948 | + |
| 1949 | + const ValueDecl *CaptureDecl = Capture.getCapturedVar(); |
| 1950 | + assert(CaptureDecl && "Expected valid decl for captured variable."); |
| 1951 | + |
| 1952 | + Align = getDeclAlignIfRequired(CaptureDecl, CGM.getContext()); |
1945 | 1953 | }
|
| 1954 | + |
| 1955 | + llvm::DIFile *VUnit = getOrCreateFile(Loc); |
| 1956 | + |
| 1957 | + elements.push_back(createFieldType( |
| 1958 | + GetLambdaCaptureName(Capture), Field->getType(), Loc, |
| 1959 | + Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl)); |
1946 | 1960 | }
|
1947 | 1961 | }
|
1948 | 1962 |
|
|
0 commit comments