1 /**
2  * This file is part of DCD, a development tool for the D programming language.
3  * Copyright (C) 2014 Brian Schott
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 module dsymbol.semantic;
20 
21 import dsymbol.symbol;
22 import dparse.ast;
23 import dparse.lexer;
24 import containers.unrolledlist;
25 import dsymbol.type_lookup;
26 import stdx.allocator.mallocator : Mallocator;
27 
28 enum ResolutionFlags : ubyte
29 {
30 	inheritance = 0b0000_0001,
31 	type = 0b0000_0010,
32 	mixinTemplates = 0b0000_0100,
33 }
34 
35 /**
36  * Intermediate form between DSymbol and the AST classes. Stores enough
37  * information to resolve things like base classes and alias this.
38  */
39 struct SemanticSymbol
40 {
41 public:
42 
43 	/// Disable default construction.
44 	@disable this();
45 	/// Disable copy construction
46 	@disable this(this);
47 
48 	/**
49 	 * Params:
50 	 *    name = the name
51 	 */
52 	this(DSymbol* acSymbol)
53 	{
54 		this.acSymbol = acSymbol;
55 	}
56 
57 	~this()
58 	{
59 		import stdx.allocator.mallocator : Mallocator;
60 		import stdx.allocator : dispose;
61 
62 		foreach (child; children[])
63 			typeid(SemanticSymbol).destroy(child);
64 		foreach (lookup; typeLookups[])
65 			Mallocator.instance.dispose(lookup);
66 	}
67 
68 	/**
69 	 * Adds a child to the children field and updates the acSymbol's parts field
70 	 */
71 	void addChild(SemanticSymbol* child, bool owns)
72 	{
73 		children.insert(child);
74 		acSymbol.addChild(child.acSymbol, owns);
75 	}
76 
77 	/// Information used to do type resolution, inheritance, mixins, and alias this
78 	UnrolledList!(TypeLookup*, Mallocator, false) typeLookups;
79 
80 	/// Child symbols
81 	UnrolledList!(SemanticSymbol*, Mallocator, false) children;
82 
83 	/// Autocompletion symbol
84 	DSymbol* acSymbol;
85 
86 	/// Parent symbol
87 	SemanticSymbol* parent;
88 
89 	/// Protection level for this symobol
90 	IdType protection;
91 }
92 
93 /**
94  * Type of the _argptr variable
95  */
96 Type argptrType;
97 
98 /**
99  * Type of _arguments
100  */
101 Type argumentsType;
102 
103 static this()
104 {
105 	import dsymbol.string_interning : internString;
106 	import stdx.allocator : make;
107 	import stdx.allocator.mallocator : Mallocator;
108 
109 	// TODO: Replace these with DSymbols
110 
111 	// _argptr has type void*
112 	argptrType = make!Type(Mallocator.instance);
113 	argptrType.type2 = make!Type2(Mallocator.instance);
114 	argptrType.type2.builtinType = tok!"void";
115 	TypeSuffix argptrTypeSuffix = make!TypeSuffix(Mallocator.instance);
116 	argptrTypeSuffix.star = Token(tok!"*");
117 	argptrType.typeSuffixes = cast(TypeSuffix[]) Mallocator.instance.allocate(TypeSuffix.sizeof);
118 	argptrType.typeSuffixes[0] = argptrTypeSuffix;
119 
120 	// _arguments has type TypeInfo[]
121 	argumentsType = make!Type(Mallocator.instance);
122 	argumentsType.type2 = make!Type2(Mallocator.instance);
123 	argumentsType.type2.typeIdentifierPart = make!TypeIdentifierPart(Mallocator.instance);
124 	IdentifierOrTemplateInstance i = make!IdentifierOrTemplateInstance(Mallocator.instance);
125 	i.identifier.text = internString("TypeInfo");
126 	i.identifier.type = tok!"identifier";
127 	argumentsType.type2.typeIdentifierPart.identifierOrTemplateInstance = i;
128 	TypeSuffix argumentsTypeSuffix = make!TypeSuffix(Mallocator.instance);
129 	argumentsTypeSuffix.array = true;
130 	argumentsType.typeSuffixes = cast(TypeSuffix[]) Mallocator.instance.allocate(TypeSuffix.sizeof);
131 	argumentsType.typeSuffixes[0] = argumentsTypeSuffix;
132 }