• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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