Files
revng-revng/lib/TypeNames/LLVMTypeNames.cpp
T
Giacomo Vercesi 8e996d2394 Output PTML in revng-c
Change the output of the backend of revng-c to PTML
2022-09-01 16:59:29 +02:00

124 lines
3.5 KiB
C++

//
// Copyright (c) rev.ng Labs Srl. See LICENSE.md for details.
//
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "revng/Model/Binary.h"
#include "revng/Model/Identifier.h"
#include "revng/Pipeline/Location.h"
#include "revng/Support/Assert.h"
#include "revng/Support/FunctionTags.h"
#include "revng-c/Pipes/Ranks.h"
#include "revng-c/Support/FunctionTags.h"
#include "revng-c/Support/PTMLC.h"
#include "revng-c/TypeNames/LLVMTypeNames.h"
using llvm::Twine;
using tokenDefinition::types::TypeString;
using namespace ArtificialTypes;
namespace tokens = ptml::c::tokenTypes;
namespace ranks = revng::ranks;
TypeString
getScalarCType(const llvm::Type *LLVMType, llvm::StringRef BaseType) {
switch (LLVMType->getTypeID()) {
case llvm::Type::HalfTyID:
case llvm::Type::BFloatTyID:
return TypeString("float16_t");
break;
case llvm::Type::FloatTyID:
return TypeString("float32_t");
break;
case llvm::Type::DoubleTyID:
return TypeString("float64_t");
break;
case llvm::Type::X86_FP80TyID:
// TODO: 80-bit float have 96 bit storage, how should we call them?
return TypeString("float96_t");
break;
case llvm::Type::FP128TyID:
case llvm::Type::PPC_FP128TyID:
return TypeString("float128_t");
break;
case llvm::Type::VoidTyID: {
return TypeString("void");
break;
case llvm::Type::IntegerTyID: {
auto *IntType = cast<llvm::IntegerType>(LLVMType);
switch (IntType->getIntegerBitWidth()) {
case 1:
return TypeString("bool");
case 8:
return TypeString("uint8_t");
case 16:
return TypeString("uint16_t");
break;
case 32:
return TypeString("uint32_t");
break;
case 64:
return TypeString("uint64_t");
break;
case 128:
return TypeString("uint128_t");
break;
default:
revng_abort("Found an LLVM integer with a size that is not a power of "
"two");
}
} break;
case llvm::Type::PointerTyID: {
if (BaseType.empty())
return TypeString("void *");
return TypeString((BaseType + " *").str());
} break;
default:
revng_abort("Cannot convert this type directly to a C type.");
}
}
}
VariableTokensWithName getReturnType(const llvm::Function *Func) {
auto *RetType = Func->getReturnType();
// Isolated functions' return types must be converted using model types
revng_assert(not FunctionTags::Isolated.isTagOf(Func));
if (RetType->isStructTy()) {
const auto &FuncName = model::Identifier::fromString(Func->getName());
const std::string StructName = (StructWrapperPrefix + FuncName).str();
return {
StructName,
tokenTag(StructName, tokens::Type)
.addAttribute(ptml::attributes::LocationDefinition,
pipeline::serializedLocation(ranks::Helpers, StructName)),
tokenTag(StructName, tokens::Type)
.addAttribute(ptml::attributes::LocationReferences,
pipeline::serializedLocation(ranks::Helpers, StructName))
};
} else {
auto CType = getScalarCType(RetType).str();
return { CType,
tokenTag(CType, tokens::Type),
tokenTag(CType, tokens::Type) };
}
}
FieldInfo getFieldInfo(const llvm::StructType *StructTy, size_t Index) {
FieldInfo FieldInfo;
FieldInfo.FieldName = TypeString((StructFieldPrefix + Twine(Index)).str());
FieldInfo.FieldTypeName = getScalarCType(StructTy->getTypeAtIndex(Index));
return FieldInfo;
}