// CPPTypeBuiltin.cpp: Builtin-type class
#include "CPPType.h"
#include "CPPTypeBuiltin.h"
#ifdef _MSC_VER
// Disable some warnings that appear commonly in Rogue Wave STL
#pragma warning (disable:4786) // long debug names
#pragma warning (disable:4146) // unary minus operator applied to unsigned type
#pragma warning (disable:4018) // '>' : signed/unsigned mismatch
#endif
#include <vector>
// These should really be nested classes, but #@$&^*@#*&^$ MSVC++ 5.0
// can't deal with nested classes as template parameters to vector<>
// TypeSpecifier compatibility table
struct CompatTable {
CompatTable(
CPPConst::TypeSpecifier toCheck_ = CPPConst::tsNONE,
CPPConst::TypeSpecifier compatibleWith_ = CPPConst::tsNONE
) :
toCheck(toCheck_),
compatibleWith(compatibleWith_)
{}
CPPConst::TypeSpecifier toCheck;
CPPConst::TypeSpecifier compatibleWith;
// Need these because MSVC++ 5.0 is brain dead
bool operator<(const CompatTable& rhs) const { return true; }
bool operator==(const CompatTable& rhs) const { return true; }
};
// TypeSpecifier name table
struct NameTable {
NameTable(
CPPConst::TypeSpecifier ts_ = CPPConst::tsNONE,
const JLStr& name_ = ""
) : ts(ts_), name(name_) {}
CPPConst::TypeSpecifier ts;
JLStr name;
// Need these because MSVC++ 5.0 is brain dead
bool operator<(const NameTable& rhs) const { return true; }
bool operator==(const NameTable& rhs) const { return true; }
};
class CPPTypeBuiltin::NameTableVector :
public vector<NameTable, allocator<NameTable> >
{
};
class CPPTypeBuiltin::CompatTableVector :
public vector<CompatTable, allocator<CompatTable> >
{
};
////////////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////////////
CPPTypeBuiltin::CPPTypeBuiltin(
CPPConst::TypeSpecifier typeSpecifier_
) :
CPPType(Builtin),
typeSpecifier(typeSpecifier_)
{
// Make sure only valid types are entered.
assert(TypeSpecifierIsValid(typeSpecifier));
}
/////////////////////////////////////////////////////////////////
// FormatName: Format the name of the type, using the names of the
// modified types where needed to construct the full type name.
//
// Inputs:
// const JLStr& declName If non-empty, then this is used
// to format the declarator name
// in the proper position.
// const JLStr& suffixStr Any accumulated suffix string
// Return:
// JLStr The formatted type name
/////////////////////////////////////////////////////////////////
// virtual
JLStr
CPPTypeBuiltin::FormatName(
const JLStr& declName,
const JLStr& suffixStr,
StrListRefI,
bool
) const
{
assertValid();
JLStr tmpStr = FormatTypeSpecifierName(typeSpecifier);
if (declName.length() != 0 || suffixStr.length() != 0)
{
tmpStr += " " + declName + suffixStr;
}
return tmpStr;
}
/////////////////////////////////////////////////////////////////
// FormatTypeSpecifierName: Format the name of the type specifiers.
//
// Inputs:
// CPPConst::TypeSpecifier ts The type specifiers
// Return:
// JLStr The formatted type name
/////////////////////////////////////////////////////////////////
// static
JLStr
CPPTypeBuiltin::FormatTypeSpecifierName(
CPPConst::TypeSpecifier ts
)
{
JLStr retval;
InitTables();
for (
NameTableVector::iterator iter = nameTable->begin();
iter != nameTable->end();
iter++
)
{
if ((ts & (*iter).ts) != 0)
{
if (retval.length() != 0)
{
retval += " ";
}
retval += (*iter).name;
}
}
return retval;
}
////////////////////////////////////////////////////////////////////
// TypeSpecifierIsValid: static method to validate a type
// specifier. This works by checking each ORable component
// of the type specifier against each other component, using
// a table of mutual-exclusivity.
////////////////////////////////////////////////////////////////////
// static
bool
CPPTypeBuiltin::TypeSpecifierIsValid(
CPPConst::TypeSpecifier typeSpecifier
)
{
// The compatibility table is independent of the order
// of the entries and the values of the ts* constants
// except that tsNONE = 0 (believe it or not...)
InitTables();
for (
CompatTableVector::iterator iter = compatTable->begin();
iter != compatTable->end();
iter++
)
{
if ((typeSpecifier & (*iter).toCheck) != CPPConst::tsNONE)
{
if ((typeSpecifier & ~(*iter).compatibleWith) != CPPConst::tsNONE)
{
return false;
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// InitStatic: initialize the tables used by CPPTypeBuiltin
// We cannot initialize these at compile-time because they
// depend on other static globals being initialized first.
////////////////////////////////////////////////////////////////////
void
CPPTypeBuiltin::InitTables()
{
if (compatTable != 0)
{
return;
}
// Initialize builtin type compatibility table
compatTable = new CompatTableVector;
compatTable->push_back(CompatTable(
CPPConst::tsVOID,
CPPConst::tsVOID
));
compatTable->push_back(CompatTable(
CPPConst::tsCHAR,
CPPConst::tsCHAR|CPPConst::tsSIGNED|CPPConst::tsUNSIGNED
));
compatTable->push_back(CompatTable(
CPPConst::tsSHORT,
CPPConst::tsSHORT|CPPConst::tsINT|CPPConst::tsSIGNED|CPPConst::tsUNSIGNED
));
compatTable->push_back(CompatTable(
CPPConst::tsINT,
CPPConst::tsINT|CPPConst::tsLONG|CPPConst::tsSHORT|CPPConst::tsSIGNED|
CPPConst::tsUNSIGNED
));
compatTable->push_back(CompatTable(
CPPConst::tsLONG,
CPPConst::tsLONG|CPPConst::tsINT|CPPConst::tsDOUBLE|CPPConst::tsSIGNED|
CPPConst::tsUNSIGNED
));
compatTable->push_back(CompatTable(
CPPConst::tsFLOAT,
CPPConst::tsFLOAT
));
compatTable->push_back(CompatTable(
CPPConst::tsDOUBLE,
CPPConst::tsLONG|CPPConst::tsDOUBLE
));
compatTable->push_back(CompatTable(
CPPConst::tsSIGNED,
CPPConst::tsSIGNED|CPPConst::tsCHAR|CPPConst::tsSHORT|CPPConst::tsINT|
CPPConst::tsLONG|CPPConst::tsINT64
));
compatTable->push_back(CompatTable(
CPPConst::tsUNSIGNED,
CPPConst::tsUNSIGNED|CPPConst::tsCHAR|CPPConst::tsSHORT|CPPConst::tsINT|
CPPConst::tsLONG|CPPConst::tsINT64
));
compatTable->push_back(CompatTable(
CPPConst::tsTYPEID,
CPPConst::tsNONE
));
compatTable->push_back(CompatTable(
CPPConst::tsSTRUCT,
CPPConst::tsNONE
));
compatTable->push_back(CompatTable(
CPPConst::tsENUM,
CPPConst::tsNONE
));
compatTable->push_back(CompatTable(
CPPConst::tsUNION,
CPPConst::tsNONE
));
compatTable->push_back(CompatTable(
CPPConst::tsCLASS,
CPPConst::tsNONE
));
compatTable->push_back(CompatTable(
CPPConst::tsWCHAR_T,
CPPConst::tsWCHAR_T
));
compatTable->push_back(CompatTable(
CPPConst::tsBOOL,
CPPConst::tsBOOL
));
compatTable->push_back(CompatTable(
CPPConst::tsINT64,
CPPConst::tsINT64|CPPConst::tsSIGNED|CPPConst::tsUNSIGNED
));
// Initialize builtin-type name table. The name table includes
// names for type specifiers that are not valid builtin types,
// for convenience.
nameTable = new NameTableVector;
nameTable->push_back(NameTable(CPPConst::tsSIGNED, "signed"));
nameTable->push_back(NameTable(CPPConst::tsUNSIGNED, "unsigned"));
nameTable->push_back(NameTable(CPPConst::tsSHORT, "short"));
nameTable->push_back(NameTable(CPPConst::tsLONG, "long"));
nameTable->push_back(NameTable(CPPConst::tsCHAR, "char"));
nameTable->push_back(NameTable(CPPConst::tsINT, "int"));
nameTable->push_back(NameTable(CPPConst::tsFLOAT, "float"));
nameTable->push_back(NameTable(CPPConst::tsDOUBLE, "double"));
nameTable->push_back(NameTable(CPPConst::tsWCHAR_T, "wchar_t"));
nameTable->push_back(NameTable(CPPConst::tsBOOL, "bool"));
nameTable->push_back(NameTable(CPPConst::tsINT64, "int64"));
nameTable->push_back(NameTable(CPPConst::tsVOID, "void"));
nameTable->push_back(NameTable(CPPConst::tsENUM, "enum"));
nameTable->push_back(NameTable(CPPConst::tsCLASS, "class"));
nameTable->push_back(NameTable(CPPConst::tsSTRUCT, "struct"));
nameTable->push_back(NameTable(CPPConst::tsUNION, "union"));
nameTable->push_back(NameTable(CPPConst::tsNONE, ""));
}
CPPTypeBuiltin::CompatTableVector *CPPTypeBuiltin::compatTable;
CPPTypeBuiltin::NameTableVector *CPPTypeBuiltin::nameTable;