2015-08-17 05:38:30 -04:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
# include "BlueprintCompilerCppBackendModulePrivatePCH.h"
# include "BlueprintCompilerCppBackendBase.h"
# include "BlueprintCompilerCppBackendUtils.h"
void FBlueprintCompilerCppBackendBase : : EmitStructProperties ( FStringOutputDevice & Target , UStruct * SourceClass )
{
// Emit class variables
for ( TFieldIterator < UProperty > It ( SourceClass , EFieldIteratorFlags : : ExcludeSuper ) ; It ; + + It )
{
UProperty * Property = * It ;
check ( Property ) ;
Emit ( Header , TEXT ( " \n \t UPROPERTY( " ) ) ;
{
2015-09-07 09:39:56 -04:00
TArray < FString > Tags = FEmitHelper : : ProperyFlagsToTags ( Property - > PropertyFlags , nullptr ! = Cast < UClass > ( SourceClass ) ) ;
2015-08-17 05:38:30 -04:00
Tags . Emplace ( FEmitHelper : : HandleRepNotifyFunc ( Property ) ) ;
Tags . Emplace ( FEmitHelper : : HandleMetaData ( Property , false ) ) ;
Tags . Remove ( FString ( ) ) ;
FString AllTags ;
FEmitHelper : : ArrayToString ( Tags , AllTags , TEXT ( " , " ) ) ;
Emit ( Header , * AllTags ) ;
}
Emit ( Header , TEXT ( " ) \n " ) ) ;
Emit ( Header , TEXT ( " \t " ) ) ;
Property - > ExportCppDeclaration ( Target , EExportedDeclaration : : Member , NULL , EPropertyExportCPPFlags : : CPPF_CustomTypeName | EPropertyExportCPPFlags : : CPPF_BlueprintCppBackend ) ;
Emit ( Header , TEXT ( " ; \n " ) ) ;
}
}
2015-09-04 07:50:42 -04:00
void FBlueprintCompilerCppBackendBase : : DeclareDelegates ( UClass * SourceClass , TIndirectArray < FKismetFunctionContext > & Functions )
2015-08-17 05:38:30 -04:00
{
// MC DELEGATE DECLARATION
{
auto DelegateDeclarations = FEmitHelper : : EmitMulticastDelegateDeclarations ( SourceClass ) ;
FString AllDeclarations ;
FEmitHelper : : ArrayToString ( DelegateDeclarations , AllDeclarations , TEXT ( " ; \n " ) ) ;
if ( DelegateDeclarations . Num ( ) )
{
Emit ( Header , * AllDeclarations ) ;
Emit ( Header , TEXT ( " ; \n " ) ) ;
}
}
// GATHER ALL SC DELEGATES
{
TArray < UDelegateProperty * > Delegates ;
for ( TFieldIterator < UDelegateProperty > It ( SourceClass , EFieldIteratorFlags : : ExcludeSuper ) ; It ; + + It )
{
Delegates . Add ( * It ) ;
}
for ( auto & FuncContext : Functions )
{
for ( TFieldIterator < UDelegateProperty > It ( FuncContext . Function , EFieldIteratorFlags : : ExcludeSuper ) ; It ; + + It )
{
Delegates . Add ( * It ) ;
}
}
auto DelegateDeclarations = FEmitHelper : : EmitSinglecastDelegateDeclarations ( Delegates ) ;
FString AllDeclarations ;
FEmitHelper : : ArrayToString ( DelegateDeclarations , AllDeclarations , TEXT ( " ; \n " ) ) ;
if ( DelegateDeclarations . Num ( ) )
{
Emit ( Header , * AllDeclarations ) ;
Emit ( Header , TEXT ( " ; \n " ) ) ;
}
}
2015-09-04 07:50:42 -04:00
}
void FBlueprintCompilerCppBackendBase : : GenerateCodeFromClass ( UClass * SourceClass , TIndirectArray < FKismetFunctionContext > & Functions , bool bGenerateStubsOnly )
{
auto CleanCppClassName = SourceClass - > GetName ( ) ;
2015-09-08 06:44:17 -04:00
CppClassName = FEmitHelper : : GetCppName ( SourceClass ) ;
2015-09-04 07:50:42 -04:00
2015-09-06 07:59:37 -04:00
FGatherConvertedClassDependencies Dependencies ( SourceClass ) ;
EmitFileBeginning ( CleanCppClassName , & Dependencies ) ;
2015-08-17 05:38:30 -04:00
// Class declaration
const bool bIsInterface = SourceClass - > IsChildOf < UInterface > ( ) ;
if ( bIsInterface )
{
2015-08-19 10:27:00 -04:00
Emit ( Header , TEXT ( " UINTERFACE(Blueprintable " ) ) ;
EmitReplaceConvertedMetaData ( SourceClass ) ;
Emit ( Header , * FString : : Printf ( TEXT ( " ) \n class U%s : public UInterface \n { \n \t GENERATED_BODY() \n }; \n " ) , * CleanCppClassName ) ) ;
2015-08-17 05:38:30 -04:00
Emit ( Header , * FString : : Printf ( TEXT ( " \n class I%s " ) , * CleanCppClassName ) ) ;
}
else
{
Emit ( Header , TEXT ( " UCLASS( " ) ) ;
if ( ! SourceClass - > IsChildOf < UBlueprintFunctionLibrary > ( ) )
{
Emit ( Header , TEXT ( " Blueprintable, BlueprintType " ) ) ;
}
2015-08-19 10:27:00 -04:00
EmitReplaceConvertedMetaData ( SourceClass ) ;
2015-08-17 05:38:30 -04:00
Emit ( Header , TEXT ( " ) \n " ) ) ;
UClass * SuperClass = SourceClass - > GetSuperClass ( ) ;
2015-09-08 06:44:17 -04:00
Emit ( Header , * FString : : Printf ( TEXT ( " class %s : public %s " ) , * CppClassName , * FEmitHelper : : GetCppName ( SuperClass ) ) ) ;
2015-08-17 05:38:30 -04:00
for ( auto & ImplementedInterface : SourceClass - > Interfaces )
{
if ( ImplementedInterface . Class )
{
2015-09-08 06:44:17 -04:00
Emit ( Header , * FString : : Printf ( TEXT ( " , public %s " ) , * FEmitHelper : : GetCppName ( ImplementedInterface . Class ) ) ) ;
2015-08-17 05:38:30 -04:00
}
}
}
// Begin scope
Emit ( Header , TEXT ( " \n { \n public: \n \t GENERATED_BODY() \n " ) ) ;
2015-09-04 07:50:42 -04:00
DeclareDelegates ( SourceClass , Functions ) ;
2015-08-17 05:38:30 -04:00
EmitStructProperties ( Header , SourceClass ) ;
// Create the state map
for ( int32 i = 0 ; i < Functions . Num ( ) ; + + i )
{
StateMapPerFunction . Add ( FFunctionLabelInfo ( ) ) ;
FunctionIndexMap . Add ( & Functions [ i ] , i ) ;
}
// Emit function declarations and definitions (writes to header and body simultaneously)
if ( Functions . Num ( ) > 0 )
{
Emit ( Header , TEXT ( " \n " ) ) ;
}
2015-09-10 09:15:43 -04:00
FEmitterLocalContext EmitterContext ( SourceClass , Dependencies ) ;
2015-08-17 05:38:30 -04:00
if ( ! bIsInterface )
{
Emit ( Header , * FString : : Printf ( TEXT ( " \t %s(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); \n \n " ) , * CppClassName ) ) ;
2015-09-10 09:15:43 -04:00
Emit ( Body , * FEmitDefaultValueHelper : : GenerateConstructor ( EmitterContext ) ) ;
2015-08-17 05:38:30 -04:00
}
2015-09-14 09:23:48 -04:00
Emit ( Header , TEXT ( " \n \t virtual void PostLoadSubobjects(FObjectInstancingGraph* OuterInstanceGraph) override; \n " ) ) ;
2015-08-17 05:38:30 -04:00
for ( int32 i = 0 ; i < Functions . Num ( ) ; + + i )
{
if ( Functions [ i ] . IsValid ( ) )
{
2015-09-10 09:15:43 -04:00
ConstructFunction ( Functions [ i ] , EmitterContext , bGenerateStubsOnly ) ;
2015-08-17 05:38:30 -04:00
}
}
2015-09-08 11:03:41 -04:00
Emit ( Header , TEXT ( " \n \t static void __StaticDependenciesAssets(TArray<FName>& OutPackagePaths); \n " ) ) ;
2015-09-04 07:50:42 -04:00
2015-09-02 04:22:33 -04:00
Emit ( Header , * FBackendHelperUMG : : WidgetFunctionsInHeader ( SourceClass ) ) ;
2015-08-17 05:38:30 -04:00
Emit ( Header , TEXT ( " }; \n \n " ) ) ;
Emit ( Body , * FEmitHelper : : EmitLifetimeReplicatedPropsImpl ( SourceClass , CppClassName , TEXT ( " " ) ) ) ;
}
void FBlueprintCompilerCppBackendBase : : DeclareLocalVariables ( FKismetFunctionContext & FunctionContext , TArray < UProperty * > & LocalVariables )
{
for ( int32 i = 0 ; i < LocalVariables . Num ( ) ; + + i )
{
UProperty * LocalVariable = LocalVariables [ i ] ;
Emit ( Body , TEXT ( " \t " ) ) ;
LocalVariable - > ExportCppDeclaration ( Body , EExportedDeclaration : : Local , NULL , EPropertyExportCPPFlags : : CPPF_CustomTypeName | EPropertyExportCPPFlags : : CPPF_BlueprintCppBackend ) ;
Emit ( Body , TEXT ( " {}; \n " ) ) ;
}
if ( LocalVariables . Num ( ) > 0 )
{
Emit ( Body , TEXT ( " \n " ) ) ;
}
}
2015-09-10 09:15:43 -04:00
void FBlueprintCompilerCppBackendBase : : ConstructFunction ( FKismetFunctionContext & FunctionContext , FEmitterLocalContext & EmitterContext , bool bGenerateStubOnly )
2015-08-17 05:38:30 -04:00
{
if ( FunctionContext . IsDelegateSignature ( ) )
{
return ;
}
UFunction * Function = FunctionContext . Function ;
UProperty * ReturnValue = NULL ;
TArray < UProperty * > LocalVariables ;
{
2015-09-08 06:44:17 -04:00
FString FunctionName = FEmitHelper : : GetCppName ( Function ) ;
2015-08-17 05:38:30 -04:00
TArray < UProperty * > ArgumentList ;
// Split the function property list into arguments, a return value (if any), and local variable declarations
for ( TFieldIterator < UProperty > It ( Function ) ; It ; + + It )
{
UProperty * Property = * It ;
if ( Property - > HasAnyPropertyFlags ( CPF_Parm ) )
{
if ( Property - > HasAnyPropertyFlags ( CPF_ReturnParm ) )
{
if ( ReturnValue = = NULL )
{
ReturnValue = Property ;
LocalVariables . Add ( Property ) ;
}
else
{
UE_LOG ( LogK2Compiler , Error , TEXT ( " Function %s from graph @@ has more than one return value (named %s and %s) " ) ,
* FunctionName , * GetPathNameSafe ( FunctionContext . SourceGraph ) , * ReturnValue - > GetName ( ) , * Property - > GetName ( ) ) ;
}
}
else
{
ArgumentList . Add ( Property ) ;
}
}
else
{
LocalVariables . Add ( Property ) ;
}
}
bool bAddCppFromBpEventMD = false ;
bool bGenerateAsNativeEventImplementation = false ;
// Get original function declaration
2015-08-18 09:51:49 -04:00
if ( FEmitHelper : : ShouldHandleAsNativeEvent ( Function ) ) // BlueprintNativeEvent
2015-08-17 05:38:30 -04:00
{
bGenerateAsNativeEventImplementation = true ;
FunctionName + = TEXT ( " _Implementation " ) ;
}
2015-08-18 09:51:49 -04:00
else if ( FEmitHelper : : ShouldHandleAsImplementableEvent ( Function ) ) // BlueprintImplementableEvent
2015-08-17 05:38:30 -04:00
{
bAddCppFromBpEventMD = true ;
}
// Emit the declaration
const FString ReturnType = ReturnValue ? ReturnValue - > GetCPPType ( NULL , EPropertyExportCPPFlags : : CPPF_CustomTypeName ) : TEXT ( " void " ) ;
//@TODO: Make the header+body export more uniform
{
const FString Start = FString : : Printf ( TEXT ( " %s %s%s%s( " ) , * ReturnType , TEXT ( " %s " ) , TEXT ( " %s " ) , * FunctionName ) ;
TArray < FString > AdditionalMetaData ;
if ( bAddCppFromBpEventMD )
{
AdditionalMetaData . Emplace ( TEXT ( " CppFromBpEvent " ) ) ;
}
if ( ! bGenerateAsNativeEventImplementation )
{
Emit ( Header , * FString : : Printf ( TEXT ( " \t %s \n " ) , * FEmitHelper : : EmitUFuntion ( Function , & AdditionalMetaData ) ) ) ;
}
Emit ( Header , TEXT ( " \t " ) ) ;
if ( Function - > HasAllFunctionFlags ( FUNC_Static ) )
{
Emit ( Header , TEXT ( " static " ) ) ;
}
if ( bGenerateAsNativeEventImplementation )
{
Emit ( Header , TEXT ( " virtual " ) ) ;
}
Emit ( Header , * FString : : Printf ( * Start , TEXT ( " " ) , TEXT ( " " ) ) ) ;
Emit ( Body , * FString : : Printf ( * Start , * CppClassName , TEXT ( " :: " ) ) ) ;
for ( int32 i = 0 ; i < ArgumentList . Num ( ) ; + + i )
{
UProperty * ArgProperty = ArgumentList [ i ] ;
if ( i > 0 )
{
Emit ( Header , TEXT ( " , " ) ) ;
Emit ( Body , TEXT ( " , " ) ) ;
}
if ( ArgProperty - > HasAnyPropertyFlags ( CPF_OutParm ) )
{
Emit ( Header , TEXT ( " /*out*/ " ) ) ;
Emit ( Body , TEXT ( " /*out*/ " ) ) ;
}
ArgProperty - > ExportCppDeclaration ( Header , EExportedDeclaration : : Parameter , NULL , EPropertyExportCPPFlags : : CPPF_CustomTypeName | EPropertyExportCPPFlags : : CPPF_BlueprintCppBackend ) ;
ArgProperty - > ExportCppDeclaration ( Body , EExportedDeclaration : : Parameter , NULL , EPropertyExportCPPFlags : : CPPF_CustomTypeName | EPropertyExportCPPFlags : : CPPF_BlueprintCppBackend ) ;
}
Emit ( Header , TEXT ( " ) " ) ) ;
if ( bGenerateAsNativeEventImplementation )
{
Emit ( Header , TEXT ( " override " ) ) ;
}
Emit ( Header , TEXT ( " ; \n " ) ) ;
Emit ( Body , TEXT ( " ) \n " ) ) ;
}
// Start the body of the implementation
Emit ( Body , TEXT ( " { \n " ) ) ;
}
if ( ! bGenerateStubOnly )
{
// Emit local variables
DeclareLocalVariables ( FunctionContext , LocalVariables ) ;
2015-08-17 06:12:13 -04:00
const bool bUseSwitchState = FunctionContext . MustUseSwitchState ( nullptr ) ;
2015-08-17 05:38:30 -04:00
// Run thru code looking only at things marked as jump targets, to make sure the jump targets are ordered in order of appearance in the linear execution list
// Emit code in the order specified by the linear execution list (the first node is always the entry point for the function)
for ( int32 NodeIndex = 0 ; NodeIndex < FunctionContext . LinearExecutionList . Num ( ) ; + + NodeIndex )
{
UEdGraphNode * StatementNode = FunctionContext . LinearExecutionList [ NodeIndex ] ;
TArray < FBlueprintCompiledStatement * > * StatementList = FunctionContext . StatementsPerNode . Find ( StatementNode ) ;
if ( StatementList ! = NULL )
{
for ( int32 StatementIndex = 0 ; StatementIndex < StatementList - > Num ( ) ; + + StatementIndex )
{
FBlueprintCompiledStatement & Statement = * ( ( * StatementList ) [ StatementIndex ] ) ;
if ( Statement . bIsJumpTarget )
{
// Just making sure we number them in order of appearance, so jump statements don't influence the order
const int32 StateNum = StatementToStateIndex ( FunctionContext , & Statement ) ;
}
}
}
}
2015-09-10 09:15:43 -04:00
const FString FunctionImplementation = InnerFunctionImplementation ( FunctionContext , EmitterContext , bUseSwitchState ) ;
2015-08-17 05:38:30 -04:00
Emit ( Body , * FunctionImplementation ) ;
}
2015-09-10 09:15:43 -04:00
const FString ReturnValueString = ReturnValue ? ( FString ( TEXT ( " " ) ) + FEmitHelper : : GetCppName ( ReturnValue ) ) : TEXT ( " " ) ;
2015-08-17 05:38:30 -04:00
Emit ( Body , * FString : : Printf ( TEXT ( " \t return%s; \n " ) , * ReturnValueString ) ) ;
Emit ( Body , TEXT ( " } \n \n " ) ) ;
}
void FBlueprintCompilerCppBackendBase : : GenerateCodeFromEnum ( UUserDefinedEnum * SourceEnum )
{
check ( SourceEnum ) ;
2015-09-08 06:44:17 -04:00
EmitFileBeginning ( SourceEnum - > GetName ( ) , nullptr ) ;
2015-08-17 05:38:30 -04:00
2015-08-19 10:27:00 -04:00
Emit ( Header , TEXT ( " UENUM(BlueprintType " ) ) ;
EmitReplaceConvertedMetaData ( SourceEnum ) ;
Emit ( Header , TEXT ( " ) \n enum class " ) ) ;
2015-09-08 06:44:17 -04:00
Emit ( Header , * FEmitHelper : : GetCppName ( SourceEnum ) ) ;
2015-08-17 05:38:30 -04:00
Emit ( Header , TEXT ( " : uint8 \n { " ) ) ;
for ( int32 Index = 0 ; Index < SourceEnum - > NumEnums ( ) ; + + Index )
{
const FString ElemName = SourceEnum - > GetEnumName ( Index ) ;
const int32 ElemValue = Index ;
const FString & DisplayNameMD = SourceEnum - > GetMetaData ( TEXT ( " DisplayName " ) , ElemValue ) ; // TODO: value or index?
const FString Meta = DisplayNameMD . IsEmpty ( ) ? FString ( ) : FString : : Printf ( TEXT ( " UMETA(DisplayName = \" %s \" ) " ) , * DisplayNameMD ) ;
Emit ( Header , * FString : : Printf ( TEXT ( " \n \t %s = %d %s, " ) , * ElemName , ElemValue , * Meta ) ) ;
}
Emit ( Header , TEXT ( " \n }; \n " ) ) ;
}
2015-08-19 10:27:00 -04:00
void FBlueprintCompilerCppBackendBase : : EmitReplaceConvertedMetaData ( UObject * Obj )
{
const FString ReplaceConvertedMD = FEmitHelper : : GenerateReplaceConvertedMD ( Obj ) ;
if ( ! ReplaceConvertedMD . IsEmpty ( ) )
{
TArray < FString > AdditionalMD ;
AdditionalMD . Add ( ReplaceConvertedMD ) ;
Emit ( Header , TEXT ( " , " ) ) ;
Emit ( Header , * FEmitHelper : : HandleMetaData ( nullptr , false , & AdditionalMD ) ) ;
}
}
2015-08-17 05:38:30 -04:00
void FBlueprintCompilerCppBackendBase : : GenerateCodeFromStruct ( UUserDefinedStruct * SourceStruct )
{
check ( SourceStruct ) ;
2015-09-06 07:59:37 -04:00
FGatherConvertedClassDependencies Dependencies ( SourceStruct ) ;
EmitFileBeginning ( SourceStruct - > GetName ( ) , & Dependencies ) ;
2015-08-17 05:38:30 -04:00
2015-09-08 06:44:17 -04:00
const FString NewName = FEmitHelper : : GetCppName ( SourceStruct ) ;
2015-08-19 10:27:00 -04:00
Emit ( Header , TEXT ( " USTRUCT(BlueprintType " ) ) ;
EmitReplaceConvertedMetaData ( SourceStruct ) ;
Emit ( Header , TEXT ( " ) \n " ) ) ;
2015-08-17 05:38:30 -04:00
Emit ( Header , * FString : : Printf ( TEXT ( " struct %s \n { \n public: \n \t GENERATED_BODY() \n " ) , * NewName ) ) ;
EmitStructProperties ( Header , SourceStruct ) ;
2015-09-06 07:59:37 -04:00
Emit ( Header , * FEmitDefaultValueHelper : : GenerateGetDefaultValue ( SourceStruct , Dependencies ) ) ;
2015-08-17 05:38:30 -04:00
Emit ( Header , TEXT ( " }; \n " ) ) ;
}
2015-09-06 07:59:37 -04:00
void FBlueprintCompilerCppBackendBase : : EmitFileBeginning ( const FString & CleanName , FGatherConvertedClassDependencies * Dependencies )
2015-08-17 05:38:30 -04:00
{
Emit ( Header , TEXT ( " #pragma once \n \n " ) ) ;
2015-09-06 07:59:37 -04:00
auto EmitIncludeHeader = [ & ] ( FStringOutputDevice & Dst , const TCHAR * Message , bool bAddDotH )
{
Emit ( Dst , * FString : : Printf ( TEXT ( " #include \" %s%s \" \n " ) , Message , bAddDotH ? TEXT ( " .h " ) : TEXT ( " " ) ) ) ;
} ;
EmitIncludeHeader ( Body , FApp : : GetGameName ( ) , true ) ;
EmitIncludeHeader ( Body , * CleanName , true ) ;
EmitIncludeHeader ( Body , TEXT ( " GeneratedCodeHelpers " ) , true ) ;
if ( Dependencies )
{
2015-09-10 09:15:43 -04:00
Emit ( Header , * FBackendHelperUMG : : AdditionalHeaderIncludeForWidget ( Cast < UClass > ( Dependencies - > GetOriginalStruct ( ) ) ) ) ;
2015-09-07 09:39:56 -04:00
2015-09-06 07:59:37 -04:00
TSet < FString > AlreadyIncluded ;
AlreadyIncluded . Add ( CleanName ) ;
auto EmitInner = [ & ] ( FStringOutputDevice & Dst , const TSet < UField * > & Src , const TSet < UField * > & Declarations )
2015-08-17 05:38:30 -04:00
{
2015-09-07 09:39:56 -04:00
auto EngineSourceDir = FPaths : : EngineSourceDir ( ) ;
auto GameSourceDir = FPaths : : GameSourceDir ( ) ;
2015-09-06 07:59:37 -04:00
2015-09-07 09:39:56 -04:00
for ( UField * Field : Src )
2015-08-17 05:38:30 -04:00
{
2015-09-07 09:39:56 -04:00
check ( Field ) ;
const bool bWantedType = Field - > IsA < UBlueprintGeneratedClass > ( ) | | Field - > IsA < UUserDefinedEnum > ( ) | | Field - > IsA < UUserDefinedStruct > ( ) ;
// Wanted no-native type, thet will be converted
if ( bWantedType )
2015-08-17 05:38:30 -04:00
{
2015-09-07 09:39:56 -04:00
const FString Name = Field - > GetName ( ) ;
2015-09-06 07:59:37 -04:00
bool bAlreadyIncluded = false ;
2015-09-07 09:39:56 -04:00
AlreadyIncluded . Add ( Name , & bAlreadyIncluded ) ;
2015-09-06 07:59:37 -04:00
if ( ! bAlreadyIncluded )
{
2015-09-07 09:39:56 -04:00
EmitIncludeHeader ( Dst , * Name , true ) ;
}
}
// headers for native items
else
{
FString PackPath ;
if ( FSourceCodeNavigation : : FindClassHeaderPath ( Field , PackPath ) )
{
if ( ! PackPath . RemoveFromStart ( EngineSourceDir ) )
{
if ( ! PackPath . RemoveFromStart ( GameSourceDir ) )
{
PackPath = FPaths : : GetCleanFilename ( PackPath ) ;
}
}
bool bAlreadyIncluded = false ;
AlreadyIncluded . Add ( PackPath , & bAlreadyIncluded ) ;
if ( ! bAlreadyIncluded )
{
EmitIncludeHeader ( Dst , * PackPath , false ) ;
}
2015-09-06 07:59:37 -04:00
}
2015-08-17 05:38:30 -04:00
}
}
2015-09-07 09:39:56 -04:00
Emit ( Dst , TEXT ( " \n " ) ) ;
2015-09-06 07:59:37 -04:00
2015-09-07 09:39:56 -04:00
for ( auto Type : Declarations )
2015-08-17 05:38:30 -04:00
{
2015-09-07 09:39:56 -04:00
if ( auto ForwardDeclaredType = Cast < UClass > ( Type ) )
{
2015-09-08 06:44:17 -04:00
Emit ( Dst , * FString : : Printf ( TEXT ( " class %s; \n " ) , * FEmitHelper : : GetCppName ( ForwardDeclaredType ) ) ) ;
2015-09-07 09:39:56 -04:00
}
2015-08-17 05:38:30 -04:00
}
2015-08-31 14:52:42 -04:00
2015-09-07 09:39:56 -04:00
Emit ( Dst , TEXT ( " \n " ) ) ;
} ;
2015-08-31 14:52:42 -04:00
2015-09-06 07:59:37 -04:00
EmitInner ( Header , Dependencies - > IncludeInHeader , Dependencies - > DeclareInHeader ) ;
EmitInner ( Body , Dependencies - > IncludeInBody , TSet < UField * > ( ) ) ;
2015-08-17 05:38:30 -04:00
}
2015-09-06 07:59:37 -04:00
2015-08-17 05:38:30 -04:00
Emit ( Header , * FString : : Printf ( TEXT ( " #include \" %s.generated.h \" \n \n " ) , * CleanName ) ) ;
}