1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_idlc.hxx"
26 #include <idlc/idlc.hxx>
27 #include <idlc/errorhandler.hxx>
28 #include <idlc/astscope.hxx>
29 #include <idlc/astmodule.hxx>
30 #include <idlc/astservice.hxx>
31 #include <idlc/astconstants.hxx>
32 #include <idlc/astexception.hxx>
33 #include <idlc/astunion.hxx>
34 #include <idlc/astenum.hxx>
35 #include <idlc/astinterface.hxx>
36 #include <idlc/astoperation.hxx>
37 #include <idlc/astbasetype.hxx>
38 #include "idlc/astdeclaration.hxx"
39 #include "idlc/astparameter.hxx"
40 #include "idlc/astsequence.hxx"
41 #include "idlc/asttype.hxx"
42 #include "idlc/asttypedef.hxx"
43
44 #include "osl/diagnose.h"
45
46 using namespace ::rtl;
47
scopeAsDecl(AstScope * pScope)48 AstDeclaration* SAL_CALL scopeAsDecl(AstScope* pScope)
49 {
50 if (pScope == NULL) return NULL;
51
52 switch( pScope->getScopeNodeType() )
53 {
54 case NT_service:
55 case NT_singleton:
56 return (AstService*)(pScope);
57 case NT_module:
58 case NT_root:
59 return (AstModule*)(pScope);
60 case NT_constants:
61 return (AstConstants*)(pScope);
62 case NT_interface:
63 return (AstInterface*)(pScope);
64 case NT_operation:
65 return (AstOperation*)(pScope);
66 case NT_exception:
67 return (AstException*)(pScope);
68 case NT_union:
69 return (AstUnion*)(pScope);
70 case NT_struct:
71 return (AstStruct*)(pScope);
72 case NT_enum:
73 return (AstEnum*)(pScope);
74 default:
75 return NULL;
76 }
77 }
78
declAsScope(AstDeclaration * pDecl)79 AstScope* SAL_CALL declAsScope(AstDeclaration* pDecl)
80 {
81 if (pDecl == NULL) return NULL;
82
83 switch(pDecl->getNodeType())
84 {
85 case NT_interface:
86 return (AstInterface*)(pDecl);
87 case NT_service:
88 case NT_singleton:
89 return (AstService*)(pDecl);
90 case NT_module:
91 case NT_root:
92 return (AstModule*)(pDecl);
93 case NT_constants:
94 return (AstConstants*)(pDecl);
95 case NT_exception:
96 return (AstException*)(pDecl);
97 case NT_union:
98 return (AstUnion*)(pDecl);
99 case NT_struct:
100 return (AstStruct*)(pDecl);
101 case NT_enum:
102 return (AstEnum*)(pDecl);
103 case NT_operation:
104 return (AstOperation*)(pDecl);
105 default:
106 return NULL;
107 }
108 }
109
predefineXInterface(AstModule * pRoot)110 static void SAL_CALL predefineXInterface(AstModule* pRoot)
111 {
112 // define the modules com::sun::star::uno
113 AstModule* pParentScope = pRoot;
114 AstModule* pModule = new AstModule(OString("com"), pParentScope);
115 pModule->setPredefined(true);
116 pParentScope->addDeclaration(pModule);
117 pParentScope = pModule;
118 pModule = new AstModule(OString("sun"), pParentScope);
119 pModule->setPredefined(true);
120 pParentScope->addDeclaration(pModule);
121 pParentScope = pModule;
122 pModule = new AstModule(OString("star"), pParentScope);
123 pModule->setPredefined(true);
124 pParentScope->addDeclaration(pModule);
125 pParentScope = pModule;
126 pModule = new AstModule(OString("uno"), pParentScope);
127 pModule->setPredefined(true);
128 pParentScope->addDeclaration(pModule);
129 pParentScope = pModule;
130
131 // define XInterface
132 AstInterface* pInterface = new AstInterface(OString("XInterface"), NULL, pParentScope);
133 pInterface->setDefined();
134 pInterface->setPredefined(true);
135 pInterface->setPublished();
136 pParentScope->addDeclaration(pInterface);
137
138 // define XInterface::queryInterface
139 AstOperation* pOp = new AstOperation(0, (AstType*)(pRoot->lookupPrimitiveType(ET_any)),
140 OString("queryInterface"), pInterface);
141 AstParameter* pParam = new AstParameter(DIR_IN, false,
142 (AstType*)(pRoot->lookupPrimitiveType(ET_type)),
143 OString("aType"), pOp);
144 pOp->addDeclaration(pParam);
145 pInterface->addMember(pOp);
146
147 // define XInterface::acquire
148 pOp = new AstOperation(1, (AstType*)(pRoot->lookupPrimitiveType(ET_void)),
149 OString("acquire"), pInterface);
150 pInterface->addMember(pOp);
151
152 // define XInterface::release
153 pOp = new AstOperation(1, (AstType*)(pRoot->lookupPrimitiveType(ET_void)),
154 OString("release"), pInterface);
155 pInterface->addMember(pOp);
156 }
157
initializePredefinedTypes(AstModule * pRoot)158 static void SAL_CALL initializePredefinedTypes(AstModule* pRoot)
159 {
160 AstBaseType* pPredefined = NULL;
161 if ( pRoot )
162 {
163 pPredefined = new AstBaseType(ET_long, OString("long"), pRoot);
164 pRoot->addDeclaration(pPredefined);
165
166 pPredefined = new AstBaseType(ET_ulong, OString("unsigned long"), pRoot);
167 pRoot->addDeclaration(pPredefined);
168
169 pPredefined = new AstBaseType(ET_hyper, OString("hyper"), pRoot);
170 pRoot->addDeclaration(pPredefined);
171
172 pPredefined = new AstBaseType(ET_uhyper, OString("unsigned hyper"), pRoot);
173 pRoot->addDeclaration(pPredefined);
174
175 pPredefined = new AstBaseType(ET_short, OString("short"), pRoot);
176 pRoot->addDeclaration(pPredefined);
177
178 pPredefined = new AstBaseType(ET_ushort, OString("unsigned short"), pRoot);
179 pRoot->addDeclaration(pPredefined);
180
181 pPredefined = new AstBaseType(ET_float, OString("float"), pRoot);
182 pRoot->addDeclaration(pPredefined);
183
184 pPredefined = new AstBaseType(ET_double, OString("double"), pRoot);
185 pRoot->addDeclaration(pPredefined);
186
187 pPredefined = new AstBaseType(ET_char, OString("char"), pRoot);
188 pRoot->addDeclaration(pPredefined);
189
190 pPredefined = new AstBaseType(ET_byte, OString("byte"), pRoot);
191 pRoot->addDeclaration(pPredefined);
192
193 pPredefined = new AstBaseType(ET_any, OString("any"), pRoot);
194 pRoot->addDeclaration(pPredefined);
195
196 pPredefined = new AstBaseType(ET_string, OString("string"), pRoot);
197 pRoot->addDeclaration(pPredefined);
198
199 pPredefined = new AstBaseType(ET_type, OString("type"), pRoot);
200 pRoot->addDeclaration(pPredefined);
201
202 pPredefined = new AstBaseType(ET_boolean, OString("boolean"), pRoot);
203 pRoot->addDeclaration(pPredefined);
204
205 pPredefined = new AstBaseType(ET_void, OString("void"), pRoot);
206 pRoot->addDeclaration(pPredefined);
207 }
208 }
209
Idlc(Options * pOptions)210 Idlc::Idlc(Options* pOptions)
211 : m_pOptions(pOptions)
212 , m_bIsDocValid(sal_False)
213 , m_bIsInMainfile(sal_True)
214 , m_published(false)
215 , m_errorCount(0)
216 , m_warningCount(0)
217 , m_lineNumber(0)
218 , m_parseState(PS_NoState)
219 {
220 m_pScopes = new AstStack();
221 // init root object after construction
222 m_pRoot = NULL;
223 m_pErrorHandler = new ErrorHandler();
224 m_bGenerateDoc = m_pOptions->isValid("-C");
225 }
226
~Idlc()227 Idlc::~Idlc()
228 {
229 if (m_pRoot)
230 delete m_pRoot;
231 if (m_pScopes)
232 delete m_pScopes;
233 if (m_pErrorHandler)
234 delete m_pErrorHandler;
235 }
236
init()237 void Idlc::init()
238 {
239 if ( m_pRoot )
240 delete m_pRoot;
241
242 m_pRoot = new AstModule(NT_root, OString(), NULL);
243
244 // push the root node on the stack
245 m_pScopes->push(m_pRoot);
246 initializePredefinedTypes(m_pRoot);
247 predefineXInterface(m_pRoot);
248 }
249
reset()250 void Idlc::reset()
251 {
252 m_bIsDocValid = sal_False;
253 m_bIsInMainfile = sal_True;
254 m_published = false;
255
256 m_errorCount = 0;
257 m_warningCount = 0;
258 m_lineNumber = 0;
259 m_parseState = PS_NoState;
260
261 m_fileName = OString();
262 m_mainFileName = OString();
263 m_realFileName = OString();
264 m_documentation = OString();
265
266 m_pScopes->clear();
267 if ( m_pRoot)
268 delete m_pRoot;
269
270 m_pRoot = new AstModule(NT_root, OString(), NULL);
271
272 // push the root node on the stack
273 m_pScopes->push(m_pRoot);
274 initializePredefinedTypes(m_pRoot);
275 }
276
isDocValid()277 sal_Bool Idlc::isDocValid()
278 {
279 if ( m_bGenerateDoc )
280 return m_bIsDocValid;
281 return sal_False;;
282 }
283
284 static Idlc* pStaticIdlc = NULL;
285
idlc()286 Idlc* SAL_CALL idlc()
287 {
288 return pStaticIdlc;
289 }
290
setIdlc(Options * pOptions)291 Idlc* SAL_CALL setIdlc(Options* pOptions)
292 {
293 if ( pStaticIdlc )
294 {
295 delete pStaticIdlc;
296 }
297 pStaticIdlc = new Idlc(pOptions);
298 pStaticIdlc->init();
299 return pStaticIdlc;
300 }
301
resolveTypedefs(AstDeclaration const * type)302 AstDeclaration const * resolveTypedefs(AstDeclaration const * type) {
303 if (type != 0) {
304 while (type->getNodeType() == NT_typedef) {
305 type = static_cast< AstTypeDef const * >(type)->getBaseType();
306 }
307 }
308 return type;
309 }
310
deconstructAndResolveTypedefs(AstDeclaration const * type,sal_Int32 * rank)311 AstDeclaration const * deconstructAndResolveTypedefs(
312 AstDeclaration const * type, sal_Int32 * rank)
313 {
314 *rank = 0;
315 for (;;) {
316 if (type == 0) {
317 return 0;
318 }
319 switch (type->getNodeType()) {
320 case NT_typedef:
321 type = static_cast< AstTypeDef const * >(type)->getBaseType();
322 break;
323 case NT_sequence:
324 ++(*rank);
325 type = static_cast< AstSequence const * >(type)->getMemberType();
326 break;
327 default:
328 return type;
329 }
330 }
331 }
332
resolveInterfaceTypedefs(AstType const * type)333 AstInterface const * resolveInterfaceTypedefs(AstType const * type) {
334 AstDeclaration const * decl = resolveTypedefs(type);
335 OSL_ASSERT(decl->getNodeType() == NT_interface);
336 return static_cast< AstInterface const * >(decl);
337 }
338