blob: 1c83c2f104e448df7f62e80a5fb3efd33b8045af [file] [log] [blame]
{{/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/}}
{{Include "common.tmpl"}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ type for the specified AST type.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Type"}}
{{if not (IsType $)}}{{Macro "C++.Type" (TypeOf $)}}
{{else if IsVoid $}}void
{{else if IsBool $}}bool
{{else if IsInt $}}int
{{else if IsUint $}}uint
{{else if IsChar $}}char
{{else if IsU8 $}}uint8_t
{{else if IsS8 $}}int8_t
{{else if IsU16 $}}uint16_t
{{else if IsS16 $}}int16_t
{{else if IsF32 $}}float
{{else if IsU32 $}}uint32_t
{{else if IsS32 $}}int32_t
{{else if IsF64 $}}double
{{else if IsU64 $}}uint64_t
{{else if IsS64 $}}int64_t
{{else if IsEnum $}}{{Macro "C++.EnumType" $}}
{{else if IsReference $}}std::shared_ptr<{{Macro "C++.Type" $.To}}>
{{else if IsString $}}std::string
{{else if IsStaticArray $}}{{Macro "C++.Type" $.ValueType}}
{{else if IsSlice $}}Slice<{{if IsVoid $.To}}uint8_t{{else}}{{Macro "C++.Type" $.To}}{{end}}>
{{else if IsPointer $}}{{Macro "C++.Type" $.To}}*
{{else if IsAny $}}auto
{{else}}{{Macro "C++.TypeName" $}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits a typename that can be used for string concatenation for the given type.
-------------------------------------------------------------------------------
*/}}
{{define "C++.TypeName"}}
{{if not (IsType $)}}{{Macro "C++.TypeName" (TypeOf $)}}
{{else if IsPseudonym $}}{{$.Name}}
{{else if IsClass $}}{{Global "prefix"}}{{$.Name}}
{{else if IsEnum $}}{{Global "prefix"}}{{$.Name}}
{{else if IsMap $}}{{Macro "C++.TypeName" $.KeyType}}To{{Macro "C++.TypeName" $.ValueType}}
{{else if IsVoid $}}Void
{{else if IsBool $}}Bool
{{else if IsInt $}}Int
{{else if IsUint $}}Uint
{{else if IsChar $}}Char
{{else if IsU8 $}}U8
{{else if IsS8 $}}S8
{{else if IsU16 $}}U16
{{else if IsS16 $}}S16
{{else if IsF32 $}}F32
{{else if IsU32 $}}U32
{{else if IsS32 $}}S32
{{else if IsF64 $}}F64
{{else if IsU64 $}}U64
{{else if IsS64 $}}S64
{{else if IsString $}}String
{{else if IsReference $}}{{Macro "C++.TypeName" $.To}}Ref
{{else if IsSlice $}}{{Macro "C++.TypeName" $.To}}Slice
{{else if IsPointer $}}{{Macro "C++.TypeName" $.To}}Ptr
{{else}}{{Error "C++.TypeName passed unsupported type (%T): %s" $ $.Name}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ default value for the provided AST type.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Null"}}
{{AssertType $ "Type"}}
{{ if IsBool $}}false
{{else if IsInt $}}0
{{else if IsUint $}}0
{{else if IsS8 $}}0
{{else if IsU8 $}}0
{{else if IsS16 $}}0
{{else if IsU16 $}}0
{{else if IsS32 $}}0
{{else if IsU32 $}}0
{{else if IsF32 $}}0
{{else if IsS64 $}}0
{{else if IsU64 $}}0
{{else if IsF64 $}}0
{{else if IsEnum $}}0
{{else if IsString $}}""
{{else if IsPseudonym $}}{{Macro "C++.Null" $.To}}
{{else if IsClass $}}{{Macro "C++.Type" $}}()
{{else if IsSlice $}}{{Macro "C++.Type" $}}()
{{else if IsPointer $}}nullptr
{{else if IsReference $}}{{Macro "C++.Type" $}}()
{{else}}{{Error "macro Type called with unsupported type: %s" $.Name}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ type for the specified Enum.
By default this emits the enum name, but this behaviour can be overridden with
the global "C++.EnumTypeOverride".
-------------------------------------------------------------------------------
*/}}
{{define "C++.EnumType"}}
{{AssertType $ "Enum"}}
{{if $override := Global "C++.EnumTypeOverride"}}{{$override}}
{{else}}{{Macro "C++.EnumName" $}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the comma-separated list of type-name paired parameters for given
function.
-------------------------------------------------------------------------------
*/}}
{{define "C++.CallParameters"}}
{{AssertType $ "Function"}}
{{range $i, $p := $.CallParameters}}
{{if $i}}, {{end}}{{Macro "C++.ParameterType" $p}} {{$p.Name}}§
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the comma-separated list of function parameter types without the
parameter names.
-------------------------------------------------------------------------------
*/}}
{{define "C++.CallParameterTypes"}}
{{AssertType $ "Function"}}
{{range $i, $p := $.CallParameters}}
{{if $i}}, {{end}}{{Macro "C++.ParameterType" $p}}§
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the comma-separated list of argument names for the given function.
-------------------------------------------------------------------------------
*/}}
{{define "C++.CallArguments"}}
{{AssertType $ "Function"}}
{{range $i, $p := $.CallParameters}}
{{if $i}}, {{end}}{{$p.Name}}§
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ type for use as a parameter for the given parameter or type.
-------------------------------------------------------------------------------
*/}}
{{define "C++.ParameterType"}}
{{AssertType $ "Type" "Parameter"}}
{{ if IsParameter $}}{{Macro "C++.ParameterType" (TypeOf $)}}
{{else if IsPseudonym $}}{{Macro "C++.ParameterType" $.To}}
{{else if IsPointer $}}{{Macro "C++.ParameterType" $.To}}*
{{else if IsString $}}char*
{{else if IsAny $}}{{Macro "C++.ParameterTypeAny" $}}
{{else }}{{Macro "C++.Type" $}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
If the specified parameter is of type 'any' then this macro emits the
corresponding template parameter name. If the parameter is not of type 'any'
then nothing is emitted.
-------------------------------------------------------------------------------
*/}}
{{define "C++.ParameterTypeAny"}}
{{AssertType $ "Parameter"}}
{{if IsAny (TypeOf $)}}
{{$index := IndexOf $.Function.FullParameters $}}
ARG{{$index}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ return type for the given command.
-------------------------------------------------------------------------------
*/}}
{{define "C++.ReturnType"}}
{{AssertType $ "Function"}}
{{Macro "C++.ParameterType" $.Return}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic for all the statements in the given block.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Block"}}
{{range $s := $.Statements}}
{{$v := Macro "C++.Statement" $s}}
{{$v}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the name for the given local variable.
-------------------------------------------------------------------------------
*/}}
{{define "C++.LocalName"}}
{{AssertType $ "Local"}}
l_{{$.Name}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to execute the given statement.
If the global "C++.Statement.Override" is specified then this the macro with
the specified name is called, otherwise the macro delegates to
"C++.Statement.Default".
-------------------------------------------------------------------------------
*/}}
{{define "C++.Statement"}}
{{if $override := Global "C++.Statement.Override"}}
{{Macro $override $}}
{{else}}
{{Macro "C++.Statement.Default" $}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to execute the given statement.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Statement.Default"}}
{{ if IsDeclareLocal $}}{{Macro "C++.Type" (TypeOf $.Local)}} {{Macro "C++.LocalName" $.Local}} = {{Macro "C++.Read" $.Local.Value}};
{{else if IsAssign $}}{{Macro "C++.Assign" $}}
{{else if IsMapAssign $}}{{Macro "C++.MapAssign" $}}
{{else if IsSliceAssign $}}{{Macro "C++.SliceAssign" $}}
{{else if IsReturn $}}return {{Macro "C++.Read" $.Value}};
{{else if IsBranch $}}if ({{Macro "C++.Read" $.Condition}}) {
{{Macro "C++.Block" $.True}}
{{if len $.False.Statements}}
} else {
{{Macro "C++.Block" $.False}}
{{end}}
}
{{else if IsSwitch $}}
switch ({{Macro "C++.Read" $.Value}}) {
{{range $i, $c := $.Cases}}
{{range $j, $cond := $c.Conditions}}
case {{Macro "C++.Read" $cond}}:{{if HasMore $j $c.Conditions}} // fall-through...{{else}} {{"{"}}{{end}}
{{end}}
{{Macro "C++.Block" $c.Block}}
break;
}
{{end}}
}
{{else if IsIteration $}}{{Macro "C++.Iteration" $}}
{{else if IsCall $}}{{Macro "C++.Call" $}};
{{else if IsAssert $}}
{{else if IsRead $}}read({{Macro "C++.Read" $.Slice}});
{{else if IsWrite $}}write({{Macro "C++.Read" $.Slice}});
{{else if IsCopy $}}copy({{Macro "C++.Read" $.Dst}}, {{Macro "C++.Read" $.Src}});
{{else }}{{Error "unsupported statement %T: %+v" $ $}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to perform an assign statement.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Assign"}}
{{AssertType $ "Assign"}}
{{Macro "C++.Read" $.LHS}} {{$.Operator}} {{Macro "C++.Read" $.RHS}};
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to perform a map assign statement.
-------------------------------------------------------------------------------
*/}}
{{define "C++.MapAssign"}}
{{AssertType $ "MapAssign"}}
{{Macro "C++.Read" $.To.Map}}[{{Macro "C++.Read" $.To.Index}}] {{$.Operator}} {{Macro "C++.Read" $.Value}};
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to perform a slice assign statement.
-------------------------------------------------------------------------------
*/}}
{{define "C++.SliceAssign"}}
{{AssertType $ "SliceAssign"}}
{{if eq $.Operator "="}}write({{Macro "C++.Read" $.To.Slice}}, {{Macro "C++.Read" $.To.Index}}, {{Macro "C++.Read" $.Value}});
{{else}}{{Error "Unsupported MapAssign operator %s" $.Operator}}{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to perform an iteration statement.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Iteration"}}
{{AssertType $ "Iteration"}}
{{if IsBinaryOp $.Iterable}}
{{Macro "C++.Range" "Name" (Macro "C++.Read" $.Iterator) "Range" $.Iterable}} {
{{Macro "C++.Block" $.Block}}
}
{{else}}
{{$it := Macro "C++.LocalName" $.Iterator}}
for ({{Macro "C++.Type" $.Iterable}}::iterator {{$it}} = {{Macro "C++.Read" $.Iterable}}; {{$it}} != {{Macro "C++.Read" $.Iterable}}.end(); ++{{$it}}) {
{{Macro "C++.Block" $.Block}}
}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to read the given expression.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Read"}}
{{ if IsBoolValue $}}{{$}}
{{else if IsNumericValue $}}{{$}}
{{else if IsStringValue $}}{{printf "%q" $}}
{{else if IsParameter $}}{{$.Name}}
{{else if IsBinaryOp $}}{{Macro "C++.Read" $.LHS}} {{$.Operator}} {{Macro "C++.Read" $.RHS}}
{{else if IsUnaryOp $}}{{$.Operator}}({{Macro "C++.Read" $.Expression}})
{{else if IsEnumEntry $}}{{Macro "C++.EnumName" $.Enum}}::{{Macro "C++.EnumEntryName" $}}
{{else if IsLocal $}}{{Macro "C++.LocalName" $}}
{{else if IsBitTest $}}({{Macro "C++.Read" $.Bitfield}} & {{Macro "C++.Read" $.Bits}}) != 0
{{else if IsBinaryOp $}}({{Macro "C++.Read" $.LHS}}) {{$.Operator}} ({{Macro "C++.Read" $.RHS}})
{{else if IsCast $}}{{Macro "C++.Cast" $}}
{{else if IsCall $}}{{Macro "C++.Call" $}}
{{else if IsUnknown $}}{{Macro "C++.Read" $.Inferred}}
{{else if IsObserved $}}{{Macro "C++.Read" $.Parameter}}
{{else if IsMember $}}{{Macro "C++.Dereference" $.Object}}m{{$.Field.Name}}
{{else if IsGlobal $}}this->{{$.Name}}
{{else if IsMapIndex $}}{{Macro "C++.Read" $.Map}}[{{Macro "C++.Read" $.Index}}]
{{else if IsMapContains $}}{{Macro "C++.Read" $.Map}}.count({{Macro "C++.Read" $.Key}}) > 0
{{else if IsLength $}}{{Macro "C++.Read" $.Object}}.size()
{{else if IsNull $}}{{Macro "C++.Null" $.Type}}
{{else if IsNew $}}{{$ty := Unpack $.Type}}std::shared_ptr<{{Macro "C++.Type" $ty.To}}>(new {{Macro "C++.Type" $ty.To}}())
{{else if IsCreate $}}{{$ty := Unpack $.Type}}std::shared_ptr<{{Macro "C++.Type" $ty.To}}>((new {{Macro "C++.Type" $ty.To}}()){{Macro "C++.InitializeFields" $.Initializer}})
{{else if IsClassInitializer $}}{{Macro "C++.Type" $}}(){{Macro "C++.InitializeFields" $}}
{{else if IsSliceIndex $}}read({{Macro "C++.Read" $.Slice}}, {{Macro "C++.Read" $.Index}})
{{else if IsSliceRange $}}slice({{Macro "C++.Read" $.Slice}}, {{Macro "C++.Read" $.Range.LHS}}, {{Macro "C++.Read" $.Range.RHS}})
{{else if IsPointerRange $}}slice({{Macro "C++.Read" $.Pointer}}, {{Macro "C++.Read" $.Range.LHS}}, {{Macro "C++.Read" $.Range.RHS}})
{{else if IsClone $}}clone({{Macro "C++.Read" $.Slice}})
{{else if IsMake $}}make<{{Macro "C++.Type" ($.Type | Unpack).To}}>({{Macro "C++.Read" $.Size}})
{{else if IsSelect $}}/* clang-format off */
/* switch({{Macro "C++.Read" $.Value}}) */»
{{range $c := $.Choices}}
/* case {{range $i, $cond := $c.Conditions}}{{if $i}}, {{end}}{{Macro "C++.Read" $cond}}{{end}}: */§
({{range $i, $cond := $c.Conditions}}§
{{if $i}} || {{end}}(({{Macro "C++.Read" $.Value}}) == ({{Macro "C++.Read" $cond}}))§
{{end}}) ? ({{Macro "C++.Read" $c.Expression}}) :
{{end}}
/* default: */ {{Macro "C++.Null" $.Type}}« /* clang-format on */
{{else}}{{Error "macro C++.Read called with unsupported type: %T" $}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits a chain of 'fluent' set calls, initializing the target class.
-------------------------------------------------------------------------------
*/}}
{{define "C++.InitializeFields"}}
{{AssertType $ "ClassInitializer"}}
{{range $f := $.Fields}}.Set{{$f.Field.Name}}({{Macro "C++.Read" $f.Value}}){{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits a C++ dereference (-> or .) for the given value.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Dereference"}}
{{Macro "C++.Read" $}}{{if or (IsReference (TypeOf $))}}->{{else}}.{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits a comma-separated list of reads.
-------------------------------------------------------------------------------
*/}}
{{define "C++.ReadList"}}
{{range $i, $v := $}}
{{if $i}}, {{end}}{{Macro "C++.Read" $v}}§
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to execute an iteration statement.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Range"}}
{{AssertType $.Name "string"}}
{{AssertType $.Range "BinaryOp"}}
for ({{Macro "C++.Type" $.Range.RHS}} {{$.Name}} = {{Macro "C++.Read" $.Range.LHS}}; {{$.Name}} < {{Macro "C++.Read" $.Range.RHS}}; ++{{$.Name}})
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to execute a cast expression.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Cast"}}
{{AssertType $ "Cast"}}
{{$src_ty := $.Object | TypeOf | Underlying | Unpack}}
{{$dst_ty := $.Type | Underlying}}
{{$src := Macro "C++.Read" $.Object}}
{{/* T[] -> T* */}}{{if and (IsSlice $src_ty) (IsPointer $dst_ty)}}
{{$src}}.begin()
{{/* char[] -> string */}}{{else if and (IsSlice $src_ty) (IsString $dst_ty)}}
string({{$src}})
{{/* string[] -> char[] */}}{{else if and (IsString $src_ty) (IsSlice $dst_ty)}}
slice({{$src}})
{{else}}
({{Macro "C++.Type" $.Type}})({{$src}})
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to execute a call expression.
-------------------------------------------------------------------------------
*/}}
{{define "C++.Call"}}
{{AssertType $ "Call"}}
{{if $.Target.Object}}{{Macro "C++.MethodCall" $}}
{{else}}{{/* extern */}}
{{$.Target.Function.Name}}({{Macro "C++.ReadList" $.Arguments}})
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ logic to execute a method call expression.
-------------------------------------------------------------------------------
*/}}
{{define "C++.MethodCall"}}
{{$is_map_delete := and (IsMap (TypeOf $.Target.Object)) (eq $.Target.Function.Name "Delete")}}
{{if $is_map_delete}}{{Macro "C++.Read" $.Target.Object}}.erase({{Macro "C++.ReadList" $.Arguments}})
{{else }}{{Macro "C++.Read" $.Target.Object}}.{{$.Target.Function.Name}}({{Macro "C++.ReadList" $.Arguments}})
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Transforms the given string or identifier into a format used for a public
type or field. Example:
this_is_public -> ThisIsPublic
-------------------------------------------------------------------------------
*/}}
{{define "C++.Public"}}
{{AssertType $ "string"}}
{{$ | SplitOn "_" | Title}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits a comment stating that the file is automatically generated.
-------------------------------------------------------------------------------
*/}}
{{define "C++.GeneratedHeader"}}⋖{{Copyright "generated" "apic"}}⋗{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the Android Open Source Project copyright header.
-------------------------------------------------------------------------------
*/}}
{{define "C++.AOSP.Copyright"}}⋖{{Copyright "generated_aosp_c" "apic"}}⋗{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the fixed-size-array postfix for static array types.
-------------------------------------------------------------------------------
*/}}
{{define "C++.ArrayPostfix"}}
{{if not (IsType $)}}{{Macro "C++.ArrayPostfix" (TypeOf $)}}
{{else if IsStaticArray $}}[{{$.Size}}]
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits a comment block containing the specified text.
-------------------------------------------------------------------------------
*/}}
{{define "C++.CommentHeader"}}
{{AssertType $ "string"}} {{/* The comment block body text */}}
////////////////////////////////////////////////////////////////////////////////
// {{.}}
////////////////////////////////////////////////////////////////////////////////
{{end}}
{{$clang_style := "{BasedOnStyle: Google, AccessModifierOffset: -4, ColumnLimit: 100, ContinuationIndentWidth: 8, IndentWidth: 4}"}}
{{Global "clang-format" (Strings "clang-format" "-style" $clang_style)}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ name of an enum type.
-------------------------------------------------------------------------------
*/}}
{{define "C++.EnumName"}}
{{AssertType $ "Enum"}}
{{if $p := Global "prefix"}}{{$p}}{{Title $.Name}}
{{else}}{{$.Name}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ name of an enum entry.
-------------------------------------------------------------------------------
*/}}
{{define "C++.EnumEntryName"}}
{{AssertType $.Enum "Enum"}}
{{AssertType $.Name "string"}}
{{/* TODO: Get rid of enum prefixes. */}}
{{if $enumPrefix := GetAnnotation $.Enum "prefix"}}
{{index $enumPrefix.Arguments 0}}_§
{{else if $apiPrefix := Global "prefix"}}
{{Upper $apiPrefix}}_§
{{$.Enum.Name | SplitPascalCase | Upper | JoinWith "_"}}_§
{{end}}
{{TrimLeft "_" $.Name}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the printf format code for the specified type
-------------------------------------------------------------------------------
*/}}
{{define "C++.PrintfFormatCode"}}
{{AssertType $ "Type"}}
{{ if IsPseudonym $}}{{Macro "C++.PrintfFormatCode" $.To}}
{{else if IsPointer $}}%p
{{else if IsClass $}}%p
{{else if IsString $}}%s
{{else if IsBool $}}%d
{{else if IsS32 $}}%d
{{else if IsU32 $}}%u
{{else if IsF32 $}}%f
{{else if IsInt $}}%d
{{else if IsUint $}}%u
{{else if IsU64 $}}%u
{{else if IsEnum $}}%u
{{else}}{{Error "C++.PrintfFormatCode passed unsupported type: %s" $.Name}}
{{end}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the typedef function-pointer name for a given command.
-------------------------------------------------------------------------------
*/}}
{{define "C++.FunctionPtrType"}}
{{AssertType $ "Function"}}
PFN{{Macro "CmdName" $ | Upper}}
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ function-pointer typedef for a given command.
-------------------------------------------------------------------------------
*/}}
{{define "C++.TypedefFunctionPtr"}}
{{AssertType $ "Function"}}
typedef {{Macro "C++.ReturnType" $}} (STDCALL *{{Macro "C++.FunctionPtrType" $}})({{Macro "C++.CallParameters" $}});
{{end}}
{{/*
-------------------------------------------------------------------------------
Emits the C++ function-pointer variable extern for a given command.
-------------------------------------------------------------------------------
*/}}
{{define "C++.FunctionPtrDecl"}}
{{AssertType $ "Function"}}
{{Macro "C++.FunctionPtrType" $}} {{Macro "CmdName" $}}
{{end}}