<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 23, 2016 at 11:03 AM, Mehdi Amini <span dir="ltr"><<a href="mailto:mehdi.amini@apple.com" target="_blank">mehdi.amini@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class=""><blockquote type="cite"><div>On Feb 23, 2016, at 10:53 AM, Teresa Johnson <<a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a>> wrote:</div><br><div><div dir="ltr">Ok, after looking at the merged module Mehdi just sent me I think I know what is going on. Xalancbmk which helped me work out most of the kinks on this must not have hit this particular permutation.</div></div></blockquote><div><br></div></span><div>Great!</div><span class=""><br><blockquote type="cite"><div><div dir="ltr"><div><br></div><div>Looking at the first error from the list Mehdi sent earlier:</div><div><div>unresolved type ref</div><div>!"_ZTSN3JSC14ScopeLabelInfoE"</div><div>!121713 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTSN3JSC14ScopeLabelInfoE", size: 64, align: 64)</div></div><div><br></div><div>here is what we have and what I think is happening:</div><div><br></div><div><div>!121500 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "FunctionParsePhase", scope: !121501, file: !121486, line: 1305, size: 32, align: 32, flags: DIFlagFwdDecl, identifier: "_ZTSN3JSC6ParserINS_5LexerIhEEE18FunctionParsePhaseE")</div><div>!121501 = !DICompositeType(tag: DW_TAG_class_type, name: "Parser<JSC::Lexer<unsigned char> >", scope: !121464, file: !121486, line: 670, size: 18880, align: 64, elements: !121502, templateParams: !121762, identifier: "_ZTSN3JSC6ParserINS_5LexerIhEEEE")</div><div>!121502 = !{... !121710, ...}</div><div>!121710 = !DISubprogram(name: "getLabel", linkageName: "_ZN3JSC6ParserINS_5LexerIhEEE8getLabelEPKNS_10IdentifierE", scope: !"_ZTSN3JSC6ParserINS_5LexerIhEEEE", file: !121486, line: 1158, type: !121711, isLocal: false, isDefinition: false, scopeLine: 1158, flags: DIFlagPrototyped, isOptimized: true)</div><div>!121711 = !DISubroutineType(types: !121712)</div><div>!121712 = !{!121713, !121539, !23033}</div><div>!121713 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTSN3JSC14ScopeLabelInfoE", size: 64, align: 64)</div></div><div><br></div><div>The DIComposite declaration !121500 was referenced by identifier indirectly via a !tbaa attachment, presumably from a function that was imported, which is why it was correctly identified as needed, and it is in the retained types list.</div><div><br></div><div>Note that !121501 is the scope of !121500. Presumably !121501 and its descendants (all the stuff listed below it) were mapped in when we mapped the retained type !121500. </div></div></div></blockquote><div><br></div></span><div>Is it really needed to map all the methods and types for the class when we are interested in only one method from it?</div></div></div></blockquote><div><br></div><div>ish.<br><br>(+Adrian)<br><br>We do have a representation that works for a few special cases where partial representations of types are emitted. In many cases this doesn't work on Apple platforms due to tools (LLDB, some driver debug utilities/APIs) not being able to cope with some of these situations.<br><br>Here are some examples:<br><br>On all platforms, implicit special members, member function templates, and nested types are attached to their type scope lazily. But on MacOS this type scope is at least a full definition. It does mean that a debugger still needs to know that those certain kinds of members may be in one type DIE but not in another type DIE, and it may be necessary to search all type DIEs for those things.<br><br>On non-Apple platforms, we aggressively emit type declarations where we can assume that the definition will be available elsewhere (the "limited" or "non-standalone" debug info size optimizations - if a type is defined, but only used in ways that would require a declaration, we emit a declaration. If the type has a vtable, we only emit the type definition where the vtable is emitted (knowing the vtable must be emitted somewhere). If the type is the subject of an explicit instantiation declaration, we only emit the definition where we see the explicit instantiation definition).<br><br>This latter can produce the sort of debug info you're proposing - any member function defined in a translation unit where the type was determined to only need a debug info declaration, would produce a type declaration-with-partial member declaration list.<br><br>I don't know if we propagate the necessary flags to make this determination in the backend so we could decide whether partial types were a good idea or not.<br><br>- Dave</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><span class="HOEnZb"><font color="#888888"><div><br></div><div>-- </div><div>Mehdi</div></font></span><div><div class="h5"><div><br></div><div><br></div><br><blockquote type="cite"><div><div dir="ltr"><div>This ultimately brought in the derived type !121713, which references _ZTSN3JSC14ScopeLabelInfoE. However, at this time we have already decided which retained types to bring in, and presumably that is why we miss it.</div><div><br></div><div>To fix this I'll need to restructure things a bit to do the mapping earlier, and iteratively catch any newly-required retained types. Need to think about the best way to do this...I found the corresponding declarations in <a href="https://github.com/WebKit/webkit/blob/master/Source/JavaScriptCore/parser/Parser.h" target="_blank">https://github.com/WebKit/webkit/blob/master/Source/JavaScriptCore/parser/Parser.h</a> and will try to create a small test case from it as well.</div><div><br></div><div>Thanks,</div><div>Teresa</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 23, 2016 at 9:22 AM, Teresa Johnson <span dir="ltr"><<a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span>On Tue, Feb 23, 2016 at 9:12 AM, Mehdi Amini <span dir="ltr"><<a href="mailto:mehdi.amini@apple.com" target="_blank">mehdi.amini@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>I think in the error output I sent, I noticed the issue seemed to happen on DIDerivedType metadata that have a "baseType". </div></div></blockquote><div><br></div></span><div>That's not really different than the below example, where the types were also reached via a DIDerivedType baseType. If we mapped in the DIDerivedType we should have mapped in the reached type identifier. </div><div><div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><span><font color="#888888"><div><br></div><div>-- </div><div>Mehdi</div></font></span><div><div><br><div><blockquote type="cite"><div>On Feb 23, 2016, at 6:59 AM, Teresa Johnson <<a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a>> wrote:</div><br><div><div dir="ltr">Both of these cases work fine. The types are in fact DICompositeType, and are reached via the DISubroutineType for the imported function. E.g. for your second example:<div><br></div><div><div>struct foo { };</div><div>struct bar { };</div><div>void f(foo (*)(bar)) {</div><div>}</div></div><div><br></div><div>The original module looks like:</div><div><br></div><div><div>!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 1, size: 8, align: 8, flags: DIFlagFwdDecl, identifier: "_ZTS3foo")</div><div>!5 = !DICompositeType(tag: DW_TAG_structure_type, name: "bar", file: !1, line: 2, size: 8, align: 8, flags: DIFlagFwdDecl, identifier: "_ZTS3bar")</div></div><div>...</div><div><div>!7 = distinct !DISubprogram(name: "f", linkageName: "_Z1fPF3foo3barE", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, variables: !13)</div><div>!8 = !DISubroutineType(types: !9)</div><div>!9 = !{null, !10}</div><div>!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64, align: 64)</div><div>!11 = !DISubroutineType(types: !12)</div><div>!12 = !{!"_ZTS3foo", !"_ZTS3bar"}</div></div><div><br></div><div>Because they are reached via the imported function's DISubprogram, they get imported properly.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 22, 2016 at 11:21 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Yeah - I figured you would've caught it already if it were this simple. What sort of testing have you done?<br><br>Happy to go through a few things with you in person tomorrow as well. Perhaps I'm just not understanding the algorithm you're implementing here.</div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 22, 2016 at 9:09 PM, Teresa Johnson <span dir="ltr"><<a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span>On Mon, Feb 22, 2016 at 8:03 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Have either of you tried creating a simple test case? Naively it looks like any use of a pointer-to-user-defined type would hit this in some way, no?<br><br>import this function:<br><br>struct foo { };<br>void bar(foo *f) { <br>}<br><br>and I think the code will look at the type of 'f', getCompositeTypeToImport will immediately return null, because 'f' isn't a DICompositeType, and the type won't be retained.<br><br>Note that the type could be worse, it could involve importing more than one type:<br><br>struct foo { };<br>struct bar { };<br>void f(foo (*)(bar)) {<br>}<br></div><div class="gmail_extra"><br></div></blockquote><div><br></div></span><div>Hadn't tried that because I wasn't sure what to look for to be honest (especially since my testing is all fine at this point). Will give that a try to see how it behaves.</div><div><div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_extra"><div class="gmail_quote"><div><div>On Mon, Feb 22, 2016 at 7:39 PM, Teresa Johnson via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div dir="ltr">Unfortunately without seeing how the types were referenced in the original module I may not be able to deduce why they weren't pulled in. But go ahead and send me the IR after importing in the meantime and I will see what I can figure out.<div><br></div></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 22, 2016 at 6:02 PM, Mehdi Amini <span dir="ltr"><<a href="mailto:mehdi.amini@apple.com" target="_blank">mehdi.amini@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Unfortunately IIRC it involved 800 files, and I don't have them. I need to reproduce and it'll take some time. I can send you the IR *after* importing (the broken module) if it can help (not sure).<span><font color="#888888"><div><br></div><div>-- </div><div>Mehdi</div></font></span><div><div><div><br></div><div><br></div><div><br><div><div><blockquote type="cite"><div>On Feb 22, 2016, at 5:52 PM, Teresa Johnson <<a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a>> wrote:</div><br><div><div dir="ltr">Can you give me a test case to reproduce, or at least the IR for the module we're importing from (where these presumably came from) and which function(s) were imported?<div><br></div><div>Thanks,</div><div>Teresa</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 22, 2016 at 5:37 PM, Mehdi Amini <span dir="ltr"><<a href="mailto:mehdi.amini@apple.com" target="_blank">mehdi.amini@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">We still have an issue with this patch, when compiling this with thinlto and debug info: <a href="https://github.com/adobe/webkit/blob/master/Source/WebCore/inspector/InspectorRuntimeAgent.cpp" rel="noreferrer" target="_blank">https://github.com/adobe/webkit/blob/master/Source/WebCore/inspector/InspectorRuntimeAgent.cpp</a><br>
<br>
I haven't had time to narrow it unfortunately, it seems that "baseType" for some DIDerivedType entries are not present.<br>
What we see is a broken LLVM Module straight after the FunctionImporter. The output looks like this:<br>
<br>
unresolved type ref<br>
!"_ZTSN3JSC14ScopeLabelInfoE"<br>
!121713 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTSN3JSC14ScopeLabelInfoE", size: 64, align: 64)<br>
unresolved type ref<br>
!"_ZTSN3JSC15DeclarationTypeE"<br>
!121577 = !DISubroutineType(types: !121578)<br>
unresolved type ref<br>
!"_ZTSN3JSC17AssignmentContextE"<br>
!121580 = !DISubroutineType(types: !121581)<br>
unresolved type ref<br>
!"_ZTSN3JSC17DestructuringKindE"<br>
!121577 = !DISubroutineType(types: !121578)<br>
unresolved type ref<br>
!"_ZTSN3JSC21DeclarationImportTypeE"<br>
!121606 = !DISubroutineType(types: !121607)<br>
unresolved type ref<br>
!"_ZTSN3JSC23SourceProviderCacheItemE"<br>
!121621 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !"_ZTSN3JSC23SourceProviderCacheItemE")<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerIhEEE10LexerStateE"<br>
!121743 = !DISubroutineType(types: !121744)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerIhEEE15AutoPopScopeRefE"<br>
!121600 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !"_ZTSN3JSC6ParserINS_5LexerIhEEE15AutoPopScopeRefE", size: 64, align: 64)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerIhEEE20ExpressionErrorClassE"<br>
!121571 = !DISubroutineType(types: !121572)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerIhEEE23AutoCleanupLexicalScopeE"<br>
!121604 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !"_ZTSN3JSC6ParserINS_5LexerIhEEE23AutoCleanupLexicalScopeE", size: 64, align: 64)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerIhEEE25ExpressionErrorClassifierE"<br>
!121535 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTSN3JSC6ParserINS_5LexerIhEEE25ExpressionErrorClassifierE", size: 64, align: 64)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerIhEEE9SavePointE"<br>
!121751 = !DISubroutineType(types: !121752)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerItEEE10LexerStateE"<br>
!122000 = !DISubroutineType(types: !122001)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerItEEE15AutoPopScopeRefE"<br>
!121866 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !"_ZTSN3JSC6ParserINS_5LexerItEEE15AutoPopScopeRefE", size: 64, align: 64)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerItEEE20ExpressionErrorClassE"<br>
!121838 = !DISubroutineType(types: !121839)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerItEEE23AutoCleanupLexicalScopeE"<br>
!121870 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !"_ZTSN3JSC6ParserINS_5LexerItEEE23AutoCleanupLexicalScopeE", size: 64, align: 64)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerItEEE25ExpressionErrorClassifierE"<br>
!121803 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTSN3JSC6ParserINS_5LexerItEEE25ExpressionErrorClassifierE", size: 64, align: 64)<br>
unresolved type ref<br>
!"_ZTSN3JSC6ParserINS_5LexerItEEE9SavePointE"<br>
!122008 = !DISubroutineType(types: !122009)<br>
unresolved type ref<br>
!"_ZTSN3JSC9ScopeNodeE"<br>
!121635 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTSN3JSC9ScopeNodeE", size: 64, align: 64)<br>
<br>
<br>
--<br>
Mehdi<br>
<div><div><br>
<br>
> On Feb 22, 2016, at 2:20 PM, Teresa Johnson <<a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a>> wrote:<br>
><br>
> tejohnson updated this revision to Diff 48732.<br>
> tejohnson added a comment.<br>
><br>
> Handle a null MD passed to MapMetadata to address problem reported by<br>
> ahatanak.<br>
><br>
><br>
> <a href="http://reviews.llvm.org/D16440" rel="noreferrer" target="_blank">http://reviews.llvm.org/D16440</a><br>
><br>
> Files:<br>
>  include/llvm/Linker/IRMover.h<br>
>  lib/Linker/IRMover.cpp<br>
>  lib/Linker/LinkModules.cpp<br>
>  lib/Transforms/Utils/ValueMapper.cpp<br>
>  test/Linker/thinlto_funcimport_debug.ll<br>
>  test/Transforms/FunctionImport/Inputs/funcimport_debug.ll<br>
>  test/Transforms/FunctionImport/funcimport_debug.ll<br>
><br>
</div></div>> <D16440.48732.patch><br>
<br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div><span style="font-family:Times;font-size:inherit"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top-style:solid;border-top-color:rgb(213,15,37);border-top-width:2px">Teresa Johnson |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(51,105,232);border-top-width:2px"> Software Engineer |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(0,153,57);border-top-width:2px"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(238,178,17);border-top-width:2px"> <a href="tel:408-460-2413" value="+14084602413" target="_blank">408-460-2413</a></td></tr></tbody></table></span></div>
</div>
</div></blockquote></div><br></div></div></div></div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div><span style="font-family:Times;font-size:inherit"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top-style:solid;border-top-color:rgb(213,15,37);border-top-width:2px">Teresa Johnson |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(51,105,232);border-top-width:2px"> Software Engineer |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(0,153,57);border-top-width:2px"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(238,178,17);border-top-width:2px"> <a href="tel:408-460-2413" value="+14084602413" target="_blank">408-460-2413</a></td></tr></tbody></table></span></div>
</div>
</div></div><br></div></div><span>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
<br></span></blockquote></div><br></div>
</blockquote></div></div></div><div><div><br><br clear="all"><div><br></div>-- <br><div><span style="font-family:Times;font-size:inherit"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top-style:solid;border-top-color:rgb(213,15,37);border-top-width:2px">Teresa Johnson |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(51,105,232);border-top-width:2px"> Software Engineer |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(0,153,57);border-top-width:2px"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(238,178,17);border-top-width:2px"> <a href="tel:408-460-2413" value="+14084602413" target="_blank">408-460-2413</a></td></tr></tbody></table></span></div>
</div></div></div></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div><span style="font-family:Times;font-size:inherit"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top-style:solid;border-top-color:rgb(213,15,37);border-top-width:2px">Teresa Johnson |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(51,105,232);border-top-width:2px"> Software Engineer |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(0,153,57);border-top-width:2px"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(238,178,17);border-top-width:2px"> <a href="tel:408-460-2413" value="+14084602413" target="_blank">408-460-2413</a></td></tr></tbody></table></span></div>
</div>
</div></blockquote></div><br></div></div></div></blockquote></div></div></div><div><div><br><br clear="all"><div><br></div>-- <br><div><span style="font-family:Times;font-size:inherit"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top-style:solid;border-top-color:rgb(213,15,37);border-top-width:2px">Teresa Johnson |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(51,105,232);border-top-width:2px"> Software Engineer |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(0,153,57);border-top-width:2px"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(238,178,17);border-top-width:2px"> <a href="tel:408-460-2413" value="+14084602413" target="_blank">408-460-2413</a></td></tr></tbody></table></span></div>
</div></div></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div><span style="font-family:Times;font-size:inherit"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top-style:solid;border-top-color:rgb(213,15,37);border-top-width:2px">Teresa Johnson |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(51,105,232);border-top-width:2px"> Software Engineer |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(0,153,57);border-top-width:2px"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(238,178,17);border-top-width:2px"> <a href="tel:408-460-2413" value="+14084602413" target="_blank">408-460-2413</a></td></tr></tbody></table></span></div>
</div>
</div></blockquote></div></div></div><br></div></blockquote></div><br></div></div>