-
Virgile Prevosto authoredVirgile Prevosto authored
ACSLLogicType.h 6.53 KiB
/**************************************************************************/
/* */
/* This file is part of Frama-Clang */
/* */
/* Copyright (C) 2012-2021 */
/* CEA (Commissariat à l'énergie atomique et aux énergies */
/* alternatives) */
/* */
/* you can redistribute it and/or modify it under the terms of the GNU */
/* Lesser General Public License as published by the Free Software */
/* Foundation, version 2.1. */
/* */
/* It is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU Lesser General Public License for more details. */
/* */
/* See the GNU Lesser General Public License version 2.1 */
/* for more details (enclosed in the file LICENSE). */
/* */
/**************************************************************************/
//
// Description:
// Definition of the ACSL logic types.
//
#ifndef ACSL_LogicTypeH
#define ACSL_LogicTypeH
#include "ACSLParser.h"
// #include "DescentParse.h"
#include "Clang_utils.h"
extern "C" {
#include "intermediate_format.h"
} // end of extern "C"
namespace Acsl {
// true if v2 is compatible with v1, i.e. is a subtype of v1
// note that we don't use inheritance relation here to check for
// compatibility.
bool logic_type_compatible(
logic_type v1, logic_type v2, Parser::Arguments& context);
bool equivalent_int_kind(ikind i1, ikind i2, Parser::Arguments& context);
bool compatible_int_kind(ikind i1, ikind i2, Parser::Arguments& context);
bool compatible_float_kind(fkind f1, fkind f2);
inline bool isFloating(typ source) { return source->tag_typ == FLOAT; }
bool is_type_synonym(logic_type_info info);
logic_type extract_synonym_def(logic_type_info info);
/*!
builds a logic type from a C/C++ type definition.
@param type must be the declaration of a C/C++ type name
*/
logic_type from_c_named_type(
clang::NamedDecl const* type, const Clang_utils* utils);
/*! returns the type of the sets of elements of <base_type>.
<base_type> is not duplicated. It must thus not be accessed directly
by the caller afterwards.
*/
logic_type make_set_type(logic_type base_type);
/*! returns the type of elements of <set_type>, which must be a type of
sets of elements.
*/
logic_type remove_set_type(logic_type set_type);
std::string str(logic_type typ);
//#define strlist(C) { list cc = C; stsd::ostringstream s; while (cc) s << str(((logic_arg_decl)cc->element.container)->la_type) << " "; cc = cc->next; }
std::string str(list typs);
/*! @class LogicType
* @brief Component that parses a logic_type with a state machine.
*
* The state is defined by the Parser::State::point() method and has
* additional information within the fields _qualification, _declContext,
* _sumIdentifier. \n \n
* Depending on the constructor used, the local parsing method readToken
* builds a logic_type within the _typeResult field or a logic_type_def
* within the _typedefResult field. The constructor
* LogicType(qualified_name superTypeName) is used to build sum types
* and it is the one that produces the logic_type_def result.
*/
class LogicType : public ::Parser::Base::RuleResult, public ::Parser::Base {
private:
qualified_name _superTypeName; //!< If defined, name of the sum type.
logic_type _typeResult;
//!< Expected result with a component defined by the default constructor.
logic_type_def _typedefResult;
//!< Expected result with a component built with LogicType(qualified_name).
GlobalContext::NestedContext* _qualification; //!< Logic parsed qualification
const clang::DeclContext* _declContext; //!< C++ parsed qualification
bool _seenInt; //<! true when we have seen an explicit 'int' specifier
bool _seenSigned; //<! true when we have seen an explicit 'signed' specifier
bool _doesStopSuffix;
//!< Does stop the parsing as son as a logic_type is parsed.
location _loc; //!< Location of the type, used to extend the caller location.
void absorbLoc(location l) { if (_loc) free_location(_loc); _loc = l; }
std::string _sumIdentifier; //!< Identifier parsed after a '|' token.
bool unspecifiedKind() {
return
!_seenInt && _typeResult &&
_typeResult->tag_logic_type == LINT &&
(_typeResult->cons_logic_type.Lint.kind == IINT ||
_typeResult->cons_logic_type.Lint.kind == IUINT);
}
public:
LogicType()
: _superTypeName(NULL), _typeResult(NULL), _typedefResult(NULL),
_qualification(NULL), _declContext(NULL), _seenInt(false),
_seenSigned(false), _doesStopSuffix(false),
_loc(NULL) {}
LogicType(qualified_name superTypeName)
: _superTypeName(superTypeName), _typeResult(NULL), _typedefResult(NULL),
_qualification(NULL), _declContext(NULL), _seenInt(false),
_seenSigned(false), _doesStopSuffix(false),
_loc(NULL) {}
~LogicType()
{ if (_typeResult) free_logic_type(_typeResult);
if (_typedefResult) free_logic_type_def(_typedefResult);
if (_loc) free_location(_loc);
}
ReadResult readToken(Parser::State& state, Parser::Arguments& argument);
void setType(logic_type typeResult, location loc)
{ assert(!_typeResult && !_loc);
_typeResult = typeResult;
_loc = copy_loc(loc);
}
void setStopOnSuffix() { _doesStopSuffix = true; }
location extractLocation()
{ location result = _loc; _loc = NULL; return result; }
logic_type extractType()
{ assert(!_typedefResult);
logic_type result = _typeResult;
_typeResult = NULL;
return result;
}
logic_type_def extractTypeDef()
{ logic_type_def result;
if (_typedefResult) {
result = _typedefResult;
_typedefResult = NULL;
}
else {
assert(_typeResult);
result = logic_type_def_LTsyn(_typeResult);
_typeResult = NULL;
};
return result;
}
};
} // end of namespace Acsl
#endif // ACSL_LogicTypeH