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 import stdx.allocator.gc_allocator : GCAllocator; 28 29 enum ResolutionFlags : ubyte 30 { 31 inheritance = 0b0000_0001, 32 type = 0b0000_0010, 33 mixinTemplates = 0b0000_0100, 34 } 35 36 alias TypeLookupsAllocator = GCAllocator; // NOTE using `Mallocator` here fails when analysing Phobos as: `munmap_chunk(): invalid pointer` 37 alias TypeLookups = UnrolledList!(TypeLookup*, TypeLookupsAllocator); 38 39 /** 40 * Intermediate form between DSymbol and the AST classes. Stores enough 41 * information to resolve things like base classes and alias this. 42 */ 43 struct SemanticSymbol 44 { 45 public: 46 47 /// Disable default construction. 48 @disable this(); 49 /// Disable copy construction 50 @disable this(this); 51 52 /** 53 * Params: 54 * name = the name 55 */ 56 this(DSymbol* acSymbol) 57 { 58 this.acSymbol = acSymbol; 59 } 60 61 ~this() 62 { 63 import stdx.allocator : dispose; 64 65 foreach (child; children[]) 66 typeid(SemanticSymbol).destroy(child); 67 foreach (lookup; typeLookups[]) 68 TypeLookupsAllocator.instance.dispose(lookup); 69 } 70 71 /** 72 * Adds a child to the children field and updates the acSymbol's parts field 73 */ 74 void addChild(SemanticSymbol* child, bool owns) 75 { 76 children.insert(child); 77 acSymbol.addChild(child.acSymbol, owns); 78 } 79 80 /// Information used to do type resolution, inheritance, mixins, and alias this 81 TypeLookups typeLookups; 82 83 /// Child symbols 84 UnrolledList!(SemanticSymbol*, GCAllocator) children; // NOTE using `Mallocator` here fails when analysing Phobos 85 86 /// Autocompletion symbol 87 DSymbol* acSymbol; 88 89 /// Parent symbol 90 SemanticSymbol* parent; 91 92 /// Protection level for this symobol 93 deprecated("Use acSymbol.protection instead") ref inout(IdType) protection() @property inout 94 { 95 return acSymbol.protection; 96 } 97 } 98 99 /** 100 * Type of the _argptr variable 101 */ 102 Type argptrType; 103 104 /** 105 * Type of _arguments 106 */ 107 Type argumentsType; 108 109 alias GlobalsAllocator = Mallocator; 110 111 static this() 112 { 113 import dsymbol.string_interning : internString; 114 import stdx.allocator : make; 115 116 // TODO: Replace these with DSymbols 117 118 // _argptr has type void* 119 argptrType = GlobalsAllocator.instance.make!Type(); 120 argptrType.type2 = GlobalsAllocator.instance.make!Type2(); 121 argptrType.type2.builtinType = tok!"void"; 122 TypeSuffix argptrTypeSuffix = GlobalsAllocator.instance.make!TypeSuffix(); 123 argptrTypeSuffix.star = Token(tok!"*"); 124 argptrType.typeSuffixes = cast(TypeSuffix[]) GlobalsAllocator.instance.allocate(TypeSuffix.sizeof); 125 argptrType.typeSuffixes[0] = argptrTypeSuffix; 126 127 // _arguments has type TypeInfo[] 128 argumentsType = GlobalsAllocator.instance.make!Type(); 129 argumentsType.type2 = GlobalsAllocator.instance.make!Type2(); 130 argumentsType.type2.typeIdentifierPart = GlobalsAllocator.instance.make!TypeIdentifierPart(); 131 IdentifierOrTemplateInstance i = GlobalsAllocator.instance.make!IdentifierOrTemplateInstance(); 132 i.identifier.text = internString("TypeInfo"); 133 i.identifier.type = tok!"identifier"; 134 argumentsType.type2.typeIdentifierPart.identifierOrTemplateInstance = i; 135 TypeSuffix argumentsTypeSuffix = GlobalsAllocator.instance.make!TypeSuffix(); 136 argumentsTypeSuffix.array = true; 137 argumentsType.typeSuffixes = cast(TypeSuffix[]) GlobalsAllocator.instance.allocate(TypeSuffix.sizeof); 138 argumentsType.typeSuffixes[0] = argumentsTypeSuffix; 139 } 140 141 static ~this() 142 { 143 import stdx.allocator : dispose; 144 GlobalsAllocator.instance.dispose(argumentsType.typeSuffixes[0]); 145 GlobalsAllocator.instance.dispose(argumentsType.type2.typeIdentifierPart.identifierOrTemplateInstance); 146 GlobalsAllocator.instance.dispose(argumentsType.type2.typeIdentifierPart); 147 GlobalsAllocator.instance.dispose(argumentsType.type2); 148 GlobalsAllocator.instance.dispose(argptrType.typeSuffixes[0]); 149 GlobalsAllocator.instance.dispose(argptrType.type2); 150 151 GlobalsAllocator.instance.deallocate(argumentsType.typeSuffixes); 152 GlobalsAllocator.instance.deallocate(argptrType.typeSuffixes); 153 154 GlobalsAllocator.instance.dispose(argumentsType); 155 GlobalsAllocator.instance.dispose(argptrType); 156 }