Skip to content

Commit

Permalink
Merged main:b607837c75d0 into amd-gfx:e52924087542
Browse files Browse the repository at this point in the history
Local branch amd-gfx e529240 Merged main:e5039aad4574 into amd-gfx:81245c8cf516
Remote branch main b607837 [libomptarget][nfc] Replace static const with enum
  • Loading branch information
Sw authored and Sw committed Dec 16, 2020
2 parents e529240 + b607837 commit 9e86972
Show file tree
Hide file tree
Showing 18 changed files with 355 additions and 99 deletions.
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -3346,7 +3346,7 @@ As ``global_device`` and ``global_host`` are a subset of
``__global/opencl_global`` address spaces it is allowed to convert
``global_device`` and ``global_host`` address spaces to
``__global/opencl_global`` address spaces (following ISO/IEC TR 18037 5.1.3
"Address space nesting and rules for pointers).
"Address space nesting and rules for pointers").
}];
}

Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5965,8 +5965,9 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T,
return QualType();
}

return Context.getConstantArrayType(ElemTy, Res, VLATy->getSizeExpr(),
ArrayType::Normal, 0);
QualType FoldedArrayType = Context.getConstantArrayType(
ElemTy, Res, VLATy->getSizeExpr(), ArrayType::Normal, 0);
return Qs.apply(Context, FoldedArrayType);
}

static void
Expand Down
12 changes: 12 additions & 0 deletions clang/test/SemaObjC/arc.m
Original file line number Diff line number Diff line change
Expand Up @@ -839,3 +839,15 @@ void block_capture_autoreleasing(A * __autoreleasing *a,
(void)*l;
}();
}

void test_vla_fold_keeps_strong(void) {
const unsigned bounds = 1;

static id array[bounds]; // expected-warning {{variable length array folded to constant array as an extension}}
typedef __typeof__(array) array_type;
typedef id __strong array_type[1];

static id weak_array[bounds] __weak; // expected-warning {{variable length array folded to constant array as an extension}}
typedef __typeof__(weak_array) weak_array_type;
typedef id __weak weak_array_type[1];
}
5 changes: 3 additions & 2 deletions flang/include/flang/Evaluate/constant.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ template <typename T> class Constant : public ConstantBase<T> {
}
}

// Apply subscripts.
// Apply subscripts. An empty subscript list is allowed for
// a scalar constant.
Element At(const ConstantSubscripts &) const;

Constant Reshape(ConstantSubscripts &&) const;
Expand Down Expand Up @@ -177,7 +178,7 @@ class Constant<Type<TypeCategory::Character, KIND>> : public ConstantBounds {
}
}

// Apply subscripts
// Apply subscripts, if any.
Scalar<Result> At(const ConstantSubscripts &) const;

Constant Reshape(ConstantSubscripts &&) const;
Expand Down
36 changes: 14 additions & 22 deletions flang/lib/Evaluate/fold-implementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,8 @@ Expr<TR> FoldElementalIntrinsicHelper(FoldingContext &context,
// Compute the shape of the result based on shapes of arguments
ConstantSubscripts shape;
int rank{0};
const ConstantSubscripts *shapes[sizeof...(TA)]{
&std::get<I>(*args)->shape()...};
const int ranks[sizeof...(TA)]{std::get<I>(*args)->Rank()...};
const ConstantSubscripts *shapes[]{&std::get<I>(*args)->shape()...};
const int ranks[]{std::get<I>(*args)->Rank()...};
for (unsigned int i{0}; i < sizeof...(TA); ++i) {
if (ranks[i] > 0) {
if (rank == 0) {
Expand All @@ -470,20 +469,19 @@ Expr<TR> FoldElementalIntrinsicHelper(FoldingContext &context,
std::vector<Scalar<TR>> results;
if (TotalElementCount(shape) > 0) {
ConstantBounds bounds{shape};
ConstantSubscripts index(rank, 1);
ConstantSubscripts resultIndex(rank, 1);
ConstantSubscripts argIndex[]{std::get<I>(*args)->lbounds()...};
do {
if constexpr (std::is_same_v<WrapperType<TR, TA...>,
ScalarFuncWithContext<TR, TA...>>) {
results.emplace_back(func(context,
(ranks[I] ? std::get<I>(*args)->At(index)
: std::get<I>(*args)->GetScalarValue().value())...));
results.emplace_back(
func(context, std::get<I>(*args)->At(argIndex[I])...));
} else if constexpr (std::is_same_v<WrapperType<TR, TA...>,
ScalarFunc<TR, TA...>>) {
results.emplace_back(func(
(ranks[I] ? std::get<I>(*args)->At(index)
: std::get<I>(*args)->GetScalarValue().value())...));
results.emplace_back(func(std::get<I>(*args)->At(argIndex[I])...));
}
} while (bounds.IncrementSubscripts(index));
(std::get<I>(*args)->IncrementSubscripts(argIndex[I]), ...);
} while (bounds.IncrementSubscripts(resultIndex));
}
// Build and return constant result
if constexpr (TR::category == TypeCategory::Character) {
Expand Down Expand Up @@ -732,17 +730,11 @@ template <typename T> class ArrayConstructorFolder {
Expr<T> folded{Fold(context_, common::Clone(expr.value()))};
if (const auto *c{UnwrapConstantValue<T>(folded)}) {
// Copy elements in Fortran array element order
ConstantSubscripts shape{c->shape()};
int rank{c->Rank()};
ConstantSubscripts index(GetRank(shape), 1);
for (std::size_t n{c->size()}; n-- > 0;) {
elements_.emplace_back(c->At(index));
for (int d{0}; d < rank; ++d) {
if (++index[d] <= shape[d]) {
break;
}
index[d] = 1;
}
if (c->size() > 0) {
ConstantSubscripts index{c->lbounds()};
do {
elements_.emplace_back(c->At(index));
} while (c->IncrementSubscripts(index));
}
return true;
} else {
Expand Down
74 changes: 43 additions & 31 deletions flang/lib/Semantics/resolve-names-utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ using common::NumericOperator;
using common::RelationalOperator;
using IntrinsicOperator = parser::DefinedOperator::IntrinsicOperator;

static constexpr const char *operatorPrefix{"operator("};

static GenericKind MapIntrinsicOperator(IntrinsicOperator);

Symbol *Resolve(const parser::Name &name, Symbol *symbol) {
Expand Down Expand Up @@ -65,6 +67,37 @@ bool IsIntrinsicOperator(
return false;
}

template <typename E>
std::forward_list<std::string> GetOperatorNames(
const SemanticsContext &context, E opr) {
std::forward_list<std::string> result;
for (const char *name : context.languageFeatures().GetNames(opr)) {
result.emplace_front(std::string{operatorPrefix} + name + ')');
}
return result;
}

std::forward_list<std::string> GetAllNames(
const SemanticsContext &context, const SourceName &name) {
std::string str{name.ToString()};
if (!name.empty() && name.end()[-1] == ')' &&
name.ToString().rfind(std::string{operatorPrefix}, 0) == 0) {
for (int i{0}; i != common::LogicalOperator_enumSize; ++i) {
auto names{GetOperatorNames(context, LogicalOperator{i})};
if (std::find(names.begin(), names.end(), str) != names.end()) {
return names;
}
}
for (int i{0}; i != common::RelationalOperator_enumSize; ++i) {
auto names{GetOperatorNames(context, RelationalOperator{i})};
if (std::find(names.begin(), names.end(), str) != names.end()) {
return names;
}
}
}
return {str};
}

bool IsLogicalConstant(
const SemanticsContext &context, const SourceName &name) {
std::string str{name.ToString()};
Expand All @@ -73,37 +106,6 @@ bool IsLogicalConstant(
(str == ".t" || str == ".f."));
}

// The operators <, <=, >, >=, ==, and /= always have the same interpretations
// as the operators .LT., .LE., .GT., .GE., .EQ., and .NE., respectively.
std::forward_list<std::string> GenericSpecInfo::GetAllNames(
SemanticsContext &context) const {
auto getNames{[&](auto opr) {
std::forward_list<std::string> result;
for (const char *name : context.languageFeatures().GetNames(opr)) {
result.emplace_front("operator("s + name + ')');
}
return result;
}};
return std::visit(
common::visitors{[&](const LogicalOperator &x) { return getNames(x); },
[&](const RelationalOperator &x) { return getNames(x); },
[&](const auto &) -> std::forward_list<std::string> {
return {symbolName_.value().ToString()};
}},
kind_.u);
}

Symbol *GenericSpecInfo::FindInScope(
SemanticsContext &context, const Scope &scope) const {
for (const auto &name : GetAllNames(context)) {
auto iter{scope.find(SourceName{name})};
if (iter != scope.end()) {
return &*iter->second;
}
}
return nullptr;
}

void GenericSpecInfo::Resolve(Symbol *symbol) const {
if (symbol) {
if (auto *details{symbol->detailsIf<GenericDetails>()}) {
Expand Down Expand Up @@ -162,6 +164,16 @@ void GenericSpecInfo::Analyze(const parser::GenericSpec &x) {
x.u);
}

llvm::raw_ostream &operator<<(
llvm::raw_ostream &os, const GenericSpecInfo &info) {
os << "GenericSpecInfo: kind=" << info.kind_.ToString();
os << " parseName="
<< (info.parseName_ ? info.parseName_->ToString() : "null");
os << " symbolName="
<< (info.symbolName_ ? info.symbolName_->ToString() : "null");
return os;
}

// parser::DefinedOperator::IntrinsicOperator -> GenericKind
static GenericKind MapIntrinsicOperator(IntrinsicOperator op) {
switch (op) {
Expand Down
12 changes: 8 additions & 4 deletions flang/lib/Semantics/resolve-names-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "flang/Semantics/semantics.h"
#include "flang/Semantics/symbol.h"
#include "flang/Semantics/type.h"
#include "llvm/Support/raw_ostream.h"
#include <forward_list>

namespace Fortran::parser {
Expand Down Expand Up @@ -50,6 +51,11 @@ parser::MessageFixedText WithIsFatal(
bool IsIntrinsicOperator(const SemanticsContext &, const SourceName &);
bool IsLogicalConstant(const SemanticsContext &, const SourceName &);

// Some intrinsic operators have more than one name (e.g. `operator(.eq.)` and
// `operator(==)`). GetAllNames() returns them all, including symbolName.
std::forward_list<std::string> GetAllNames(
const SemanticsContext &, const SourceName &);

template <typename T>
MaybeIntExpr EvaluateIntExpr(SemanticsContext &context, const T &expr) {
if (MaybeExpr maybeExpr{
Expand All @@ -75,13 +81,11 @@ class GenericSpecInfo {

GenericKind kind() const { return kind_; }
const SourceName &symbolName() const { return symbolName_.value(); }
// Some intrinsic operators have more than one name (e.g. `operator(.eq.)` and
// `operator(==)`). GetAllNames() returns them all, including symbolName.
std::forward_list<std::string> GetAllNames(SemanticsContext &) const;
// Set the GenericKind in this symbol and resolve the corresponding
// name if there is one
void Resolve(Symbol *) const;
Symbol *FindInScope(SemanticsContext &, const Scope &) const;
friend llvm::raw_ostream &operator<<(
llvm::raw_ostream &, const GenericSpecInfo &);

private:
GenericKind kind_;
Expand Down
Loading

0 comments on commit 9e86972

Please sign in to comment.