diff --git a/include/revng/CliftImportModel/ImportModel.h b/include/revng/CliftImportModel/ImportModel.h index 24275b809..1b41b4bc8 100644 --- a/include/revng/CliftImportModel/ImportModel.h +++ b/include/revng/CliftImportModel/ImportModel.h @@ -67,4 +67,7 @@ void importDescriptiveInfo(const model::Function &Function, const model::Binary &Model, mlir::ModuleOp Module); +clift::StructType makeOpaqueStruct(mlir::MLIRContext &Context, + uint64_t NumBytes); + } // namespace clift diff --git a/lib/CliftEmitC/CMakeLists.txt b/lib/CliftEmitC/CMakeLists.txt index df00f9421..52941eb5b 100644 --- a/lib/CliftEmitC/CMakeLists.txt +++ b/lib/CliftEmitC/CMakeLists.txt @@ -14,4 +14,5 @@ revng_add_library_internal( TypeDefinitionEmitter.cpp TypeDependencyGraph.cpp) -target_link_libraries(revngCliftEmitC MLIRPass revngClift revngPTML) +target_link_libraries(revngCliftEmitC MLIRPass revngClift revngCliftImportModel + revngPTML) diff --git a/lib/CliftImportModel/ImportTypes.cpp b/lib/CliftImportModel/ImportTypes.cpp index 5d5c9e392..2cf8f297b 100644 --- a/lib/CliftImportModel/ImportTypes.cpp +++ b/lib/CliftImportModel/ImportTypes.cpp @@ -16,6 +16,7 @@ #include "revng/Clift/CliftTypes.h" #include "revng/CliftImportModel/CAttributeListBuilder.h" #include "revng/CliftImportModel/ImportModel.h" +#include "revng/Model/NameBuilder.h" #include "revng/Model/Segment.h" #include "revng/Pipeline/Location.h" #include "revng/Pipes/Ranks.h" @@ -831,3 +832,31 @@ void clift::importAllModelSegmentDeclarations(const model::Binary &Model, importSegmentType(Segment, Model, Module)); } } + +static std::string getOpaqueTypeHandle(uint64_t ByteSize) { + return pipeline::locationString(revng::ranks::OpaqueType, ByteSize); +} + +clift::StructType clift::makeOpaqueStruct(mlir::MLIRContext &Context, + uint64_t ByteSize) { + std::string Handle = getOpaqueTypeHandle(ByteSize); + + auto NameAttr = makeNameAttr(&Context, Handle); + auto CommentAttr = makeCommentAttr(&Context, Handle); + auto Attrs = llvm::ArrayRef{}; + auto Def = clift::StructAttr::get(&Context, + Handle, + NameAttr, + CommentAttr, + ByteSize, + {}, + Attrs); + + // TODO: this discards the prefix configuration option. + // We should fix this after the configuration is separate from the + // model + model::CNameBuilder Builder(model::Binary{}); + Def.getMutableName().setValue(Builder.opaqueTypeName(ByteSize)); + + return clift::StructType::get(Def); +} diff --git a/lib/Clifter/Clifter.cpp b/lib/Clifter/Clifter.cpp index 7c2ed5bfa..76fccc5f7 100644 --- a/lib/Clifter/Clifter.cpp +++ b/lib/Clifter/Clifter.cpp @@ -24,6 +24,7 @@ #include "revng/Model/Binary.h" #include "revng/Model/FunctionTags.h" #include "revng/Model/IRHelpers.h" +#include "revng/Model/NameBuilder.h" #include "revng/Pipeline/Location.h" #include "revng/Pipes/Ranks.h" #include "revng/RestructureCFG/ScopeGraphGraphTraits.h" @@ -263,37 +264,6 @@ private: return getVoidPointerType(); } - std::string getOpaqueTypeHandle(uint64_t ByteSize) { - return pipeline::locationString(revng::ranks::OpaqueType, ByteSize); - } - - clift::StructType importOpaqueStruct(uint64_t NumBytes) { - std::string Handle = getOpaqueTypeHandle(NumBytes); - - auto NameAttr = makeNameAttr(Context, Handle); - auto CommentAttr = makeCommentAttr(Context, Handle); - auto Attrs = llvm::ArrayRef{}; - auto Def = clift::StructAttr::get(Context, - Handle, - NameAttr, - CommentAttr, - NumBytes, - {}, - Attrs); - - return clift::StructType::get(Def); - } - - clift::StructType importOpaqueStruct(const llvm::ArrayType *Array) { - const auto *ElementType = Array->getElementType(); - revng_assert(ElementType->isIntegerTy()); - revng_assert(ElementType->getIntegerBitWidth() == 8); - uint64_t NumBytes = Array->getNumElements() - * (ElementType->getIntegerBitWidth() / 8); - - return importOpaqueStruct(NumBytes); - } - mlir::Type importLLVMType(const llvm::Type *Type) { if (Type->isVoidTy()) return getVoidType(); @@ -304,8 +274,15 @@ private: if (auto *T = llvm::dyn_cast(Type)) return importLLVMPointerType(T); - if (auto *T = llvm::dyn_cast(Type)) - return importOpaqueStruct(T); + if (auto *T = llvm::dyn_cast(Type)) { + const auto *ElementType = T->getElementType(); + revng_assert(ElementType->isIntegerTy()); + revng_assert(ElementType->getIntegerBitWidth() == 8); + uint64_t NumBytes = T->getNumElements() + * (ElementType->getIntegerBitWidth() / 8); + + return clift::makeOpaqueStruct(*Context, NumBytes); + } if (auto *S = llvm::dyn_cast(Type)) { const auto *StructLayout = DataLayout->getStructLayout(S); @@ -334,7 +311,7 @@ private: uint64_t ByteSize = PreviousOffsetInBits / 8; revng_assert(llvm::alignTo(ByteSize, Alignment) == StructByteSize); revng_assert(StructByteSize); - return importOpaqueStruct(StructByteSize); + return clift::makeOpaqueStruct(*Context, StructByteSize); } revng_abort("Unsupported LLVM type");