summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarphaman <arphaman@gmail.com>2013-09-13 11:09:03 +0100
committerarphaman <arphaman@gmail.com>2013-09-13 11:09:03 +0100
commit715ff12488de990af7f5ed3929110d0a610666da (patch)
tree0b8a64d22ccfa1640ce9cb51d7c862f1b34071a2
parentfbafdc64bcd3e478776b63fd716748a94550eed1 (diff)
downloadflang-715ff12488de990af7f5ed3929110d0a610666da.tar.gz
added unittest for expr evaluation, fixed data sema test
-rw-r--r--CMakeLists.txt6
-rw-r--r--include/flang/AST/Expr.h2
-rw-r--r--lib/AST/ExprConstant.cpp8
-rw-r--r--test/Sema/data.f956
-rw-r--r--unittests/AST/CMakeLists.txt12
-rw-r--r--unittests/AST/ExprEvaluator.cpp113
-rw-r--r--unittests/CMakeLists.txt1
7 files changed, 135 insertions, 13 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index af18932bd4..3e81f2aaa9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -276,9 +276,9 @@ add_subdirectory(tools)
add_subdirectory(test)
if( LLVM_INCLUDE_TESTS )
- if( NOT FLANG_BUILT_STANDALONE )
-# add_subdirectory(unittests)
- endif()
+ # if( NOT FLANG_BUILT_STANDALONE )
+ add_subdirectory(unittests)
+ #endif()
endif()
# Workaround for MSVS10 to avoid the Dialog Hell
diff --git a/include/flang/AST/Expr.h b/include/flang/AST/Expr.h
index da53838ddb..1ab68f1335 100644
--- a/include/flang/AST/Expr.h
+++ b/include/flang/AST/Expr.h
@@ -211,7 +211,7 @@ public:
static IntegerConstantExpr *Create(ASTContext &C, SourceLocation Loc,
SourceLocation MaxLoc, APInt Value);
static IntegerConstantExpr *Create(ASTContext &C, int64_t Value) {
- return Create(C, SourceLocation(), SourceLocation(), APInt(64, Value));
+ return Create(C, SourceLocation(), SourceLocation(), APInt(64, Value, true));
}
APInt getValue() const { return Num.getValue(); }
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index e0f08b5d7c..984f23f83a 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -128,12 +128,8 @@ struct IntValueTy : public llvm::APInt {
template<typename T = int64_t>
bool Assign(const llvm::APInt &I) {
auto u64 = I.getLimitedValue();
- if(u64 <= uint64_t(std::numeric_limits<T>::max())) {
- *this = IntValueTy(u64);
- return true;
- }
- *this = IntValueTy(1);
- return false;
+ *this = IntValueTy(u64);
+ return true;
}
};
diff --git a/test/Sema/data.f95 b/test/Sema/data.f95
index 5301f24974..d0dcd496bc 100644
--- a/test/Sema/data.f95
+++ b/test/Sema/data.f95
@@ -107,7 +107,7 @@ subroutine sub3
data ((i_mat(i,j), j = 1,two), i = 1,2) / 4*3 / ! CHECK: i_mat = (/3, 3, 3, 3 /)
data (i_arr(i), i = 1,3), i_arr(4) / 11,12,13,14 / ! CHECK: i_arr = (/11, 12, 13, 14 /)
- data i_arr(-2), (i_arr2(i), i = -1,2) / 100, 101, &
+ data i_arr2(-2), (i_arr2(i), i = -1,2) / 100, 101, &
102, 103, 104 / ! CHECK: i_arr2 = (/100, 101, 102, 103, 104 /)
end
@@ -132,8 +132,8 @@ subroutine sub5
type(point) pArr2(3)
data p1 / Point(-1,1) / p2%x, p2%y / 13, 42 / ! CHECK: p2 = point(13, 42)
- data pArr / 2*Point(0,7), Point(1,1) / ! CHECK: pArr = (/point(0,7), point(0,7), point(1,1) /)
- data pArr2(1)%x, pArr2(1)%y / 2*16 / ! CHECK: pArr2 = (/point(16,16), point(1,2), point(3,4) /)
+ data pArr / 2*Point(0,7), Point(1,1) / ! CHECK: parr = (/point(0, 7), point(0, 7), point(1, 1) /)
+ data pArr2(1)%x, pArr2(1)%y / 2*16 / ! CHECK: parr2 = (/point(16, 16), point(1, 2), point(3, 4) /)
data pArr2(2), parr2(3) / point(1,2), point(3,4) /
! FIXME: TODO: data (pArr2(i)%x, pArr2(i)%y, i = 2,3) / 1, 2, 3, 4 /
diff --git a/unittests/AST/CMakeLists.txt b/unittests/AST/CMakeLists.txt
new file mode 100644
index 0000000000..75fec72198
--- /dev/null
+++ b/unittests/AST/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_flang_executable(exprEvaluatorTest
+ ExprEvaluator.cpp
+ )
+
+target_link_libraries(exprEvaluatorTest
+ flangAST
+ flangFrontend
+ flangParse
+ flangSema
+ flangBasic
+ flangCodeGen
+ )
diff --git a/unittests/AST/ExprEvaluator.cpp b/unittests/AST/ExprEvaluator.cpp
new file mode 100644
index 0000000000..d38688e4f7
--- /dev/null
+++ b/unittests/AST/ExprEvaluator.cpp
@@ -0,0 +1,113 @@
+//===-- ExprEvaluator.cpp - Unittests for expression evaluation methosds --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/AST/ASTContext.h"
+#include "flang/AST/Expr.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace flang;
+
+bool CheckEvaluatable(ASTContext &C, const Expr *E, bool Value = true) {
+ if(E->isEvaluatable(C) != Value) {
+ llvm::errs() << "Expected an evaluatable expression\n";
+ return true;
+ }
+ return false;
+}
+
+bool CheckIntValue(ASTContext &C, const Expr *E, int64_t Value) {
+ int64_t X = 0;
+ if(!E->EvaluateAsInt(X, C)) {
+ llvm::errs() << "Failed to evaluate an integer expression \n";
+ return true;
+ }
+ if(X != Value) {
+ llvm::errs() << "Expected " << Value << " instead of " << X << "\n";
+ return true;
+ }
+ return false;
+}
+
+bool CheckArrayElementOffset(ASTContext &C, const ArrayElementExpr *E, uint64_t Value) {
+ uint64_t Offset = 0;
+ if(!E->EvaluateOffset(C, Offset)) {
+ llvm::errs() << "Failed to evaluate an array element offset\n";
+ return true;
+ }
+ if(Offset != Value) {
+ llvm::errs() << "Expected offset of " << Value << " instead of " << Offset << "\n";
+ return true;
+ }
+ return false;
+}
+
+int test(ASTContext &C) {
+ auto Int = IntegerConstantExpr::Create(C, 13);
+ if(CheckEvaluatable(C, Int)) return 1;
+ if(CheckIntValue(C, Int, 13)) return 1;
+ auto Int2 = IntegerConstantExpr::Create(C, -11);
+ if(CheckEvaluatable(C, Int2)) return 1;
+ if(CheckIntValue(C, Int2, -11)) return 1;
+
+
+ // unary operations
+ auto Neg = UnaryExpr::Create(C, SourceLocation(), UnaryExpr::Minus, Int);
+ if(CheckEvaluatable(C, Neg)) return 1;
+ if(CheckIntValue(C, Neg, -13)) return 1;
+
+ auto Pos = UnaryExpr::Create(C, SourceLocation(), UnaryExpr::Plus, Int);
+ if(CheckEvaluatable(C, Pos)) return 1;
+ if(CheckIntValue(C, Pos, 13)) return 1;
+
+
+ // binary operations
+ auto Sum = BinaryExpr::Create(C, SourceLocation(), BinaryExpr::Plus, Int->getType(), Int, Int2);
+ if(CheckEvaluatable(C, Sum)) return 1;
+ if(CheckIntValue(C, Sum, 2)) return 1;
+
+ auto Diff = BinaryExpr::Create(C, SourceLocation(), BinaryExpr::Minus, Int->getType(), Neg, Int2);
+ if(CheckEvaluatable(C, Diff)) return 1;
+ if(CheckIntValue(C, Diff, -2)) return 1;
+
+ auto Prod = BinaryExpr::Create(C, SourceLocation(), BinaryExpr::Multiply, Int->getType(), Int, Int2);
+ if(CheckEvaluatable(C, Prod)) return 1;
+ if(CheckIntValue(C, Prod, -143)) return 1;
+
+ auto Div = BinaryExpr::Create(C, SourceLocation(), BinaryExpr::Divide, Int->getType(), Neg, Int2);
+ if(CheckEvaluatable(C, Div)) return 1;
+ if(CheckIntValue(C, Div, 1)) return 1;
+
+
+ // array element offset
+ Expr *Items[5] = { Int, Int, Int, Int, Int };
+ auto Dim = ExplicitShapeSpec::Create(C, IntegerConstantExpr::Create(C, -2), IntegerConstantExpr::Create(C, 2));
+ auto AVal = ArrayConstructorExpr::Create(C, SourceLocation(), Items, C.getArrayType(Int->getType(), Dim));
+ if(CheckArrayElementOffset(C, ArrayElementExpr::Create(C, SourceLocation(), AVal, IntegerConstantExpr::Create(C, -2)), 0))
+ return 1;
+ if(CheckArrayElementOffset(C, ArrayElementExpr::Create(C, SourceLocation(), AVal, IntegerConstantExpr::Create(C, -1)), 1))
+ return 1;
+ if(CheckArrayElementOffset(C, ArrayElementExpr::Create(C, SourceLocation(), AVal, IntegerConstantExpr::Create(C, 0)), 2))
+ return 1;
+ if(CheckArrayElementOffset(C, ArrayElementExpr::Create(C, SourceLocation(), AVal, IntegerConstantExpr::Create(C, 1)), 3))
+ return 1;
+ if(CheckArrayElementOffset(C, ArrayElementExpr::Create(C, SourceLocation(), AVal, IntegerConstantExpr::Create(C, 2)), 4))
+ return 1;
+
+ return 0;
+}
+
+int main() {
+ auto SM = new llvm::SourceMgr();
+ auto Context = new ASTContext(*SM, LangOptions());
+ auto Result = test(*Context);
+ delete Context;
+ delete SM;
+ return Result;
+}
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
new file mode 100644
index 0000000000..f16f15395b
--- /dev/null
+++ b/unittests/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(AST)