%%============================================================================
%%Abstract:
%%LibraryoffunctionsforgeneratingcodeInfoobjectanditscomponents.
%%
%%Copyright1994-2019TheMathWorks,Inc.
%%
%%
 
%if EXISTS("_CIINFODATALIB_") == 0
%assign _CIINFODATALIB_ = 1
 
%include "codeinfolib.tlc"
%include "autosarsup.tlc"
 
%selectfile NULL_FILE
 
%function FcnReplaceIdentifierToken(fcnName, identifier)
  %assign fcnName = FEVAL("strrep", fcnName, "$N", identifier)
  %return fcnName
%endfunction
 
 
%%FunctionSLibCreateInportInterfaces========================================
%%Abstract:
%%ThisfunctionloopsthroughInportsandcreatesaRTW.DataInterface
%%objectforeachofthem.
%%TheprocessofcreationheremeansemittingouttheMATLABsyntaxwhichcan
%%createaMATLABobject.
%%TheMATLABsyntaxis
%%inportObj=RTW.DataInterface(sid,
%%signalName,
%%implementation,
%%timing)
%%
%%sid-SIDoftheinportblock
%%signalName-Labelofthesignalfrominport(orblockName)
%%implementation-codeimplementation,eitheraRTW.Variableobject
%%oraRTW.StructExpressionobject.
%%timing-ARTW.TimingInterfaceobject,givingthesamplerate
%%oftheinport
%%
%%Thisfunctionwillbecalledincodeinfo.tlcwhichwritesoutMATLABcode.
%%TheMATLABsyntaxemittedbythisfunctionwillbepartofthatfile
%%
%function SLibCreateInportInterfaces() Output
  %% Flag to determine if memory for Inport will be defined by
  %% generated code
  %assign IsInportDefined = ...
    !(SLibFcnProtoCtrlActive() || IsMultiInstanceERTOrModelReference() || ...
    SLibAutosarActive())
  %%
  %% Flag to determine if memory forInport is typed as ExternalInputs structure
  %assign IsInportStructure = ...
    ( IsInportDefined || (MultiInstanceERTCode && RootIOStructures) )
  %%
  %% Start looping over Inports
  %with ::CompiledModel.ExternalInputs
  %assign unsetEIIdx = FcnGetUnsetEIIdxFromIRInfo()
  %foreach idx = SIZE(unsetEIIdx, 1)
    %assign ei = ExternalInput[unsetEIIdx[idx]]
    %assign regObj = "RTW.DataImplementation.empty"
    %if ((ei.StorageClass != "Auto") && (ei.StorageClass != "SimulinkGlobal")) || ...
        SLibIsLegacyStorageClassForDataRecord(ei)
      %% Process storage class data
      %assign cgTypeIdx = ei.CGTypeIdx
      %assign sigID = LibGetRecordIdentifier(ei)
      %assert (ei.StorageClass == "Custom" || SLibIsLegacyStorageClassForDataRecord(ei))
         
      %% Process CSC - custom storage class inputs
      %assign msDefn = SLibGetMemorySectionDefForData(ei)
      %assign cscDefn = SLibGetCSCDefForData(ei)
      %assign isR13CSC = ((SLibGetDataAccess(cscDefn, ei) == "unknown") ? 1 : 0)
      %assign isPtr = ((SLibGetDataAccess(cscDefn, ei)=="Pointer") ? 1 : 0)
      %assign isMPTVar = ISEQUAL(cscDefn.TLCFileName,"MPTUnstructured.tlc")
       %% Determine type qualifers
      %assign ei_const = (msDefn.IsConst ? 1 : 0)
      %assign ei_vol = (msDefn.IsVolatile ? 1 : 0)
      %if (!isR13CSC)
        %% Only the following CSC are supported
        %% - Not a pre-R14 CSC
        %% - Non-Pointer Access
        %if (cscDefn.CSCType == "Unstructured") || isMPTVar
          %% Ungrouped CSC
          %%
          %%
          %% Determine type - Returns a coder.types.* object
          %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, ei_const, ei_vol)
          %if !ISEQUAL(ei.FrameData, "no")
            %assign typeObj = FcnGetMatrixFrameTypeObj(typeObj)
          %endif
          %assign codeTypeObj = typeObj
          %if ISFIELD(ei,"ContainerCGTypeIdx")
            %assign codeTypeObj = SLibGetCoderTypeObject(ei.ContainerCGTypeIdx, ei_const, ei_vol)
          %endif
          %%
          %% If Component exports, add known properties to Variable Object
          %assign ownerName = ""
          %assign defnFile = ""
          %assign declFile = ""
          %assign props = LibGetCustomStorageAttributes(ei)
          %assign dataOwner = LibGetInstanceSpecificProp(cscDefn, props, "Owner")
          %if !ISEMPTY(dataOwner)
            %assign dataIsOwned = (dataOwner == LibGetModelName())
          %else
            %assign dataIsOwned = TLC_TRUE
          %endif
          %assign notOwned = ( SLibIsERTTarget() && ...
            (::CompiledModel.ConfigSet.EnableDataOwnership == TLC_TRUE) && ...
            !dataIsOwned)
          %if (!IsModelReferenceRTWTarget() && !notOwned)
            %if ISFIELD(ei, "FilePackaging") && (!ISEMPTY(ei.FilePackaging))
              %assign defineFileIdx = ei.FilePackaging.DefineFile
              %assign hdrFileName = ei.FilePackaging.HeaderFile
              %if (defineFileIdx != -1)
                %with ::CompiledModel.DataObjectUsage
                  %assign defFileName = File[defineFileIdx].Name
                %endwith
                %assign defnFile = defFileName + "." + ::LangFileExt
                %assign ownerName = ::CompiledModel.Name
                %if (hdrFileName != "")
                  %assign declFile = hdrFileName
                %endif
              %endif
            %endif
          %endif
          %if (isPtr)
            %assign tgtVar = SLibGetRTWVariableObject(sigID, typeObj, ...
                LibGetRecordIdentifier(ei), ownerName, defnFile, declFile)
            %assign pTypeObj = FcnCreatePointerTypeObj(cgTypeIdx, 0, 0)
            %assign regObj = ...
              SLibGetRTWPointerVariableObject(sigID, pTypeObj, ...
              LibGetRecordIdentifier(ei), tgtVar)
          %else
          %%
          %% Create a RTW.Variable object using type, identifer and decl/defn file
          %assign regObj = SLibGetRTWVariableObject(sigID, typeObj, ...
            LibGetRecordIdentifier(ei), ownerName, defnFile, declFile)
          %endif
 
          %<regObj>.StorageSpecifier = 'extern';
          %<regObj>.CodeType = %<codeTypeObj>;
          %%
        %elseif (cscDefn.CSCType == "FlatStructure")
          %% Grouped CSC
          %assign regObjName = "ExternInput%<idx>_CSC"
          %assign regObj = SLibCodeInfoObjectForFlatStructure(ei, cscDefn, regObjName, TLC_FALSE)
          %%
        %elseif (cscDefn.CSCType == "AccessFunction")
          %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, 0, 0)
          %if !ISEQUAL(ei.FrameData, "no")
            %assign typeObj = FcnGetMatrixFrameTypeObj(typeObj)
          %endif
          %assign bIdx = LibGetRecordWidth(ei) == 1 ? "" : "[0]"
          %assign csAttr = LibGetCustomStorageAttributes(ei)
          %assign aReadExpr = FcnReplaceIdentifierToken(LibGetInstanceSpecificProp(cscDefn, csAttr, "GetFunction"), sigID)
          %assign aWriteExpr = FcnReplaceIdentifierToken(LibGetInstanceSpecificProp(cscDefn, csAttr, "SetFunction"), sigID)
          %assign regObj = "ExternInput%<idx>_CSC"
          %<regObj> = RTW.CustomExpression(%<typeObj>,regexprep('%<aReadExpr>','^/[/]$',''),regexprep('%<aWriteExpr>','^/[/]$',''),'');
          %if ISFIELD(LibGetCustomStorageAttributes(ei), "HeaderFile")
             %assign aHeaderFile = LibGetInstanceSpecificProp(cscDefn, csAttr, "HeaderFile")
             %<regObj>.HeaderFile = '%<aHeaderFile>';
          %endif
          %if SLibGetAccessDataThroughMacro(cscDefn)
             %<regObj>.AccessViaMacro = true;
          %endif
        %else
        %% CSC of type "Other"
          %assign regObj = SLibCustomStorageTypeOtherForCodeInfo(ei, cscDefn, TLC_FALSE)
        %endif
      %else
        %% Unsupported CSC
        %% No implementation provided. The default regObj = "[]" will be used
      %endif
    %else
      %% Process Auto storage class data
      %if (IsInportStructure)
        %<LibReportFatalError("CodeInfo: Structured Inports not created")>
      %else
        %% Root Inputs not defined - passed as args or accessed as autosar rte
        %%
        %if (SLibAutosarActive())
          %<LibReportFatalError("CodeInfo: Autosar Inports not created")>
        %else
          %<LibReportFatalError("CodeInfo: IOArg Inports not created")>
        %endif
      %endif
    %endif
    %%
    %% Set the implementation of the Inport appropriately
    %assign comment = "% Setting Inport#%'s implementation"
         
    %<comment>
    codeInfo.Inports(%<FcnGetCIIdxFromEIIdx(unsetEIIdx[idx])>).Implementation = %<regObj>;
    wr.writeRootInport(%<regObj>, codeInfo.Inports(%<FcnGetCIIdxFromEIIdx(unsetEIIdx[idx])>));
     
  %endforeach
  %endwith %%ExternalInputs
%endfunction
 
%%FunctionSLibCreateOutportInterfaces=======================================
%%Abstract:
%%ThisfunctionloopsthroughOutportsandcreatesaRTW.DataInterface
%%objectforeachofthem.
%%TheprocessofcreationheremeansemittingouttheMATLABsyntaxwhichcan
%%createaMATLABobject.
%%TheMATLABsyntaxis
%%outportObj=RTW.DataInterface(sid,
%%signalName,
%%implementation,
%%timing)
%%
%%sid-sidoftheoutportblock
%%signalName-Labelofthesignalfeedingoutport(orblockName)
%%implementation-codeimplementation,eitheraRTW.Variableobject
%%oraRTW.StructExpressionobject.
%%timing-ARTW.TimingInterfaceobject,givingthesamplerate
%%oftheoutport
%%
%%Thisfunctionwillbecalledincodeinfo.tlcwhichwritesoutMATLABcode.
%%TheMATLABsyntaxemittedbythisfunctionwillbepartofthatfile
%%
%function SLibCreateOutportInterfaces() Output
  %%
  %% Determine if memory for ExternalIO will be defined by generated code
  %assign IsOutportDefined = ...
    !(SLibFcnProtoCtrlActive() || IsMultiInstanceERTOrModelReference() || ...
    SLibAutosarActive())
  %%
  %% Determine if memory for Outport is typed as ExternalOutputs structure
  %assign IsOutportStruct = ...
    ( IsOutportDefined || (MultiInstanceERTCode && RootIOStructures) )
  %with ::CompiledModel.ExternalOutputs
  %assign unsetEOIdx = FcnGetUnsetEOIdxFromIRInfo()
  %foreach idx = SIZE(unsetEOIdx, 1)
    %assign eo = ExternalOutput[unsetEOIdx[idx]]
    %assign regObj = "RTW.DataImplementation.empty"
    %%
    %% Get Block and get associated signal record/memory
 
    %assign isLegacyDefaultMapped = TLC_FALSE
 
    %assign eoBlk = ::CompiledModel.System[eo.Block[0]].Block[eo.Block[1]]
    %with eoBlk
      %assign ip = FcnGetInputPortRecord(0)
      %assign numSrcs = 0
      %roll idx = eoBlk.RollRegions, lcv = 1, eoBlk, "FlatRoller", [""]
        %assign numSrcs = numSrcs+1
      %endroll
      %assign sigRec = SLibGetSourceRecord(ip, 0)
      %assign eoStorageClass = LibBlockInputSignalStorageClass(0, 0)
      %assign sigOffset = ip.SignalOffset[0]
      %assign isLegacyDefaultMapped = !ISEMPTY(sigRec) && SLibIsLegacyStorageClassForDataRecord(sigRec)
    %endwith
    %%
    %%
    %% If the outport block has its own signal specification, use that
    %if ((eo.StorageClass != "Auto") && (eo.StorageClass != "SimulinkGlobal")) || ...
        SLibIsLegacyStorageClassForDataRecord(eo)
      %assign sigRec = eo
      %assign eoStorageClass = eo.StorageClass
      %assign isLegacyDefaultMapped = SLibIsLegacyStorageClassForDataRecord(eo)
    %endif
    %if (numSrcs > 1)
      %% do nothing -skip
      %% empty implementation
    %elseif ((eoStorageClass != "Auto") && (eoStorageClass != "SimulinkGlobal")) || ...
      isLegacyDefaultMapped
      %assert (eoStorageClass == "Custom" || isLegacyDefaultMapped)
      %% Process storage class data
      %assign cgTypeIdx = eo.CGTypeIdx
      %assign sigTypeIdx = sigRec.CGTypeIdx
      %assign sigID = LibGetRecordIdentifier(sigRec)
 
      %% Process CSC - custom storage class data
      %assign msDefn = SLibGetMemorySectionDefForData(sigRec)
      %assign cscDefn = SLibGetCSCDefForData(sigRec)
      %assign isR13CSC = ...
        ((SLibGetDataAccess(cscDefn, sigRec) == "unknown") ? 1 : 0)
      %assign isPtr = ((SLibGetDataAccess(cscDefn, sigRec)=="Pointer") ? 1 : 0)
      %assign isMPTVar = ISEQUAL(cscDefn.TLCFileName,"MPTUnstructured.tlc")
      %% Determine type qualifers
      %assign eo_const = (msDefn.IsConst ? 1 : 0)
      %assign eo_vol = (msDefn.IsVolatile ? 1 : 0)
      %if (!isR13CSC)
        %% Only the following CSC are supported
        %% - Not a pre-R14 CSC
        %%
        %if (cscDefn.CSCType == "Unstructured") || isMPTVar
          %% Ungrouped CSC
          %%
          %% Determine type - Returns a coder.types.* object
          %assign typeObj=SLibGetCoderTypeObject(sigTypeIdx, eo_const, eo_vol)
          %if !ISEQUAL(eo.FrameData, "no")
            %assign typeObj = FcnGetMatrixFrameTypeObj(typeObj)
          %endif
          %assign codeTypeObj = typeObj
          %if ISFIELD(eo,"ContainerCGTypeIdx")
            %assign codeTypeObj = SLibGetCoderTypeObject(eo.ContainerCGTypeIdx, eo_const, eo_vol)
          %endif
          %%
          %% If Component exports, add known properties to Variable Object
          %assign defineFileIdx = SLibCustomStorageGetDefineFileIdxIfNecessary(sigRec, cscDefn)
          %assign defnFile = SLibCustomStorageGetDefineFileFromIdx(defineFileIdx)
          %assign ownerName = SLibCustomStorageGetOwnerNameForCodeInfo(defineFileIdx)
          %assign declFile = SLibCustomStorageGetDeclFileForCodeInfo(sigRec, defineFileIdx)
          %assign sigID = LibGetRecordIdentifier(sigRec)
          %%
          %if (isPtr)
              %assign tgtVar = SLibGetRTWVariableObject(sigID, typeObj, ...
                LibGetRecordIdentifier(sigRec), ownerName, defnFile, declFile)
            %assign pTypeObj = FcnCreatePointerTypeObj(cgTypeIdx, 0, 0)
            %assign regObj = ...
              SLibGetRTWPointerVariableObject(sigID, pTypeObj, ...
              LibGetRecordIdentifier(sigRec), tgtVar)
          %else
          %% Create a RTW.Variable object using type, identifer & decl/defn file
          %assign regObj = SLibGetRTWVariableObject(sigID, typeObj, ...
            LibGetRecordIdentifier(sigRec), ownerName, defnFile, declFile)
          %endif
          %assign tgtVar = regObj
          %<regObj>.StorageSpecifier = 'extern';
          %<regObj>.CodeType = %<codeTypeObj>;
          %%
        %elseif (cscDefn.CSCType == "FlatStructure")
          %% Grouped CSC
          %assign regObjName = "ExternOutput%<idx>_CSC"
          %assign regObj = SLibCodeInfoObjectForFlatStructure(sigRec, cscDefn, regObjName, TLC_FALSE)
          %%
        %elseif (cscDefn.CSCType == "AccessFunction")
          %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, 0, 0)
          %if !ISEQUAL(eo.FrameData, "no")
            %assign typeObj = FcnGetMatrixFrameTypeObj(typeObj)
          %endif
          %assign bIdx = LibGetRecordWidth(sigRec) == 1 ? "" : "[0]"
          %assign csAttr = LibGetCustomStorageAttributes(sigRec)
          %assign aReadExpr = FcnReplaceIdentifierToken(LibGetInstanceSpecificProp(cscDefn, csAttr, "GetFunction"),sigID)
          %assign aWriteExpr = FcnReplaceIdentifierToken(LibGetInstanceSpecificProp(cscDefn, csAttr, "SetFunction"),sigID)
          %assign regObj = "ExternInput%<idx>_CSC"
          %<regObj> = RTW.CustomExpression(%<typeObj>,regexprep('%<aReadExpr>','^/[/]$',''),regexprep('%<aWriteExpr>','^/[/]$',''),'');
          %if ISFIELD(LibGetCustomStorageAttributes(sigRec), "HeaderFile")
             %assign aHeaderFile = LibGetInstanceSpecificProp(cscDefn, csAttr, "HeaderFile")
             %<regObj>.HeaderFile = '%<aHeaderFile>';
          %endif
          %if SLibGetAccessDataThroughMacro(cscDefn)
             %<regObj>.AccessViaMacro = true;
          %endif
        %else
          %% CSC of type "Other"
          %assign regObj = SLibCustomStorageTypeOtherForCodeInfo(sigRec, cscDefn, TLC_FALSE)
          %assign tgtVar = regObj
        %endif
        %if ( LibCGTypeWidth">LibCGTypeWidth(sigTypeIdx) > LibCGTypeWidth">LibCGTypeWidth(cgTypeIdx) )
          %if (cscDefn.CSCType == "Unstructured") || ...
                ((cscDefn.CSCType == "Other") && SLibCustomStorageTypeOtherSupportsSILPIL(sigRec, cscDefn))
            %% possible array expression
            %assign arTypeObj = SLibGetCoderTypeObject(cgTypeIdx, eo_const, eo_vol)
            %assign regObj = SLibGetRTWArrayExprObject(arTypeObj, tgtVar, sigOffset)
          %else
            %assign regObj = "RTW.DataImplementation.empty"
          %endif
        %endif
      %else
        %% Unsupported CSC
        %% No implementation provided. The default regObj = "[]" will be used
      %endif
    %else
      %% We may still get here in some edge cases. See:
      %% test/toolbox/rtw/targets/mpt/mmissinginput.mdl
      %% The Port is passed as argument
      %%
      %% Create a type - Returns a coder.types.* object
      %assign typeObj = SLibGetCoderTypeObject(eo.CGTypeIdx, 0, 0)
      %if !ISEQUAL(eo.FrameData, "no")
        %assign typeObj = FcnGetMatrixFrameTypeObj(typeObj)
      %endif
      %%
      %% Create a RTW.Variable object with no owner
      %assign regObj = ...
        SLibGetRTWVariableObject("EO%<idx>", typeObj, LibGetRecordIdentifier(eoBlk),"","","")
    %endif
    %assign comment = "% Setting Outport#%'s Implementation"
         
    %<comment>
    codeInfo.Outports(%).Implementation = %<regObj>;
    wr.writeRootOutport(%<regObj>, codeInfo.Outports(%));
  %endforeach
  %endwith %%ExternalOutputs
%endfunction
 
%%Function:FcnAddRunnableToParamAccessInfo=================================
%%Abstract:
%%Recursivelyrecordsparentrunnable(s)nameofsystem
%%
%function FcnAddRunnableToParamAccessInfo(sysIdx, pAccessInfo, calPrmIdx) void
  %assign system = ::CompiledModel.System[sysIdx]
  %assign runnableIdx = system.RunnableIdx
  %if runnableIdx >= 0
    %assign runName = ...
      ::CompiledModel.RTWAutosar.AutosarRunnables.Runnable[runnableIdx].Name
    %if !ISFIELD(pAccessInfo, runName)
      %addtorecord pAccessInfo %<runName> [%<calPrmIdx>]
    %else
      %assign pAccessInfo.%<runName> = pAccessInfo.%<runName> + calPrmIdx
    %endif
  %else
    %assign numCallers = SIZE(system.CallSites, 0)
    %foreach idx = numCallers
      %<FcnAddRunnableToParamAccessInfo(system.CallSites[idx][0], pAccessInfo, calPrmIdx)>
    %endforeach
  %endif
%endfunction
 
%%FunctionSLibCreateInstanceSpecificParameterInterfaces=====================================
%%Abstract:
%%ThisfunctionloopsthroughInstance-SpecificParametersandcreatesaRTW.DataInterface
%%objectforeachofthem.
%%TheprocessofcreationheremeansemittingouttheMATLABsyntaxwhichcan
%%createaMATLABobject.
%%TheMATLABsyntaxis
%%paramObj=RTW.DataInterface(sid,
%%paramName,
%%implementation,
%%timing)
%%
%%sid-Either''(forWorkspaceVariables)orSIDofmodel.
%%IncaseInlinedParametersisoff,SIDoftheblock
%%usingtheParameter.
%%paramName-NameofParameter
%%implementation-codeimplementation,eitheraRTW.Variableobject
%%oraRTW.StructExpressionobject.
%%timing-ARTW.TimingInterfaceobjectindicatingthatparams
%%areupdatedatonetime.
%%
%%Thisfunctionwillbecalledincodeinfo.tlcwhichwritesoutMATLABcode.
%%TheMATLABsyntaxemittedbythisfunctionwillbepartofthatfile
%%
%function SLibCreateInstanceSpecificParameterInterfaces() Output
 
  %with ::CompiledModel.ModelParameters
  %assign unsetParamPairs = FcnGetInstanceSpecificParamIdxFromIRInfo()
  %foreach idx = SIZE(unsetParamPairs, 0)
    %assign unsetParamIdx = unsetParamPairs[idx]
    %assign param = Parameter[unsetParamIdx[0]]
     
     %% skip protected parameters. They should not be present in codeinfo
    %if (ISEQUAL(param.Protected, "yes"))
      %continue
    %endif
 
    %assert(param.InstanceSpecific)
 
        %if !ISFIELD(param, "ChildGroupSID")
          %continue
        %endif
 
        InstParamArray = RTW.StructExpression.empty;
    
        %assign cgTypeIdx = SLibGetRecordOriginalCGTypeIdx(param)
        %%
        %% Determine type - Returns a coder.types.* object
        %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, 0, 0)
        %%
         
        %assign coderCgTypeIdx = cgTypeIdx
        %% Get CoderType Object
        %if ISFIELD(param, "ContainerCGTypeIdx")
           %assign coderCgTypeIdx = param.ContainerCGTypeIdx
        %endif
 
        %% We will use the type and codetype when we finally create the DataImplementation
        %% for the parameter itself, and not the outer struct accesses
        %assign codeTypeObj = SLibGetCoderTypeObject(coderCgTypeIdx, 0, 0)
 
        %% Often, parameter identifiers have numbers in the named, such as
        %% 4.152.ParamName
        %% This regexpr gets rid of 4.152 as the actual struct member will be ParamName
        %assign paramName = LibGetRecordIdentifier(param)
        %assign regexp = "//d*//.*//d*//."
        %assign fixedParamName = FEVAL("regexprep", paramName, regexp, "")
        %assign fixedFullPath = FcnParamExternalPath(param)
        %% The ExternalFullPath may or may not have a "." member operator on the end
        %% Get rid of it because we will call strsplit to get the member names
        %if fixedFullPath[SIZE(fixedFullPath,1)-1] == "."
           %assign fixedFullPath = Substring(fixedFullPath,0,SIZE(fixedFullPath,1)-1)
        %endif
        %% Turn "a.b.c.d" into ["a", "b", "c", "d"]
        %assign structMemberNames = FEVAL("strsplit", fixedFullPath, ".")
       %% Iterate over every struct member in ExternalFullPath
       %foreach idx = SIZE(structMemberNames, 1)
          %assign curName = structMemberNames[idx]
          %% The first iteration is special, because we need to either look up the existing root-level
          %% struct from InternalData, or create it and add it outselves
          %if idx == 0
            %if FcnPropagatedParamSingleInstancePropagator(param)
               %assign typeName = FcnPropagatedParamSingleInstanceType(param)
               %assign desc = "Storage class " + typeName
               group_var_exists = 0;
               for idx = 1:numel(codeInfo.InternalData)
                curr_var = codeInfo.InternalData(idx).Implementation;
                if isa(curr_var,'RTW.Variable') && strcmp(curr_var.Identifier, '%<curName>')
                   instPDataInterface = codeInfo.InternalData(idx);
                   groupVar = curr_var;
                   group_var_exists = 1;
                   break;
                end
               end
               if ~group_var_exists
                  groupType = coder.types.Opaque;
                  groupType.Identifier = '%<typeName>';
                  groupVar = RTW.Variable(groupType, '%<curName>');
                  instPDataInterface = RTW.DataInterface('', '%<desc>', groupVar, RTW.TimingInterface.empty);
               end
               %assign groupVar = "groupVar"
            %else
                %assign groupIndex = FcnPropagatedParamGroupIndex(param)
                %assign group = ::CompiledModel.CoderDataGroup[groupIndex]
                %assign typeObjName = group.Name + "Type"
                %assign groupType = FcnGetInternalTypeObj(typeObjName, SLibCoderDataGroupType(group), "")
                %assign groupVar = SLibGetCoderDataGroupVariable(group)
                %assign desc = "Storage class " + group.Name
                %% If we did not find the root level in InternalData add it now
                instPDataInterface = RTW.DataInterface('', '%<desc>', %<groupVar>, RTW.TimingInterface.empty);
             %endif
             %if !IsMultiInstanceERTOrModelReference()
                %<groupVar>.Owner = '%<::CompiledModel.Name>';
             %endif
             if group_var_exists == 0
                codeInfo.InternalData = [codeInfo.InternalData instPDataInterface];
             end
             wr.writeInternalData(instPDataInterface);
             type = coder.types.AggregateElement;
             type.Type = coder.types.Opaque;
             %if SIZE(structMemberNames,1) == 1
                %% If the size of structMemberNames is 1, which would occur with something like ExternalFullPath
                %% being "InstP", we only need to generate a single StructExpression with the final param name
                type.Identifier = '%<fixedParamName>';
             %else
                type.Identifier = '%';
             %endif
             %% Here, we store each StructExpression in a vector, so we can easily access the previous StructExpression we added
             InstParamArray(%) = RTW.StructExpression(type, %<groupVar>);
             InstParamArray(%).Type = coder.types.Opaque;
             InstParamArray(%).CodeType = coder.types.Opaque;
           %% If this is not the first iteration, we already made the first StructExpression pointing to the
           %% root struct, and we now need to generate the rest of the StructExpressions
           %else
              type = coder.types.AggregateElement;
              %% If this is the last iteration, we need to use the paramName as the type's identifier, which
              %% will be used for ElementIdentifier in the StructExpression
              %if idx == SIZE(structMemberNames,1) - 1
              type.Identifier = '%<fixedParamName>';
              %else
              type.Identifier = '%';
              %endif
              type.Type = coder.types.Opaque;
              InstParamArray(%) = RTW.StructExpression(type, InstParamArray(%<idx>));
              %% We shouldn't use an Opaque type if this is the last iteration, because we can easily get the
              %% type of the parameter, which will be the type of the StructExpression
              %if idx != SIZE(structMemberNames,1) - 1
                   InstParamArray(%).Type = coder.types.Opaque;
                   InstParamArray(%).CodeType = coder.types.Opaque;
              %endif
          %endif
       %endforeach
       %% Write the final element of the map to codeInfo
       %% It contains the nested StructExpressions
        codeInfo.Parameters(%).Implementation = InstParamArray(size(InstParamArray,2));
        codeInfo.Parameters(%).Type = %<typeObj>;
        codeInfo.Parameters(%).Implementation.Type = %<typeObj>;
        codeInfo.Parameters(%).Implementation.CodeType = %<codeTypeObj>;
 
        %% Also write to CodeDescriptor
        wr.writeInstanceSpecificParameterArgument(codeInfo.Parameters(%).Implementation, %);
       %continue
  %endforeach
 %endwith
%endfunction
 
%%FunctionSLibCreateParameterInterfaces=====================================
%%Abstract:
%%ThisfunctionloopsthroughParameterandcreatesaRTW.DataInterface
%%objectforeachofthem.
%%TheprocessofcreationheremeansemittingouttheMATLABsyntaxwhichcan
%%createaMATLABobject.
%%TheMATLABsyntaxis
%%paramObj=RTW.DataInterface(sid,
%%paramName,
%%implementation,
%%timing)
%%
%%sid-Either''(forWorkspaceVariables)orSIDofmodel.
%%IncaseInlinedParametersisoff,SIDoftheblock
%%usingtheParameter.
%%paramName-NameofParameter
%%implementation-codeimplementation,eitheraRTW.Variableobject
%%oraRTW.StructExpressionobject.
%%timing-ARTW.TimingInterfaceobjectindicatingthatparams
%%areupdatedatonetime.
%%
%%Thisfunctionwillbecalledincodeinfo.tlcwhichwritesoutMATLABcode.
%%TheMATLABsyntaxemittedbythisfunctionwillbepartofthatfile
%%
%function SLibCreateParameterInterfaces() Output
  %%
  %% Flag to determine if memory for Parameters are typed as structure
  %assign isParamsStructured = !SLibAreSimulinkGlobalParamsUnstructured()
  %if (SLibAutosarActive())
    %if !ISFIELD(::CompiledModel.RTWAutosar, "ParamAccessInfo")
      %addtorecord ::CompiledModel.RTWAutosar ParamAccessInfo {}
      %addtorecord ::CompiledModel.RTWAutosar ParamNameToIdxMap {}
    %endif
  %endif
  %%
  %with ::CompiledModel.ModelParameters
  %assign unsetParamPairs = FcnGetUnsetParamIdxFromIRInfo()
  %foreach idx = SIZE(unsetParamPairs, 0)
    %assign unsetParamIdx = unsetParamPairs[idx]
    %assign param = Parameter[unsetParamIdx[0]]
    %assign regObj = "RTW.DataImplementation.empty"
    %% skip protected parameters. They should not be present in codeinfo
    %if (ISEQUAL(param.Protected, "yes"))
      %continue
    %endif
 
    %% Please note some instance Specific parameters will be handled specially in
    %% SLibCreateInstanceSpecificParameterInterfaces
 
    %assign isParamDefaultMapped = SLibIsLegacyStorageClassForDataRecord(param)
    %if ((param.StorageClass !="Auto") && (param.StorageClass !="SimulinkGlobal")) || ...
         isParamDefaultMapped
      %if ISFIELD(param, "OrigIdentifier") && !ISEMPTY(param.OrigIdentifier)
        %assign paramRTWId = param.OrigIdentifier
      %else
        %assign paramRTWId = LibGetRecordIdentifier(param)
      %endif
 
      %if !isParamDefaultMapped
        checkDataGraphicalNames(codeInfo.Parameters(%).GraphicalName, '%<paramRTWId>');
      %endif
 
      %assign sc = param.StorageClass
      %assign IsAutosarCalPrm = TLC_FALSE
      %if (SLibAutosarActive() && (sc == "Custom" || isParamDefaultMapped))
          %assign rtwInfo = LibGetRTWInfoObjectProperties(param)
          %assign csAttribs = rtwInfo.CustomAttributes.Object
          %assign isParamReferenced = SIZE(param.GraphicalRef,0) > 0 || ISFIELD(param,"UsedInSLExpr")
          %assign IsAutosarCalPrm = !ISEMPTY(csAttribs) && ...
             ((ISFIELD(csAttribs, "Package") && ISEQUAL(csAttribs.Package, "SimulinkCSC")) && ...
             isParamReferenced && (ISFIELD(csAttribs, "Class")) && ...
             (ISEQUAL(csAttribs.Class, "AttribClass_AUTOSAR_CalPrm") || ...
              ISEQUAL(csAttribs.Class, "AttribClass_AUTOSAR_InternalCalPrm") || ...
              ISEQUAL(csAttribs.Class, "AttribClass_AUTOSAR_SystemConstant") ) )
      %endif
 
      %% Process storage class data
      %assign cgTypeIdx = SLibGetRecordOriginalCGTypeIdx(param)
      %assign containerCgTypeIdx = SLibGetRecordContainerCGTypeIdx(param)
      %assign containerTypeObj = ""
       
      %if (IsAutosarCalPrm)
        %%
        %% Get Custom attributes from the parameter
        %assign rtwInfo = LibGetRTWInfoObjectProperties(param)
        %assign csAttribs = rtwInfo.CustomAttributes.Object
        %assert (!ISEMPTY(csAttribs))
        %%
        %% Autosar CSC parameters
        %assign cgTypeIdx = SLibGetRecordOriginalCGTypeIdx(param)
        %%
        %% Determine type - Returns a coder.types.* object
        %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, 0, 0)
        %%
         
        %assign coderCgTypeIdx = cgTypeIdx
        %% Get CoderType Object
        %if ISFIELD(param, "ContainerCGTypeIdx")
           %assign coderCgTypeIdx = param.ContainerCGTypeIdx
        %endif
 
        %assign coderTypesObj = SLibGetCoderTypeObject(coderCgTypeIdx, 0, 0)
 
        %if ISFIELD(param, "OrigIdentifier") && !ISEMPTY(param.OrigIdentifier)
          %assign paramId = param.OrigIdentifier
        %else
          %assign paramId = LibGetRecordIdentifier(param)
        %endif
        %if !isParamDefaultMapped
          checkDataGraphicalNames(codeInfo.Parameters(%).GraphicalName, '%<paramId>');
        %endif
        %assign regObj = SLibGetRTWCalibrationObject("Par%<idx>", typeObj, LibGetRecordIdentifier(param), csAttribs, coderTypesObj)
         
        %%
        %% Update CalPrm Access info for autosar target
        %assign calPrmIdx = unsetParamIdx[1] + 1
        %assign isSysConst = ISEQUAL(csAttribs.Class, "AttribClass_AUTOSAR_SystemConstant")
        %if ( SLibAutosarActive() && !isSysConst)
          %addtorecord ::CompiledModel.RTWAutosar.ParamNameToIdxMap %<paramId> %<calPrmIdx>
          %assign runnables = FIELDNAMES(param.RunnableAccessInfo)
          %assign numRunnables = SIZE(runnables, 1)
          %foreach runIdx = numRunnables
            %assign runName = runnables[runIdx]
            %assign pAccessInfo = ::CompiledModel.RTWAutosar.ParamAccessInfo
            %if !ISFIELD(pAccessInfo, runName)
              %addtorecord pAccessInfo %<runName> [%<calPrmIdx>]
            %else
              %assign pAccessInfo.%<runName> = pAccessInfo.%<runName> + calPrmIdx
            %endif
          %endforeach
        %endif
        %% Done CalPrmAccess info
      %else
        %%
        %% Process CSC - custom storage class data
        %assign msDefn = SLibGetMemorySectionDefForData(param)
        %assign cscDefn = SLibGetCSCDefForData(param)
        %assign isR13CSC = ...
          ((SLibGetDataAccess(cscDefn, param) == "unknown") ? 1 : 0)
        %assign isMacro = ...
          ((SLibGetDataInitForData(cscDefn, param) == "Macro") ? 1: 0)
        %if isMacro
          skippedParameters(end+1) = %;
          %continue
        %endif
        %assign isPtr = ...
          ((SLibGetDataAccess(cscDefn, param)=="Pointer") ? 1 : 0)
        %assign isMPTVar = ISEQUAL(cscDefn.TLCFileName,"MPTUnstructured.tlc")
        %% Determine type qualifers
        %assign p_const = (msDefn.IsConst ? 1 : 0)
        %assign p_vol = (msDefn.IsVolatile ? 1 : 0)
        %if ( !isR13CSC && !isMacro)
          %% Only the following CSC are supported
          %% - Not a pre-R14 CSC
          %%
          %if (cscDefn.CSCType == "Unstructured") || isMPTVar
            %% Ungrouped CSC
            %%
            %% Determine type - Returns a coder.types.* object
            %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, p_const, p_vol)
            %assign containerTypeObj = SLibGetCoderTypeObject(containerCgTypeIdx, p_const, p_vol)
            %%
            %% If Component exports, add known properties to Variable Object
            %assign ownerName = ""
            %assign defnFile = ""
            %assign declFile = ""
            %assign props = LibGetCustomStorageAttributes(param)
            %assign dataOwner = LibGetInstanceSpecificProp(cscDefn, props, "Owner")
            %if !ISEMPTY(dataOwner)
              %assign dataIsOwned = (dataOwner == LibGetModelName())
            %else
              %assign dataIsOwned = TLC_TRUE
            %endif
            %assign isFileScope = TLC_FALSE
            %assign notOwned = ( SLibIsERTTarget() && ...
              (::CompiledModel.ConfigSet.EnableDataOwnership == TLC_TRUE) && ...
              !dataIsOwned)
            %if (!IsModelReferenceRTWTarget() && !notOwned)
              %if ISFIELD(param, "FilePackaging") && !ISEMPTY(param.FilePackaging)
                %assign defineFileIdx = param.FilePackaging.DefineFile
                %assign hdrFileName = param.FilePackaging.HeaderFile
                %if (defineFileIdx != -1)
                  %with ::CompiledModel.DataObjectUsage
                    %assign defFileName = File[defineFileIdx].Name
                  %endwith
                  %assign defnFile = defFileName + "." + ::LangFileExt
                  %assign ownerName = ::CompiledModel.Name
                  %if (hdrFileName != "")
                    %assign declFile = hdrFileName
                  %endif
                %endif
                %assign isFileScope = ...
                  ISEMPTY(param.FilePackaging.FilesWithDeclare) && ...
                  ISEMPTY(param.FilePackaging.FilesWithInclude)
              %endif
            %endif
            %%
            %% For Indirect access, add level of indirection to type
            %if (SLibGetDataAccess(cscDefn, param) == "Pointer")
              %assign tgtVar = SLibGetRTWVariableObject("Par%<idx>",typeObj, ...
                "%<LibGetRecordIdentifier(param)>_val", "","","")
              %assign pTypeObj = FcnCreatePointerTypeObj(cgTypeIdx,0, 0)
              %assign regObj = ...
                SLibGetRTWPointerVariableObject("Par%<idx>", pTypeObj, ...
                LibGetRecordIdentifier(param), tgtVar)
            %else
              %% Create a RTW.Variable object using type, identifer, decl/defn file
              %assign regObj = SLibGetRTWVariableObject("Par%<idx>",typeObj, ...
                LibGetRecordIdentifier(param), ownerName, defnFile, declFile)
            %endif
            %if isFileScope
              %<regObj>.StorageSpecifier = 'static';
            %else
              %<regObj>.StorageSpecifier = 'extern';
            %endif
            %%
          %elseif (cscDefn.CSCType == "FlatStructure")
            %% Grouped CSC
            %assert(LibCGTypeIsMatrix(cgTypeIdx))
            %assign regObjName = "ModelParameter%<idx>_CSC"
            %assign regObj = SLibCodeInfoObjectForFlatStructure(param, cscDefn, regObjName, TLC_TRUE)
            %%
        %elseif (cscDefn.CSCType == "AccessFunction")
            %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, 0, 0)
            %assign bIdx = LibGetRecordWidth(param) == 1 ? "" : "[0]"
            %assign csAttr = LibGetCustomStorageAttributes(param)
            %assign aReadExpr = FcnReplaceIdentifierToken(LibGetInstanceSpecificProp(cscDefn, csAttr, "GetFunction"),LibGetRecordIdentifier(param))
            %assign aWriteExpr = FcnReplaceIdentifierToken(LibGetInstanceSpecificProp(cscDefn, csAttr, "SetFunction"),LibGetRecordIdentifier(param))
            %assign regObj = "ExternInput%<idx>_CSC"
 
            %<regObj> = RTW.CustomExpression(%<typeObj>,regexprep('%<aReadExpr>','^/[/]$',''),regexprep('%<aWriteExpr>','^/[/]$',''),'');
             
            %if ISFIELD(LibGetCustomStorageAttributes(param), "HeaderFile")
               %assign aHeaderFile = LibGetInstanceSpecificProp(cscDefn, csAttr, "HeaderFile")
               %<regObj>.HeaderFile = '%<aHeaderFile>';
            %endif
            %if SLibGetAccessDataThroughMacro(cscDefn)
             %<regObj>.AccessViaMacro = true;
            %endif
          %else
            %% CSC of type "Other"
            %assign regObj = SLibCustomStorageTypeOtherForCodeInfo(param, cscDefn, TLC_TRUE)
          %endif
        %else
          %% Unsupported CSC
          %% No implementation provided. The default regObj = "[]" will be used
        %endif
      %endif
    %else %%
      %if ( !(ISEQUAL(param.Tunable, "yes") && ...
        ISEQUAL(param.IsSfcnSizePrm, 0) && ...
        !ISEMPTY(param.Value)) )
        %<LibReportFatalError("CodeInfo: Unsupported parameter")>
      %endif
      %%
      %assign cgTypeIdx = SLibGetRecordOriginalCGTypeIdx(param)
      %%
      %% Determine type - Returns a coder.types.* object
      %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, 0, 0)
      %%
      %if SLibIsParamUnstructured(param)
        %%
        %% Create a RTW.Variable object
        %assign paramName = "%<tUnstructParameters>_%<LibGetRecordIdentifier(param)>"
        %if (!IsModelReferenceRTWTarget())
          %assign ownerName = ::CompiledModel.Name
          %assign defnFile = "%<::CompiledModel.Name>_data." + ::LangFileExt
          %assign declFile = "%<::CompiledModel.Name>.h"
        %else
          %assign ownerName = ""
          %assign defnFile = ""
          %assign declFile = ""
        %endif
        %assign regObj = ...
          SLibGetRTWVariableObject("Par%<idx>", typeObj, paramName, ...
          ownerName, defnFile, declFile)
        %<regObj>.StorageSpecifier = 'extern';
        %%
      %else
        %%
        %if (param.WasAccessedAsVariable != 1)
          skippedParameters(end+1) = %;
        %endif
        %continue
        %%
        %%
      %endif
      %%
    %endif
    %%
    %% Create a RTW.DataInterface object which describes the parameter
    %assign comment = "% Setting Parameter#%'s implementation"
     
    %<comment>
    codeInfo.Parameters(%).Implementation = %<regObj>;
    %if !ISEMPTY(containerTypeObj)
    codeInfo.Parameters(%).Implementation.CodeType = %<containerTypeObj>;
    %endif
    wr.writeParameter(%<regObj>, codeInfo.Parameters(%).GraphicalName);
  %endforeach
  %assign arSharedParamPairs =FcnGetArSharedParamIdxFromIRInfo()
  %foreach idx = SIZE(arSharedParamPairs, 0)
    %assign arSharedParamIdx = arSharedParamPairs[idx]
    %assign param = Parameter[arSharedParamIdx[0]]
    %assign calPrmIdx = arSharedParamIdx[1] + 1
    %if ISFIELD(param, "OrigIdentifier") && !ISEMPTY(param.OrigIdentifier)
      %assign paramId = param.OrigIdentifier
    %else
      %assign paramId = LibGetRecordIdentifier(param)
    %endif
    %addtorecord ::CompiledModel.RTWAutosar.ParamNameToIdxMap %<paramId> %<calPrmIdx>
    %assign runnables = []
    %if ISFIELD(param, "RunnableAccessInfo")
        %assign runnables = FIELDNAMES(param.RunnableAccessInfo)
    %endif
    %assign numRunnables = SIZE(runnables, 1)
    %foreach runIdx = numRunnables
      %assign runName = runnables[runIdx]
      %assign pAccessInfo = ::CompiledModel.RTWAutosar.ParamAccessInfo
      %if !ISFIELD(pAccessInfo, runName)
        %addtorecord pAccessInfo %<runName> [%<calPrmIdx>]
      %else
        %assign pAccessInfo.%<runName> = pAccessInfo.%<runName> + calPrmIdx
      %endif
    %endforeach
  %endforeach
  %endwith
  %if (SLibAutosarActive())
    %assign mdlRefBlks = ISFIELD(::CompiledModel,"ModelReferenceBlocks") ? ...
      ::CompiledModel.ModelReferenceBlocks : []
    %if !ISEMPTY(mdlRefBlks)
      %foreach rowIdx = SIZE(mdlRefBlks,0)
        %assign mdlRefInfo = mdlRefBlks[rowIdx]
        %assign mSysIdx = mdlRefInfo[0]
        %assign bIdx = mdlRefInfo[1]
        %assign blkInterface = GetModelrefInterface(System[mSysIdx].Block[bIdx])
        %%
        %% Add Init Runnable Access
        %assign initAccess = ...
          FIELDNAMES(blkInterface.AutosarParamAccessInfo.InitializeAccess)
        %assign numInitAccess = SIZE(initAccess, 1)
        %foreach pIdx = numInitAccess
          %assign paramName = initAccess[pIdx]
          %assign calPrmIdx = ...
            GETFIELD(::CompiledModel.RTWAutosar.ParamNameToIdxMap, paramName)
          %assign pAccessInfo = ::CompiledModel.RTWAutosar.ParamAccessInfo
          %assign runName = ::CompiledModel.RTWAutosar.InitRunnables.Runnable[0].Name
          %if !ISFIELD(pAccessInfo, runName)
            %addtorecord pAccessInfo %<runName> [%<calPrmIdx>]
          %else
            %assign pAccessInfo.%<runName> = pAccessInfo.%<runName> + calPrmIdx
          %endif
        %endforeach
        %%
        %% Add Out Runnable Access
        %assign outAccess = ...
          FIELDNAMES(blkInterface.AutosarParamAccessInfo.OutputAccess)
        %assign numOutAccess = SIZE(outAccess, 1)
        %foreach pIdx = numOutAccess
          %assign paramName = outAccess[pIdx]
          %assign calPrmIdx = ...
            GETFIELD(::CompiledModel.RTWAutosar.ParamNameToIdxMap, paramName)
          %assign pAccessInfo = ::CompiledModel.RTWAutosar.ParamAccessInfo
          %<FcnAddRunnableToParamAccessInfo(mSysIdx, pAccessInfo, calPrmIdx)>
        %endforeach
      %endforeach
    %endif
  %endif
%endfunction
 
%%FunctionSLibCreateParameterArguments=====================================
%%Abstract:
%%ThisfunctionloopsthroughModelArgumentsandcreatesaRTW.DataInterface
%%objectforeachofthem.
%%TheprocessofcreationheremeansemittingouttheMATLABsyntaxwhichcan
%%createaMATLABobject.
%%TheMATLABsyntaxis
%%paramObj=RTW.DataInterface(modelSID,
%%paramName,
%%implementation,
%%[])
%%
%%modelSID-SIDofmodel(referencedmodel)
%%paramName-Nameofmodelargument
%%implementation-codeimplementation,aRTW.Variableobject
%%
%%Thisfunctionwillbecalledincodeinfo.tlcwhichwritesoutMATLABcode.
%%TheMATLABsyntaxemittedbythisfunctionwillbepartofthatfile
%%
%function SLibCreateParameterArguments() Output
  tmpParams = [];
  %if IsModelReferenceTarget()
    %assign baseIdx = GetBaseSystemIdx()
    %with System[baseIdx].Interface
    %% create a map to store the index that each newly added
    %% parameter will have in the codeInfo.Parameters array
    %assign mapValuePrmIdx = 0
    prmIdxMap = containers.Map;
    prmStartIdx = length(codeInfo.Parameters) + 1;
      %foreach argIdx=NumCanonicalPrmArgDefs
        %assign canPrmDef = CanonicalPrmArgDef[argIdx]
        %% If the canPrmDef is a grouped argument do not add a new
        %% RTW.DataInterface to codeInfo.Parameters.
        %% RTWParameterBuilder.cpp adds the grouped arguments to codeInfo.
        %if (canPrmDef.IsUsed == "no") || ...
            (ISFIELD(canPrmDef, "ModelParamGroup") && !IsModelReferenceSimTarget())
          %continue
        %endif
        %assign argCGTypeIdx = canPrmDef.CGTypeIdx
        %%
        %% Determine type - Returns a coder.types.* object
        %assign typeObj = SLibGetCoderTypeObject(argCGTypeIdx, 0, 0)
        %%
        %% Create a RTW.Variable object
        %% use LibGetRecordIdentifier instead of Globalidentifier
        %% For SIMTarget, we use a pointer variable to get the
        %% parameter out of Simulink.
        %if IsModelReferenceSimTarget()
          %assign prmCgType = ::CompiledModel.CGTypes.CGType[argCGTypeIdx]
          %if (LibCGTypeIsMatrix(argCGTypeIdx) && (LibGetRecordWidth(canPrmDef) > 1)) || ...
            (LibCGTypeIsStruct(LibCGTypeBaseIndex(argCGTypeIdx)))
            %assign baseTypeObj = SLibGetCoderTypeObject(LibCGTypeBaseIndex(argCGTypeIdx), 0, 0)
          %else
            %assign baseTypeObj = typeObj
          %endif
          %assign pTypeObj = FcnGetPointerTypeObj(baseTypeObj, 0, 0)
          %assign regObj = SLibGetRTWVariableObject("CanPar%<argIdx>",pTypeObj, ...
            LibGetRecordIdentifier(canPrmDef), "", "", "")
        %else
          %assert IsModelReferenceRTWTarget()
          %assign regObj = ...
            SLibGetRTWVariableObject("CanPar%<argIdx>",typeObj, ...
            LibGetRecordIdentifier(canPrmDef), "", "", "")
        %endif
        %%
        %%
        %% Create a RTW.DataInterface object which describes the parameter
        %assign paramTimeObj = SLibGetRTWTimingObject("constant")
        %assign comment = "% Parameter Arg %<argIdx>: Data Interface"
        %assign paramId = SLibGetModelArgumentIdentifier(canPrmDef, argIdx)
        %<comment>
        temp_P = RTW.DataInterface(codeInfo.GraphicalPath, '%<paramId>', %<regObj>, %<paramTimeObj>);
        %% update the map to store the index of the new parameter
        %assign mapKey = canPrmDef.ArgSrc
        assert(~prmIdxMap.isKey('%<mapKey>'),'%<mapKey> is already a key in prmIdxMap.');
        prmIdxMap('%<mapKey>') = prmStartIdx + %<mapValuePrmIdx>;
        %assign mapValuePrmIdx = mapValuePrmIdx + 1
        tmpParams = [tmpParams; temp_P];
        codeInfo.Parameters = [codeInfo.Parameters, temp_P];
        wr.writeParameterArgument(%<regObj>, temp_P.GraphicalName, temp_P.SID);
      %endforeach
    %endwith
  %endif
  %return "tmpParams"
%endfunction
 
%%FunctionSLibCreateDataStoreInterfaces========================================
%%Abstract:
%%ThisfunctionloopsthroughDataStoresandcreatesaRTW.DataInterface
%%objectforeachofthem.
%%TheprocessofcreationheremeansemittingouttheMATLABsyntaxwhichcan
%%createaMATLABobject.
%%TheMATLABsyntaxis
%%dStoreObj=RTW.DataInterface(sid,
%%dataStoreName,
%%implementation,
%%timing)
%%
%%sid-SIDoftheDataStoreMemoryblock.
%%IfGlobalDSM,sid==''
%%dataStoreName-Nameofthedatastore
%%implementation-codeimplementation,eitheraRTW.Variableobject
%%oraRTW.StructExpressionobject.
%%timing-ARTW.TimingInterfaceobject,givingthesamplerate
%%ofthedatastore
%%
%%Thisfunctionwillbecalledincodeinfo.tlcwhichwritesoutMATLABcode.
%%TheMATLABsyntaxemittedbythisfunctionwillbepartofthatfile
%%
%function SLibCreateDataStoreInterfaces() Output
  %% Start looping over DWorks
 
  %with ::CompiledModel.DWorks
  %assign unsetDSMIdx = FcnGetUnsetDSMIdxFromIRInfo()
  %assign dwIdx = 0
  %if SLibAutosarActive() && !ISFIELD(::CompiledModel.RTWAutosar, "DSMAccessInfo")
    %addtorecord ::CompiledModel.RTWAutosar DSMAccessInfo {}
  %endif
  %foreach idx = SIZE(unsetDSMIdx, 1)
    %assign dw = DWork[unsetDSMIdx[idx]]
    %if ISFIELD(dw, "OrigIdentifier") && !ISEMPTY(dw.OrigIdentifier)
      %assign dwRTWId = dw.OrigIdentifier
      checkDataGraphicalNames(codeInfo.DataStores(%).GraphicalName, '%<dwRTWId>');
    %else
      %% do nothing, because RTWID could be mangled in rtwgen.
    %endif
    %assign regObj = "RTW.DataImplementation.empty"
    %% Is it a Shared Local
    %assign isSharedLocalDSM = (dw.SharedLocalDSM || dw.SharedLocalDSMForSubmodel)
    %% Check that interface DSM is never be put into DWork structure.
    %if (ISFIELD(dw, "VarGroupIdx") || ISEQUAL(dw.StorageClass, "Auto")) && !SLibIsLegacyStorageClassForDataRecord(dw)
        %continue
    %endif
    %% Process storage class data
    %assign cgTypeIdx = dw.CGTypeIdx
    %assign containerCgTypeIdx = ""
    %if ISFIELD(dw, "ContainerCGTypeIdx")
      %assign containerCgTypeIdx = dw.ContainerCGTypeIdx
    %endif
    %assign containerTypeObj = ""
    %if (dw.StorageClass != "Custom") && !SLibIsLegacyStorageClassForDataRecord(dw)
      %% Process datastores configured with eitther of the following storage classes
      %% 1) ExportedGlobal 2) ImportedExtern, 3) ImportedExternPointer
      %%
      %% Determine type qualifers
      %assign dw_const = 0
      %assign dw_vol = 0
      %if !ISEMPTY(dw.StorageTypeQualifier)
        %if (dw.StorageTypeQualifier == "const volatile")
          %assign dw_const = 1
          %assign dw_vol = 1
        %elseif (dw.StorageTypeQualifier == "const")
          %assign dw_const = 1
        %elseif (dw.StorageTypeQualifier == "volatile")
          %assign dw_vol = 1
        %endif
      %endif
      %%
      %% Determine type - Returns a coder.types.* object
      %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, dw_const, dw_vol)
      %if !ISEMPTY(containerCgTypeIdx)
        %assign containerTypeObj = SLibGetCoderTypeObject(containerCgTypeIdx, dw_const, dw_vol)
      %endif
      %%
      %% If ExportedGlobal, the datastore's definition & declaration file are known
      %if ((!IsModelReferenceRTWTarget() || isSharedLocalDSM) && ...
        (dw.StorageClass == "ExportedGlobal"))
        %assign ownerName = ::CompiledModel.Name
        %assign defnFile = "%<::CompiledModel.Name>." + ::LangFileExt
        %assign declFile = "%<::CompiledModel.Name>.h"
      %else
        %assign ownerName = ""
        %assign defnFile = ""
        %assign declFile = ""
      %endif
      %%
      %% For datastore which is scalar and configured as ImportedExternPointer,
      %% add level of indirection to type
      %if (dw.StorageClass == "ImportedExternPointer")
        %assign tgtVar = SLibGetRTWVariableObject("DW%<idx>", typeObj, ...
          "%<LibGetRecordIdentifier(dw)>_val", "","","")
        %assign pTypeObj = FcnCreatePointerTypeObj(cgTypeIdx, 0, 0)
        %assign regObj = ...
          SLibGetRTWPointerVariableObject("DW%<idx>", pTypeObj, ...
          LibGetRecordIdentifier(dw), tgtVar)
      %else
        %%
        %% Create a RTW.Variable object using type, identifer and decl/defn file
        %assign regObj = SLibGetRTWVariableObject("DW%<idx>", typeObj, ...
          LibGetRecordIdentifier(dw), ownerName, defnFile, declFile)
      %endif
      %<regObj>.StorageSpecifier = 'extern';
      %%
    %else
      %% Process CSC - custom storage class datastores
      %assign msDefn = SLibGetMemorySectionDefForData(dw)
      %assign cscDefn = SLibGetCSCDefForData(dw)
      %assign isR13CSC = ((SLibGetDataAccess(cscDefn, dw) == "unknown") ? 1 : 0)
      %assign isPtr = ((SLibGetDataAccess(cscDefn, dw)=="Pointer") ? 1 : 0)
      %assign isPIM = ISFIELD(cscDefn, "IsAutosarPerInstanceMemory") && ...
        cscDefn.IsAutosarPerInstanceMemory
      %assign isMPTVar = ISEQUAL(cscDefn.TLCFileName,"MPTUnstructured.tlc")
      %% Determine type qualifers
      %assign dw_const = (msDefn.IsConst ? 1 : 0)
      %assign dw_vol = (msDefn.IsVolatile ? 1 : 0)
      %if (!isR13CSC)
        %% Only the following CSC are supported
        %% - Not a pre-R14 CSC
        %% - Non-Pointer Access
        %%
        %if ( (cscDefn.CSCType == "Unstructured") || isPIM || isMPTVar)
          %% Either Ungrouped CSC or Autosar PIM
          %%
          %% Determine type - Returns a coder.types.* object
          %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, dw_const, dw_vol)
          %if !ISEMPTY(containerCgTypeIdx)
            %assign containerTypeObj = SLibGetCoderTypeObject(containerCgTypeIdx, dw_const, dw_vol)
          %endif
          %%
          %% If Component exports, add known properties to Variable Object
          %assign ownerName = ""
          %assign defnFile = ""
          %assign declFile = ""
          %assign props = LibGetCustomStorageAttributes(dw)
          %assign dataOwner = LibGetInstanceSpecificProp(cscDefn, props, "Owner")
          %if !ISEMPTY(dataOwner)
            %assign dataIsOwned = (dataOwner == LibGetModelName())
          %else
            %assign dataIsOwned = TLC_TRUE
          %endif
          %assign isFileScope = TLC_FALSE
          %assign notOwned = ( SLibIsERTTarget() && ...
            (::CompiledModel.ConfigSet.EnableDataOwnership == TLC_TRUE) && ...
            !dataIsOwned)
          %assign isFileScope = ISEQUAL(cscDefn.DataScope, "File")
          %% For SharedLocalDSMs in modelref we want to check the file pacakging information
          %if ((!IsModelReferenceRTWTarget() || dw.SharedLocalDSM) && !notOwned) || isFileScope
            %if ISFIELD(dw, "FilePackaging") && (!ISEMPTY(dw.FilePackaging))
              %assign defineFildwdx = dw.FilePackaging.DefineFile
              %assign hdrFileName = dw.FilePackaging.HeaderFile
              %if (defineFildwdx != -1)
                %with ::CompiledModel.DataObjectUsage
                  %assign defFileName = File[defineFildwdx].Name
                %endwith
                %assign defnFile = defFileName + "." + ::LangFileExt
                %assign ownerName = ::CompiledModel.Name
                %if (hdrFileName != "")
                  %assign declFile = hdrFileName
                %endif
              %endif
              %assign isFileScope = ...
                  ISEMPTY(dw.FilePackaging.FilesWithDeclare) && ...
                  ISEMPTY(dw.FilePackaging.FilesWithInclude)
            %endif
          %endif
          %if (isPtr)
            %assign tgtVar = SLibGetRTWVariableObject("DW%<idx>", typeObj, ...
              "%<LibGetRecordIdentifier(dw)>", ownerName,defnFile,declFile)
            %assign pTypeObj = FcnCreatePointerTypeObj(cgTypeIdx, 0, 0)
            %assign baseRegObj = ...
              SLibGetRTWPointerVariableObject("DW%<idx>", pTypeObj, ...
              LibGetRecordIdentifier(dw), tgtVar)
          %else
            %% Create a RTW.Variable object using type, identifer and decl/defn file
            %assign baseRegObj = SLibGetRTWVariableObject("DW%<idx>", typeObj, ...
              LibGetRecordIdentifier(dw), ownerName, defnFile, declFile)
          %endif
          %if isFileScope
            %<baseRegObj>.StorageSpecifier = 'static';
          %else
            %<baseRegObj>.StorageSpecifier = 'extern';
          %endif
          %% For AUTOSAR PIMs wrap in an AutosarMemoryExpression object
          %if dw.StorageClass == "Custom" && ISFIELD(dw, "AutosarPIMDSM")
            %assign ca = LibGetCustomStorageAttributes(dw)
            %assign locName = LibGetRecordIdentifier(dw)
            %assign locNeedsNVRAMAccess = ca.needsNVRAMAccess
            %assign locIsArTypedPerInstanceMemory = ca.IsArTypedPerInstanceMemory
            %assign regObj = "PIMDSM%<idx>"
            %if locIsArTypedPerInstanceMemory
                %assign locDataAccessMode = "ArTypedPerInstanceMemory"
            %else
                %assign locDataAccessMode = "CTypedPerInstanceMemory"
            %endif
            %<regObj> = RTW.AutosarMemoryExpression('%<locDataAccessMode>');
            %<regObj>.VariableName = '%<locName>';
            %<regObj>.NeedsNVRAMAccess = %<locNeedsNVRAMAccess>;
            %<regObj>.BaseRegion = %<baseRegObj>;
            %<regObj>.Type = %<typeObj>;
          %else
            %assign regObj = baseRegObj
          %endif
          %%
        %elseif (cscDefn.CSCType == "FlatStructure")
          %% Grouped CSC
          %assign regObjName = "DataStore%<idx>_CSC"
          %assign regObj = SLibCodeInfoObjectForFlatStructure(dw, cscDefn, regObjName, TLC_FALSE)
          %%
        %elseif (cscDefn.CSCType == "AccessFunction")
          %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, 0, 0)
          %assign bIdx = LibGetRecordWidth(dw) == 1 ? "" : "[0]"
          %assign csAttr = LibGetCustomStorageAttributes(dw)
          %assign aReadExpr = FcnReplaceIdentifierToken(LibGetInstanceSpecificProp(cscDefn, csAttr, "GetFunction"),LibGetRecordIdentifier(dw))
          %assign aWriteExpr = FcnReplaceIdentifierToken(LibGetInstanceSpecificProp(cscDefn, csAttr, "SetFunction"),LibGetRecordIdentifier(dw))
          %assign regObj = "ExternInput%<idx>_CSC"
          %<regObj> = RTW.CustomExpression(%<typeObj>,regexprep('%<aReadExpr>','^/[/]$',''),regexprep('%<aWriteExpr>','^/[/]$',''),'');
          %if ISFIELD(LibGetCustomStorageAttributes(dw), "HeaderFile")
               %assign aHeaderFile = LibGetInstanceSpecificProp(cscDefn, csAttr, "HeaderFile")
               %<regObj>.HeaderFile = '%<aHeaderFile>';
          %endif
          %if SLibGetAccessDataThroughMacro(cscDefn)
             %<regObj>.AccessViaMacro = true;
          %endif
        %else
          %% CSC of type "other"
          %assign regObj = SLibCustomStorageTypeOtherForCodeInfo(dw, cscDefn, TLC_FALSE)
        %endif
      %else
        %% Unsupported CSC
        %% No implementation provided. The default regObj = "[]" will be used
      %endif
    %endif
    %assign comment = "% Setting DataStore#%'s implementation"
     
    %<comment>
    codeInfo.DataStores(%).Implementation = %<regObj>;
    %if !ISEMPTY(containerTypeObj)
      codeInfo.DataStores(%).Implementation.CodeType = %<containerTypeObj>;
    %endif
    wr.writeDataStore(%<regObj>, codeInfo.DataStores(%));
    %if SLibAutosarActive()
     %assign dwIdx = dwIdx + 1
      %if ISFIELD(dw, "RunnableAccessInfo")
        %with ::CompiledModel.RTWAutosar
          %assign runnables = FIELDNAMES(dw.RunnableAccessInfo)
          %assign numRunnables = SIZE(runnables, 1)
          %foreach runIdx = numRunnables
            %assign runName = runnables[runIdx]
            %if !ISFIELD(DSMAccessInfo, runName)
              %addtorecord DSMAccessInfo %<runName> [%<dwIdx>]
            %else
              %assign DSMAccessInfo.%<runName> = ...
                DSMAccessInfo.%<runName> + dwIdx
            %endif
          %endforeach
        %endwith
      %endif
     %endif %%SLibAutosarActive()
   %endforeach
  %endwith %%DWorks
%endfunction
 
%%FunctionSLibIsGlobalVariable========================================
%%Abstract:
%%ThisfunctioncheckifBlockOutportsandBlockStateisa
%%GlobalVariable
%%
%function SLibIsGlobalVariable(glbData) Output
%assign isPIM = (ISFIELD(glbData, "AutosarPIMDSM") && glbData.AutosarPIMDSM)
  %if ISEQUAL(glbData.StorageClass, "Auto") || isPIM
    %return TLC_FALSE
  %endif
  %% Process storage class data
  %if (glbData.StorageClass != "Custom")
    %%
    %% If not ExportedGlobal, continue
    %if !ISEQUAL(glbData.StorageClass, "ExportedGlobal")
      %return TLC_FALSE
    %endif
  %else
    %% Custom storage Classes.
    %assign cscDefn = SLibGetCSCDefForData(glbData)
    %assign isDirect = ((SLibGetDataAccess(cscDefn, glbData)=="Direct") ? 1 : 0)
    %assign isMacro = ((SLibGetDataInitForData(cscDefn, glbData) == "Macro") ? 1: 0)
    %assign isUnstructured = ((cscDefn.CSCType == "Unstructured") ? 1 : 0)
    %assign isExported = (ISEQUAL(cscDefn.DataScope, "Exported") ? 1 : 0)
    %if (isDirect && !isMacro && isUnstructured && isExported)
      %if !(ISFIELD(glbData, "FilePackaging") && (!ISEMPTY(glbData.FilePackaging)))
        %return TLC_FALSE
      %endif
    %endif
  %endif
  %return TLC_TRUE
%endfunction
 
%%FunctionSLibCreateGlobalVariable========================================
%%Abstract:
%%ThisfunctionloopsthroughBlockOutportsorBlockStateandcreates
%%aRTW.Variableobjectforeachofthemwithstorageclassas
%%ExportedGlobal.
%%
%%Thisfunctionwillbecalledincodeinfo.tlcwhichwritesoutMATLABcode.
%%TheMATLABsyntaxemittedbythisfunctionwillbepartofthatfile
%%
%function SLibCreateGlobalVariable(glbData) Output
  %if !SLibIsGlobalVariable(glbData)
    %return TLC_FALSE
  %endif
  %assign regObj = "RTW.DataImplementation.empty"
 
  %% Process storage class data
  %assign cgTypeIdx = glbData.CGTypeIdx
  %assign ownerName = ""
  %assign defnFile = ""
  %assign declFile = ""
  %assign glbData_const = 0
  %assign glbData_vol = 0
  %if (glbData.StorageClass != "Custom")
      %% If ExportedGlobal, the datastore's definition & declaration file are known
    %assign ownerName = ::CompiledModel.Name
    %assign defnFile = "%<::CompiledModel.Name>." + ::LangFileExt
    %assign declFile = "%<::CompiledModel.Name>.h"
    %%
    %% Determine type qualifers
    %if !ISEMPTY(glbData.StorageTypeQualifier)
      %if (glbData.StorageTypeQualifier == "const volatile")
        %assign glbData_const = 1
        %assign glbData_vol = 1
      %elseif (glbData.StorageTypeQualifier == "const")
        %assign glbData_const = 1
      %elseif (glbData.StorageTypeQualifier == "volatile")
        %assign glbData_vol = 1
      %endif
    %endif
  %else
      %% Custom storage Classes.
      %assign cscDefn = SLibGetCSCDefForData(glbData)
      %assign isDirect = ((SLibGetDataAccess(cscDefn, glbData)=="Direct") ? 1 : 0)
      %assign isMacro = ...
        ((SLibGetDataInitForData(cscDefn, glbData) == "Macro") ? 1: 0)
      %assign isUnstructured = ((cscDefn.CSCType == "Unstructured") ? 1 : 0)
      %assign isExported = (ISEQUAL(cscDefn.DataScope, "Exported") ? 1 : 0)
      %if (isDirect && !isMacro && isUnstructured && isExported)
        %% Determine type qualifers
        %assign msDefn = SLibGetMemorySectionDefForData(glbData)
        %assign glbData_const = (msDefn.IsConst ? 1 : 0)
        %assign glbData_vol = (msDefn.IsVolatile ? 1 : 0)
        %if ISFIELD(glbData, "FilePackaging") && (!ISEMPTY(glbData.FilePackaging))
          %assign defineFildwdx = glbData.FilePackaging.DefineFile
          %assign hdrFileName = glbData.FilePackaging.HeaderFile
          %if (defineFildwdx != -1)
            %with ::CompiledModel.DataObjectUsage
              %assign defFileName = File[defineFildwdx].Name
            %endwith
            %assign defnFile = defFileName + "." + ::LangFileExt
            %assign ownerName = ::CompiledModel.Name
            %if (hdrFileName != "")
              %assign declFile = hdrFileName
            %endif
          %endif
        %endif
      %endif
  %endif
  %%
  %% Determine type - Returns a coder.types.* object
  %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, glbData_const, glbData_vol)
  %% Create a RTW.Variable object using type, identifer and decl/defn file
  %assign dataID = LibGetRecordIdentifier(glbData)
  %assign regObj = SLibGetRTWVariableObject("glbData_%<dataID>", typeObj, ...
    dataID, ownerName, defnFile, declFile)
 
  %assign isMutuallyExclusive = ISFIELD(glbData,"isMutuallyExclusiveSignal") ? (glbData.isMutuallyExclusiveSignal == "yes") : 0
   
  %<regObj>.StorageSpecifier = 'extern';
  %%
  %assign comment = "% Adding Global Variable: %<dataID>"
  %<comment>
  if isempty(codeInfo.Code.GlobalVariables)
    codeInfo.Code.GlobalVariables = %<regObj>;
  else
    codeInfo.Code.GlobalVariables(end+1) = %<regObj>;
  end
     
  %if isMutuallyExclusive
      if isempty(codeInfo.Code.MutuallyExclusiveVariables)
        codeInfo.Code.MutuallyExclusiveVariables = {'%<dataID>'};
      else
        codeInfo.Code.MutuallyExclusiveVariables(end+1) = {'%<dataID>'};
      end
  %endif
     
  %return TLC_TRUE
%endfunction
 
%%FunctionSLibCreateStaticMemory========================================
%%Abstract:
%%ThisfunctionloopsthroughBlockOutportsandBlockStateandcreates
%%aRTW.Variableobjectforeachofthemwithstorageclassas
%%ExportedGlobal.
%%
%%Thisfunctionwillbecalledincodeinfo.tlcwhichwritesoutMATLABcode.
%%TheMATLABsyntaxemittedbythisfunctionwillbepartofthatfile
%%
%function SLibCreateStaticMemory() Output
  %% Start looping over BlockOutputs
  %assign globalMemoryIndex = 0
  %with ::CompiledModel.BlockOutputs
  %foreach idx = NumExternalBlockOutputs
    %assign eBO = ExternalBlockOutput[idx]
    %assign isGlobalMemory = %<SLibCreateGlobalVariable(eBO)>
    %if isGlobalMemory
      %assign globalMemoryIndex = globalMemoryIndex+1
      %assign fieldName = "CIIdx"
      %addtorecord eBO %<fieldName> %<globalMemoryIndex>
    %endif
  %endforeach
  %endwith %%BlockOutputs
  %% Start looping over DWorks
  %with ::CompiledModel.DWorks
  %foreach idx = NumDWorks
    %assign dw = DWork[idx]
    %assign isState = ISEQUAL(dw.UsedAs, "DSTATE")
    %if isState || (dw.IsDataStoreMemory == 1)
      %assign isGlobalMemory = %<SLibCreateGlobalVariable(dw)>
      %if isGlobalMemory
        %assign globalMemoryIndex = globalMemoryIndex+1
        %assign fieldName = "CIIdx"
        %addtorecord dw %<fieldName> %<globalMemoryIndex>
      %endif
    %endif
  %endforeach
  %endwith %%DWorks
%endfunction
 
%%FunctionSLibAddArTypedPIMInfo========================================
%%Abstract:
%%ThisfunctionaddsfieldCIIDandPIMName/VARNameforGlobalBlockOutputrecord
%%whentheBlockOutputisbelongstoArTypedPIM/StaticMemoryCoderDataGroup.
%%
%%Thisfunctionwillbecalledincodeinfo.tlcwhichwritesoutMATLABcode.
%%TheMATLABsyntaxemittedbythisfunctionwillbepartofthatfile
%%
%function SLibAddAutosarVarInfo() Output
  %assign rootSystem = ::CompiledModel.System[::CompiledModel.NumSystems-1]
  %assign varIndex = 0
  %foreach groupIdx = ::CompiledModel.NumCoderDataGroups
    %assign group = ::CompiledModel.CoderDataGroup[groupIdx]
    %if ISFIELD(group, "SynthesizedNamePrefix") && !ISEMPTY(group.SynthesizedNamePrefix) && ...
        ((group.SynthesizedNamePrefix == "_PIM") || (group.SynthesizedNamePrefix == "_VAR"))
      %assign fieldName = "CoderDataGroup" + group.Name + "VarGroupIndex"
      %if ISFIELD(rootSystem, fieldName)
        %assign varIndex = 0
        %assign idFieldName = "CIIdx"
        %if group.SynthesizedNamePrefix == "_PIM"
          %assign nameFieldName = "PIMName"
        %else
          %assign nameFieldName = "VARName"
        %endif
        %assign varGrpIdx = GETFIELD(rootSystem, fieldName)
        %assign varGrp = ::CompiledModel.VarGroups.VarGroup[varGrpIdx[0]]
        %foreach elemIdx = varGrp.NumVarGroupElements
          %assign element = varGrp.VarGroupElements[elemIdx]
          %assign idnum = IDNUM(element)
          %switch idnum[0]
            %case "B"
              %assign gBO = ::CompiledModel.BlockOutputs.GlobalBlockOutput[idnum[1]]
              %assign varName = varGrp.VarGroupElementIds[elemIdx]
              %assign varIndex = varIndex+1
              %addtorecord gBO %<idFieldName> %<varIndex>
              %addtorecord gBO %<nameFieldName> varName
              %break
            %default
              %break
          %endswitch
        %endforeach
      %endif
    %endif
  %endforeach
%endfunction
 
%function SLibCreateExternalBlockOutputInterfaces() Output
  %with ::CompiledModel.BlockOutputs
  %foreach idx = NumExternalBlockOutputs
    %assign eBO = ExternalBlockOutput[idx]
    %if ISFIELD(eBO,"IsRemovedInIR") && eBO.IsRemovedInIR ==1
        %continue
    %endif
    %assign rtwFileIdx = FcnGetRTWFileModelRecordIndex(eBO)
    %% All Block Output Buffers are not written to CGModel. The function
    %% below will tell us if ExternalBlockOutput[rtwFileIdx] has a
    %% custom storage class and its implementation needs to set in
    %% Code Descriptor.
    %assign boIdx = CGMODEL_ACCESS("CGModel.getDMRBlockOutputIndex",%<rtwFileIdx>)
    %if boIdx == -1
        %% This is not a custom storage class ExternalBlockOutput, no need
        %% to create a Data Interface for Code Descriptor.
        %continue
    %endif
    %<SLibCreateDataInterfaceHelper(eBO, "ExternalBlockOutput", boIdx)>
  %endforeach
  %endwith %%BlockOutputs
%endfunction
 
%function SLibCreateDWorkInterfaces() Output
  %with ::CompiledModel.DWorks
  %foreach idx = NumDWorks
    %assign dw = DWork[idx]
    %if ISFIELD(dw,"IsRemovedInIR") && dw.IsRemovedInIR == 1
        %continue
    %endif
     
    %if ISFIELD(dw,"IsLocalScratchDWork") && dw.IsLocalScratchDWork == 1
        %continue
    %endif
     
    %% Skip PIRWork
    %if dw.Origin == "PWORK" || dw.Origin == "IWORK" || dw.Origin == "RWORK"
        %continue
    %endif
     
    %% Skip DSMs for legacy CSCs
    %if dw.IsDataStoreMemory == 1
        %continue
    %endif
         
  %assign rtwFileIdx = FcnGetRTWFileModelRecordIndex(dw)
 
  %if ISFIELD(dw, "OptimizedAwayInTLC") && dw.OptimizedAwayInTLC == 1
      %assign dwIdx = CGMODEL_ACCESS("CGModel.getDMRDWorkIndex",%<rtwFileIdx>)
      %if dwIdx != -1
         fr.removeDWorkOptimizedInTLC(%);
      %endif
      %continue
  %endif
 
    %% All DWork Buffers are not written to CGModel. The function
    %% below will tell us if DWorks[rtwFileIdx] has a
    %% custom storage class and its implementation needs to set in
    %% Code Descriptor.
  %assign dwIdx = CGMODEL_ACCESS("CGModel.getDMRCustomDWorkIndex",%<rtwFileIdx>)
  %if dwIdx == -1
        %% This is not a custom storage class DWork, no need
    %% to create a Data Interface for Code Descriptor.
      %continue
  %endif
 
  %<SLibCreateDataInterfaceHelper(dw, "DWork", dwIdx)>
  %endforeach
  %endwith %%DWorks
%endfunction
 
%function SLibCreateDataInterfaceHelper(dataRec, category, cgModelIdx) Output
    %if ((dataRec.StorageClass != "Auto") ...
    && (dataRec.StorageClass != "SimulinkGlobal") ...
    && (dataRec.StorageClass != "ExportedGlobal")) ...
    || SLibIsLegacyStorageClassForDataRecord(dataRec)
      %assign regObj = "RTW.DataImplementation.empty"
      %% Process storage class data
      %assign cgTypeIdx = dataRec.CGTypeIdx
      %assign cgContainerTypeIdx = ""
      %if ISFIELD(dataRec, "ContainerCGTypeIdx")
        %assign cgContainerTypeIdx = dataRec.ContainerCGTypeIdx
      %else
        %assign cgContainerTypeIdx = cgTypeIdx
      %endif
      %assign sigID = LibGetRecordIdentifier(dataRec)
      %% Process CSC - custom storage class inputs
      %assign msDefn = SLibGetMemorySectionDefForData(dataRec)
      %assign cscDefn = SLibGetCSCDefForData(dataRec)
      %assign isR13CSC = ((SLibGetDataAccess(cscDefn, dataRec) == "unknown") ? 1 : 0)
      %assign isPtr = ((SLibGetDataAccess(cscDefn, dataRec)=="Pointer") ? 1 : 0)
      %assign isMPTVar = ISEQUAL(cscDefn.TLCFileName,"MPTUnstructured.tlc")
       %% Determine type qualifers
      %assign IsConst = (msDefn.IsConst ? 1 : 0)
      %assign IsVol = (msDefn.IsVolatile ? 1 : 0)
      %if (!isR13CSC)
        %% Only the following CSC are supported
        %% - Not a pre-R14 CSC
        %% - Non-Pointer Access
        %if (cscDefn.CSCType == "Unstructured") || isMPTVar
          %% Ungrouped CSC
          %%
          %%
          %% Determine type - Returns a coder.types.* object
          %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, IsConst, IsVol)
          %if ISFIELD(dataRec,"FrameData") && !ISEQUAL(dataRec.FrameData, "no")
            %assign typeObj = FcnGetMatrixFrameTypeObj(typeObj)
          %endif
           
          %% Determine CodeType
          %assign codeTypeObj = ""
          %if !ISEMPTY(cgContainerTypeIdx)
            %assign codeTypeObj = SLibGetCoderTypeObject(cgContainerTypeIdx, IsConst, IsVol)
            %if ISFIELD(dataRec,"FrameData") && !ISEQUAL(dataRec.FrameData, "no")
              %assign codeTypeObj = FcnGetMatrixFrameTypeObj(codeTypeObj)
            %endif
          %endif
 
          %%
          %% If Component exports, add known properties to Variable Object
          %assign defineFileIdx = SLibCustomStorageGetDefineFileIdxIfNecessary(dataRec, cscDefn)
          %assign defnFile = SLibCustomStorageGetDefineFileFromIdx(defineFileIdx)
          %assign ownerName = SLibCustomStorageGetOwnerNameForCodeInfo(defineFileIdx)
          %assign declFile = SLibCustomStorageGetDeclFileForCodeInfo(dataRec, defineFileIdx)
 
          %if (isPtr)
                %assign tgtVar = SLibGetRTWVariableObject(sigID, typeObj, ...
                LibGetRecordIdentifier(dataRec), ownerName, defnFile, declFile)
                %assign pTypeObj = FcnCreatePointerTypeObj(cgTypeIdx, 0, 0)
                %assign regObj = ...
                  SLibGetRTWPointerVariableObject("Ptr_%<sigID>", pTypeObj, ...
                  LibGetRecordIdentifier(dataRec), tgtVar)
          %else
          %% Create a RTW.Variable object using type, identifer and decl/defn file
          %assign regObj = SLibGetRTWVariableObject(sigID, typeObj, ...
            LibGetRecordIdentifier(dataRec), ownerName, defnFile, declFile)
                  
          %endif
          %if ISFIELD(dataRec, "isFileScoped") && dataRec.isFileScoped
             %<regObj>.StorageSpecifier = 'static';
          %else
             %<regObj>.StorageSpecifier = 'extern';
          %endif
          %if !ISEMPTY(codeTypeObj)
            %<regObj>.CodeType = %<codeTypeObj>;
          %endif
        %elseif (cscDefn.CSCType == "FlatStructure")
          %% Grouped CSC
          %assign idx = FcnGetRTWFileModelRecordIndex(dataRec)
          %assign regObjName = "ExternalBlockOutput%<idx>_CSC"
          %assign regObj = SLibCodeInfoObjectForFlatStructure(dataRec, cscDefn, regObjName, TLC_FALSE)
          %%
        %elseif (cscDefn.CSCType == "AccessFunction")
          %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, 0, 0)
          %if ISFIELD(dataRec,"FrameData") && !ISEQUAL(dataRec.FrameData, "no")
            %assign typeObj = FcnGetMatrixFrameTypeObj(typeObj)
          %endif
          %assign bIdx = LibGetRecordWidth(dataRec) == 1 ? "" : "[0]"
          %assign csAttr = LibGetCustomStorageAttributes(dataRec)
          %assign aReadExpr = FcnReplaceIdentifierToken(LibGetInstanceSpecificProp(cscDefn, csAttr, "GetFunction"),LibGetRecordIdentifier(dataRec))
          %assign aWriteExpr = FcnReplaceIdentifierToken(LibGetInstanceSpecificProp(cscDefn, csAttr, "SetFunction"),LibGetRecordIdentifier(dataRec))
          %assign idx = FcnGetRTWFileModelRecordIndex(dataRec)
          %assign regObj = "ExternalBlockOutput%<idx>_CSC"
          %<regObj> = RTW.CustomExpression(%<typeObj>,regexprep('%<aReadExpr>','^/[/]$',''),regexprep('%<aWriteExpr>','^/[/]$',''),'');
           
          %if ISFIELD(LibGetCustomStorageAttributes(dataRec), "HeaderFile")
             %assign aHeaderFile = LibGetInstanceSpecificProp(cscDefn, csAttr, "HeaderFile")
             %<regObj>.HeaderFile = '%<aHeaderFile>';
          %endif
          %if SLibGetAccessDataThroughMacro(cscDefn)
             %<regObj>.AccessViaMacro = true;
          %endif
        %else
        %% Unsupported CSC
        %% No implementation provided. The default regObj = "[]" will be use
        %endif
        %if category=="ExternalBlockOutput"
            wr.writeExternalBlockOutput(%<regObj>, %<cgModelIdx>);
        %elseif category=="DWork"
            wr.writeDWork(%<regObj>, %<cgModelIdx>);
        %endif
      %else
        %% Unsupported CSC
        %% No implementation provided. The default regObj = "[]" will be used
      %endif
    %endif
%endfunction
 
%%FunctionFcnGetRTWFileModelRecordIndex========================================
%%Abstract:
%%GivenamodeldatarecordlikeDWork/ExternalBlockOutput,
%%thisfunctionreturnstheIndexatwhichthisrecordwaswrittento
%%RTWfile.
 
%function FcnGetRTWFileModelRecordIndex(RTWFileRecord)
    %% Get rid of the "B" or "D". The remaining string is the buffer index
    %assign rtwFileIdx_string = STRING(RTWFileRecord.LogicalSrc)
    %assign rtwFileIdx = ""
    %assign strlen = SIZE(rtwFileIdx_string,1)
    %foreach idx = strlen
        %if idx==0
            %continue
        %else
            %assign rtwFileIdx = "%<rtwFileIdx>%"
        %endif
    %endforeach
    %return rtwFileIdx
%endfunction
 
%%FunctionSLibCustomStorageDataIsNotOwned===============================
%%
%%Abstract:ReturnstrueifthedataassociatedwithrecorddataRecdoes
%%nothaveanowningfileassociatedwithit.
%function SLibCustomStorageDataIsNotOwned(dataRec, cscDefn)
  %assign props = LibGetCustomStorageAttributes(dataRec)
  %assign dataOwner = LibGetInstanceSpecificProp(cscDefn, props, "Owner")
  %if !ISEMPTY(dataOwner)
    %assign dataIsOwned = (dataOwner == LibGetModelName())
  %else
    %assign dataIsOwned = TLC_TRUE
  %endif
  %assign notOwned = ( SLibIsERTTarget() && ...
    (::CompiledModel.ConfigSet.EnableDataOwnership == TLC_TRUE) && ...
      !dataIsOwned)
  %return notOwned
%endfunction
 
%%FunctionSLibCustomStorageGetDefineFileIdxIfNecessary=================
%%
%%Abstract:Returnsthefileidxofthedefinitionfileassociated
%%withthecustomstorageclass.Returns-1ifthedefinitionfile
%%isnotownedbythecurrentmodel.
%function SLibCustomStorageGetDefineFileIdxIfNecessary(dataRec, cscDefn)
  %assign notOwned = SLibCustomStorageDataIsNotOwned(dataRec, cscDefn)
  %assign defineFileIdx = -1
  %if (!IsModelReferenceRTWTarget() && !notOwned)
    %if ISFIELD(dataRec, "FilePackaging") && (!ISEMPTY(dataRec.FilePackaging))
      %assign defineFileIdx = dataRec.FilePackaging.DefineFile
    %endif
  %endif
  %return defineFileIdx
%endfunction
 
%%FunctionSLibCustomStorageGetDefineFileFromIdx=================
%%
%%Abstract:Givenafileindex,returnthedefinefile'sname.
%%Returnemptyiffileindexis-1.
%function SLibCustomStorageGetDefineFileFromIdx(defineFileIdx)
  %if (defineFileIdx == -1)
    %assign defnFile = ""
  %else
    %with ::CompiledModel.DataObjectUsage
      %assign defFileName = File[defineFileIdx].Name
    %endwith
    %assign defnFile = defFileName + "." + ::LangFileExt
  %endif
  %return defnFile
%endfunction
 
 
%%FunctionSLibCustomStorageGetOwnerNameForCodeInfo=================
%%
%%Abstract:ReturnsthenameofthecurrentmodelifdefineFileIdxis
%%not-1.
%function SLibCustomStorageGetOwnerNameForCodeInfo(defineFileIdx)
  %if (defineFileIdx == -1)
    %assign ownerName = ""
  %else
    %assign ownerName = ::CompiledModel.Name
  %endif
  %return ownerName
%endfunction
 
%%FunctionSLibCustomStorageGetDeclFileForCodeInfo=======================
%%
%%Abstract:Returnsthenameofthedeclarationfileassociatedwith
%%dataRec.Returnsemptyifthevariableisnotownedbythecurrentmodel.
%function SLibCustomStorageGetDeclFileForCodeInfo(dataRec, defineFileIdx)
  %assign declFile = ""
  %if (defineFileIdx != -1)
    %assign hdrFileName = dataRec.FilePackaging.HeaderFile
    %if (hdrFileName != "")
      %assign declFile = hdrFileName
    %endif
  %endif
  %return declFile
%endfunction
 
%%FunctionSLibIsFlatStructureBitField===================================
%function SLibIsFlatStructureBitField(cscDefn, cgTypeIdx)
  %assign isBitField = ...
        ((ISFIELD(cscDefn.CSCTypeAttributes, "BitPackBoolean")) && ...
        (cscDefn.CSCTypeAttributes.BitPackBoolean) && ...
        (::CompiledModel.CGTypes.CGType[cgTypeIdx].SLTypeIdx == 8))
  %return isBitField
%endfunction
 
%%FunctionSLibCodeInfoObjectForFlatStructure==========================
%function SLibCodeInfoObjectForFlatStructure(dataRec, cscDefn, regObj, isParam) Output
    %if ISEQUAL(cscDefn.DataScope, "Imported")
        %return SLibCustomStorageTypeOtherForCodeInfo(dataRec, cscDefn, isParam)
    %else
        %return SLibCustomExpressionForFlatStructure(dataRec, cscDefn, regObj, isParam)
    %endif
%endfunction
 
%%FunctionSLibCustomExpressionForFlatStructure==========================
%function SLibCustomExpressionForFlatStructure(dataRec, cscDefn, regObj, isParam) Output
  %assign msDefn = SLibGetMemorySectionDefForData(dataRec)
  %if isParam
    %assign cgTypeIdx = SLibGetRecordOriginalCGTypeIdx(dataRec)
    %assign baseCGTypeIdx = LibCGTypeBaseIndex(cgTypeIdx)
    %assign isBitField = SLibIsFlatStructureBitField(cscDefn, baseCGTypeIdx)
  %else
    %assign cgTypeIdx = dataRec.CGTypeIdx
    %assign isBitField = SLibIsFlatStructureBitField(cscDefn, cgTypeIdx)
  %endif
   
  %assign data_const = (msDefn.IsConst ? 1 : 0)
  %assign data_vol = (msDefn.IsVolatile ? 1 : 0)
  %if isBitField
    %if isParam
        %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, data_const,data_vol)
%<typeObj>.BaseType = coder.types.Bool;
    %else
        %assign typeObj = "coder.types.Bool"
    %endif
  %else
     %assign typeObj = SLibGetCoderTypeObject(cgTypeIdx, data_const,data_vol)
     %if ISFIELD(dataRec, "FrameData") && !ISEQUAL(dataRec.FrameData, "no")
       %assign typeObj = FcnGetMatrixFrameTypeObj(typeObj)
     %endif
  %endif
  
  %assign aExpr = LibCustomData(dataRec, "contents", "", "")
  %assign owner = ISEQUAL(cscDefn.DataScope, "Exported") ? ::CompiledModel.Name : ""
   
%<regObj> = RTW.CustomExpression(%<typeObj>,'%<aExpr>','%<aExpr>','%<owner>');
  %return regObj
%endfunction
 
%%FunctionSLibCustomStorageTypeOtherSupportsSILPIL======================
%%
%%Abstract:ReturnTLC_TRUEiftheCSCoftype"Other"supportsSILand
%%PIL-specifically,ifithasaclass-specificorinstance-specific
%%booleanattribute"SupportSILPIL"thathasthevalue"true".
%function SLibCustomStorageTypeOtherSupportsSILPIL(dataRec, cscDefn)
  %assign hasSupportSILPILAttr = ISFIELD(cscDefn, "SupportSILPIL") || ...
                (ISFIELD(cscDefn, "CSCTypeAttributes") && ...
                   !ISEMPTY(cscDefn.CSCTypeAttributes) && ...
                   ISFIELD(cscDefn.CSCTypeAttributes, "SupportSILPIL"))
  %assign customAttrProps = LibGetCustomStorageAttributes(dataRec)
  %if hasSupportSILPILAttr
    %assign supportSILPIL = LibGetInstanceSpecificProp(cscDefn, customAttrProps, "SupportSILPIL")
  %elseif cscDefn.CSCType == "FlatStructure"
    %assign supportSILPIL = TLC_TRUE
  %else
    %assign supportSILPIL = TLC_FALSE
  %endif
  %return supportSILPIL
%endfunction
 
%%FunctionSLibCustomStorageTypeOtherForCodeInfo=========================
%%
%%Abstract:ConstructtheMATLABcodetoinstantiateanobjectoftype
%%RTW.CustomVariabletodescribetheimplementationofthevariable
%%implementedusingaCSCoftype"other".Returnsthenameoftheobject.
%function SLibCustomStorageTypeOtherForCodeInfo(dataRec, cscDefn, isParam) Output
 
  %% Return empty if the CSC is not configured to support SIL/PIL.
  %assign supportSILPIL = SLibCustomStorageTypeOtherSupportsSILPIL(dataRec, cscDefn)
  %if !supportSILPIL
    %return "RTW.DataImplementation.empty"
  %endif
  %% Mark the data record as being accessed for SIL/PIL
  %if ISFIELD(dataRec, "DataAccessForSILPIL")
    %assign dataRec.DataAccessForSILPIL = TLC_TRUE
  %else
    %addtorecord dataRec DataAccessForSILPIL TLC_TRUE
  %endif
   
  %% Get the custom attribute properties
  %assign customAttrProps = LibGetCustomStorageAttributes(dataRec)
 
  %% Return empty if the CSC is not configured with one of the supported
  %% memory layouts.
  %assign layout = LibAccessCustomData(dataRec, "layout", "[]", "", "")
  %if (layout[0] != "other") && ...
            (layout[0] != "scalar") && ...
            (layout[0] != "vector") && ...
            (layout[0] != "row-mat") && ...
            (layout[0] != "col-mat")
    %return "RTW.DataImplementation.empty"
  %endif
 
  %% Construct the Type object and the CodeType object.
  %assign dataTypeIdx = SLibGetRecordOriginalCGTypeIdx(dataRec)
  %assign dataCodeTypeIdx = SLibGetRecordContainerCGTypeIdx(dataRec)
 
 
  %assign isPtr = ((SLibGetDataAccess(cscDefn, dataRec)=="Pointer") ? 1 : 0)
  %if (isPtr)
    %assign typeObj = FcnCreatePointerTypeObj(dataTypeIdx, 0, 0)
 
    %% Don't add a code type object for pointer types.
    %%
    %% Pointer-types always point to a scalar base type, even for a matrix
    %% valued signal. To avoid incompatibilities with SIL/PIL trying to
    %% "preserve" this, don't add CodeType for CustomVariable.
    %if LibCGTypeIsMatrix(dataCodeTypeIdx) && !LibCGTypeIsComplex(dataCodeTypeIdx)
        %assign codeTypeObj = "coder.types.Type.empty"
    %else
        %assign codeTypeObj = FcnCreatePointerTypeObj(dataCodeTypeIdx, 0, 0)
    %endif
  %else
    %assign msDefn = SLibGetMemorySectionDefForData(dataRec)
    %assign p_const = (msDefn.IsConst ? 1 : 0)
    %assign p_vol = (msDefn.IsVolatile ? 1 : 0)
    %assign typeObj = SLibGetCoderTypeObject(dataTypeIdx, p_const, p_vol)
    %assign codeTypeObj = SLibGetCoderTypeObject(dataCodeTypeIdx, p_const, p_vol)
  %endif
  %if ISFIELD(dataRec, "FrameData") && !ISEQUAL(dataRec.FrameData, "no")
    %assign typeObj = FcnGetMatrixFrameTypeObj(typeObj)
  %endif
 
 
  %% If Component exports, add details about owner, declaration and
  %% definition files.
  %assign defineFileIdx = SLibCustomStorageGetDefineFileIdxIfNecessary(dataRec, cscDefn)
  %assign defnFile = SLibCustomStorageGetDefineFileFromIdx(defineFileIdx)
  %assign identifier = LibGetRecordIdentifier(dataRec)
  %assign varKey = identifier
 
  %if (cscDefn.IsGrouped)
 
    %% The logic for non-grouped variables does not work for grouped
    %% variables.
    %assign declFile = LibGetInstanceSpecificProp(cscDefn, customAttrProps, "HeaderFile")
    %assign enableDataOwnership = SLibIsERTTarget() && (::CompiledModel.ConfigSet.EnableDataOwnership == TLC_TRUE)
 
    %% Could be "Auto".
    %assign isExported = !ISEQUAL(cscDefn.DataScope, "Imported")
    %assign specifiedOwner = LibGetInstanceSpecificProp(cscDefn, customAttrProps, "Owner")
    %assign specifiedOwnerIsThisModel = (specifiedOwner == "") || (specifiedOwner == LibGetModelName())
    %assign isOwned = isExported && !IsModelReferenceRTWTarget() && ...
        ( !enableDataOwnership || specifiedOwnerIsThisModel )
    %assign ownerName = isOwned ? LibGetModelName() : ""
  %else
    %assign declFile = SLibCustomStorageGetDeclFileForCodeInfo(dataRec, defineFileIdx)
    %assign ownerName = SLibCustomStorageGetOwnerNameForCodeInfo(defineFileIdx)
  %endif
 
 
  %assign regObj = SLibGetRTWCustomVariableObject(varKey, typeObj, identifier, ownerName, defnFile, declFile)
  %<regObj>.CodeType = %<codeTypeObj>;
   
  %% Store whether the variable is static or extern
  %assign isFileScope = ISFIELD(dataRec, "FilePackaging") && ...
        !ISEMPTY(dataRec.FilePackaging) && ...
            ( ISEMPTY(dataRec.FilePackaging.FilesWithDeclare) && ...
              ISEMPTY(dataRec.FilePackaging.FilesWithInclude))
  %if isFileScope
    %<regObj>.StorageSpecifier = 'static';
  %else
    %<regObj>.StorageSpecifier = 'extern';
  %endif
 
  %% Query the TLC for the definition and declaration expressions and cache
  %% them in regObj.
  %if (cscDefn.IsGrouped)
    %% We need to search for the class record
    %assign cscRec = LibGetCustomStorageInMap(cscDefn.OwnerPackage, cscDefn.Name)
    %assign ownerPackage = cscDefn.OwnerPackage
    %assign className = cscDefn.Name
    %assign classAccessObj = "CodeInfoClassAccess.%<ownerPackage>.%<className>"
 
    %if !ISFIELD(cscRec, "CachedCodeInfoClassAccessObject")
        %% Only re-create the ClassAccess object if it has not
        %% already been created.
 
        %% Mark the csc record as being accessed for SIL/PIL
        %if ISFIELD(cscRec, "DataAccessForSILPIL")
            %assign cscRec.DataAccessForSILPIL = TLC_TRUE
        %else
            %addtorecord cscRec DataAccessForSILPIL TLC_TRUE
        %endif
     
        %% Temporarily set data initialization to "none" - we do not want
        %% CodeInfo to contain code for static initialization - just enough
        %% to define the variable.
        %%
        %% For example, we do not want a definition expression of the form:
        %%
        %% myStructType myStruct = { {0,1,2,3}, {4,5,6,7}, {8,9,10,11} };
        %%
        %% since the "Imported" struct is not guaranteed to have the same
        %% memory layout (number of fields, ordering of fields) as the
        %% struct that the code generator might have generated had an
        %% Exported data scope been used. Instead, we want an expression
        %% of the form:
        %%
        %% myStructType myStruct;
        %%
        %assign cachedDataInit = cscDefn.DataInit
        %assign cscDefn.DataInit = "None"
         
        %% Query for the type def, data declaration and data definitions
        %assign groupTypeDeclDefn = LibCustomClass(cscRec, "groupTypeDeclDefn")
        %assign typeDefinition = groupTypeDeclDefn[0]
        %assign dataDeclaration = groupTypeDeclDefn[1]
        %assign dataDefinition = groupTypeDeclDefn[2]
 
        %if (cscDefn.CSCType == "FlatStructure" && cscDefn.DataAccess == "Pointer")
        %% For FlatStructure with an imported pointer type we know how
        %% the pointer will have been defined, so we can use a regexp
        %% to build a string that also instantiates storage, and initializes
        %% the pointer.
            %assign escapedDeclDefns = ...
                FEVAL("coder.internal.updatePtrDefnForImportedFlatStructure", ...
                    typeDefinition, ...
                    dataDeclaration, ...
                    dataDefinition)
        %else
            %assign escapedDeclDefns = ...
                FEVAL("coder.internal.escapeValuesFromTLCForCodeDescriptor", ...
                    typeDefinition, ...
                    dataDeclaration, ...
                    dataDefinition)
        %endif
         
        %% Restore the value of cscDefn.DataInit
        %assign cscDefn.DataInit = cachedDataInit
 
        %% Remove marker from class record
        %with cscRec
            %undef DataAccessForSILPIL
        %endwith
         
        %% Serialize the RTW.CustomVariableClassAccess object
        %<classAccessObj> = RTW.CustomVariableClassAccess;
        %<classAccessObj>.Package = '%<ownerPackage>';
        %<classAccessObj>.ClassName = '%<className>';
        %<classAccessObj>.GroupTypeDefinition = %;
        %<classAccessObj>.GroupDataDeclaration = %;
        %<classAccessObj>.GroupDataDefinition = %;
         
        %% Add a marker to say that a ClassAccess object has been created.
        %addtorecord cscRec CachedCodeInfoClassAccessObject classAccessObj
    %endif
    %<regObj>.ClassAccess = %<classAccessObj>;
  %else
    %assign defineExpression = LibAccessCustomData(dataRec, "define", "[]", "", "")
    %assign declareExpression = LibAccessCustomData(dataRec, "declare", "[]", "", "")
    %assign escapedExpressions = FEVAL("coder.internal.escapeValuesFromTLCForCodeDescriptor", defineExpression, declareExpression)
    %<regObj>.DefineExpression = %;
    %<regObj>.DeclareExpression = %;
  %endif
 
  %% If a Zero Index has been set in the response to "layout", (i.e.,
  %% the response to "layout" has 4 elements, and not only 1), then set
  %% set that in the data implementation object.
  %<regObj>.Layout = '%';
  %if SIZE(layout)[1] > 3
    %<regObj>.ZeroIndex = '%';
  %endif
 
  %% Need to build up a set of data elements - namely,
  %% struct elements and complex number elements
  %assign elemIdx = 0
  %assign levelIdx = 0
 
  %% In some cases the "initialize" request might not have been defined in
  %% the CSC's TLC.
  %assign needsInitialize = !isParam && ...
        !(SLibGetDataInitForData(cscDefn, dataRec) == "None")
   
  %% Create RTW.CustomExpression objects for each element of the data
  %assign newValueTok = "$(NEWVALUE_TOKEN)"
  %assign elemIdx = SLibCreateTLCVariablePartOuter(dataRec, ...
            needsInitialize, ...
            regObj, ...
            dataTypeIdx, ...
            layout, ...
            elemIdx, ...
            "", ...
            newValueTok, ...
            levelIdx)
 
  %% Remove marker from data record
  %with dataRec
    %undef DataAccessForSILPIL
  %endwith
 
  %return regObj
%endfunction
 
%%FunctionSLibCreateTLCVariablePartOuter===============================
%%
%%Abstract:ConstructtheMATLABcodetoinstantiateanobjectoftype
%%RTW.CustomExpressiontodescribetheimplementationoftheindividual
%%elementsofavariable.
%function SLibCreateTLCVariablePartOuter(dataRec, needsInitialize, regObj, dataTypeIdx, layout, elemIdx, idxTok, newValueTok, levelIdx) Output
    %% Sort out matrix indexing
    %if LibCGTypeIsMatrix(dataTypeIdx) && LibCGTypeSymbolicWidth(dataTypeIdx) != "1"
        %assign dataTypeIdx = LibCGTypeBaseIndex(dataTypeIdx)
        %assign levelIdxTok = "%<idxTok>[$(INDEX_TOKEN_%<levelIdx>)]"
        %assign levelIdx = levelIdx+1
    %else
        %assign levelIdxTok = idxTok
    %endif
 
    %if LibCGTypeIsStruct(dataTypeIdx)
        %% Recurse into struct data types
        %assign cgTypeRec = ::CompiledModel.CGTypes.CGType[dataTypeIdx]
        %foreach mIdx = LibCGTypeNumMembers(dataTypeIdx)
            %assign elementIdentifier = LibCGTypeMemberName(dataTypeIdx, mIdx)
            %assign elementDataTypeIdx = LibCGTypeMemberCGTypeIdx(dataTypeIdx, mIdx)
 
            %assign locIdxTok = "%<levelIdxTok>.%<elementIdentifier>"
            %assign elemIdx = SLibCreateTLCVariablePartOuter(dataRec, ...
                needsInitialize, ...
                regObj, ...
                elementDataTypeIdx, ...
                layout, ...
                elemIdx, ...
                locIdxTok, ...
                newValueTok, ...
                levelIdx)
        %endforeach
    %else
        %assign elemIdx = SLibCreateTLCVariablePartLeaf(dataRec, ...
                    needsInitialize, ...
                    regObj, ...
                    dataTypeIdx, ...
                    layout, ...
                    elemIdx, ...
                    levelIdxTok, ...
                    newValueTok)
    %endif
     
    %% We need to return the running count of elements in
    %% the current CodeInfo object
    %return elemIdx
%endfunction
 
%%FunctionSLibCreateTLCVariablePartLeaf================================
%%
%%Abstract:ConstructtheMATLABcodetoinstantiateanobjectoftype
%%RTW.CustomExpressiontodescribetheimplementationofthefinal
%%realorcomplex"leaf"elementsofavariable.
%function SLibCreateTLCVariablePartLeaf(dataRec, needsInitialize, regObj, leafDataTypeIdx, layout, elemIdx, idxTok, newValueTok) Output
    %if (LibCGTypeIsComplex(leafDataTypeIdx))
        %assign reIdentifier = "%<idxTok>.re"
        %assign imIdentifier = "%<idxTok>.im"
        %assign elemIdx = elemIdx + 1
        %<SLibCreateTLCVariablePartElem(dataRec, needsInitialize, regObj, layout, elemIdx, reIdentifier, idxTok, ".%<tRealPart>", newValueTok)>
        %assign elemIdx = elemIdx + 1
        %<SLibCreateTLCVariablePartElem(dataRec, needsInitialize, regObj, layout, elemIdx, imIdentifier, idxTok, ".%<tImagPart>", newValueTok)>
    %else
        %assign elemIdx = elemIdx + 1
        %<SLibCreateTLCVariablePartElem(dataRec, needsInitialize, regObj, layout, elemIdx, idxTok, idxTok, "", newValueTok)>
  %endif
  %return elemIdx
%endfunction
 
%%FunctionSLibCreateTLCVariablePartElem================================
%%
%%Abstract:ConstructtheMATLABcodetoinstantiateanobjectoftype
%%RTW.CustomExpressiontodescribetheimplementationofanelementsof
%%ofavariable.
%function SLibCreateTLCVariablePartElem(dataRec, needsInitialize, regObj, layout, elemIdx, elementIdentifier, idxTok, reIm, newValueTok) Output
 
    %assign readExpression = LibAccessCustomData(dataRec, "contents", idxTok, reIm, "")
    %if (dataRec.CustomStorageClassVersion > 1)
        %assign writeExpression = "%<LibAccessCustomData(dataRec, "set", idxTok, reIm, newValueTok)>"
    %else
        %assign writeExpression = "%<LibAccessCustomData(dataRec, "contents", idxTok, reIm, "")> = %<newValueTok>;"
    %endif
     
    %% The initialize expression does not have to be defined for parameters
    %% and querying it when not defined will cause a code generation failure.
    %if (needsInitialize)
        %assign initializeExpression = LibAccessCustomData(dataRec, "initialize", idxTok, reIm, "")
    %else
        %assign initializeExpression = ""
    %endif
 
    %if (layout[0] != "other")
        %assign addressExpression = LibAccessCustomData(dataRec, "address", idxTok, reIm, "")
    %else
        %assign addressExpression = ""
    %endif
     
    %% Call back into MATLAB using FEVAL only once
    %assign escapedExpressions = FEVAL("coder.internal.escapeValuesFromTLCForCodeDescriptor", readExpression, writeExpression, initializeExpression, addressExpression)
 
    %<regObj>.DataElements(%<elemIdx>) = RTW.CustomExpression;
    %<regObj>.DataElements(%<elemIdx>).DataElementIdentifier = '%<elementIdentifier>';
    %<regObj>.DataElements(%<elemIdx>).ReadExpression = %;
    %<regObj>.DataElements(%<elemIdx>).WriteExpression = %;
    %<regObj>.DataElements(%<elemIdx>).InitializeExpression = %;
    %<regObj>.DataElements(%<elemIdx>).AddressExpression = %;
%endfunction
 
%%FunctionSLibGetCoderDataGroupVariable=====================================
%%Abstract:
%%ThisfunctionreturnsaRTW.Variableobjectforthecoderdatagroup.
%%IfInternalDataalreadycontainsaTypedRegionforthisgroupwedon'tneedto
%%createanewone.
%%
%function SLibGetCoderDataGroupVariable(group) Output
  %assign typeObjName = group.Name + "Type"
  %assign groupType = FcnGetInternalTypeObj(typeObjName, SLibCoderDataGroupType(group), "")
   
  %% For multiinstance groups set to InParent or InSelf in modelref mode, the group will end up inside RTM.
  %% We should use the name of the element used in RTM for the variable name
  %if IsModelReferenceTarget() && SLibMultiInstance() &&...
    (group.AsStructure == "InParent" || group.AsStructure == "InSelf")
    %assign groupInstance = SLibCoderDataGroupReference(group)
  %else
    %assign groupInstance = SLibCoderDataGroupInstance(group)
  %endif
  %assign groupVarId = "rt_" + group.Name
  %assign groupVar = "Var_" + groupVarId
  %assign instanceStrId = "'" + groupInstance + "'"
  %% search the existing InternalData for a matching implentation
  group_var_exists = 0;
  for idx = 1:numel(codeInfo.InternalData)
      curr_var = codeInfo.InternalData(idx).Implementation;
      if isa(curr_var,'RTW.Variable') && strcmp(curr_var.Identifier, %<instanceStrId>)
          group_var_exists = 1;
          break;
      end
  end
 
  if group_var_exists
      %<groupVar> = curr_var;
  else
      %assign groupVar = ...
        SLibGetRTWVariableObject(groupVarId, groupType, groupInstance, "","","")
  end
  %return groupVar
%endfunction
 
%%FunctionSLibCreateModelConstructorActualArgs=====================================
%%Abstract:
%%ThisfunctionpopulatescodeInfo.ConstructorFunction.ActualArgs.
%%Currentlyonlycoderdatagroupargissupported,
%%othercases,e.g.functionserviceports,needtobehandledseparately.
%%
%function SLibCreateModelConstructorActualArgs() Output
  %assert GenerateClassInterface
 
  %assign rootSystem = System[GetBaseSystemIdx()]
  %assign rootModule = RTWCGModules.RTWCGModule[rootSystem.CGIRModuleIdx]
  %assign fcnIdx = ISFIELD(rootModule, "SystemFunctionTypes") && ISFIELD(rootModule.SystemFunctionTypes, "ModelConstructor") ...
    ? GETFIELD(rootModule.SystemFunctionTypes, "ModelConstructor") : -1
  %if fcnIdx < 0
    %return
  %endif
 
  %assign constrFcn = rootModule.Function[fcnIdx]
  tempActualArgs = [];
  %foreach argIdx = constrFcn.NumArgs
    %if 0 == constrFcn.ArgAccessed[argIdx]
      %continue
    %endif
 
    %assign idnum = IDNUM(constrFcn.ArgSource[argIdx])
    %if idnum[0] != "LCDG"
      %return
    %endif
 
    %assign group = CoderDataGroup[idnum[1]]
 
    %assign groupVar = SLibGetCoderDataGroupVariable(group)
    %assign groupVarId = "rt_" + group.Name
    %assign typeObjName = group.Name + "Type"
    %assign groupType = FcnGetInternalTypeObj(typeObjName, SLibCoderDataGroupType(group), "")
    %assign groupPtrType = FcnGetPointerTypeObj(groupType, 0, 0)
 
    %% For multiinstance groups set to InParent or InSelf in modelref mode, the group will end up inside RTM.
    %% We should use the name of the element used in RTM for the variable name
    %if IsModelReferenceTarget() && SLibMultiInstance() &&...
      (group.AsStructure == "InParent" || group.AsStructure == "InSelf")
      %assign groupInstance = SLibCoderDataGroupReference(group)
    %else
      %assign groupInstance = SLibCoderDataGroupInstance(group)
    %endif
 
    %assign groupPtrVar = SLibGetRTWPointerVariableObject(groupVarId, groupPtrType, "%<groupInstance>_ptr", groupVar)
 
    %% Create a DataInterface and add it to ActualArgs
    %assign desc = "Storage class " + group.Name
    argDataInterface = RTW.DataInterface('', '%<desc>', %<groupPtrVar>, RTW.TimingInterface.empty);
    tempActualArgs = [tempActualArgs, argDataInterface];
  %endforeach
     
  codeInfo.ConstructorFunction.ActualArgs = [tempActualArgs];
%endfunction
 
%%FunctionFcnHasRTMOrSelf=====================================
%%Abstract:
%%DeterminesifthemodelhasanRTMorSelfCoderDataGroup
%%
%function FcnHasRTMOrSelf()
  %assign rtRecs = RTMGetRTModelRecShell()
  %assign hStruct = FcnGenHStructFromRTMRecs(rtRecs)
  %return FcnShouldGenerateRTM(hStruct) || SLibGetSelfCoderDataGroupIndex() != -1
%endfunction
 
%%FunctionFcnAddModelBlockInstanceVariableName
%%Abstract:
%%AddsthevariablenameofallmodelblockinstancestotherespectiveblockinBlockHierarchyMap
%%
%function FcnAddModelBlockInstanceVariableName() Output
%assign mdlRefBlks = ISFIELD(::CompiledModel,"ModelReferenceBlocks") ? ...
      ::CompiledModel.ModelReferenceBlocks : []
 %if !ISEMPTY(mdlRefBlks)
      %foreach rowIdx = SIZE(mdlRefBlks,0)
        %assign mdlRefInfo = mdlRefBlks[rowIdx]
        %assign sysIdx = mdlRefInfo[0]
        %assign blkIdx = mdlRefInfo[1]
        %assign mdlBlk = System[sysIdx].Block[blkIdx]
        %if mdlBlk.MdlRefIsCPPClassGenMode
          %assign varName = SLibGetCPPMdlRefObjName(sysIdx, blkIdx)
          %assign mdlBlkSID = BlockHierarchyMap.Subsystem[mdlBlk.GrSrc[0]].Block[mdlBlk.GrSrc[1]].SID
          wr.writeModelBlockClassVariableName('%<mdlBlkSID>', '%<varName>');
        %endif
      %endforeach
%endif
%endfunction
 
%endif %% EXISTS("_CIINFODATALIB_") == 0
 
%%[EOF]codeinfo_datalib.tlc