]> git.saurik.com Git - bison.git/blame - src/conflicts.c
Merge remote-tracking branch 'origin/maint'
[bison.git] / src / conflicts.c
CommitLineData
742e4900 1/* Find and resolve or report lookahead conflicts for bison,
f041e30b 2
7d6bad19 3 Copyright (C) 1984, 1989, 1992, 2000-2013 Free Software Foundation,
575619af 4 Inc.
08089d5d 5
ceed8467 6 This file is part of Bison, the GNU Compiler Compiler.
08089d5d 7
f16b0819
PE
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
08089d5d 12
f16b0819
PE
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
08089d5d 17
ceed8467 18 You should have received a copy of the GNU General Public License
f16b0819 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
08089d5d 20
2cec9080 21#include <config.h>
08089d5d 22#include "system.h"
f041e30b
PE
23
24#include <bitset.h>
25
26#include "LR0.h"
7da99ede 27#include "complain.h"
f041e30b 28#include "conflicts.h"
08089d5d 29#include "files.h"
f041e30b 30#include "getargs.h"
08089d5d 31#include "gram.h"
720d742f 32#include "lalr.h"
41d7a5f2 33#include "print-xml.h"
b2ca4022 34#include "reader.h"
f041e30b
PE
35#include "state.h"
36#include "symtab.h"
d2729d44 37
7da99ede 38/* -1 stands for not specified. */
d6328241
PH
39int expected_sr_conflicts = -1;
40int expected_rr_conflicts = -1;
da2a7671 41static char *conflicts;
d6b771c3 42static struct obstack solved_conflicts_obstack;
41d7a5f2 43static struct obstack solved_conflicts_xml_obstack;
08089d5d 44
8dd162d3 45static bitset shift_set;
742e4900 46static bitset lookahead_set;
b408954b 47
c29240e7 48\f
08089d5d 49
f041e30b 50enum conflict_resolution
b408954b
AD
51 {
52 shift_resolution,
53 reduce_resolution,
54 left_resolution,
55 right_resolution,
86eff183 56 nonassoc_resolution
b408954b
AD
57 };
58
59
9801d40c
AD
60/*----------------------------------------------------------------.
61| Explain how an SR conflict between TOKEN and RULE was resolved: |
62| RESOLUTION. |
63`----------------------------------------------------------------*/
64
c29240e7 65static inline void
f041e30b 66log_resolution (rule *r, symbol_number token,
e9690142 67 enum conflict_resolution resolution)
08089d5d 68{
b408954b
AD
69 if (report_flag & report_solved_conflicts)
70 {
71 /* The description of the resolution. */
72 switch (resolution)
e9690142
JD
73 {
74 case shift_resolution:
75 case right_resolution:
cb9ec4fa 76 obstack_printf (&solved_conflicts_obstack,
e9690142
JD
77 _(" Conflict between rule %d and token %s"
78 " resolved as shift"),
79 r->number,
80 symbols[token]->tag);
81 break;
82
83 case reduce_resolution:
84 case left_resolution:
cb9ec4fa 85 obstack_printf (&solved_conflicts_obstack,
e9690142
JD
86 _(" Conflict between rule %d and token %s"
87 " resolved as reduce"),
88 r->number,
89 symbols[token]->tag);
90 break;
91
92 case nonassoc_resolution:
cb9ec4fa 93 obstack_printf (&solved_conflicts_obstack,
e9690142
JD
94 _(" Conflict between rule %d and token %s"
95 " resolved as an error"),
96 r->number,
97 symbols[token]->tag);
98 break;
99 }
b408954b
AD
100
101 /* The reason. */
102 switch (resolution)
e9690142
JD
103 {
104 case shift_resolution:
cb9ec4fa 105 obstack_printf (&solved_conflicts_obstack,
e9690142
JD
106 " (%s < %s)",
107 r->prec->tag,
108 symbols[token]->tag);
109 break;
110
111 case reduce_resolution:
cb9ec4fa 112 obstack_printf (&solved_conflicts_obstack,
e9690142
JD
113 " (%s < %s)",
114 symbols[token]->tag,
115 r->prec->tag);
116 break;
117
118 case left_resolution:
cb9ec4fa 119 obstack_printf (&solved_conflicts_obstack,
e9690142
JD
120 " (%%left %s)",
121 symbols[token]->tag);
122 break;
123
124 case right_resolution:
cb9ec4fa 125 obstack_printf (&solved_conflicts_obstack,
e9690142
JD
126 " (%%right %s)",
127 symbols[token]->tag);
128 break;
129
130 case nonassoc_resolution:
cb9ec4fa 131 obstack_printf (&solved_conflicts_obstack,
e9690142
JD
132 " (%%nonassoc %s)",
133 symbols[token]->tag);
134 break;
135 }
41d7a5f2 136
b408954b 137 obstack_sgrow (&solved_conflicts_obstack, ".\n");
ef1b4273 138 }
41d7a5f2 139
ef1b4273
JD
140 /* XML report */
141 if (xml_flag)
142 {
143 /* The description of the resolution. */
144 switch (resolution)
145 {
146 case shift_resolution:
147 case right_resolution:
aaf63e45 148 obstack_printf (&solved_conflicts_xml_obstack,
ef1b4273
JD
149 " <resolution rule=\"%d\" symbol=\"%s\""
150 " type=\"shift\">",
151 r->number,
152 xml_escape (symbols[token]->tag));
153 break;
154
155 case reduce_resolution:
156 case left_resolution:
aaf63e45 157 obstack_printf (&solved_conflicts_xml_obstack,
ef1b4273
JD
158 " <resolution rule=\"%d\" symbol=\"%s\""
159 " type=\"reduce\">",
160 r->number,
161 xml_escape (symbols[token]->tag));
162 break;
163
164 case nonassoc_resolution:
aaf63e45 165 obstack_printf (&solved_conflicts_xml_obstack,
ef1b4273
JD
166 " <resolution rule=\"%d\" symbol=\"%s\""
167 " type=\"error\">",
168 r->number,
169 xml_escape (symbols[token]->tag));
170 break;
171 }
41d7a5f2 172
ef1b4273
JD
173 /* The reason. */
174 switch (resolution)
175 {
176 case shift_resolution:
aaf63e45 177 obstack_printf (&solved_conflicts_xml_obstack,
ef1b4273
JD
178 "%s &lt; %s",
179 xml_escape_n (0, r->prec->tag),
180 xml_escape_n (1, symbols[token]->tag));
181 break;
182
183 case reduce_resolution:
aaf63e45 184 obstack_printf (&solved_conflicts_xml_obstack,
ef1b4273
JD
185 "%s &lt; %s",
186 xml_escape_n (0, symbols[token]->tag),
187 xml_escape_n (1, r->prec->tag));
188 break;
189
190 case left_resolution:
aaf63e45 191 obstack_printf (&solved_conflicts_xml_obstack,
ef1b4273
JD
192 "%%left %s",
193 xml_escape (symbols[token]->tag));
194 break;
195
196 case right_resolution:
aaf63e45 197 obstack_printf (&solved_conflicts_xml_obstack,
ef1b4273
JD
198 "%%right %s",
199 xml_escape (symbols[token]->tag));
200 break;
201
202 case nonassoc_resolution:
aaf63e45 203 obstack_printf (&solved_conflicts_xml_obstack,
ef1b4273
JD
204 "%%nonassoc %s",
205 xml_escape (symbols[token]->tag));
206 break;
207 }
208
209 obstack_sgrow (&solved_conflicts_xml_obstack, "</resolution>\n");
b408954b 210 }
08089d5d
DM
211}
212
213
c29240e7
AD
214/*------------------------------------------------------------------.
215| Turn off the shift recorded for the specified token in the |
216| specified state. Used when we resolve a shift-reduce conflict in |
9d774aff 217| favor of the reduction or as an error (%nonassoc). |
c29240e7
AD
218`------------------------------------------------------------------*/
219
4a120d45 220static void
f041e30b 221flush_shift (state *s, int token)
08089d5d 222{
f041e30b 223 transitions *trans = s->transitions;
9f136c07 224 int i;
c29240e7 225
742e4900 226 bitset_reset (lookahead_set, token);
f041e30b
PE
227 for (i = 0; i < trans->num; i++)
228 if (!TRANSITION_IS_DISABLED (trans, i)
e9690142 229 && TRANSITION_SYMBOL (trans, i) == token)
f041e30b 230 TRANSITION_DISABLE (trans, i);
08089d5d
DM
231}
232
233
8dd162d3 234/*--------------------------------------------------------------------.
9d774aff
JD
235| Turn off the reduce recorded for the specified token in the |
236| specified lookahead set. Used when we resolve a shift-reduce |
237| conflict in favor of the shift or as an error (%nonassoc). |
8dd162d3 238`--------------------------------------------------------------------*/
709ae8c6
AD
239
240static void
742e4900 241flush_reduce (bitset lookahead_tokens, int token)
709ae8c6 242{
742e4900 243 bitset_reset (lookahead_tokens, token);
709ae8c6
AD
244}
245
246
c29240e7
AD
247/*------------------------------------------------------------------.
248| Attempt to resolve shift-reduce conflict for one rule by means of |
249| precedence declarations. It has already been checked that the |
250| rule has a precedence. A conflict is resolved by modifying the |
251| shift or reduce tables so that there is no longer a conflict. |
9801d40c 252| |
742e4900 253| RULENO is the number of the lookahead bitset to consider. |
8b752b00 254| |
9d774aff
JD
255| ERRORS and NERRS can be used to store discovered explicit |
256| errors. |
c29240e7 257`------------------------------------------------------------------*/
08089d5d 258
4a120d45 259static void
9d774aff 260resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
08089d5d 261{
f041e30b
PE
262 symbol_number i;
263 reductions *reds = s->reductions;
9801d40c 264 /* Find the rule to reduce by to get precedence of reduction. */
f041e30b 265 rule *redrule = reds->rules[ruleno];
9801d40c 266 int redprec = redrule->prec->prec;
742e4900 267 bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
08089d5d 268
08089d5d 269 for (i = 0; i < ntokens; i++)
742e4900 270 if (bitset_test (lookahead_tokens, i)
e9690142
JD
271 && bitset_test (lookahead_set, i)
272 && symbols[i]->prec)
92b16366 273 {
e9690142
JD
274 /* Shift-reduce conflict occurs for token number i
275 and it has a precedence.
276 The precedence of shifting is that of token i. */
277 if (symbols[i]->prec < redprec)
278 {
284bc49c 279 register_precedence (redrule->prec->number, i);
e9690142
JD
280 log_resolution (redrule, i, reduce_resolution);
281 flush_shift (s, i);
282 }
283 else if (symbols[i]->prec > redprec)
284 {
284bc49c 285 register_precedence (i, redrule->prec->number);
e9690142
JD
286 log_resolution (redrule, i, shift_resolution);
287 flush_reduce (lookahead_tokens, i);
288 }
289 else
d78f0ac9
AD
290 /* Matching precedence levels.
291 For non-defined associativity, keep both: unexpected
292 associativity conflict.
293 For left associativity, keep only the reduction.
294 For right associativity, keep only the shift.
295 For nonassociativity, keep neither. */
709ae8c6 296
e9690142
JD
297 switch (symbols[i]->assoc)
298 {
d78f0ac9 299 case undef_assoc:
e9690142 300 abort ();
68cae94e 301
d78f0ac9
AD
302 case precedence_assoc:
303 break;
304
e9690142 305 case right_assoc:
e8f7155d 306 register_assoc (i, redrule->prec->number);
e9690142
JD
307 log_resolution (redrule, i, right_resolution);
308 flush_reduce (lookahead_tokens, i);
309 break;
310
311 case left_assoc:
e8f7155d 312 register_assoc (i, redrule->prec->number);
e9690142
JD
313 log_resolution (redrule, i, left_resolution);
314 flush_shift (s, i);
315 break;
316
317 case non_assoc:
e8f7155d 318 register_assoc (i, redrule->prec->number);
e9690142
JD
319 log_resolution (redrule, i, nonassoc_resolution);
320 flush_shift (s, i);
321 flush_reduce (lookahead_tokens, i);
322 /* Record an explicit error for this token. */
323 errors[(*nerrs)++] = symbols[i];
324 break;
325 }
92b16366 326 }
08089d5d
DM
327}
328
329
8b752b00 330/*-------------------------------------------------------------------.
f041e30b 331| Solve the S/R conflicts of state S using the |
8b752b00 332| precedence/associativity, and flag it inconsistent if it still has |
f041e30b 333| conflicts. ERRORS can be used as storage to compute the list of |
742e4900 334| lookahead tokens on which S raises a syntax error (%nonassoc). |
8b752b00
AD
335`-------------------------------------------------------------------*/
336
4a120d45 337static void
f041e30b 338set_conflicts (state *s, symbol **errors)
08089d5d 339{
914feea9 340 int i;
f041e30b
PE
341 transitions *trans = s->transitions;
342 reductions *reds = s->reductions;
9d774aff 343 int nerrs = 0;
c29240e7 344
f041e30b 345 if (s->consistent)
c29240e7 346 return;
08089d5d 347
742e4900 348 bitset_zero (lookahead_set);
08089d5d 349
f041e30b 350 FOR_EACH_SHIFT (trans, i)
742e4900 351 bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
08089d5d 352
742e4900 353 /* Loop over all rules which require lookahead in this state. First
c29240e7 354 check for shift-reduce conflict, and try to resolve using
9801d40c 355 precedence. */
cd08e51e
AD
356 for (i = 0; i < reds->num; ++i)
357 if (reds->rules[i]->prec && reds->rules[i]->prec->prec
e9690142 358 && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
9d774aff
JD
359 resolve_sr_conflict (s, i, errors, &nerrs);
360
361 if (nerrs)
362 {
363 /* Some tokens have been explicitly made errors. Allocate a
364 permanent errs structure for this state, to record them. */
365 state_errs_set (s, nerrs, errors);
366 }
367 if (obstack_object_size (&solved_conflicts_obstack))
6fbe73b6 368 s->solved_conflicts = obstack_finish0 (&solved_conflicts_obstack);
41d7a5f2 369 if (obstack_object_size (&solved_conflicts_xml_obstack))
6fbe73b6 370 s->solved_conflicts_xml = obstack_finish0 (&solved_conflicts_xml_obstack);
08089d5d 371
742e4900 372 /* Loop over all rules which require lookahead in this state. Check
c29240e7 373 for conflicts not resolved above. */
cd08e51e 374 for (i = 0; i < reds->num; ++i)
08089d5d 375 {
742e4900 376 if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
e9690142 377 conflicts[s->number] = 1;
742e4900 378 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
c29240e7
AD
379 }
380}
08089d5d 381
8b752b00
AD
382
383/*----------------------------------------------------------------.
384| Solve all the S/R conflicts using the precedence/associativity, |
385| and flag as inconsistent the states that still have conflicts. |
386`----------------------------------------------------------------*/
387
08089d5d 388void
b408954b 389conflicts_solve (void)
08089d5d 390{
f041e30b 391 state_number i;
742e4900 392 /* List of lookahead tokens on which we explicitly raise a syntax error. */
da2a7671 393 symbol **errors = xnmalloc (ntokens + 1, sizeof *errors);
08089d5d 394
da2a7671 395 conflicts = xcalloc (nstates, sizeof *conflicts);
8dd162d3 396 shift_set = bitset_create (ntokens, BITSET_FIXED);
742e4900 397 lookahead_set = bitset_create (ntokens, BITSET_FIXED);
b408954b 398 obstack_init (&solved_conflicts_obstack);
41d7a5f2 399 obstack_init (&solved_conflicts_xml_obstack);
08089d5d 400
c29240e7 401 for (i = 0; i < nstates; i++)
8b752b00 402 {
f041e30b 403 set_conflicts (states[i], errors);
8b752b00
AD
404
405 /* For uniformity of the code, make sure all the states have a valid
45eebca4 406 'errs' member. */
8b752b00 407 if (!states[i]->errs)
e9690142 408 states[i]->errs = errs_new (0, 0);
8b752b00
AD
409 }
410
f041e30b 411 free (errors);
08089d5d
DM
412}
413
414
5967f0cf
JD
415void
416conflicts_update_state_numbers (state_number old_to_new[],
417 state_number nstates_old)
418{
14462c2b
JD
419 state_number i;
420 for (i = 0; i < nstates_old; ++i)
5967f0cf
JD
421 if (old_to_new[i] != nstates_old)
422 conflicts[old_to_new[i]] = conflicts[i];
423}
424
425
c29240e7
AD
426/*---------------------------------------------.
427| Count the number of shift/reduce conflicts. |
428`---------------------------------------------*/
429
6c094ad0
AD
430static size_t
431count_state_sr_conflicts (state *s)
08089d5d 432{
f9abaa2c 433 int i;
f041e30b
PE
434 transitions *trans = s->transitions;
435 reductions *reds = s->reductions;
08089d5d 436
f041e30b 437 if (!trans)
0df87bb6 438 return 0;
08089d5d 439
742e4900 440 bitset_zero (lookahead_set);
8dd162d3 441 bitset_zero (shift_set);
08089d5d 442
f041e30b 443 FOR_EACH_SHIFT (trans, i)
8dd162d3 444 bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
08089d5d 445
cd08e51e 446 for (i = 0; i < reds->num; ++i)
742e4900 447 bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
08089d5d 448
742e4900 449 bitset_and (lookahead_set, lookahead_set, shift_set);
08089d5d 450
6c094ad0
AD
451 return bitset_count (lookahead_set);
452}
0df87bb6 453
6c094ad0
AD
454/*---------------------------------------------.
455| The total number of shift/reduce conflicts. |
456`---------------------------------------------*/
457
458static size_t
459count_sr_conflicts (void)
460{
461 size_t res = 0;
462 state_number i;
463
464 /* Conflicts by state. */
465 for (i = 0; i < nstates; i++)
466 if (conflicts[i])
467 res += count_state_sr_conflicts (states[i]);
468 return res;
08089d5d
DM
469}
470
471
6c094ad0 472
676385e2
PH
473/*----------------------------------------------------------------.
474| Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
475| count one conflict for each token that has any reduce/reduce |
476| conflicts. Otherwise, count one conflict for each pair of |
477| conflicting reductions. |
6c094ad0 478`----------------------------------------------------------------*/
c29240e7 479
6c094ad0
AD
480static size_t
481count_state_rr_conflicts (state *s, bool one_per_token)
08089d5d 482{
c29240e7 483 int i;
f041e30b 484 reductions *reds = s->reductions;
6c094ad0 485 size_t res = 0;
08089d5d 486
08089d5d
DM
487 for (i = 0; i < ntokens; i++)
488 {
0df87bb6
AD
489 int count = 0;
490 int j;
cd08e51e 491 for (j = 0; j < reds->num; ++j)
6c094ad0 492 count += bitset_test (reds->lookahead_tokens[j], i);
c29240e7 493 if (count >= 2)
6c094ad0 494 res += one_per_token ? 1 : count-1;
08089d5d 495 }
0df87bb6 496
6c094ad0 497 return res;
08089d5d
DM
498}
499
6c094ad0
AD
500static size_t
501count_rr_conflicts (bool one_per_token)
502{
503 size_t res = 0;
504 state_number i;
505
506 /* Conflicts by state. */
507 for (i = 0; i < nstates; i++)
508 if (conflicts[i])
509 res += count_state_rr_conflicts (states[i], one_per_token);
510 return res;
511}
52489d44 512
52489d44 513
0df87bb6
AD
514/*-----------------------------------------------------------.
515| Output the detailed description of states with conflicts. |
516`-----------------------------------------------------------*/
c29240e7
AD
517
518void
0df87bb6 519conflicts_output (FILE *out)
c29240e7 520{
8307162d 521 bool printed_sth = false;
f041e30b 522 state_number i;
0df87bb6 523 for (i = 0; i < nstates; i++)
640748ee 524 {
f041e30b 525 state *s = states[i];
640748ee 526 if (conflicts[i])
e9690142 527 {
d87ea54c
AD
528 int src = count_state_sr_conflicts (s);
529 int rrc = count_state_rr_conflicts (s, true);
e9690142 530 fprintf (out, _("State %d "), i);
d87ea54c
AD
531 if (src && rrc)
532 fprintf (out,
533 _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
534 src, rrc);
535 else if (src)
536 fprintf (out, _("conflicts: %d shift/reduce\n"), src);
537 else if (rrc)
538 fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc);
e9690142
JD
539 printed_sth = true;
540 }
640748ee 541 }
d2d1b42b
AD
542 if (printed_sth)
543 fputs ("\n\n", out);
0df87bb6 544}
c29240e7 545
676385e2
PH
546/*--------------------------------------------------------.
547| Total the number of S/R and R/R conflicts. Unlike the |
548| code in conflicts_output, however, count EACH pair of |
742e4900 549| reductions for the same state and lookahead as one |
e9690142 550| conflict. |
676385e2
PH
551`--------------------------------------------------------*/
552
553int
554conflicts_total_count (void)
555{
6c094ad0 556 return count_sr_conflicts () + count_rr_conflicts (false);
676385e2 557}
e0e5bf84 558
c29240e7 559
0df87bb6
AD
560/*------------------------------------------.
561| Reporting the total number of conflicts. |
562`------------------------------------------*/
0619caf0 563
0df87bb6
AD
564void
565conflicts_print (void)
566{
d1400569 567 if (! glr_parser && expected_rr_conflicts != -1)
d6328241 568 {
bb8e56ff 569 complain (NULL, Wother, _("%%expect-rr applies only to GLR parsers"));
d6328241
PH
570 expected_rr_conflicts = -1;
571 }
572
d87ea54c
AD
573 /* Screams for factoring, but almost useless because of the
574 different strings to translate. */
575 {
576 int total = count_sr_conflicts ();
c5ae8e85 577 /* If %expect is not used, but %expect-rr is, then expect 0 sr. */
d87ea54c
AD
578 int expected =
579 (expected_sr_conflicts == -1 && expected_rr_conflicts != -1)
580 ? 0
581 : expected_sr_conflicts;
582 if (expected != -1)
583 {
584 if (expected != total)
bb8e56ff 585 complain (NULL, complaint,
d87ea54c
AD
586 _("shift/reduce conflicts: %d found, %d expected"),
587 total, expected);
588 }
589 else if (total)
bb8e56ff 590 complain (NULL, Wconflicts_sr,
d87ea54c
AD
591 ngettext ("%d shift/reduce conflict",
592 "%d shift/reduce conflicts",
593 total),
594 total);
595 }
7da99ede 596
d87ea54c
AD
597 {
598 int total = count_rr_conflicts (true);
c5ae8e85 599 /* If %expect-rr is not used, but %expect is, then expect 0 rr. */
d87ea54c
AD
600 int expected =
601 (expected_rr_conflicts == -1 && expected_sr_conflicts != -1)
602 ? 0
603 : expected_rr_conflicts;
604 if (expected != -1)
605 {
606 if (expected != total)
bb8e56ff 607 complain (NULL, complaint,
d87ea54c
AD
608 _("reduce/reduce conflicts: %d found, %d expected"),
609 total, expected);
610 }
611 else if (total)
bb8e56ff 612 complain (NULL, Wconflicts_rr,
d87ea54c
AD
613 ngettext ("%d reduce/reduce conflict",
614 "%d reduce/reduce conflicts",
615 total),
616 total);
617 }
c29240e7
AD
618}
619
620
08089d5d 621void
b408954b 622conflicts_free (void)
08089d5d 623{
afbb696d 624 free (conflicts);
8dd162d3 625 bitset_free (shift_set);
742e4900 626 bitset_free (lookahead_set);
b408954b 627 obstack_free (&solved_conflicts_obstack, NULL);
41d7a5f2 628 obstack_free (&solved_conflicts_xml_obstack, NULL);
08089d5d 629}