//
// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// ManglerCommon.cpp --
//
// Author           : Richard C. Bilson
// Created On       : Sun May 17 21:44:03 2015
// Last Modified By : Peter A. Buhr
// Last Modified On : Mon Jan 11 21:23:10 2021
// Update Count     : 29
//

#include "Mangler.hpp"

#include "AST/Decl.hpp"
#include "AST/Type.hpp"

namespace Mangle {

namespace Encoding {

const std::string manglePrefix = "_X";

// GENERATED START, DO NOT EDIT
// GENERATED BY BasicTypes-gen.cpp
// NOTES ON MANGLING:
// * Itanium spec says that Float80 encodes to "e" (like LongDouble), but the distinct lengths cause resolution problems.
// * Float128 is supposed to encode to "g", but I wanted it to mangle equal to LongDouble.
// * Mangling for non-standard complex types is by best guess
// * _FloatN is supposed to encode as "DF"N"_"; modified for same reason as above.
// * unused mangling identifiers:
//   - "z" ellipsis
//   - "Dd" IEEE 754r 64-bit decimal floating point (borrowed for _Float32x)
//   - "De" IEEE 754r 128-bit decimal floating point
//   - "Df" IEEE 754r 32-bit decimal floating point
//   - "Dh" IEEE 754r 16-bit decimal floating point (borrowed for _Float16)
//   - "DF"N"_" ISO/IEC TS 18661 N-bit binary floating point (_FloatN)
//   - "Di" char32_t
//   - "Ds" char16_t
const std::string basicTypes[ast::BasicKind::NUMBER_OF_BASIC_TYPES] = {
	"b",        // _Bool
	"c",        // char
	"a",        // signed char
	"h",        // unsigned char
	"s",        // signed short int
	"t",        // unsigned short int
	"i",        // signed int
	"j",        // unsigned int
	"l",        // signed long int
	"m",        // unsigned long int
	"x",        // signed long long int
	"y",        // unsigned long long int
	"n",        // __int128
	"o",        // unsigned __int128
	"DF16_",    // _Float16
	"CDF16_",   // _Float16 _Complex
	"DF32_",    // _Float32
	"CDF32_",   // _Float32 _Complex
	"f",        // float
	"Cf",       // float _Complex
	"DF32x_",   // _Float32x
	"CDF32x_",  // _Float32x _Complex
	"DF64_",    // _Float64
	"CDF64_",   // _Float64 _Complex
	"d",        // double
	"Cd",       // double _Complex
	"DF64x_",   // _Float64x
	"CDF64x_",  // _Float64x _Complex
	"Dq",       // __float80
	"e",        // long double
	"Ce",       // long double _Complex
	"g",        // __float128
	"DF128_",   // _Float128
	"CDF128_",  // _Float128 _Complex
	"DF128x_",  // _Float128x
	"CDF128x_", // _Float128x _Complex
}; // basicTypes
// GENERATED END
static_assert(
	sizeof(basicTypes) / sizeof(basicTypes[0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES,
	"Each basic type kind should have a corresponding mangler letter"
);

const std::map<int, std::string> qualifiers = {
	{ ast::CV::Const, "K" },
	{ ast::CV::Volatile, "V" },
	{ ast::CV::Atomic, "DA" }, // A is array, so need something unique for atmoic. For now, go with multiletter DA
	{ ast::CV::Mutex, "X" },
};

const std::string void_t = "v";
const std::string zero = "Z";
const std::string one = "O";

const std::string function = "F";
const std::string tuple = "T";
const std::string pointer = "P";
const std::string array = "A";
const std::string qualifiedTypeStart = "N";
const std::string qualifiedTypeEnd = "E";

const std::string forall = "Q";
const std::string typeVariables[] = {
	"BD", // dtype
	"BDS", // dtype + sized
	"BO", // otype
	"BF", // ftype
	"BT", // ttype
	"BAL", // array length type
};
static_assert(
	sizeof(typeVariables) / sizeof(typeVariables[0]) == ast::TypeDecl::NUMBER_OF_KINDS,
	"Each type variable kind should have a corresponding mangler prefix"
);

const std::string struct_t = "S";
const std::string union_t = "U";
const std::string enum_t = "M";
const std::string type = "Y";

const std::string autogen = "autogen__";
const std::string intrinsic = "intrinsic__";

} // namespace Encoding

} // namespace Mangle
