[flang][PPC] Improve vector type names in expression diagnostics (NFC) (#199383)
Continuation of #197821 The change only affects vector types; all other types preserve their existing formatting behavior. Co-authored-by: virsworld <virpatel@mac.home>
This commit is contained in:
parent
f828c0e39f
commit
c8efcf55ee
7 changed files with 93 additions and 41 deletions
|
|
@ -28,6 +28,10 @@ ENUM_CLASS(IoStmtKind, None, Backspace, Close, Endfile, Flush, Inquire, Open,
|
|||
ENUM_CLASS(
|
||||
DefinedIo, ReadFormatted, ReadUnformatted, WriteFormatted, WriteUnformatted)
|
||||
|
||||
// Vector type categories for DerivedTypeSpec
|
||||
ENUM_CLASS(
|
||||
VectorTypeCategory, DerivedType, IntrinsicVector, PairVector, QuadVector)
|
||||
|
||||
RT_OFFLOAD_VAR_GROUP_BEGIN
|
||||
// Fortran arrays may have up to 15 dimensions (See Fortran 2018 section 5.4.6).
|
||||
static constexpr int maxRank{15};
|
||||
|
|
|
|||
|
|
@ -103,6 +103,10 @@ bool AreCompatibleCUDADataAttrs(std::optional<CUDADataAttr>,
|
|||
bool isHostDeviceProcedure,
|
||||
const LanguageFeatureControl *features = nullptr);
|
||||
|
||||
// Format vector type as Fortran string
|
||||
std::string FormatVectorTypeAsFortran(
|
||||
int category, int64_t elementCategory, int64_t elementKind);
|
||||
|
||||
static constexpr char blankCommonObjectName[] = "__BLNK__";
|
||||
|
||||
// Get the assembly name for a non BIND(C) external symbol other than the blank
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
// Forward declaration for static helper function
|
||||
static std::string FormatVectorType(const semantics::DerivedTypeSpec &);
|
||||
|
||||
// Constant arrays can have non-default lower bounds, but this can't be
|
||||
// expressed in Fortran syntax directly, only implied through the use of
|
||||
// named constant (PARAMETER) definitions. For debugging, setting this flag
|
||||
|
|
@ -676,6 +679,9 @@ llvm::raw_ostream &StructureConstructor::AsFortran(llvm::raw_ostream &o) const {
|
|||
std::string DynamicType::AsFortran() const {
|
||||
if (derived_) {
|
||||
CHECK(category_ == TypeCategory::Derived);
|
||||
if (derived_->IsVectorType()) {
|
||||
return FormatVectorType(*derived_);
|
||||
}
|
||||
std::string result{DerivedTypeSpecAsFortran(*derived_)};
|
||||
if (IsPolymorphic()) {
|
||||
result = "CLASS("s + result + ')';
|
||||
|
|
@ -884,6 +890,25 @@ llvm::raw_ostream &Assignment::AsFortran(llvm::raw_ostream &o) const {
|
|||
return o;
|
||||
}
|
||||
|
||||
static std::string FormatVectorType(const semantics::DerivedTypeSpec &derived) {
|
||||
int64_t vecElemKind{0};
|
||||
int64_t vecElemCategory{-1};
|
||||
|
||||
if (derived.category() ==
|
||||
semantics::DerivedTypeSpec::Category::IntrinsicVector) {
|
||||
for (const auto &pair : derived.parameters()) {
|
||||
if (pair.first == "element_category") {
|
||||
vecElemCategory = ToInt64(pair.second.GetExplicit()).value_or(-1);
|
||||
} else if (pair.first == "element_kind") {
|
||||
vecElemKind = ToInt64(pair.second.GetExplicit()).value_or(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return common::FormatVectorTypeAsFortran(
|
||||
static_cast<int>(derived.category()), vecElemCategory, vecElemKind);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER // disable bogus warning about missing definitions
|
||||
#pragma warning(disable : 4661)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5538,7 +5538,9 @@ std::string ArgumentAnalyzer::TypeAsFortran(std::size_t i) {
|
|||
: type->IsUnlimitedPolymorphic() ? "CLASS(*)"s
|
||||
: type->IsPolymorphic() ? type->AsFortran()
|
||||
: type->category() == TypeCategory::Derived
|
||||
? "TYPE("s + type->AsFortran() + ')'
|
||||
? (type->GetDerivedTypeSpec().IsVectorType()
|
||||
? type->AsFortran()
|
||||
: "TYPE("s + type->AsFortran() + ')')
|
||||
: type->category() == TypeCategory::Character
|
||||
? "CHARACTER(KIND="s + std::to_string(type->kind()) + ')'
|
||||
: ToUpperCase(type->AsFortran());
|
||||
|
|
|
|||
|
|
@ -758,15 +758,10 @@ const DeclTypeSpec *CloneDerivedTypeForUseDevice(Scope &containingScope,
|
|||
}
|
||||
|
||||
std::string DerivedTypeSpec::VectorTypeAsFortran() const {
|
||||
std::string buf;
|
||||
llvm::raw_string_ostream ss{buf};
|
||||
|
||||
switch (category()) {
|
||||
SWITCH_COVERS_ALL_CASES
|
||||
case (Fortran::semantics::DerivedTypeSpec::Category::IntrinsicVector): {
|
||||
int64_t vecElemKind;
|
||||
int64_t vecElemCategory;
|
||||
int64_t vecElemKind{0};
|
||||
int64_t vecElemCategory{-1};
|
||||
|
||||
if (category() == Category::IntrinsicVector) {
|
||||
for (const auto &pair : parameters()) {
|
||||
if (pair.first == "element_category") {
|
||||
vecElemCategory =
|
||||
|
|
@ -776,39 +771,10 @@ std::string DerivedTypeSpec::VectorTypeAsFortran() const {
|
|||
Fortran::evaluate::ToInt64(pair.second.GetExplicit()).value_or(0);
|
||||
}
|
||||
}
|
||||
|
||||
assert((vecElemCategory >= 0 &&
|
||||
static_cast<size_t>(vecElemCategory) <
|
||||
Fortran::common::VectorElementCategory_enumSize) &&
|
||||
"Vector element type is not specified");
|
||||
assert(vecElemKind && "Vector element kind is not specified");
|
||||
|
||||
ss << "vector(";
|
||||
switch (static_cast<common::VectorElementCategory>(vecElemCategory)) {
|
||||
SWITCH_COVERS_ALL_CASES
|
||||
case common::VectorElementCategory::Integer:
|
||||
ss << "integer(" << vecElemKind << ")";
|
||||
break;
|
||||
case common::VectorElementCategory::Unsigned:
|
||||
ss << "unsigned(" << vecElemKind << ")";
|
||||
break;
|
||||
case common::VectorElementCategory::Real:
|
||||
ss << "real(" << vecElemKind << ")";
|
||||
break;
|
||||
}
|
||||
ss << ")";
|
||||
break;
|
||||
}
|
||||
case (Fortran::semantics::DerivedTypeSpec::Category::PairVector):
|
||||
ss << "__vector_pair";
|
||||
break;
|
||||
case (Fortran::semantics::DerivedTypeSpec::Category::QuadVector):
|
||||
ss << "__vector_quad";
|
||||
break;
|
||||
case (Fortran::semantics::DerivedTypeSpec::Category::DerivedType):
|
||||
Fortran::common::die("Vector element type not implemented");
|
||||
}
|
||||
return buf;
|
||||
|
||||
return common::FormatVectorTypeAsFortran(
|
||||
static_cast<int>(category()), vecElemCategory, vecElemKind);
|
||||
}
|
||||
|
||||
std::string DerivedTypeSpec::AsFortran() const {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "flang/Support/Fortran.h"
|
||||
#include "flang/Support/Fortran-features.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace Fortran::common {
|
||||
|
||||
|
|
@ -181,4 +182,39 @@ bool AreCompatibleCUDADataAttrs(std::optional<CUDADataAttr> x,
|
|||
}
|
||||
}
|
||||
|
||||
std::string FormatVectorTypeAsFortran(
|
||||
int category, int64_t elementCategory, int64_t elementKind) {
|
||||
std::string buf;
|
||||
llvm::raw_string_ostream ss{buf};
|
||||
|
||||
switch (static_cast<VectorTypeCategory>(category)) {
|
||||
case (VectorTypeCategory::IntrinsicVector): {
|
||||
CHECK(elementCategory >= 0 && elementKind > 0);
|
||||
ss << "vector(";
|
||||
switch (static_cast<VectorElementCategory>(elementCategory)) {
|
||||
case VectorElementCategory::Integer:
|
||||
ss << "integer(" << elementKind << ")";
|
||||
break;
|
||||
case VectorElementCategory::Unsigned:
|
||||
ss << "unsigned(" << elementKind << ")";
|
||||
break;
|
||||
case VectorElementCategory::Real:
|
||||
ss << "real(" << elementKind << ")";
|
||||
break;
|
||||
}
|
||||
ss << ")";
|
||||
break;
|
||||
}
|
||||
case (VectorTypeCategory::PairVector):
|
||||
ss << "__vector_pair";
|
||||
break;
|
||||
case (VectorTypeCategory::QuadVector):
|
||||
ss << "__vector_quad";
|
||||
break;
|
||||
default:
|
||||
CHECK(false && "Vector element type not implemented");
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
} // namespace Fortran::common
|
||||
|
|
|
|||
15
flang/test/Semantics/PowerPC/ppc-vector-diagnostics.f90
Normal file
15
flang/test/Semantics/PowerPC/ppc-vector-diagnostics.f90
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
! RUN: %python %S/../test_errors.py %s %flang_fc1
|
||||
! REQUIRES: target=powerpc{{.*}}
|
||||
|
||||
subroutine test_vector_add()
|
||||
vector(integer(4)) :: v1, v2
|
||||
!ERROR: Operands of + must be numeric; have vector(integer(4)) and vector(integer(4))
|
||||
v1 = v1 + v2
|
||||
end subroutine
|
||||
|
||||
subroutine test_vector_assignment()
|
||||
vector(integer(4)) :: v1
|
||||
vector(real(4)) :: v2
|
||||
!ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches operand types vector(integer(4)) and vector(real(4))
|
||||
v1 = v2
|
||||
end subroutine
|
||||
Loading…
Reference in a new issue