[flang] Adapt to new directory for idioms.cc, idioms.h.
authorTim Keith <tkeith@nvidia.com>
Wed, 7 Feb 2018 23:19:54 +0000 (15:19 -0800)
committerTim Keith <tkeith@nvidia.com>
Wed, 7 Feb 2018 23:19:54 +0000 (15:19 -0800)
Change idioms.h so that calls to die will work outside the parser
namespace.

Use unordered_map to cache IntConst values.

Original-commit: flang-compiler/f18@9d06c385d9f2d9598f8e882d3badc9544c3567b9
Reviewed-on: https://github.com/flang-compiler/f18/pull/3

flang/CMakeLists.txt
flang/attr.cc
flang/attr.h
flang/lib/parser/idioms.h
flang/type.cc
flang/type.h

index 08bd5f6..ac02d18 100644 (file)
@@ -20,4 +20,4 @@ set(SOURCES
   lib/parser/source.cc
 )
 add_executable(f18 ${SOURCES})
-add_executable(type-test type.cc idioms.cc attr.cc)
+add_executable(type-test type.cc attr.cc lib/parser/idioms.cc)
index 859642d..9c906e5 100644 (file)
@@ -44,7 +44,7 @@ void checkAttrs(std::string className, Attrs attrs, Attrs allowed) {
     if (allowed.find(attr) == allowed.end()) {
       std::stringstream temp;
       temp << attr;
-      die("invalid attribute '%s' for class %s", temp.str().c_str(),
+      parser::die("invalid attribute '%s' for class %s", temp.str().c_str(),
           className.c_str());
     }
   }
index f510974..56cc6e8 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef FORTRAN_ATTR_H_
 #define FORTRAN_ATTR_H_
 
-#include "idioms.h"
+#include "lib/parser/idioms.h"
 #include <iostream>
 #include <set>
 #include <string>
index 34a71ce..e988688 100644 (file)
@@ -62,11 +62,15 @@ template<typename A> bool operator!(const std::optional<A> &x) {
 }  // namespace Fortran
 
 // For switch statements without default: labels.
-#define CRASH_NO_CASE die("no case at " __FILE__ "(%d)", __LINE__)
+#define CRASH_NO_CASE \
+  Fortran::parser::die("no case at " __FILE__ "(%d)", __LINE__)
 
 // For cheap assertions that should be applied in production.
 #define CHECK(x) \
-  ((x) || (die("CHECK(" #x ") failed at " __FILE__ "(%d)", __LINE__), false))
+  ((x) || \
+      (Fortran::parser::die( \
+           "CHECK(" #x ") failed at " __FILE__ "(%d)", __LINE__), \
+          false))
 
 // To make error messages more informative, wrap some type information
 // around a false compile-time value, e.g.
index 3b5812a..37cafe6 100644 (file)
@@ -16,35 +16,32 @@ static void checkParams(
     Name name = def.name();
     validNames.insert(name);
     if (!def.defaultValue() && values.find(name) == values.end()) {
-      die("no value or default value for %s parameter '%s'", kindOrLen.c_str(),
+      parser::die("no value or default value for %s parameter '%s'", kindOrLen.c_str(),
           name.c_str());
     }
   }
   for (auto pair : values) {
     Name name = pair.first;
     if (validNames.find(name) == validNames.end()) {
-      die("invalid %s parameter '%s'", kindOrLen.c_str(), name.c_str());
+      parser::die("invalid %s parameter '%s'", kindOrLen.c_str(), name.c_str());
     }
   }
 }
 
-const IntConst IntConst::ZERO = IntConst{0};
-const IntConst IntConst::ONE = IntConst{1};
-
-const IntExpr *IntConst::clone() const {
-  if (*this == ZERO) {
-    return &ZERO;
-  } else if (*this == ONE) {
-    return &ONE;
-  } else {
-    return new IntConst{*this};
-  }
-}
+std::unordered_map<int, IntConst> IntConst::cache;
 
 std::ostream &operator<<(std::ostream &o, const KindParamValue &x) {
   return o << x.value_;
 }
 
+const IntConst &IntConst::make(int value) {
+  auto it = cache.find(value);
+  if (it == cache.end()) {
+    it = cache.insert({value, IntConst{value}}).first;
+  }
+  return it->second;
+}
+
 const LenParamValue LenParamValue::ASSUMED =
     LenParamValue(LenParamValue::Assumed);
 const LenParamValue LenParamValue::DEFERRED =
@@ -196,7 +193,7 @@ void testTypeSpec() {
   std::cout << r2 << "\n";
   CharacterTypeSpec c1{LenParamValue::DEFERRED, 1};
   std::cout << c1 << "\n";
-  CharacterTypeSpec c2{IntConst{10}};
+  CharacterTypeSpec c2{IntConst::make(10)};
   std::cout << c2 << "\n";
 
   IntegerTypeSpec i1 = IntegerTypeSpec::make();
@@ -223,21 +220,21 @@ void testTypeSpec() {
 }
 
 void testShapeSpec() {
-  IntConst ten{10};
+  const IntConst &ten{IntConst::make(10)};
   const ShapeSpec s1{ShapeSpec::makeExplicit(ten)};
   std::cout << "explicit-shape-spec: " << s1 << "\n";
-  ShapeSpec s2{ShapeSpec::makeExplicit(IntConst{2}, IntConst{8})};
+  ShapeSpec s2{ShapeSpec::makeExplicit(IntConst::make(2), IntConst::make(8))};
   std::cout << "explicit-shape-spec: " << s2 << "\n";
 
   ShapeSpec s3{ShapeSpec::makeAssumed()};
   std::cout << "assumed-shape-spec:  " << s3 << "\n";
-  ShapeSpec s4{ShapeSpec::makeAssumed(IntConst{2})};
+  ShapeSpec s4{ShapeSpec::makeAssumed(IntConst::make(2))};
   std::cout << "assumed-shape-spec:  " << s4 << "\n";
 
   ShapeSpec s5{ShapeSpec::makeDeferred()};
   std::cout << "deferred-shape-spec: " << s5 << "\n";
 
-  ShapeSpec s6{ShapeSpec::makeImplied(IntConst{2})};
+  ShapeSpec s6{ShapeSpec::makeImplied(IntConst::make(2))};
   std::cout << "implied-shape-spec:  " << s6 << "\n";
 
   ShapeSpec s7{ShapeSpec::makeAssumedRank()};
index 0a198f7..bfbaf94 100644 (file)
@@ -2,7 +2,7 @@
 #define FORTRAN_TYPE_H_
 
 #include "attr.h"
-#include "idioms.h"
+#include "lib/parser/idioms.h"
 #include <algorithm>
 #include <list>
 #include <map>
@@ -11,6 +11,7 @@
 #include <ostream>
 #include <sstream>
 #include <string>
+#include <unordered_map>
 #include <vector>
 
 /*
@@ -56,31 +57,30 @@ std::ostream &operator<<(std::ostream &o, const IntExpr &x) {
 // TODO
 class IntConst : public IntExpr {
 public:
-  static const IntConst ZERO;
-  static const IntConst ONE;
-  IntConst(int value) : value_{value} {}
-  virtual const IntExpr *clone() const;
+  static const IntConst &make(int value);
+  virtual const IntExpr *clone() const { return &make(value_); }
   bool operator==(const IntConst &x) const { return value_ == x.value_; }
   bool operator!=(const IntConst &x) const { return !operator==(x); }
   bool operator<(const IntConst &x) const { return value_ < x.value_; }
   virtual std::ostream &output(std::ostream &o) const {
     return o << this->value_;
   }
-
 private:
+  static std::unordered_map<int, IntConst> cache;
+  IntConst(int value) : value_{value} {}
   const int value_;
 };
 
 // The value of a kind type parameter
 class KindParamValue {
 public:
-  KindParamValue(int value) : value_{value} {}
+  KindParamValue(int value) : value_{IntConst::make(value)} {}
   bool operator==(const KindParamValue &x) const { return value_ == x.value_; }
   bool operator!=(const KindParamValue &x) const { return !operator==(x); }
   bool operator<(const KindParamValue &x) const { return value_ < x.value_; }
 
 private:
-  const IntConst value_;
+  const IntConst &value_;
   friend std::ostream &operator<<(std::ostream &, const KindParamValue &);
 };
 
@@ -267,8 +267,8 @@ using LenParamValues = std::map<Name, LenParamValue>;
 // Instantiation of a DerivedTypeDef with kind and len parameter values
 class DerivedTypeSpec : public TypeSpec {
 public:
-  DerivedTypeSpec(DerivedTypeDef def, KindParamValues kindParamValues{},
-      LenParamValues lenParamValues{});
+  DerivedTypeSpec(DerivedTypeDef def, KindParamValues kindParamValues = {},
+      LenParamValues lenParamValues = {});
 
 private:
   const DerivedTypeDef def_;
@@ -348,7 +348,7 @@ public:
 
 private:
   enum Category { Explicit, Deferred, Assumed };
-  Bound(Category category) : category_{category}, expr_{&IntConst::ZERO} {}
+  Bound(Category category) : category_{category}, expr_{&IntConst::make(0)} {}
   const Category category_;
   const IntExpr *const expr_;
   friend std::ostream &operator<<(std::ostream &, const Bound &);
@@ -362,10 +362,10 @@ public:
   }
   // 1:ub
   static const ShapeSpec makeExplicit(const Bound &ub) {
-    return makeExplicit(IntConst::ONE, ub);
+    return makeExplicit(IntConst::make(1), ub);
   }
   // 1: or lb:
-  static ShapeSpec makeAssumed(const Bound &lb = IntConst::ONE) {
+  static ShapeSpec makeAssumed(const Bound &lb = IntConst::make(1)) {
     return ShapeSpec(lb, Bound::DEFERRED);
   }
   // :