Commit | Line | Data |
---|---|---|
b1ea73b5 MK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2015 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials | |
5 | * are made available under the terms of the Eclipse Public License v1.0 | |
6 | * which accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | *******************************************************************************/ | |
9 | package org.eclipse.tracecompass.internal.ctf.core.event.metadata.tsdl; | |
10 | ||
11 | import java.util.HashMap; | |
12 | import java.util.List; | |
13 | import java.util.Map; | |
14 | ||
15 | import org.antlr.runtime.tree.CommonTree; | |
16 | import org.eclipse.jdt.annotation.NonNullByDefault; | |
17 | import org.eclipse.tracecompass.ctf.core.event.metadata.DeclarationScope; | |
18 | import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration; | |
19 | import org.eclipse.tracecompass.ctf.core.event.types.VariantDeclaration; | |
20 | import org.eclipse.tracecompass.ctf.core.trace.CTFTrace; | |
21 | import org.eclipse.tracecompass.ctf.parser.CTFParser; | |
22 | import org.eclipse.tracecompass.internal.ctf.core.event.metadata.AbstractScopedCommonTreeParser; | |
23 | import org.eclipse.tracecompass.internal.ctf.core.event.metadata.ParseException; | |
24 | ||
25 | /** | |
26 | * C typedef parser | |
27 | * | |
28 | * @author Matthew Khouzam | |
29 | * | |
30 | */ | |
31 | public class TypedefParser extends AbstractScopedCommonTreeParser { | |
32 | ||
33 | /** | |
34 | * Parameter object with a trace and current scope | |
35 | * | |
36 | * @author Matthew Khouzam | |
37 | * | |
38 | */ | |
39 | @NonNullByDefault | |
40 | public static final class Param implements ICommonTreeParserParameter { | |
41 | private final DeclarationScope fDeclarationScope; | |
42 | private final CTFTrace fTrace; | |
43 | ||
44 | /** | |
45 | * Constructor | |
46 | * | |
47 | * @param trace | |
48 | * the trace | |
49 | * @param scope | |
50 | * the current scope | |
51 | */ | |
52 | public Param(CTFTrace trace, DeclarationScope scope) { | |
53 | fTrace = trace; | |
54 | fDeclarationScope = scope; | |
55 | } | |
56 | } | |
57 | ||
58 | /** | |
59 | * The instance | |
60 | */ | |
61 | public final static TypedefParser INSTANCE = new TypedefParser(); | |
62 | ||
63 | private TypedefParser() { | |
64 | } | |
65 | ||
66 | /** | |
67 | * Parses a typedef node. This creates and registers a new declaration for | |
68 | * each declarator found in the typedef. | |
69 | * | |
70 | * @param typedef | |
71 | * A TYPEDEF node. | |
72 | * | |
73 | * @return map of type name to type declaration | |
74 | * @throws ParseException | |
75 | * If there is an error creating the declaration. | |
76 | */ | |
77 | @Override | |
78 | public Map<String, IDeclaration> parse(CommonTree typedef, ICommonTreeParserParameter param) throws ParseException { | |
79 | if (!(param instanceof Param)) { | |
80 | throw new IllegalArgumentException("Param must be a " + Param.class.getCanonicalName()); //$NON-NLS-1$ | |
81 | } | |
82 | DeclarationScope scope = ((Param) param).fDeclarationScope; | |
83 | ||
84 | CommonTree typeDeclaratorListNode = (CommonTree) typedef.getFirstChildWithType(CTFParser.TYPE_DECLARATOR_LIST); | |
85 | if (typeDeclaratorListNode == null) { | |
86 | throw new ParseException("Cannot have a typedef without a declarator"); //$NON-NLS-1$ | |
87 | } | |
88 | CommonTree typeSpecifierListNode = (CommonTree) typedef.getFirstChildWithType(CTFParser.TYPE_SPECIFIER_LIST); | |
89 | if (typeSpecifierListNode == null) { | |
90 | throw new ParseException("Cannot have a typedef without specifiers"); //$NON-NLS-1$ | |
91 | } | |
92 | List<CommonTree> typeDeclaratorList = typeDeclaratorListNode.getChildren(); | |
93 | ||
94 | Map<String, IDeclaration> declarations = new HashMap<>(); | |
95 | ||
96 | for (CommonTree typeDeclaratorNode : typeDeclaratorList) { | |
97 | StringBuilder identifierSB = new StringBuilder(); | |
98 | CTFTrace trace = ((Param) param).fTrace; | |
99 | IDeclaration typeDeclaration = TypeDeclaratorParser.INSTANCE.parse(typeDeclaratorNode, new TypeDeclaratorParser.Param(trace, typeSpecifierListNode, scope, identifierSB)); | |
100 | ||
101 | if ((typeDeclaration instanceof VariantDeclaration) | |
102 | && !((VariantDeclaration) typeDeclaration).isTagged()) { | |
103 | throw new ParseException("Typealias of untagged variant is not permitted"); //$NON-NLS-1$ | |
104 | } | |
105 | ||
106 | scope.registerType(identifierSB.toString(), typeDeclaration); | |
107 | ||
108 | declarations.put(identifierSB.toString(), typeDeclaration); | |
109 | } | |
110 | return declarations; | |
111 | } | |
112 | ||
113 | } |