@@ -82,133 +82,59 @@ static const unsigned TypeDepthThreshold = 50;
8282// / Set the width threshold rather high, because some projects uses very wide
8383// / tuples to model fixed size arrays.
8484static const unsigned TypeWidthThreshold = 2000 ;
85+ // / Max length of an opaque archetype's type parameter.
86+ static const unsigned TypeLengthThreshold = 10 ;
8587
8688// / Compute the width and the depth of a type.
8789// / We compute both, because some pathological test-cases result in very
8890// / wide types and some others result in very deep types. It is important
8991// / to bail as soon as we hit the threshold on any of both dimensions to
9092// / prevent compiler hangs and crashes.
91- static std::pair<unsigned , unsigned > getTypeDepthAndWidth (Type t) {
92- unsigned Depth = 0 ;
93- unsigned Width = 0 ;
94- if (auto *BGT = t->getAs <BoundGenericType>()) {
95- auto *NTD = BGT->getNominalOrBoundGenericNominal ();
96- if (NTD) {
97- auto StoredProperties = NTD->getStoredProperties ();
98- Width += StoredProperties.size ();
99- }
100- ++Depth;
101- unsigned MaxTypeDepth = 0 ;
102- auto GenericArgs = BGT->getGenericArgs ();
103- for (auto Ty : GenericArgs) {
104- unsigned TypeWidth;
105- unsigned TypeDepth;
106- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (Ty);
107- if (TypeDepth > MaxTypeDepth)
108- MaxTypeDepth = TypeDepth;
109- Width += TypeWidth;
110- }
111- Depth += MaxTypeDepth;
112- return std::make_pair (Depth, Width);
113- }
114-
115- if (auto *TupleTy = t->getAs <TupleType>()) {
116- Width += TupleTy->getNumElements ();
117- ++Depth;
118- unsigned MaxTypeDepth = 0 ;
119- auto ElementTypes = TupleTy->getElementTypes ();
120- for (auto Ty : ElementTypes) {
121- unsigned TypeWidth;
122- unsigned TypeDepth;
123- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (Ty);
124- if (TypeDepth > MaxTypeDepth)
125- MaxTypeDepth = TypeDepth;
126- Width += TypeWidth;
127- }
128- Depth += MaxTypeDepth;
129- return std::make_pair (Depth, Width);
130- }
131-
132- if (auto *FnTy = t->getAs <SILFunctionType>()) {
133- ++Depth;
134- unsigned MaxTypeDepth = 0 ;
135- auto Params = FnTy->getParameters ();
136- Width += Params.size ();
137- for (auto Param : Params) {
138- unsigned TypeWidth;
139- unsigned TypeDepth;
140- std::tie (TypeDepth, TypeWidth) =
141- getTypeDepthAndWidth (Param.getInterfaceType ());
142- if (TypeDepth > MaxTypeDepth)
143- MaxTypeDepth = TypeDepth;
144- Width += TypeWidth;
145- }
146- auto Results = FnTy->getResults ();
147- Width += Results.size ();
148- for (auto Result : Results) {
149- unsigned TypeWidth;
150- unsigned TypeDepth;
151- std::tie (TypeDepth, TypeWidth) =
152- getTypeDepthAndWidth (Result.getInterfaceType ());
153- if (TypeDepth > MaxTypeDepth)
154- MaxTypeDepth = TypeDepth;
155- Width += TypeWidth;
156- }
157- if (FnTy->hasErrorResult ()) {
158- Width += 1 ;
159- unsigned TypeWidth;
160- unsigned TypeDepth;
161- std::tie (TypeDepth, TypeWidth) =
162- getTypeDepthAndWidth (FnTy->getErrorResult ().getInterfaceType ());
163- if (TypeDepth > MaxTypeDepth)
164- MaxTypeDepth = TypeDepth;
165- Width += TypeWidth;
166- }
167- Depth += MaxTypeDepth;
168- return std::make_pair (Depth, Width);
169- }
170-
171- if (auto *FnTy = t->getAs <FunctionType>()) {
172- ++Depth;
173- unsigned MaxTypeDepth = 0 ;
174- auto Params = FnTy->getParams ();
175- Width += Params.size ();
176- for (auto &Param : Params) {
177- unsigned TypeWidth;
178- unsigned TypeDepth;
179- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (Param.getParameterType ());
180- if (TypeDepth > MaxTypeDepth)
181- MaxTypeDepth = TypeDepth;
182- Width += TypeWidth;
183- }
184- unsigned TypeWidth;
185- unsigned TypeDepth;
186- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (FnTy->getResult ());
187- if (TypeDepth > MaxTypeDepth)
188- MaxTypeDepth = TypeDepth;
189- Width += TypeWidth;
190- Depth += MaxTypeDepth;
191- return std::make_pair (Depth, Width);
192- }
193-
194- if (auto *MT = t->getAs <MetatypeType>()) {
195- Depth += 1 ;
196- unsigned TypeWidth;
197- unsigned TypeDepth;
198- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (MT->getInstanceType ());
199- Width += TypeWidth;
200- Depth += TypeDepth;
201- return std::make_pair (Depth, Width);
202- }
203-
204- return std::make_pair (Depth, Width);
205- }
206-
20793static bool isTypeTooComplex (Type t) {
208- unsigned TypeWidth;
209- unsigned TypeDepth;
210- std::tie (TypeDepth, TypeWidth) = getTypeDepthAndWidth (t);
211- return TypeWidth >= TypeWidthThreshold || TypeDepth >= TypeDepthThreshold;
94+ struct Walker : TypeWalker {
95+ unsigned Depth = 0 ;
96+ unsigned MaxDepth = 0 ;
97+ unsigned MaxWidth = 0 ;
98+ unsigned MaxLength = 0 ;
99+
100+ Action walkToTypePre (Type ty) override {
101+ // The TypeWalker won't visit the interface type encapsulated by the
102+ // archetype, so we do it directly to measure its length.
103+ if (auto *opaqueArchetypeTy = ty->getAs <OpaqueTypeArchetypeType>()) {
104+ auto interfaceTy = opaqueArchetypeTy->getInterfaceType ();
105+
106+ unsigned length = 0 ;
107+ while (auto memberTy = interfaceTy->getAs <DependentMemberType>()) {
108+ ++length;
109+ interfaceTy = memberTy->getBase ();
110+ }
111+ assert (interfaceTy->is <GenericTypeParamType>());
112+
113+ if (length > MaxLength)
114+ MaxLength = length;
115+ }
116+
117+ ++Depth;
118+ MaxDepth = std::max (Depth, MaxDepth);
119+
120+ ++MaxWidth;
121+
122+ return Action::Continue;
123+ }
124+
125+ Action walkToTypePost (Type ty) override {
126+ --Depth;
127+
128+ return Action::Continue;
129+ }
130+ };
131+
132+ Walker walker;
133+ t.walk (walker);
134+
135+ return (walker.MaxWidth >= TypeWidthThreshold ||
136+ walker.MaxDepth >= TypeDepthThreshold ||
137+ walker.MaxLength >= TypeLengthThreshold);
212138}
213139
214140namespace {
0 commit comments