source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Compiler.cpp@ 693

Last change on this file since 693 was 693, checked in by dai_9181, 16 years ago

#179#180への対応。TypeDefした名前でクラスにアクセスすると、型パラメータ解決エラーが出てしまう不具合を修正。

File size: 12.2 KB
RevLine 
[206]1#include "stdafx.h"
2
[598]3using namespace ActiveBasic::Compiler;
4
[195]5Compiler compiler;
[193]6
[636]7Compiler::Compiler()
8 : isBuildSuccessful( false )
9 , targetModuleType( ActiveBasic::Common::TargetModuleType::Exe )
10 , isDebug( false )
11 , isUnicode( false )
12 , isCore( false )
13 , currentRelationalObjectModuleIndexForSource( 0 )
14{
15 // 生成先のオブジェクトモジュールを登録
16 ObjectModule *pObjectModule = new ObjectModule();
17 staticLibraries.push_back( pObjectModule );
18 SelectObjectModule( pObjectModule );
19
20 namespaceSupporter.RegistAllNamespaceScopesCollection( &GetObjectModule().meta.GetNamespaces() );
21
22 Symbol::RegistNamespaceSupporter( &namespaceSupporter );
23}
24Compiler::~Compiler()
25{
26 BOOST_FOREACH( ObjectModule *pStaticLibrary, staticLibraries )
27 {
28 delete pStaticLibrary;
29 }
30 staticLibraries.clear();
31}
32
33void Compiler::PreStaticLink( const ObjectModules &staticLibraries )
34{
35 BOOST_FOREACH( const ObjectModule *pStaticLibrary, staticLibraries )
36 {
37 // 関連オブジェクトモジュールの名前リスト
38 this->GetObjectModule().relationalObjectModuleNames.push_back( pStaticLibrary->GetName() );
39 }
40}
[270]41void Compiler::StaticLink( ObjectModules &staticLibraries )
42{
43 BOOST_FOREACH( ObjectModule *pStaticLibrary, staticLibraries )
44 {
[636]45 if( &this->GetObjectModule() == pStaticLibrary )
46 {
47 // 自分自身の場合はリンクしない
48 continue;
49 }
50
[270]51 // メタ情報
[637]52 this->GetObjectModule().StaticLink( *pStaticLibrary, this->IsSll() );
[270]53 }
54}
55
[632]56ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToGenericTypeEx( const std::string &typeName, Type &type )
[628]57{
[632]58 // ジェネリッククラスをインスタンス化した型の場合
59 int i = 0;
60 char className[VN_SIZE];
61 GetIdentifierToken( className, typeName.c_str(), i );
[193]62
[632]63 // ジェネリクスクラスを取得
64 const CClass *pGenericClass = this->GetObjectModule().meta.FindClassSupportedTypeDef(
65 LexicalAnalyzer::FullNameToSymbol( className )
66 );
[290]67
[632]68 if( !pGenericClass )
69 {
70 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::NotfoundGenericClass;
71 }
[290]72
[632]73 if( typeName[i] != '<' )
[290]74 {
[632]75 Jenga::Throw( "StringToType内でジェネリクス構文の解析に失敗" );
76 }
[290]77
[632]78 GenericTypes genericTypes;
79 bool isValueType = false;
80 while( true )
81 {
82 i++;
[290]83
[632]84 char typeParameterStr[VN_SIZE];
85 GetIdentifierToken( typeParameterStr, typeName.c_str(), i );
86
87 // 型パラメータの型情報を取得
88 Type typeParameterType;
89 StringToType( typeParameterStr, typeParameterType );
90
91 genericTypes.push_back( GenericType( "(non support)", typeParameterType ) );
92
93 if( typeParameterType.IsValueType() )
[301]94 {
[632]95 // 値型の場合
96 isValueType = true;
[301]97 }
[290]98
[632]99 if( typeName[i] != ',' )
[301]100 {
[632]101 break;
[301]102 }
[632]103 }
[301]104
[632]105 // 基本型をセット
106 type.SetBasicType( DEF_OBJECT );
[290]107
[632]108 if( isValueType )
109 {
110 // 型パラメータに値型が指定された場合
[301]111
[632]112 // 仮型パラメータを実型パラメータに変換
113 Types actualTypes;
114 BOOST_FOREACH( const GenericType &genericType, genericTypes )
115 {
116 actualTypes.push_back( genericType.GetType() );
117 }
[301]118
[632]119 // テンプレートとしてクラスを展開する
120 const CClass *pExpandedClass = LexicalAnalyzer::TemplateExpand( *const_cast<CClass *>(pGenericClass), actualTypes );
[301]121
[632]122 if( pExpandedClass )
123 {
124 // 拡張情報をセット
125 type.SetClassPtr( pExpandedClass );
[301]126 }
[632]127 else
128 {
129 // TODO: 消す
130 goto Generic;
131 }
132 }
133 else
134 {
135Generic:
136 // 型パラメータにクラス型が指定された場合
[301]137
[632]138 // ジェネリック クラスとして利用する
[290]139
140 // 拡張情報をセット
141 type.SetClassPtr( pGenericClass );
142 type.SetActualGenericTypes( genericTypes );
[632]143 }
[290]144
[632]145 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
146}
147ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType Compiler::StringToTypeEx( const std::string &typeName, Type &type, bool isResolveGenerics )
148{
149 type.SetIndex( -1 );
150
151
152 /////////////////////////////////////////////////////////
153 // ☆★☆ ジェネリクスサポート ☆★☆
154
155 if( strstr( typeName.c_str(), "<" ) )
156 {
157 return StringToGenericTypeEx( typeName, type );
[290]158 }
159
160 //
161 /////////////////////////////////////////////////////////
162
163
[193]164 if( typeName[0] == '*' ){
165 if( typeName.size() >= 3
[575]166 && typeName[1] == 1 && ( typeName[2] == ESC_FUNCTION || typeName[2] == ESC_SUB ) )
167 {
168 // 関数ポインタを追加する
169 {
170 DWORD dwProcType = (DWORD)typeName[2];
171 const std::string &paramStr = typeName.substr( 3 );
172
173 Procedure::Kind kind = ( dwProcType == ESC_FUNCTION )
174 ? Procedure::Function
175 : Procedure::Sub;
176
177 ProcPointer *pProcPointer = new ProcPointer( kind );
178
179 //buffer[0]は'('となっている
180 extern int cp;
181 ActiveBasic::Compiler::LexicalAnalyzer::SetParamsAndReturnType( pProcPointer, paramStr.c_str(), false, cp );
182
183 this->GetObjectModule().meta.GetProcPointers().push_back( pProcPointer );
184 }
185
186 //関数ポインタ(*Function)
187 type.SetBasicType( DEF_PTR_PROC );
188 type.SetIndex( this->GetObjectModule().meta.GetProcPointers().size() - 1 );
[628]189 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]190 }
191
[523]192 const std::string &nextTypeName = typeName.substr( 1 );
[193]193
[628]194 ActiveBasic::Compiler::Error::StringToTypeErrorCode::EnumType result = StringToTypeEx( nextTypeName, type, isResolveGenerics );
195 if( result != ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful )
196 {
197 return result;
[193]198 }
199
200 type.PtrLevelUp();
201
[628]202 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]203 }
204
205 {
206 int basicType;
[628]207 if( Type::StringToBasicType( typeName, basicType ) )
208 {
[193]209 // 基本型だったとき
210 type.SetBasicType( basicType );
[628]211 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]212 }
213 }
214
215 // Object型だったとき
[628]216 if( typeName == "Object" )
217 {
[299]218 type.SetType( DEF_OBJECT, this->GetObjectModule().meta.GetClasses().GetObjectClassPtr() );
[628]219 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]220 }
221
222 // String型だったとき
[628]223 if( typeName == "String" )
224 {
[299]225 type.SetType( DEF_OBJECT, this->GetObjectModule().meta.GetClasses().GetStringClassPtr() );
[628]226 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]227 }
228
229
230 ////////////////////
231 // TypeDefされた型
232 ////////////////////
[632]233 const TypeDef *pTypeDef = this->GetObjectModule().meta.GetTypeDefs().Find( LexicalAnalyzer::FullNameToSymbol( typeName ) );
234 if( pTypeDef )
[628]235 {
[632]236 type = pTypeDef->GetBaseType();
237
238 if( type.IsObject() )
239 {
[693]240 if( isResolveGenerics && type.GetClass().IsGeneric() && !type.HasActualGenericType() )
[632]241 {
242 // ジェネリッククラスの場合
243 trace( "型解決されていない" );
244 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::FailedResolveGenericType;
245 }
246 }
247
[628]248 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]249 }
250
251 //クラス
[632]252 const CClass *pobj_c = this->GetObjectModule().meta.FindClassSupportedTypeDef( LexicalAnalyzer::FullNameToSymbol( typeName ) );
[628]253 if(pobj_c)
254 {
[693]255 if( isResolveGenerics && pobj_c->IsGeneric() )
[628]256 {
[693]257 // ジェネリッククラスの場合
258 trace( "型解決されていない" );
259 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::FailedResolveGenericType;
[628]260 }
261
262 if( pobj_c->IsStructure() )
263 {
[193]264 type.SetBasicType( DEF_STRUCT );
265 }
[628]266 else
267 {
[193]268 type.SetBasicType( DEF_OBJECT );
269 }
[290]270 type.SetClassPtr( pobj_c );
[628]271 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[193]272 }
273
[290]274
275 /////////////////////////////////////////////////////////
276 // ☆★☆ ジェネリクスサポート ☆★☆
277
278 // 型パラメータ
[536]279 if( this->IsCompilingClass() )
[290]280 {
281 // クラスに属するメソッドをコンパイルしているとき
[536]282 int formalTypeIndex = this->GetCompilingClass().GetFormalGenericTypeParameterIndex( typeName );
[299]283 if( formalTypeIndex != -1 )
[290]284 {
285 // コンパイル中クラスにおけるジェネリクス用の型パラメータのとき
286 type.SetBasicType( DEF_TYPE_PARAMETER );
[536]287 type.SetClassPtr( &this->GetCompilingClass().GetFormalGenericTypes()[formalTypeIndex].GetType().GetClass() );
[299]288 type.SetFormalTypeName( typeName );
289 type.SetFormalTypeIndex( formalTypeIndex );
[628]290 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful;
[290]291 }
292 }
293
294 //
295 /////////////////////////////////////////////////////////
296
[628]297 return ActiveBasic::Compiler::Error::StringToTypeErrorCode::NotfoundType;
[193]298}
299
[628]300bool Compiler::StringToType( const std::string &typeName, Type &type )
301{
302 return ( StringToTypeEx( typeName, type, false ) == ActiveBasic::Compiler::Error::StringToTypeErrorCode::Successful );
303}
304
[523]305const std::string Compiler::TypeToString( const Type &type )
[193]306{
307 if( PTR_LEVEL( type.GetBasicType() ) ){
308 //ポインタレベルが1以上の場合
309 Type tempType( type );
310 tempType.PtrLevelDown();
311
[523]312 return (std::string)"*" + TypeToString( tempType );
[193]313 }
[683]314 else if( type.IsObject() || type.IsStruct() )
315 {
[193]316 //オブジェクトまたは構造体
317
[683]318 if( !( type.GetIndex() == 0 || type.GetIndex() == -1 ) )
319 {
320 std::string result = type.GetClass().GetName();
[193]321 if( type.GetClass().GetNamespaceScopes().size() >= 1 )
322 {
[683]323 result = type.GetClass().GetNamespaceScopes().ToString()
324 + "."
325 + result;
[193]326 }
[683]327
328 if( type.GetClass().IsExpanded() )
329 {
330 // テンプレート展開済みのクラスの場合
331 std::string actualGenericTypesName;
332 BOOST_FOREACH( const Type &typeParameter, type.GetClass().expandedClassActualTypeParameters )
333 {
334 if( actualGenericTypesName.size() )
335 {
336 actualGenericTypesName += ",";
337 }
338 actualGenericTypesName += typeParameter.ToString();
339 }
340
341 result += "<" + actualGenericTypesName + ">";
342 }
343
344 return result;
[193]345 }
346 }
347 else if( type.IsProcPtr() ){
348 if( type.GetIndex() == 0 || type.GetIndex() == -1 ){
349 return "VoidPtr";
350 }
351 else{
[299]352 if( this->GetObjectModule().meta.GetProcPointers()[type.GetIndex()]->ReturnType().IsNull() ){
[193]353 return "*Sub";
354 }
355 return "*Function";
356 }
357 }
358 else{
359 // 基本型
360 const char *lpszTypeName = Type::BasicTypeToCharPtr( type );
361 if( lpszTypeName )
362 {
[523]363 return (const std::string)lpszTypeName;
[193]364 }
365 }
366
[465]367 compiler.errorMessenger.Output(1, NULL, cp);
[193]368
[523]369 return (std::string)"(null)";
[193]370}
[533]371
[672]372int Compiler::SizeOf( const Type &type )
373{
374 Type tempType( type );
375 if( this->IsCompilingClass() )
376 {
377 if( this->pCompilingClass->IsExpanded() && tempType.IsTypeParameter() )
378 {
379 // 現在コンパイル中のクラスがテンプレート展開済みのクラスで、
380 // 尚且つターゲットとなる型が型パラメータだったとき
381
382 // テンプレート展開情報を用いて型解決を行う
383 this->pCompilingClass->ResolveExpandedClassActualTypeParameter( tempType );
384 }
385 }
386 return tempType.GetSize();
387}
388
[536]389void Compiler::ClearCompilingUserProcAndClass()
390{
391 this->pCompilingUserProc = NULL;
392 this->pCompilingClass = NULL;
393}
394
395void Compiler::SetCompilingClass( const CClass *pClass )
396{
397 this->pCompilingClass = pClass;
398}
399
[537]400void Compiler::SetCompilingUserProc( const UserProc *pUserProc )
[533]401{
[536]402 this->pCompilingUserProc = pUserProc;
403
404 this->SetCompilingClass( pUserProc->GetParentClassPtr() );
[537]405}
[533]406
[537]407void Compiler::StartGlobalAreaCompile()
408{
409 ClearCompilingUserProcAndClass();
410}
411
412void Compiler::StartProcedureCompile( const UserProc *pUserProc )
413{
414 //コンパイル中の関数
415 this->SetCompilingUserProc( pUserProc );
416
[540]417 if( pUserProc->HasParentClass() )
418 {
419 // クラスの使用チェック
420 pUserProc->GetParentClass().Using();
421 }
[533]422
423 // コンパイル中の関数が属する名前空間
424 this->GetNamespaceSupporter().SetLivingNamespaceScopes( pUserProc->GetNamespaceScopes() );
425
426 // コンパイル中の関数でImportsされている名前空間
427 this->GetNamespaceSupporter().SetImportedNamespaces( pUserProc->GetImportedNamespaces() );
428
429 // コード生成対象を選択
430 this->codeGenerator.Select( (const_cast<UserProc *>(pUserProc))->GetNativeCode() );
431}
432void Compiler::FinishProcedureCompile()
433{
[536]434 this->pCompilingUserProc = NULL;
435 this->pCompilingClass = NULL;
[533]436}
[536]437
438bool Compiler::IsGlobalAreaCompiling()
439{
[641]440 if( pCompilingUserProc == NULL )
441 {
442 return true;
443 }
444 return ( pCompilingUserProc->GetName() == this->globalAreaProcName );
[536]445}
[537]446bool Compiler::IsLocalAreaCompiling()
447{
[641]448 return !IsGlobalAreaCompiling();
[537]449}
[536]450const UserProc &Compiler::GetCompilingUserProc()
451{
[641]452 if( pCompilingUserProc == NULL )
[536]453 {
[641]454 _ASSERTE( false );
455 throw;
[536]456 }
[641]457 return *pCompilingUserProc;
[536]458}
459
460bool Compiler::IsCompilingClass()
461{
462 return ( pCompilingClass != NULL );
463}
464const CClass &Compiler::GetCompilingClass()
465{
466 if( this->IsCompilingClass() )
467 {
468 return *pCompilingClass;
469 }
470
471 throw;
472}
Note: See TracBrowser for help on using the repository browser.