1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
//===- SemaFormat.cpp - FORMAT AST Builder and Semantic Analysis Implementation -===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "flang/Sema/Sema.h"
#include "flang/Sema/DeclSpec.h"
#include "flang/Sema/SemaDiagnostic.h"
#include "flang/AST/ASTContext.h"
#include "flang/AST/Decl.h"
#include "flang/AST/Expr.h"
#include "flang/AST/FormatItem.h"
#include "flang/Basic/Diagnostic.h"
#include "llvm/Support/raw_ostream.h"
namespace flang {
static void CheckPositive(DiagnosticsEngine &Diags, IntegerConstantExpr *E) {
if(!E) return;
if(E->getValue().isNegative()) {
Diags.Report(E->getLocation(), diag::err_expected_positive_integer)
<< E->getSourceRange();
}
}
static void CheckPositiveOrZero(DiagnosticsEngine &Diags, IntegerConstantExpr *E) {
if(!E) return;
if(E->getValue().isNegative() || E->getValue().getLimitedValue() == 0) {
Diags.Report(E->getLocation(), diag::err_expected_integer_gt_0)
<< E->getSourceRange();
}
}
StmtResult Sema::ActOnFORMAT(ASTContext &C, SourceLocation Loc,
FormatItemResult Items,
FormatItemResult UnlimitedItems,
Expr *StmtLabel,
bool IsInline) {
auto ItemList = cast<FormatItemList>(Items.take());
auto UnlimitedItemList = UnlimitedItems.isUsable()?
cast<FormatItemList>(UnlimitedItems.take()):
nullptr;
if(!IsInline && !StmtLabel)
Diags.Report(Loc, diag::err_format_without_stmt_label);
auto Result = FormatStmt::Create(C, Loc, ItemList, UnlimitedItemList,
StmtLabel);
if(StmtLabel) DeclareStatementLabel(StmtLabel, Result);
return Result;
}
FormatItemResult Sema::ActOnFORMATIntegerDataEditDesc(ASTContext &C, SourceLocation Loc,
tok::TokenKind Kind,
IntegerConstantExpr *RepeatCount,
IntegerConstantExpr *W,
IntegerConstantExpr *M) {
CheckPositive(Diags, RepeatCount);
CheckPositiveOrZero(Diags, W);
return IntegerDataEditDesc::Create(C, Loc, Kind, RepeatCount, W, M);
}
FormatItemResult Sema::ActOnFORMATRealDataEditDesc(ASTContext &C, SourceLocation Loc,
tok::TokenKind Kind,
IntegerConstantExpr *RepeatCount,
IntegerConstantExpr *W,
IntegerConstantExpr *D,
IntegerConstantExpr *E) {
CheckPositive(Diags, RepeatCount);
if(Kind == tok::fs_F || Kind == tok::fs_G)
CheckPositiveOrZero(Diags, W);
else CheckPositive(Diags, W);
CheckPositive(Diags, E);
// FIXME: add G constraints.
return RealDataEditDesc::Create(C, Loc, Kind, RepeatCount, W, D, E);
}
FormatItemResult Sema::ActOnFORMATLogicalDataEditDesc(ASTContext &C, SourceLocation Loc,
tok::TokenKind Kind,
IntegerConstantExpr *RepeatCount,
IntegerConstantExpr *W) {
CheckPositive(Diags, RepeatCount);
CheckPositive(Diags, W);
return LogicalDataEditDesc::Create(C, Loc, Kind, RepeatCount, W);
}
FormatItemResult Sema::ActOnFORMATCharacterDataEditDesc(ASTContext &C, SourceLocation Loc,
tok::TokenKind Kind,
IntegerConstantExpr *RepeatCount,
IntegerConstantExpr *W) {
CheckPositive(Diags, RepeatCount);
CheckPositive(Diags, W);
return CharacterDataEditDesc::Create(C, Loc, Kind, RepeatCount, W);
}
FormatItemResult Sema::ActOnFORMATPositionEditDesc(ASTContext &C, SourceLocation Loc,
tok::TokenKind Kind,
IntegerConstantExpr *N) {
CheckPositive(Diags, N);
return PositionEditDesc::Create(C, Loc, Kind, N);
}
FormatItemResult Sema::ActOnFORMATControlEditDesc(ASTContext &C, SourceLocation Loc,
tok::TokenKind Kind) {
return FormatItemResult(true);
}
FormatItemResult Sema::ActOnFORMATCharacterStringDesc(ASTContext &C, SourceLocation Loc,
ExprResult E) {
auto Str = cast<CharacterConstantExpr>(E.take());
return CharacterStringEditDesc::Create(C, Str);
}
FormatItemResult Sema::ActOnFORMATFormatItemList(ASTContext &C, SourceLocation Loc,
IntegerConstantExpr *RepeatCount,
ArrayRef<FormatItem*> Items) {
CheckPositive(Diags, RepeatCount);
return FormatItemList::Create(C, Loc, RepeatCount, Items);
}
} // end namespace flang
|