@@ -30,14 +30,17 @@ extern const char *TestMainArgv0;
30
30
namespace {
31
31
32
32
const char *DwarfClang = " test-dwarf-clang.o" ;
33
+ // Two compile units: one declares `extern int foo_printf(const char *, ...);`
34
+ // and another one that defines the function.
35
+ const char *DwarfClangUnspecParams = " test-dwarf-clang-unspec-params.elf" ;
33
36
const char *DwarfGcc = " test-dwarf-gcc.o" ;
34
37
35
38
// Helper function to get the first compile unit.
36
39
LVScopeCompileUnit *getFirstCompileUnit (LVScopeRoot *Root) {
37
40
EXPECT_NE (Root, nullptr );
38
41
const LVScopes *CompileUnits = Root->getScopes ();
39
42
EXPECT_NE (CompileUnits, nullptr );
40
- EXPECT_EQ (CompileUnits->size (), 1u );
43
+ EXPECT_GT (CompileUnits->size (), 0u );
41
44
42
45
LVScopes::const_iterator Iter = CompileUnits->begin ();
43
46
EXPECT_NE (Iter, nullptr );
@@ -124,6 +127,36 @@ void checkElementProperties(LVReader *Reader) {
124
127
ASSERT_EQ (Lines->size (), 0x12u );
125
128
}
126
129
130
+ // Check proper handling of DW_AT_unspecified_parameters in
131
+ // LVScope::addMissingElements().
132
+ void checkUnspecifiedParameters (LVReader *Reader) {
133
+ LVScopeRoot *Root = Reader->getScopesRoot ();
134
+ LVScopeCompileUnit *CompileUnit = getFirstCompileUnit (Root);
135
+
136
+ EXPECT_EQ (Root->getFileFormatName (), " elf64-x86-64" );
137
+ EXPECT_EQ (Root->getName (), DwarfClangUnspecParams);
138
+
139
+ const LVPublicNames &PublicNames = CompileUnit->getPublicNames ();
140
+ ASSERT_EQ (PublicNames.size (), 1u );
141
+
142
+ LVPublicNames::const_iterator IterNames = PublicNames.cbegin ();
143
+ LVScope *Function = (*IterNames).first ;
144
+ EXPECT_EQ (Function->getName (), " foo_printf" );
145
+ const LVElements *Elements = Function->getChildren ();
146
+ ASSERT_NE (Elements, nullptr );
147
+ // foo_printf is a variadic function whose prototype is
148
+ // `int foo_printf(const char *, ...)`, where the '...' is represented by a
149
+ // DW_TAG_unspecified_parameters, i.e. we expect to find at least one child
150
+ // for which getIsUnspecified() returns true.
151
+ EXPECT_EQ (std::any_of (
152
+ Elements->begin (), Elements->end (),
153
+ [](const LVElement *elt) {
154
+ return elt->getIsSymbol () &&
155
+ static_cast <const LVSymbol *>(elt)->getIsUnspecified ();
156
+ }),
157
+ true );
158
+ }
159
+
127
160
// Check the logical elements selection.
128
161
void checkElementSelection (LVReader *Reader) {
129
162
LVScopeRoot *Root = Reader->getScopesRoot ();
@@ -253,6 +286,7 @@ void elementProperties(SmallString<128> &InputsDir) {
253
286
ReaderOptions.setAttributePublics ();
254
287
ReaderOptions.setAttributeRange ();
255
288
ReaderOptions.setAttributeLocation ();
289
+ ReaderOptions.setAttributeInserted ();
256
290
ReaderOptions.setPrintAll ();
257
291
ReaderOptions.resolveDependencies ();
258
292
@@ -264,6 +298,9 @@ void elementProperties(SmallString<128> &InputsDir) {
264
298
std::unique_ptr<LVReader> Reader =
265
299
createReader (ReaderHandler, InputsDir, DwarfClang);
266
300
checkElementProperties (Reader.get ());
301
+
302
+ Reader = createReader (ReaderHandler, InputsDir, DwarfClangUnspecParams);
303
+ checkUnspecifiedParameters (Reader.get ());
267
304
}
268
305
269
306
// Logical elements selection.
0 commit comments