We want to use Survey123 to reverse geocode a point from a map question. This function works well using the ArcGIS World Geocoder except there is no option to retrieve certain address fields in a stand-alone fashion. Specifically, we want to parse street name and street type into separate fields, but the geocoder only returns the full address in the JSON response. How to do we just get the street name and street type? @JamesTedrick @Ismael
Subtrees are a great way to share a single tree across multiple projects using it in their own codebases. For many use-cases, they are a vastly superior alternative to submodules. Alas, there is no built-in equivalent to git submodule to help you properly manage subtrees.
Maintenance of git stree has stopped in favor of another third-party project: git-subrepo. It is actively maintained, much more robust, with more features, excellent test coverage and system integration, and more. It does cover all the actual use cases, and there's no point in plodding forward with git-stree now.
We'd like to take this opportunity to thank all the people who gave git-stree a spin, and contributed some of their time to feedback and possibly pull requests. But because this project is now deprecated and maintenance has stopped, pull requests won't be accepted anymore, and issues are closed. If you *really want to keep with it*, feel free to fork and make progress! Thanks a ton for using this so far.
The stree project is based on three fundamental premises. First:for an important class of development tasks (roughly: GUI programswritten in a relatively simple subset of C++, compiled at -O0-g), compilation time is dominated by the C++ front end. Second:the performance of the C++ front end is dominated by memory allocationand management. This includes memory allocation, initializing newlyallocated objects, and bookkeeping for garbage collection. Reducingfront end memory usage should thus improve front endperformance. Third: many programs consist of small source files thatinclude truly enormous header files. Such header filesinclude (25,000 lines),Apple's (91,000 lines), and the X11headers. Any given translation unit only uses a tiny fraction of thedeclarations in one of these headers.
The main idea of the stree project is to avoid generating decltrees when possible. Instead the parser will generate a compact flatrepresentation for declarations, called an stree, and expand the streeto a decl tree when necessary. Strees are not a substitute fortrees. The middle-end and back end will still understand trees, notstrees.
Consider the front end data structure for a simple enumerationdeclaration, enum foo a, b ;. We have two enumerators.For each one we need to know its name, its type, the underlying integertype used to represent it, and its value. At present we representenumerators with CONST_DECL nodes, so each enumerator takes128 bytes for the tree_decl node, plus additional memoryfor cp-tree.h's version of lang_decl.
Each enumerator has an entry in the hash table, an identifier. Eachidentifier has a pointer to a binding of type cxx_binding(this is the bindings field in lang_identifier, defined inname_lookup.h). The binding for foo itself points to a tree_type, and the bindings for aand bpoint to CONST_DECL nodes. Each CONST_DECL nodehas pointers to the name and to the ENUMERAL_TYPE node, andadditionally has a pointer to a node representing the enumerator'svalue. In simple examples like this one each enumerator's value isan INTEGER_CST, giving us another 36 byteseach. (An INTEGER_CST node contains a tree_commonsubobject, with all the generality that implies.)
We don't need 200 bytes to represent the fact that theenumerator a has the value 0. First: as an stree it'sunnecessary to store a pointer to the name of this enumerator. Thestree will only be accessed via a cxx_binding, so any codethat accesses the stree already knows the name. Second: it isn'tnecessary to use anything so large as an INTEGER_CST torepresent the value "0". Most of the information stored inan INTEGER_CST (chain nodes, type pointers, etc.) isunnecessary, since we already know we're getting to the value throughan enumerator. We only need to store two pieces of information: theenumeration that this enumerator is associated with, and its initialvalue. This allows us to represent the enumerator in six bytes: aone-byte code for the type of the stree (specifically:the TREE_CODE of the tree that this stree corresponds to),four bytes (a pointer or the equivalent) for the enumeration, and onebyte for the value. Note that this implies a variable-width encodingfor the integer values; some enumerations will require seven or morebytes.
Our current implementation is limited to enumerations defined atnamespace scope. First, enumerations defined at class scope requireadditional context information. Second, enumerators declared at classscope might have values that depend on template parameters, meaningthat we can't necessarily represent the values as simpleintegers. Neither is a serious problem. Becausea cxx_binding's value can be either a tree or stree, we canuse strees for the common, simple cases, and default to treesotherwise. Because strees are a variable-sized representation, we canadd additional values needed for building trees for the complex caseas needed without bloating the simpler cases.
Clientsaccess stree data via an iterator: given anstree with index s, the function get_s_tree_iter (declared instree.h) creates an iterator pointing to the beginningof s. Other functions declared in stree.h access theiterator to extract each serialized value in turn. This scheme allowsus to store data in the most compressed representation possible, andin a way such that clients are insulated from the details of therepresentation. For enumerators, for example, instead of using afull INTEGER_CST for each value, we can use one or two bytesin the (typical) case where the values are small.
Strees are created with build_s_tree, a varargs functiondefined in stree.c. Its first argument is the stree code, andits remaining arguments are the contents of that stree and tags toidentify their types. There is no function for creating an stree bytreating it as a "stream" to which values are written one at a time;eventually there probably will need to be one. It won't be hard to addit.
The files stree.h and stree.c arelanguage-independent, since, at bottom, strees are just a way ofpacking bytes and integers into chunks. Creation and expansion ofstrees are language dependent. The present implementation is focusedon C++.
We change cxx_binding::value fromtype tree to type s_tree_i_or_tree (atagged union), and we change IDENTIFIER_VALUE so that itreturns the tree value, expandingthe stree if necessary. A few changes are required in functions thatmanipulate cxx_binding directly, but those changes arelargely mechanical and are localizedto cp/name_lookup.[ch].
Strees are expanded by the s_tree_to_tree function,defined in cp/decl.c. There are three points to notice aboutit. First, as described above, it uses the stree iteratorinterface. Second, the first byte of the stree is the streecode; s_tree_to_tree uses that code to determine what kindof tree to create. Third, at present s_tree_to_tree doesn'thandle any cases other than enumerators.
The major changes required to use strees for enumerators arein build_enumerator. First, we need to separate parsing anderror checking from tree generation, deferring the latter untillater. Second, for simple cases we use build_s_tree to createthe stree and push_s_decl to enter the stree into the currentlexical scope. In principle push_s_decl would need to knowall of the same logic that pushdecl does; in practice we onlyuse push_s_decl for the simplest cases, deferringto pushdecl (i.e. using trees instead of strees) for the morecomplicated cases.
This design has the virtue that most of the C++ front end doesn'thave to know about strees: code that goes through bindings to get treeslooks exactly as before. It has the defect that, as presently written,it requires code duplication. The code required to generate anenumerator node is in both build_enumeratorand s_tree_to_tree. Additionally, s_tree_to_treeis manageable only because at the moment it only handles a singlecase. If this project succeeds, and we're handling many kinds ofstrees, it would become a monstrosity. The right solution willprobably be to replace s_tree_to_tree with a wrapper functionthat examines the stree code and dispatches to a function for theappropriate code, and, for each code, to write an implementationfunction that's shared between the tree and stree versions. Similarly,we can probably achieve better code sharing between pushdecland push_s_decl.
At present the compiler will not generate debugging information forunexpanded strees. This is potentially a serious issue. In principle,there are two ways of dealing with this issue: either figure out a wayto generate debugging information without expanding strees, or elsedecide that it's acceptable to omit debugging information for "unused"declarations. (Note that by "unused" we mean declarations that areirrelevant to the compilation of the code, rather than the weakerdefinition of "never executed". As soon as a declaration's name isseen elsewhere in the code, we create a decl tree node for thename.)
More importantly, some gcc versions already remove unneededdeclarations from debug information. GCC 3.4 does not generate DWARFdebug info for function declarations, and does not generate debug infofor unused types unless -fno-eliminate-unused-debug-types isspecified. Apple's gcc has stripped "unused" symbols out of STABSdebugging format for the last two and a half years. The debugger teamexpected many bugs from users trying to examine unused declarations,but have been surprised at how few bugs they've received. One of thefew complaints was from a user who had a "debug" version of a structthat was used only for pretty-printing the real structure, and wasstripped out because it was never actually referenced.
7fc3f7cf58