//
// 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.
//
// TypeData.h -- 
//
// Author           : Rodolfo G. Esteves
// Created On       : Sat May 16 15:18:36 2015
// Last Modified By : Peter A. Buhr
// Last Modified On : Mon Oct  3 12:34:08 2016
// Update Count     : 142
//

#ifndef TYPEDATA_H
#define TYPEDATA_H

#include <bitset>

#include "ParseNode.h"
#include "SynTree/Type.h"

struct TypeData {
	enum Kind { Basic, Pointer, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
				SymbolicInst, Tuple, Typeof, Builtin, Unknown };

	struct Aggregate_t {
		DeclarationNode::Aggregate kind;
		const std::string * name;
		DeclarationNode * params;
		ExpressionNode * actuals;						// holds actual parameters later applied to AggInst
		DeclarationNode * fields;
		bool body;
	};

	struct AggInst_t {
		TypeData * aggregate;
		ExpressionNode * params;
	};

	struct Array_t {
		ExpressionNode * dimension;
		bool isVarLen;
		bool isStatic;
	};

	struct Enumeration_t {
		const std::string * name;
		DeclarationNode * constants;
	};

	struct Function_t {
		DeclarationNode * params;
		DeclarationNode * idList;						// old-style
		DeclarationNode * oldDeclList;
		StatementNode * body;
		bool hasBody;
		bool newStyle;
	};

	struct Symbolic_t {
		const std::string * name;
		bool isTypedef;									// false => TYPEGENname, true => TYPEDEFname
		DeclarationNode * params;
		ExpressionNode * actuals;
		DeclarationNode * assertions;
	};

	Kind kind;
	TypeData * base;
	DeclarationNode::BasicType basictype = DeclarationNode::NoBasicType;
	DeclarationNode::ComplexType complextype = DeclarationNode::NoComplexType;
	DeclarationNode::Signedness signedness = DeclarationNode::NoSignedness;
	DeclarationNode::Length length = DeclarationNode::NoLength;
	typedef std::bitset< DeclarationNode::NoQualifier > Qualifiers;
	Qualifiers qualifiers;
	DeclarationNode * forall;

		// Basic_t basic;
		Aggregate_t aggregate;
		AggInst_t aggInst;
		Array_t array;
		Enumeration_t enumeration;
		// Variable_t variable;
		Function_t function;
		Symbolic_t symbolic;
		DeclarationNode * tuple;
		ExpressionNode * typeexpr;
		// DeclarationNode::BuiltinType builtin;

	TypeData( Kind k = Unknown );
	~TypeData();
	void print( std::ostream &, int indent = 0 ) const;
	TypeData * clone() const;
};

Type * typebuild( const TypeData * );
TypeData * typeextractAggregate( const TypeData * td, bool toplevel = true );
Type::Qualifiers buildQualifiers( const TypeData * td );
Type * buildBasicType( const TypeData * );
PointerType * buildPointer( const TypeData * );
ArrayType * buildArray( const TypeData * );
AggregateDecl * buildAggregate( const TypeData * );
ReferenceToType * buildAggInst( const TypeData * );
NamedTypeDecl * buildSymbolic( const TypeData *, const std::string &name, DeclarationNode::StorageClass sc );
TypeDecl * buildVariable( const TypeData * );
EnumDecl * buildEnum( const TypeData * );
TypeInstType * buildSymbolicInst( const TypeData * );
TupleType * buildTuple( const TypeData * );
TypeofType * buildTypeof( const TypeData * );
Declaration * buildDecl( const TypeData *, const std::string &, DeclarationNode::StorageClass, Expression *, bool isInline, bool isNoreturn, LinkageSpec::Spec, Initializer * init = nullptr );
FunctionType * buildFunction( const TypeData * );

#endif // TYPEDATA_H

// Local Variables: //
// tab-width: 4 //
// mode: c++ //
// compile-command: "make install" //
// End: //
