зеркало из https://github.com/microsoft/clang-1.git
Reapply r151702 with a small fix for a failure to cut and paste
correctly. Still rdar://10900684 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151838 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
88530d5e13
Коммит
ad8de5142a
|
@ -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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool IsMsStruct = record->hasAttr<MsStructAttr>();
|
||||
const FieldDecl *LastFD = 0;
|
||||
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;
|
||||
}
|
||||
LastFD = field;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
LastFD = field;
|
||||
|
||||
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);
|
||||
|
||||
elements.push_back(fieldType);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
elements.push_back(fieldType);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -g | FileCheck %s
|
||||
|
||||
auto var = [](int i) { return i+1; };
|
||||
|
||||
extern "C" auto cvar = []{};
|
||||
|
||||
int a() { return []{ return 1; }(); }
|
||||
|
||||
int b(int x) { return [x]{return x;}(); }
|
||||
|
||||
int c(int x) { return [&x]{return x;}(); }
|
||||
|
||||
struct D { D(); D(const D&); int x; };
|
||||
int d(int x) { D y[10]; [x,y] { return y[x].x; }(); }
|
||||
|
||||
|
||||
// A: 5
|
||||
// CHECK: [[A_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE:.*]], metadata !"a", metadata !"a", metadata !"_Z1av", metadata {{.*}}, i32 [[A_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @_Z1av, null, null, {{.*}} [ DW_TAG_subprogram ]
|
||||
|
||||
// Randomness for file. -- 6
|
||||
// CHECK: [[FILE]] = metadata !{i32 {{.*}}, metadata !{{.*}}debug-lambda-expressions.cpp{{.*}}; [ DW_TAG_file_type ]
|
||||
|
||||
// B: 12
|
||||
// CHECK: [[B_FUNC:.*]] = metadata !{i32 786478, i32 0, metadata [[FILE]], metadata !"b", metadata !"b", metadata !"_Z1bi", metadata [[FILE]], i32 [[B_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1bi, null, null, {{.*}} ; [ DW_TAG_subprogram ]
|
||||
|
||||
// C: 17
|
||||
// CHECK: [[C_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"c", metadata !"c", metadata !"_Z1ci", metadata [[FILE]], i32 [[C_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1ci, null, null, metadata {{.*}} ; [ DW_TAG_subprogram ]
|
||||
|
||||
// D: 20
|
||||
// CHECK: [[D_FUNC:.*]] = metadata !{i32 {{.*}}, i32 0, metadata [[FILE]], metadata !"d", metadata !"d", metadata !"_Z1di", metadata [[FILE]], i32 [[D_LINE:.*]], metadata {{.*}}, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @_Z1di, null, null, metadata {{.*}} ; [ DW_TAG_subprogram ]
|
||||
|
||||
// Back to D. -- 120
|
||||
// CHECK: [[LAM_D:.*]] = metadata !{i32 {{.*}}, metadata [[D_FUNC]], metadata !"", metadata [[FILE]], i32 [[D_LINE]], i64 352, i64 32, i32 0, i32 0, null, metadata [[LAM_D_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
|
||||
// CHECK: [[LAM_D_ARGS]] = metadata !{metadata [[CAP_D_X:.*]], metadata [[CAP_D_Y:.*]], metadata [[CON_LAM_D:.*]], metadata [[DES_LAM_D:.*]]}
|
||||
// CHECK: [[CAP_D_X]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"x", metadata [[FILE]], i32 14, i64 32, i64 32, i64 0, i32 1, metadata {{.*}} ; [ DW_TAG_member ]
|
||||
// CHECK: [[CAP_D_Y]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"y", metadata [[FILE]], i32 14, i64 320, i64 32, i64 32, i32 1, metadata {{.*}} ; [ DW_TAG_member ]
|
||||
// CHECK: [[CON_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
|
||||
// CHECK: [[DES_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ]
|
||||
|
||||
|
||||
// Back to C. -- 159
|
||||
// CHECK: [[LAM_C:.*]] = metadata !{i32 {{.*}}, metadata [[C_FUNC]], metadata !"", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i32 0, i32 0, null, metadata [[LAM_C_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
|
||||
// CHECK: [[LAM_C_ARGS]] = metadata !{metadata [[CAP_C:.*]], metadata [[CON_LAM_C:.*]], metadata [[DES_LAM_C:.*]]}
|
||||
// Ignoring the member type for now.
|
||||
// CHECK: [[CAP_C]] = metadata !{i32 {{.*}}, metadata [[LAM_C]], metadata !"x", metadata [[FILE]], i32 [[C_LINE]], i64 64, i64 64, i64 0, i32 1, metadata {{.*}}} ; [ DW_TAG_member ]
|
||||
// CHECK: [[CON_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
|
||||
// CHECK: [[DES_LAM_C]] = metadata {{.*}}[[LAM_C]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ]
|
||||
|
||||
|
||||
// Back to B. -- 179
|
||||
// CHECK: [[LAM_B:.*]] = metadata !{i32 {{.*}}, metadata [[B_FUNC]], metadata !"", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i32 0, i32 0, null, metadata [[LAM_B_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
|
||||
// CHECK: [[LAM_B_ARGS]] = metadata !{metadata [[CAP_B:.*]], metadata [[CON_LAM_B:.*]], metadata [[DES_LAM_B:.*]]}
|
||||
// CHECK: [[CAP_B]] = metadata !{i32 {{.*}}, metadata [[LAM_B]], metadata !"x", metadata [[FILE]], i32 [[B_LINE]], i64 32, i64 32, i64 0, i32 1, metadata {{.*}}} ; [ DW_TAG_member ]
|
||||
// CHECK: [[CON_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
|
||||
// CHECK: [[DES_LAM_B]] = metadata {{.*}}[[LAM_B]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ]
|
||||
|
||||
// Back to A. -- 204
|
||||
// CHECK: [[LAM_A:.*]] = metadata !{i32 {{.*}}, metadata [[A_FUNC]], metadata !"", metadata [[FILE]], i32 [[A_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata [[LAM_A_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
|
||||
// CHECK: [[LAM_A_ARGS]] = metadata !{metadata [[CON_LAM_A:.*]], metadata [[DES_LAM_A:.*]]}
|
||||
// CHECK: [[CON_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
|
||||
// CHECK: [[DES_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"~", metadata !"~"{{.*}}[ DW_TAG_subprogram ]
|
||||
|
||||
// VAR:
|
||||
// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"var", metadata !"var", metadata !"", metadata [[FILE]], i32 [[VAR_LINE:.*]], metadata ![[VAR_T:.*]], i32 1, i32 1, %class.anon* @var} ; [ DW_TAG_variable ]
|
||||
// CHECK: [[VAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[VAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[VAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
|
||||
// CHECK: [[VAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata !{{.*}}}
|
||||
|
||||
// CVAR:
|
||||
// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"cvar", metadata !"cvar", metadata !"", metadata [[FILE]], i32 [[CVAR_LINE:.*]], metadata ![[CVAR_T:.*]], i32 0, i32 1, %class.anon.0* @cvar} ; [ DW_TAG_variable ]
|
||||
// CHECK: [[CVAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[CVAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[CVAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
|
||||
// CHECK: [[CVAR_ARGS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata !{{.*}}}
|
Загрузка…
Ссылка в новой задаче