Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

450 lines
11 KiB

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
header.cxx
Abstract:
Generates header file.
Notes:
History:
----------------------------------------------------------------------------*/
/****************************************************************************
* include files
***************************************************************************/
#include "becls.hxx"
#pragma hdrstop
#include "buffer.hxx"
/****************************************************************************
* local definitions
***************************************************************************/
/****************************************************************************
* externs
***************************************************************************/
extern CMD_ARG * pCommand;
CG_STATUS
CG_OBJECT_INTERFACE::GenHeader(
CCB * pCCB )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Generate interface header file.
Arguments:
pCCB - a pointer to the code generation control block.
Return Value:
CG_OK if all is well, error otherwise.
Notes: The interface header file has the following structure:
Forward declaration
TypeDeclarations
#if defined(__cplusplus) && !defined(CINTERFACE)
CPlusPlusLanguageBinding
#else
CLanguageBinding
#endif
----------------------------------------------------------------------------*/
{
node_interface * pInterface = (node_interface *) GetType();
ISTREAM * pStream = pCCB->GetStream();
char * pName = pInterface->GetSymName();
if (!pInterface->PrintedDef())
{
//Initialize the CCB for this interface.
InitializeCCB(pCCB);
// put out the interface guards
pStream->Write("\n#ifndef __");
pStream->Write( pName );
pStream->Write( "_INTERFACE_DEFINED__\n" );
pStream->Write( "#define __");
pStream->Write( pName );
pStream->Write( "_INTERFACE_DEFINED__\n" );
// Print out the declarations of the types
pStream->NewLine();
pInterface->PrintType( PRT_INTERFACE | PRT_OMIT_PROTOTYPE, pStream, 0);
Out_IID(pCCB);
// print out the vtable/class definitions
pStream->NewLine();
pStream->Write("#if defined(__cplusplus) && !defined(CINTERFACE)");
pStream->IndentInc();
CPlusPlusLanguageBinding(pCCB);
pStream->IndentDec();
pStream->NewLine();
pStream->Write("#else \t/* C style interface */");
pStream->IndentInc();
CLanguageBinding(pCCB);
pStream->IndentDec();
// print out the C Macros
CLanguageMacros( pCCB );
pStream->NewLine( 2 );
pStream->Write("#endif \t/* C style interface */");
pStream->NewLine( 2 );
// print out the prototypes for the proxy and stub routines
ProxyPrototypes(pCCB);
pStream->NewLine();
// put out the trailing interface guard
pStream->Write( "\n#endif \t/* __");
pStream->Write( pName );
pStream->Write( "_INTERFACE_DEFINED__ */\n" );
pStream->NewLine();
pInterface->SetPrintedDef();
}
return CG_OK;
}
CG_STATUS
CG_OBJECT_INTERFACE::CPlusPlusLanguageBinding(CCB *pCCB)
{
ISTREAM *pStream = pCCB->GetStream();
char *pName;
pStream->NewLine();
pName = GetType()->GetSymName();
MIDL_ASSERT (pName != (char *)0);
pStream->NewLine();
// put out the declspec for the uuid
if ( pCommand->GetMSCVer() >= 1100 )
{
pStream->Write("MIDL_INTERFACE(\"");
pStream->Write(GuidStrs.str1);
pStream->Write('-');
pStream->Write(GuidStrs.str2);
pStream->Write('-');
pStream->Write(GuidStrs.str3);
pStream->Write('-');
pStream->Write(GuidStrs.str4);
pStream->Write('-');
pStream->Write(GuidStrs.str5);
pStream->Write("\")");
}
else
{
pStream->Write(" struct ");
}
pStream->NewLine();
pStream->Write(pName);
CG_OBJECT_INTERFACE* pBaseCG = (CG_OBJECT_INTERFACE*) GetBaseInterfaceCG();
//Check if this interface was derived from a base interface.
if(pBaseCG)
{
pStream->Write(" : public ");
pStream->Write(pBaseCG->GetType()->GetSymName());
}
pStream->NewLine();
pStream->Write('{');
pStream->NewLine();
pStream->Write("public:");
pStream->IndentInc();
// REVIEW: BEGIN/END_INTERFACE were only need for PowerMac. Maybe we
// should stop emitting them? -- MikeW 26-Jul-99
if( ! pBaseCG )
{
pStream->NewLine();
pStream->Write("BEGIN_INTERFACE");
}
PrintMemberFunctions( pStream, TRUE );
if( ! pBaseCG )
{
pStream->NewLine();
pStream->Write("END_INTERFACE");
}
pStream->IndentDec();
pStream->NewLine();
pStream->Write("};");
pStream->NewLine();
return CG_OK;
}
STATUS_T
CG_OBJECT_INTERFACE::PrintMemberFunctions(
ISTREAM * pStream,
BOOL fAbstract)
/*++
Routine Description:
This routine prints C++ function prototypes for the interface member functions.
We assume that all of the procedure nodes are pure virtual functions.
Arguments:
pStream - Specifies the output stream.
fAbstract - Specifies whether the methods should be abstract ( = 0 ).
--*/
{
CG_OBJECT_PROC * pProc = (CG_OBJECT_PROC *) GetChild();
MIDL_ASSERT (GetType()->GetSymName() != (char *)0);
while( pProc )
{
if ( !pProc->SupressHeader() )
{
node_skl* pN = pProc->GetType();
//Assume this is a pure virtual function.
// use the call_as form, if any
pStream->NewLine();
pStream->Write("virtual ");
pN->PrintType( PRT_PROTOTYPE | PRT_CALL_AS | PRT_FORCE_CALL_CONV | PRT_CPP_PROTOTYPE,
pStream,
0 );
if ( fAbstract)
pStream->Write(" = 0;");
else
pStream->Write(";");
pStream->NewLine();
}
pProc = (CG_OBJECT_PROC *) pProc->GetSibling();
}
return STATUS_OK;
}
CG_STATUS
CG_OBJECT_PROC::PrintVtableEntry(
CCB * pCCB)
{
ISTREAM * pStream = pCCB->GetStream();
node_id * pTempID;
char * pName = GetType()->GetSymName();
if (SupressHeader())
{
return CG_OK;
}
if ( GetCallAsName() )
{
pName = GetCallAsName();
}
pTempID = MakePtrIDNode( pName, GetType() );
pStream->NewLine();
pTempID->PrintType( PRT_PROC_PTR_PROTOTYPE | PRT_THIS_POINTER | PRT_CALL_AS | PRT_FORCE_CALL_CONV,
pStream,
NULL ,
pCCB->GetInterfaceCG()->GetType() );
return CG_OK;
}
CG_STATUS
CG_OBJECT_INTERFACE::CLanguageBinding(CCB *pCCB)
{
#ifndef DISABLE_C_OUTPUT
ISTREAM * pStream = pCCB->GetStream();
char * pName = pCCB->GetInterfaceName();
pStream->NewLine( 2 );
pStream->Write("typedef struct ");
pStream->Write(pName);
pStream->Write("Vtbl");
pStream->NewLine();
pStream->Write('{');
pStream->IndentInc();
pStream->NewLine();
// REVIEW: BEGIN/END_INTERFACE were only need for PowerMac. Maybe we
// should stop emitting them? -- MikeW 26-Jul-99
pStream->Write("BEGIN_INTERFACE");
pStream->NewLine();
// Now the regular entries.
PrintVtableEntries( pCCB );
// This is a match for the other macro.
pStream->NewLine();
pStream->Write("END_INTERFACE");
pStream->IndentDec();
pStream->NewLine();
pStream->Write("} ");
pStream->Write(pName);
pStream->Write("Vtbl;");
pStream->NewLine( 2 );
pStream->Write("interface ");
pStream->Write(pName);
pStream->NewLine();
pStream->Write('{');
pStream->IndentInc();
pStream->NewLine();
pStream->Write("CONST_VTBL struct ");
pStream->Write(pName);
pStream->Write("Vtbl *lpVtbl;");
pStream->IndentDec();
pStream->NewLine();
pStream->Write("};");
pStream->NewLine( 2 );
#endif
return CG_OK;
}
CG_STATUS
CG_OBJECT_INTERFACE::ProxyPrototypes(CCB *pCCB)
/*++
Routine Description:
This routine generates function prototypes for the interface proxy.
For each procedure, we generate a proxy prototype and a
stub prototype.
Arguments:
pCCB - a pointer to the code generation control block.
Return Value:
CG_OK if all is well, error otherwise.
--*/
{
ISTREAM * pStream = pCCB->GetStream();
CG_OBJECT_PROC * pProcCG = 0;
char * pszName;
CG_ITERATOR I;
pszName = GetType()->GetSymName();
MIDL_ASSERT (pszName != (char *)0);
GetMembers( I );
while( ITERATOR_GETNEXT( I, pProcCG ) )
{
if (!pProcCG->SupressHeader())
{
//print proxy function prototype
pStream->NewLine();
pProcCG->Out_ProxyFunctionPrototype(pCCB,
PRT_TRAILING_SEMI );
//print stub function prototype
pStream->NewLine();
pProcCG->Out_StubFunctionPrototype( pCCB );
pStream->Write(';');
pStream->NewLine();
}
}
pStream->NewLine();
return CG_OK;
}
CG_STATUS
CG_OBJECT_INTERFACE::PrintCMacros(CCB *pCCB)
/*++
Routine Description:
This routine generates C macros for an interface
Arguments:
pCCB - a pointer to the code generation control block.
Return Value:
CG_OK if all is well, error otherwise.
--*/
{
#ifndef DISABLE_C_OUTPUT
ISTREAM * pStream = pCCB->GetStream();
CG_OBJECT_PROC * pProcCG = 0;
CG_ITERATOR I;
// print inherited methods ( with our current ccb intf name )
if ( GetBaseInterfaceCG() )
((CG_OBJECT_INTERFACE *)GetBaseInterfaceCG())->PrintCMacros( pCCB );
GetMembers( I );
while( ITERATOR_GETNEXT( I, pProcCG ) )
{
//print proxy function prototype
pStream->NewLine();
pProcCG->GenCMacro(pCCB);
}
pStream->NewLine();
#endif
return CG_OK;
}
CG_STATUS
CG_OBJECT_INTERFACE::CLanguageMacros(CCB *pCCB)
{
#ifndef DISABLE_C_OUTPUT
ISTREAM * pStream = pCCB->GetStream();
pStream->NewLine( 2 );
pStream->Write("#ifdef COBJMACROS");
pStream->NewLine();
PrintCMacros( pCCB );
pStream->NewLine();
pStream->Write("#endif /* COBJMACROS */");
pStream->NewLine();
#endif
return CG_OK;
}