blob: bdba01402c35c6d0390156fc4e0b643c603e4f8c [file] [log] [blame]
Douglas Gregora8f32e02009-10-06 17:59:45 +00001//===------ CXXInheritance.cpp - C++ Inheritance ----------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file provides routines that help analyzing C++ inheritance hierarchies.
11//
12//===----------------------------------------------------------------------===//
13#include "clang/AST/CXXInheritance.h"
14#include "clang/AST/DeclCXX.h"
15#include <algorithm>
16#include <set>
17
18using namespace clang;
19
20/// \brief Computes the set of declarations referenced by these base
21/// paths.
22void CXXBasePaths::ComputeDeclsFound() {
23 assert(NumDeclsFound == 0 && !DeclsFound &&
24 "Already computed the set of declarations");
25
26 std::set<NamedDecl *> Decls;
27 for (CXXBasePaths::paths_iterator Path = begin(), PathEnd = end();
28 Path != PathEnd; ++Path)
29 Decls.insert(*Path->Decls.first);
30
31 NumDeclsFound = Decls.size();
32 DeclsFound = new NamedDecl * [NumDeclsFound];
33 std::copy(Decls.begin(), Decls.end(), DeclsFound);
34}
35
36CXXBasePaths::decl_iterator CXXBasePaths::found_decls_begin() {
37 if (NumDeclsFound == 0)
38 ComputeDeclsFound();
39 return DeclsFound;
40}
41
42CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() {
43 if (NumDeclsFound == 0)
44 ComputeDeclsFound();
45 return DeclsFound + NumDeclsFound;
46}
47
48/// isAmbiguous - Determines whether the set of paths provided is
49/// ambiguous, i.e., there are two or more paths that refer to
50/// different base class subobjects of the same type. BaseType must be
51/// an unqualified, canonical class type.
Douglas Gregore0d5fe22010-05-21 20:29:55 +000052bool CXXBasePaths::isAmbiguous(CanQualType BaseType) {
53 BaseType = BaseType.getUnqualifiedType();
Douglas Gregora8f32e02009-10-06 17:59:45 +000054 std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
55 return Subobjects.second + (Subobjects.first? 1 : 0) > 1;
56}
57
58/// clear - Clear out all prior path information.
59void CXXBasePaths::clear() {
60 Paths.clear();
61 ClassSubobjects.clear();
62 ScratchPath.clear();
63 DetectedVirtual = 0;
64}
65
66/// @brief Swaps the contents of this CXXBasePaths structure with the
67/// contents of Other.
68void CXXBasePaths::swap(CXXBasePaths &Other) {
69 std::swap(Origin, Other.Origin);
70 Paths.swap(Other.Paths);
71 ClassSubobjects.swap(Other.ClassSubobjects);
72 std::swap(FindAmbiguities, Other.FindAmbiguities);
73 std::swap(RecordPaths, Other.RecordPaths);
74 std::swap(DetectVirtual, Other.DetectVirtual);
75 std::swap(DetectedVirtual, Other.DetectedVirtual);
76}
77
John McCallaf8e6ed2009-11-12 03:15:40 +000078bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base) const {
Douglas Gregora8f32e02009-10-06 17:59:45 +000079 CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
80 /*DetectVirtual=*/false);
81 return isDerivedFrom(Base, Paths);
82}
83
John McCallaf8e6ed2009-11-12 03:15:40 +000084bool CXXRecordDecl::isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const {
Douglas Gregora8f32e02009-10-06 17:59:45 +000085 if (getCanonicalDecl() == Base->getCanonicalDecl())
86 return false;
87
John McCallaf8e6ed2009-11-12 03:15:40 +000088 Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
Douglas Gregora8f32e02009-10-06 17:59:45 +000089 return lookupInBases(&FindBaseClass, Base->getCanonicalDecl(), Paths);
90}
91
Douglas Gregor4e6ba4b2010-03-03 04:38:46 +000092bool CXXRecordDecl::isVirtuallyDerivedFrom(CXXRecordDecl *Base) const {
93 CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
94 /*DetectVirtual=*/false);
95
96 if (getCanonicalDecl() == Base->getCanonicalDecl())
97 return false;
98
99 Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
100 return lookupInBases(&FindVirtualBaseClass, Base->getCanonicalDecl(), Paths);
101}
102
John McCalle8174bc2009-12-08 07:42:38 +0000103static bool BaseIsNot(const CXXRecordDecl *Base, void *OpaqueTarget) {
104 // OpaqueTarget is a CXXRecordDecl*.
105 return Base->getCanonicalDecl() != (const CXXRecordDecl*) OpaqueTarget;
106}
107
108bool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const {
109 return forallBases(BaseIsNot, (void*) Base->getCanonicalDecl());
110}
111
112bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
113 void *OpaqueData,
114 bool AllowShortCircuit) const {
John McCalle8174bc2009-12-08 07:42:38 +0000115 llvm::SmallVector<const CXXRecordDecl*, 8> Queue;
116
117 const CXXRecordDecl *Record = this;
118 bool AllMatches = true;
119 while (true) {
120 for (CXXRecordDecl::base_class_const_iterator
121 I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
122 const RecordType *Ty = I->getType()->getAs<RecordType>();
123 if (!Ty) {
124 if (AllowShortCircuit) return false;
125 AllMatches = false;
126 continue;
127 }
128
Anders Carlssonca910e82009-12-09 04:26:02 +0000129 CXXRecordDecl *Base =
Douglas Gregor952b0172010-02-11 01:04:33 +0000130 cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition());
John McCalle8174bc2009-12-08 07:42:38 +0000131 if (!Base) {
132 if (AllowShortCircuit) return false;
133 AllMatches = false;
134 continue;
135 }
136
Anders Carlssonca910e82009-12-09 04:26:02 +0000137 Queue.push_back(Base);
138 if (!BaseMatches(Base, OpaqueData)) {
John McCalle8174bc2009-12-08 07:42:38 +0000139 if (AllowShortCircuit) return false;
140 AllMatches = false;
141 continue;
142 }
143 }
144
145 if (Queue.empty()) break;
146 Record = Queue.back(); // not actually a queue.
147 Queue.pop_back();
148 }
149
150 return AllMatches;
151}
152
Douglas Gregor89b77022010-03-03 02:18:00 +0000153bool CXXBasePaths::lookupInBases(ASTContext &Context,
154 const CXXRecordDecl *Record,
155 CXXRecordDecl::BaseMatchesCallback *BaseMatches,
156 void *UserData) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000157 bool FoundPath = false;
John McCall46460a62010-01-20 21:53:11 +0000158
John McCall92f88312010-01-23 00:46:32 +0000159 // The access of the path down to this record.
Douglas Gregor89b77022010-03-03 02:18:00 +0000160 AccessSpecifier AccessToHere = ScratchPath.Access;
161 bool IsFirstStep = ScratchPath.empty();
John McCall92f88312010-01-23 00:46:32 +0000162
Douglas Gregor89b77022010-03-03 02:18:00 +0000163 for (CXXRecordDecl::base_class_const_iterator BaseSpec = Record->bases_begin(),
164 BaseSpecEnd = Record->bases_end();
165 BaseSpec != BaseSpecEnd;
166 ++BaseSpec) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000167 // Find the record of the base class subobjects for this type.
Douglas Gregora4923eb2009-11-16 21:35:15 +0000168 QualType BaseType = Context.getCanonicalType(BaseSpec->getType())
169 .getUnqualifiedType();
Douglas Gregora8f32e02009-10-06 17:59:45 +0000170
171 // C++ [temp.dep]p3:
172 // In the definition of a class template or a member of a class template,
173 // if a base class of the class template depends on a template-parameter,
174 // the base class scope is not examined during unqualified name lookup
175 // either at the point of definition of the class template or member or
176 // during an instantiation of the class tem- plate or member.
177 if (BaseType->isDependentType())
178 continue;
179
180 // Determine whether we need to visit this base class at all,
181 // updating the count of subobjects appropriately.
Douglas Gregor89b77022010-03-03 02:18:00 +0000182 std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
Douglas Gregora8f32e02009-10-06 17:59:45 +0000183 bool VisitBase = true;
184 bool SetVirtual = false;
185 if (BaseSpec->isVirtual()) {
186 VisitBase = !Subobjects.first;
187 Subobjects.first = true;
Douglas Gregor89b77022010-03-03 02:18:00 +0000188 if (isDetectingVirtual() && DetectedVirtual == 0) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000189 // If this is the first virtual we find, remember it. If it turns out
190 // there is no base path here, we'll reset it later.
Douglas Gregor89b77022010-03-03 02:18:00 +0000191 DetectedVirtual = BaseType->getAs<RecordType>();
Douglas Gregora8f32e02009-10-06 17:59:45 +0000192 SetVirtual = true;
193 }
194 } else
195 ++Subobjects.second;
196
Douglas Gregor89b77022010-03-03 02:18:00 +0000197 if (isRecordingPaths()) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000198 // Add this base specifier to the current path.
199 CXXBasePathElement Element;
200 Element.Base = &*BaseSpec;
Douglas Gregor89b77022010-03-03 02:18:00 +0000201 Element.Class = Record;
Douglas Gregora8f32e02009-10-06 17:59:45 +0000202 if (BaseSpec->isVirtual())
203 Element.SubobjectNumber = 0;
204 else
205 Element.SubobjectNumber = Subobjects.second;
Douglas Gregor89b77022010-03-03 02:18:00 +0000206 ScratchPath.push_back(Element);
John McCall46460a62010-01-20 21:53:11 +0000207
John McCall92f88312010-01-23 00:46:32 +0000208 // Calculate the "top-down" access to this base class.
209 // The spec actually describes this bottom-up, but top-down is
210 // equivalent because the definition works out as follows:
211 // 1. Write down the access along each step in the inheritance
212 // chain, followed by the access of the decl itself.
213 // For example, in
214 // class A { public: int foo; };
215 // class B : protected A {};
216 // class C : public B {};
217 // class D : private C {};
218 // we would write:
219 // private public protected public
220 // 2. If 'private' appears anywhere except far-left, access is denied.
221 // 3. Otherwise, overall access is determined by the most restrictive
222 // access in the sequence.
223 if (IsFirstStep)
Douglas Gregor89b77022010-03-03 02:18:00 +0000224 ScratchPath.Access = BaseSpec->getAccessSpecifier();
John McCall92f88312010-01-23 00:46:32 +0000225 else
Douglas Gregor89b77022010-03-03 02:18:00 +0000226 ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere,
227 BaseSpec->getAccessSpecifier());
Douglas Gregora8f32e02009-10-06 17:59:45 +0000228 }
John McCalled814cc2010-02-09 00:57:12 +0000229
230 // Track whether there's a path involving this specific base.
231 bool FoundPathThroughBase = false;
232
Douglas Gregor89b77022010-03-03 02:18:00 +0000233 if (BaseMatches(BaseSpec, ScratchPath, UserData)) {
John McCall92f88312010-01-23 00:46:32 +0000234 // We've found a path that terminates at this base.
John McCalled814cc2010-02-09 00:57:12 +0000235 FoundPath = FoundPathThroughBase = true;
Douglas Gregor89b77022010-03-03 02:18:00 +0000236 if (isRecordingPaths()) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000237 // We have a path. Make a copy of it before moving on.
Douglas Gregor89b77022010-03-03 02:18:00 +0000238 Paths.push_back(ScratchPath);
239 } else if (!isFindingAmbiguities()) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000240 // We found a path and we don't care about ambiguities;
241 // return immediately.
242 return FoundPath;
243 }
244 } else if (VisitBase) {
245 CXXRecordDecl *BaseRecord
246 = cast<CXXRecordDecl>(BaseSpec->getType()->getAs<RecordType>()
247 ->getDecl());
Douglas Gregor89b77022010-03-03 02:18:00 +0000248 if (lookupInBases(Context, BaseRecord, BaseMatches, UserData)) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000249 // C++ [class.member.lookup]p2:
250 // A member name f in one sub-object B hides a member name f in
251 // a sub-object A if A is a base class sub-object of B. Any
252 // declarations that are so hidden are eliminated from
253 // consideration.
254
255 // There is a path to a base class that meets the criteria. If we're
256 // not collecting paths or finding ambiguities, we're done.
John McCalled814cc2010-02-09 00:57:12 +0000257 FoundPath = FoundPathThroughBase = true;
Douglas Gregor89b77022010-03-03 02:18:00 +0000258 if (!isFindingAmbiguities())
Douglas Gregora8f32e02009-10-06 17:59:45 +0000259 return FoundPath;
260 }
261 }
262
263 // Pop this base specifier off the current path (if we're
264 // collecting paths).
Douglas Gregor89b77022010-03-03 02:18:00 +0000265 if (isRecordingPaths()) {
266 ScratchPath.pop_back();
John McCall46460a62010-01-20 21:53:11 +0000267 }
268
Douglas Gregora8f32e02009-10-06 17:59:45 +0000269 // If we set a virtual earlier, and this isn't a path, forget it again.
John McCalled814cc2010-02-09 00:57:12 +0000270 if (SetVirtual && !FoundPathThroughBase) {
Douglas Gregor89b77022010-03-03 02:18:00 +0000271 DetectedVirtual = 0;
Douglas Gregora8f32e02009-10-06 17:59:45 +0000272 }
273 }
John McCall92f88312010-01-23 00:46:32 +0000274
275 // Reset the scratch path access.
Douglas Gregor89b77022010-03-03 02:18:00 +0000276 ScratchPath.Access = AccessToHere;
Douglas Gregora8f32e02009-10-06 17:59:45 +0000277
278 return FoundPath;
279}
280
Douglas Gregor89b77022010-03-03 02:18:00 +0000281bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
282 void *UserData,
283 CXXBasePaths &Paths) const {
Douglas Gregor4e6ba4b2010-03-03 04:38:46 +0000284 // If we didn't find anything, report that.
285 if (!Paths.lookupInBases(getASTContext(), this, BaseMatches, UserData))
286 return false;
287
288 // If we're not recording paths or we won't ever find ambiguities,
289 // we're done.
290 if (!Paths.isRecordingPaths() || !Paths.isFindingAmbiguities())
291 return true;
292
293 // C++ [class.member.lookup]p6:
294 // When virtual base classes are used, a hidden declaration can be
295 // reached along a path through the sub-object lattice that does
296 // not pass through the hiding declaration. This is not an
297 // ambiguity. The identical use with nonvirtual base classes is an
298 // ambiguity; in that case there is no unique instance of the name
299 // that hides all the others.
300 //
301 // FIXME: This is an O(N^2) algorithm, but DPG doesn't see an easy
302 // way to make it any faster.
303 for (CXXBasePaths::paths_iterator P = Paths.begin(), PEnd = Paths.end();
304 P != PEnd; /* increment in loop */) {
305 bool Hidden = false;
306
307 for (CXXBasePath::iterator PE = P->begin(), PEEnd = P->end();
308 PE != PEEnd && !Hidden; ++PE) {
309 if (PE->Base->isVirtual()) {
310 CXXRecordDecl *VBase = 0;
311 if (const RecordType *Record = PE->Base->getType()->getAs<RecordType>())
312 VBase = cast<CXXRecordDecl>(Record->getDecl());
313 if (!VBase)
314 break;
315
316 // The declaration(s) we found along this path were found in a
317 // subobject of a virtual base. Check whether this virtual
318 // base is a subobject of any other path; if so, then the
319 // declaration in this path are hidden by that patch.
320 for (CXXBasePaths::paths_iterator HidingP = Paths.begin(),
321 HidingPEnd = Paths.end();
322 HidingP != HidingPEnd;
323 ++HidingP) {
324 CXXRecordDecl *HidingClass = 0;
325 if (const RecordType *Record
326 = HidingP->back().Base->getType()->getAs<RecordType>())
327 HidingClass = cast<CXXRecordDecl>(Record->getDecl());
328 if (!HidingClass)
329 break;
330
331 if (HidingClass->isVirtuallyDerivedFrom(VBase)) {
332 Hidden = true;
333 break;
334 }
335 }
336 }
337 }
338
339 if (Hidden)
340 P = Paths.Paths.erase(P);
341 else
342 ++P;
343 }
344
345 return true;
Douglas Gregor89b77022010-03-03 02:18:00 +0000346}
347
John McCallaf8e6ed2009-11-12 03:15:40 +0000348bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier,
Douglas Gregora8f32e02009-10-06 17:59:45 +0000349 CXXBasePath &Path,
350 void *BaseRecord) {
351 assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
352 "User data for FindBaseClass is not canonical!");
353 return Specifier->getType()->getAs<RecordType>()->getDecl()
354 ->getCanonicalDecl() == BaseRecord;
355}
356
Douglas Gregor4e6ba4b2010-03-03 04:38:46 +0000357bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
358 CXXBasePath &Path,
359 void *BaseRecord) {
360 assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
361 "User data for FindBaseClass is not canonical!");
362 return Specifier->isVirtual() &&
363 Specifier->getType()->getAs<RecordType>()->getDecl()
364 ->getCanonicalDecl() == BaseRecord;
365}
366
John McCallaf8e6ed2009-11-12 03:15:40 +0000367bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier,
Douglas Gregora8f32e02009-10-06 17:59:45 +0000368 CXXBasePath &Path,
369 void *Name) {
370 RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
371
372 DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
373 for (Path.Decls = BaseRecord->lookup(N);
374 Path.Decls.first != Path.Decls.second;
375 ++Path.Decls.first) {
376 if ((*Path.Decls.first)->isInIdentifierNamespace(IDNS_Tag))
377 return true;
378 }
379
380 return false;
381}
382
John McCallaf8e6ed2009-11-12 03:15:40 +0000383bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
Douglas Gregora8f32e02009-10-06 17:59:45 +0000384 CXXBasePath &Path,
385 void *Name) {
386 RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
387
388 const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member;
389 DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
390 for (Path.Decls = BaseRecord->lookup(N);
391 Path.Decls.first != Path.Decls.second;
392 ++Path.Decls.first) {
393 if ((*Path.Decls.first)->isInIdentifierNamespace(IDNS))
394 return true;
395 }
396
397 return false;
398}
399
John McCallaf8e6ed2009-11-12 03:15:40 +0000400bool CXXRecordDecl::
401FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
402 CXXBasePath &Path,
403 void *Name) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000404 RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
405
406 DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
407 for (Path.Decls = BaseRecord->lookup(N);
408 Path.Decls.first != Path.Decls.second;
409 ++Path.Decls.first) {
410 // FIXME: Refactor the "is it a nested-name-specifier?" check
411 if (isa<TypedefDecl>(*Path.Decls.first) ||
412 (*Path.Decls.first)->isInIdentifierNamespace(IDNS_Tag))
413 return true;
414 }
415
416 return false;
Mike Stump82109bd2009-10-06 23:38:59 +0000417}
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000418
419void OverridingMethods::add(unsigned OverriddenSubobject,
420 UniqueVirtualMethod Overriding) {
421 llvm::SmallVector<UniqueVirtualMethod, 4> &SubobjectOverrides
422 = Overrides[OverriddenSubobject];
423 if (std::find(SubobjectOverrides.begin(), SubobjectOverrides.end(),
424 Overriding) == SubobjectOverrides.end())
425 SubobjectOverrides.push_back(Overriding);
426}
427
428void OverridingMethods::add(const OverridingMethods &Other) {
429 for (const_iterator I = Other.begin(), IE = Other.end(); I != IE; ++I) {
430 for (overriding_const_iterator M = I->second.begin(),
431 MEnd = I->second.end();
432 M != MEnd;
433 ++M)
434 add(I->first, *M);
435 }
436}
437
438void OverridingMethods::replaceAll(UniqueVirtualMethod Overriding) {
439 for (iterator I = begin(), IEnd = end(); I != IEnd; ++I) {
440 I->second.clear();
441 I->second.push_back(Overriding);
442 }
443}
444
445
446namespace {
447 class FinalOverriderCollector {
448 /// \brief The number of subobjects of a given class type that
449 /// occur within the class hierarchy.
450 llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCount;
451
452 /// \brief Overriders for each virtual base subobject.
453 llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders;
454
455 CXXFinalOverriderMap FinalOverriders;
456
457 public:
458 ~FinalOverriderCollector();
459
460 void Collect(const CXXRecordDecl *RD, bool VirtualBase,
461 const CXXRecordDecl *InVirtualSubobject,
462 CXXFinalOverriderMap &Overriders);
463 };
464}
465
466void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
467 bool VirtualBase,
468 const CXXRecordDecl *InVirtualSubobject,
469 CXXFinalOverriderMap &Overriders) {
470 unsigned SubobjectNumber = 0;
471 if (!VirtualBase)
472 SubobjectNumber
473 = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
474
475 for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(),
476 BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base) {
477 if (const RecordType *RT = Base->getType()->getAs<RecordType>()) {
478 const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl());
479 if (!BaseDecl->isPolymorphic())
480 continue;
481
482 if (Overriders.empty() && !Base->isVirtual()) {
483 // There are no other overriders of virtual member functions,
484 // so let the base class fill in our overriders for us.
485 Collect(BaseDecl, false, InVirtualSubobject, Overriders);
486 continue;
487 }
488
489 // Collect all of the overridders from the base class subobject
490 // and merge them into the set of overridders for this class.
491 // For virtual base classes, populate or use the cached virtual
492 // overrides so that we do not walk the virtual base class (and
493 // its base classes) more than once.
494 CXXFinalOverriderMap ComputedBaseOverriders;
495 CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders;
496 if (Base->isVirtual()) {
497 CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl];
498 if (!MyVirtualOverriders) {
499 MyVirtualOverriders = new CXXFinalOverriderMap;
500 Collect(BaseDecl, true, BaseDecl, *MyVirtualOverriders);
501 }
502
503 BaseOverriders = MyVirtualOverriders;
504 } else
505 Collect(BaseDecl, false, InVirtualSubobject, ComputedBaseOverriders);
506
507 // Merge the overriders from this base class into our own set of
508 // overriders.
509 for (CXXFinalOverriderMap::iterator OM = BaseOverriders->begin(),
510 OMEnd = BaseOverriders->end();
511 OM != OMEnd;
512 ++OM) {
513 const CXXMethodDecl *CanonOM
514 = cast<CXXMethodDecl>(OM->first->getCanonicalDecl());
515 Overriders[CanonOM].add(OM->second);
516 }
517 }
518 }
519
520 for (CXXRecordDecl::method_iterator M = RD->method_begin(),
521 MEnd = RD->method_end();
522 M != MEnd;
523 ++M) {
524 // We only care about virtual methods.
525 if (!M->isVirtual())
526 continue;
527
528 CXXMethodDecl *CanonM = cast<CXXMethodDecl>(M->getCanonicalDecl());
529
530 if (CanonM->begin_overridden_methods()
531 == CanonM->end_overridden_methods()) {
532 // This is a new virtual function that does not override any
533 // other virtual function. Add it to the map of virtual
534 // functions for which we are tracking overridders.
535
536 // C++ [class.virtual]p2:
537 // For convenience we say that any virtual function overrides itself.
538 Overriders[CanonM].add(SubobjectNumber,
539 UniqueVirtualMethod(CanonM, SubobjectNumber,
540 InVirtualSubobject));
541 continue;
542 }
543
544 // This virtual method overrides other virtual methods, so it does
545 // not add any new slots into the set of overriders. Instead, we
546 // replace entries in the set of overriders with the new
547 // overrider. To do so, we dig down to the original virtual
548 // functions using data recursion and update all of the methods it
549 // overrides.
550 typedef std::pair<CXXMethodDecl::method_iterator,
551 CXXMethodDecl::method_iterator> OverriddenMethods;
552 llvm::SmallVector<OverriddenMethods, 4> Stack;
553 Stack.push_back(std::make_pair(CanonM->begin_overridden_methods(),
554 CanonM->end_overridden_methods()));
555 while (!Stack.empty()) {
556 OverriddenMethods OverMethods = Stack.back();
557 Stack.pop_back();
558
559 for (; OverMethods.first != OverMethods.second; ++OverMethods.first) {
560 const CXXMethodDecl *CanonOM
561 = cast<CXXMethodDecl>((*OverMethods.first)->getCanonicalDecl());
Anders Carlssonffdb2d22010-06-03 01:00:02 +0000562
563 // C++ [class.virtual]p2:
564 // A virtual member function C::vf of a class object S is
565 // a final overrider unless the most derived class (1.8)
566 // of which S is a base class subobject (if any) declares
567 // or inherits another member function that overrides vf.
568 //
569 // Treating this object like the most derived class, we
570 // replace any overrides from base classes with this
571 // overriding virtual function.
572 Overriders[CanonOM].replaceAll(
573 UniqueVirtualMethod(CanonM, SubobjectNumber,
574 InVirtualSubobject));
575
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000576 if (CanonOM->begin_overridden_methods()
Anders Carlssonffdb2d22010-06-03 01:00:02 +0000577 == CanonOM->end_overridden_methods())
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000578 continue;
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000579
580 // Continue recursion to the methods that this virtual method
581 // overrides.
582 Stack.push_back(std::make_pair(CanonOM->begin_overridden_methods(),
583 CanonOM->end_overridden_methods()));
584 }
585 }
Anders Carlssonffdb2d22010-06-03 01:00:02 +0000586
587 // C++ [class.virtual]p2:
588 // For convenience we say that any virtual function overrides itself.
589 Overriders[CanonM].add(SubobjectNumber,
590 UniqueVirtualMethod(CanonM, SubobjectNumber,
591 InVirtualSubobject));
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000592 }
593}
594
595FinalOverriderCollector::~FinalOverriderCollector() {
596 for (llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *>::iterator
597 VO = VirtualOverriders.begin(), VOEnd = VirtualOverriders.end();
598 VO != VOEnd;
599 ++VO)
600 delete VO->second;
601}
602
603void
604CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const {
605 FinalOverriderCollector Collector;
606 Collector.Collect(this, false, 0, FinalOverriders);
607
608 // Weed out any final overriders that come from virtual base class
609 // subobjects that were hidden by other subobjects along any path.
610 // This is the final-overrider variant of C++ [class.member.lookup]p10.
611 for (CXXFinalOverriderMap::iterator OM = FinalOverriders.begin(),
612 OMEnd = FinalOverriders.end();
613 OM != OMEnd;
614 ++OM) {
615 for (OverridingMethods::iterator SO = OM->second.begin(),
616 SOEnd = OM->second.end();
617 SO != SOEnd;
618 ++SO) {
619 llvm::SmallVector<UniqueVirtualMethod, 4> &Overriding = SO->second;
620 if (Overriding.size() < 2)
621 continue;
622
623 for (llvm::SmallVector<UniqueVirtualMethod, 4>::iterator
624 Pos = Overriding.begin(), PosEnd = Overriding.end();
625 Pos != PosEnd;
626 /* increment in loop */) {
627 if (!Pos->InVirtualSubobject) {
628 ++Pos;
629 continue;
630 }
631
632 // We have an overriding method in a virtual base class
633 // subobject (or non-virtual base class subobject thereof);
634 // determine whether there exists an other overriding method
635 // in a base class subobject that hides the virtual base class
636 // subobject.
637 bool Hidden = false;
638 for (llvm::SmallVector<UniqueVirtualMethod, 4>::iterator
639 OP = Overriding.begin(), OPEnd = Overriding.end();
640 OP != OPEnd && !Hidden;
641 ++OP) {
642 if (Pos == OP)
643 continue;
644
645 if (OP->Method->getParent()->isVirtuallyDerivedFrom(
646 const_cast<CXXRecordDecl *>(Pos->InVirtualSubobject)))
647 Hidden = true;
648 }
649
650 if (Hidden) {
651 // The current overriding function is hidden by another
652 // overriding function; remove this one.
653 Pos = Overriding.erase(Pos);
654 PosEnd = Overriding.end();
655 } else {
656 ++Pos;
657 }
658 }
659 }
660 }
661}