// CPPSymTableEnum.cpp: Type manipulation for CPPParserSym
#include "CPPSymTable.h"
#include "CPPScope.h"
#include "CPPTypeEnum.h"
#include "CPPDecl.h"
/////////////////////////////////////////////////////////////////////
// NewEnumType: Create a new, unique enumeration type and enter it
// into the current scope.
//
// Inputs:
// const JLStr& name The name of the enumerator.
// CPPscopeRefI& targetScope The scope in which the enum will
// be created.
// Outputs:
// CPPTypeRefI& typeReturn The new enumerator type
// CPPDeclRefI& declReturn The new enumerator type declaration
// Return: none
/////////////////////////////////////////////////////////////////////
// virtual
void
CPPSymTable::NewEnumType(
const JLStr& name,
CPPScopeRefI& targetScope,
CPPTypeRefI& typeReturn,
CPPDeclRefI& declReturn
)
{
// Create the type
typeReturn = new CPPTypeEnum(name);
// ... and enter the declaration
declReturn = new CPPDeclType(
name,
targetScope->GetCurrentAccess(),
typeReturn,
false
);
targetScope->AddDecl(declReturn);
}
/////////////////////////////////////////////////////////////////////
// DeclareEnumType: Declare an enumerator type. OK if enumerator
// exists, but the name cannot define a different type. This internal
// method takes different parameters than the parser virtual method.
//
// Inputs:
// const JLStr& name The name of the enumerator (may be empty)
// CPPScopeRefI targetScope The scope in which the
// definition will be made
// const ANTLRTokenPtr& errTok A token for error-handling.
// Outputs:
// CPPTypeRefI& typeReturn The enumerator type
// CPPDeclRefI& declReturn The enumerator type declaration
// JLStr& enumNameReturn The name of the declared enum
// Return:
// bool true if the declaration succeeded.
/////////////////////////////////////////////////////////////////////
bool
CPPSymTable::DeclareEnumType(
const JLStr& name,
CPPScopeRefI targetScope,
const ANTLRTokenPtr& errTok,
CPPTypeRefI& typeReturn,
CPPDeclRefI& declReturn,
JLStr& enumNameReturn
)
{
bool retval = true;
enumNameReturn = (name.length() == 0) ? GetUniqueName() : name;
bool foundType = false;
CPPScopeRefI containingScope;
if (targetScope.get() == 0)
{
// Special consideration for declaration made in the current scope,
// because it may find and return a declaration elsewhere on the scope stack.
targetScope = GetCurrentScope();
foundType = LookupType(enumNameReturn, declReturn, typeReturn, containingScope);
} else {
// target scope was specified
// Check for the declaration already existing in the target scope.
declReturn = targetScope->FindTypeDeclByName(enumNameReturn);
if (declReturn.get() != 0)
{
foundType = true;
typeReturn = declReturn->GetType();
containingScope = targetScope;
}
}
bool foundEnum =
foundType &&
!declReturn->IsTypedef() &&
typeReturn->GetFlavor() == CPPType::Enum;
if (foundType && containingScope == targetScope && !foundEnum)
{
// The type was found and it's not an enum
ReportError(
JLStr("\"") + enumNameReturn + "\" is already defined as something other than an enum",
errTok
);
// Return the found type, for lack of anything better to do
retval = false;
} else if (foundType && foundEnum)
{
// The class was found -- use the found type
} else {
// Declare the enum in the appropriate scope
NewEnumType(enumNameReturn, targetScope, typeReturn, declReturn);
}
return retval;
}
/////////////////////////////////////////////////////////////////////
// DefineEnumType: Define an enumerator type in the current scope.
// Invalid if the enumerator is already defined, but OK if it is
// declared.
//
// Inputs:
// const JLStr& name The name of the enumerator
// (may be empty)
// CPPScopeRefI targetScope The scope in which the
// definition will be made
// const ANTLRTokenPtr errTok A token for error-handling
// Outputs:
// CPPTypeRefI& typeReturn The enumerator type
// CPPDeclRefI& declReturn The enumerator type declaration
// JLStr& enumNameReturn The name of the declared enum
// Return: none
/////////////////////////////////////////////////////////////////////
void
CPPSymTable::DefineEnumType(
const JLStr& name,
CPPScopeRefI targetScope,
const ANTLRTokenPtr& errTok,
CPPTypeRefI& typeReturn,
CPPDeclRefI& declReturn,
JLStr& enumNameReturn
)
{
if (DeclareEnumType(name, targetScope, errTok, typeReturn, declReturn, enumNameReturn))
{
// The enum was successfully declared -- make sure it is not defined
if (typeReturn->GetComplete())
{
// Error -- enumerator already defined
ReportError(
JLStr("enum \"") + enumNameReturn + "\" has already been defined ",
errTok
);
} else {
// define it
typeReturn->SetComplete();
}
}
}