Skip to content

Commit

Permalink
Debuginfo: Fix type for associative arrays and make -gc emit C++-imit…
Browse files Browse the repository at this point in the history
…ating names (#2869)
  • Loading branch information
void-995 authored and kinke committed Nov 11, 2018
1 parent 9537185 commit 540f19c
Show file tree
Hide file tree
Showing 5 changed files with 377 additions and 62 deletions.
233 changes: 233 additions & 0 deletions gen/cpp-imitating-naming.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
//===-- gen/cpp-imitating-naming.d --------------------------------*- D -*-===//
//
// LDC – the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//

module gen.cpp_imitating_naming;

private string dTemplateToCPlusPlus(const(string) name) @safe pure
{
import std.string : indexOf, indexOfAny;

ptrdiff_t start = 0;
ptrdiff_t index = name.indexOf('!');

string result;

if (index != -1)
{
result ~= name[start .. index];
result ~= '<';

start = index + 1;

if (name[index + 1] == '(')
{
start++;
index++;

size_t enclosedParentheses = 0;

while (true)
{
switch (name[index])
{
case '(':
enclosedParentheses++;
break;
case ')':
enclosedParentheses--;
break;
default:
break;
}

if (enclosedParentheses == 0)
break;

if (index == cast(ptrdiff_t) name.length - 1)
break;

index++;
}

if (name[index] != ')')
index++;
}
else
{
index = name.indexOfAny(" ,.:<>()[]", start);

if (index == -1)
index = name.length;
}

result ~= name[start .. index];
result ~= '>';

start = index;

if (start != name.length && name[start] == ')')
start++;
}

if (start != name.length)
result ~= name[start .. $];

return result;
}

private string dArrayToCPlusPlus(const(string) name) @safe pure
{
import std.ascii : isDigit;
import std.string : indexOf, lastIndexOfAny, replace;

ptrdiff_t index = name.indexOf('[');

while (index != -1 && name[index + 1].isDigit)
index = name.indexOf('[', index + 1);

string result = name;

if (index > 0)
{
index--;

if (name[index] == '>' || name[index] == ')')
{
size_t enclosedParentheses = 0;
size_t enclosedChevrons = 0;

while (true)
{
switch (name[index])
{
case '(':
enclosedParentheses++;
break;
case ')':
enclosedParentheses--;
break;
case '>':
enclosedChevrons++;
break;
case '<':
enclosedChevrons--;
break;
default:
break;
}

if (enclosedParentheses == 0 && enclosedChevrons == 0)
break;

if (index == 0)
break;

index--;
}
}

if (index > 0)
{
index = name.lastIndexOfAny(" ,<(", index - 1);
index = index != -1 ? index + 1 : 0;
}

ptrdiff_t bracketsStart = name.indexOf('[', index);
ptrdiff_t bracketsIndex = bracketsStart;

size_t enclosedSquareBrackets = 0;

while (true)
{
switch (name[bracketsIndex])
{
case '[':
enclosedSquareBrackets++;
break;
case ']':
enclosedSquareBrackets--;
break;
default:
break;
}

if (enclosedSquareBrackets == 0)
break;

if (bracketsIndex == cast(ptrdiff_t) name.length - 1)
break;

bracketsIndex++;
}

bracketsIndex++;

immutable string search = name[index .. bracketsIndex];
immutable string value = name[index .. bracketsStart];

if (name[bracketsIndex - 1] == ']')
bracketsIndex--;

bracketsStart++;

immutable string key = name[bracketsStart .. bracketsIndex];

if (key.length == 0)
{
immutable string replaceString = "slice<" ~ value ~ ">";
result = name.replace(search, replaceString);
}
else
{
immutable string pairKeyValue = key ~ ", " ~ value;
immutable string replaceString = "associative_array<" ~ pairKeyValue ~ ">";
result = name.replace(search, replaceString);
}
}

return result;
}

private string convertDToCPlusPlus(alias identifierModifier)(const(string) name) @safe pure
{
string result = name;
string previousResult;

do
{
previousResult = result;
result = identifierModifier(result);
}
while (result != previousResult);

return result;
}

///
string convertDIdentifierToCPlusPlus(const(string) name) @safe pure
{
import std.string : replace;

string result = name.replace(".", "::");

result = result.convertDToCPlusPlus!dTemplateToCPlusPlus;
result = result.convertDToCPlusPlus!dArrayToCPlusPlus;

return result;
}

///
extern (C++, ldc)
const(char)* convertDIdentifierToCPlusPlus(const(char)* name, size_t nameLength) @trusted pure
{
import std.exception : assumeUnique;
import std.string : toStringz;

return name[0 .. nameLength].assumeUnique.convertDIdentifierToCPlusPlus.toStringz;
}
Loading

0 comments on commit 540f19c

Please sign in to comment.