1#include "sageInterfaceAda.h"
2#include "sageInterface.h"
4#include "sageBuilder.h"
11#include <boost/lexical_cast.hpp>
12#include <boost/algorithm/string.hpp>
13#include <boost/algorithm/string/predicate.hpp>
15#include "Rose/Diagnostics.h"
33 bool stringeq(
const std::string& lhs,
const std::string& rhs)
35 return boost::iequals(lhs, rhs);
42 const std::string attrname =
"class";
44 return ::si::Ada::isAttribute(attr, attrname);
50 return attr && isClassAttribute(*attr);
55 const std::string attrname =
"range";
57 return ::si::Ada::isAttribute(attr, attrname);
62 return attr && isRangeAttribute(*attr);
75 if (defdcl !=
nullptr) dcl = defdcl;
85 return SG_DEREF(dominant_declaration(n).get_base_type());
95 ReturnType descend(
SgType* n);
98 void handle(
SgNode& n) { SG_UNEXPECTED_NODE(n); }
101 void handle(
SgType&) { res =
nullptr; }
105 void handle(
SgAdaSubtype& n) { res = descend(n.get_base_type()); }
107 void handle(
SgTypedefType& n) { res = descend(&base_type(n)); }
108 void handle(
SgModifierType& n) { res = descend(n.get_base_type()); }
109 void handle(
SgAdaFormalType& n) { res = descend(n.get_formal_type()); }
114 void handle(
SgRangeType& n) { res = descend(n.get_base_type()); }
124 ArrayType::find(
SgType* n)
131 ArrayType::ReturnType
132 ArrayType::descend(
SgType* n)
134 return ArrayType::find(n);
143 ReturnType descend(
SgNode* n);
146 void handle(
SgNode& n) { SG_UNEXPECTED_NODE(n); }
155 if (isRangeAttribute(n))
174 void handle(
SgTypedefType& n) { res = descend(&base_type(n)); }
175 void handle(
SgAdaFormalType& n) { res = descend(n.get_formal_type()); }
178 void handle(
SgRangeType& n) { res = descend(n.get_base_type()); }
184 res = descend(
range->get_range());
188 ASSERT_not_null(isSgAdaNullConstraint(n.get_constraint()));
189 res = descend(n.get_base_type());
196 return SG_DEREF(descend(n));
200 DimRange::descend(
SgNode* n)
218 void handle(
SgNode& n) { SG_UNEXPECTED_NODE(n); }
225 void handle(
SgTypedefType& n) { res = descend(&base_type(n)); }
226 void handle(
SgModifierType& n) { res = descend(n.get_base_type()); }
227 void handle(
SgAdaFormalType& n) { res = descend(n.get_formal_type()); }
230 void handle(
SgRangeType& n) { res = descend(n.get_base_type()); }
239 if (isSgAdaNullConstraint(constraint))
241 res = descend(n.get_base_type());
247 SgExpressionPtrList& idxlst = idx.get_indexRanges();
249 for (
size_t i = 0; i < idxlst.size(); ++i)
253 res.dims().push_back(&DimRange::find(expr));
256 res.constrained(
true);
262 SgExpressionPtrList& idxlst = idx.get_expressions();
264 res.dims().insert(res.dims().end(), idxlst.begin(), idxlst.end());
265 res.constrained(!n.get_is_variable_length_array());
270 ArrayBounds::ReturnType
274 return ArrayBounds::ReturnType{};
276 ArrayBounds::ReturnType res{
baseType, {},
false};
281 ArrayBounds::ReturnType
282 ArrayBounds::descend(
SgType* n)
289 void handle(
const SgNode& n) { SG_UNEXPECTED_NODE(n); }
293 static const char*
const msg =
"sageInterface::ada: Expected constant integral value, got ";
298 void handle(
const SgShortVal& n) { res = n.get_value(); }
299 void handle(
const SgIntVal& n) { res = n.get_value(); }
300 void handle(
const SgLongIntVal& n) { res = n.get_value(); }
315 RangeExp(
size_t whichDimension)
316 : base(), dim(whichDimension)
321 find(
SgNode* n,
size_t dim);
326 void notFound()
const { ROSE_ASSERT(!res); }
328 size_t dimension()
const
330 ASSERT_require(dim > 0);
338 void handle(
SgNode& n) { SG_UNEXPECTED_NODE(n); }
344 void handle(
SgType&) { notFound(); }
358 res = find(n.get_indexRanges().at(dimension()), 1);
363 SgNode* constraint = n.get_constraint();
365 res = descend(constraint ? constraint : n.get_base_type());
370 if (::si::Ada::unconstrained(n))
375 res = find(exprlst.get_expressions().at(dimension()), 1);
379 void handle(
SgTypedefType& n) { res = descend(&base_type(n)); }
382 void handle(
SgRangeType& n) { res = descend(n.get_base_type()); }
389 RangeExp::find(
SgNode* n,
size_t dim)
395 RangeExp::descend(
SgNode* n)
403 ReturnType find(
SgType* n);
408 void handle(
const SgNode& n) { SG_UNEXPECTED_NODE(n); }
409 void handle(
const SgType&) { }
411 void handle(
const SgNamedType& n) { res = n.get_declaration(); }
413 void handle(
const SgAdaSubtype& n) { res = descend(n.get_base_type()); }
414 void handle(
const SgModifierType& n) { res = descend(n.get_base_type()); }
415 void handle(
const SgAdaDerivedType& n) { res = descend(n.get_base_type()); }
416 void handle(
const SgRangeType& n) { res = descend(n.get_base_type()); }
419 BaseTypeDecl::ReturnType
420 BaseTypeDecl::find(
SgType* n)
425 BaseTypeDecl::ReturnType
426 BaseTypeDecl::descend(
SgType* n)
431 void convertSymbolTablesToCaseSensitive_internal(
SgNode* node)
433 using SymbolTableEntry = std::pair<const SgName, SgSymbol*>;
434 using TmpSymbolTableEntry = std::pair<SgName, SgSymbol*>;
437 if (!scopestmt)
return;
443 const size_t mapsize = symap.size();
446 std::vector<TmpSymbolTableEntry> tmp;
449 for (SymbolTableEntry& el : symap)
453 sytable.setCaseInsensitive(
false);
456 for (TmpSymbolTableEntry& elTmp : tmp)
459 ASSERT_require(symap.size() == mapsize);
462 template <
class SageDeclarationStatement,
class SageScopeStatement>
464 getSpecFromBody(
const SageScopeStatement& defn)
465 ->
decltype(std::declval<SageDeclarationStatement>().get_spec()->get_definition())
467 const SageDeclarationStatement* bodyDecl =
dynamic_cast<const SageDeclarationStatement*
>(defn.get_parent());
468 ASSERT_not_null(bodyDecl);
470 const auto* specDecl = bodyDecl->get_spec();
471 ASSERT_not_null(specDecl);
473 return specDecl->get_definition();
476 template <
class SageDeclarationStatement,
class SageScopeStatement>
478 getBodyFromSpec(
const SageScopeStatement& defn)
479 ->
decltype(std::declval<SageDeclarationStatement>().get_body()->get_definition())
481 const SageDeclarationStatement* specDecl =
dynamic_cast<const SageDeclarationStatement*
>(defn.get_parent());
482 ASSERT_not_null(specDecl);
484 const auto* bodyDecl = specDecl->get_body();
487 return bodyDecl ? bodyDecl->get_definition() :
nullptr;
496 void handle(
const SgNode& n) { SG_UNEXPECTED_NODE(n); }
498 void handle(
const SgAdaPackageBody& n) { res = getSpecFromBody<SgAdaPackageBodyDecl>(n); }
503 CanonicalScope::ReturnType
511 return dcl.get_declarationModifier().get_accessModifier().isPrivate();
519 const std::string roseOperatorPrefix =
"operator";
520 const std::string packageStandardName =
"Standard";
521 const std::string durationTypeName =
"Duration";
522 const std::string exceptionName =
"Exception";
529 const auto lim = lst.end();
530 const auto pos = std::find_if( lst.begin(), lim,
533 return stringeq(nm->get_name(), n.get_name());
537 ASSERT_require(pos != lim);
538 return SG_DEREF(*pos);
543 return CanonicalScope::find(scope);
553 ASSERT_not_null(lhs);
554 ASSERT_not_null(rhs);
556 return ( (lhs == rhs)
570 SgExpressionPtrList& exprlst = args.get_expressions();
572 if (exprlst.size() == 0)
575 ASSERT_require(exprlst.size() == 1);
578 ASSERT_require(res <= std::numeric_limits<int>::max());
585 ASSERT_not_null(args);
598 return def && isPrivate(*def);
609 if (atype ==
nullptr)
610 return {
nullptr, {},
false };
618 return ArrayBounds::find(&atype, ArrayType::find(&atype));
628 return originalSymbol(*alisy);
630 return SG_DEREF(orig);
636 return originalSymbol(*alisy);
641 void appendAllVariableSymbols(
const SgScopeStatement& scope, std::vector<RecordField>& res)
646 for (
const auto& entry : allsyms)
648 const SgSymbol& sym = SG_DEREF(entry.second);
649 const SgSymbol& orig = originalSymbol(sym);
651 if ( isSgVariableSymbol(&orig))
652 res.emplace_back(&sym);
656 void appendAllDiscriminantsFromParents(
const SgClassDefinition&, std::vector<RecordField>&)
661 mlog[
TRACE] <<
"collecting discriminants from parents not implemented.."
667 RecordField::record()
const
669 const SgVariableSymbol& sym = SG_DEREF( isSgVariableSymbol(&originalSymbol()) );
672 return SG_DEREF( isSgClassDefinition(var.get_scope()) );
676 RecordField::originalSymbol()
const
678 return SageInterface::Ada::originalSymbol(symbol());
682 RecordField::symbol()
const
685 return *std::get<0>(*
this);
689 RecordField::discriminant()
const
695 std::vector<RecordField>
701 std::vector<RecordField> res;
703 appendAllVariableSymbols(rec, res);
707 appendAllVariableSymbols(SG_DEREF(disc->get_discriminantScope()), res);
708 appendAllDiscriminantsFromParents(rec, res);
714 std::vector<RecordField>
717 if (rec ==
nullptr)
return {};
724 std::vector<IfExpressionInfo>
727 std::vector<IfExpressionInfo> res;
743 res.emplace_back(
nullptr, SG_DEREF(cond).get_false_exp());
751 return SG_DEREF(es).get_expression();
754 std::vector<IfStatementInfo>
757 std::vector<IfStatementInfo> res;
772 res.emplace_back(
nullptr, falseBranch);
781 if (!isRangeAttribute(n))
784 const int dim = si::Ada::firstLastDimension(SG_DEREF(n.get_args()));
786 return RangeExp::find(n.get_object(), dim);
800 return ( isRangeAttribute(isSgAdaAttributeExp(e))
801 || isSgTypeExpression(e)
814 return ty.get_is_variable_length_array();
831 if (accty && !accty->get_is_anonymous())
835 mlog[TRACE] <<
"surprising non-anonymous access type." << std::endl;
838 return accty !=
nullptr;
845 if (!bodyDecl)
return nullptr;
847 return bodyDecl->get_spec();
853 return SG_DEREF(bodyDecl.get_spec());
858 return SG_DEREF(bodyDecl.get_specificationDeclaration());
868 return SG_DEREF(bodyDecl.get_specificationDeclaration());
879 if (!specDecl)
return nullptr;
881 return specDecl->get_body();
887 return SG_DEREF(specDecl.get_body());
892 return SG_DEREF(getSpecFromBody<SgAdaPackageBodyDecl>(body));
897 if (!body)
return nullptr;
899 return getSpecFromBody<SgAdaPackageBodyDecl>(*body);
904 return SG_DEREF(getBodyFromSpec<SgAdaPackageSpecDecl>(spec));
909 if (!spec)
return nullptr;
911 return getBodyFromSpec<SgAdaPackageSpecDecl>(*spec);
919 void handle(
const SgNode&) { }
920 void handle(
const SgAdaPackageSpec& n) { res = getBodyFromSpec<SgAdaPackageSpecDecl>(n); }
934 ASSERT_not_null(scope);
944 return isSgDeclarationStatement(s) ==
nullptr;
950 if (pdcl ==
nullptr)
return false;
952 const SgPragma& prgm = SG_DEREF(pdcl->get_pragma());
953 std::string prgName = boost::to_lower_copy(prgm.get_pragma());
955 return ( (prgName !=
"import")
956 && (prgName !=
"export")
957 && (prgName !=
"priority")
958 && (prgName !=
"volatile")
962 template <
class SageStatementPtrList>
963 auto findDeclarationLimit(SageStatementPtrList& list) ->
decltype(list.begin())
965 using IteratorType =
decltype(list.begin());
967 IteratorType beg = list.begin();
968 IteratorType lim = list.end();
969 IteratorType pos = std::find_if(beg, lim, isNormalStatement);
970 IteratorType prv = std::prev(pos);
973 while ((pos != beg) && isNondeclarativePragma(*prv))
976 prv = std::prev(pos);
983 SgStatementPtrList::const_iterator
986 return findDeclarationLimit(list);
989 SgStatementPtrList::const_iterator
995 SgStatementPtrList::const_iterator
1001 SgStatementPtrList::iterator
1004 return findDeclarationLimit(list);
1007 SgStatementPtrList::iterator
1013 SgStatementPtrList::iterator
1022 if (blk ==
nullptr)
return false;
1031 return std::distance(dcllimit, stmts.end()) == 1;
1058 ASSERT_not_null(rendcl);
1063 return SG_DEREF(
isGenericDecl(funref->getAssociatedFunctionDeclaration()));
1079 return getRenamedGenericDecl(renref->get_decl());
1088 return getRenamedGenericDecl(n.get_genericDeclaration());
1101 return isSgAdaGenericDecl(defn->get_parent());
1108 if (n ==
nullptr)
return nullptr;
1131 if (scope ==
nullptr)
return false;
1132 if (scope->
get_parent() == decl)
return true;
1139 if (n ==
nullptr)
return false;
1141 return isLogicalChildScopeOfDecl(sg::ancestor<SgScopeStatement>(n), decl);
1149 return gendcl && isLogicalChildOfDecl(&n, gendcl);
1159 return SG_DEREF(n.get_discriminants()).get_parameters().size() == 0;
1170 return isSgAdaDiscriminatedTypeDecl(n.
get_parent());
1181 using Iterator = SgExpressionPtrList::const_iterator;
1183 const SgExpressionPtrList& exprs = lst.get_expressions();
1184 Iterator aa = exprs.begin();
1185 Iterator zz = exprs.end();
1190 ini = isSgAdaAncestorInitializer(*aa);
1216 return isSgAdaPackageSpecDecl(unitref->get_decl());
1228 return isSgTypeVoid(ty.get_return_type()) ==
nullptr;
1238 return isSgTypeVoid(ty.get_return_type()) ==
nullptr;
1254 const SgFunctionType* res = inhsy ? inhsy->get_derivedFunctionType()
1255 : isSgFunctionType(funsy.
get_type());
1257 return SG_DEREF(res);
1283 bool isExceptionType(
const SgType& n)
1286 if (ty ==
nullptr || (!stringeq(ty->
get_name().getString(), exceptionName)))
1291 return definedInStandard(SG_DEREF(dcl));
1297 const SgType* ty = dcl.get_type();
1299 return ty && (!isSgTypeVoid(ty)) && (!isExceptionType(*ty));
1311 const SgType* ty = dcl.get_type();
1313 return ty && isExceptionType(*ty);
1331 return isSgAdaModularType(ty);
1342 return isSgTypeLongLong(ty);
1352 return isSgTypeLongDouble(ty);
1362 return isSgAdaDiscreteType(ty);
1372 return isSgTypeFixed(ty);
1383 if (!boolTy)
return false;
1385 const SgEnumDeclaration* boolDcl = isSgEnumDeclaration(boolTy->get_declaration());
1387 return ( (boolDcl !=
nullptr)
1388 && (stringeq(boolDcl->
get_name().getString(),
"BOOLEAN"))
1389 && definedInStandard(*boolDcl)
1395 bool isScalarGenericType(
const SgType& ty)
1399 return formTy &&
isScalarType(formTy->get_formal_type());
1405 ty = si::Ada::typeRoot(
const_cast<SgType*
>(ty)).typerep();
1407 if (!ty)
return false;
1419 || isScalarGenericType(*ty)
1430 si::Ada::FlatArrayType arrinfo = si::Ada::getArrayTypeInfo(
const_cast<SgType*
>(ty));
1433 if ((arrty ==
nullptr) || (arrinfo.dims().size() > 1))
1436 SgType const* elmty = si::Ada::typeRoot(arrty->get_base_type()).typerep();
1438 if (elmty ==
nullptr)
return false;
1440 return ( si::Ada::isModularType(*elmty)
1441 || si::Ada::isIntegerType(*elmty)
1443 || si::Ada::isDiscreteType(*elmty)
1446 || isSgEnumType(elmty)
1463 TypeResolver(std::function<
bool (
const SgType&)> typetest)
1464 : base(), checker(typetest)
1467 bool descend(
const SgType*);
1469 void handle(
SgNode& n) { SG_UNEXPECTED_NODE(n); }
1479 void handle(
SgModifierType& n) { res = descend(n.get_base_type()); }
1480 void handle(
SgAdaSubtype& n) { res = descend(n.get_base_type()); }
1482 void handle(
SgTypedefType& n) { res = descend(&base_type(n)); }
1485 void handle(
SgRangeType& n) { res = descend(n.get_base_type()); }
1493 bool TypeResolver::descend(
const SgType* ty)
1495 return ty &&
sg::dispatch(TypeResolver{std::move(checker)}, ty);
1515 return delta && delta->get_isDecimal();
1522 return isFixedType(sub->get_base_type()) && isDecimalConstraint(sub->get_constraint());
1535 return dcl.get_declarationModifier().isAdaSeparate();
1555 template <
class SageNodeSequence>
1559 using iterator =
typename SageNodeSequence::const_reverse_iterator;
1561 auto sameFirstNondefining = [key](
typename SageNodeSequence::value_type ptr) ->
bool
1568 iterator lim = seq.rend();
1569 iterator pos = std::find_if(seq.rbegin(), lim, sameFirstNondefining);
1571 return pos != lim ? isSgFunctionDeclaration(*pos) : nullptr;
1579 : findSecondaryFunctionDecl(scope.getStatementList(), key);
1585 ASSERT_not_null(nondef);
1597 return nondef->get_declarationModifier().isAdaSeparate();
1602 return ( (n.get_definition() !=
nullptr)
1623 static std::map<SgType*, SgArrayType*> m;
1631 return SG_DEREF(res);
1642 if (args ==
nullptr)
return false;
1644 const SgExpressionPtrList& lst = args->get_expressions();
1645 const auto lim = lst.end();
1647 return lim != std::find_if(lst.begin(), lim,
denotesRange);
1650 template <
class ResolverT>
1653 TypeDescription descend(
SgType* ty)
1655 return static_cast<ResolverT&
>(*this).descend(ty);
1658 void handle(
SgNode& n) { SG_UNEXPECTED_NODE(n); }
1664 void handle(
SgTypedefType& n) { res = descend(&base_type(n)); }
1667 void handle(
SgModifierType& n) { res = descend(n.get_base_type()); }
1671 void handle(
SgRangeType& n) { res = descend(n.get_base_type()); }
1676 TypeDescription dt = descend(n.get_base_type());
1677 std::vector<SgAdaTypeConstraint*> constr = std::move(dt).toplevelConstraints();
1679 constr.insert(constr.begin(), n.get_constraint());
1681 res = TypeDescription{dt.typerep_ref(), dt.polymorphic(), std::move(constr)};
1685 void handle(
SgAdaFormalType& n) { res = descend(n.get_formal_type()); }
1690 struct DerefedType : TypeDescResolver<DerefedType>
1692 using base = TypeDescResolver<DerefedType>;
1694 TypeDescription descend(
SgType* ty);
1699 void handle(
SgAdaAccessType& n) { res = TypeDescription{n.get_base_type()}; }
1702 void handle(
SgPointerType& n) { res = TypeDescription{n.get_base_type()}; }
1706 DerefedType::descend(
SgType* ty)
1712 bool isElementaryInteger(
const SgType* ty) {
return isSgTypeLongLong(ty) !=
nullptr; }
1713 bool isElementaryReal (
const SgType* ty) {
return isSgTypeLongDouble(ty) !=
nullptr; }
1715 bool isElementaryFixed (
const SgType* ty)
1719 return fx && (fx->get_fraction() ==
nullptr) && (fx->get_scale() ==
nullptr);
1724 bool isElementaryType(
const SgType* ty)
1726 return ( isElementaryInteger(ty)
1727 || isElementaryReal(ty)
1728 || isElementaryFixed(ty)
1737 if (lhs ==
nullptr)
return rhs;
1738 if (rhs ==
nullptr)
return lhs;
1741 if (isSgTypeDefault(lhs))
return rhs;
1742 if (isSgTypeDefault(rhs))
return lhs;
1746 if (isElementaryType(lhs))
return rhs;
1747 if (isElementaryType(rhs))
return lhs;
1750 if (lhs == rhs)
return lhs;
1758 if (
SgType* com = simpleCommonDenominator(lhs, rhs))
1761 TypeDescription lhsDesc =
typeRoot(lhs);
1762 TypeDescription rhsDesc =
typeRoot(rhs);
1764 if (
SgType* com = simpleCommonDenominator(lhsDesc.typerep(), rhsDesc.typerep()))
1772 mlog[
WARN] <<
"*FLAW* commonDenominator: type mismatch "
1773 << lhs <<
" " <<
typeid(*lhs).name() <<
" " << (lhsty ? lhsty->
get_name() :
SgName{})
1775 << rhs <<
" " <<
typeid(*rhs).name() <<
" " << (rhsty ? rhsty->
get_name() :
SgName{})
1779 return lhsDesc.typerep();
1789 return arrty->get_base_type();
1796 void handle(
const SgNode& n) { SG_UNEXPECTED_NODE(n); }
1805 res = TypeDescription{n.
get_type()};
1807 if (isSgAutoType(res.typerep()))
1814 res =
typeRoot(SG_DEREF(init->get_operand()).get_type());
1823 res = TypeDescription{accessTy};
1838 const bool slice = containsRange(idx);
1840 if (!slice) resty = arrayBaseType(resty);
1842 res = TypeDescription{resty};
1852 res = TypeDescription{lhs.
get_type()};
1857 res = TypeDescription{n.
get_type()};
1860 void handle(
const SgIntVal&) { res = TypeDescription{ integralType() }; }
1861 void handle(
const SgLongIntVal&) { res = TypeDescription{ integralType() }; }
1862 void handle(
const SgLongLongIntVal&) { res = TypeDescription{ integralType() }; }
1870 if (n.get_is16bitString()) strty = &
standardType(
"Wide_String");
1871 else if (n.get_is32bitString()) strty = &
standardType(
"Wide_Wide_String");
1874 ASSERT_not_null(strty);
1876 res = TypeDescription{strty};
1886 res = TypeDescription{ commonDenominator(truDesc.typerep(), falDesc.typerep()) };
1894 const bool polymorph = isClassAttribute(n);
1896 res = TypeDescription{ SG_DEREF(n.
get_type()), polymorph };
1914 return ty && ty->get_fromRootType();
1919 void handle(
SgNode& n) { SG_UNEXPECTED_NODE(n); }
1924 void handle(
SgTypeLongLong&) { res = TypeDescription{integralType()}; }
1926 void handle(
SgTypeFixed&) { res = TypeDescription{fixedType()}; }
1939 void handle(
SgTypeVoid& n) { res = TypeDescription{n}; }
1941 void handle(
SgAutoType& n) { res = TypeDescription{n}; }
1947 res = TypeDescription{n};
1953 void handle(
SgTypeBool& n) { res = TypeDescription{n}; }
1959 void handle(
SgTypeInt&) { res = TypeDescription{integralType()}; }
1960 void handle(
SgTypeLong&) { res = TypeDescription{integralType()}; }
1961 void handle(
SgTypeShort&) { res = TypeDescription{integralType()}; }
1963 void handle(
SgTypeFloat&) { res = TypeDescription{realType()}; }
1964 void handle(
SgTypeDouble&) { res = TypeDescription{realType()}; }
1965 void handle(
SgTypeFloat128&) { res = TypeDescription{realType()}; }
1968 void handle(
SgTypeChar& n) { res = TypeDescription{n}; }
1969 void handle(
SgTypeChar16& n) { res = TypeDescription{n}; }
1970 void handle(
SgTypeChar32& n) { res = TypeDescription{n}; }
1973 void handle(
SgClassType& n) { res = TypeDescription{n}; }
1974 void handle(
SgEnumType& n) { res = TypeDescription{n}; }
1983 res = TypeDescription{arrayType(find(n.get_base_type()).typerep())};
1994 void handle(
SgTypeNullptr&) { res = TypeDescription{pointerType()}; }
1995 void handle(
SgPointerType&) { res = TypeDescription{pointerType()}; }
1996 void handle(
SgAdaAccessType&) { res = TypeDescription{pointerType()}; }
2003 void handle(
SgModifierType& n) { res = find(n.get_base_type()); }
2004 void handle(
SgAdaSubtype& n) { res = find(n.get_base_type()); }
2009 void handle(
SgRangeType& n) { res = find(n.get_base_type()); }
2015 const bool useThisDecl = ( isSgAdaDerivedType(basety)
2016 || isSgAdaAccessType(basety)
2017 || isSgAdaModularType(basety)
2018 || isSgArrayType(basety)
2019 || fromRootType(isSgAdaSubtype(basety))
2023 res = useThisDecl ? TypeDescription{n} : find(basety);
2029 res = TypeDescription{n};
2042 TypeDescription find(
SgType* ty);
2046 RootTypeFinder::find(
SgType* ty)
2058 void handle(
const SgNode& n) { SG_UNEXPECTED_NODE(n); }
2070 if (isClassAttribute(n))
2072 res = find(tyex->get_type());
2080 void handle(
const SgType&) { }
2133 void handle(
const SgPointerType& n) { res = find(n.get_base_type()); }
2134 void handle(
const SgAdaAccessType& n) { res = find(n.get_base_type()); }
2141 void handle(
const SgModifierType& n) { res = find(n.get_base_type()); }
2142 void handle(
const SgAdaSubtype& n) { res = find(n.get_base_type()); }
2144 void handle(
const SgRangeType& n) { res = find(n.get_base_type()); }
2149 void handle(
const SgNamedType& n) { res = SG_DEREF(n.get_declaration()).get_scope(); }
2155 const bool useThisDecl = ( isSgAdaDerivedType(basety)
2156 || isSgAdaAccessType(basety)
2157 || isSgAdaModularType(basety)
2158 || isSgArrayType(basety)
2159 || fromRootType(isSgAdaSubtype(basety))
2167 res = dominant_declaration(n).get_scope();
2173 void handle(
const SgDeclType& n) { res = find(n.get_base_expression()); }
2182 associatedDeclaration_internal(
const SgType* ty,
int skipNumAccessTypes = -1);
2188 DeclFinder(
int skipLayers)
2189 : skipAccessLayers(skipLayers)
2194 void handle(
SgNode& n) { SG_UNEXPECTED_NODE(n); }
2199 void handle(
SgModifierType& n) { res = associatedDeclaration_internal(n.get_base_type(), skipAccessLayers); }
2200 void handle(
SgAdaSubtype& n) { res = associatedDeclaration_internal(n.get_base_type(), skipAccessLayers); }
2201 void handle(
SgAdaDerivedType& n) { res = associatedDeclaration_internal(n.get_base_type(), skipAccessLayers); }
2202 void handle(
SgPointerType& n) { res = fromBaseType(n.get_base_type()); }
2203 void handle(
SgAdaAccessType& n) { res = fromBaseType(n.get_base_type()); }
2204 void handle(
SgRangeType& n) { res = fromBaseType(n.get_base_type()); }
2211 void handle(
SgNamedType& n) { res = n.get_declaration(); }
2214 const int skipAccessLayers;
2218 DeclFinder::fromBaseType(
SgType* baseTy)
2220 if (skipAccessLayers == 0)
2223 return associatedDeclaration_internal(baseTy, (skipAccessLayers > 0) ? skipAccessLayers-1 : skipAccessLayers);
2227 associatedDeclaration_internal(
const SgType* ty,
int skipNumAccessTypes)
2229 return sg::dispatch(DeclFinder{ skipNumAccessTypes }, ty);
2237 void handle(
const SgNode& n) { SG_UNEXPECTED_NODE(n); }
2241 res = ReturnType{ nameOf(n), &
declOf(n),
nullptr, &n };
2249 dcl = gendcl->get_declaration();
2251 ASSERT_not_null(dcl);
2252 res = ReturnType{ nameOf(n), dcl,
nullptr, &n };
2257 res = ReturnType{ nameOf(n), n.get_decl(), n.get_decl(), &n};
2264 return SG_DEREF(stdpkg).get_definition();
2271 if (!toplevel)
return false;
2274 if (!pkgdcl)
return false;
2276 const std::string pkgname = boost::to_upper_copy(pkgdcl->get_name().getString());
2278 return ( pkgname ==
"ADA"
2279 || pkgname ==
"INTERFACES"
2280 || pkgname ==
"SYSTEM"
2281 || pkgname ==
"STANDARD"
2290 SgType& TypeDescription::typerep_ref()
const
2292 return SG_DEREF(typerep());
2298 return RootTypeFinder::find(&ty);
2319 return acc->get_base_type();
2328 return ptr->get_base_type();
2354 bool isFixedSpecialOperator(
const std::string& opname)
2356 return opname ==
"*" || opname ==
"/";
2361 bool isFixedSpecial(
const std::string& opname,
const SgTypePtrList& argtypes)
2363 if (!isFixedSpecialOperator(opname))
2366 ROSE_ASSERT(argtypes.size() >= 1);
2372 bool isFixedSpecial(
const std::string& opname,
const SgType& ty)
2374 return isFixedSpecial(opname, {
const_cast<SgType*
>(&ty) });
2379 operatorArgumentWithNamedRootIfAvail(
const SgTypePtrList& argtypes)
2381 ROSE_ASSERT(argtypes.size() == 1 || argtypes.size() == 2);
2383 SgType* lhsty = argtypes.front();
2387 if (argtypes.size() == 1 || isSgNamedType(
typeRoot(lhsty).typerep()))
2388 return { lhsty, 0 };
2390 SgType* rhsty = argtypes.back();
2394 if (isSgNamedType(
typeRoot(rhsty).typerep()))
2395 return { rhsty, argtypes.size()-1 };
2397 return { lhsty, 0 };
2404 ROSE_ASSERT(argtypes.size());
2406 if (isFixedSpecial(opname, argtypes))
2412 DominantArgInfo dominantType = operatorArgumentWithNamedRootIfAvail(argtypes);
2420 if (isFixedSpecial(opname, ty))
2429 if (ty ==
nullptr)
return nullptr;
2437 return DeclScopeFinder::find(ty);
2447 return associatedDeclaration_internal(&ty);
2456 std::vector<ImportedUnitResult>
2459 std::vector<ImportedUnitResult> res;
2460 const SgExpressionPtrList& lst = impdcl.get_import_list();
2462 std::transform( lst.begin(), lst.end(),
2463 std::back_inserter(res),
2466 return sg::dispatch(ImportedUnit{}, exp);
2487 bool isOperatorName(
const std::string&
id)
2489 static std::set<std::string> adaops =
2490 {
"+",
"-",
"*",
"/",
"**",
"REM",
"MOD",
"ABS"
2491 ,
"=",
"/=",
"<",
">",
"<=",
">="
2492 ,
"NOT",
"AND",
"OR",
"XOR",
"&"
2495 const std::string canonicalname = boost::to_upper_copy(
id);
2497 return adaops.find(canonicalname) != adaops.end();
2503 if (name.rfind(si::Ada::roseOperatorPrefix, 0) != 0)
2506 const std::string op = name.substr(si::Ada::roseOperatorPrefix.size());
2508 if (!isOperatorName(op))
2516 static const std::string quotes =
"\"";
2518 if (name.rfind(si::Ada::roseOperatorPrefix, 0) != 0)
2521 const std::string op = name.substr(si::Ada::roseOperatorPrefix.size());
2523 if (!isOperatorName(op))
2526 return quotes + op + quotes;
2532 void add(
SgNode* n) { res.push_back(n); }
2533 void add_opt(
SgNode* n) {
if (n) add(n); }
2535 template <
class SageNode>
2536 void handleWithGetType(SageNode& n)
2543 void handle(
SgNode& n) { SG_UNEXPECTED_NODE(n); }
2547 void handle(
SgCastExp& n) { handleWithGetType(n); }
2554 add(n.get_specified_type());
2566 add(n.get_recordType());
2573 add(n.get_enumType());
2589 add(n.get_base_type());
2596 add(SG_DEREF(n.get_type()).get_formal_type());
2605 void handle(
SgDeclType& n) { add(n.get_base_expression()); }
2607 void handle(
SgRangeType& n) { add(n.get_base_type()); }
2613 add(n.get_base_type());
2614 add_opt(n.get_constraint());
2619 SgTypePtrList& lst = n.get_types();
2621 std::copy( lst.begin(), lst.end(), std::back_inserter(res) );
2626 add(n.get_dim_info());
2627 add(n.get_base_type());
2639 add(n.get_digits());
2640 add_opt(n.get_subConstraint());
2646 add_opt(n.get_subConstraint());
2651 SgExpressionPtrList& lst = n.get_indexRanges();
2653 std::copy( lst.begin(), lst.end(), std::back_inserter(res) );
2658 SgExpressionPtrList& lst = n.get_discriminants();
2660 std::copy( lst.begin(), lst.end(), std::back_inserter(res) );
2672 void visit(
SgNode*)
override;
2675 std::function<void(
SgNode*)> fn;
2694 ASSERT_not_null(dcl);
2698 return fileInfo.get_filenameString() == mainFile;
2702 return !declaredInMainFile(dcl);
2706 SgDeclarationStatementPtrList::iterator zz = lst.end();
2707 SgDeclarationStatementPtrList::iterator first = std::find_if(lst.begin(), zz, declaredInMainFile);
2708 SgDeclarationStatementPtrList::iterator limit = std::find_if(first, zz, notDeclaredInMainFile);
2710 return std::make_pair(first, limit);
2727 : prefix(useLineComments ?
"//" :
"/*"),
2728 suffix(useLineComments ?
"" :
"*/"),
2729 commentKind(useLineComments ? PreprocessingInfo::CplusplusStyleComment : PreprocessingInfo:: C_StyleComment)
2735 void operator()(
SgNode*)
const;
2739 const std::string prefix;
2740 const std::string suffix;
2741 const PreprocessingInfo::DirectiveType commentKind;
2749 void CommentCxxifier::operator()(
SgNode* n)
const
2752 if (node ==
nullptr)
return;
2755 if (prepInfo ==
nullptr)
return;
2759 ASSERT_not_null(ppinfo);
2761 if (ppinfo->getTypeOfDirective() != PreprocessingInfo::AdaStyleComment)
continue;
2763 std::string comment = ppinfo->getString();
2765 ROSE_ASSERT(comment.rfind(
"--", 0) == 0);
2766 comment.replace(0, 2, prefix);
2767 comment.append(suffix);
2768 ppinfo->setString(comment);
2769 ppinfo->setTypeOfDirective(commentKind);
2776 : convertOperatorCalls(convOperatorCalls), convertNamedArguments(convNamedArgs)
2781 void executeTransformations()
const;
2783 void operator()(
SgNode*);
2786 using replacement_t = std::tuple<SgFunctionCallExp*, std::string>;
2788 std::vector<replacement_t> work;
2789 const bool convertOperatorCalls;
2790 const bool convertNamedArguments;
2802 return SG_DEREF(args).get_expressions().size();
2810 return isSgNullExpression(SG_DEREF(args).get_expressions().at(0));
2813 void FunctionCallToOperatorConverter::operator()(
SgNode* n)
2816 if ( (fncall ==
nullptr)
2817 || ((!convertOperatorCalls) && (!fncall->get_uses_operator_syntax()))
2818 || (arity(*fncall) > 2)
2824 if (fndecl ==
nullptr || (!definedInStandard(*fndecl)))
return;
2827 std::string op = convertRoseOperatorNameToAdaOperator(fndecl->get_name());
2828 if (op.empty())
return;
2832 work.emplace_back(fncall, std::move(op));
2835 using CallToOperatorTransformer = std::function<
SgExpression&(SgExpressionPtrList)>;
2837 template <
class BinaryBuilderFn>
2838 CallToOperatorTransformer tf2(BinaryBuilderFn fn)
2840 return [fn](SgExpressionPtrList operands) ->
SgExpression&
2842 ROSE_ASSERT(operands.size() == 2);
2846 ASSERT_not_null(lhs);
2847 ASSERT_not_null(rhs);
2854 return SG_DEREF(fn(lhs, rhs));
2858 template <
class UnaryBuilderFn>
2859 CallToOperatorTransformer tf1(UnaryBuilderFn fn)
2861 return [fn](SgExpressionPtrList operands) ->
SgExpression&
2863 ROSE_ASSERT(operands.size() == 1);
2866 ASSERT_not_null(arg);
2870 return SG_DEREF(fn(arg));
2877 return SG_DEREF(n.get_args()).get_expressions();
2881 namedArgumentPosition(
const SgInitializedNamePtrList& paramList,
const std::string& name)
2883 SgInitializedNamePtrList::const_iterator aaa = paramList.begin();
2884 SgInitializedNamePtrList::const_iterator zzz = paramList.end();
2885 SgInitializedNamePtrList::const_iterator pos = std::find_if( aaa, zzz,
2889 return stringeq(name, n->get_name().getString());
2898 throw std::logic_error(std::string{
"unable to find argument position for "} + name);
2901 return std::distance(aaa, pos);
2907 const std::size_t sz = pos;
2909 if (container.size() < sz) container.resize(sz, val);
2912 void FunctionCallToOperatorConverter::executeTransformations()
const
2914 using OperandExtractor =
decltype(&simpleArgumentExtractor);
2915 using BuilderMap = std::map<std::string, CallToOperatorTransformer>;
2936 static const BuilderMap tfFn1 = { {
"not", tf1(&
sb::buildNotOp) }
2940 , {
"-", tf1(&sb::buildUnaryExpression<SgMinusOp>) }
2944 : simpleArgumentExtractor;
2946 for (
const replacement_t& r : work)
2949 const int numargs = arity(orig);
2950 ROSE_ASSERT(numargs == 1 || numargs == 2);
2951 std::string
const key = boost::to_lower_copy(std::get<1>(r));
2952 SgExpression& repl = numargs == 1 ? tfFn1.at(key)(operandExtractor(orig,
false))
2953 : tfFn2.at(key)(operandExtractor(orig, false));
2969 if (!first)
return false;
2971 const SgTypedefType* ty = isSgTypedefType(first->get_type());
2973 return ty && (stringeq(ty->
get_name().getString(), si::Ada::exceptionName));
2981 return declaresException(n) ? &n :
nullptr;
2987 return (n && declaresException(*n)) ? n :
nullptr;
2993 return declaresException(n) ? &n :
nullptr;
2999 return (n && declaresException(*n)) ? n :
nullptr;
3006 return assocfn->get_parameterList();
3008 const SgExpression& target = SG_DEREF(n.get_function());
3015 return routty->get_parameterList();
3022 return routty->get_parameterList();
3040 baseTypeOfClass(
const SgClassType& n,
bool publicInfoPreferred =
false)
3052 const bool privateDecl = isPrivate(nondefdcl);
3053 const bool privateDefn = isPrivate(defdcl);
3057 if ((privateDecl == privateDefn) || !publicInfoPreferred)
3062 if (bases.size()) basecl = bases.front();
3067 if (basecl ==
nullptr)
3069 basecl = nondefdcl.get_adaParentType();
3075 res =
typeOfExpr(basexp->get_base_class_exp()).typerep();
3081 res = basedcl.get_type();
3094 auto lim = path.end();
3096 return lim != std::find(path.begin(), lim, dcl.
get_scope());
3106 ASSERT_not_null(res);
3118 if (orig.get_return_type() != derv.get_return_type())
3119 return assertNamedType(orig.get_return_type());
3121 SgTypePtrList& origParams = SG_DEREF(orig.get_argument_list()).get_arguments();
3122 SgTypePtrList& dervParams = SG_DEREF(derv.get_argument_list()).get_arguments();
3123 ASSERT_require(origParams.size() == dervParams.size());
3125 auto iterpair = std::mismatch( origParams.begin(), origParams.end(), dervParams.begin() );
3126 ASSERT_require(iterpair.first != origParams.end());
3128 return assertNamedType(*iterpair.first);
3132 std::vector<const SgType*>
3135 std::vector<const SgType*> res;
3140 res.push_back(clsty);
3146 clsty = isSgClassType(baseTypeOfClass(*clsty,
true ));
3160 if (drvdeclDef && (!isPrivate(*drvdeclDef)))
3168 if (drvclssNondef ==
nullptr)
3169 return isPrivate(drvdeclNondef);
3172 std::vector<const SgType*> ancestors = linearizePublicAncestors(*drvclssNondef);
3173 auto lim = ancestors.end();
3175 return lim != std::find(ancestors.begin(), lim, &basety);
3182 auto validBaseOverriderType =
3183 [&dervTy, &baseTy](
const SgType* drv,
const SgType* bas) ->
bool
3185 return ( ((drv == &dervTy) && (bas == &baseTy))
3186 || ((drv != &dervTy) && (bas == drv))
3190 const SgTypePtrList& dervArgs = SG_DEREF(dervFunTy.get_argument_list()).get_arguments();
3191 const SgTypePtrList& baseArgs = SG_DEREF(baseFunTy.get_argument_list()).get_arguments();
3193 return ( validBaseOverriderType(dervFunTy.get_return_type(), baseFunTy.get_return_type())
3194 && std::equal( dervArgs.begin(), dervArgs.end(),
3195 baseArgs.begin(), baseArgs.end(),
3196 validBaseOverriderType
3208 if (overridesBase(dervFunTy, dervTy, *candty, baseTy))
3210 res = isSgFunctionSymbol(&sym);
3211 ASSERT_not_null(res);
3223 findFunctionSymbolForType(
const SgClassType& basety,
3229 const SgClassDeclaration& clsdcl = SG_DEREF(isSgClassDeclaration(basety.get_declaration()));
3231 SgSymbol* sym = scope.lookup_symbol(fnname,
nullptr,
nullptr);
3236 res = symbolForBaseFunction(*sym, drvFunType, basety, dervty);
3249 ASSERT_not_null(res);
3250 ASSERT_require(res == scope.lastStatement());
3260 : base(), call(&callexp)
3263 void handle(
const SgNode& n) { SG_UNEXPECTED_NODE(n); }
3287 res = find( SG_DEREF(n.get_decl()).get_type() );
3296 res = find(n.get_declaration());
3303 if (isVisibleFrom(fndcl, sg::ancestor<const SgScopeStatement>(*call)))
3309 res = find(n.get_publiclyVisibleFunctionSymbol());
3317 return find(n, *call);
3330 return sg::dispatch(AccessibleArgumentListFinder{call}, n);
3336 ASSERT_not_null(var);
3341 res = init->get_operand();
3343 return SG_DEREF(res);
3360 if (isPrivate(firstDervDcl))
3365 if (defnDervDcl ==
nullptr || (!isPrivate(*defnDervDcl)))
3369 if (firstClsDcl ==
nullptr)
3373 const SgClassType& clsty = SG_DEREF(firstClsDcl->get_type());
3375 if (
const SgClassType* basety = isSgClassType(baseTypeOfClass(clsty,
true )))
3377 res = findFunctionSymbolForType(*basety, dervTy, fnsym.
get_name(), drvFunTy);
3380 return res ? res : &fnsym;
3388 SgExpressionPtrList res;
3389 SgExpressionPtrList& orig = SG_DEREF(n.get_args()).get_expressions();
3391 SgExpressionPtrList::iterator aaa = orig.begin();
3392 SgExpressionPtrList::iterator pos = aaa + posArgLimit;
3393 SgExpressionPtrList::iterator zzz = orig.end();
3395 res.reserve(orig.size());
3396 std::copy(aaa, pos, std::back_inserter(res));
3398 const SgInitializedNamePtrList& parmList = arglist.
get_args();
3400 ROSE_ASSERT(res.size() <= parmList.size());
3401 extend(res, parmList.size());
3403 std::for_each( pos, zzz,
3407 const std::size_t pos = namedArgumentPosition(parmList, arg.get_argument_name());
3409 ASSERT_require(res[pos] ==
nullptr);
3410 res[pos] = arg.get_expression();
3414 if (!withDefaultArguments)
3417 const auto resbeg = res.begin();
3418 const auto reslim = res.end();
3419 auto respos = std::find(resbeg, reslim,
nullptr);
3421 while (respos != reslim)
3423 *respos = &getInitializerExpr(parmList.at(std::distance(resbeg, respos)));
3425 respos = std::find(resbeg, reslim,
nullptr);
3435 if (fnparms ==
nullptr)
3436 throw std::logic_error(
"unable to retrieve associated function parameter list");
3444 unwrapActualArgumentExpression(
const SgExpression& arg)
3447 return SG_DEREF(namedarg->get_expression());
3456 SgExpression const& actarg = unwrapActualArgumentExpression(arg);
3457 SgExpressionPtrList
const normargs = si::Ada::normalizedCallArguments(call);
3458 SgExpressionPtrList::const_iterator
const beg = normargs.begin();
3459 SgExpressionPtrList::const_iterator
const lim = normargs.end();
3460 SgExpressionPtrList::const_iterator
const pos = std::find(beg, lim, &actarg);
3462 if (pos == lim)
throw std::logic_error{
"si::Ada::normalizedArgumentPosition: unable to find argument position"};
3464 return std::distance(beg, pos);
3470 if (fnparms ==
nullptr)
3471 throw std::logic_error(
"unable to retrieve associated function parameter list");
3476 SgTypeModifier const& tymod = parmdcl.get_declarationModifier().get_typeModifier();
3478 return tymod.isIntent_out() || tymod.isIntent_inout();
3483 return ( (call !=
nullptr)
3497 return SG_DEREF(tydcl.get_type());
3505 return SG_DEREF(defdcl.
get_type());
3514 return n && (n->*property)();
3535 bool blockIsFrontendGenerated = ( isSgFunctionDefinition(par)
3538 || isSgSwitchStatement(par)
3539 || isSgForStatement(par)
3540 || isSgWhileStmt(par)
3541 || isSgAdaLoopStmt(par)
3542 || isSgAdaAcceptStmt(par)
3543 || isSgCatchOptionStmt(par)
3544 || isSgAdaGenericInstanceDecl(par)
3545 || isSgAdaFormalPackageDecl(par)
3546 || isSgAdaRepresentationClause(par)
3550 return !blockIsFrontendGenerated;
3564 while (!isSgGlobal(curr))
3582 ASSERT_not_null(root);
3593 std::for_each( roots.first, roots.second,
3596 tv.traverse(n, preorder);
3644 isBasedDelimiter(
char ch)
3646 return ch ==
'#' || ch ==
':';
3650 isExponentChar(
char ch)
3652 return ch ==
'E' || ch ==
'e';
3655 std::pair<int, bool>
3658 return std::make_pair(s, s < m);
3661 std::pair<int, bool>
3662 char2Val(
char c,
int max)
3664 using ResultType = std::pair<int, bool>;
3666 if ((c >=
'0') && (c <=
'9'))
3667 return check(c -
'0', max);
3669 if ((c >=
'A') && (c <=
'F'))
3670 return check(c -
'A' + 10, max);
3672 if ((c >=
'a') && (c <=
'f'))
3673 return check(c -
'a' + 10, max);
3675 return ResultType{0,
false};
3679 std::pair<T, const char*>
3680 parseDec(
const char* buf,
int base = 10)
3682 ROSE_ASSERT((*buf !=
'\0') && (base > 0));
3686 const int negmul = (*buf ==
'-') ? -1 : 1;
3688 if (negmul < 0) ++buf;
3690 ROSE_ASSERT((*buf !=
'\0') && char2Val(*buf, base).second);
3693 while (*buf !=
'\0')
3695 const auto v = char2Val(*buf, base);
3699 return std::make_pair(res, buf);
3706 ROSE_ASSERT( (std::numeric_limits<T>::lowest() / base <= res)
3707 && (std::numeric_limits<T>::max() / base >= res)
3708 && (
"arithmethic over-/underflow during literal parsing (mul)")
3712 ROSE_ASSERT( ((negmul < 0) && (std::numeric_limits<T>::lowest() + v.first <= res))
3713 || ((negmul > 0) && (std::numeric_limits<T>::max() - v.first >= res))
3714 || (!
"arithmethic over-/underflow during literal parsing (add)")
3716 res += (v.first * negmul);
3723 while (*buf ==
'_') ++buf;
3726 return std::make_pair(res, buf);
3730 std::pair<T, const char*>
3731 parseFrac(
const char* buf,
size_t base = 10)
3733 ROSE_ASSERT((*buf !=
'\0') && char2Val(*buf, base).second);
3736 size_t divisor = 1*base;
3738 while ((*buf !=
'\0') && (!isBasedDelimiter(*buf)))
3740 const auto v = char2Val(*buf, base);
3741 ROSE_ASSERT(v.second);
3747 ROSE_ASSERT(!std::isnan(divisor));
3749 T frac = val/divisor;
3750 ROSE_ASSERT(!std::isnan(frac));
3755 divisor = divisor*base;
3762 while (*buf ==
'_') ++buf;
3765 return std::make_pair(res, buf);
3769 std::pair<int, const char*>
3770 parseExp(
const char* buf)
3774 if (isExponentChar(*buf))
3777 const bool positiveE = (*buf !=
'-');
3780 if (!positiveE || (*buf ==
'+')) ++buf;
3782 std::tie(exp, buf) = parseDec<long int>(buf, 10);
3784 if (!positiveE) exp = -exp;
3787 return std::make_pair(exp, buf);
3791 T computeLiteral(T val,
int base,
int exp)
3793 T res = val * std::pow(base, exp);
3801 basedLiteral(
long long int res,
const char* cur,
int base)
3805 ROSE_ASSERT(isBasedDelimiter(*cur));
3808 ROSE_ASSERT( (res >= std::numeric_limits<
decltype(base)>::min())
3809 && (res <= std::numeric_limits<
decltype(base)>::max())
3813 std::tie(res, cur) = parseDec<long long int>(cur, base);
3815 if (isBasedDelimiter(*cur))
3819 std::tie(exp, cur) = parseExp(cur);
3822 return computeLiteral(res, base, exp);
3827 return isSgActualArgumentExpression(expr);
3834 long long int res = 0;
3837 const char* cur = img;
3839 std::tie(res, cur) = parseDec<long long int>(cur);
3841 if (isBasedDelimiter(*cur))
3843 return basedLiteral(res, cur, base);
3848 throw std::logic_error(
"SageInterfaceAda.C: Ada decimal literals not yet handled");
3856 std::tie(exp, cur) = parseExp(cur);
3862 return computeLiteral(res, base, exp);
3867 ASSERT_not_null(textrep);
3869 std::stringstream buf;
3870 const char delimiter = *textrep;
3871 ROSE_ASSERT(delimiter ==
'"' || delimiter ==
'%');
3874 while (*(textrep+1))
3878 if (*textrep == delimiter)
3881 ROSE_ASSERT(*textrep == delimiter);
3888 return std::move(buf).str();
3894 std::string litText{img};
3896 boost::replace_all(litText,
"_",
"");
3899 if (litText.find_first_of(
"#:") == std::string::npos)
3902 return boost::lexical_cast<long double>(litText);
3906 long double dec = 0;
3907 long double frac = 0;
3910 const char* cur = img;
3912 std::tie(base, cur) = parseDec<long int>(cur);
3913 ASSERT_require(isBasedDelimiter(*cur));
3916 std::tie(dec, cur) = parseDec<long double>(cur, base);
3921 std::tie(frac, cur) = parseFrac<long double>(cur, base);
3924 const long double res = dec + frac;
3926 ASSERT_require(isBasedDelimiter(*cur));
3929 std::tie(exp, cur) = parseExp(cur);
3937 return computeLiteral(res, base, exp);
3943 ASSERT_not_null(img);
3945 const char delimiter = *img;
3946 ROSE_ASSERT(delimiter ==
'\'');
3948 const char res = img[1];
3950 ROSE_ASSERT(res && img[2] ==
'\'');
3967 if (tydcl && (tydcl->
get_scope() == scope))
3975std::vector<PrimitiveParameterDesc>
3978 std::vector<PrimitiveParameterDesc> res;
3982 for (
const SgInitializedName* parm : SG_DEREF(dcl.get_parameterList()).get_args())
3984 ASSERT_not_null(parm);
3987 res.emplace_back(parmpos, parm, tydcl);
3995std::vector<PrimitiveParameterDesc>
3998 ASSERT_not_null(dcl);
4003PrimitiveSignatureElementsDesc
4007 ASSERT_not_null(fnty);
4009 return { primitiveInScope(fnty->get_return_type(), dcl.
get_scope())
4014PrimitiveSignatureElementsDesc
4017 ASSERT_not_null(dcl);
4027 SgExpressionPtrList::const_iterator aaa = arglst.begin();
4028 SgExpressionPtrList::const_iterator pos = std::find_if(aaa, arglst.end(), isNamedArgument);
4030 return std::distance(aaa, pos);
4042 ASSERT_not_null(args);
4051 using PrimitiveParmIterator = std::vector<PrimitiveParameterDesc>::const_iterator;
4052 using ArgumentIterator = SgExpressionPtrList::const_iterator;
4054 if (primitiveArgs.size() == 0)
4057 const SgExpressionPtrList& arglst = args.get_expressions();
4059 PrimitiveParmIterator aa = primitiveArgs.begin();
4060 PrimitiveParmIterator zz = primitiveArgs.end();
4063 while ((aa != zz) && (aa->pos() < posArgLimit))
4073 ROSE_ASSERT(posArgLimit <= arglst.size());
4074 ArgumentIterator firstNamed = arglst.begin() + posArgLimit;
4075 ArgumentIterator argLimit = arglst.end();
4080 const std::string parmName = SG_DEREF(aa->name()).get_name();
4081 auto sameNamePred = [&parmName](
const SgExpression* arg) ->
bool
4085 ASSERT_not_null(actarg);
4086 return parmName == std::string{actarg->get_argument_name()};
4088 ArgumentIterator argpos = std::find_if(firstNamed, argLimit, sameNamePred);
4092 if (argpos == argLimit)
4107 ASSERT_not_null(args);
4116 void handle(
const SgNode& n) { SG_UNEXPECTED_NODE(n); }
4137 res = &base_type(n);
4142 res = n.get_formal_type();
4155 res = baseTypeOfClass(n);
4163 SgEnumDeclaration* defdecl = isSgEnumDeclaration(enmdcl->get_definingDeclaration());
4165 if (defdecl ==
nullptr) defdecl = enmdcl;
4167 res = defdecl->get_adaParentType();
4202 return isSgEnumDeclaration(basedcl);
4219 if (
SgEnumDeclaration* enumdcl = isSgEnumDeclaration(BaseTypeDecl::find(baseTy)))
4220 return enumdcl->get_type();
4225 while (
SgEnumType* curr = baseEnumDecl(last))
4231 if (enumdcl ==
nullptr)
return nullptr;
4234 && (boost::algorithm::ends_with(enumdcl->
get_name().getString(),
"Character"))
4237 return isCharType ? enumdcl->
get_type() :
nullptr;
4258 return isSgMinusMinusOp(n.get_increment());
4281boost::optional<bool>
4284 if (
const SgEnumVal* enumval = isSgEnumVal(e))
4286 return stringeq(enumval->get_name().getString(),
"True");
4291boost::optional<bool>
4306 void handle(
const SgNode& n) { SG_UNEXPECTED_NODE(n); }
4319 void handle(
const SgGlobal&) { res =
nullptr; }
4324 void handle(
const SgAdaPackageBody& n) { res = getSpecFromBody<SgAdaPackageBodyDecl>(n); }
4329 void handle(
const SgAdaTaskSpec& n) { res = fromParent(n); }
4344 fromParent(
const SgNode& n);
4348 LogicalParent::fromParent(
const SgNode& n)
4357 ReturnType filterReturnType(ReturnType v) {
return v; }
4360 ReturnType filterReturnType(
const SgNode*) {
return nullptr; }
4363 auto handlesyms(
const SgNode& n,
const SgNode&) ->
const SgNode* { SG_UNEXPECTED_NODE(n); }
4367 template <
class SageSymbol>
4368 auto handlesyms(
const SageSymbol& n,
const SgSymbol&) ->
decltype(n.get_declaration())
4370 return n.get_declaration();
4377 std::stringstream out;
4379 out <<
"unhandled symbol kind: " <<
typeid(n).name() << std::endl;
4380 throw std::runtime_error{out.str()};
4386 template <
class SageNode>
4387 void handle(
const SageNode& n)
4389 res = filterReturnType(handlesyms(n, n));
4393 template <
class SageNode>
4401 if (info ==
nullptr)
4404 ASSERT_not_null(info);
4409 return SG_DEREF(info);
4412 template <
class SageNode>
4413 void setFileInfo( SageNode& n,
4419 ensureFileInfo(n, setter, getter) = orig;
4434 template <
class SageLocatedNode>
4435 void cpyFileInfo( SageLocatedNode& n,
4438 const SageLocatedNode& src
4443 if (infox ==
nullptr)
4444 throw std::runtime_error(
"copied file location from node where Sg_File_Info == nullptr");
4448 setFileInfo(n, setter, getter, info);
4464std::tuple<const SgScopeStatement*, const SgSymbol*>
4467 constexpr SgTemplateParameterPtrList* templParams =
nullptr;
4468 constexpr SgTemplateArgumentPtrList* templArgs =
nullptr;
4473 while ((curr !=
nullptr) && (curr != limit))
4475 sym = curr->lookup_symbol(
id, templParams, templArgs);
4491 return stringeq(attr.get_attribute().getString(), attrname);
4506 SgPragma* pragma = prgdcl.get_pragma();
4507 if ((pragma ==
nullptr) || !stringeq(pragma->get_pragma(), prgname))
4511 ASSERT_not_null(res);
4531 cpyFileInfo( *tgtexp,
4532 &SgExpression::set_operatorPosition, &SgExpression::get_operatorPosition,
4538 throw std::runtime_error{
"cannot assign set_operatorPosition from non-SgExpression."};
4549 l->setCompilerGenerated();
4566 void report_error(std::string desc,
const char* file,
size_t ln)
4568 static const char* AT =
" at ";
4569 static const char* SEP =
" : ";
4573 const std::string filename(file);
4574 const std::string num(conv<std::string>(ln));
4576 desc.reserve(desc.size() + num.size() + filename.size() + std::strlen(AT) + std::strlen(SEP)+1);
4579 desc.append(filename);
4590 mlog[
FATAL] <<
"[throw] " << desc << std::endl;
4591 mlog[
INFO] <<
"gdb: b sageInterfaceAda.C:" << __LINE__ << std::endl;
4592 throw std::runtime_error(desc);
4600 void unexpected_node(
const SgNode& n,
const char* file,
size_t ln)
4602 static const std::string msg =
"assertion failed: unexpected node-type: ";
4604 report_error(msg +
typeid(n).name(), file, ln);
Class for traversing the AST.
void traverse(SgNode *node, Order treeTraversalOrder)
traverse the entire AST. Order defines preorder (preorder) or postorder (postorder) traversal....
For preprocessing information including source comments, include , if, define, etc.
SgType * get_type() const override
unparsing support for pragmas
SgScopeStatement * get_scope() const override
Returns scope of current statement.
SgScopeStatement * get_scope() const override
Returns scope of current statement.
SgScopeStatement * get_scope() const override
Returns scope of current statement.
SgScopeStatement * get_scope() const override
Returns scope of current statement.
This class represents the rhs of a variable declaration which includes an optional assignment (e....
This class represents the concept of a block (not a basic block from control flow analysis).
const SgStatementPtrList & get_statements() const
Returns a const STL list by reference.
SgExpression * get_lhs_operand() const
returns SgExpression pointer to the lhs operand associated with this binary operator.
SgExpression * get_rhs_operand() const
returns SgExpression pointer to the rhs operand associated with this binary operator.
This class represents a cast of one type to another.
This class represents the concept of a class declaration statement. It includes the concept of an ins...
SgScopeStatement * get_scope() const override
Returns scope of current statement.
This class represents the concept of a class definition in C++.
const SgBaseClassPtrList & get_inheritances() const
Returns a const list to the base classes.
const SgDeclarationStatementPtrList & get_members() const
Returns a const list to the data member declarations.
This class represents the concept of a C trinary conditional expression (e.g. "test ?...
SgExpression * get_true_exp() const
Access function for p_true_exp.
SgExpression * get_conditional_exp() const
Access function for p_conditional_exp.
SgExpression * get_false_exp() const
Access function for p_false_exp.
This class represents the concept of a declaration statement.
SgDeclarationStatement * get_definingDeclaration() const
This is an access function for the SgDeclarationStatement::p_definingDeclaration data member (see tha...
SgDeclarationStatement * get_firstNondefiningDeclaration() const
This is an access function for the SgDeclarationStatement::p_firstNondefiningDeclaration data member ...
This class represents the concept of an enum declaration.
SgScopeStatement * get_scope() const override
Access function for p_scope.
SgName get_name() const
Access function for p_name.
const SgInitializedNamePtrList & get_enumerators() const
Access function for p_enumerators.
SgEnumType * get_type() const
Access function for p_type.
This class represents the concept of a C and C++ expression list.
This class represents the concept of a C or C++ statement which contains a expression.
This class represents the notion of an expression. Expressions are derived from SgLocatedNodes,...
void set_need_paren(bool need_paren)
This function allows the p_need_paren flag to be set (used internally).
virtual SgType * get_type() const
unparsing support for pragmas
virtual std::vector< SgNode * > get_traversalSuccessorContainer() override
container of pointers to AST successor nodes used in the traversal overridden in every class by gener...
bool get_need_paren() const
returns bool value if front-end considers parenthesis to be required.
std::string getFileName() const
associated filename
This class represents the variable declaration or variable initialization withn a for loop.
This class represents the concept of a for loop.
This class represents the concept of a C++ function call (which is an expression).
SgFunctionDeclaration * getAssociatedFunctionDeclaration() const
Returns the associated function declaration, if it can be resolved statically.
This class represents the concept of a function declaration statement.
SgScopeStatement * get_scope() const override
Returns scope of current statement.
This class represents the concept of a scope in C++ (e.g. global scope, fuction scope,...
SgBasicBlock * get_body() const
Access function for p_body.
This class represents the concept of a declaration list.
const SgInitializedNamePtrList & get_args() const
Access function for p_args.
This class represents the function being called and must be assembled in the SgFunctionCall with the ...
SgName get_name() const override
Access function for getting name from declarations or types internally.
SgType * get_type() const override
This function returns the type associated with the named entity.
This class represents a type for all functions.
This class represents the concept of a namespace definition.
const SgDeclarationStatementPtrList & get_declarations() const
Returns a const list to the global scope declarations.
This class represents the concept of an "if" construct.
SgStatement * get_conditional() const
Access function for p_conditional.
SgStatement * get_true_body() const
Access function for p_true_body.
SgStatement * get_false_body() const
Access function for p_false_body.
This class represents the notion of a declared variable.
virtual std::vector< SgNode * > get_traversalSuccessorContainer() override
container of pointers to AST successor nodes used in the traversal overridden in every class by gener...
This class represents the notion of an expression or statement which has a position within the source...
Sg_File_Info * get_endOfConstruct() const override
New function interface for Sg_File_Info data stores ending location of contruct (typically the closin...
void set_endOfConstruct(Sg_File_Info *endOfConstruct)
This function sets the current source location position of the end of the current construct.
Sg_File_Info * get_startOfConstruct() const override
New function interface for Sg_File_Info data stores starting location of contruct (typically the open...
void set_startOfConstruct(Sg_File_Info *startOfConstruct)
This function sets the current source location position of the start of the current construct.
virtual Sg_File_Info * get_file_info() const override
Interface function to implement original SAGE interface to SgFile_Info objects.
AttachedPreprocessingInfoType *& getAttachedPreprocessingInfo(void)
Computes the number of nodes in the defined subtree of the AST.
This class represents strings within the IR nodes.
virtual SgName get_name() const
Gets name of the type (useful for debugging, unparsing, etc.)
This class represents the concept of a C++ call to the new operator.
SgType * get_type() const override
unparsing support for pragmas
This class represents the base class for all IR nodes within Sage III.
SgNode * get_parent() const
Access function for parent node.
virtual std::string unparseToString(SgUnparse_Info *info) const
This function unparses the AST node (excluding comments and unnecessary white space)
SgType * get_type() const override
unparsing support for pragmas
This class represents the concept of a C Assembler statement (untested).
This class represents the concept of a scope in C++ (e.g. global scope, fuction scope,...
SgSymbol * next_any_symbol() const
Only use after lookup_XXX_symbol(const SgName&) or after first_XXX_symbol() These functions use the s...
SgSymbolTable * get_symbol_table() const
Returns a pointer to the locally strored SgSymbolTable.
SgDeclarationStatementPtrList & getDeclarationList()
Gets reference to internal STL list of pointers to SgDeclarationStatement objects (only defined for s...
bool containsOnlyDeclarations() const
This function is used to indicate if either the getDeclarationList() or getStatementList() can be cal...
This class represents the notion of a statement.
virtual std::vector< SgNode * > get_traversalSuccessorContainer() override
container of pointers to AST successor nodes used in the traversal overridden in every class by gener...
virtual SgScopeStatement * get_scope(void) const
Returns scope of current statement.
This class represents the symbol tables used in both SgScopeStatement and the SgFunctionTypeSymbolTab...
bool isCaseInsensitive() const
Query of scope symbol table behavior (is symbol table behavior case sensitive (C/C++) or case insensi...
This class represents the concept of a name within the compiler.
virtual SgType * get_type() const =0
This function returns the type associated with the named entity.
This class represents the concept of try statement within the try-catch support for exception handlin...
This class represents a default type used for some IR nodes (see below).
SgType * get_type() const override
unparsing support for pragmas
This class represents a string type used for SgStringVal IR node.
This class represents the base class for all types.
SgType * stripType(unsigned char bit_array=STRIP_MODIFIER_TYPE|STRIP_REFERENCE_TYPE|STRIP_RVALUE_REFERENCE_TYPE|STRIP_POINTER_TYPE|STRIP_ARRAY_TYPE|STRIP_TYPEDEF_TYPE|STRIP_POINTER_MEMBER_TYPE) const
Returns hidden type beneath layers of typedefs, pointers, references, modifiers, array representation...
This class represents the notion of a typedef declaration.
SgName get_name() const override
Support for some classes which have pure virtual function in base classes.
SgExpression * get_operand() const
returns SgExpression pointer to the operand associated with this unary operator.
This class represents the variable refernece in expressions.
SgType * get_type() const override
Get the type associated with this expression.
This class represents the concept of a C or C++ variable declaration.
const SgInitializedNamePtrList & get_variables() const
Access function for p_variables.
This class represents the concept of a variable name within the compiler (a shared container for the ...
This class represents the location of the code associated with the IR node in the original source cod...
bool isCompilerGenerated() const
Returns true only if compiler generated (either by the front-end or by ROSE).
static Sg_File_Info * generateDefaultFileInfoForTransformationNode()
Static function to return new Sg_File_Info object set to default values appropriate for transformatio...
Hash table support for symbol tables within ROSE.
__when_T< checker_t > checker
Used by the -rose:ast:checker:XXX options.
Controls diagnostic messages from ROSE.
ROSE_DLL_API Sawyer::Message::Facility mlog
Diagnostic facility for the ROSE library as a whole.
Functions that build an AST.
ROSE_DLL_API SgAddOp * buildAddOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgEqualityOp * buildEqualityOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgConcatenationOp * buildConcatenationOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgMultiplyOp * buildMultiplyOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgGreaterThanOp * buildGreaterThanOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgBitAndOp * buildBitAndOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgLessOrEqualOp * buildLessOrEqualOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgSubtractOp * buildSubtractOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgBitOrOp * buildBitOrOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgArrayType * buildArrayType(SgType *base_type=nullptr, SgExpression *index=nullptr)
Build ArrayType.
ROSE_DLL_API SgTypeFixed * buildFixedType(SgExpression *fraction, SgExpression *scale)
Build a Jovial fixed type with a fraction specifier and a scale specifier.
ROSE_DLL_API SgTypeLongLong * buildLongLongType()
Built in simple types.
ROSE_DLL_API SgRemOp * buildRemOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgUnaryAddOp * buildUnaryAddOp(SgExpression *op=NULL)
ROSE_DLL_API SgNullExpression * buildNullExpression()
Build a null expression, set file info as the default one.
ROSE_DLL_API SgBitXorOp * buildBitXorOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgGreaterOrEqualOp * buildGreaterOrEqualOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgTypeLongDouble * buildLongDoubleType()
Built in simple types.
ROSE_DLL_API SgNotOp * buildNotOp(SgExpression *op=NULL)
ROSE_DLL_API SgNotEqualOp * buildNotEqualOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgTypeChar * buildCharType()
Built in simple types.
ROSE_DLL_API SgLessThanOp * buildLessThanOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgDivideOp * buildDivideOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgTypeNullptr * buildNullptrType()
Built in simple types.
ROSE_DLL_API SgExponentiationOp * buildExponentiationOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
ROSE_DLL_API SgAbsOp * buildAbsOp(SgExpression *op=NULL)
ROSE_DLL_API SgModOp * buildModOp(SgExpression *lhs=NULL, SgExpression *rhs=NULL)
bool tryFollowsDeclarativeBlock(const SgTryStmt &n)
returns true iff n is a try block following a declarative region
std::string convertRoseOperatorNameToAdaOperator(const std::string &nameInRose)
takes a function name as used in ROSE and converts it to an operator in Ada (i.e.,...
void conversionTraversal(std::function< void(SgNode *)> &&fn, SgNode *root)
bool systemPackage(const SgScopeStatement &n)
returns true if the scope n is part of a system package
bool isFixedType(const SgType *ty)
returns if the type ty is a fixed point type
SgAdaPackageBody & getBodyDefinition(const SgAdaPackageSpec &spec)
returns the body definition (scope) of the package specification
bool isBooleanType(const SgType *ty)
return if the type ty is the corresponding universal type representation in ROSE
SgScopeStatement * overridingScope(const SgExprListExp &args, const std::vector< PrimitiveParameterDesc > &primitiveArgs)
returns the overriding scope of a primitive function based on the associated arguments as defined by ...
PrimitiveSignatureElementsDesc primitiveSignatureElements(const SgFunctionDeclaration &)
returns the descriptions for result type and parameters that make an operation primitive.
FlatArrayType getArrayTypeInfo(SgType *atype)
returns a flattened representation of Ada array types.
SgInitializedName & declOf(const SgEnumVal &)
returns the declaration of the enum value
SgFunctionSymbol * findPubliclyVisibleFunction(SgFunctionSymbol &fnsym, const SgFunctionType &drvFunTy, const SgNamedType &dervTy)
finds the function symbol for a publicly accessible function.
bool denotesRange(const SgExpression &e)
returns true if the expression e denotes a range
bool resolvesToFixedType(const SgType *ty)
returns if the type ty resolves to a fixed point type
StatementRange declsInPackage(SgGlobal &globalScope, const std::string &mainFile)
returns all statements/declarations in the global scope that were defined in the source file.
SgExpressionPtrList normalizedCallArguments2(const SgFunctionCallExp &n, const SgFunctionParameterList &arglist, bool withDefaultArguments=false)
returns a list of arguments with named arguments placed at the correct position by taking into accoun...
std::string convertStringLiteral(const char *img)
converts text to constant values
std::vector< IfExpressionInfo > flattenIfExpressions(const SgConditionalExp &n)
returns a flat representation of if expressions
void convertToCaseSensitiveSymbolTables(SgNode *root)
converts all symbol tables from case insensitive to case sensitive
SgAdaDiscriminatedTypeDecl * getAdaDiscriminatedTypeDecl(const SgDeclarationStatement &n)
returns the SgAdaDiscriminatedTypeDecl iff n is discriminated null otherwise
void copyFileInfo(SgLocatedNode &tgt, const SgLocatedNode &src)
copies the source code location from src to tgt.
bool isObjectRenaming(const SgAdaRenamingDecl *dcl)
returns true iff ty refers to an object renaming
void setSourcePositionInSubtreeToCompilerGenerated(SgLocatedNode *n)
sets source position in entire subtree of n to compiler generated
AggregateInfo splitAggregate(const SgExprListExp &exp)
returns the ancestor initializer, if exp refers to an extension aggregate null otherwise
bool isFloatingPointType(const SgType &ty)
return if the type ty is the corresponding universal type representation in ROSE
const SgFunctionType * functionType(const SgFunctionSymbol *fnsy)
returns the static type of the function symbol fnsy
void simpleTraversal(std::function< void(SgNode *)> &&fn, SgNode *root)
Traverses all AST nodes in an unspecified order.
bool isAnyAccessAttribute(const SgAdaAttributeExp &attr)
tests if attr is an access attribute
size_t positionalArgumentLimit(const SgExpressionPtrList &arglst)
finds the one past the last positional argument (aka the first named argument position).
SgScopeStatement * logicalParentScope(const SgScopeStatement &s)
returns the logical parent scope of a scope s.
SgAdaPackageSpecDecl * renamedPackage(const SgAdaRenamingDecl &n)
returns a package spec decl if the declaration n renames a package returns nullptr otherwise
SgExprListExp * isPragma(const SgPragmaDeclaration &prgdcl, const std::string &pragmaname)
tests if prgdcl is a pragma with name pragmaname.
bool isSeparatedDefinition(const SgFunctionDeclaration &n)
returns true iff n is a separated function definition is separated
SgExpression * underlyingExpr(const SgStatement *s)
returns the expression of an expression statement, or nullptr if s is some other node
long long int convertIntegerLiteral(const char *img)
converts text to constant values
SgScopeStatement * pkgStandardScope()
do not use, this is temporary
bool isSeparatedBody(const SgDeclarationStatement &n)
returns true iff n is a unit definition that has been separated
bool isScalarType(const SgType *ty)
returns true if ty refers to a scalar type
void extend(SgExpressionPtrList &container, std::size_t pos, SgExpression *val=nullptr)
resize the container if pos is outside the valid index range
SgDeclarationStatement * associatedDeclaration(const SgSymbol &n)
returns the associated declaration for symbol n or nullptr if there is none.
const SgVariableDeclaration * exceptionTypeDecl(const SgVariableDeclaration &n)
returns n or a pointer to n if n declares an exception type.
bool explicitNullProcedure(const SgFunctionDefinition &fndef)
returns true, iff fndef is the body of an explicit null procedure
SgEnumType * characterBaseType(SgEnumType *ty)
checks if the type is based on one of the Standard character types.
bool isDiscreteType(const SgType *ty)
return if the type ty is the corresponding universal type representation in ROSE
bool explicitNullRecord(const SgClassDefinition &recdef)
returns true, iff recdef is the body of an explicit null record
OperatorScopeInfo operatorScope(const std::string &opname, const SgTypePtrList &argtypes)
returns the scope where an operator with name opname and argument types in argtypes shall be declared...
bool unconstrained(const SgArrayType *ty)
tests if ty is an unconstrained array
bool isDiscreteArrayType(const SgType &ty)
returns true if ty refers to a discrete array type
std::vector< PrimitiveParameterDesc > primitiveParameterPositions(const SgFunctionDeclaration &fn)
returns the descriptions for parameters that make an operation primitive.
std::tuple< const SgScopeStatement *, const SgSymbol * > findSymbolInContext(std::string id, const SgScopeStatement &scope, const SgScopeStatement *limit=nullptr)
finds the symbol with Naming tips in the context of scope or its logical parents in the range [scope,...
void convertToOperatorRepresentation(SgNode *root, bool convertCallSyntax=false, bool convertNamedArguments=false)
converts AST from a function call representation to operator form for fundamental operator declaratio...
SgFunctionParameterList * calleeParameterList(const SgFunctionCallExp &n)
returns the function parameter list of the associated callee (if available).
boost::optional< bool > booleanConstant(const SgExpression *e)
if e denotes an Ada boolean constant, it is returned; otherwise an empty result is returned.
bool isIntegerType(const SgType &ty)
return if the type ty is the corresponding universal type representation in ROSE
bool isReverseForLoop(const SgForStatement *n)
returns true, iff n is a reverse for loop; returns false otherwise
const SgScopeStatement * canonicalScope(const SgScopeStatement *scope)
returns the canonical scope of some Ada scope scope.
SgAdaGenericDecl & getGenericDecl(const SgAdaGenericInstanceDecl &n)
Returns SgAdaGenericDecl for a given SgAdaGenericInstanceDecl.
SgAdaGenericDecl * isGenericDecl(const SgDeclarationStatement &n)
Returns the SgAdaGenericDecl node that makes a declaration (either function/procedure or package) gen...
SgType & standardType(const std::string &name)
returns a type from the standard package with name name.
bool isModularType(const SgType &ty)
return if the type ty is the corresponding universal type representation in ROSE
bool unitRefDenotesGenericInstance(const SgAdaUnitRefExp &n)
returns true iff n refers to a generic declaration from inside said declaration false otherwise (e....
bool anonymousAccess(const SgType *ty)
tests if ty is an anonymous access type
bool isFunction(const SgFunctionType &ty)
returns true iff ty refers to a function type (as opposed to procedure)
bool isAttribute(const SgAdaAttributeExp &attr, const std::string &attrname)
tests if attr is an attribute with name attrname.
char convertCharLiteral(const char *img)
converts text to constant values
SgRangeExp * range(const SgAdaAttributeExp *rangeAttribute)
returns a range for the range attribute rangeAttribute.
long double convertRealLiteral(const char *img)
converts text to constant values
bool isExceptionRenaming(const SgAdaRenamingDecl *dcl)
returns true iff ty refers to an exception renaming
std::vector< IfStatementInfo > flattenIfStatements(const SgIfStmt &n)
returns a flat representation of if-elsif-else statements
bool isDecimalFixedType(const SgType *ty)
returns if the type ty is a decimal fixed point type
TypeDescription typeOfExpr(const SgExpression &)
returns the type of an expression corrects for some peculiarities in the AST
SgType * baseOfAccessType(const SgType *ty)
returns the base type if ty is an access type
bool blockExistsInSource(const SgBasicBlock *blk)
checks if the block blk is present in the Ada source code.
SgStatementPtrList::iterator declarationLimit(SgStatementPtrList &list)
returns the iterator to one past the last declaration (the limit) in the statement sequence.
std::vector< RecordField > getAllRecordFields(const SgClassDefinition &rec)
returns all fields (defined and inherited) of a record.
SgAdaPackageSpec & getSpecificationDefinition(const SgAdaPackageBody &body)
returns the specification definition (scope) of the package body
SgNodePtrList unparsedChildren(SgNode &n)
returns a container of children nodes that are relevant for unparsing.
bool isPackageTryBlock(const SgTryStmt &n)
returns true iff n is an Ada package try block
SgType * baseType(const SgType &ty)
returns the base type of a type ty
bool hasSeparatedBody(const SgDeclarationStatement &dcl)
tests if the declaration decl corresponds to a stub (aka separated unit)
std::size_t normalizedArgumentPosition(const SgFunctionCallExp &call, const SgExpression &arg)
returns the parameter position of arg in the callee, after the parameters have been normalized.
int firstLastDimension(SgExprListExp &args)
returns an integer value for args[0] as used by type attributes first and last
bool isOutInoutArgument(const SgFunctionCallExp &call, const SgExpression &arg)
returns true if arg is a used as l-value in the call
bool withPrivateDefinition(const SgDeclarationStatement *dcl)
tests if the declaration dcl defines a public type that is completed in a private section.
bool sameCanonicalScope(const SgScopeStatement *lhs, const SgScopeStatement *rhs)
tests if lhs and have the same canonical scope.
void convertAdaToCxxComments(SgNode *root, bool cxxLineComments=true)
/}
ScopePath pathToGlobal(const SgScopeStatement &n)
Constructs a path from a scope statement to the top-level (global) scope.
SgAdaPackageSpecDecl & getSpecificationDeclaration(const SgAdaPackageBodyDecl &bodyDecl)
returns the declaration node for the package specification
const SgScopeStatement * correspondingBody(const SgScopeStatement *scope)
returns the body scope (aka definition) of a task, package, or protected object.
std::vector< ImportedUnitResult > importedUnits(const SgImportStatement &impdcl)
queries properties of all units in an import statement
SgScopeStatement * declarationScope(const SgType *ty)
returns the scope where type ty has been declared
SgEnumDeclaration * baseEnumDeclaration(const SgType *ty)
finds the underlying enum declaration of a type ty
TypeDescription typeRoot(SgType &)
returns the most fundamental type after skipping subtypes, typedefs, etc.
SgAdaPackageBodyDecl & getPackageBodyDeclaration(const SgAdaPackageSpecDecl &specDecl)
returns the declaration node for the package body, if available
long long int staticIntegralValue(SgExpression *n)
integer constant folding
bool hasUnknownDiscriminants(const SgAdaDiscriminatedTypeDecl &n)
returns true iff n has an unknown discriminant part
std::string convertRoseOperatorNameToAdaName(const std::string &nameInRose)
takes a function name as used in ROSE and converts it to a name in Ada (i.e., '"' + operator_text + '...
SgExpressionPtrList normalizedCallArguments(const SgFunctionCallExp &n, bool withDefaultArguments=false)
attempts to identify the argument list automatically and uses it to invoke the preceding normalizedCa...
Functions that are useful when operating on the AST.
ROSE_DLL_API SgScopeStatement * getEnclosingScope(SgNode *n, const bool includingSelf=false)
Get the enclosing scope from a node n.
ROSE_DLL_API void replaceExpression(SgExpression *oldExp, SgExpression *newExp, bool keepOldExp=false)
Replace an expression with another, used for variable reference substitution and others....
SgNamedType * getDeclaredType(const SgDeclarationStatement *declaration)
Returns the type introduced by a declaration.
@ WARN
Warning messages that indicate an unusual situation from which the program was able to fully recover.
@ TRACE
Detailed tracing information useful to end-users that are trying to understand program internals.
@ INFO
Informative messages.
@ FATAL
Messages that indicate an abnormal situation from which the program was unable to recover.
This namespace contains template functions that operate on the ROSE AST.
std::remove_const< typenamestd::remove_reference< RoseVisitor >::type >::type dispatch(RoseVisitor &&rv, SgNode *n)
uncovers the type of SgNode and passes it to an function "handle" in RoseVisitor.
SageNode::base_node_type & asBaseType(SageNode &n)
returns the same node n upcasted to its base type
This file implements generic (template) sage query functions Currently this includes functions for:
stores a path from an innermost scope to the global scope (not part of the path) in form of a sequenc...
void push_back(base::value_type ptr)
overload vector's push_back to check element validity
experimental class for returning non-null pointers