Я пытаюсь написать проход LLVM, который манипулирует строками.
После итерации всех объектов GlobalVariable и выбора строк я получаю строковые данные, выполняю манипуляции, создаю новую GlobalVariable и затем использую replaceAllUsesWith()
для замены старого новым.Звучит достаточно просто ...
Однако я получаю ошибку подтверждения, сообщающую, что замена должна быть того же типа.Я не изменил длину строки, поэтому я не знаю, почему тип будет другим.Ниже приведена сокращенная версия кода.
for (Module::global_iterator gi = M.global_begin(), ge = M.global_end(); gi != ge; gi++) {
GlobalVariable *gv = *gi;
ConstantDataSequential *cdata = dyn_cast<ConstantDataSequential>(gv->getInitializer());
std::string orig = "";
if (cdata->isString() {
orig = cdata->getAsString();
} else if (cdata->isCString() {
orig = cdata->getAsCString();
} else {
continue;
}
// string returned has the same length, but different contents
std::string modified = manipulateString(orig);
std::ostringstream oss;
oss << gv->getName() << "Modified" ;
Constant *cMod = ConstantDataArray::getString(M.getContext(), modified, true);
GlobalVariable *newGv = new GlobalVariable(M,
cMod->getType(),
true,
GlobalValue::ExternalLinkage,
cMod,
oss.str());
gv->replaceAllUsesWith(newGv);
}
Примечание. Я вручную набрал этот код, поэтому он может не компилироваться, но он должен служить иллюстрацией того, что япытаюсь достичь и как я пытаюсь достичь этого.
По какой-то причине новый GlobalVariable имеет другой тип.Печать типов во время выполнения дает:
gv->getType() = [36 x i8]*
newGv->getType() = [37 * x i8]*
Размер обеих строк составляет 36 символов.Почему тип нового GlobalVariable отличается, хотя длина строки не изменилась?Почему был добавлен дополнительный элемент?
Кроме того, replaceAllUsesWith()
требует, чтобы замена была того же типа.Если бы я хотел, чтобы замена была строкой другой длины, как бы я этого достиг?