1 /**
2    Deals with D-specific translation, such as avoiding keywords
3  */
4 module dpp.translation.dlang;
5 
6 import dpp.from;
7 
8 
9 string maybeRename(in from!"clang".Cursor cursor,
10                    in from!"dpp.runtime.context".Context context)
11     @safe pure nothrow
12 {
13     return nameClashes(cursor, context) ? rename(cursor.spelling, context) : cursor.spelling;
14 }
15 
16 string maybePragma(in from!"clang".Cursor cursor,
17                    in from!"dpp.runtime.context".Context context)
18     @safe pure nothrow
19 {
20     import clang: Language;
21     import std.algorithm: startsWith;
22     // FIXME - why are free function operators showing up as Language.C?
23     const isCpp = cursor.language == Language.CPlusPlus || cursor.spelling.startsWith("operator");
24     if(isCpp) return pragmaMangle(cursor.mangling);
25     return nameClashes(cursor, context) ? pragmaMangle(cursor.mangling) : "";
26 }
27 
28 string rename(string spelling,
29               in from!"dpp.runtime.context".Context context)
30     @safe pure nothrow
31 {
32     do
33         spelling ~= "_";
34     while(spelling in context.aggregateDeclarations);
35 
36     return spelling;
37 }
38 
39 string pragmaMangle(in string mangling) @safe pure nothrow {
40     return mangling == "" ? "" : `pragma(mangle, "` ~ mangling ~ `") `;
41 }
42 
43 private bool nameClashes(in from!"clang".Cursor cursor,
44                          in from!"dpp.runtime.context".Context context)
45     @safe pure nothrow
46 {
47     return
48         cursor.spelling.isKeyword ||
49         cursor.spelling in context.aggregateDeclarations;
50 }
51 
52 bool isKeyword(string str) @safe @nogc pure nothrow {
53     switch (str) {
54         default: return false;
55         case "abstract":
56         case "alias":
57         case "align":
58         case "asm":
59         case "assert":
60         case "auto":
61 
62         case "body":
63         case "bool":
64         case "break":
65         case "byte":
66 
67         case "case":
68         case "cast":
69         case "catch":
70         case "cdouble":
71         case "cent":
72         case "cfloat":
73         case "char":
74         case "class":
75         case "const":
76         case "continue":
77         case "creal":
78 
79         case "dchar":
80         case "debug":
81         case "default":
82         case "delegate":
83         case "delete":
84         case "deprecated":
85         case "do":
86         case "double":
87 
88         case "else":
89         case "enum":
90         case "export":
91         case "extern":
92 
93         case "false":
94         case "final":
95         case "finally":
96         case "float":
97         case "for":
98         case "foreach":
99         case "foreach_reverse":
100         case "function":
101 
102         case "goto":
103 
104         case "idouble":
105         case "if":
106         case "ifloat":
107         case "import":
108         case "in":
109         case "inout":
110         case "int":
111         case "interface":
112         case "invariant":
113         case "ireal":
114         case "is":
115 
116         case "lazy":
117         case "long":
118 
119         case "macro":
120         case "mixin":
121         case "module":
122 
123         case "new":
124         case "nothrow":
125         case "null":
126 
127         case "out":
128         case "override":
129 
130         case "package":
131         case "pragma":
132         case "private":
133         case "protected":
134         case "public":
135         case "pure":
136 
137         case "real":
138         case "ref":
139         case "return":
140 
141         case "scope":
142         case "shared":
143         case "short":
144         case "static":
145         case "struct":
146         case "super":
147         case "switch":
148         case "synchronized":
149 
150         case "template":
151         case "this":
152         case "throw":
153         case "true":
154         case "try":
155         case "typedef":
156         case "typeid":
157         case "typeof":
158 
159         case "ubyte":
160         case "ucent":
161         case "uint":
162         case "ulong":
163         case "union":
164         case "unittest":
165         case "ushort":
166 
167         case "version":
168         case "void":
169         case "volatile":
170 
171         case "wchar":
172         case "while":
173         case "with":
174         case "immutable":
175         case "__gshared":
176         case "__thread":
177         case "__traits":
178 
179         case "__EOF__":
180         case "__FILE__":
181         case "__LINE__":
182         case "__DATE__":
183         case "__TIME__":
184         case "__TIMESTAMP__":
185         case "__VENDOR__":
186         case "__VERSION__":
187             return true;
188     }
189 
190     assert(0);
191 }