| Index: src/IceGlobalContext.cpp
|
| diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
|
| index 11de0130984823800f0332d2dd0f698786b4970a..ab63b4cda6bd878b4bcc89fd0eae600fa92fcbb9 100644
|
| --- a/src/IceGlobalContext.cpp
|
| +++ b/src/IceGlobalContext.cpp
|
| @@ -17,6 +17,7 @@
|
| #include "IceCfg.h"
|
| #include "IceGlobalContext.h"
|
| #include "IceOperand.h"
|
| +#include "IceTargetLowering.h"
|
|
|
| namespace Ice {
|
|
|
| @@ -75,18 +76,17 @@ public:
|
|
|
| GlobalContext::GlobalContext(llvm::raw_ostream *OsDump,
|
| llvm::raw_ostream *OsEmit, VerboseMask Mask,
|
| + TargetArch Arch, OptLevel Opt,
|
| IceString TestPrefix)
|
| : StrDump(OsDump), StrEmit(OsEmit), VMask(Mask),
|
| - ConstPool(new ConstantPool()), TestPrefix(TestPrefix) {}
|
| + ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt),
|
| + TestPrefix(TestPrefix), HasEmittedFirstMethod(false) {}
|
|
|
| // In this context, name mangling means to rewrite a symbol using a
|
| // given prefix. For a C++ symbol, nest the original symbol inside
|
| // the "prefix" namespace. For other symbols, just prepend the
|
| // prefix.
|
| IceString GlobalContext::mangleName(const IceString &Name) const {
|
| - // TODO: Add explicit tests (beyond the implicit tests in the linker
|
| - // that come from the cross tests).
|
| - //
|
| // An already-nested name like foo::bar() gets pushed down one
|
| // level, making it equivalent to Prefix::foo::bar().
|
| // _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz
|
| @@ -100,9 +100,9 @@ IceString GlobalContext::mangleName(const IceString &Name) const {
|
|
|
| unsigned PrefixLength = getTestPrefix().length();
|
| char NameBase[1 + Name.length()];
|
| - const size_t BufLen = 30 + Name.length() + getTestPrefix().length();
|
| + const size_t BufLen = 30 + Name.length() + PrefixLength;
|
| char NewName[BufLen];
|
| - uint32_t BaseLength = 0;
|
| + uint32_t BaseLength = 0; // using uint32_t due to sscanf format string
|
|
|
| int ItemsParsed = sscanf(Name.c_str(), "_ZN%s", NameBase);
|
| if (ItemsParsed == 1) {
|
| @@ -118,15 +118,28 @@ IceString GlobalContext::mangleName(const IceString &Name) const {
|
| }
|
|
|
| ItemsParsed = sscanf(Name.c_str(), "_Z%u%s", &BaseLength, NameBase);
|
| - if (ItemsParsed == 2) {
|
| - // Transform _Z3barxyz ==> ZN6Prefix3barExyz
|
| - // ^^^^^^^^ ^
|
| + if (ItemsParsed == 2 && BaseLength <= strlen(NameBase)) {
|
| + // Transform _Z3barxyz ==> _ZN6Prefix3barExyz
|
| + // ^^^^^^^^ ^
|
| // (splice in "N6Prefix", and insert "E" after "3bar")
|
| + // But an "I" after the identifier indicates a template argument
|
| + // list terminated with "E"; insert the new "E" before/after the
|
| + // old "E". E.g.:
|
| + // Transform _Z3barIabcExyz ==> _ZN6Prefix3barIabcEExyz
|
| + // ^^^^^^^^ ^
|
| + // (splice in "N6Prefix", and insert "E" after "3barIabcE")
|
| char OrigName[Name.length()];
|
| char OrigSuffix[Name.length()];
|
| - strncpy(OrigName, NameBase, BaseLength);
|
| - OrigName[BaseLength] = '\0';
|
| - strcpy(OrigSuffix, NameBase + BaseLength);
|
| + uint32_t ActualBaseLength = BaseLength;
|
| + if (NameBase[ActualBaseLength] == 'I') {
|
| + ++ActualBaseLength;
|
| + while (NameBase[ActualBaseLength] != 'E' &&
|
| + NameBase[ActualBaseLength] != '\0')
|
| + ++ActualBaseLength;
|
| + }
|
| + strncpy(OrigName, NameBase, ActualBaseLength);
|
| + OrigName[ActualBaseLength] = '\0';
|
| + strcpy(OrigSuffix, NameBase + ActualBaseLength);
|
| snprintf(NewName, BufLen, "_ZN%u%s%u%sE%s", PrefixLength,
|
| getTestPrefix().c_str(), BaseLength, OrigName, OrigSuffix);
|
| return NewName;
|
|
|