@@ -30,14 +30,17 @@ extern const char *TestMainArgv0;
3030namespace {
3131
3232const 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" ;
3336const char *DwarfGcc = " test-dwarf-gcc.o" ;
3437
3538// Helper function to get the first compile unit.
3639LVScopeCompileUnit *getFirstCompileUnit (LVScopeRoot *Root) {
3740 EXPECT_NE (Root, nullptr );
3841 const LVScopes *CompileUnits = Root->getScopes ();
3942 EXPECT_NE (CompileUnits, nullptr );
40- EXPECT_EQ (CompileUnits->size (), 1u );
43+ EXPECT_GT (CompileUnits->size (), 0u );
4144
4245 LVScopes::const_iterator Iter = CompileUnits->begin ();
4346 EXPECT_NE (Iter, nullptr );
@@ -124,6 +127,36 @@ void checkElementProperties(LVReader *Reader) {
124127 ASSERT_EQ (Lines->size (), 0x12u );
125128}
126129
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+
127160// Check the logical elements selection.
128161void checkElementSelection (LVReader *Reader) {
129162 LVScopeRoot *Root = Reader->getScopesRoot ();
@@ -253,6 +286,7 @@ void elementProperties(SmallString<128> &InputsDir) {
253286 ReaderOptions.setAttributePublics ();
254287 ReaderOptions.setAttributeRange ();
255288 ReaderOptions.setAttributeLocation ();
289+ ReaderOptions.setAttributeInserted ();
256290 ReaderOptions.setPrintAll ();
257291 ReaderOptions.resolveDependencies ();
258292
@@ -264,6 +298,9 @@ void elementProperties(SmallString<128> &InputsDir) {
264298 std::unique_ptr<LVReader> Reader =
265299 createReader (ReaderHandler, InputsDir, DwarfClang);
266300 checkElementProperties (Reader.get ());
301+
302+ Reader = createReader (ReaderHandler, InputsDir, DwarfClangUnspecParams);
303+ checkUnspecifiedParameters (Reader.get ());
267304}
268305
269306// Logical elements selection.
0 commit comments