def _unit_entry(self, cur):
    '''enter a subroutine or function into:
       1. The local symtab for the object
       2. The unit symtab
       3. The parent of the unit (if there is one)
    '''
    DebugManager.debug('[Line ' + str(self.lineNumber) +
                       ']: stmt2unit._unit_entry() for ' + str(self))
    if (cur.val.nestLevel == 2):
        DebugManager.warning(
            'Open64 front-end handling of doubly nested module procedures is fragile; check >'
            + self.name + '< for correct handling.', self.lineNumber,
            DebugManager.WarnType.nesting)
    currentSymtab = cur.val.symtab
    if (currentSymtab.parent and (self.name in currentSymtab.parent.ids)):
        mpSymtabEntry = currentSymtab.parent.ids[self.name]
        if (isinstance(mpSymtabEntry.entryKind,
                       SymtabEntry.ProcedureEntryKind)):
            # this is the definition of a previously declared module procedure
            entry = self.makeSymtabEntry(currentSymtab)
            mpSymtabEntry.entryKind = entry.entryKind
            mpSymtabEntry.typetab_id = entry.typetab_id
            currentSymtab.enter_name(self.name, entry)
        else:
            # this is some forward declaration as e.g. in public/private statement
            entry = self.makeSymtabEntry(currentSymtab)
            currentSymtab.enter_name(self.name, entry)
            DebugManager.debug('[Line ' + str(self.lineNumber) +
                               ']: new unit symtab entry ' +
                               entry.debug(self.name))
            # update the parent info
            currentSymtab.augmentParentEntry(entry, mpSymtabEntry, self.name)
            DebugManager.debug('[Line ' + str(self.lineNumber) +
                               ']: updated parent symtab entry ' +
                               mpSymtabEntry.debug(self.name))
    else:  # nothing exists in parent
        entry = self.makeSymtabEntry(currentSymtab)
        currentSymtab.enter_name(self.name, entry)
        DebugManager.debug('[Line ' + str(self.lineNumber) +
                           ']: new unit symtab entry ' +
                           entry.debug(self.name))
        if currentSymtab.parent:
            currentSymtab.replicateEntry(self.name,
                                         "local",
                                         self.name,
                                         currentSymtab.parent,
                                         replicatingUp=True)
            DebugManager.debug('[Line ' + str(self.lineNumber) +
                               ']: new PARENT unit symtab entry (see above)')
    DebugManager.debug('[Line ' + str(self.lineNumber) +
                       ']: stmt2unit._unit_entry() for ' + str(self) +
                       ': with symtab ' + str(currentSymtab) +
                       ' with parent symtab ' + str(currentSymtab.parent))
    if (isinstance(self, fs.FunctionStmt)):
        cur.val._in_functionDecl = self
    if (isinstance(self, fs.SubroutineStmt)):
        cur.val._in_subroutineDecl = self
    return self
 def __rename(self, anExpression, targetEntrySymtab, replicatingUp=False):
     if isinstance(anExpression, str):
         origExp = anExpression
         parentEntry = targetEntrySymtab.lookup_name(anExpression)
         if replicatingUp:
             if parentEntry is None:
                 #if there is no entry in the parent symtab, and there is a rename defined, rename to source
                 if anExpression in self.renames.values():
                     anExpression = self.__renamedToSource(anExpression)
                     #if there is a rename defined in the parent symtab for the mod, sourceToRenamed
                     if anExpression in targetEntrySymtab.renames:
                         anExpression = targetEntrySymtab.__sourceToRenamed(
                             anExpression)
                     #else if mod is not defined in parent, issue warning
                     elif targetEntrySymtab.lookup_name(
                             anExpression) is None:
                         DebugManager.warning(
                             "a SymtabEntry has been replicated up, and modifier '"
                             + str(origExp) +
                             "' has been renamed to its source '" +
                             str(anExpression) +
                             "', which is not defined in the parent context."
                         )
             elif anExpression in targetEntrySymtab.renames:
                 anExpression = targetEntrySymtab.__sourceToRenamed(
                     anExpression)
         elif parentEntry is None and anExpression in targetEntrySymtab.renames:
             #if there is no entry in the symtab, but there is a rename defined in the target entry symtab, rename
             anExpression = targetEntrySymtab.__sourceToRenamed(
                 anExpression)
     elif isinstance(anExpression, App):
         anExpression.args = map(
             lambda anArg: self.__rename(anArg, targetEntrySymtab,
                                         replicatingUp), anExpression.args)
     else:
         raise SymtabError(sys._getframe().f_code.co_name + ': expression' +
                           str(anExpression) +
                           'is not a string and not an App!')
     return anExpression
def _processParameterStmt(aParameterStmt, curr):
    localSymtab = curr.val.symtab
    DebugManager.debug('[Line ' + str(aParameterStmt.lineNumber) +
                       ']: stmt2unit._processParameterStmt(' +
                       str(aParameterStmt) + ') with symbol table ' +
                       str(localSymtab))
    for aNamedParam in aParameterStmt.namedParamList:
        try:
            theSymtabEntry = localSymtab.lookup_name_local(aNamedParam[0])
            if theSymtabEntry:
                DebugManager.debug(
                    '\tvariable "' + aNamedParam[0] +
                    '" already present in local symbol table as ' +
                    theSymtabEntry.debug(aNamedParam[0]))
                theSymtabEntry.enterConstInit(aNamedParam[2])
            else:
                # try implicit typing
                implicitLocalType = localSymtab.implicit[aNamedParam[0][0]]
                if implicitLocalType:  # we handle the error condition below
                    theSymtabEntry = SymtabEntry(
                        SymtabEntry.VariableEntryKind(),
                        type=implicitLocalType)
                    DebugManager.warning(
                        sys._getframe().f_code.co_name + ' implicit typing: ' +
                        str(implicitLocalType) + ' ' + str(aNamedParam),
                        aParameterStmt.lineNumber,
                        DebugManager.WarnType.implicit)
                    theSymtabEntry.enterConstInit(aNamedParam[2])
                else:
                    raise SymtabError(
                        "Parameter statement uses a variable not found in symtab",
                        symbolName=aNamedParam[0],
                        lineNumber=aParameterStmt.lineNumber)
        except SymtabError, e:  # add lineNumber and symbol name to any SymtabError we encounter
            e.lineNumber = e.lineNumber or aParameterStmt.lineNumber
            e.symbolName = e.symbolName or aNamedParam[0]
            raise e
                                   str(aUseStmt.onlyList))
                cur.val.symtab.update_w_module_only(module_unit,
                                                    aUseStmt.onlyList)
        except KeyError, e:
            raise SymtabError('KeyError for key "'+str(e)+'"' \
                             +' while updating '+cur.val.symtab.debug() \
                             +' according to use statement "'+str(aUseStmt)+'"',
                              symbolName=str(e),
                              entry=None,
                              lineNumber=aUseStmt.lineNumber)
    else:
        global reportedMissingModules
        if not (aUseStmt.moduleName.lower() in reportedMissingModules):
            reportedMissingModules.add(aUseStmt.moduleName.lower())
            DebugManager.warning(
                'definition for module ' + aUseStmt.moduleName +
                ' not seen in the input.', aUseStmt.lineNumber,
                DebugManager.WarnType.noDefinition)
    return aUseStmt


def _setAccess(anAccessStmt, cur):
    ''' set the access attributes '''
    DebugManager.debug('[Line ' + str(anAccessStmt.lineNumber) +
                       ']: stmt2unit._setAccess() for ' + str(anAccessStmt))

    accessAttr = anAccessStmt.__class__.kw
    if (not anAccessStmt.vlist):
        if (cur.val._in_drvdType):
            cur.val._drvdTypeDefaultAccess = accessAttr  # and process it at the end of rhe derived type definition
        else:
            cur.val.symtab.setDefaultAccess(accessAttr)