1
2
3
4
5
6 #include <sngcpp/symbols/SymbolTable.hpp>
7 #include <sngcpp/symbols/ParameterSymbol.hpp>
8 #include <sngcpp/symbols/VariableSymbol.hpp>
9 #include <sngcpp/symbols/TypedefSymbol.hpp>
10 #include <sngcpp/symbols/ExternalTypeSymbol.hpp>
11 #include <sngcpp/symbols/ClassTemplateSpecializationSymbol.hpp>
12 #include <sngcpp/symbols/IntegerLiteralTypeSymbol.hpp>
13 #include <sngcpp/symbols/LambdaExpressionSymbol.hpp>
14 #include <sngcpp/symbols/GrammarSymbol.hpp>
15 #include <sngcpp/ast/Class.hpp>
16 #include <soulng/util/Unicode.hpp>
17 #include <soulng/util/Sha1.hpp>
18 #include <algorithm>
19
20 namespace sngcpp { namespace symbols {
21
22 using namespace soulng::unicode;
23 using namespace soulng::util;
24
25 SymbolTable::SymbolTable() : globalNs(Span(), U""), container(&globalNs), blockNumber(0), gendocMode(false)
26 {
27 globalNs.SetAccess(Specifier::public_);
28 }
29
30 std::std::unique_ptr<sngxml::dom::Document>SymbolTable::ToDomDocument()
31 {
32 std::unique_ptr<sngxml::dom::Document> symbolTableDoc(new sngxml::dom::Document());
33 symbolTableDoc->AppendChild(std::move(ToDomElement()));
34 return symbolTableDoc;
35 }
36
37 std::std::unique_ptr<sngxml::dom::Element>SymbolTable::ToDomElement()
38 {
39 std::unique_ptr<sngxml::dom::Element> symbolTableElement(new sngxml::dom::Element(U"symbolTable"));
40 std::unique_ptr<sngxml::dom::Element> globalNsElement = globalNs.ToDomElement();
41 symbolTableElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(globalNsElement.release()));
42 std::unique_ptr<sngxml::dom::Element> typesElement = CreateTypesElement();
43 if (typesElement)
44 {
45 symbolTableElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(typesElement.release()));
46 }
47 return symbolTableElement;
48 }
49
50 std::std::unique_ptr<sngxml::dom::Element>SymbolTable::CreateTypesElement()
51 {
52 std::unique_ptr<sngxml::dom::Element> typesElement;
53 if (!types.empty())
54 {
55 typesElement.reset(new sngxml::dom::Element(U"types"));
56 std::vector<TypeSymbol*> typeSymbols;
57 for (const std::std::unique_ptr<TypeSymbol>&type : types)
58 {
59 typeSymbols.push_back(type.get());
60 }
61 std::sort(typeSymbols.begin(), typeSymbols.end(), ByName());
62 for (TypeSymbol* typeSymbol : typeSymbols)
63 {
64 std::unique_ptr<sngxml::dom::Element> typeElement = typeSymbol->ToDomElement();
65 typesElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(typeElement.release()));
66 }
67 }
68 return typesElement;
69 }
70
71 void SymbolTable::BeginContainer(ContainerSymbol* container_)
72 {
73 containerStack.push(container);
74 container = container_;
75 }
76
77 void SymbolTable::EndContainer()
78 {
79 container = containerStack.top();
80 containerStack.pop();
81 }
82
83 int SymbolTable::BeginNameSequence(const std::std::vector<std::std::pair<std::u32string, int>>&nameSequence)
84 {
85 int result = 0;
86 int n = nameSequence.size();
87 for (int i = 0; i < n - 1; ++i)
88 {
89 if (nameSequence[i].first.empty())
90 {
91 BeginContainer(&globalNs);
92 ++result;
93 }
94 else
95 {
96 Symbol* symbol = container->GetContainerScope()->Lookup(nameSequence[i].first);
97 if (symbol)
98 {
99 if (symbol->IsClassGroupSymbol())
100 {
101 ClassGroupSymbol* classGroup = static_cast<ClassGroupSymbol*>(symbol);
102 ClassTypeSymbol* cls = classGroup->GetClass(nameSequence[i].second);
103 if (cls)
104 {
105 BeginContainer(cls);
106 ++result;
107 }
108 }
109 else if (symbol->IsContainerSymbol())
110 {
111 ContainerSymbol* containerSymbol = static_cast<ContainerSymbol*>(symbol);
112 BeginContainer(containerSymbol);
113 ++result;
114 }
115 }
116 }
117 }
118 return result;
119 }
120
121 void SymbolTable::EndNameSequence(int n)
122 {
123 for (int i = 0; i < n; ++i)
124 {
125 EndContainer();
126 }
127 }
128
129 void SymbolTable::BeginNamespace(const std::u32string& namespaceName, const std::u32string& projectName)
130 {
131 if (namespaceName.empty())
132 {
133 BeginContainer(&globalNs);
134 }
135 else
136 {
137 Symbol* symbol = container->GetContainerScope()->Lookup(namespaceName);
138 if (symbol)
139 {
140 if (symbol->IsNamespaceSymbol())
141 {
142 NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(symbol);
143 if (!projectName.empty())
144 {
145 ns->AddProject(projectName);
146 }
147 BeginContainer(ns);
148 }
149 else
150 {
151 throw std::runtime_error(ToUtf8(namespaceName) + " does not denote a namespace");
152 }
153 }
154 else
155 {
156 std::unique_ptr<NamespaceSymbol> newNs(new NamespaceSymbol(Span(), namespaceName));
157 newNs->SetAccess(Specifier::public_);
158 NamespaceSymbol* ns = newNs.get();
159 if (!projectName.empty())
160 {
161 ns->AddProject(projectName);
162 }
163 container->AddMember(std::move(newNs));
164 BeginContainer(ns);
165 }
166 }
167 }
168
169 void SymbolTable::EndNamespace()
170 {
171 EndContainer();
172 }
173
174 void SymbolTable::BeginClass(ClassNode* classNode, const std::u32string& className, std::std::vector<std::std::unique_ptr<TypeSymbol>>&templateParameters, conststd::u32string&projectName)
175 {
176 ClassTypeSymbol* classType = new ClassTypeSymbol(classNode->GetSpan(), className, classNode->GetClassKey());
177 classType->SetProjectName(projectName);
178 MapNode(classNode, classType);
179 for (std::std::unique_ptr<TypeSymbol>&templateParameter : templateParameters)
180 {
181 classType->AddTemplateParameter(std::move(templateParameter));
182 }
183 BeginContainer(classType);
184 }
185
186 void SymbolTable::EndClass(const std::u32string& projectName)
187 {
188 ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(container);
189 EndContainer();
190 container->AddMember(std::unique_ptr<Symbol>(classType));
191 if (container->IsNamespaceSymbol())
192 {
193 if (container->Name() == U"")
194 {
195 NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(container);
196 ns->AddProject(projectName);
197 }
198 }
199 }
200
201 void SymbolTable::BeginLambdaExpression(LambdaExpressionNode* lambdaExpressionNode)
202 {
203 LambdaExpressionSymbol* lambdaExpression = new LambdaExpressionSymbol(lambdaExpressionNode->GetSpan());
204 MapNode(lambdaExpressionNode, lambdaExpression);
205 BeginContainer(lambdaExpression);
206 }
207
208 void SymbolTable::EndLambdaExpression()
209 {
210 LambdaExpressionSymbol* lambdaExpression = static_cast<LambdaExpressionSymbol*>(container);
211 EndContainer();
212 container->AddMember(std::unique_ptr<Symbol>(lambdaExpression));
213 }
214
215 void SymbolTable::BeginGrammar(const Span& span, const std::u32string& grammarName, const std::u32string& projectName)
216 {
217 GrammarSymbol* grammar = new GrammarSymbol(span, grammarName);
218 grammar->SetProjectName(projectName);
219 BeginContainer(grammar);
220 }
221
222 void SymbolTable::EndGrammar(const std::u32string& projectName)
223 {
224 GrammarSymbol* grammar = static_cast<GrammarSymbol*>(container);
225 EndContainer();
226 container->AddMember(std::unique_ptr<Symbol>(grammar));
227 if (container->IsNamespaceSymbol() && container->Name() == U"")
228 {
229 NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(container);
230 ns->AddProject(projectName);
231 }
232 }
233
234 RuleSymbol* SymbolTable::AddRule(const Span& span, const std::u32string& ruleName)
235 {
236 RuleSymbol* rule = new RuleSymbol(span, ruleName);
237 container->AddMember(std::unique_ptr<Symbol>(rule));
238 return rule;
239 }
240
241 void SymbolTable::BeginEnumType(EnumTypeNode* enumTypeNode, const std::u32string& enumTypeName, const std::u32string& projectName)
242 {
243 EnumTypeSymbol* enumType = new EnumTypeSymbol(enumTypeNode->GetSpan(), enumTypeName, enumTypeNode->GetEnumKey());
244 enumType->SetProjectName(projectName);
245 MapNode(enumTypeNode, enumType);
246 BeginContainer(enumType);
247 }
248
249 void SymbolTable::EndEnumType(const std::u32string& projectName)
250 {
251 EnumTypeSymbol* enumType = static_cast<EnumTypeSymbol*>(container);
252 EndContainer();
253 container->AddMember(std::unique_ptr<Symbol>(enumType));
254 if (container->IsNamespaceSymbol() && container->Name() == U"")
255 {
256 NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(container);
257 ns->AddProject(projectName);
258 }
259 }
260
261 void SymbolTable::AddEnumerator(EnumeratorNode* enumeratorNode, const std::u32string& enumeratorName, const std::u32string& enumeratorValue)
262 {
263 EnumeratorSymbol* enumeratorSymbol = new EnumeratorSymbol(enumeratorNode->GetSpan(), enumeratorName, enumeratorValue);
264 MapNode(enumeratorNode, enumeratorSymbol);
265 container->AddMember(std::unique_ptr<Symbol>(enumeratorSymbol));
266 }
267
268 void SymbolTable::BeginFunction(FunctionDeclaratorNode* functionDeclaratorNode, const std::u32string& groupName, const std::u32string& functionName,
269 std::std::vector<std::std::unique_ptr<TypeSymbol>>&templateParameters, Specifierspecifiers, conststd::u32string&projectName)
270 {
271 if (container->IsClassTypeSymbol() && groupName == U"destructor")
272 {
273 DestructorSymbol* destructorSymbol = new DestructorSymbol(functionDeclaratorNode->GetSpan(), groupName, specifiers);
274 destructorSymbol->SetProjectName(projectName);
275 MapNode(functionDeclaratorNode, destructorSymbol);
276 BeginContainer(destructorSymbol);
277 }
278 else if (container->IsClassTypeSymbol() && groupName == container->Name())
279 {
280 ConstructorSymbol* constructorSymbol = new ConstructorSymbol(functionDeclaratorNode->GetSpan(), groupName, specifiers);
281 constructorSymbol->SetProjectName(projectName);
282 MapNode(functionDeclaratorNode, constructorSymbol);
283 BeginContainer(constructorSymbol);
284 for (std::std::unique_ptr<TypeSymbol>&templateParameter : templateParameters)
285 {
286 constructorSymbol->AddTemplateParameter(std::move(templateParameter));
287 }
288 }
289 else
290 {
291 FunctionSymbol* functionSymbol = new FunctionSymbol(functionDeclaratorNode->GetSpan(), groupName, functionName, specifiers);
292 functionSymbol->SetProjectName(projectName);
293 MapNode(functionDeclaratorNode, functionSymbol);
294 BeginContainer(functionSymbol);
295 for (std::std::unique_ptr<TypeSymbol>&templateParameter : templateParameters)
296 {
297 functionSymbol->AddTemplateParameter(std::move(templateParameter));
298 }
299 }
300 }
301
302 void SymbolTable::EndFunction(const std::u32string& projectName)
303 {
304 FunctionSymbol* functionSymbol = static_cast<FunctionSymbol*>(container);
305 EndContainer();
306 container->AddMember(std::unique_ptr<Symbol>(functionSymbol));
307 if (container->IsNamespaceSymbol() && container->Name() == U"")
308 {
309 NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(container);
310 ns->AddProject(projectName);
311 }
312 }
313
314 void SymbolTable::BeginFunctionDeclaration(FunctionDeclaratorNode* functionDeclaratorNode, const std::u32string& groupName, const std::u32string& functionName,
315 std::std::vector<std::std::unique_ptr<TypeSymbol>>&templateParameters, Specifierspecifiers, conststd::u32string&projectName)
316 {
317 if (container->IsClassTypeSymbol() && groupName == container->Name())
318 {
319 ConstructorDeclarationSymbol* constructorDeclarationSymbol = new ConstructorDeclarationSymbol(functionDeclaratorNode->GetSpan(), groupName, specifiers);
320 constructorDeclarationSymbol->SetProjectName(projectName);
321 MapNode(functionDeclaratorNode, constructorDeclarationSymbol);
322 BeginContainer(constructorDeclarationSymbol);
323 for (std::std::unique_ptr<TypeSymbol>&templateParameter : templateParameters)
324 {
325 constructorDeclarationSymbol->AddTemplateParameter(std::move(templateParameter));
326 }
327 }
328 else
329 {
330 FunctionDeclarationSymbol* functionDeclarationSymbol = new FunctionDeclarationSymbol(functionDeclaratorNode->GetSpan(), groupName, functionName, specifiers);
331 functionDeclarationSymbol->SetProjectName(projectName);
332 MapNode(functionDeclaratorNode, functionDeclarationSymbol);
333 BeginContainer(functionDeclarationSymbol);
334 for (std::std::unique_ptr<TypeSymbol>&templateParameter : templateParameters)
335 {
336 functionDeclarationSymbol->AddTemplateParameter(std::move(templateParameter));
337 }
338 }
339 }
340
341 void SymbolTable::EndFunctionDeclaration()
342 {
343 FunctionDeclarationSymbol* functionDeclarationSymbol = static_cast<FunctionDeclarationSymbol*>(container);
344 EndContainer();
345 container->AddMember(std::unique_ptr<Symbol>(functionDeclarationSymbol));
346 }
347
348 void SymbolTable::AddParameter(ParameterNode* parameterNode, const std::u32string& parameterName)
349 {
350 ParameterSymbol* parameterSymbol = new ParameterSymbol(parameterNode->GetSpan(), parameterName);
351 parameterSymbol->SetAccess(Specifier::public_);
352 MapNode(parameterNode, parameterSymbol);
353 container->AddMember(std::unique_ptr<Symbol>(parameterSymbol));
354 }
355
356 void SymbolTable::BeginDeclarationBlock(Node* blockNode)
357 {
358 DeclarationBlockSymbol* declarationBlock = new DeclarationBlockSymbol(blockNode->GetSpan(), U"block" + ToUtf32(std::to_string(blockNumber++)));
359 declarationBlock->SetAccess(Specifier::public_);
360 MapNode(blockNode, declarationBlock);
361 BeginContainer(declarationBlock);
362 }
363
364 void SymbolTable::EndDeclarationBlock()
365 {
366 DeclarationBlockSymbol* declarationBlock = static_cast<DeclarationBlockSymbol*>(container);
367 EndContainer();
368 container->AddMember(std::unique_ptr<Symbol>(declarationBlock));
369 }
370
371 void SymbolTable::AddTypedef(TypedefNode* node, const std::u32string& typedefName, const std::u32string& projectName)
372 {
373 TypedefSymbol* typedefSymbol = new TypedefSymbol(node->GetSpan(), typedefName);
374 typedefSymbol->SetProjectName(projectName);
375 MapNode(node, typedefSymbol);
376 container->AddMember(std::unique_ptr<Symbol>(typedefSymbol));
377 if (container->IsNamespaceSymbol() && container->Name() == U"")
378 {
379 NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(container);
380 ns->AddProject(projectName);
381 }
382 }
383
384 void SymbolTable::AddVariable(Node* node, const std::u32string& variableName, const std::u32string& projectName)
385 {
386 Symbol* symbol = container->GetContainerScope()->Lookup(variableName);
387 if (symbol)
388 {
389 MapNode(node, symbol);
390 }
391 else
392 {
393 VariableSymbol* variableSymbol = new VariableSymbol(node->GetSpan(), variableName);
394 variableSymbol->SetProjectName(projectName);
395 MapNode(node, variableSymbol);
396 container->AddMember(std::unique_ptr<Symbol>(variableSymbol));
397 if (container->IsNamespaceSymbol() && container->Name() == U"")
398 {
399 NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(container);
400 ns->AddProject(projectName);
401 }
402 }
403 }
404
405 void SymbolTable::MapNode(Node* node, Symbol* symbol)
406 {
407 nodeSymbolMap[node] = symbol;
408 }
409
410 void SymbolTable::MapIdNodeSequence(Node* node, const std::std::vector<IdentifierNode*>&idNodeSequence)
411 {
412 idNodeSequenceMap[node] = idNodeSequence;
413 }
414
415 void SymbolTable::MapTemplateIdToTemplateArgumentNodes(TemplateIdNode* templateIdNode, const std::std::vector<Node*>&templateArgumentNodes)
416 {
417 templateIdTemplateArgumentNodeMap[templateIdNode] = templateArgumentNodes;
418 }
419
420 Symbol* SymbolTable::GetSymbolNothrow(Node* node)
421 {
422 auto it = nodeSymbolMap.find(node);
423 if (it != nodeSymbolMap.cend())
424 {
425 return it->second;
426 }
427 else
428 {
429 return nullptr;
430 }
431 }
432
433 Symbol* SymbolTable::GetSymbol(Node* node)
434 {
435 Symbol* symbol = GetSymbolNothrow(node);
436 if (symbol)
437 {
438 return symbol;
439 }
440 else
441 {
442 throw std::runtime_error("symbol for node not found");
443 }
444 }
445
446 const std::std::vector<IdentifierNode*>&SymbolTable::GetIdNodeSequence(Node*node)
447 {
448 auto it = idNodeSequenceMap.find(node);
449 if (it != idNodeSequenceMap.cend())
450 {
451 return it->second;
452 }
453 else
454 {
455 throw std::runtime_error("id node sequence for node not found");
456 }
457 }
458
459 const std::std::vector<Node*>&SymbolTable::GetTemplateArgumentNodes(TemplateIdNode*templateIdNode)
460 {
461 auto it = templateIdTemplateArgumentNodeMap.find(templateIdNode);
462 if (it != templateIdTemplateArgumentNodeMap.cend())
463 {
464 return it->second;
465 }
466 else
467 {
468 throw std::runtime_error("template argument nodes for template id node not found");
469 }
470 }
471
472 ContainerScope* SymbolTable::GetContainerScope()
473 {
474 return container->GetContainerScope();
475 }
476
477 TypeSymbol* SymbolTable::GetBoolType()
478 {
479 SimpleTypeNode boolNode(soulng::lexer::Span(), std::vector<SimpleTypeSpecifier>(1, SimpleTypeSpecifier::bool_));
480 return MakeSimpleTypeSymbol(boolNode);
481 }
482
483 TypeSymbol* SymbolTable::GetLongType()
484 {
485 SimpleTypeNode longNode(soulng::lexer::Span(), std::vector<SimpleTypeSpecifier>(1, SimpleTypeSpecifier::long_));
486 return MakeSimpleTypeSymbol(longNode);
487 }
488
489 TypeSymbol* SymbolTable::GetDoubleType()
490 {
491 SimpleTypeNode doubleNode(soulng::lexer::Span(), std::vector<SimpleTypeSpecifier>(1, SimpleTypeSpecifier::double_));
492 return MakeSimpleTypeSymbol(doubleNode);
493 }
494
495 TypeSymbol* SymbolTable::GetIntType()
496 {
497 SimpleTypeNode intNode(soulng::lexer::Span(), std::vector<SimpleTypeSpecifier>(1, SimpleTypeSpecifier::int_));
498 return MakeSimpleTypeSymbol(intNode);
499 }
500
501 TypeSymbol* SymbolTable::GetUIntType()
502 {
503 std::vector<SimpleTypeSpecifier> specifiers;
504 specifiers.push_back(SimpleTypeSpecifier::unsigned_);
505 specifiers.push_back(SimpleTypeSpecifier::int_);
506 SimpleTypeNode uintNode(soulng::lexer::Span(), specifiers);
507 return MakeSimpleTypeSymbol(uintNode);
508 }
509
510 TypeSymbol* SymbolTable::GetCharType()
511 {
512 SimpleTypeNode charNode(soulng::lexer::Span(), std::vector<SimpleTypeSpecifier>(1, SimpleTypeSpecifier::char_));
513 return MakeSimpleTypeSymbol(charNode);
514 }
515
516 TypeSymbol* SymbolTable::GetChar16Type()
517 {
518 SimpleTypeNode char16Node(soulng::lexer::Span(), std::vector<SimpleTypeSpecifier>(1, SimpleTypeSpecifier::char16));
519 return MakeSimpleTypeSymbol(char16Node);
520 }
521
522 TypeSymbol* SymbolTable::GetChar32Type()
523 {
524 SimpleTypeNode char32Node(soulng::lexer::Span(), std::vector<SimpleTypeSpecifier>(1, SimpleTypeSpecifier::char32));
525 return MakeSimpleTypeSymbol(char32Node);
526 }
527
528 TypeSymbol* SymbolTable::GetVoidType()
529 {
530 SimpleTypeNode voidNode(soulng::lexer::Span(), std::vector<SimpleTypeSpecifier>(1, SimpleTypeSpecifier::void_));
531 return MakeSimpleTypeSymbol(voidNode);
532 }
533
534 TypeSymbol* SymbolTable::MakeSimpleTypeSymbol(SimpleTypeNode& simpleTypeNode)
535 {
536 std::u32string id = simpleTypeNode.Id();
537 auto it = idTypeMap.find(id);
538 if (it != idTypeMap.cend())
539 {
540 return it->second;
541 }
542 else
543 {
544 SimpleTypeSymbol* simpleTypeSymbol = new SimpleTypeSymbol(simpleTypeNode.GetSpan(), simpleTypeNode.Str(), id, simpleTypeNode.Flags());
545 simpleTypeSymbol->SetAccess(Specifier::public_);
546 idTypeMap[id] = simpleTypeSymbol;
547 types.push_back(std::unique_ptr<TypeSymbol>(simpleTypeSymbol));
548 return simpleTypeSymbol;
549 }
550 }
551
552 TypeSymbol* SymbolTable::MakeElaborateClassTypeSymbol(ClassKey classKey, TypeSymbol* classType)
553 {
554 std::u32string idMaterial = ToString(classKey) + classType->IdStr();
555 std::u32string id = U"type_" + ToUtf32(GetSha1MessageDigest(ToUtf8(idMaterial)));
556 auto it = idTypeMap.find(id);
557 if (it != idTypeMap.cend())
558 {
559 return it->second;
560 }
561 else
562 {
563 ElaborateClassTypeSymbol* elaborateClassTypeSymbol = new ElaborateClassTypeSymbol(classType->GetSpan(), classKey, classType, id);
564 idTypeMap[id] = elaborateClassTypeSymbol;
565 types.push_back(std::unique_ptr<TypeSymbol>(elaborateClassTypeSymbol));
566 return elaborateClassTypeSymbol;
567 }
568 }
569
570 TypeSymbol* SymbolTable::MakeDerivedTypeSymbol(std::std::vector<Derivation>&derivations, TypeSymbol*baseType)
571 {
572 if (baseType->IsDerivedTypeSymbol())
573 {
574 DerivedTypeSymbol* derivedType = static_cast<DerivedTypeSymbol*>(baseType);
575 derivations = UnifyDerivations(derivations, derivedType->Derivations());
576 baseType = derivedType->BaseType();
577 }
578 std::u32string id = MakeDerivedTypeId(derivations, baseType);
579 auto it = idTypeMap.find(id);
580 if (it != idTypeMap.cend())
581 {
582 return it->second;
583 }
584 else
585 {
586 DerivedTypeSymbol* derivedTypeSymbol = new DerivedTypeSymbol(baseType->GetSpan(), MakeDerivedTypeName(derivations, baseType), baseType, derivations, id);
587 derivedTypeSymbol->SetAccess(Specifier::public_);
588 idTypeMap[id] = derivedTypeSymbol;
589 types.push_back(std::unique_ptr<TypeSymbol>(derivedTypeSymbol));
590 return derivedTypeSymbol;
591 }
592 }
593
594 TypeSymbol* SymbolTable::MakeExternalTypeSymbol(const Span& span, const std::u32string& name, ClassKey classKey)
595 {
596 std::u32string id = U"type_";
597 if (classKey != ClassKey::none)
598 {
599 id.append(ToString(classKey));
600 id.append(1, '_');
601 }
602 id.append(ToUtf32(GetSha1MessageDigest(ToUtf8(name))));
603 auto it = idTypeMap.find(id);
604 if (it != idTypeMap.cend())
605 {
606 return it->second;
607 }
608 else
609 {
610 ExternalTypeSymbol* externalTypeSymbol = new ExternalTypeSymbol(span, name, classKey, id);
611 externalTypeSymbol->SetAccess(Specifier::public_);
612 idTypeMap[id] = externalTypeSymbol;
613 types.push_back(std::unique_ptr<TypeSymbol>(externalTypeSymbol));
614 return externalTypeSymbol;
615 }
616 }
617
618 TypeSymbol* SymbolTable::MakeClassGroupTypeSymbol(ClassGroupSymbol* classGroup)
619 {
620 std::u32string id = classGroup->Id();
621 auto it = idTypeMap.find(id);
622 if (it != idTypeMap.cend())
623 {
624 return it->second;
625 }
626 else
627 {
628 ClassGroupTypeSymbol* classGroupTypeSymbol = new ClassGroupTypeSymbol(classGroup);
629 idTypeMap[id] = classGroupTypeSymbol;
630 types.push_back(std::unique_ptr<TypeSymbol>(classGroupTypeSymbol));
631 return classGroupTypeSymbol;
632 }
633 }
634
635 TypeSymbol* SymbolTable::MakeClassTemplateSpecializationSymbol(const Span& span, TypeSymbol* primaryClassTemplate, const std::std::vector<TypeSymbol*>&templateArguments)
636 {
637 std::u32string id = MakeClassTemplateSpecializationId(primaryClassTemplate, templateArguments);
638 auto it = idTypeMap.find(id);
639 if (it != idTypeMap.cend())
640 {
641 return it->second;
642 }
643 else
644 {
645 ClassTemplateSpecializationSymbol* classTemplateSpecializationSymbol = new ClassTemplateSpecializationSymbol(span,
646 MakeClassTemplateSpecializationName(primaryClassTemplate, templateArguments), primaryClassTemplate, templateArguments, id);
647 classTemplateSpecializationSymbol->SetAccess(Specifier::public_);
648 idTypeMap[id] = classTemplateSpecializationSymbol;
649 types.push_back(std::unique_ptr<TypeSymbol>(classTemplateSpecializationSymbol));
650 if (gendocMode)
651 {
652 if (primaryClassTemplate->IsExternalTypeSymbol() && primaryClassTemplate->Name() == U"std::unique_ptr")
653 {
654 BeginContainer(classTemplateSpecializationSymbol);
655 FunctionDeclaratorNode* functionDeclaratorNode = new FunctionDeclaratorNode(span, new IdDeclaratorNode(span, new IdentifierNode(span, U"get")), nullptr, Specifier());
656 ownedNodes.push_back(std::unique_ptr<Node>(functionDeclaratorNode));
657 std::vector<std::std::unique_ptr<TypeSymbol>>templateParameters;
658 BeginFunction(functionDeclaratorNode, U"get", U"get()", templateParameters, Specifier(), std::u32string());
659 FunctionSymbol* functionSymbol = static_cast<FunctionSymbol*>(container);
660 std::vector<Derivation> derivations;
661 derivations.push_back(Derivation::ptr);
662 functionSymbol->SetReturnType(MakeDerivedTypeSymbol(derivations, templateArguments.front()));
663 EndFunction(std::u32string());
664 EndContainer();
665 }
666 }
667 return classTemplateSpecializationSymbol;
668 }
669 }
670
671 TypeSymbol* SymbolTable::MakeIntegerLiteralTypeSymbol(const Span& span, const std::u32string& valueName)
672 {
673 std::u32string id = U"literal_" + valueName;
674 auto it = idTypeMap.find(id);
675 if (it != idTypeMap.cend())
676 {
677 return it->second;
678 }
679 else
680 {
681 IntegerLiteralTypeSymbol* integerLiteralTypeSymbol = new IntegerLiteralTypeSymbol(span, valueName, id);
682 integerLiteralTypeSymbol->SetAccess(Specifier::public_);
683 idTypeMap[id] = integerLiteralTypeSymbol;
684 types.push_back(std::unique_ptr<TypeSymbol>(integerLiteralTypeSymbol));
685 return integerLiteralTypeSymbol;
686 }
687 }
688
689 } }