|
Lines 159-251
Link Here
|
| 159 |
BacktrackException { |
159 |
BacktrackException { |
| 160 |
if (LT(1) == IToken.tASSIGN) { |
160 |
if (LT(1) == IToken.tASSIGN) { |
| 161 |
consume(); |
161 |
consume(); |
| 162 |
final List<IASTNode> empty= Collections.emptyList(); |
162 |
return cInitializerClause(false); |
| 163 |
return cInitializerClause(empty, false); |
|
|
| 164 |
} |
163 |
} |
| 165 |
return null; |
164 |
return null; |
| 166 |
} |
165 |
} |
| 167 |
|
166 |
|
| 168 |
protected IASTInitializer cInitializerClause(List<IASTNode> designators, boolean inAggregateInitializer) |
167 |
protected IASTInitializer cInitializerClause(boolean inAggregate) throws EndOfFileException, BacktrackException { |
| 169 |
throws EndOfFileException, BacktrackException { |
168 |
final int offset = LA(1).getOffset(); |
| 170 |
IToken la = LA(1); |
169 |
if (LT(1) != IToken.tLBRACE) { |
| 171 |
int startingOffset = la.getOffset(); |
170 |
IASTExpression assignmentExpression= assignmentExpression(); |
| 172 |
la = null; |
171 |
if (inAggregate && skipTrivialExpressionsInAggregateInitializers) { |
| 173 |
if (LT(1) == IToken.tLBRACE) { |
172 |
if (!ASTQueries.canContainName(assignmentExpression)) |
| 174 |
consume(); |
173 |
return null; |
| 175 |
IASTInitializerList result = createInitializerList(); |
174 |
} |
| 176 |
((ASTNode) result).setOffset(startingOffset); |
175 |
IASTInitializerExpression result= createInitializerExpression(); |
| 177 |
|
176 |
result.setExpression(assignmentExpression); |
| 178 |
// bug 196468, gcc accepts empty braces. |
177 |
setRange(result, assignmentExpression); |
| 179 |
if (supportGCCStyleDesignators && LT(1) == (IToken.tRBRACE)) { |
178 |
return result; |
| 180 |
int l = consume().getEndOffset(); |
|
|
| 181 |
((ASTNode) result).setLength(l - startingOffset); |
| 182 |
return result; |
| 183 |
} |
| 184 |
|
179 |
|
| 185 |
for (;;) { |
180 |
} |
| 186 |
final IToken startToken= LA(1); |
181 |
|
| 187 |
// required at least one initializer list |
182 |
// it's an aggregate initializer |
| 188 |
// get designator list |
183 |
consume(IToken.tLBRACE); |
| 189 |
List<IASTNode> newDesignators = designatorList(); |
184 |
IASTInitializerList result = createInitializerList(); |
| 190 |
if (newDesignators.size() != 0) |
185 |
|
| 191 |
if (LT(1) == IToken.tASSIGN) |
186 |
// bug 196468, gcc accepts empty braces. |
| 192 |
consume(); |
187 |
if (supportGCCStyleDesignators && LT(1) == IToken.tRBRACE) { |
| 193 |
|
188 |
int endOffset= consume().getEndOffset(); |
| 194 |
IASTInitializer initializer = cInitializerClause(newDesignators, true); |
189 |
setRange(result, offset, endOffset); |
| 195 |
|
190 |
return result; |
| 196 |
// depending on value of skipTrivialItemsInCompoundInitializers initializer may be null |
191 |
} |
| 197 |
if (initializer != null) { |
|
|
| 198 |
if (newDesignators.isEmpty()) { |
| 199 |
result.addInitializer(initializer); |
| 200 |
} else { |
| 201 |
ICASTDesignatedInitializer desigInitializer = createDesignatorInitializer(); |
| 202 |
((ASTNode) desigInitializer).setOffsetAndLength( |
| 203 |
((ASTNode) newDesignators.get(0)).getOffset(), |
| 204 |
((ASTNode)initializer).getOffset() + ((ASTNode)initializer).getLength() - ((ASTNode) newDesignators.get(0)).getOffset()); |
| 205 |
for (int i = 0; i < newDesignators.size(); ++i) { |
| 206 |
ICASTDesignator d = (ICASTDesignator) newDesignators.get(i); |
| 207 |
desigInitializer.addDesignator(d); |
| 208 |
} |
| 209 |
desigInitializer.setOperandInitializer(initializer); |
| 210 |
result.addInitializer(desigInitializer); |
| 211 |
} |
| 212 |
} |
| 213 |
// can end with ", }" or "}" |
| 214 |
if (LT(1) == IToken.tCOMMA) |
| 215 |
consume(); |
| 216 |
if (LT(1) == IToken.tRBRACE) |
| 217 |
break; |
| 218 |
|
| 219 |
final IToken nextToken= LA(1); |
| 220 |
if (nextToken.getType() == IToken.tEOC) { |
| 221 |
return result; |
| 222 |
} |
| 223 |
if (nextToken == startToken) { |
| 224 |
throwBacktrack(startingOffset, nextToken.getEndOffset() - startingOffset); |
| 225 |
return null; |
| 226 |
} |
| 227 |
|
192 |
|
| 228 |
// otherwise, its another initializer in the list |
193 |
for (;;) { |
| 229 |
} |
194 |
final int checkOffset= LA(1).getOffset(); |
| 230 |
// consume the closing brace |
195 |
// required at least one initializer list |
| 231 |
int lastOffset = consume(IToken.tRBRACE).getEndOffset(); |
196 |
// get designator list |
| 232 |
((ASTNode) result).setLength(lastOffset - startingOffset); |
197 |
List<? extends ICASTDesignator> designator= designatorList(); |
| 233 |
return result; |
198 |
if (designator == null) { |
|
|
199 |
IASTInitializer initializer= cInitializerClause(true); |
| 200 |
// depending on value of skipTrivialItemsInCompoundInitializers initializer may be null |
| 201 |
if (initializer != null) { |
| 202 |
result.addInitializer(initializer); |
| 203 |
} |
| 204 |
} else { |
| 205 |
if (LT(1) == IToken.tASSIGN) |
| 206 |
consume(); |
| 207 |
IASTInitializer initializer= cInitializerClause(false); |
| 208 |
ICASTDesignatedInitializer desigInitializer = createDesignatorInitializer(); |
| 209 |
setRange(desigInitializer, designator.get(0)); |
| 210 |
adjustLength(desigInitializer, initializer); |
| 211 |
|
| 212 |
for (ICASTDesignator d : designator) { |
| 213 |
desigInitializer.addDesignator(d); |
| 214 |
} |
| 215 |
desigInitializer.setOperandInitializer(initializer); |
| 216 |
result.addInitializer(desigInitializer); |
| 217 |
} |
| 218 |
|
| 219 |
// can end with ", }" or "}" |
| 220 |
boolean canContinue= LT(1) == IToken.tCOMMA; |
| 221 |
if (canContinue) |
| 222 |
consume(); |
| 223 |
|
| 224 |
switch (LT(1)) { |
| 225 |
case IToken.tRBRACE: |
| 226 |
int lastOffset = consume().getEndOffset(); |
| 227 |
setRange(result, offset, lastOffset); |
| 228 |
return result; |
| 229 |
|
| 230 |
case IToken.tEOC: |
| 231 |
setRange(result, offset, LA(1).getOffset()); |
| 232 |
return result; |
| 233 |
} |
| 234 |
|
| 235 |
if (!canContinue || LA(1).getOffset() == checkOffset) { |
| 236 |
throwBacktrack(offset, LA(1).getEndOffset() - offset); |
| 237 |
} |
| 234 |
} |
238 |
} |
| 235 |
// if we get this far, it means that we have not yet succeeded |
239 |
// consume the closing brace |
| 236 |
// try this now instead |
|
|
| 237 |
// assignmentExpression |
| 238 |
IASTExpression assignmentExpression = assignmentExpression(); |
| 239 |
if (inAggregateInitializer && skipTrivialExpressionsInAggregateInitializers) { |
| 240 |
if (!ASTQueries.canContainName(assignmentExpression)) |
| 241 |
return null; |
| 242 |
} |
| 243 |
IASTInitializerExpression result = createInitializerExpression(); |
| 244 |
result.setExpression(assignmentExpression); |
| 245 |
((ASTNode) result).setOffsetAndLength( |
| 246 |
((ASTNode) assignmentExpression).getOffset(), |
| 247 |
((ASTNode) assignmentExpression).getLength()); |
| 248 |
return result; |
| 249 |
} |
240 |
} |
| 250 |
|
241 |
|
| 251 |
protected ICASTDesignatedInitializer createDesignatorInitializer() { |
242 |
protected ICASTDesignatedInitializer createDesignatorInitializer() { |
|
Lines 260-361
Link Here
|
| 260 |
return new CASTInitializerExpression(); |
251 |
return new CASTInitializerExpression(); |
| 261 |
} |
252 |
} |
| 262 |
|
253 |
|
| 263 |
protected List<IASTNode> designatorList() throws EndOfFileException, |
254 |
private List<? extends ICASTDesignator> designatorList() throws EndOfFileException, BacktrackException { |
| 264 |
BacktrackException { |
255 |
final int lt1= LT(1); |
| 265 |
// designated initializers for C |
256 |
if (lt1 == IToken.tDOT || lt1 == IToken.tLBRACKET) { |
| 266 |
List<IASTNode> designatorList= Collections.emptyList(); |
257 |
List<ICASTDesignator> designatorList= null; |
| 267 |
|
258 |
while (true) { |
| 268 |
if (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { |
259 |
switch (LT(1)) { |
| 269 |
while (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { |
260 |
case IToken.tDOT: |
| 270 |
if (LT(1) == IToken.tDOT) { |
|
|
| 271 |
int offset = consume().getOffset(); |
261 |
int offset = consume().getOffset(); |
| 272 |
IToken id = identifier(); |
262 |
IToken id = identifier(); |
| 273 |
ICASTFieldDesignator designator = createFieldDesignator(); |
|
|
| 274 |
((ASTNode) designator).setOffsetAndLength(offset, id.getEndOffset() - offset); |
| 275 |
IASTName n = createName(id); |
263 |
IASTName n = createName(id); |
| 276 |
designator.setName(n); |
264 |
ICASTFieldDesignator fieldDesignator = createFieldDesignator(); |
| 277 |
if (designatorList == Collections.EMPTY_LIST) |
265 |
setRange(fieldDesignator, offset, id.getEndOffset()); |
| 278 |
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE); |
266 |
fieldDesignator.setName(n); |
| 279 |
designatorList.add(designator); |
267 |
if (designatorList == null) |
| 280 |
} else if (LT(1) == IToken.tLBRACKET) { |
268 |
designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE); |
| 281 |
IToken mark = consume(); |
269 |
designatorList.add(fieldDesignator); |
| 282 |
int offset = mark.getOffset(); |
270 |
break; |
|
|
271 |
|
| 272 |
case IToken.tLBRACKET: |
| 273 |
offset = consume().getOffset(); |
| 283 |
IASTExpression constantExpression = expression(); |
274 |
IASTExpression constantExpression = expression(); |
| 284 |
if (LT(1) == IToken.tRBRACKET) { |
275 |
if (supportGCCStyleDesignators && LT(1) == IToken.tELLIPSIS) { |
| 285 |
int lastOffset = consume().getEndOffset(); |
276 |
consume(IToken.tELLIPSIS); |
|
|
277 |
IASTExpression constantExpression2 = expression(); |
| 278 |
int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); |
| 279 |
IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); |
| 280 |
setRange(designator, offset, lastOffset); |
| 281 |
designator.setRangeFloor(constantExpression); |
| 282 |
designator.setRangeCeiling(constantExpression2); |
| 283 |
if (designatorList == null) |
| 284 |
designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE); |
| 285 |
designatorList.add(designator); |
| 286 |
} else { |
| 287 |
int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); |
| 286 |
ICASTArrayDesignator designator = createArrayDesignator(); |
288 |
ICASTArrayDesignator designator = createArrayDesignator(); |
| 287 |
((ASTNode) designator).setOffsetAndLength(offset, lastOffset - offset); |
289 |
setRange(designator, offset, lastOffset); |
| 288 |
designator.setSubscriptExpression(constantExpression); |
290 |
designator.setSubscriptExpression(constantExpression); |
| 289 |
if (designatorList == Collections.EMPTY_LIST) |
291 |
if (designatorList == null) |
| 290 |
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE); |
292 |
designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE); |
| 291 |
designatorList.add(designator); |
|
|
| 292 |
continue; |
| 293 |
} |
| 294 |
backup(mark); |
| 295 |
if (supportGCCStyleDesignators) { |
| 296 |
int startOffset = consume(IToken.tLBRACKET).getOffset(); |
| 297 |
IASTExpression constantExpression1 = expression(); |
| 298 |
consume(IToken.tELLIPSIS); |
| 299 |
IASTExpression constantExpression2 = expression(); |
| 300 |
int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); |
| 301 |
IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); |
| 302 |
((ASTNode) designator).setOffsetAndLength(startOffset, lastOffset - startOffset); |
| 303 |
designator.setRangeFloor(constantExpression1); |
| 304 |
designator.setRangeCeiling(constantExpression2); |
| 305 |
if (designatorList == Collections.EMPTY_LIST) |
| 306 |
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE); |
| 307 |
designatorList.add(designator); |
293 |
designatorList.add(designator); |
| 308 |
} |
294 |
} |
| 309 |
} else if (supportGCCStyleDesignators |
295 |
break; |
| 310 |
&& LT(1) == IToken.tIDENTIFIER) { |
296 |
|
| 311 |
IToken identifier = identifier(); |
297 |
default: |
| 312 |
int lastOffset = consume(IToken.tCOLON).getEndOffset(); |
298 |
return designatorList; |
| 313 |
ICASTFieldDesignator designator = createFieldDesignator(); |
|
|
| 314 |
((ASTNode) designator).setOffsetAndLength(identifier |
| 315 |
.getOffset(), lastOffset - identifier.getOffset()); |
| 316 |
IASTName n = createName(identifier); |
| 317 |
designator.setName(n); |
| 318 |
if (designatorList == Collections.EMPTY_LIST) |
| 319 |
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE); |
| 320 |
designatorList.add(designator); |
| 321 |
} |
| 322 |
} |
| 323 |
} else { |
| 324 |
if (supportGCCStyleDesignators |
| 325 |
&& (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tLBRACKET)) { |
| 326 |
|
| 327 |
if (LT(1) == IToken.tIDENTIFIER) { |
| 328 |
// fix for 84176: if reach identifier and it's not a designator then return empty designator list |
| 329 |
if (LT(2) != IToken.tCOLON) |
| 330 |
return designatorList; |
| 331 |
|
| 332 |
IToken identifier = identifier(); |
| 333 |
int lastOffset = consume(IToken.tCOLON).getEndOffset(); |
| 334 |
ICASTFieldDesignator designator = createFieldDesignator(); |
| 335 |
((ASTNode) designator).setOffsetAndLength(identifier |
| 336 |
.getOffset(), lastOffset - identifier.getOffset()); |
| 337 |
IASTName n = createName(identifier); |
| 338 |
designator.setName(n); |
| 339 |
if (designatorList == Collections.EMPTY_LIST) |
| 340 |
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE); |
| 341 |
designatorList.add(designator); |
| 342 |
} else if (LT(1) == IToken.tLBRACKET) { |
| 343 |
int startOffset = consume().getOffset(); |
| 344 |
IASTExpression constantExpression1 = expression(); |
| 345 |
consume(IToken.tELLIPSIS); |
| 346 |
IASTExpression constantExpression2 = expression(); |
| 347 |
int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); |
| 348 |
IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); |
| 349 |
((ASTNode) designator).setOffsetAndLength(startOffset, lastOffset - startOffset); |
| 350 |
designator.setRangeFloor(constantExpression1); |
| 351 |
designator.setRangeCeiling(constantExpression2); |
| 352 |
if (designatorList == Collections.EMPTY_LIST) |
| 353 |
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE); |
| 354 |
designatorList.add(designator); |
| 355 |
} |
299 |
} |
| 356 |
} |
300 |
} |
| 357 |
} |
301 |
} |
| 358 |
return designatorList; |
302 |
|
|
|
303 |
// fix for 84176: if reach identifier and it's not a designator then return empty designator list |
| 304 |
if (supportGCCStyleDesignators && lt1 == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) { |
| 305 |
IToken identifier = identifier(); |
| 306 |
int lastOffset = consume(IToken.tCOLON).getEndOffset(); |
| 307 |
ICASTFieldDesignator designator = createFieldDesignator(); |
| 308 |
((ASTNode) designator).setOffsetAndLength(identifier.getOffset(), lastOffset - identifier.getOffset()); |
| 309 |
IASTName n = createName(identifier); |
| 310 |
designator.setName(n); |
| 311 |
return Collections.singletonList(designator); |
| 312 |
} |
| 313 |
|
| 314 |
return null; |
| 359 |
} |
315 |
} |
| 360 |
|
316 |
|
| 361 |
protected IGCCASTArrayRangeDesignator createArrayRangeDesignator() { |
317 |
protected IGCCASTArrayRangeDesignator createArrayRangeDesignator() { |
|
Lines 689-696
Link Here
|
| 689 |
if (t != null) { |
645 |
if (t != null) { |
| 690 |
consume(IToken.tRPAREN).getEndOffset(); |
646 |
consume(IToken.tRPAREN).getEndOffset(); |
| 691 |
if (LT(1) == IToken.tLBRACE) { |
647 |
if (LT(1) == IToken.tLBRACE) { |
| 692 |
final List<IASTNode> emptyList = Collections.emptyList(); |
648 |
IASTInitializer i = cInitializerClause(false); |
| 693 |
IASTInitializer i = cInitializerClause(emptyList, false); |
|
|
| 694 |
firstExpression = buildTypeIdInitializerExpression(t, i, offset, calculateEndOffset(i)); |
649 |
firstExpression = buildTypeIdInitializerExpression(t, i, offset, calculateEndOffset(i)); |
| 695 |
break; |
650 |
break; |
| 696 |
} |
651 |
} |