blob: 801ed7442de28b5dfef6e78b3aae545cf50b99e9 [file] [log] [blame]
Douglas Gregor94b1dd22008-10-24 04:54:22 +00001//===------ SemaInherit.h - 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 Sema data structures that help analyse C++
11// inheritance semantics, including searching the inheritance
12// hierarchy.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CLANG_SEMA_INHERIT_H
17#define LLVM_CLANG_SEMA_INHERIT_H
18
19#include "clang/AST/Type.h"
20#include "clang/AST/TypeOrdering.h"
21#include "llvm/ADT/SmallVector.h"
22#include <list>
23#include <map>
24
25namespace clang {
26 class Sema;
27 class CXXBaseSpecifier;
28
29 /// BasePathElement - An element in a path from a derived class to a
30 /// base class. Each step in the path references the link from a
31 /// derived class to one of its direct base classes, along with a
32 /// base "number" that identifies which base subobject of the
33 /// original derived class we are referencing.
34 struct BasePathElement {
35 /// Base - The base specifier that states the link from a derived
36 /// class to a base class, which will be followed by this base
37 /// path element.
38 const CXXBaseSpecifier *Base;
39
40 /// SubobjectNumber - Identifies which base class subobject (of type
41 /// @c Base->getType()) this base path element refers to. This
42 /// value is only valid if @c !Base->isVirtual(), because there
43 /// is no base numbering for the zero or one virtual bases of a
44 /// given type.
45 int SubobjectNumber;
46 };
47
48 /// BasePath - Represents a path from a specific derived class
49 /// (which is not represented as part of the path) to a particular
50 /// (direct or indirect) base class subobject. Individual elements
51 /// in the path are described by the BasePathElement structure,
52 /// which captures both the link from a derived class to one of its
53 /// direct bases and identification describing which base class
54 /// subobject is being used.
55 typedef llvm::SmallVector<BasePathElement, 4> BasePath;
56
57 /// BasePaths - Represents the set of paths from a derived class to
58 /// one of its (direct or indirect) bases. For example, given the
59 /// following class hierachy:
60 ///
61 /// @code
62 /// class A { };
63 /// class B : public A { };
64 /// class C : public A { };
65 /// class D : public B, public C{ };
66 /// @endcode
67 ///
68 /// There are two potential BasePaths to represent paths from D to a
69 /// base subobject of type A. One path is (D,0) -> (B,0) -> (A,0)
70 /// and another is (D,0)->(C,0)->(A,1). These two paths actually
71 /// refer to two different base class subobjects of the same type,
72 /// so the BasePaths object refers to an ambiguous path. On the
73 /// other hand, consider the following class hierarchy:
74 ///
75 /// @code
76 /// class A { };
77 /// class B : public virtual A { };
78 /// class C : public virtual A { };
79 /// class D : public B, public C{ };
80 /// @endcode
81 ///
82 /// Here, there are two potential BasePaths again, (D, 0) -> (B, 0)
83 /// -> (A,v) and (D, 0) -> (C, 0) -> (A, v), but since both of them
84 /// refer to the same base class subobject of type A (the virtual
85 /// one), there is no ambiguity.
86 class BasePaths {
87 /// Paths - The actual set of paths that can be taken from the
88 /// derived class to the same base class.
89 std::list<BasePath> Paths;
90
91 /// ClassSubobjects - Records the class subobjects for each class
92 /// type that we've seen. The first element in the pair says
93 /// whether we found a path to a virtual base for that class type,
94 /// while the element contains the number of non-virtual base
95 /// class subobjects for that class type. The key of the map is
96 /// the cv-unqualified canonical type of the base class subobject.
97 std::map<QualType, std::pair<bool, unsigned>, QualTypeOrdering>
98 ClassSubobjects;
99
100 /// FindAmbiguities - Whether Sema::IsDirectedFrom should try find
101 /// ambiguous paths while it is looking for a path from a derived
102 /// type to a base type.
103 bool FindAmbiguities;
104
105 /// RecordPaths - Whether Sema::IsDirectedFrom should record paths
106 /// while it is determining whether there are paths from a derived
107 /// type to a base type.
108 bool RecordPaths;
109
110 /// ScratchPath - A BasePath that is used by Sema::IsDerivedFrom
111 /// to help build the set of paths.
112 BasePath ScratchPath;
113
114 friend class Sema;
115
116 public:
117 typedef std::list<BasePath>::const_iterator paths_iterator;
118
119 /// BasePaths - Construct a new BasePaths structure to record the
120 /// paths for a derived-to-base search.
121 explicit BasePaths(bool FindAmbiguities = true, bool RecordPaths = true)
122 : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths) { }
123
124 paths_iterator begin() const { return Paths.begin(); }
125 paths_iterator end() const { return Paths.end(); }
126
127 bool isAmbiguous(QualType BaseType);
128
129 /// isFindingAmbiguities - Whether we are finding multiple paths
130 /// to detect ambiguities.
131 bool isFindingAmbiguities() const { return FindAmbiguities; }
132
133 /// isRecordingPaths - Whether we are recording paths.
134 bool isRecordingPaths() const { return RecordPaths; }
135
136 /// setRecordingPaths - Specify whether we should be recording
137 /// paths or not.
138 void setRecordingPaths(bool RP) { RecordPaths = RP; }
139
140 void clear();
141 };
142}
143
144#endif