 
 class GCField 
 {
-    function GCField(tag, attr) {
+    function GCField(tag, attr, _cond) {
         cls = getAttr(attr, 0);
         name = getAttr(attr, 1);
         ifdef = tag.match("_IFDEF") != null ? getAttr(attr,2) : false;
         ifndef = tag.match("_IFNDEF") != null ? getAttr(attr,2) : false;
         if_ = !ifdef && !ifndef && tag.match("_IF") != null ? getAttr(attr,2) : false;
+        cond = _cond;
     }
 
     public function toString() { return printProps(this, ["cls","name","ifdef", "if_"]) }

        if (s.if_) fieldname += "!if!" + s.if_;
        if (s.ifdef) fieldname += "!ifdef!" + s.ifdef;
        if (s.ifndef) fieldname += "!ifndef!" + s.ifndef;
        if (isVariableLength(s)) {
            // FIXME: It would be good to loosen the following restriction up; it 
            // would be sufficient to decree that only one of the arrays can be 

            // known-good index.  This yields the same performance as
            // using a global regex and setting lastIndex to indicate
            // where we want to start matching.

            if (cppIndex >= 0) {
                // CPP macro?
                //
                // There are two options for handling elif / else:
                //
                //  - break them out as separate #ifdefs by accumulating (and negating) conditions
                //  - preserve the elif / else structure
                //
                // I've gone with the former because it fits the structure of existing code, but
                // if the resulting condtions end up being messy, or it becomes unreliable for
                // any reason, then we should reconsider.  In practice most conditions are simple
                // and #if..elif chains are not long.  The main liability is that we sort field names
                // lexicographically so clauses may become reorganized on output; this does not lead
                // to bugs but makes the code confusing to read.

                if ((result = (/^#\s*(ifdef|ifndef|if|elif|else|endif|define)/).exec(line.substring(cppIndex))) != null) {
                    var rest = sanitizeCondition(line.substring(cppIndex + result[0].length));
                    var directive = result[1];
                    switch (directive) {
                    case "ifdef":
                        cppIfStack.push(new Condition(Condition.IFDEF, rest));
                        break;
                    case "ifndef":
                        cppIfStack.push(new Condition(Condition.IFNDEF, rest));
                        break;
                    case "define":
                        // This is a hack, but it's necessary: if this is a header file, and the top element 
                        // is #ifndef, and the condition for that element is the same name that is being 
                        // defined here, then we replace the top element with an inert element.  This takes
                        // care of the include-a-file-once idiom that would otherwise be hard to handle.
                        if (hfile && 
                            cppIfStack.length > 0 &&
                            rest == cppIfStack[cppIfStack.length-1].cond) {
                            cppIfStack.pop();
                            cppIfStack.push(new Condition(Condition.INERT, rest));
                        }
                        break;
                    case "if":
                        cppIfStack.push(new Condition(Condition.IF, rest));
                        break;
                    case "elif":
                        cppIfStack.length > 0 || fail("found #elif without matching #if, #ifdef, or #ifndef: " + line);
                        var top = cppIfStack.pop();
                        cppIfStack.push(new Condition(Condition.ELIF, rest, top));
                        break;
                    case "else": {
                        cppIfStack.length > 0 || fail("found #else without matching #if, #ifdef, or #ifndef: " + line);
                        var top = cppIfStack.pop();
                        cppIfStack.push(new Condition(Condition.ELSE, null, top));
                        break;
                    }
                    case "endif":
                        cppIfStack.length > 0 || fail("found #endif without matching #if, #ifdef, or #ifndef: " + line);
                        cppIfStack.pop();
                        break;
                    }
                }
            }

            if (gcIndex >= 0) {
                // C++ annotations.
