<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 1, 2014, at 10:32 AM, Adrian Prantl <<a href="mailto:aprantl@apple.com" class="">aprantl@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Dec 1, 2014, at 10:27 AM, Ben Langmuir <<a href="mailto:blangmuir@apple.com" class="">blangmuir@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Nov 25, 2014, at 5:25 PM, Adrian Prantl <<a href="mailto:aprantl@apple.com" class="">aprantl@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Nov 24, 2014, at 4:55 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" class="">richard@metafoo.co.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="gmail_extra"><div class="gmail_quote">On Fri, Nov 21, 2014 at 5:52 PM, Adrian Prantl<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:aprantl@apple.com" target="_blank" class="">aprantl@apple.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">Plans for module debugging<br class="">==========================<br class=""><br class="">I recently had a chat with Eric Christopher and David Blaikie to discuss ideas for debug info for Clang modules and this is what we came up with.<br class=""><br class="">Goals<br class="">-----<br class=""><br class="">Clang modules [1], (and their siblings C++ modules and precompiled header files) are a method for improving compile time by making the serialized AST for commonly-used headers files directly available to the compiler.<br class=""><br class="">Currently debug info is totally oblivious to this, when the developer compiles a file that uses a type from a module, clang simply emits a copy of the full definition (some exceptions apply for C++) of this type in DWARF into the debug info section of the resulting object file. That's a lot of copies.<br class=""><br class="">The key idea is to emit DWARF for types defined in modules only once, and then only emit references to these types in all the individual compile units that import this module. We are going to build on the split DWARF and type unit facilities provided by DWARF for this. DWARF consumers can follow the type references into module debug info section quite similar to how they resolve types in external type units today. Additionally, the format will allow consumers that support clang modules natively (such as LLDB) to directly look up types in the module, without having to go through the usual translation from AST to DWARF and back to AST.<br class=""><br class="">The primary benefit from doing all this is performance. This change is expected to reduce the size of the debug info in object files significantly by<br class="">- emitting only references to the full types and thus<br class="">- implicitly uniquing types that are defined in modules.<br class="">The smaller object files will result in faster compile times and faster llvm::Module load times when doing LTO. The type uniquing will also result in significantly smaller debug info for the finished executables, especially for C and Objective-C, which do not support ODR-based type uniquing. This comes at the price of longer initial module build times, as debug info is emitted alongside the module.<br class=""><br class="">Design<br class="">------<br class=""><br class="">Clang modules are designed to be ephemeral build artifacts that live in a shared module cache. Compiling a source file that imports `MyModule` results in `Module.pcm` to be generated to the module cache directory, which contains the serialized AST of the declarations found in the header files that comprise the module.<br class=""><br class="">We will change the binary clang module format to became a container (ELF, Mach-O, depending on the platform). Inside the container there will be multiple sections: one containing the serialized AST, and ones containing DWARF5 split debug type information for all types defined in the module that can be encoded in DWARF. By virtue of using type units, each type is emitted into its own type unit which can be identified via a unique type signature. DWARF consumers can use the type signatures to look up type definitions in the module debug info section. For module-aware consumers (LLDB), we will add an index that maps type signatures directly to an offset in the AST section.<br class=""><br class="">For an object file that was built using modules, we need to record the fact that a module has been imported. To this end, we add a DW_TAG_compile_unit into a COMDAT .debug_info.dwo section that references the split DWARF inside the module. Similar to split DWARF objects, the module will be identified by its filename and a checksum. The imported unit also contains a couple of extra attributes holding all the information necessary to recreate the module in case the module cache has been flushed.</blockquote><div class=""><br class=""></div><div class="">How does the debugging experience work in this case? When do you trigger the (possibly-lengthy) rebuild of the source in order to recreate the DWARF for the module (is it possible to delay that until the information is needed)?</div></div></div></div></div></blockquote><div class=""><br class=""></div><div class=""><div class="">The module debugging scenario is primarily aimed at providing a better/faster edit-compile-debug cycle. In this scenario, the module would most likely still be in the cache. In a case were the binary was build so long ago that the module cache has since been flushed it is generally more likely the the user also used a DWARF linking step (such as dsymutil on Darwin, and maybe dwz on Linux?) because they did a release/archive build which would just copy the DWARF out of the module and store it alongside the binary. For this reason I’m not very concerned about the time necessary for rebuilding the module. But this is all very platform-specific, and different platforms may need different defaults.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">This description is in terms of building a module that has gone missing, but just to be clear: a modules-aware debugger probably also needs to rebuild modules that have gone out of date, such as when one of their headers is modified.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">In this case were the module is out of date, the debugger should probably fall back to the DWARF types, because it cannot guarantee that the modifications to the header files did not change the types it wants to look up.</div></div></div></blockquote><div><br class=""></div><div>Are you also worried about this when the debugger builds a module that has gone missing?  At that point there is nothing to fall back to, and rebuilding the module could produce incorrect information.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""><div class="">Delaying the module DWARF output until needed (maybe even by the debugger!) is an interesting idea. We should definitely measure how expensive it is to emit DWARF for an entire module with of types to see if this is worthwhile.</div></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="gmail_extra"><div class="gmail_quote"><div class="">How much knowledge does the debugger have/need of Clang's modules to do this? Are we just embedding an arbitrary command that can be run to rebuild the .dwo if it's missing? And if so, how do we make that safe when (say) root attaches a debugger to an arbitrary process?</div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">I think it is reasonable to assume that a consumer that can make use of clang modules also knows how to rebuild clang modules, which is why the example only contained the name of the module, sysroot, include path, and defines; not an arbitrary command. On platforms were the debugger does not understand clang modules, the whole problem can be dodged by treating the modules as explicit build artifacts.</div></div></div></blockquote><div class=""><br class=""></div><div class="">You are probably already aware, but you will need a bunch more information (language options, target options, header search options) to rebuild a module.</div></div></div></div></blockquote><div class=""><br class=""></div>Thanks, language options and target options were absent from the list previously!</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">-- adrian<br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">Platforms that treat modules as an explicit build artifact do not have this problem. In the .debug_info section all types that are defined in the module are referenced via their unique type signature using DW_FORM_ref_sig8, just as they would be if this were types from a regular DWARF type unit.<br class=""><br class="">Example<br class="">-------<br class=""><br class="">Let's say we have a module `MyModule` that defines a type `MyStruct`::<br class=""> $ cat foo.c<br class=""> #include <MyModule.h><br class=""> MyStruct x;<br class=""><br class="">when compiling `foo.c` like this::<br class=""> clang -fmodules -gmodules foo.c -c<br class=""><br class="">clang produces `foo.o` and an ELF or Mach-O container for the module::<br class=""> /path/to/module-cache/MyModule.pcm<br class=""><br class="">In the module container, we have a section for the serialized AST and a split DWARF sections for the debug type info. The exact format is likely still going to evolve a little, but this should give a rough idea::<br class=""><br class=""> MyModule.pcm:<br class=""> <span class="Apple-converted-space"> </span>.debug_info.dwo:<br class="">   <span class="Apple-converted-space"> </span>DW_TAG_compile_unit<br class="">     <span class="Apple-converted-space"> </span>DW_AT_dwo_name ("/path/to/MyModule.pcm")<br class="">     <span class="Apple-converted-space"> </span>DW_AT_dwo_id   ([unique AST signature])<br class=""><br class="">   <span class="Apple-converted-space"> </span>DW_TAG_type_unit ([hash for MyStruct])<br class="">       DW_TAG_structure_type<br class="">         <span class="Apple-converted-space"> </span>DW_AT_signature ([hash for MyStruct])<br class="">         <span class="Apple-converted-space"> </span>DW_AT_name “MyStruct”<br class="">         <span class="Apple-converted-space"> </span>...<br class=""><br class=""> <span class="Apple-converted-space"> </span>.debug_abbrev.dwo:<br class="">   <span class="Apple-converted-space"> </span>// abbrevs referenced by .debug_info.dwo<br class=""> <span class="Apple-converted-space"> </span>.debug_line.dwo:<br class="">   <span class="Apple-converted-space"> </span>// filenames referenced by .debug_info.dwo<br class=""> <span class="Apple-converted-space"> </span>.debug_str.dwo:<br class="">   <span class="Apple-converted-space"> </span>// strings referenced by .debug_info.dwo<br class=""><br class=""> <span class="Apple-converted-space"> </span>.ast<br class="">   <span class="Apple-converted-space"> </span>// Index at the top of the AST section sorted by hash value.<br class="">   <span class="Apple-converted-space"> </span>[hash for MyStruct] -> [offset for MyStruct in this section]<br class="">   <span class="Apple-converted-space"> </span>...<br class="">   <span class="Apple-converted-space"> </span>// Serialized AST follows<br class="">   <span class="Apple-converted-space"> </span>...<br class=""><br class="">The debug info in foo.o will look like this::<br class=""><br class=""> .debug_info.dwo<br class="">   DW_TAG_compile_unit<br class="">     <span class="Apple-converted-space"> </span>// For DWARF consumers<br class="">     <span class="Apple-converted-space"> </span>DW_AT_dwo_name ("/path/to/module-cache/MyModule.pcm")<br class="">     <span class="Apple-converted-space"> </span>DW_AT_dwo_id   ([unique AST signature])<br class=""><br class="">     <span class="Apple-converted-space"> </span>// For LLDB / dsymutil so they can recreate the module<br class="">     <span class="Apple-converted-space"> </span>DW_AT_name “MyModule"<br class="">     <span class="Apple-converted-space"> </span>DW_AT_LLVM_system_root "/"<br class="">     <span class="Apple-converted-space"> </span>DW_AT_LLVM_preprocessor_defines  "-DNDEBUG"<br class="">     <span class="Apple-converted-space"> </span>DW_AT_LLVM_include_path "/path/to/MyModule.map"<br class=""><br class=""> .debug_info<br class="">   DW_TAG_compile_unit<br class="">     DW_TAG_variable<br class="">       DW_AT_name "x"<br class="">       DW_AT_type (DW_FORM_ref_sig8) ([hash for MyStruct])<br class=""><br class=""><br class="">Type signatures<br class="">---------------<br class=""><br class="">We are going to deviate from the DWARF spec by using a more efficient hashing function that uses the type's unique mangled name and the name of the module as input.</blockquote><div class=""><br class=""></div><div class="">Why do you need/want the name of the module here? Modules are not a namespacing mechanism. How would you compute this name when the same type is defined in multiple imported modules?</div></div></div></div></div></blockquote><div class=""><br class=""></div>Great point! I’m mostly concerned about non-ODR languages ...<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">For languages that do not have mangled type names or an ODR,</blockquote><div class=""><br class=""></div><div class="">The people working on C modules have expressed an intent to apply the ODR there too, so it's not clear that Clang modules will support any such language in the longer term.</div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">... and this may be the answer to the question!</div><div class=""><br class=""></div><div class="">+Doug: do Objective-C modules have an ODR?</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">we will use the unique identifiers produces by the clang indexer (USRs) as input instead.<br class=""><br class="">Extension: Replacing type units with a more efficient storage format<br class="">--------------------------------------------------------------------<br class=""><br class="">As an extension to this proposal, we are thinking of replacing the type units within the module debug info with a more efficient format: Instead of emitting each type into its own type unit (complete with its entire declcontext), it would be much more more efficient to emit one large bag of DWARF together with an index that maps hash values (type signatures) to DIE offsets.<br class=""><br class="">Next steps<br class="">----------<br class=""><br class="">In order to implement this, the next steps would be as follows:<br class="">1. Change the clang module format to be an ELF/Mach-O container.<br class="">2. Teach clang to emit debug info for module types (e.g., by passing an empty compile unit with retained types to LLVM) into the module container.<br class="">3a. Add a -gmodules switch to clang that triggers the emission of type signatures for types coming from a module.<br class=""></blockquote><div class=""><br class=""></div><div class="">Can you clarify what this flag would do? Does this turn on adding DWARF to the .pcm file? Does it turn off generating DWARF for imported modules in the current IR module? Both?</div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">It would emit references to the type from imported modules instead of the types themselves.</div><div class="">Since the module cache is shared, we could — depending on just expensive this is — turn on DWARF generation for .pcm files by default. I’d like to measure this first, though.</div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">I assume this means that the default remains that we build debug information for modules as if we didn't have modules (that is, put complete DWARF with the object code). Do you think that's the right long-term default? I think it's possibly not.</div></div></div></div></div></blockquote><div class=""><br class=""></div>I think you’re absolutely right about the long term. In the short term, it may be better to have compatibility by default, but I don’t know what the official LLVM policy on new features is, if there is one.</div></div></blockquote><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">How does this interact with explicit module builds? Can I use a module built without -g in a compile that uses -g? And if I do, do I get complete debug information, or debug info just for the parts that aren't in the module? Does -gmodules let me choose between these?</div></div></div></div></div></blockquote><div class=""><br class=""></div>Personally I would expect old-style (full copy of the types) debug information if I build agains a module that does not have embedded debug information.</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">thanks,</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">adrian<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">3b. Implement type-signature-based lookup in llvm-dsymutil and lldb.<br class="">4a. Emit an index that maps type signatures to AST section offsets into the module container.<br class="">4b. Implement direct loading of AST types in lldb.<br class="">5a. Improve the efficiency by replace type units in the module debug info with a lookup table that maps type signatures to DIE offsets.<br class="">5b. Support this format in lldb and llvm-dsymutil.<br class=""><br class="">Let me know what you think!<br class=""><br class="">cheers,<br class="">Adrian<br class=""><br class="">[1] For more details about clang modules see<br class=""><a href="http://clang.llvm.org/docs/Modules.html" target="_blank" class="">http://clang.llvm.org/docs/Modules.html</a><span class="Apple-converted-space"> </span>and<br class=""><a href="http://clang.llvm.org/docs/PCHInternals.html" target="_blank" class="">http://clang.llvm.org/docs/PCHInternals.html</a><br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-dev mailing list<br class=""><a href="mailto:cfe-dev@cs.uiuc.edu" class="">cfe-dev@cs.uiuc.edu</a><br class=""><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a></blockquote></div></div></div></div></blockquote></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">_______________________________________________</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">cfe-dev mailing list</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;"><a href="mailto:cfe-dev@cs.uiuc.edu" class="">cfe-dev@cs.uiuc.edu</a></span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;"><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" class="">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a></span></div></blockquote></div></div></div></blockquote></div></div></blockquote></div><br class=""></body></html>