-
-
Notifications
You must be signed in to change notification settings - Fork 255
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Debuginfo: Fix type for associative arrays and make -gc emit C++-imit…
…ating names (#2869)
- Loading branch information
Showing
5 changed files
with
377 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
Oops, something went wrong.