#include "Declaration.h"
#include "Type.h"
#include "utility.h"


NamedTypeDecl::NamedTypeDecl( const std::string &name, StorageClass sc, Type *base )
    : Parent( name, sc, LinkageSpec::Cforall ), base( base )
{
}

NamedTypeDecl::NamedTypeDecl( const TypeDecl &other )
    : Parent( other ), base( maybeClone( other.base ) )
{
    cloneAll( other.parameters, parameters );
    cloneAll( other.assertions, assertions );
}

NamedTypeDecl::~NamedTypeDecl()
{
    delete base;
    deleteAll( parameters );
    deleteAll( assertions );
}

void 
NamedTypeDecl::print( std::ostream &os, int indent ) const
{
    using namespace std;
    
    if( get_name() != "" ) {
	os << get_name() << ": a ";
    }
    if( get_storageClass() != NoStorageClass ) {
	os << storageClassName[ get_storageClass() ] << ' ';
    }
    os << typeString();
    if( base ) {
	os << " for ";
	base->print( os, indent );
    }
    if( !parameters.empty() ) {
	os << endl << string( indent, ' ' ) << "with parameters" << endl;
	printAll( parameters, os, indent+2 );
    }
    if( !assertions.empty() ) {
	os << endl << string( indent, ' ' ) << "with assertions" << endl;
	printAll( assertions, os, indent+2 );
    }
}

void 
NamedTypeDecl::printShort( std::ostream &os, int indent ) const
{
    using namespace std;
    
    if( get_name() != "" ) {
	os << get_name() << ": a ";
    }
    if( get_storageClass() != NoStorageClass ) {
	os << storageClassName[ get_storageClass() ] << ' ';
    }
    os << typeString();
    if( base ) {
	os << " for ";
	base->print( os, indent );
    }
    if( !parameters.empty() ) {
	os << endl << string( indent, ' ' ) << "with parameters" << endl;
	printAll( parameters, os, indent+2 );
    }
}

std::string TypedefDecl::typeString() const { return "typedef"; }
    
