@@ -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 );
@@ -129,6 +132,36 @@ void checkElementProperties(LVReader *Reader) {
129
132
ASSERT_EQ (Lines->size (), 0x12u );
130
133
}
131
134
135
+ // Check proper handling of DW_AT_unspecified_parameters in
136
+ // LVScope::addMissingElements().
137
+ void checkUnspecifiedParameters (LVReader *Reader) {
138
+ LVScopeRoot *Root = Reader->getScopesRoot ();
139
+ LVScopeCompileUnit *CompileUnit = getFirstCompileUnit (Root);
140
+
141
+ EXPECT_EQ (Root->getFileFormatName (), " elf64-x86-64" );
142
+ EXPECT_EQ (Root->getName (), DwarfClangUnspecParams);
143
+
144
+ const LVPublicNames &PublicNames = CompileUnit->getPublicNames ();
145
+ ASSERT_EQ (PublicNames.size (), 1u );
146
+
147
+ LVPublicNames::const_iterator IterNames = PublicNames.cbegin ();
148
+ LVScope *Function = (*IterNames).first ;
149
+ EXPECT_EQ (Function->getName (), " foo_printf" );
150
+ const LVElements *Elements = Function->getChildren ();
151
+ ASSERT_NE (Elements, nullptr );
152
+ // foo_printf is a variadic function whose prototype is
153
+ // `int foo_printf(const char *, ...)`, where the '...' is represented by a
154
+ // DW_TAG_unspecified_parameters, i.e. we expect to find at least one child
155
+ // for which getIsUnspecified() returns true.
156
+ EXPECT_EQ (std::any_of (
157
+ Elements->begin (), Elements->end (),
158
+ [](const LVElement *elt) {
159
+ return elt->getIsSymbol () &&
160
+ static_cast <const LVSymbol *>(elt)->getIsUnspecified ();
161
+ }),
162
+ true );
163
+ }
164
+
132
165
// Check the logical elements selection.
133
166
void checkElementSelection (LVReader *Reader) {
134
167
LVScopeRoot *Root = Reader->getScopesRoot ();
@@ -258,6 +291,7 @@ void elementProperties(SmallString<128> &InputsDir) {
258
291
ReaderOptions.setAttributePublics ();
259
292
ReaderOptions.setAttributeRange ();
260
293
ReaderOptions.setAttributeLocation ();
294
+ ReaderOptions.setAttributeInserted ();
261
295
ReaderOptions.setPrintAll ();
262
296
ReaderOptions.resolveDependencies ();
263
297
@@ -269,6 +303,9 @@ void elementProperties(SmallString<128> &InputsDir) {
269
303
std::unique_ptr<LVReader> Reader =
270
304
createReader (ReaderHandler, InputsDir, DwarfClang);
271
305
checkElementProperties (Reader.get ());
306
+
307
+ Reader = createReader (ReaderHandler, InputsDir, DwarfClangUnspecParams);
308
+ checkUnspecifiedParameters (Reader.get ());
272
309
}
273
310
274
311
// Logical elements selection.
0 commit comments