summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarphaman <arphaman@gmail.com>2013-09-13 12:42:19 +0100
committerarphaman <arphaman@gmail.com>2013-09-13 12:42:19 +0100
commit43e78c02ca0fbe7219efb962b2fd8dd03dda318e (patch)
tree41176bac483fd7630e41da65155b8e899712170e
parent715ff12488de990af7f5ed3929110d0a610666da (diff)
downloadflang-43e78c02ca0fbe7219efb962b2fd8dd03dda318e.tar.gz
updated codegen for DATA stmt, added codegen for charater initialization
-rw-r--r--include/flang/AST/Stmt.h17
-rw-r--r--lib/AST/ASTDumper.cpp4
-rw-r--r--lib/AST/Stmt.cpp18
-rw-r--r--lib/CodeGen/CGDecl.cpp162
-rw-r--r--lib/CodeGen/CGExpr.cpp7
-rw-r--r--lib/CodeGen/CGStmt.cpp35
-rw-r--r--lib/CodeGen/CMakeLists.txt1
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp104
-rw-r--r--lib/CodeGen/CodeGenFunction.h7
-rw-r--r--lib/Sema/SemaDataStmt.cpp20
-rw-r--r--test/CodeGen/data.f954
-rw-r--r--test/CodeGenInAction/arrayOperations.f953
-rw-r--r--test/CodeGenInAction/data.f9521
13 files changed, 221 insertions, 182 deletions
diff --git a/include/flang/AST/Stmt.h b/include/flang/AST/Stmt.h
index 175ac07245..fd415c54ef 100644
--- a/include/flang/AST/Stmt.h
+++ b/include/flang/AST/Stmt.h
@@ -606,26 +606,19 @@ class DataStmt : public Stmt {
Stmt *Body;
DataStmt(ASTContext &C, SourceLocation Loc,
- ArrayRef<Expr*> Names,
- ArrayRef<Expr*> Values,
- Stmt *BodyStmt,
- Expr *StmtLabel);
+ ArrayRef<Expr*> Objects,
+ ArrayRef<Expr*> Values, Expr *StmtLabel);
public:
static DataStmt *Create(ASTContext &C, SourceLocation Loc,
- ArrayRef<Expr*> Names,
- ArrayRef<Expr*> Values,
- Stmt *Body,
- Expr *StmtLabel);
+ ArrayRef<Expr*> Objects,
+ ArrayRef<Expr*> Values, Expr *StmtLabel);
- ArrayRef<Expr*> getNames() const {
+ ArrayRef<Expr*> getObjects() const {
return ArrayRef<Expr*>(NameList, NumNames);
}
ArrayRef<Expr*> getValues() const {
return ArrayRef<Expr*>(ValueList, NumValues);
}
- const Stmt *getBody() const {
- return Body;
- }
static bool classof(const DataStmt*) { return true; }
static bool classof(const Stmt *S) {
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 078ca238f6..5131200018 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -461,12 +461,10 @@ void ASTDumper::VisitEquivalenceStmt(const EquivalenceStmt *S) {
void ASTDumper::VisitDataStmt(const DataStmt *S) {
OS << "data ";
- dumpExprList(S->getNames());
+ dumpExprList(S->getObjects());
OS << " / ";
dumpExprList(S->getValues());
OS << " / \n";
- if(S->getBody())
- dumpSubStmt(S->getBody());
}
void ASTDumper::VisitBlockStmt(const BlockStmt *S) {
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 1a57341091..e00ff31803 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -302,15 +302,14 @@ EquivalenceSet *EquivalenceSet::Create(ASTContext &C, ArrayRef<Object> Objects)
//===----------------------------------------------------------------------===//
DataStmt::DataStmt(ASTContext &C, SourceLocation Loc,
- ArrayRef<Expr*> Names,
+ ArrayRef<Expr*> Objects,
ArrayRef<Expr*> Values,
- Stmt *BodyStmt,
Expr *StmtLabel)
- : Stmt(DataStmtClass, Loc, StmtLabel), Body(BodyStmt) {
- NumNames = Names.size();
+ : Stmt(DataStmtClass, Loc, StmtLabel) {
+ NumNames = Objects.size();
NameList = new (C) Expr* [NumNames];
- for(size_t I = 0; I < Names.size(); ++I)
- NameList[I] = Names[I];
+ for(size_t I = 0; I < Objects.size(); ++I)
+ NameList[I] = Objects[I];
NumValues = Values.size();
ValueList = new (C) Expr* [NumValues];
@@ -319,10 +318,9 @@ DataStmt::DataStmt(ASTContext &C, SourceLocation Loc,
}
DataStmt *DataStmt::Create(ASTContext &C, SourceLocation Loc,
- ArrayRef<Expr*> Names,
- ArrayRef<Expr*> Values, Stmt *Body,
- Expr *StmtLabel) {
- return new(C) DataStmt(C, Loc, Names, Values, Body, StmtLabel);
+ ArrayRef<Expr*> Objects,
+ ArrayRef<Expr*> Values, Expr *StmtLabel) {
+ return new(C) DataStmt(C, Loc, Objects, Values, StmtLabel);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
new file mode 100644
index 0000000000..e00566b3ea
--- /dev/null
+++ b/lib/CodeGen/CGDecl.cpp
@@ -0,0 +1,162 @@
+//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Decl nodes as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "flang/AST/Decl.h"
+#include "flang/AST/DeclVisitor.h"
+#include "flang/AST/Expr.h"
+#include "flang/AST/EquivalenceSet.h"
+
+namespace flang {
+namespace CodeGen {
+
+class FuncDeclEmitter : public ConstDeclVisitor<FuncDeclEmitter> {
+ CodeGenFunction &CGF;
+public:
+ FuncDeclEmitter(CodeGenFunction &cgf) : CGF(cgf) {}
+
+ void VisitVarDecl(const VarDecl *D) {
+ CGF.EmitVarDecl(D);
+ }
+};
+
+void CodeGenFunction::EmitFunctionDecls(const DeclContext *DC) {
+ FuncDeclEmitter DV(*this);
+ DV.Visit(DC);
+}
+
+void CodeGenFunction::EmitVarDecl(const VarDecl *D) {
+ if(D->isParameter() ||
+ D->isArgument() ||
+ D->isFunctionResult()) return;
+
+ if(D->hasEquivalenceSet()) {
+ auto Set = EmitEquivalenceSet(D->getEquivalenceSet());
+ auto Ptr = EmitEquivalenceSetObject(Set, D);
+ LocalVariables.insert(std::make_pair(D, Ptr));
+ return;
+ }
+
+ llvm::Value *Ptr;
+ auto Type = D->getType();
+ auto Quals = Type.getExtQualsPtrOrNull();
+ if(Quals && Quals->getQualifiers().hasAttributeSpec(Qualifiers::AS_save) &&
+ !IsMainProgram) {
+ Ptr = CGM.EmitGlobalVariable(CurFn->getName(), D);
+ HasSavedVariables = true;
+ } else {
+ if(Type->isArrayType())
+ Ptr = CreateArrayAlloca(Type, D->getName());
+ else Ptr = Builder.CreateAlloca(ConvertTypeForMem(Type),
+ nullptr, D->getName());
+ }
+ LocalVariables.insert(std::make_pair(D, Ptr));
+}
+
+class VarInitEmitter : public ConstDeclVisitor<VarInitEmitter> {
+ CodeGenFunction &CGF;
+ bool VisitSaveQualified;
+public:
+ VarInitEmitter(CodeGenFunction &cgf, bool VisitSave = false)
+ : CGF(cgf), VisitSaveQualified(VisitSave) {}
+
+ void VisitVarDecl(const VarDecl *D) {
+ if(D->isParameter() || D->isArgument() ||
+ D->isFunctionResult())
+ return;
+ auto Ext = D->getType().getExtQualsPtrOrNull();
+ bool HasSave = Ext && Ext->getQualifiers().hasAttributeSpec(Qualifiers::AS_save);
+ if(HasSave != VisitSaveQualified)
+ return;
+ if(D->hasInit())
+ CGF.EmitVarInitializer(D);
+ }
+};
+
+void CodeGenFunction::EmitVarInitializers(const DeclContext *DC) {
+ VarInitEmitter DV(*this, false);
+ DV.Visit(DC);
+}
+
+void CodeGenFunction::EmitSavedVarInitializers(const DeclContext *DC) {
+ VarInitEmitter DV(*this, true);
+ DV.Visit(DC);
+}
+
+void CodeGenFunction::EmitVarInitializer(const VarDecl *D) {
+ assert(D->hasInit());
+
+ auto T = D->getType();
+ if(T->isArrayType()) {
+ auto Dest = Builder.CreateConstInBoundsGEP2_32(GetVarPtr(D), 0, 0);
+ auto Init = cast<ArrayConstructorExpr>(D->getInit())->getItems();
+ for(size_t I = 0; I < Init.size(); ++I) {
+ auto Val = EmitRValue(Init[I]);
+ EmitStoreCharSameLength(Val, Builder.CreateConstInBoundsGEP1_64(Dest, I), T.getSelfOrArrayElementType());
+ }
+ return;
+ }
+ auto Val = EmitRValue(D->getInit());
+ EmitStoreCharSameLength(Val, GetVarPtr(D), D->getType());
+}
+
+// FIXME: support substrings.
+std::pair<int64_t, int64_t> CodeGenFunction::GetObjectBounds(const VarDecl *Var, const Expr *E) {
+ auto Size = CGM.getDataLayout().getTypeStoreSize(ConvertTypeForMem(Var->getType()));
+ uint64_t Offset = 0;
+ if(auto Arr = dyn_cast<ArrayElementExpr>(E)) {
+ Arr->EvaluateOffset(getContext(), Offset);
+ Offset = Offset * CGM.getDataLayout().getTypeStoreSize(ConvertTypeForMem(E->getType()));
+ } else
+ Offset = 0;
+
+ return std::make_pair(-int64_t(Offset), -int64_t(Offset) + int64_t(Size));
+}
+
+CodeGenFunction::EquivSet CodeGenFunction::EmitEquivalenceSet(const EquivalenceSet *S) {
+ auto Result = EquivSets.find(S);
+ if(Result != EquivSets.end())
+ return Result->second;
+
+ // Find the bounds of the set
+ int64_t LowestBound = 0;
+ int64_t HighestBound = 0;
+ for(auto I : S->getObjects()) {
+ auto Bounds = GetObjectBounds(I.Var, I.E);
+ LowestBound = std::min(Bounds.first, LowestBound);
+ HighestBound = std::max(Bounds.second, HighestBound);
+ LocalVariablesInEquivSets.insert(std::make_pair(I.Var, Bounds.first));
+ }
+ EquivSet Set;
+ // FIXME: more accurate alignment?
+ Set.Ptr= Builder.Insert(new llvm::AllocaInst(CGM.Int8Ty,
+ llvm::ConstantInt::get(CGM.SizeTy, HighestBound - LowestBound),
+ CGM.getDataLayout().getTypeStoreSize(CGM.DoubleTy)),
+ "equivalence-set");
+ Set.LowestBound = LowestBound;
+ EquivSets.insert(std::make_pair(S, Set));
+ return Set;
+}
+
+llvm::Value *CodeGenFunction::EmitEquivalenceSetObject(EquivSet Set, const VarDecl *Var) {
+ // Compute the pointer to the object.
+ auto ObjLowBound = LocalVariablesInEquivSets.find(Var)->second;
+ auto Ptr = Builder.CreateConstInBoundsGEP1_64(Set.Ptr,
+ uint64_t(ObjLowBound - Set.LowestBound));
+ auto T = Var->getType();
+ return Builder.CreatePointerCast(Ptr, llvm::PointerType::get(ConvertTypeForMem(T), 0));
+}
+
+}
+}
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 6e4b6f2468..a16e63e17f 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -69,6 +69,13 @@ void CodeGenFunction::EmitStore(RValueTy Val, LValueTy Dest, QualType T) {
}
}
+void CodeGenFunction::EmitStoreCharSameLength(RValueTy Val, LValueTy Dest, QualType T) {
+ if(!Val.isCharacter())
+ return EmitStore(Val, Dest, T);
+ auto CharVal = Val.asCharacter();
+ Builder.CreateMemCpy(Dest.getPointer(), CharVal.Ptr, CharVal.Len, 1, Dest.isVolatileQualifier());
+}
+
RValueTy CodeGenFunction::EmitBinaryExpr(BinaryExpr::Operator Op, RValueTy LHS, RValueTy RHS) {
if(LHS.isScalar())
return EmitScalarBinaryExpr(Op, LHS.asScalar(), RHS.asScalar());
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 0989777ce2..9d0b3e4db8 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -24,41 +24,6 @@
namespace flang {
namespace CodeGen {
-class DataStmtEmmitter : public ConstStmtVisitor<DataStmtEmmitter> {
- bool InData, Saved;
- CodeGenFunction &CGF;
-public:
- DataStmtEmmitter(CodeGenFunction &cgf, bool SavedOnly)
- : CGF(cgf), InData(false), Saved(SavedOnly) {}
-
- void VisitCompoundStmt(const CompoundStmt *S) {
- for(auto I : S->getBody())
- Visit(I);
- }
- void VisitDataStmt(const DataStmt *S) {
- assert(!InData);
- InData = true;
- Visit(S->getBody());
- InData = false;
- }
- void VisitBlockStmt(const BlockStmt *S) {
- for(auto I : S->getStatements())
- Visit(I);
- }
- void VisitAssignmentStmt(const AssignmentStmt *S) {
- if(!InData || CGF.IsAssignmentStmtAssignmentToSaved(S) != Saved)
- return;
- CGF.EmitAssignmentStmt(S);
- }
-};
-
-void CodeGenFunction::EmitDataStmts(const Stmt *S, bool Saved) {
- DataStmtEmmitter SV(*this, Saved);
- if(S->getStmtLabel())
- EmitStmtLabel(S);
- SV.Visit(S);
-}
-
class StmtEmmitter : public ConstStmtVisitor<StmtEmmitter> {
CodeGenFunction &CGF;
public:
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 4a0c6b4457..ed8e5d045a 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -6,6 +6,7 @@ add_flang_library(flangCodeGen
CodeGenAction.cpp
BackendUtil.cpp
CGABI.cpp
+ CGDecl.cpp
CGStmt.cpp
CGExpr.cpp
CGExprScalar.cpp
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index b8b9c10054..961dd1e540 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -16,10 +16,8 @@
#include "CGSystemRuntime.h"
#include "flang/AST/ASTContext.h"
#include "flang/AST/Decl.h"
-#include "flang/AST/DeclVisitor.h"
#include "flang/AST/Stmt.h"
#include "flang/AST/Expr.h"
-#include "flang/AST/EquivalenceSet.h"
#include "flang/Frontend/CodeGenOptions.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Intrinsics.h"
@@ -42,21 +40,6 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, llvm::Function *Fn)
CodeGenFunction::~CodeGenFunction() {
}
-void CodeGenFunction::EmitFunctionDecls(const DeclContext *DC) {
- class Visitor : public ConstDeclVisitor<Visitor> {
- public:
- CodeGenFunction *CG;
-
- Visitor(CodeGenFunction *P) : CG(P) {}
-
- void VisitVarDecl(const VarDecl *D) {
- CG->EmitVarDecl(D);
- }
- };
- Visitor DV(this);
- DV.Visit(DC);
-}
-
void CodeGenFunction::EmitMainProgramBody(const DeclContext *DC, const Stmt *S) {
EmitBlock(createBasicBlock("program_entry"));
CGM.getSystemRuntime().EmitInit(*this);
@@ -143,14 +126,14 @@ void CodeGenFunction::EmitFunctionBody(const DeclContext *DC, const Stmt *S) {
AllocaInsertPt = Builder.CreateBr(BodyBB);
EmitBlock(BodyBB);
if(HasSavedVariables)
- EmitFirstInvocationBlock(S);
- if(S) {
- EmitDataStmts(S);
+ EmitFirstInvocationBlock(DC, S);
+ EmitVarInitializers(DC);
+ if(S)
EmitStmt(S);
- }
}
-void CodeGenFunction::EmitFirstInvocationBlock(const Stmt *S) {
+void CodeGenFunction::EmitFirstInvocationBlock(const DeclContext *DC,
+ const Stmt *S) {
auto GlobalFirstInvocationFlag = CGM.EmitGlobalVariable(CurFn->getName(), "FIRST_INVOCATION",
CGM.Int1Ty, Builder.getTrue());
auto FirstInvocationBB = createBasicBlock("first-invocation");
@@ -158,7 +141,7 @@ void CodeGenFunction::EmitFirstInvocationBlock(const Stmt *S) {
Builder.CreateCondBr(Builder.CreateLoad(GlobalFirstInvocationFlag), FirstInvocationBB,
EndBB);
EmitBlock(FirstInvocationBB);
- if(S) EmitDataStmts(S, true);
+ EmitSavedVarInitializers(DC);
Builder.CreateStore(Builder.getFalse(), GlobalFirstInvocationFlag);
EmitBlock(EndBB);
}
@@ -194,81 +177,6 @@ void CodeGenFunction::EmitFunctionEpilogue(const FunctionDecl *Func,
EmitAssignedGotoDispatcher();
}
-void CodeGenFunction::EmitVarDecl(const VarDecl *D) {
- if(D->isParameter() ||
- D->isArgument() ||
- D->isFunctionResult()) return;
-
- if(D->hasEquivalenceSet()) {
- auto Set = EmitEquivalenceSet(D->getEquivalenceSet());
- auto Ptr = EmitEquivalenceSetObject(Set, D);
- LocalVariables.insert(std::make_pair(D, Ptr));
- return;
- }
-
- llvm::Value *Ptr;
- auto Type = D->getType();
- auto Quals = Type.getExtQualsPtrOrNull();
- if(Quals && Quals->getQualifiers().hasAttributeSpec(Qualifiers::AS_save) &&
- !IsMainProgram) {
- Ptr = CGM.EmitGlobalVariable(CurFn->getName(), D);
- HasSavedVariables = true;
- } else {
- if(Type->isArrayType())
- Ptr = CreateArrayAlloca(Type, D->getName());
- else Ptr = Builder.CreateAlloca(ConvertTypeForMem(Type),
- nullptr, D->getName());
- }
- LocalVariables.insert(std::make_pair(D, Ptr));
-}
-
-// FIXME: support substrings.
-std::pair<int64_t, int64_t> CodeGenFunction::GetObjectBounds(const VarDecl *Var, const Expr *E) {
- auto Size = CGM.getDataLayout().getTypeStoreSize(ConvertTypeForMem(Var->getType()));
- uint64_t Offset = 0;
- if(auto Arr = dyn_cast<ArrayElementExpr>(E)) {
- Arr->EvaluateOffset(getContext(), Offset);
- Offset = Offset * CGM.getDataLayout().getTypeStoreSize(ConvertTypeForMem(E->getType()));
- } else
- Offset = 0;
-
- return std::make_pair(-int64_t(Offset), -int64_t(Offset) + int64_t(Size));
-}
-
-CodeGenFunction::EquivSet CodeGenFunction::EmitEquivalenceSet(const EquivalenceSet *S) {
- auto Result = EquivSets.find(S);
- if(Result != EquivSets.end())
- return Result->second;
-
- // Find the bounds of the set
- int64_t LowestBound = 0;
- int64_t HighestBound = 0;
- for(auto I : S->getObjects()) {
- auto Bounds = GetObjectBounds(I.Var, I.E);
- LowestBound = std::min(Bounds.first, LowestBound);
- HighestBound = std::max(Bounds.second, HighestBound);
- LocalVariablesInEquivSets.insert(std::make_pair(I.Var, Bounds.first));
- }
- EquivSet Set;
- // FIXME: more accurate alignment?
- Set.Ptr= Builder.Insert(new llvm::AllocaInst(CGM.Int8Ty,
- llvm::ConstantInt::get(CGM.SizeTy, HighestBound - LowestBound),
- CGM.getDataLayout().getTypeStoreSize(CGM.DoubleTy)),
- "equivalence-set");
- Set.LowestBound = LowestBound;
- EquivSets.insert(std::make_pair(S, Set));
- return Set;
-}
-
-llvm::Value *CodeGenFunction::EmitEquivalenceSetObject(EquivSet Set, const VarDecl *Var) {
- // Compute the pointer to the object.
- auto ObjLowBound = LocalVariablesInEquivSets.find(Var)->second;
- auto Ptr = Builder.CreateConstInBoundsGEP1_64(Set.Ptr,
- uint64_t(ObjLowBound - Set.LowestBound));
- auto T = Var->getType();
- return Builder.CreatePointerCast(Ptr, llvm::PointerType::get(ConvertTypeForMem(T), 0));
-}
-
llvm::Value *CodeGenFunction::GetVarPtr(const VarDecl *D) {
if(D->isFunctionResult())
return ReturnValuePtr;
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 3177444153..0c795dff3a 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -203,8 +203,10 @@ public:
void EmitCleanup();
void EmitVarDecl(const VarDecl *D);
- void EmitDataStmts(const Stmt *S, bool Saved = false);
- void EmitFirstInvocationBlock(const Stmt *S);
+ void EmitVarInitializers(const DeclContext *DC);
+ void EmitSavedVarInitializers(const DeclContext *DC);
+ void EmitVarInitializer(const VarDecl *D);
+ void EmitFirstInvocationBlock(const DeclContext *DC, const Stmt *S);
std::pair<int64_t, int64_t> GetObjectBounds(const VarDecl *Var, const Expr *E);
EquivSet EmitEquivalenceSet(const EquivalenceSet *S);
@@ -268,6 +270,7 @@ public:
/// Generic value operations for scalar/complex/character values.
RValueTy EmitLoad (llvm::Value *Ptr, QualType T, bool IsVolatile = false);
void EmitStore(RValueTy Val, LValueTy Dest, QualType T);
+ void EmitStoreCharSameLength(RValueTy Val, LValueTy Dest, QualType T);
RValueTy EmitBinaryExpr(BinaryExpr::Operator Op, RValueTy LHS, RValueTy RHS);
RValueTy EmitUnaryExpr(UnaryExpr::Operator Op, RValueTy Val);
RValueTy EmitImplicitConversion(RValueTy Val, QualType T);
diff --git a/lib/Sema/SemaDataStmt.cpp b/lib/Sema/SemaDataStmt.cpp
index b3c1e52c36..88d4693c26 100644
--- a/lib/Sema/SemaDataStmt.cpp
+++ b/lib/Sema/SemaDataStmt.cpp
@@ -93,7 +93,6 @@ class DataStmtEngine : public ExprVisitor<DataStmtEngine> {
SourceLocation DataStmtLoc;
ExprEvalScope ImpliedDoEvaluator;
- SmallVector<Stmt*, 16> ResultingAST;
bool Done;
@@ -124,18 +123,9 @@ public:
void VisitMemberExpr(MemberExpr *E);
void VisitImpliedDoExpr(ImpliedDoExpr *E);
- void Emit(Stmt *S);
- ArrayRef<Stmt*> getEmittedStmtList() const {
- return ResultingAST;
- }
-
bool CheckVar(VarExpr *E);
};
-void DataStmtEngine::Emit(Stmt *S) {
- ResultingAST.push_back(S);
-}
-
bool DataStmtEngine::HasValues(const Expr *Where) {
if(Values.isEmpty()) {
// more items than values.
@@ -401,16 +391,8 @@ StmtResult Sema::ActOnDATA(ASTContext &C, SourceLocation Loc,
<< SourceRange(FirstVal->getLocStart(), LastVal->getLocEnd());
}
- Stmt *ResultStmt;
- auto ResultStmts = LHSVisitor.getEmittedStmtList();
- if(ResultStmts.size() > 1)
- ResultStmt = BlockStmt::Create(Context, Loc, ResultStmts);
- else if(ResultStmts.size() == 1)
- ResultStmt = ResultStmts[0];
- else ResultStmt = nullptr;
-
auto Result = DataStmt::Create(C, Loc, Objects, Values,
- ResultStmt, StmtLabel);
+ StmtLabel);
if(StmtLabel) DeclareStatementLabel(StmtLabel, Result);
return Result;
}
diff --git a/test/CodeGen/data.f95 b/test/CodeGen/data.f95
index 1239d3c39d..890aa09379 100644
--- a/test/CodeGen/data.f95
+++ b/test/CodeGen/data.f95
@@ -4,14 +4,18 @@ PROGRAM datatest
REAL X
INTEGER I_ARR(10)
LOGICAL L_ARR(4)
+ character(len=5) str1
DATA (I_ARR(I), I = 1,10) / 2*0, 5*2, 3*-1 /
DATA L_ARR / .false., .true., .false., .true. /
+ data str1 / 'Hello' /
+
DATA I / 1 / J, X / 2*0 / ! CHECK: store i32 1
CONTINUE ! CHECK-NEXT: store i32 0
CONTINUE ! CHECK-NEXT: store float 0
+ continue ! CHECK: call void @llvm.memcpy.p0i8.p0i8
END PROGRAM
diff --git a/test/CodeGenInAction/arrayOperations.f95 b/test/CodeGenInAction/arrayOperations.f95
index 89ed41772e..a3069cfdff 100644
--- a/test/CodeGenInAction/arrayOperations.f95
+++ b/test/CodeGenInAction/arrayOperations.f95
@@ -9,7 +9,6 @@ program arrayops
! assignment using data statement
data i_arr / 1, 2*0, -69 /
data i_mat / 1, 0, 0, 0, 1, 0, 0, 0, 1 /
- ! FIXME: data char_arr / 'Hello', 'World' /
print *, i_arr(1), ', ', i_arr(2), ', ', i_arr(3), ', ', i_arr(4)
continue ! CHECK: 1, 0, 0, -69
@@ -19,8 +18,6 @@ program arrayops
i_mat(1,3), ', ', i_mat(2,3), ', ', i_mat(3,3)
continue ! CHECK-NEXT: 1, 0, 0, 0, 1, 0, 0, 0, 1
- ! FIXME: print *, char_arr(1), char_arr(2) ! CECK-NEXT: HelloWorld
-
i_mat2 = 1
i_mat = i_mat + i_mat2 * 2
diff --git a/test/CodeGenInAction/data.f95 b/test/CodeGenInAction/data.f95
index 49af67b680..67e59ff72b 100644
--- a/test/CodeGenInAction/data.f95
+++ b/test/CodeGenInAction/data.f95
@@ -11,6 +11,18 @@ program datatest
/ 3*42, 3*11, 3*-88 /
+ character(len=5) str1, str2, str3
+ character(len=5) strArr(2), strArr2(3)
+
+ data str1 / 'Hello' / str2(:) / 'World' /
+ data str3(2:4) / 'Flang' /
+
+ data strArr / 'Hello', 'World' /
+ data strArr2(1) / 'Hello' /
+ data strArr2(2)(2:4) / '+' /
+ data (strArr2(i), i = 3,3) / 'funke' /
+
+
print *, 'START' ! CHECK: START
print *, i ! CHECK-NEXT: 1
print *, j ! CHECK-NEXT: 0
@@ -24,4 +36,13 @@ program datatest
i_mat(1,3), ', ', i_mat(2,3), ', ', i_mat(3,3)
continue ! CHECK-NEXT: 42, 42, 42, 11, 11, 11, -88, -88, -88
+ print *, str1 ! CHECK-NEXT: Hello
+ print *, str2 ! CHECK-NEXT: World
+ print *, str3 ! CHECK-NEXT: Fla
+ print *, strArr(1) ! CHECK-NEXT: Hello
+ print *, strArr(2) ! CHECK-NEXT: World
+ print *, strArr2(1) ! CHECK-NEXT: Hello
+ print *, strArr2(2) ! CHECK-NEXT: +
+ print *, strArr2(3) ! CHECK-NEXT: funke
+
end program