1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "mir_scope.h"
17 #include "mir_function.h"
18 #include "printing.h"
19
20 namespace maple {
21
22 // scp is a sub scope
23 // (low (scp.low, scp.high] high]
IsSubScope(const MIRScope * scp) const24 bool MIRScope::IsSubScope(const MIRScope *scp) const
25 {
26 // special case for function level scope which might not have range specified
27 if (level == 0) {
28 return true;
29 }
30 auto &l = GetRangeLow();
31 auto &l1 = scp->GetRangeLow();
32 // allow included file
33 if (l.FileNum() != l1.FileNum()) {
34 return true;
35 }
36 auto &h = GetRangeHigh();
37 auto &h1 = scp->GetRangeHigh();
38 return l.IsBfOrEq(l1) && h1.IsBfOrEq(h);
39 }
40
41 // s1 and s2 has join
42 // (s1.low (s2.low s1.high] s2.high]
43 // (s2.low (s1.low s2.high] s1.high]
HasJoinScope(const MIRScope * scp1,const MIRScope * scp2) const44 bool MIRScope::HasJoinScope(const MIRScope *scp1, const MIRScope *scp2) const
45 {
46 auto &l1 = scp1->GetRangeLow();
47 auto &h1 = scp1->GetRangeHigh();
48 auto &l2 = scp2->GetRangeLow();
49 auto &h2 = scp2->GetRangeHigh();
50 return (l1.IsBfOrEq(l2) && l2.IsBfOrEq(h1)) || (l2.IsBfOrEq(l1) && l1.IsBfOrEq(h2));
51 }
52
53 // scope range of s1 and s2 may be completly same when macro calling macro expand
HasSameRange(const MIRScope * scp1,const MIRScope * scp2) const54 bool MIRScope::HasSameRange(const MIRScope *scp1, const MIRScope *scp2) const
55 {
56 auto &l1 = scp1->GetRangeLow();
57 auto &h1 = scp1->GetRangeHigh();
58 auto &l2 = scp2->GetRangeLow();
59 auto &h2 = scp2->GetRangeHigh();
60 return l1.IsSrcPostionEq(l2) && h1.IsSrcPostionEq(h2);
61 }
62
IncLevel()63 void MIRScope::IncLevel()
64 {
65 level++;
66 for (auto *s : subScopes) {
67 s->IncLevel();
68 }
69 }
70
AddScope(MIRScope * scope)71 bool MIRScope::AddScope(MIRScope *scope)
72 {
73 // check first if it is valid with parent scope and sibling sub scopes
74 CHECK_FATAL(IsSubScope(scope), "<%s %s> is not a subscope of scope <%s %s>",
75 scope->GetRangeLow().DumpLocWithColToString().c_str(),
76 scope->GetRangeHigh().DumpLocWithColToString().c_str(), GetRangeLow().DumpLocWithColToString().c_str(),
77 GetRangeHigh().DumpLocWithColToString().c_str());
78 for (auto *s : subScopes) {
79 if (!HasSameRange(s, scope) && HasJoinScope(s, scope)) {
80 CHECK_FATAL(false, "<%s %s> has join range with another subscope <%s %s>",
81 scope->GetRangeLow().DumpLocWithColToString().c_str(),
82 scope->GetRangeHigh().DumpLocWithColToString().c_str(),
83 s->GetRangeLow().DumpLocWithColToString().c_str(),
84 s->GetRangeHigh().DumpLocWithColToString().c_str());
85 }
86 }
87 if (this != module->CurFunction()->GetScope()) {
88 // skip level incremental if this is function-scope, of level 0,
89 // as scope is aready starting from 1
90 scope->IncLevel();
91 }
92 subScopes.push_back(scope);
93 return true;
94 }
95
Dump(int32 indent) const96 void MIRScope::Dump(int32 indent) const
97 {
98 int32 ind = static_cast<int32>(level != 0);
99 if (level != 0) {
100 SrcPosition low = range.first;
101 SrcPosition high = range.second;
102 PrintIndentation(indent);
103 LogInfo::MapleLogger() << "SCOPE <(" << low.FileNum() << ", " << low.LineNum() << ", " << low.Column() << "), ("
104 << high.FileNum() << ", " << high.LineNum() << ", " << high.Column() << ")> {\n";
105 }
106
107 for (auto it : aliasVarMap) {
108 PrintIndentation(indent + ind);
109 LogInfo::MapleLogger() << "ALIAS %" << GlobalTables::GetStrTable().GetStringFromStrIdx(it.first)
110 << ((it.second.isLocal) ? " %" : " $")
111 << GlobalTables::GetStrTable().GetStringFromStrIdx(it.second.mplStrIdx) << " ";
112 GlobalTables::GetTypeTable().GetTypeFromTyIdx(it.second.tyIdx)->Dump(0);
113 if (it.second.sigStrIdx) {
114 LogInfo::MapleLogger() << " \"" << GlobalTables::GetStrTable().GetStringFromStrIdx(it.second.sigStrIdx)
115 << "\"";
116 }
117 LogInfo::MapleLogger() << '\n';
118 }
119
120 for (auto it : subScopes) {
121 if (it->NeedEmitAliasInfo()) {
122 it->Dump(indent + ind);
123 }
124 }
125
126 if (level != 0) {
127 PrintIndentation(indent);
128 LogInfo::MapleLogger() << "}\n";
129 }
130 }
131
Dump() const132 void MIRScope::Dump() const
133 {
134 Dump(0);
135 }
136 } // namespace maple
137