xref: /aoo41x/main/idlc/source/astscope.cxx (revision 2fe1ca3d)
1*2fe1ca3dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2fe1ca3dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2fe1ca3dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2fe1ca3dSAndrew Rist  * distributed with this work for additional information
6*2fe1ca3dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2fe1ca3dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2fe1ca3dSAndrew Rist  * "License"); you may not use this file except in compliance
9*2fe1ca3dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*2fe1ca3dSAndrew Rist  *
11*2fe1ca3dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*2fe1ca3dSAndrew Rist  *
13*2fe1ca3dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2fe1ca3dSAndrew Rist  * software distributed under the License is distributed on an
15*2fe1ca3dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2fe1ca3dSAndrew Rist  * KIND, either express or implied.  See the License for the
17*2fe1ca3dSAndrew Rist  * specific language governing permissions and limitations
18*2fe1ca3dSAndrew Rist  * under the License.
19*2fe1ca3dSAndrew Rist  *
20*2fe1ca3dSAndrew Rist  *************************************************************/
21*2fe1ca3dSAndrew Rist 
22*2fe1ca3dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_idlc.hxx"
26cdf0e10cSrcweir #include <idlc/astscope.hxx>
27cdf0e10cSrcweir #include <idlc/astbasetype.hxx>
28cdf0e10cSrcweir #ifndef _IDLC_ASTINERFACE_HXX_
29cdf0e10cSrcweir #include <idlc/astinterface.hxx>
30cdf0e10cSrcweir #endif
31cdf0e10cSrcweir #include <idlc/errorhandler.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir 
34cdf0e10cSrcweir using namespace ::rtl;
35cdf0e10cSrcweir 
isGlobal(const OString & scopedName)36cdf0e10cSrcweir sal_Bool isGlobal(const OString& scopedName)
37cdf0e10cSrcweir {
38cdf0e10cSrcweir 	if ((scopedName.getLength() == 0) || (scopedName.indexOf(':') == 0))
39cdf0e10cSrcweir 	{
40cdf0e10cSrcweir 		return sal_True;
41cdf0e10cSrcweir 	}
42cdf0e10cSrcweir 	return sal_False;
43cdf0e10cSrcweir }
44cdf0e10cSrcweir 
AstScope(NodeType nodeType)45cdf0e10cSrcweir AstScope::AstScope(NodeType nodeType)
46cdf0e10cSrcweir 	: m_nodeType(nodeType)
47cdf0e10cSrcweir {
48cdf0e10cSrcweir 
49cdf0e10cSrcweir }
50cdf0e10cSrcweir 
~AstScope()51cdf0e10cSrcweir AstScope::~AstScope()
52cdf0e10cSrcweir {
53cdf0e10cSrcweir 
54cdf0e10cSrcweir }
55cdf0e10cSrcweir 
addDeclaration(AstDeclaration * pDecl)56cdf0e10cSrcweir AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
57cdf0e10cSrcweir {
58cdf0e10cSrcweir 	AstDeclaration* pDeclaration = NULL;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir 	if ((pDeclaration = lookupForAdd(pDecl)) != NULL)
61cdf0e10cSrcweir 	{
62cdf0e10cSrcweir 		if (pDecl->getNodeType() == NT_union_branch )
63cdf0e10cSrcweir 		{
64cdf0e10cSrcweir 			m_declarations.push_back(pDecl);
65cdf0e10cSrcweir 			return pDecl;
66cdf0e10cSrcweir 		}
67cdf0e10cSrcweir 		if ( pDecl->hasAncestor(pDeclaration) )
68cdf0e10cSrcweir 		{
69cdf0e10cSrcweir 			idlc()->error()->error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration);
70cdf0e10cSrcweir 			return NULL;
71cdf0e10cSrcweir 		}
72cdf0e10cSrcweir 		if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
73cdf0e10cSrcweir 			 (pDecl->getNodeType() == NT_sequence
74cdf0e10cSrcweir               || pDecl->getNodeType() == NT_array
75cdf0e10cSrcweir               || pDecl->getNodeType() == NT_instantiated_struct) )
76cdf0e10cSrcweir 		{
77cdf0e10cSrcweir 			return pDeclaration;
78cdf0e10cSrcweir 		}
79cdf0e10cSrcweir 		if ( (pDeclaration->getNodeType() == NT_interface)
80cdf0e10cSrcweir 			 && (pDecl->getNodeType() == NT_interface)
81cdf0e10cSrcweir 			 && !((AstInterface*)pDeclaration)->isDefined() )
82cdf0e10cSrcweir 		{
83cdf0e10cSrcweir 			m_declarations.push_back(pDecl);
84cdf0e10cSrcweir 			return pDecl;
85cdf0e10cSrcweir 		}
86cdf0e10cSrcweir 		if ( (NT_service == m_nodeType) &&
87cdf0e10cSrcweir 			 ( ((pDecl->getNodeType() == NT_interface_member)
88cdf0e10cSrcweir 			    && (pDeclaration->getNodeType() == NT_interface)) ||
89cdf0e10cSrcweir                ((pDecl->getNodeType() == NT_service_member)
90cdf0e10cSrcweir 			    && (pDeclaration->getNodeType() == NT_service)) )
91cdf0e10cSrcweir             )
92cdf0e10cSrcweir 		{
93cdf0e10cSrcweir 			m_declarations.push_back(pDecl);
94cdf0e10cSrcweir 			return pDecl;
95cdf0e10cSrcweir 		}
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 		idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl);
98cdf0e10cSrcweir 		return NULL;
99cdf0e10cSrcweir 	}
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 	m_declarations.push_back(pDecl);
102cdf0e10cSrcweir 	return pDecl;
103cdf0e10cSrcweir }
104cdf0e10cSrcweir 
getNodeCount(NodeType nodeType)105cdf0e10cSrcweir sal_uInt16 AstScope::getNodeCount(NodeType nodeType)
106cdf0e10cSrcweir {
107cdf0e10cSrcweir 	DeclList::const_iterator iter = getIteratorBegin();
108cdf0e10cSrcweir 	DeclList::const_iterator end = getIteratorEnd();
109cdf0e10cSrcweir 	AstDeclaration* pDecl = NULL;
110cdf0e10cSrcweir 	sal_uInt16 count = 0;
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 	while ( iter != end )
113cdf0e10cSrcweir 	{
114cdf0e10cSrcweir 		pDecl = *iter;
115cdf0e10cSrcweir 		if ( pDecl->getNodeType() == nodeType )
116cdf0e10cSrcweir 			count++;
117cdf0e10cSrcweir 		++iter;
118cdf0e10cSrcweir 	}
119cdf0e10cSrcweir 	return count;
120cdf0e10cSrcweir }
121cdf0e10cSrcweir 
lookupByName(const OString & scopedName)122cdf0e10cSrcweir AstDeclaration* AstScope::lookupByName(const OString& scopedName)
123cdf0e10cSrcweir {
124cdf0e10cSrcweir 	AstDeclaration* pDecl = NULL;
125cdf0e10cSrcweir 	AstScope*		pScope = NULL;
126cdf0e10cSrcweir 	if (scopedName.getLength() == 0)
127cdf0e10cSrcweir 		return NULL;
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 	// If name starts with "::" start look up in global scope
130cdf0e10cSrcweir 	if ( isGlobal(scopedName) )
131cdf0e10cSrcweir 	{
132cdf0e10cSrcweir 		pDecl = scopeAsDecl(this);
133cdf0e10cSrcweir 		if ( !pDecl )
134cdf0e10cSrcweir 			return NULL;
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 		pScope = pDecl->getScope();
137cdf0e10cSrcweir 		// If this is the global scope ...
138cdf0e10cSrcweir 		if ( !pScope )
139cdf0e10cSrcweir 		{
140cdf0e10cSrcweir 			// look up the scopedName part after "::"
141cdf0e10cSrcweir 			OString subName = scopedName.copy(2);
142cdf0e10cSrcweir 			pDecl = lookupByName(subName);
143cdf0e10cSrcweir 			return pDecl;
144cdf0e10cSrcweir 			//return pScope->lookupByName();
145cdf0e10cSrcweir 		}
146cdf0e10cSrcweir 		// OK, not global scope yet, so simply iterate with parent scope
147cdf0e10cSrcweir 		pDecl = pScope->lookupByName(scopedName);
148cdf0e10cSrcweir 		return pDecl;
149cdf0e10cSrcweir 	}
150cdf0e10cSrcweir 
151cdf0e10cSrcweir 	// The name does not start with "::"
152cdf0e10cSrcweir 	// Look up in the local scope and start with the first scope
153cdf0e10cSrcweir     sal_Int32 nIndex = scopedName.indexOf(':');
154cdf0e10cSrcweir 	OString firstScope =  nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
155cdf0e10cSrcweir 	sal_Bool	bFindFirstScope = sal_True;
156cdf0e10cSrcweir 	pDecl = lookupByNameLocal(firstScope);
157cdf0e10cSrcweir 	if ( !pDecl )
158cdf0e10cSrcweir 	{
159cdf0e10cSrcweir 		bFindFirstScope = sal_False;
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 		// OK, not found. Go down parent scope chain
162cdf0e10cSrcweir 		pDecl = scopeAsDecl(this);
163cdf0e10cSrcweir 		if ( pDecl )
164cdf0e10cSrcweir 		{
165cdf0e10cSrcweir 			pScope = pDecl->getScope();
166cdf0e10cSrcweir 			if ( pScope )
167cdf0e10cSrcweir 	   			pDecl = pScope->lookupByName(scopedName);
168cdf0e10cSrcweir 			else
169cdf0e10cSrcweir 				pDecl = NULL;
170cdf0e10cSrcweir 
171cdf0e10cSrcweir 		 	// Special case for scope which is an interface. We
172cdf0e10cSrcweir 		 	// have to look in the inherited interfaces as well.
173cdf0e10cSrcweir 			if ( !pDecl )
174cdf0e10cSrcweir 			{
175cdf0e10cSrcweir 				if (m_nodeType == NT_interface)
176cdf0e10cSrcweir 					pDecl = lookupInInherited(scopedName);
177cdf0e10cSrcweir 			}
178cdf0e10cSrcweir 	   }
179cdf0e10cSrcweir 	}
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 	if ( bFindFirstScope && (firstScope != scopedName) )
182cdf0e10cSrcweir 	{
183cdf0e10cSrcweir         sal_Int32 i = 0;
184cdf0e10cSrcweir         sal_Int32 nOffset = 2;
185cdf0e10cSrcweir         do
186cdf0e10cSrcweir         {
187cdf0e10cSrcweir             pScope = declAsScope(pDecl);
188cdf0e10cSrcweir             if( pScope )
189cdf0e10cSrcweir             {
190cdf0e10cSrcweir                 pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
191cdf0e10cSrcweir                 nOffset = 1;
192cdf0e10cSrcweir             }
193cdf0e10cSrcweir             if( !pDecl )
194cdf0e10cSrcweir                 break;
195cdf0e10cSrcweir         } while( i != -1 );
196cdf0e10cSrcweir 
197cdf0e10cSrcweir         if ( !pDecl )
198cdf0e10cSrcweir         {
199cdf0e10cSrcweir             // last try if is not the global scope and the scopeName isn't specify global too
200cdf0e10cSrcweir             pDecl = scopeAsDecl(this);
201cdf0e10cSrcweir             if ( pDecl && (pDecl->getLocalName() != "") )
202cdf0e10cSrcweir             {
203cdf0e10cSrcweir                 pScope = pDecl->getScope();
204cdf0e10cSrcweir                 if ( pScope )
205cdf0e10cSrcweir                     pDecl = pScope->lookupByName(scopedName);
206cdf0e10cSrcweir             } else
207cdf0e10cSrcweir             {
208cdf0e10cSrcweir                 pDecl = NULL;
209cdf0e10cSrcweir             }
210cdf0e10cSrcweir         }
211cdf0e10cSrcweir 
212cdf0e10cSrcweir 	}
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 	return pDecl;
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
lookupByNameLocal(const OString & name) const217cdf0e10cSrcweir AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const
218cdf0e10cSrcweir {
219cdf0e10cSrcweir 	DeclList::const_iterator iter(m_declarations.begin());
220cdf0e10cSrcweir 	DeclList::const_iterator end(m_declarations.end());
221cdf0e10cSrcweir 	AstDeclaration* pDecl = NULL;
222cdf0e10cSrcweir 
223cdf0e10cSrcweir 	while ( iter != end )
224cdf0e10cSrcweir 	{
225cdf0e10cSrcweir 		pDecl = *iter;
226cdf0e10cSrcweir 		if ( pDecl->getLocalName() == name )
227cdf0e10cSrcweir 			return pDecl;
228cdf0e10cSrcweir 		++iter;
229cdf0e10cSrcweir 	}
230cdf0e10cSrcweir 	return NULL;
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
lookupInInherited(const OString & scopedName) const233cdf0e10cSrcweir AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
234cdf0e10cSrcweir {
235cdf0e10cSrcweir 	AstInterface* pInterface = (AstInterface*)this;
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 	if ( !pInterface )
238cdf0e10cSrcweir 		return NULL;
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 	// Can't look in an interface which was not yet defined
241cdf0e10cSrcweir 	if ( !pInterface->getScope() )
242cdf0e10cSrcweir 	{
243cdf0e10cSrcweir 		idlc()->error()->forwardLookupError(pInterface, scopedName);
244cdf0e10cSrcweir 	}
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 	// OK, loop through inherited interfaces. Stop when you find it
247cdf0e10cSrcweir     AstInterface::InheritedInterfaces::const_iterator iter(
248cdf0e10cSrcweir         pInterface->getAllInheritedInterfaces().begin());
249cdf0e10cSrcweir     AstInterface::InheritedInterfaces::const_iterator end(
250cdf0e10cSrcweir         pInterface->getAllInheritedInterfaces().end());
251cdf0e10cSrcweir     while ( iter != end )
252cdf0e10cSrcweir     {
253cdf0e10cSrcweir         AstInterface const * resolved = iter->getResolved();
254cdf0e10cSrcweir         AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
255cdf0e10cSrcweir         if ( pDecl )
256cdf0e10cSrcweir             return pDecl;
257cdf0e10cSrcweir         pDecl = resolved->lookupInInherited(scopedName);
258cdf0e10cSrcweir         if ( pDecl )
259cdf0e10cSrcweir             return pDecl;
260cdf0e10cSrcweir         ++iter;
261cdf0e10cSrcweir     }
262cdf0e10cSrcweir 	// Not found
263cdf0e10cSrcweir 	return NULL;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
lookupPrimitiveType(ExprType type)266cdf0e10cSrcweir AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
267cdf0e10cSrcweir {
268cdf0e10cSrcweir 	AstDeclaration* pDecl = NULL;
269cdf0e10cSrcweir 	AstScope*		pScope = NULL;
270cdf0e10cSrcweir 	AstBaseType*	pBaseType = NULL;
271cdf0e10cSrcweir 	OString			typeName;
272cdf0e10cSrcweir 	pDecl = scopeAsDecl(this);
273cdf0e10cSrcweir 	if ( !pDecl )
274cdf0e10cSrcweir 		return NULL;
275cdf0e10cSrcweir 	pScope = pDecl->getScope();
276cdf0e10cSrcweir 	if ( pScope)
277cdf0e10cSrcweir 		return pScope->lookupPrimitiveType(type);
278cdf0e10cSrcweir 
279cdf0e10cSrcweir 	switch (type)
280cdf0e10cSrcweir 	{
281cdf0e10cSrcweir         case ET_none:
282cdf0e10cSrcweir             OSL_ASSERT(false);
283cdf0e10cSrcweir             break;
284cdf0e10cSrcweir 		case ET_short:
285cdf0e10cSrcweir 			typeName = OString("short");
286cdf0e10cSrcweir 			break;
287cdf0e10cSrcweir 		case ET_ushort:
288cdf0e10cSrcweir 			typeName = OString("unsigned short");
289cdf0e10cSrcweir 			break;
290cdf0e10cSrcweir 		case ET_long:
291cdf0e10cSrcweir 			typeName = OString("long");
292cdf0e10cSrcweir 			break;
293cdf0e10cSrcweir 		case ET_ulong:
294cdf0e10cSrcweir 			typeName = OString("unsigned long");
295cdf0e10cSrcweir 			break;
296cdf0e10cSrcweir 		case ET_hyper:
297cdf0e10cSrcweir 			typeName = OString("hyper");
298cdf0e10cSrcweir 			break;
299cdf0e10cSrcweir 		case ET_uhyper:
300cdf0e10cSrcweir 			typeName = OString("unsigned hyper");
301cdf0e10cSrcweir 			break;
302cdf0e10cSrcweir 		case ET_float:
303cdf0e10cSrcweir 			typeName = OString("float");
304cdf0e10cSrcweir 			break;
305cdf0e10cSrcweir 		case ET_double:
306cdf0e10cSrcweir 			typeName = OString("double");
307cdf0e10cSrcweir 			break;
308cdf0e10cSrcweir 		case ET_char:
309cdf0e10cSrcweir 			typeName = OString("char");
310cdf0e10cSrcweir 			break;
311cdf0e10cSrcweir 		case ET_byte:
312cdf0e10cSrcweir 			typeName = OString("byte");
313cdf0e10cSrcweir 			break;
314cdf0e10cSrcweir 		case ET_boolean:
315cdf0e10cSrcweir 			typeName = OString("boolean");
316cdf0e10cSrcweir 			break;
317cdf0e10cSrcweir 		case ET_any:
318cdf0e10cSrcweir 			typeName = OString("any");
319cdf0e10cSrcweir 			break;
320cdf0e10cSrcweir 		case ET_void:
321cdf0e10cSrcweir 			typeName = OString("void");
322cdf0e10cSrcweir 			break;
323cdf0e10cSrcweir 		case ET_type:
324cdf0e10cSrcweir 			typeName = OString("type");
325cdf0e10cSrcweir 			break;
326cdf0e10cSrcweir 		case ET_string:
327cdf0e10cSrcweir 			typeName = OString("string");
328cdf0e10cSrcweir 			break;
329cdf0e10cSrcweir 	}
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 	pDecl = lookupByNameLocal(typeName);
332cdf0e10cSrcweir 
333cdf0e10cSrcweir 	if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
334cdf0e10cSrcweir 	{
335cdf0e10cSrcweir 		pBaseType = (AstBaseType*)pDecl;
336cdf0e10cSrcweir 
337cdf0e10cSrcweir 		if ( pBaseType->getExprType() == type )
338cdf0e10cSrcweir 			return pDecl;
339cdf0e10cSrcweir 	}
340cdf0e10cSrcweir 
341cdf0e10cSrcweir 	return NULL;
342cdf0e10cSrcweir }
343cdf0e10cSrcweir 
lookupForAdd(AstDeclaration * pDecl)344cdf0e10cSrcweir AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl)
345cdf0e10cSrcweir {
346cdf0e10cSrcweir 	if ( !pDecl )
347cdf0e10cSrcweir 		return NULL;
348cdf0e10cSrcweir 
349cdf0e10cSrcweir 	AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
350cdf0e10cSrcweir 
351cdf0e10cSrcweir    return pRetDecl;
352cdf0e10cSrcweir }
353