blob: 292b23dcc6924e19dad0140687770c24441f30ad [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"
Benjamin Kramerd4f51982012-07-04 18:45:14 +000014#include "clang/AST/ASTContext.h"
Anders Carlsson46170f92010-11-24 22:50:27 +000015#include "clang/AST/RecordLayout.h"
Douglas Gregora8f32e02009-10-06 17:59:45 +000016#include "clang/AST/DeclCXX.h"
Douglas Gregora13cdf42012-09-11 07:19:42 +000017#include "llvm/ADT/SetVector.h"
Douglas Gregora8f32e02009-10-06 17:59:45 +000018#include <algorithm>
19#include <set>
20
21using namespace clang;
22
23/// \brief Computes the set of declarations referenced by these base
24/// paths.
25void CXXBasePaths::ComputeDeclsFound() {
26 assert(NumDeclsFound == 0 && !DeclsFound &&
27 "Already computed the set of declarations");
Benjamin Kramerd0e49e52012-02-23 15:18:31 +000028
Douglas Gregora13cdf42012-09-11 07:19:42 +000029 llvm::SetVector<NamedDecl *, SmallVector<NamedDecl *, 8> > Decls;
Benjamin Kramerd0e49e52012-02-23 15:18:31 +000030 for (paths_iterator Path = begin(), PathEnd = end(); Path != PathEnd; ++Path)
Douglas Gregora13cdf42012-09-11 07:19:42 +000031 Decls.insert(*Path->Decls.first);
Benjamin Kramerd0e49e52012-02-23 15:18:31 +000032
Douglas Gregora8f32e02009-10-06 17:59:45 +000033 NumDeclsFound = Decls.size();
34 DeclsFound = new NamedDecl * [NumDeclsFound];
35 std::copy(Decls.begin(), Decls.end(), DeclsFound);
36}
37
38CXXBasePaths::decl_iterator CXXBasePaths::found_decls_begin() {
39 if (NumDeclsFound == 0)
40 ComputeDeclsFound();
41 return DeclsFound;
42}
43
44CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() {
45 if (NumDeclsFound == 0)
46 ComputeDeclsFound();
47 return DeclsFound + NumDeclsFound;
48}
49
50/// isAmbiguous - Determines whether the set of paths provided is
51/// ambiguous, i.e., there are two or more paths that refer to
52/// different base class subobjects of the same type. BaseType must be
53/// an unqualified, canonical class type.
Douglas Gregore0d5fe22010-05-21 20:29:55 +000054bool CXXBasePaths::isAmbiguous(CanQualType BaseType) {
55 BaseType = BaseType.getUnqualifiedType();
Douglas Gregora8f32e02009-10-06 17:59:45 +000056 std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
57 return Subobjects.second + (Subobjects.first? 1 : 0) > 1;
58}
59
60/// clear - Clear out all prior path information.
61void CXXBasePaths::clear() {
62 Paths.clear();
63 ClassSubobjects.clear();
64 ScratchPath.clear();
65 DetectedVirtual = 0;
66}
67
68/// @brief Swaps the contents of this CXXBasePaths structure with the
69/// contents of Other.
70void CXXBasePaths::swap(CXXBasePaths &Other) {
71 std::swap(Origin, Other.Origin);
72 Paths.swap(Other.Paths);
73 ClassSubobjects.swap(Other.ClassSubobjects);
74 std::swap(FindAmbiguities, Other.FindAmbiguities);
75 std::swap(RecordPaths, Other.RecordPaths);
76 std::swap(DetectVirtual, Other.DetectVirtual);
77 std::swap(DetectedVirtual, Other.DetectedVirtual);
78}
79
John McCalld89d30f2011-01-28 22:02:36 +000080bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base) const {
Douglas Gregora8f32e02009-10-06 17:59:45 +000081 CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
82 /*DetectVirtual=*/false);
83 return isDerivedFrom(Base, Paths);
84}
85
John McCalld89d30f2011-01-28 22:02:36 +000086bool CXXRecordDecl::isDerivedFrom(const CXXRecordDecl *Base,
87 CXXBasePaths &Paths) const {
Douglas Gregora8f32e02009-10-06 17:59:45 +000088 if (getCanonicalDecl() == Base->getCanonicalDecl())
89 return false;
90
John McCallaf8e6ed2009-11-12 03:15:40 +000091 Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
John McCalld89d30f2011-01-28 22:02:36 +000092 return lookupInBases(&FindBaseClass,
93 const_cast<CXXRecordDecl*>(Base->getCanonicalDecl()),
94 Paths);
Douglas Gregora8f32e02009-10-06 17:59:45 +000095}
96
Jordan Rose2aa800a2012-08-08 18:23:20 +000097bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const {
Anders Carlsson1c4c3972010-06-04 01:40:08 +000098 if (!getNumVBases())
99 return false;
100
Douglas Gregor4e6ba4b2010-03-03 04:38:46 +0000101 CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
102 /*DetectVirtual=*/false);
103
104 if (getCanonicalDecl() == Base->getCanonicalDecl())
105 return false;
106
Jordan Rose2aa800a2012-08-08 18:23:20 +0000107 Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
108
109 const void *BasePtr = static_cast<const void*>(Base->getCanonicalDecl());
110 return lookupInBases(&FindVirtualBaseClass,
111 const_cast<void *>(BasePtr),
112 Paths);
Douglas Gregor4e6ba4b2010-03-03 04:38:46 +0000113}
114
John McCalle8174bc2009-12-08 07:42:38 +0000115static bool BaseIsNot(const CXXRecordDecl *Base, void *OpaqueTarget) {
116 // OpaqueTarget is a CXXRecordDecl*.
117 return Base->getCanonicalDecl() != (const CXXRecordDecl*) OpaqueTarget;
118}
119
120bool CXXRecordDecl::isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const {
121 return forallBases(BaseIsNot, (void*) Base->getCanonicalDecl());
122}
123
Richard Smithf62c6902012-11-22 00:24:47 +0000124bool
125CXXRecordDecl::isCurrentInstantiation(const DeclContext *CurContext) const {
126 assert(isDependentContext());
127
128 for (; !CurContext->isFileContext(); CurContext = CurContext->getParent())
129 if (CurContext->Equals(this))
130 return true;
131
132 return false;
133}
134
John McCalle8174bc2009-12-08 07:42:38 +0000135bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
136 void *OpaqueData,
Douglas Gregor229d47a2012-11-10 07:24:09 +0000137 bool AllowShortCircuit) const {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000138 SmallVector<const CXXRecordDecl*, 8> Queue;
John McCalle8174bc2009-12-08 07:42:38 +0000139
140 const CXXRecordDecl *Record = this;
141 bool AllMatches = true;
142 while (true) {
143 for (CXXRecordDecl::base_class_const_iterator
144 I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
Douglas Gregor229d47a2012-11-10 07:24:09 +0000145 const RecordType *Ty = I->getType()->getAs<RecordType>();
146 if (!Ty) {
John McCalle8174bc2009-12-08 07:42:38 +0000147 if (AllowShortCircuit) return false;
148 AllMatches = false;
149 continue;
150 }
151
Douglas Gregor229d47a2012-11-10 07:24:09 +0000152 CXXRecordDecl *Base =
153 cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition());
Richard Smithf62c6902012-11-22 00:24:47 +0000154 if (!Base ||
155 (Base->isDependentContext() &&
156 !Base->isCurrentInstantiation(Record))) {
John McCalle8174bc2009-12-08 07:42:38 +0000157 if (AllowShortCircuit) return false;
158 AllMatches = false;
159 continue;
160 }
161
Anders Carlssonca910e82009-12-09 04:26:02 +0000162 Queue.push_back(Base);
163 if (!BaseMatches(Base, OpaqueData)) {
John McCalle8174bc2009-12-08 07:42:38 +0000164 if (AllowShortCircuit) return false;
165 AllMatches = false;
166 continue;
167 }
168 }
169
170 if (Queue.empty()) break;
171 Record = Queue.back(); // not actually a queue.
172 Queue.pop_back();
173 }
174
175 return AllMatches;
176}
177
Jordan Rose2aa800a2012-08-08 18:23:20 +0000178bool CXXBasePaths::lookupInBases(ASTContext &Context,
Douglas Gregor89b77022010-03-03 02:18:00 +0000179 const CXXRecordDecl *Record,
180 CXXRecordDecl::BaseMatchesCallback *BaseMatches,
181 void *UserData) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000182 bool FoundPath = false;
John McCall46460a62010-01-20 21:53:11 +0000183
John McCall92f88312010-01-23 00:46:32 +0000184 // The access of the path down to this record.
Douglas Gregor89b77022010-03-03 02:18:00 +0000185 AccessSpecifier AccessToHere = ScratchPath.Access;
186 bool IsFirstStep = ScratchPath.empty();
John McCall92f88312010-01-23 00:46:32 +0000187
Douglas Gregor89b77022010-03-03 02:18:00 +0000188 for (CXXRecordDecl::base_class_const_iterator BaseSpec = Record->bases_begin(),
189 BaseSpecEnd = Record->bases_end();
190 BaseSpec != BaseSpecEnd;
191 ++BaseSpec) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000192 // Find the record of the base class subobjects for this type.
Douglas Gregora4923eb2009-11-16 21:35:15 +0000193 QualType BaseType = Context.getCanonicalType(BaseSpec->getType())
194 .getUnqualifiedType();
Douglas Gregora8f32e02009-10-06 17:59:45 +0000195
196 // C++ [temp.dep]p3:
197 // In the definition of a class template or a member of a class template,
198 // if a base class of the class template depends on a template-parameter,
199 // the base class scope is not examined during unqualified name lookup
200 // either at the point of definition of the class template or member or
201 // during an instantiation of the class tem- plate or member.
202 if (BaseType->isDependentType())
203 continue;
204
205 // Determine whether we need to visit this base class at all,
206 // updating the count of subobjects appropriately.
Douglas Gregor89b77022010-03-03 02:18:00 +0000207 std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
Douglas Gregora8f32e02009-10-06 17:59:45 +0000208 bool VisitBase = true;
209 bool SetVirtual = false;
210 if (BaseSpec->isVirtual()) {
211 VisitBase = !Subobjects.first;
212 Subobjects.first = true;
Douglas Gregor89b77022010-03-03 02:18:00 +0000213 if (isDetectingVirtual() && DetectedVirtual == 0) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000214 // If this is the first virtual we find, remember it. If it turns out
215 // there is no base path here, we'll reset it later.
Douglas Gregor89b77022010-03-03 02:18:00 +0000216 DetectedVirtual = BaseType->getAs<RecordType>();
Douglas Gregora8f32e02009-10-06 17:59:45 +0000217 SetVirtual = true;
218 }
219 } else
220 ++Subobjects.second;
221
Douglas Gregor89b77022010-03-03 02:18:00 +0000222 if (isRecordingPaths()) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000223 // Add this base specifier to the current path.
224 CXXBasePathElement Element;
225 Element.Base = &*BaseSpec;
Douglas Gregor89b77022010-03-03 02:18:00 +0000226 Element.Class = Record;
Douglas Gregora8f32e02009-10-06 17:59:45 +0000227 if (BaseSpec->isVirtual())
228 Element.SubobjectNumber = 0;
229 else
230 Element.SubobjectNumber = Subobjects.second;
Douglas Gregor89b77022010-03-03 02:18:00 +0000231 ScratchPath.push_back(Element);
John McCall46460a62010-01-20 21:53:11 +0000232
John McCall92f88312010-01-23 00:46:32 +0000233 // Calculate the "top-down" access to this base class.
234 // The spec actually describes this bottom-up, but top-down is
235 // equivalent because the definition works out as follows:
236 // 1. Write down the access along each step in the inheritance
237 // chain, followed by the access of the decl itself.
238 // For example, in
239 // class A { public: int foo; };
240 // class B : protected A {};
241 // class C : public B {};
242 // class D : private C {};
243 // we would write:
244 // private public protected public
245 // 2. If 'private' appears anywhere except far-left, access is denied.
246 // 3. Otherwise, overall access is determined by the most restrictive
247 // access in the sequence.
248 if (IsFirstStep)
Douglas Gregor89b77022010-03-03 02:18:00 +0000249 ScratchPath.Access = BaseSpec->getAccessSpecifier();
John McCall92f88312010-01-23 00:46:32 +0000250 else
Douglas Gregor89b77022010-03-03 02:18:00 +0000251 ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere,
252 BaseSpec->getAccessSpecifier());
Douglas Gregora8f32e02009-10-06 17:59:45 +0000253 }
John McCalled814cc2010-02-09 00:57:12 +0000254
255 // Track whether there's a path involving this specific base.
256 bool FoundPathThroughBase = false;
257
Douglas Gregor89b77022010-03-03 02:18:00 +0000258 if (BaseMatches(BaseSpec, ScratchPath, UserData)) {
John McCall92f88312010-01-23 00:46:32 +0000259 // We've found a path that terminates at this base.
John McCalled814cc2010-02-09 00:57:12 +0000260 FoundPath = FoundPathThroughBase = true;
Douglas Gregor89b77022010-03-03 02:18:00 +0000261 if (isRecordingPaths()) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000262 // We have a path. Make a copy of it before moving on.
Douglas Gregor89b77022010-03-03 02:18:00 +0000263 Paths.push_back(ScratchPath);
264 } else if (!isFindingAmbiguities()) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000265 // We found a path and we don't care about ambiguities;
266 // return immediately.
267 return FoundPath;
268 }
269 } else if (VisitBase) {
270 CXXRecordDecl *BaseRecord
Ted Kremenekcca17802012-09-12 06:50:29 +0000271 = cast<CXXRecordDecl>(BaseSpec->getType()->castAs<RecordType>()
Douglas Gregora8f32e02009-10-06 17:59:45 +0000272 ->getDecl());
Douglas Gregor89b77022010-03-03 02:18:00 +0000273 if (lookupInBases(Context, BaseRecord, BaseMatches, UserData)) {
Douglas Gregora8f32e02009-10-06 17:59:45 +0000274 // C++ [class.member.lookup]p2:
275 // A member name f in one sub-object B hides a member name f in
276 // a sub-object A if A is a base class sub-object of B. Any
277 // declarations that are so hidden are eliminated from
278 // consideration.
279
280 // There is a path to a base class that meets the criteria. If we're
281 // not collecting paths or finding ambiguities, we're done.
John McCalled814cc2010-02-09 00:57:12 +0000282 FoundPath = FoundPathThroughBase = true;
Douglas Gregor89b77022010-03-03 02:18:00 +0000283 if (!isFindingAmbiguities())
Douglas Gregora8f32e02009-10-06 17:59:45 +0000284 return FoundPath;
285 }
286 }
287
288 // Pop this base specifier off the current path (if we're
289 // collecting paths).
Douglas Gregor89b77022010-03-03 02:18:00 +0000290 if (isRecordingPaths()) {
291 ScratchPath.pop_back();
John McCall46460a62010-01-20 21:53:11 +0000292 }
293
Douglas Gregora8f32e02009-10-06 17:59:45 +0000294 // If we set a virtual earlier, and this isn't a path, forget it again.
John McCalled814cc2010-02-09 00:57:12 +0000295 if (SetVirtual && !FoundPathThroughBase) {
Douglas Gregor89b77022010-03-03 02:18:00 +0000296 DetectedVirtual = 0;
Douglas Gregora8f32e02009-10-06 17:59:45 +0000297 }
298 }
John McCall92f88312010-01-23 00:46:32 +0000299
300 // Reset the scratch path access.
Douglas Gregor89b77022010-03-03 02:18:00 +0000301 ScratchPath.Access = AccessToHere;
Douglas Gregora8f32e02009-10-06 17:59:45 +0000302
303 return FoundPath;
304}
305
Douglas Gregor89b77022010-03-03 02:18:00 +0000306bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
307 void *UserData,
308 CXXBasePaths &Paths) const {
Douglas Gregor4e6ba4b2010-03-03 04:38:46 +0000309 // If we didn't find anything, report that.
310 if (!Paths.lookupInBases(getASTContext(), this, BaseMatches, UserData))
311 return false;
312
313 // If we're not recording paths or we won't ever find ambiguities,
314 // we're done.
315 if (!Paths.isRecordingPaths() || !Paths.isFindingAmbiguities())
316 return true;
317
318 // C++ [class.member.lookup]p6:
319 // When virtual base classes are used, a hidden declaration can be
320 // reached along a path through the sub-object lattice that does
321 // not pass through the hiding declaration. This is not an
322 // ambiguity. The identical use with nonvirtual base classes is an
323 // ambiguity; in that case there is no unique instance of the name
324 // that hides all the others.
325 //
326 // FIXME: This is an O(N^2) algorithm, but DPG doesn't see an easy
327 // way to make it any faster.
328 for (CXXBasePaths::paths_iterator P = Paths.begin(), PEnd = Paths.end();
329 P != PEnd; /* increment in loop */) {
330 bool Hidden = false;
331
332 for (CXXBasePath::iterator PE = P->begin(), PEEnd = P->end();
333 PE != PEEnd && !Hidden; ++PE) {
334 if (PE->Base->isVirtual()) {
335 CXXRecordDecl *VBase = 0;
336 if (const RecordType *Record = PE->Base->getType()->getAs<RecordType>())
337 VBase = cast<CXXRecordDecl>(Record->getDecl());
338 if (!VBase)
339 break;
340
341 // The declaration(s) we found along this path were found in a
342 // subobject of a virtual base. Check whether this virtual
343 // base is a subobject of any other path; if so, then the
344 // declaration in this path are hidden by that patch.
345 for (CXXBasePaths::paths_iterator HidingP = Paths.begin(),
346 HidingPEnd = Paths.end();
347 HidingP != HidingPEnd;
348 ++HidingP) {
349 CXXRecordDecl *HidingClass = 0;
350 if (const RecordType *Record
351 = HidingP->back().Base->getType()->getAs<RecordType>())
352 HidingClass = cast<CXXRecordDecl>(Record->getDecl());
353 if (!HidingClass)
354 break;
355
356 if (HidingClass->isVirtuallyDerivedFrom(VBase)) {
357 Hidden = true;
358 break;
359 }
360 }
361 }
362 }
363
364 if (Hidden)
365 P = Paths.Paths.erase(P);
366 else
367 ++P;
368 }
369
370 return true;
Douglas Gregor89b77022010-03-03 02:18:00 +0000371}
372
John McCallaf8e6ed2009-11-12 03:15:40 +0000373bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier,
Douglas Gregora8f32e02009-10-06 17:59:45 +0000374 CXXBasePath &Path,
375 void *BaseRecord) {
376 assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
377 "User data for FindBaseClass is not canonical!");
Ted Kremenek890f0f12012-08-23 20:46:57 +0000378 return Specifier->getType()->castAs<RecordType>()->getDecl()
379 ->getCanonicalDecl() == BaseRecord;
Douglas Gregora8f32e02009-10-06 17:59:45 +0000380}
381
Douglas Gregor4e6ba4b2010-03-03 04:38:46 +0000382bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
383 CXXBasePath &Path,
384 void *BaseRecord) {
385 assert(((Decl *)BaseRecord)->getCanonicalDecl() == BaseRecord &&
386 "User data for FindBaseClass is not canonical!");
387 return Specifier->isVirtual() &&
Ted Kremenek890f0f12012-08-23 20:46:57 +0000388 Specifier->getType()->castAs<RecordType>()->getDecl()
389 ->getCanonicalDecl() == BaseRecord;
Douglas Gregor4e6ba4b2010-03-03 04:38:46 +0000390}
391
John McCallaf8e6ed2009-11-12 03:15:40 +0000392bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier,
Douglas Gregora8f32e02009-10-06 17:59:45 +0000393 CXXBasePath &Path,
394 void *Name) {
Ted Kremenek890f0f12012-08-23 20:46:57 +0000395 RecordDecl *BaseRecord =
396 Specifier->getType()->castAs<RecordType>()->getDecl();
Douglas Gregora8f32e02009-10-06 17:59:45 +0000397
398 DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
399 for (Path.Decls = BaseRecord->lookup(N);
400 Path.Decls.first != Path.Decls.second;
401 ++Path.Decls.first) {
402 if ((*Path.Decls.first)->isInIdentifierNamespace(IDNS_Tag))
403 return true;
404 }
405
406 return false;
407}
408
John McCallaf8e6ed2009-11-12 03:15:40 +0000409bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
Douglas Gregora8f32e02009-10-06 17:59:45 +0000410 CXXBasePath &Path,
411 void *Name) {
Ted Kremenek890f0f12012-08-23 20:46:57 +0000412 RecordDecl *BaseRecord =
413 Specifier->getType()->castAs<RecordType>()->getDecl();
Douglas Gregora8f32e02009-10-06 17:59:45 +0000414
415 const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member;
416 DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
417 for (Path.Decls = BaseRecord->lookup(N);
418 Path.Decls.first != Path.Decls.second;
419 ++Path.Decls.first) {
420 if ((*Path.Decls.first)->isInIdentifierNamespace(IDNS))
421 return true;
422 }
423
424 return false;
425}
426
John McCallaf8e6ed2009-11-12 03:15:40 +0000427bool CXXRecordDecl::
428FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
429 CXXBasePath &Path,
430 void *Name) {
Ted Kremenek890f0f12012-08-23 20:46:57 +0000431 RecordDecl *BaseRecord =
432 Specifier->getType()->castAs<RecordType>()->getDecl();
Douglas Gregora8f32e02009-10-06 17:59:45 +0000433
434 DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
435 for (Path.Decls = BaseRecord->lookup(N);
436 Path.Decls.first != Path.Decls.second;
437 ++Path.Decls.first) {
438 // FIXME: Refactor the "is it a nested-name-specifier?" check
Richard Smith162e1c12011-04-15 14:24:37 +0000439 if (isa<TypedefNameDecl>(*Path.Decls.first) ||
Douglas Gregora8f32e02009-10-06 17:59:45 +0000440 (*Path.Decls.first)->isInIdentifierNamespace(IDNS_Tag))
441 return true;
442 }
443
444 return false;
Mike Stump82109bd2009-10-06 23:38:59 +0000445}
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000446
447void OverridingMethods::add(unsigned OverriddenSubobject,
448 UniqueVirtualMethod Overriding) {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000449 SmallVector<UniqueVirtualMethod, 4> &SubobjectOverrides
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000450 = Overrides[OverriddenSubobject];
451 if (std::find(SubobjectOverrides.begin(), SubobjectOverrides.end(),
452 Overriding) == SubobjectOverrides.end())
453 SubobjectOverrides.push_back(Overriding);
454}
455
456void OverridingMethods::add(const OverridingMethods &Other) {
457 for (const_iterator I = Other.begin(), IE = Other.end(); I != IE; ++I) {
458 for (overriding_const_iterator M = I->second.begin(),
459 MEnd = I->second.end();
460 M != MEnd;
461 ++M)
462 add(I->first, *M);
463 }
464}
465
466void OverridingMethods::replaceAll(UniqueVirtualMethod Overriding) {
467 for (iterator I = begin(), IEnd = end(); I != IEnd; ++I) {
468 I->second.clear();
469 I->second.push_back(Overriding);
470 }
471}
472
473
474namespace {
475 class FinalOverriderCollector {
476 /// \brief The number of subobjects of a given class type that
477 /// occur within the class hierarchy.
478 llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCount;
479
480 /// \brief Overriders for each virtual base subobject.
481 llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders;
482
483 CXXFinalOverriderMap FinalOverriders;
484
485 public:
486 ~FinalOverriderCollector();
487
488 void Collect(const CXXRecordDecl *RD, bool VirtualBase,
489 const CXXRecordDecl *InVirtualSubobject,
490 CXXFinalOverriderMap &Overriders);
491 };
492}
493
494void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
495 bool VirtualBase,
496 const CXXRecordDecl *InVirtualSubobject,
497 CXXFinalOverriderMap &Overriders) {
498 unsigned SubobjectNumber = 0;
499 if (!VirtualBase)
500 SubobjectNumber
501 = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
502
503 for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(),
504 BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base) {
505 if (const RecordType *RT = Base->getType()->getAs<RecordType>()) {
506 const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl());
507 if (!BaseDecl->isPolymorphic())
508 continue;
509
510 if (Overriders.empty() && !Base->isVirtual()) {
511 // There are no other overriders of virtual member functions,
512 // so let the base class fill in our overriders for us.
513 Collect(BaseDecl, false, InVirtualSubobject, Overriders);
514 continue;
515 }
516
517 // Collect all of the overridders from the base class subobject
518 // and merge them into the set of overridders for this class.
519 // For virtual base classes, populate or use the cached virtual
520 // overrides so that we do not walk the virtual base class (and
521 // its base classes) more than once.
522 CXXFinalOverriderMap ComputedBaseOverriders;
523 CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders;
524 if (Base->isVirtual()) {
525 CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl];
Benjamin Kramere0cf31d2012-05-27 22:41:08 +0000526 BaseOverriders = MyVirtualOverriders;
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000527 if (!MyVirtualOverriders) {
528 MyVirtualOverriders = new CXXFinalOverriderMap;
Benjamin Kramere0cf31d2012-05-27 22:41:08 +0000529
530 // Collect may cause VirtualOverriders to reallocate, invalidating the
531 // MyVirtualOverriders reference. Set BaseOverriders to the right
532 // value now.
533 BaseOverriders = MyVirtualOverriders;
534
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000535 Collect(BaseDecl, true, BaseDecl, *MyVirtualOverriders);
536 }
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000537 } else
538 Collect(BaseDecl, false, InVirtualSubobject, ComputedBaseOverriders);
539
540 // Merge the overriders from this base class into our own set of
541 // overriders.
542 for (CXXFinalOverriderMap::iterator OM = BaseOverriders->begin(),
543 OMEnd = BaseOverriders->end();
544 OM != OMEnd;
545 ++OM) {
546 const CXXMethodDecl *CanonOM
547 = cast<CXXMethodDecl>(OM->first->getCanonicalDecl());
548 Overriders[CanonOM].add(OM->second);
549 }
550 }
551 }
552
553 for (CXXRecordDecl::method_iterator M = RD->method_begin(),
554 MEnd = RD->method_end();
555 M != MEnd;
556 ++M) {
557 // We only care about virtual methods.
558 if (!M->isVirtual())
559 continue;
560
561 CXXMethodDecl *CanonM = cast<CXXMethodDecl>(M->getCanonicalDecl());
562
563 if (CanonM->begin_overridden_methods()
564 == CanonM->end_overridden_methods()) {
565 // This is a new virtual function that does not override any
566 // other virtual function. Add it to the map of virtual
567 // functions for which we are tracking overridders.
568
569 // C++ [class.virtual]p2:
570 // For convenience we say that any virtual function overrides itself.
571 Overriders[CanonM].add(SubobjectNumber,
572 UniqueVirtualMethod(CanonM, SubobjectNumber,
573 InVirtualSubobject));
574 continue;
575 }
576
577 // This virtual method overrides other virtual methods, so it does
578 // not add any new slots into the set of overriders. Instead, we
579 // replace entries in the set of overriders with the new
580 // overrider. To do so, we dig down to the original virtual
581 // functions using data recursion and update all of the methods it
582 // overrides.
583 typedef std::pair<CXXMethodDecl::method_iterator,
584 CXXMethodDecl::method_iterator> OverriddenMethods;
Chris Lattner5f9e2722011-07-23 10:55:15 +0000585 SmallVector<OverriddenMethods, 4> Stack;
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000586 Stack.push_back(std::make_pair(CanonM->begin_overridden_methods(),
587 CanonM->end_overridden_methods()));
588 while (!Stack.empty()) {
589 OverriddenMethods OverMethods = Stack.back();
590 Stack.pop_back();
591
592 for (; OverMethods.first != OverMethods.second; ++OverMethods.first) {
593 const CXXMethodDecl *CanonOM
594 = cast<CXXMethodDecl>((*OverMethods.first)->getCanonicalDecl());
Anders Carlssonffdb2d22010-06-03 01:00:02 +0000595
596 // C++ [class.virtual]p2:
597 // A virtual member function C::vf of a class object S is
598 // a final overrider unless the most derived class (1.8)
599 // of which S is a base class subobject (if any) declares
600 // or inherits another member function that overrides vf.
601 //
602 // Treating this object like the most derived class, we
603 // replace any overrides from base classes with this
604 // overriding virtual function.
605 Overriders[CanonOM].replaceAll(
606 UniqueVirtualMethod(CanonM, SubobjectNumber,
607 InVirtualSubobject));
608
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000609 if (CanonOM->begin_overridden_methods()
Anders Carlssonffdb2d22010-06-03 01:00:02 +0000610 == CanonOM->end_overridden_methods())
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000611 continue;
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000612
613 // Continue recursion to the methods that this virtual method
614 // overrides.
615 Stack.push_back(std::make_pair(CanonOM->begin_overridden_methods(),
616 CanonOM->end_overridden_methods()));
617 }
618 }
Anders Carlssonffdb2d22010-06-03 01:00:02 +0000619
620 // C++ [class.virtual]p2:
621 // For convenience we say that any virtual function overrides itself.
622 Overriders[CanonM].add(SubobjectNumber,
623 UniqueVirtualMethod(CanonM, SubobjectNumber,
624 InVirtualSubobject));
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000625 }
626}
627
628FinalOverriderCollector::~FinalOverriderCollector() {
629 for (llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *>::iterator
630 VO = VirtualOverriders.begin(), VOEnd = VirtualOverriders.end();
631 VO != VOEnd;
632 ++VO)
633 delete VO->second;
634}
635
636void
637CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const {
638 FinalOverriderCollector Collector;
639 Collector.Collect(this, false, 0, FinalOverriders);
640
641 // Weed out any final overriders that come from virtual base class
642 // subobjects that were hidden by other subobjects along any path.
643 // This is the final-overrider variant of C++ [class.member.lookup]p10.
644 for (CXXFinalOverriderMap::iterator OM = FinalOverriders.begin(),
645 OMEnd = FinalOverriders.end();
646 OM != OMEnd;
647 ++OM) {
648 for (OverridingMethods::iterator SO = OM->second.begin(),
649 SOEnd = OM->second.end();
650 SO != SOEnd;
651 ++SO) {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000652 SmallVector<UniqueVirtualMethod, 4> &Overriding = SO->second;
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000653 if (Overriding.size() < 2)
654 continue;
655
Chris Lattner5f9e2722011-07-23 10:55:15 +0000656 for (SmallVector<UniqueVirtualMethod, 4>::iterator
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000657 Pos = Overriding.begin(), PosEnd = Overriding.end();
658 Pos != PosEnd;
659 /* increment in loop */) {
660 if (!Pos->InVirtualSubobject) {
661 ++Pos;
662 continue;
663 }
664
665 // We have an overriding method in a virtual base class
666 // subobject (or non-virtual base class subobject thereof);
667 // determine whether there exists an other overriding method
668 // in a base class subobject that hides the virtual base class
669 // subobject.
670 bool Hidden = false;
Chris Lattner5f9e2722011-07-23 10:55:15 +0000671 for (SmallVector<UniqueVirtualMethod, 4>::iterator
Douglas Gregor7b2fc9d2010-03-23 23:47:56 +0000672 OP = Overriding.begin(), OPEnd = Overriding.end();
673 OP != OPEnd && !Hidden;
674 ++OP) {
675 if (Pos == OP)
676 continue;
677
678 if (OP->Method->getParent()->isVirtuallyDerivedFrom(
679 const_cast<CXXRecordDecl *>(Pos->InVirtualSubobject)))
680 Hidden = true;
681 }
682
683 if (Hidden) {
684 // The current overriding function is hidden by another
685 // overriding function; remove this one.
686 Pos = Overriding.erase(Pos);
687 PosEnd = Overriding.end();
688 } else {
689 ++Pos;
690 }
691 }
692 }
693 }
694}
Anders Carlsson46170f92010-11-24 22:50:27 +0000695
696static void
697AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context,
698 CXXIndirectPrimaryBaseSet& Bases) {
699 // If the record has a virtual primary base class, add it to our set.
700 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
Anders Carlssonc9e814b2010-11-24 23:12:57 +0000701 if (Layout.isPrimaryBaseVirtual())
Anders Carlsson46170f92010-11-24 22:50:27 +0000702 Bases.insert(Layout.getPrimaryBase());
703
704 for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
705 E = RD->bases_end(); I != E; ++I) {
Anders Carlsson3a037652010-11-24 22:55:29 +0000706 assert(!I->getType()->isDependentType() &&
Anders Carlsson46170f92010-11-24 22:50:27 +0000707 "Cannot get indirect primary bases for class with dependent bases.");
708
709 const CXXRecordDecl *BaseDecl =
Ted Kremenek890f0f12012-08-23 20:46:57 +0000710 cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
Anders Carlsson46170f92010-11-24 22:50:27 +0000711
712 // Only bases with virtual bases participate in computing the
713 // indirect primary virtual base classes.
714 if (BaseDecl->getNumVBases())
715 AddIndirectPrimaryBases(BaseDecl, Context, Bases);
716 }
717
718}
719
720void
721CXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const {
722 ASTContext &Context = getASTContext();
723
724 if (!getNumVBases())
725 return;
726
727 for (CXXRecordDecl::base_class_const_iterator I = bases_begin(),
728 E = bases_end(); I != E; ++I) {
Anders Carlsson3a037652010-11-24 22:55:29 +0000729 assert(!I->getType()->isDependentType() &&
Anders Carlsson46170f92010-11-24 22:50:27 +0000730 "Cannot get indirect primary bases for class with dependent bases.");
731
732 const CXXRecordDecl *BaseDecl =
Ted Kremenekcca17802012-09-12 06:50:29 +0000733 cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
Anders Carlsson46170f92010-11-24 22:50:27 +0000734
735 // Only bases with virtual bases participate in computing the
736 // indirect primary virtual base classes.
737 if (BaseDecl->getNumVBases())
738 AddIndirectPrimaryBases(BaseDecl, Context, Bases);
739 }
740}