// CPPSymTableSpecialize.cpp: Templated class/function specialization
#include "CPPSymTable.h"
#include "CPPScope.h"
#include "CPPType.h"
#include "CPPDecl.h"
#include "JLCast.h"
#include "CPPScopeContainers.h"
////////////////////////////////////////////////////////////////////
// LookupSpecialization: Given the name of a template
// and a list of template arguments, create a specialization
// if one does not exist.
//
// Inputs:
// const JLStr& name name of the template
// CPPScopeRefI containingScope
// The scope in which the
// template is declared
// TemplateArgumentListRef argList list of actual template
// arguments (types or values)
// Outputs:
// JLStr& specializationNameReturn
// If successful, filled with the
// decorated template name
// CPPTypeRefI& specializationTypeReturn
// If successful, points to the
// type entry for the specialization.
// Return:
// bool true on success, false if something was wrong with
// the specialization, in which case an error has
// already been reported.
//////////////////////////////////////////////////////////////////
bool
CPPSymTable::LookupSpecialization(
const JLStr& name,
TemplateArgumentListRefI templateArgumentList,
const ANTLRTokenPtr& errTok,
JLStr& specializationNameReturn,
CPPTypeRefI& specializationTypeReturn
)
{
CPPScopeRefI containingScope;
// Lookup a template declaration under this name, to
// determine whether it is a class or function template.
// Search the scope stack for the desired name
bool done = false;
for (
CPPScopeStack::iterator stackIter = scopeStack->begin();
!done && stackIter != scopeStack->end();
stackIter++
)
{
containingScope = (*stackIter).GetScope();
CPPScope::DeclIterator iter;
for (
CPPDeclRefI tmpDecl = containingScope->FindDeclByName(name, iter);
tmpDecl.get() != 0;
tmpDecl = containingScope->NextDecl(iter)
)
{
if (tmpDecl->GetType()->GetFlavor() == CPPType::Templated)
{
// found the containing scope and declaration
if (tmpDecl->IsType())
{
// class template
return LookupClassSpecialization(
name,
containingScope,
templateArgumentList,
errTok,
specializationNameReturn,
specializationTypeReturn
);
} else {
// function template
return LookupFunctionSpecialization(
name,
containingScope,
templateArgumentList,
errTok,
specializationNameReturn,
specializationTypeReturn
);
}
} else if (!NameIsDecoratedName(tmpDecl->GetName(), containingScope->GetName()))
{
// Found a hiding declaration
// A declaration of a class name inside itself is not a hiding declaration.
done = true;
break;
}
}
if ((*stackIter).GetResolved())
{
// Don't search past resolved scopes
break;
}
}
// The template was not found or was hidden by another declaration
// Should we ever get here? Perhaps when the "template" keword is
// used to qualify an object member.
ReportError("'" + name + "' does not name a template", errTok);
specializationTypeReturn = LookupBuiltinType(CPPConst::tsVOID);
return false;
}