|
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,61 @@ 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 if (Capture.capturesVariable()) { |
| 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()); |
| 1953 | + } else { |
| 1954 | + continue; |
1945 | 1955 | } |
| 1956 | + |
| 1957 | + llvm::DIFile *VUnit = getOrCreateFile(Loc); |
| 1958 | + |
| 1959 | + elements.push_back(createFieldType( |
| 1960 | + GetLambdaCaptureName(Capture), Field->getType(), Loc, |
| 1961 | + Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl)); |
1946 | 1962 | } |
1947 | 1963 | } |
1948 | 1964 |
|
|
0 commit comments