<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Thanks David for bringing that up.<div class=""><br class=""></div><div class="">FWIW, I think this is a totally reasonable approach and I am supportive of this.<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jan 16, 2018, at 9:21 AM, David Blaikie via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Context: I've been looking at experimenting with using Modular Code Generation (My talk at last year's LLVM dev meeting <a href="https://www.youtube.com/watch?v=lYYxDXgbUZ0" class="">https://www.youtube.com/watch?v=lYYxDXgbUZ0</a> is about the best reference at the moment) when building the LLVM project, as a good experiment for the feature. This can/does enforce a stronger layering invariant than LLVM has historically been enforced. So I'm curious to get buy-in and maybe document this if it's something people like the idea of.<br class=""><br class="">I'm starting this discussion here rather than in an actual code review on llvm-commits since it seems like it could do with a bit of a wider discussion, but once/if the general direction is agreed on, I'll send a patch for review of specific wording for the LLVM Coding Standards.<br class=""><br class=""><br class="">Currently the <a href="https://llvm.org/docs/CodingStandards.html" class="">LLVM Coding Standards</a> doesn't say much/anything about layering. <a href="https://llvm.org/docs/CodingStandards.html#a-public-header-file-is-a-module" class="">'A Public Header File <b class="">is</b> a Module'</a> section talks about modules of functionality, mostly trying to describe why a header file should be self contained - but uses anachronistic language about modules that doesn't line up with the implicit or explicit modules concepts in use today, I think.<br class=""><br class="">I propose making this wording a bit more explicit, including:<br class=""><br class="">1) Headers should be standalone (include all their dependencies - this is mentioned in the "is a Module" piece, by way of a technique to help ensure this, but not explicit as a goal itself).<br class=""><br class="">2) Files intended to be included in a particular context (that aren't safe/benign to include multiple times, in multiple .cpp files, etc) should use a '.inc' or '.def' (.def specifically for those "define a macro, include the header which will reference that macro" style setups we have in a few places).<br class=""><br class="">And the actual layering issue:<br class="">3) Each library should only include headers or otherwise reference entities from libraries it depends on. Including in headers and inline functions. A simple/explicit way to put this: every inline function should be able to be moved into a .cpp file and the build (with a unix linker - one that cannot handle circular library dependencies) should still succeed.<br class=""><br class=""><br class="">This last point is the most interesting - and I hope one that people generally find desirable, so it might not be immediately obvious why it may be contentious or difficult:<br class=""><br class="">LLVM violates this constraint by using inline functions in headers to avoid certain layering constraints that might otherwise cause the build to fail. A couple of major examples I've hit are:<br class=""><br class=""><a href="http://lists.llvm.org/pipermail/llvm-dev/2017-December/119494.html" class="">TargetSelect.h </a>and similar: This one's especially tricky - the header is part of libSupport, but each function in here depends on a different subset of targets (creating a circular dependency) - to call the given function the programmer needs to choose the right dependencies to link to or the program will not link.<br class=""><a href="https://reviews.llvm.org/D41357" class="">Clang Diagnostics</a> (work in progress): The diagnostics for each component are in their own component directories, but are then all included from libClangBasic, a library none of those components depends on. (so this isn't so much an inlining case as #include based circular dependency)<br class=""><br class=""><br class="">Generally I'd like to get buy-in that stricter layering is desirable, and that these few cases are at least sub-optimal, if accepted for now.<br class=""><br class="">Happy to go into more details about any of this, examples, etc, but I realize this is already a bit long.<br class="">- Dave</div>
_______________________________________________<br class="">LLVM Developers mailing list<br class=""><a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<br class=""></div></blockquote></div><br class=""></div></body></html>