// // 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. // // CommonType.cc -- // // Author : Richard C. Bilson // Created On : Sun May 17 06:59:27 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Thu Feb 14 17:10:10 2019 // Update Count : 24 // #include "CommonType.hpp" #include // for strict_dynamic_cast #include // for _Rb_tree_const_iterator #include // for pair #include "AST/Decl.hpp" #include "AST/Pass.hpp" #include "AST/Type.hpp" #include "Unify.h" // for unifyExact, WidenMode #include "typeops.h" // for isFtype #include "Tuples/Tuples.h" // #define DEBUG #ifdef DEBUG #define PRINT(x) x #else #define PRINT(x) #endif namespace ResolvExpr { namespace { // GENERATED START, DO NOT EDIT // GENERATED BY BasicTypes-gen.cc #define BT ast::BasicKind:: static const ast::BasicKind commonTypes[BT NUMBER_OF_BASIC_TYPES][BT NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X _FDXC F80 _FB _FLDC FB LD LDC _FBX _FLDXC */ { /* B */ BT Bool, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* C */ BT Char, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* SC */ BT SignedChar, BT SignedChar, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* UC */ BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* SI */ BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortUnsignedInt, BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* SUI */ BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* I */ BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* UI */ BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* LI */ BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* LUI */ BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* LLI */ BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* IB */ BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* UIB */ BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* _FH */ BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* _FH */ BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat32Complex, BT uFloat32Complex, BT FloatComplex, BT FloatComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex, BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, }, { /* _F */ BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32Complex, BT uFloat32, BT uFloat32Complex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* _FC */ BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT FloatComplex, BT FloatComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex, BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, }, { /* F */ BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, BT FloatComplex, BT Float, BT FloatComplex, BT Float, BT FloatComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* FC */ BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex, BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, }, { /* _FX */ BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* _FXC */ BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat64Complex, BT uFloat64Complex, BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, }, { /* FD */ BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* _FDC */ BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, }, { /* D */ BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* DC */ BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, }, { /* F80X */ BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* _FDXC */ BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, }, { /* F80 */ BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat64xComplex, BT uuFloat80, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* _FB */ BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* _FLDC */ BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, }, { /* FB */ BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* LD */ BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* LDC */ BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT uFloat128xComplex, BT uFloat128xComplex, }, { /* _FBX */ BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, }, { /* _FLDXC */ BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, }, }; // commonTypes #undef BT // GENERATED END static_assert( sizeof(commonTypes)/sizeof(commonTypes[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES, "Each basic type kind should have a corresponding row in the combined type matrix" ); class CommonType final : public ast::WithShortCircuiting { const ast::Type * type2; WidenMode widen; ast::TypeEnvironment & tenv; const ast::OpenVarSet & open; ast::AssertionSet & need; ast::AssertionSet & have; public: static size_t traceId; ast::ptr< ast::Type > result; CommonType( const ast::Type * t2, WidenMode w, ast::TypeEnvironment & env, const ast::OpenVarSet & o, ast::AssertionSet & need, ast::AssertionSet & have ) : type2( t2 ), widen( w ), tenv( env ), open( o ), need (need), have (have) ,result() {} void previsit( const ast::Node * ) { visit_children = false; } void postvisit( const ast::VoidType * ) {} void postvisit( const ast::BasicType * basic ) { if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) { ast::BasicKind kind; if (basic->kind != basic2->kind && !widen.first && !widen.second) return; else if (!widen.first) kind = basic->kind; // widen.second else if (!widen.second) kind = basic2->kind; else kind = commonTypes[ basic->kind ][ basic2->kind ]; // xxx - what does qualifiers even do here?? if ( (basic->qualifiers >= basic2->qualifiers || widen.first) && (basic->qualifiers <= basic2->qualifiers || widen.second) ) { result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers }; } } else if ( dynamic_cast< const ast::ZeroType * >( type2 ) || dynamic_cast< const ast::OneType * >( type2 ) ) { if (widen.second) { result = new ast::BasicType{ basic->kind, basic->qualifiers | type2->qualifiers }; } } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { const ast::EnumDecl* enumDecl = enumInst->base; if ( !enumDecl->base ) { ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ]; if ( ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) || widen.first ) && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) || widen.second ) ) { result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; } } } else if ( auto type2AsAttr = dynamic_cast< const ast::EnumAttrType * >( type2 ) ) { if ( type2AsAttr->attr == ast::EnumAttribute::Posn ) { ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ]; if ( ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) || widen.first ) && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) || widen.second ) ) { result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; } } } } private: template< typename Pointer > void getCommonWithVoidPointer( const Pointer * voidPtr, const Pointer * oPtr ) { const ast::Type * base = oPtr->base; if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) { auto entry = open.find( *var ); if ( entry != open.end() ) { ast::AssertionSet need, have; if ( ! tenv.bindVar( var, voidPtr->base, entry->second, need, have, open, widen ) ) return; } } result = voidPtr; add_qualifiers( result, oPtr->qualifiers ); } public: void postvisit( const ast::PointerType * pointer ) { if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) { if ( widen.first && pointer2->base.as< ast::VoidType >() && ! ast::isFtype( pointer->base ) ) { getCommonWithVoidPointer( pointer2, pointer ); } else if ( widen.second && pointer->base.as< ast::VoidType >() && ! ast::isFtype( pointer2->base ) ) { getCommonWithVoidPointer( pointer, pointer2 ); } else if ( ( pointer->base->qualifiers >= pointer2->base->qualifiers || widen.first ) && ( pointer->base->qualifiers <= pointer2->base->qualifiers || widen.second ) ) { ast::CV::Qualifiers q1 = pointer->base->qualifiers; ast::CV::Qualifiers q2 = pointer2->base->qualifiers; // force t{1,2} to be cloned if their qualifiers must be stripped, so that // pointer{,2}->base are unchanged ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base }; reset_qualifiers( t1 ); reset_qualifiers( t2 ); ast::OpenVarSet newOpen{ open }; if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden() ) ) { result = pointer; if ( q1.val != q2.val ) { // reset result->base->qualifiers to be union of two base qualifiers strict_dynamic_cast< ast::PointerType * >( result.get_and_mutate() )->base.get_and_mutate()->qualifiers = q1 | q2; } } else if ( isFtype (t1) && isFtype (t2) ) { auto f1 = t1.as(); if (!f1) return; auto f2 = t2.strict_as(); assertf(f1->returns.size() <= 1, "Function return should not be a list"); assertf(f2->returns.size() <= 1, "Function return should not be a list"); if ( ( f1->params.size() != f2->params.size() || f1->returns.size() != f2->returns.size() ) && ! f1->isTtype() && ! f2->isTtype() ) return; auto params1 = flattenList( f1->params, tenv ); auto params2 = flattenList( f2->params, tenv ); auto crnt1 = params1.begin(); auto crnt2 = params2.begin(); auto end1 = params1.end(); auto end2 = params2.end(); while (crnt1 != end1 && crnt2 != end2 ) { const ast::Type * arg1 = *crnt1; const ast::Type * arg2 = *crnt2; bool isTuple1 = Tuples::isTtype( t1 ); bool isTuple2 = Tuples::isTtype( t2 ); // assumes here that ttype *must* be last parameter if ( isTuple1 && ! isTuple2 ) { // combine remainder of list2, then unify if (unifyExact( arg1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open, noWiden() )) { break; } else return; } else if ( ! isTuple1 && isTuple2 ) { // combine remainder of list1, then unify if (unifyExact( tupleFromTypes( crnt1, end1 ), arg2, tenv, need, have, open, noWiden() )) { break; } else return; } // allow qualifiers of pointer and reference base to become more specific if (auto ref1 = dynamic_cast (arg1)) { if (auto ref2 = dynamic_cast (arg2)) { ast::ptr base1 = ref1->base; ast::ptr base2 = ref2->base; // xxx - assume LHS is always the target type if ( ! ((widen.second && ref2->qualifiers.is_mutex) || (ref1->qualifiers.is_mutex == ref2->qualifiers.is_mutex ))) return; if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) { reset_qualifiers(base1); reset_qualifiers(base2); if ( !unifyExact( base1, base2, tenv, need, have, open, noWiden() ) ) return; } } else return; } else if (auto ptr1 = dynamic_cast (arg1)) { if (auto ptr2 = dynamic_cast (arg2)) { ast::ptr base1 = ptr1->base; ast::ptr base2 = ptr2->base; // xxx - assume LHS is always the target type // a function accepting const can always be called by non-const arg if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) { reset_qualifiers(base1); reset_qualifiers(base2); if ( ! unifyExact( base1, base2, tenv, need, have, open, noWiden() ) ) return; } } else return; } else if (! unifyExact( arg1, arg2, tenv, need, have, open, noWiden() )) { return; } ++crnt1; ++crnt2; } if ( crnt1 != end1 ) { // try unifying empty tuple with ttype const ast::Type * t1 = *crnt1; if (! Tuples::isTtype( t1 ) ) return; if (! unifyExact( t1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open, noWiden() )) return; } else if ( crnt2 != end2 ) { // try unifying empty tuple with ttype const ast::Type * t2 = *crnt2; if ( !Tuples::isTtype( t2 ) ) return; if ( !unifyExact( tupleFromTypes( crnt1, end1 ), t2, tenv, need, have, open, noWiden() )) return; } if ((f1->returns.size() == 0 && f2->returns.size() == 0) || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden()))) { result = pointer; for (auto & assn : f1->assertions) { auto i = need.find(assn); if (i != need.end()) i->second.isUsed = true; auto j = have.find(assn); if (j != have.end()) j->second.isUsed = true; } for (auto & assn : f2->assertions) { auto i = need.find(assn); if (i != need.end()) i->second.isUsed = true; auto j = have.find(assn); if (j != have.end()) j->second.isUsed = true; } } } // if ftype } } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { result = pointer; add_qualifiers( result, type2->qualifiers ); } } void postvisit( const ast::ArrayType * ) {} void postvisit( const ast::ReferenceType * ref ) { if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { if ( widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) ) { getCommonWithVoidPointer( ref2, ref ); } else if ( widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) ) { getCommonWithVoidPointer( ref, ref2 ); } else if ( ( ref->base->qualifiers >= ref2->base->qualifiers || widen.first ) && ( ref->base->qualifiers <= ref2->base->qualifiers || widen.second ) ) { ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers; // force t{1,2} to be cloned if their qualifiers must be stripped, so that // ref{,2}->base are unchanged ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base }; reset_qualifiers( t1 ); reset_qualifiers( t2 ); ast::OpenVarSet newOpen{ open }; if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden() ) ) { result = ref; if ( q1.val != q2.val ) { // reset result->base->qualifiers to be union of two base qualifiers strict_dynamic_cast< ast::ReferenceType * >( result.get_and_mutate() )->base.get_and_mutate()->qualifiers = q1 | q2; } } } } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { result = ref; add_qualifiers( result, type2->qualifiers ); } else { if (!dynamic_cast(type2)) result = commonType( type2, ref, tenv, need, have, open, widen ); } } void postvisit( const ast::FunctionType * ) {} void postvisit( const ast::StructInstType * ) {} void postvisit( const ast::UnionInstType * ) {} void postvisit( const ast::EnumInstType * enumInst ) { if ( enumInst->base && !enumInst->base->base ) { auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt ); result = commonType( basicType, type2, tenv, need, have, open, widen); } } void postvisit( const ast::EnumAttrType * ) {} void postvisit( const ast::TraitInstType * ) {} void postvisit( const ast::TypeInstType * ) {} void postvisit( const ast::TupleType * ) {} void postvisit( const ast::VarArgsType * ) {} void postvisit( const ast::ZeroType * zero ) { if ( !widen.first ) return; if ( dynamic_cast< const ast::BasicType * >( type2 ) || dynamic_cast< const ast::PointerType * >( type2 ) ) { if ( widen.second || zero->qualifiers <= type2->qualifiers ) { result = type2; add_qualifiers( result, zero->qualifiers ); } } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) { result = new ast::BasicType{ ast::BasicKind::SignedInt, zero->qualifiers | type2->qualifiers }; } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { const ast::EnumDecl * enumDecl = enumInst->base; if ( !enumDecl->base ) { if ( widen.second || zero->qualifiers <= type2->qualifiers ) { result = type2; add_qualifiers( result, zero->qualifiers ); } } } } void postvisit( const ast::OneType * one ) { if ( !widen.first ) return; if ( dynamic_cast< const ast::BasicType * >( type2 ) ) { if ( widen.second || one->qualifiers <= type2->qualifiers ) { result = type2; add_qualifiers( result, one->qualifiers ); } } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { result = new ast::BasicType{ ast::BasicKind::SignedInt, one->qualifiers | type2->qualifiers }; } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { const ast::EnumDecl * enumDecl = enumInst->base; if ( !enumDecl->base ) { if ( widen.second || one->qualifiers <= type2->qualifiers ) { result = type2; add_qualifiers( result, one->qualifiers ); } } } } }; // size_t CommonType::traceId = Stats::Heap::new_stacktrace_id("CommonType"); ast::ptr< ast::Type > handleReference( const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, ast::TypeEnvironment & env, const ast::OpenVarSet & open ) { ast::ptr common; ast::AssertionSet have, need; ast::OpenVarSet newOpen( open ); // need unify to bind type variables if ( unify( t1, t2, env, have, need, newOpen, common ) ) { ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers; PRINT( std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl; ) if ( ( widen.first || q2 <= q1 ) && ( widen.second || q1 <= q2 ) ) { PRINT( std::cerr << "widen okay" << std::endl; ) add_qualifiers( common, q1 | q2 ); return common; } } PRINT( std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl; ) return { nullptr }; } } // namespace ast::ptr< ast::Type > commonType( const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen ) { unsigned depth1 = type1->referenceDepth(); unsigned depth2 = type2->referenceDepth(); if ( depth1 != depth2 ) { // implies depth1 > 0 || depth2 > 0 PRINT( std::cerr << "reference depth diff: " << (depth1-depth2) << std::endl; ) ast::ptr< ast::Type > result; const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >(); const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >(); if ( depth1 > depth2 ) { assert( ref1 ); result = handleReference( ref1->base, type2, widen, env, open ); } else { // Implies depth1 < depth2 assert( ref2 ); result = handleReference( type1, ref2->base, widen, env, open ); } if ( result && ref1 ) { // formal is reference, so result should be reference PRINT( std::cerr << "formal is reference; result should be reference" << std::endl; ) result = new ast::ReferenceType{ result, ref1->qualifiers }; } PRINT( std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is " "[" << result << "]" << std::endl; ) return result; } // otherwise both are reference types of the same depth and this is handled by the visitor return ast::Pass::read( type1.get(), type2, widen, env, open, need, have ); } } // namespace ResolvExpr // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //