analctor.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 676 行 · 第 1/2 页
C
676 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "plusplus.h"
#include "cgfront.h"
#include "fnovload.h"
#include "calldiag.h"
#include "memmgr.h"
#include "errdefns.h"
#include "rtfuncod.h"
#include "ring.h"
#include "defarg.h"
#include "class.h"
#include "objmodel.h"
static CNV_DIAG diagCtor = // diagnosis for CTORing
{ ERR_CTOR_IMPOSSIBLE
, ERR_CTOR_AMBIGUOUS
, ERR_CALL_WATCOM
, ERR_CALL_WATCOM
, ERR_CALL_WATCOM
};
static boolean ctorDefineDefault( // DEFINE A DEFAULT CTOR
TYPE cl_type, // - class type
arg_list *alist ) // - arguments list
{
boolean retn; // - TRUE ==> a default CTOR was defined
SYMBOL ctor; // - CTOR symbol
if( ! TypeDefined( cl_type ) ) {
retn = FALSE;
} else if( alist->num_args == 0 ) {
if( CNV_OK == ClassDefaultCtorDefine( cl_type, &ctor ) ) {
retn = TRUE;
} else {
retn = FALSE;
}
} else if( alist->num_args == 1 ) {
if( NULL == ClassAddDefaultCopy( cl_type->u.c.scope ) ) {
retn = FALSE;
} else {
retn = TRUE;
}
} else {
retn = FALSE;
}
return retn;
}
static boolean ctorDefineDefaultCnv( // DEFINE A DEFAULT CTOR FOR CONVERSION
TYPE cl_type, // - class type
arg_list *alist ) // - arguments list
{
boolean retn; // - TRUE ==> a default CTOR was defined
if( ! TypeDefined( cl_type ) ) {
retn = FALSE;
} else if( alist->num_args == 0 ) {
retn = ctorDefineDefault( cl_type, alist );
} else if( alist->num_args == 1 ) {
cl_type = ClassTypeForType( cl_type );
if( NULL == ClassAddDefaultCopy( cl_type->u.c.scope ) ) {
retn = FALSE;
} else {
retn = TRUE;
}
} else {
retn = FALSE;
}
return retn;
}
static SEARCH_RESULT *ctorResult( // GET SEARCH RESULT FOR A CTOR
SCOPE access, // - accessing derived class
TOKEN_LOCN *locn, // - location for any access errors
TYPE cl_type ) // - a class type
{
SCOPE class_scope;
char *ctor_name;
SEARCH_RESULT *result;
ctor_name = CppConstructorName();
class_scope = TypeScope( cl_type );
if( access != NULL ) {
result = ScopeFindBaseMember( class_scope, ctor_name );
} else {
result = ScopeContainsMember( class_scope, ctor_name );
}
if( locn != NULL && result != NULL ) {
ScopeResultErrLocn( result, locn );
}
return result;
}
FNOV_LIST *CtorFindList( TYPE src, TYPE tgt )
/*******************************************/
// Find all ctors from src to tgt type
// - does not rank or resolve list
{
arg_list alist; // argument list for ctor
SEARCH_RESULT *search_result; // search result
SYMBOL sym; // current symbol in list
FNOV_LIST *list; // FNOV_LIST of ctors found
search_result = ctorResult( NULL, NULL, tgt );
if( search_result == NULL ) {
InitArgList( &alist );
alist.num_args = 1;
alist.type_list[0] = src;
if( ctorDefineDefaultCnv( tgt, &alist ) ) {
search_result = ctorResult( NULL, NULL, tgt );
}
}
list = NULL;
if( search_result != NULL ) {
RingIterBeg( search_result->sym_name->name_syms, sym ) {
BuildUdcList( &list, sym );
} RingIterEnd( sym )
ScopeFreeResult( search_result );
}
return list;
}
static FNOV_RESULT ctorExplicitDiag(// FIND CONSTRUCTOR FOR ARGUMENT LIST
SCOPE access, // - accessing derived class
TYPE cl_type, // - type for class
arg_list *alist, // - arguments list
PTREE *ptlist, // - parse tree nodes for arguments
TOKEN_LOCN *locn, // - location for access errors
SYMBOL *ctor, // - ctor symbol
FNOV_DIAG *fnov_diag ) // - diagnosis information
{
SEARCH_RESULT *result; // - search result
FNOV_RESULT ovret; // - overload resolution result
cl_type = ClassTypeForType( cl_type );
result = ctorResult( access, locn, cl_type );
if( result == NULL ) {
ovret = FNOV_NO_MATCH;
} else {
ovret = FuncOverloadedLimitDiag( ctor
, result
, result->sym_name->name_syms
, alist
, ptlist
, FNC_RANKING_CTORS
, fnov_diag );
if( ovret == FNOV_NONAMBIGUOUS ) {
if( ScopeCheckSymbol( result, *ctor ) ) {
ovret = FNOV_ERR;
}
}
ScopeFreeResult( result );
}
return ovret;
}
static CNV_RETN ctorFindDiag( // FIND CONSTRUCTOR FOR ARGUMENT LIST
SCOPE access, // - accessing derived class
TYPE cl_type, // - type for class
arg_list *alist, // - arguments list
PTREE *ptlist, // - parse tree nodes for arguments
TOKEN_LOCN *locn, // - location for access errors
SYMBOL *ctor, // - addr( constructor symbol )
FNOV_DIAG *fnov_diag ) // - diagnosis information
{
CNV_RETN retn; // - return: TRUE ==> no error
FNOV_RESULT ovret; // - overload resolution result
*ctor = NULL;
ovret = ctorExplicitDiag( access, cl_type, alist, ptlist, locn, ctor, fnov_diag );
if( ovret == FNOV_NO_MATCH ) {
if( ctorDefineDefault( cl_type, alist ) ) {
FnovInitDiag( fnov_diag );
ovret = ctorExplicitDiag( access, cl_type, alist, ptlist, locn, ctor, fnov_diag );
}
}
switch( ovret ) {
case FNOV_ERR :
retn = CNV_ERR;
break;
case FNOV_NONAMBIGUOUS :
retn = CNV_OK;
break;
case FNOV_NO_MATCH :
retn = CNV_IMPOSSIBLE;
break;
case FNOV_AMBIGUOUS :
retn = CNV_AMBIGUOUS;
break;
DbgDefault( "unexpected return from ctorExplicitDiag" );
}
return retn;
}
CNV_RETN CtorFind( // FIND CONSTRUCTOR FOR ARGUMENT LIST
SCOPE access, // - accessing derived class
TYPE cl_type, // - type for class
arg_list *alist, // - arguments list
PTREE *ptlist, // - parse tree nodes for arguments
TOKEN_LOCN *locn, // - location for access errors
SYMBOL *ctor ) // - addr( constructor symbol )
{
return ctorFindDiag( access, cl_type, alist, ptlist, locn, ctor, NULL );
}
static CNV_RETN single_arg( // VERIFY ZERO OR SINGLE CTOR ARGUMENT
PTREE *a_expr ) // - addr( expression )
{
CNV_RETN retn; // - return: CNV_...
PTREE expr; // - expression
expr = *a_expr;
if( expr == NULL ) {
retn = CNV_OK;
} else if( expr->u.subtree[0] != NULL ) {
PTreeErrorExpr( expr, ERR_ONE_CTOR_ARG_REQD );
retn = CNV_ERR;
} else {
*a_expr = expr->u.subtree[1];
PTreeFree( expr );
retn = CNV_OK;
}
return retn;
}
static CNV_RETN analyseCtorClassDiag( // ANALYSE A CLASS CTOR
TYPE type, // - class type for CTOR
SCOPE access, // - scope ctor is accessed from
SYMBOL *ctor, // - ctor to be filled in
PTREE initial, // - initialization arguments (modified)
PTREE *expr, // - expression, when CTOR'd
FNOV_DIAG *fnov_diag ) // - diagnosis information
{
PTREE node; // - converted arguments
arg_list *alist; // - arguments structure
PTREE *ptlist; // - parse tree for arguments
unsigned count; // - # arg.s
CNV_RETN retn; // - return: CNV_...
TOKEN_LOCN err_locn; // - location for access errors
TEMP_PT_LIST default_list; // - default PTREE list
TEMP_ARG_LIST default_args; // - default arg_list
node = NodeReverseArgs( &count, initial );
alist = ArgListTempAlloc( &default_args, count );
ptlist = PtListAlloc( default_list, count );
NodeBuildArgList( alist, ptlist, node, count );
PTreeExtractLocn( initial, &err_locn );
retn = ctorFindDiag( access
, type
, alist
, ptlist
, &err_locn
, ctor
, fnov_diag );
switch( retn ) {
case CNV_OK :
node = NodeConvertCallArgList( node
, count
, (*ctor)->sym_type
, &node );
if( ( node != NULL ) && ( node->op == PT_ERROR ) ) {
retn = CNV_ERR;
}
break;
case CNV_AMBIGUOUS :
if( fnov_diag != NULL ) {
CallDiagAmbiguous( node, ERR_CTOR_AMBIGUOUS, fnov_diag );
retn = CNV_ERR;
}
break;
case CNV_IMPOSSIBLE :
if( count == 1
&& StructType( initial->type ) == type
&& OMR_CLASS_VAL == ObjModelArgument( type ) ) {
retn = CNV_OK;
break;
}
// drops thru
default :
if( initial != NULL ) {
ConversionTypesSet( NodeType( initial ), type );
}
break;
}
*expr = node;
ArgListTempFree( alist, count );
PtListFree( ptlist, count );
return retn;
}
// Determine if the "type" is properly CTORable:
//
// - for a scalar type, this is so if there is no initializer list
// - for a scalar type, this is so if there is one argument which can be
// converted to the argument type
// - for a class, this is so if there is no initializer list
// - the ctor SYMBOL might be found
// - for a class, this is so if there exists a CTOR to match the initializer
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?