> -----Original Message----- > From: [email protected] [mailto:cfe-commits- > [email protected]] On Behalf Of David Blaikie > Sent: Tuesday, November 11, 2014 12:45 PM > To: [email protected] > Subject: r221704 - PR16091 continued: Debug Info for member functions with > undeduced return types. > > Author: dblaikie > Date: Tue Nov 11 14:44:45 2014 > New Revision: 221704 > > URL: http://llvm.org/viewvc/llvm-project?rev=221704&view=rev > Log: > PR16091 continued: Debug Info for member functions with undeduced return > types. > > So DWARF5 specs out auto deduced return types as DW_TAG_unspecified_type > with DW_AT_name "auto", and GCC implements this somewhat, but it > presents a few problems to do this with Clang. > > GCC's implementation only applies to member functions where the auto > return type isn't deduced immediately (ie: member functions of templates > or member functions defined out of line). In the common case of an > inline deduced return type function, GCC emits the DW_AT_type as the > deduced return type. > > Currently GDB doesn't seem to behave too well with this debug info - it > treats the return type as 'void', even though the definition of the > function has the correctly deduced return type (I guess it sees the > return type the declaration has, doesn't understand it, and assumes > void). This means the function's ABI might be broken (non-trivial return > types, etc), etc. > > Clang, on the other hand doesn't track this particular case of a > deducable return type that is deduced immediately versus one that is > deduced 'later'. So if we implement the DWARF5 representation, all > deducible return type functions would get adverse GDB behavior > (including deduced return type lambda functions, inline deduced return > type functions, etc). > > Also, we can't just do this for auto types that are not deduced - > because Clang marks even the declaration's return type as deduced (& > provides the underlying type) once a definition is seen that allows the > deduction. So we have to ignore even deduced types - but we can't do > that for auto variables (because this representation only applies to > function declarations - variables and function definitions need the real > type so the function can be called, etc) so we'd need to add an extra > flag to the type unwrapping/creation code to indicate when we want to > see through deduced types and when we don't. It's also not as simple as > just checking at the top level when building a function type (for one > thing, we reuse the function type building for building function pointer > types which might also have 'auto' in them - but be the type of a > variable instead) because the auto might be arbitrarily deeply nested > ("auto &", "auto (*)()", etc...) > > So, with all that said, let's do the simple thing that works in existing > debuggers for now and treat these functions the same way we do function > templates and implicit special members: omit them from the member list, > since they can't be correctly called anyway (without knowing the return > type the ABI isn't know and a function call could put the arguments in > the wrong place) so they're not much use to the user.
In summary: all auto-return-type functions are omitted from the class, whether or not the CU has a definition? That provides the consistency we need for type units and LTO deduplication. I see from the test that there's still metadata for the definition; where does that end up as far as the DWARF is concerned? --paulr > > At some point in the future, when GDB understands the DWARF5 > representation better it might be worth plumbing through the extra type > builder handling to avoid looking through AutoType for some callers, > etc... > > Modified: > cfe/trunk/lib/CodeGen/CGDebugInfo.cpp > cfe/trunk/test/CodeGenCXX/debug-info-cxx1y.cpp > > Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp > URL: http://llvm.org/viewvc/llvm- > project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=221704&r1=221703&r2=2217 > 04&view=diff > ========================================================================== > ==== > --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Nov 11 14:44:45 2014 > @@ -1175,6 +1175,10 @@ void CGDebugInfo::CollectCXXMemberFuncti > // referenced) > if (!Method || Method->isImplicit()) > continue; > + > + if (Method->getType()->getAs<FunctionProtoType>()- > >getContainedAutoType()) > + continue; > + > // Reuse the existing member function declaration if it exists. > // It may be associated with the declaration of the type & should be > // reused as we're building the definition. > @@ -2013,8 +2017,7 @@ static QualType UnwrapTypeForDebugInfo(Q > break; > case Type::Auto: > QualType DT = cast<AutoType>(T)->getDeducedType(); > - if (DT.isNull()) > - return T; > + assert(!DT.isNull() && "Undeduced types shouldn't reach here."); > T = DT; > break; > } > @@ -2106,8 +2109,6 @@ llvm::DIType CGDebugInfo::CreateTypeNode > if (Ty.hasLocalQualifiers()) > return CreateQualifiedType(Ty, Unit); > > - const char *Diag = nullptr; > - > // Work out details of type. > switch (Ty->getTypeClass()) { > #define TYPE(Class, Base) > @@ -2167,6 +2168,7 @@ llvm::DIType CGDebugInfo::CreateTypeNode > case Type::TemplateSpecialization: > return CreateType(cast<TemplateSpecializationType>(Ty), Unit); > > + case Type::Auto: > case Type::Attributed: > case Type::Elaborated: > case Type::Paren: > @@ -2176,18 +2178,10 @@ llvm::DIType CGDebugInfo::CreateTypeNode > case Type::Decltype: > case Type::UnaryTransform: > case Type::PackExpansion: > - llvm_unreachable("type should have been unwrapped!"); > - case Type::Auto: > - Diag = "auto"; > break; > } > > - assert(Diag && "Fall through without a diagnostic?"); > - unsigned DiagID = CGM.getDiags().getCustomDiagID( > - DiagnosticsEngine::Error, > - "debug information for %0 is not yet supported"); > - CGM.getDiags().Report(DiagID) << Diag; > - return llvm::DIType(); > + llvm_unreachable("type should have been unwrapped!"); > } > > /// getOrCreateLimitedType - Get the type from the cache or create a new > > Modified: cfe/trunk/test/CodeGenCXX/debug-info-cxx1y.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug- > info-cxx1y.cpp?rev=221704&r1=221703&r2=221704&view=diff > ========================================================================== > ==== > --- cfe/trunk/test/CodeGenCXX/debug-info-cxx1y.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/debug-info-cxx1y.cpp Tue Nov 11 14:44:45 > 2014 > @@ -1,7 +1,20 @@ > -// RUN: not %clang_cc1 -emit-llvm-only -std=c++1y -g %s 2>&1 | FileCheck > %s > +// RUN: %clang_cc1 -emit-llvm-only -std=c++14 -emit-llvm -g %s -o - | > FileCheck %s > + > +// CHECK: [[EMPTY:![0-9]*]] = metadata !{} > +// CHECK: \00foo\00{{.*}}, metadata [[EMPTY]], {{.*}}} ; [ > DW_TAG_structure_type ] > +// FIXME: The context of this definition should be the CU/file scope, not > the class. > +// CHECK: metadata !"_ZTS3foo", metadata [[SUBROUTINE_TYPE:![0-9]*]], > {{.*}}, metadata [[FUNC_DECL:![0-9]*]], metadata {{![0-9]*}}} ; [ > DW_TAG_subprogram ] {{.*}} [def] [func] > +// CHECK: [[SUBROUTINE_TYPE]] = {{.*}}, metadata [[TYPE_LIST:![0-9]*]], > +// CHECK: [[TYPE_LIST]] = metadata !{metadata [[INT:![0-9]*]]} > +// CHECK: [[INT]] = {{.*}} ; [ DW_TAG_base_type ] [int] > +// CHECK: [[FUNC_DECL]] = {{.*}}, metadata !"_ZTS3foo", metadata > [[SUBROUTINE_TYPE]], {{.*}}} ; [ DW_TAG_subprogram ] {{.*}} [func] > > struct foo { > - auto func(); // CHECK: error: debug information for auto is not yet > supported > + static auto func(); > }; > > foo f; > + > +auto foo::func() { > + return 1; > +} > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
