#ifndef PCC_TYPEMANAGER_H #define PCC_TYPEMANAGER_H #include #include #include #include #include "Type.hh" namespace pcc { class ExprNode; enum class BuiltinType { VOID, BOOLEAN, CHAR, SHORT, INTEGER, INT64, REAL, STRING, VOIDPTR, BUILTIN_NUMBER }; class TypeManager { public: TypeManager(); std::shared_ptr GetBuiltinType(BuiltinType type); std::shared_ptr GetPointerIndexType(); std::shared_ptr GetPointerDifferenceType(); std::shared_ptr GetRecordMemberIndexType(); // if call this function twice with the same ElementType, it will return the // same shared_ptr to the Type. std::shared_ptr GetPointerType(std::shared_ptr ElementType, const char* CustomName = nullptr); // record, array and function types are considered unique, unless use type // alias, you can't get the same type as previous call to this function. std::shared_ptr CreateRecordType(const std::vector& members); std::shared_ptr CreateArrayType(std::shared_ptr ElementType, std::shared_ptr start, std::shared_ptr end); std::shared_ptr CreateFunctionType(std::shared_ptr ReturnType, std::vector> ArgTypes, bool IsVariadic = false); // binary operators may change type std::pair, Value> CreateOperation(BinaryOperator op, std::shared_ptr LeftType, std::shared_ptr RightType, Value left, Value right, Context* context); // unary operators never change type Value CreateOperation(UnaryOperator op, std::shared_ptr type, Value v, Context* context); Value CreateCast(std::shared_ptr DstType, std::shared_ptr SrcType, Value v, Context* context); private: std::vector> builtins_; std::map, std::shared_ptr> PointerTypes_; std::vector> FunctionTypes_; std::vector> ArrayTypes_; std::vector> RecordTypes_; // if we are porting to some 64-bit machines, we can change these types to // 64-bit type, in order to make pointers behave correctly std::shared_ptr PointerDifferenceType_; std::shared_ptr PointerIndexType_; std::shared_ptr RecordMemberIndexType_; }; } // namespace pcc #endif // !PCC_TYPEMANAGER_H