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