static_cast<int>(e), #__VA_ARGS__); \
}
+// Check that a pointer is non-null and dereference it
+#define DEREF(p) Fortran::common::Deref(p, __FILE__, __LINE__)
+
+template<typename T> T &Deref(T *p, const char *file, int line) {
+ if (p == nullptr) {
+ Fortran::common::die("nullptr dereference at %s(%d)", file, line);
+ }
+ return *p;
+}
+
// Given a const reference to a value, return a copy of the value.
template<typename A> A Clone(const A &x) { return x; }
void AssignmentContext::Analyze(
const parser::WhereConstruct::Elsewhere &elsewhere) {
- CHECK(where_ != nullptr);
- MaskExpr copyCumulative{where_->cumulativeMaskExpr};
+ MaskExpr copyCumulative{DEREF(where_).cumulativeMaskExpr};
where_->thisMaskExpr = evaluate::LogicalNegation(std::move(copyCumulative));
for (const auto &x :
std::get<std::list<parser::WhereBodyConstruct>>(elsewhere.t)) {
}
void AssignmentContext::Analyze(const parser::ConcurrentHeader &header) {
- CHECK(forall_ != nullptr);
- forall_->integerKind = GetIntegerKind(
+ DEREF(forall_).integerKind = GetIntegerKind(
std::get<std::optional<parser::IntegerTypeSpec>>(header.t));
for (const auto &control :
std::get<std::list<parser::ConcurrentControl>>(header.t)) {
}
if (info.gotSrc || info.gotMold) {
- CHECK(parserSourceExpr);
- if (const auto *expr{GetExpr(*parserSourceExpr)}) {
+ if (const auto *expr{GetExpr(DEREF(parserSourceExpr))}) {
info.sourceExprType = expr->GetType();
if (!info.sourceExprType.has_value()) {
CHECK(context.AnyFatalError());
return true;
}
if (const IntrinsicTypeSpec * intrinsicType1{type1.AsIntrinsic()}) {
- const IntrinsicTypeSpec *intrinsicType2{type2.AsIntrinsic()};
- CHECK(intrinsicType2); // Violation of type compatibility hypothesis.
- return intrinsicType1->kind() == intrinsicType2->kind();
+ return intrinsicType1->kind() == DEREF(type2.AsIntrinsic()).kind();
} else if (const DerivedTypeSpec * derivedType1{type1.AsDerived()}) {
- const DerivedTypeSpec *derivedType2{type2.AsDerived()};
- CHECK(derivedType2); // Violation of type compatibility hypothesis.
- return HaveCompatibleKindParameters(*derivedType1, *derivedType2);
+ return HaveCompatibleKindParameters(
+ *derivedType1, DEREF(type2.AsDerived()));
} else {
common::die("unexpected type1 category");
}
[&](auto &&ckExpr) -> MaybeExpr {
using Result = ResultType<decltype(ckExpr)>;
auto *cp{std::get_if<Constant<Result>>(&ckExpr.u)};
- CHECK(cp != nullptr); // the parent was parsed as a constant string
- CHECK(cp->size() == 1);
+ CHECK(DEREF(cp).size() == 1);
StaticDataObject::Pointer staticData{StaticDataObject::Create()};
staticData->set_alignment(Result::kind)
.set_itemBytes(Result::kind)
ProcedureRef{std::move(proc), std::move(arguments)}};
} else {
// Not a procedure pointer, so type and shape are known.
- const auto *typeAndShape{result.GetTypeAndShape()};
- CHECK(typeAndShape != nullptr);
- return TypedWrapper<FunctionRef, ProcedureRef>(typeAndShape->type(),
+ return TypedWrapper<FunctionRef, ProcedureRef>(
+ DEREF(result.GetTypeAndShape()).type(),
ProcedureRef{std::move(proc), std::move(arguments)});
}
}
template<typename T> void DoExpr(evaluate::Expr<T> expr) {
evaluate::Visitor<SymbolVisitor> visitor{0};
for (const Symbol *symbol : visitor.Traverse(expr)) {
- CHECK(symbol && "bad symbol from Traverse");
- DoSymbol(*symbol);
+ DoSymbol(DEREF(symbol));
}
}
};
}
// sort normal symbols, then namelists, then common blocks:
auto compareByOrder = [](const Symbol *x, const Symbol *y) {
- CHECK(x != nullptr);
- return x->name().begin() < y->name().begin();
+ return DEREF(x).name().begin() < DEREF(y).name().begin();
};
auto cursor{sorted.begin()};
std::sort(cursor, sorted.end(), compareByOrder);
void PutObjectEntity(std::ostream &os, const Symbol &symbol) {
auto &details{symbol.get<ObjectEntityDetails>()};
- PutEntity(os, symbol, [&]() {
- auto *type{symbol.GetType()};
- CHECK(type);
- PutLower(os, *type);
- });
+ PutEntity(os, symbol, [&]() { PutLower(os, DEREF(symbol.GetType())); });
PutShape(os, details.shape(), '(', ')');
PutShape(os, details.coshape(), '[', ']');
PutInit(os, details.init());
void PutTypeParam(std::ostream &os, const Symbol &symbol) {
auto &details{symbol.get<TypeParamDetails>()};
PutEntity(os, symbol, [&]() {
- auto *type{symbol.GetType()};
- CHECK(type);
- PutLower(os, *type);
+ PutLower(os, DEREF(symbol.GetType()));
PutLower(os << ',', common::EnumToString(details.attr()));
});
PutInit(os, details.init());
DoSymbol(details.result());
}
for (const Symbol *dummyArg : details.dummyArgs()) {
- CHECK(dummyArg);
- DoSymbol(*dummyArg);
+ DoSymbol(DEREF(dummyArg));
}
for (const auto &pair : scope_) {
const Symbol *symbol{pair.second};
void ScopeHandler::SayDerivedType(
const SourceName &name, MessageFixedText &&msg, const Scope &type) {
const Symbol *typeSymbol{type.GetSymbol()};
- CHECK(typeSymbol != nullptr);
- Say(name, std::move(msg), name, typeSymbol->name())
+ Say(name, std::move(msg), name, DEREF(typeSymbol).name())
.Attach(typeSymbol->name(), "Declaration of derived type '%s'"_en_US,
typeSymbol->name());
}
void Scope::set_chars(parser::CookedSource &cooked) {
CHECK(kind_ == Kind::Module);
CHECK(parent_.IsGlobal() || parent_.IsModuleFile());
- CHECK(symbol_ != nullptr);
- CHECK(symbol_->test(Symbol::Flag::ModFile));
+ CHECK(DEREF(symbol_).test(Symbol::Flag::ModFile));
// TODO: Preserve the CookedSource rather than acquiring its string.
chars_ = cooked.AcquireData();
}
const Symbol *GetSymbol() const;
const Scope *GetDerivedTypeParent() const;
- const SourceName &name() const {
- const Symbol *sym{GetSymbol()};
- CHECK(sym != nullptr);
- return sym->name();
- }
+ const SourceName &name() const { return DEREF(GetSymbol()).name(); }
/// Make a scope nested in this one
Scope &MakeScope(Kind kind, Symbol *symbol = nullptr);
-// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
+// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
void SymbolDumpVisitor::Post(const parser::Name &name) {
if (const auto *symbol{name.symbol}) {
if (!symbol->has<MiscDetails>()) {
- CHECK(currStmt_);
- symbols_.emplace(currStmt_->begin(), symbol);
+ symbols_.emplace(DEREF(currStmt_).begin(), symbol);
}
}
}