pet_scop_from_pet_tree: extract pet_scop from the root down to the leaves
[pet.git] / loc.c
blob42ecd32314a3d9d957196630177142b17f909a9d
1 /*
2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2014 Ecole Normale Superieure. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and documentation
30 * are those of the authors and should not be interpreted as
31 * representing official policies, either expressed or implied, of
32 * Leiden University.
35 #include <string.h>
37 #include "loc.h"
39 /* A pet_loc object represents a region of the input file.
40 * The "start" and "end" fields contain the offsets in the input file
41 * of the region, where end points to the first character after the region.
42 * "line" is the line number of a line inside the region.
44 * A special pet_loc_dummy instance is used to indicate that
45 * no offset information is available (yet).
47 struct pet_loc {
48 int ref;
49 isl_ctx *ctx;
51 unsigned start;
52 unsigned end;
53 int line;
56 /* A special pet_loc object that is used to indicate that
57 * no region information is available yet.
59 * This special pet_loc object cannot be changed.
60 * In particular, it is not allowed to call pet_loc_cow on this object.
62 pet_loc pet_loc_dummy = {
63 .ref = -1,
64 .ctx = NULL,
65 .start = 0,
66 .end = 0,
67 .line = -1,
70 /* Allocate a pet_loc with the given start, end and line number.
72 __isl_give pet_loc *pet_loc_alloc(isl_ctx *ctx,
73 unsigned start, unsigned end, int line)
75 pet_loc *loc;
77 loc = isl_alloc_type(ctx, struct pet_loc);
78 if (!loc)
79 return NULL;
81 loc->ctx = ctx;
82 isl_ctx_ref(ctx);
83 loc->ref = 1;
85 loc->start = start;
86 loc->end = end;
87 loc->line = line;
89 return loc;
92 /* Return a pet_loc that is equal to "loc" and that has only one reference.
94 * It is not allowed to call pet_loc_cow on pet_loc_dummy.
95 * We cannot raise an error in this case because pet_loc_dummy does
96 * not have a reference to a valid isl_ctx.
98 __isl_give pet_loc *pet_loc_cow(__isl_take pet_loc *loc)
100 if (loc == &pet_loc_dummy)
101 return NULL;
102 if (!loc)
103 return NULL;
105 if (loc->ref == 1)
106 return loc;
107 loc->ref--;
108 return pet_loc_alloc(loc->ctx, loc->start, loc->end, loc->line);
111 /* Return an extra reference to "loc".
113 * The special pet_loc_dummy object is not reference counted.
115 __isl_give pet_loc *pet_loc_copy(__isl_keep pet_loc *loc)
117 if (loc == &pet_loc_dummy)
118 return loc;
120 if (!loc)
121 return NULL;
123 loc->ref++;
124 return loc;
127 /* Free a reference to "loc" and return NULL.
129 * The special pet_loc_dummy object is not reference counted.
131 __isl_null pet_loc *pet_loc_free(__isl_take pet_loc *loc)
133 if (loc == &pet_loc_dummy)
134 return NULL;
135 if (!loc)
136 return NULL;
137 if (--loc->ref > 0)
138 return NULL;
140 isl_ctx_deref(loc->ctx);
141 free(loc);
142 return NULL;
145 /* Return the offset in the input file of the start of "loc".
147 unsigned pet_loc_get_start(__isl_keep pet_loc *loc)
149 return loc ? loc->start : 0;
152 /* Return the offset in the input file of the character after "loc".
154 unsigned pet_loc_get_end(__isl_keep pet_loc *loc)
156 return loc ? loc->end : 0;
159 /* Return the line number of a line within the "loc" region.
161 int pet_loc_get_line(__isl_keep pet_loc *loc)
163 return loc ? loc->line : -1;
166 /* Update loc->start and loc->end to include the region from "start"
167 * to "end".
169 * Since we may be modifying "loc", it should be different from
170 * pet_loc_dummy.
172 __isl_give pet_loc *pet_loc_update_start_end(__isl_take pet_loc *loc,
173 unsigned start, unsigned end)
175 loc = pet_loc_cow(loc);
176 if (!loc)
177 return NULL;
179 if (start < loc->start)
180 loc->start = start;
181 if (end > loc->end)
182 loc->end = end;
184 return loc;
187 /* Update loc->start and loc->end to include the region of "loc2".
189 * "loc" may be pet_loc_dummy, in which case we return a copy of "loc2".
190 * Similarly, if "loc2" is pet_loc_dummy, then we leave "loc" untouched.
192 __isl_give pet_loc *pet_loc_update_start_end_from_loc(__isl_take pet_loc *loc,
193 __isl_keep pet_loc *loc2)
195 if (!loc2)
196 return pet_loc_free(loc);
197 if (loc == &pet_loc_dummy)
198 return pet_loc_copy(loc2);
199 if (loc2 == &pet_loc_dummy)
200 return loc;
201 return pet_loc_update_start_end(loc, loc2->start, loc2->end);