File: | clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp |
Warning: | line 210, column 28 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- DataflowEnvironment.cpp ---------------------------------*- C++ -*-===// | ||||||
2 | // | ||||||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||
4 | // See https://llvm.org/LICENSE.txt for license information. | ||||||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||
6 | // | ||||||
7 | //===----------------------------------------------------------------------===// | ||||||
8 | // | ||||||
9 | // This file defines an Environment class that is used by dataflow analyses | ||||||
10 | // that run over Control-Flow Graphs (CFGs) to keep track of the state of the | ||||||
11 | // program at given program points. | ||||||
12 | // | ||||||
13 | //===----------------------------------------------------------------------===// | ||||||
14 | |||||||
15 | #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" | ||||||
16 | #include "clang/AST/Decl.h" | ||||||
17 | #include "clang/AST/DeclCXX.h" | ||||||
18 | #include "clang/AST/Type.h" | ||||||
19 | #include "clang/Analysis/FlowSensitive/DataflowLattice.h" | ||||||
20 | #include "clang/Analysis/FlowSensitive/StorageLocation.h" | ||||||
21 | #include "clang/Analysis/FlowSensitive/Value.h" | ||||||
22 | #include "llvm/ADT/DenseMap.h" | ||||||
23 | #include "llvm/ADT/DenseSet.h" | ||||||
24 | #include "llvm/Support/ErrorHandling.h" | ||||||
25 | #include <memory> | ||||||
26 | #include <utility> | ||||||
27 | |||||||
28 | namespace clang { | ||||||
29 | namespace dataflow { | ||||||
30 | |||||||
31 | /// Returns a map consisting of key-value entries that are present in both maps. | ||||||
32 | template <typename K, typename V> | ||||||
33 | llvm::DenseMap<K, V> intersectDenseMaps(const llvm::DenseMap<K, V> &Map1, | ||||||
34 | const llvm::DenseMap<K, V> &Map2) { | ||||||
35 | llvm::DenseMap<K, V> Result; | ||||||
36 | for (auto &Entry : Map1) { | ||||||
37 | auto It = Map2.find(Entry.first); | ||||||
38 | if (It != Map2.end() && Entry.second == It->second) | ||||||
39 | Result.insert({Entry.first, Entry.second}); | ||||||
40 | } | ||||||
41 | return Result; | ||||||
42 | } | ||||||
43 | |||||||
44 | Environment::Environment(DataflowAnalysisContext &DACtx, | ||||||
45 | const DeclContext &DeclCtx) | ||||||
46 | : Environment(DACtx) { | ||||||
47 | if (const auto *FuncDecl
| ||||||
| |||||||
48 | for (const auto *ParamDecl : FuncDecl->parameters()) { | ||||||
49 | assert(ParamDecl != nullptr)(static_cast <bool> (ParamDecl != nullptr) ? void (0) : __assert_fail ("ParamDecl != nullptr", "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp" , 49, __extension__ __PRETTY_FUNCTION__)); | ||||||
50 | auto &ParamLoc = createStorageLocation(*ParamDecl); | ||||||
51 | setStorageLocation(*ParamDecl, ParamLoc); | ||||||
52 | initValueInStorageLocation(ParamLoc, ParamDecl->getType()); | ||||||
53 | } | ||||||
54 | } | ||||||
55 | |||||||
56 | if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(&DeclCtx)) { | ||||||
57 | if (!MethodDecl->isStatic()) { | ||||||
58 | QualType ThisPointeeType = MethodDecl->getThisObjectType(); | ||||||
59 | // FIXME: Add support for union types. | ||||||
60 | if (!ThisPointeeType->isUnionType()) { | ||||||
61 | auto &ThisPointeeLoc = createStorageLocation(ThisPointeeType); | ||||||
62 | DACtx.setThisPointeeStorageLocation(ThisPointeeLoc); | ||||||
63 | initValueInStorageLocation(ThisPointeeLoc, ThisPointeeType); | ||||||
64 | } | ||||||
65 | } | ||||||
66 | } | ||||||
67 | } | ||||||
68 | |||||||
69 | bool Environment::operator==(const Environment &Other) const { | ||||||
70 | assert(DACtx == Other.DACtx)(static_cast <bool> (DACtx == Other.DACtx) ? void (0) : __assert_fail ("DACtx == Other.DACtx", "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp" , 70, __extension__ __PRETTY_FUNCTION__)); | ||||||
71 | return DeclToLoc == Other.DeclToLoc && LocToVal == Other.LocToVal; | ||||||
72 | } | ||||||
73 | |||||||
74 | LatticeJoinEffect Environment::join(const Environment &Other) { | ||||||
75 | assert(DACtx == Other.DACtx)(static_cast <bool> (DACtx == Other.DACtx) ? void (0) : __assert_fail ("DACtx == Other.DACtx", "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp" , 75, __extension__ __PRETTY_FUNCTION__)); | ||||||
76 | |||||||
77 | auto Effect = LatticeJoinEffect::Unchanged; | ||||||
78 | |||||||
79 | const unsigned DeclToLocSizeBefore = DeclToLoc.size(); | ||||||
80 | DeclToLoc = intersectDenseMaps(DeclToLoc, Other.DeclToLoc); | ||||||
81 | if (DeclToLocSizeBefore != DeclToLoc.size()) | ||||||
82 | Effect = LatticeJoinEffect::Changed; | ||||||
83 | |||||||
84 | // FIXME: Add support for joining distinct values that are assigned to the | ||||||
85 | // same storage locations in `LocToVal` and `Other.LocToVal`. | ||||||
86 | const unsigned LocToValSizeBefore = LocToVal.size(); | ||||||
87 | LocToVal = intersectDenseMaps(LocToVal, Other.LocToVal); | ||||||
88 | if (LocToValSizeBefore != LocToVal.size()) | ||||||
89 | Effect = LatticeJoinEffect::Changed; | ||||||
90 | |||||||
91 | return Effect; | ||||||
92 | } | ||||||
93 | |||||||
94 | StorageLocation &Environment::createStorageLocation(QualType Type) { | ||||||
95 | assert(!Type.isNull())(static_cast <bool> (!Type.isNull()) ? void (0) : __assert_fail ("!Type.isNull()", "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp" , 95, __extension__ __PRETTY_FUNCTION__)); | ||||||
96 | if (Type->isStructureOrClassType()) { | ||||||
97 | // FIXME: Explore options to avoid eager initialization of fields as some of | ||||||
98 | // them might not be needed for a particular analysis. | ||||||
99 | llvm::DenseMap<const ValueDecl *, StorageLocation *> FieldLocs; | ||||||
100 | for (const FieldDecl *Field : Type->getAsRecordDecl()->fields()) { | ||||||
101 | FieldLocs.insert({Field, &createStorageLocation(Field->getType())}); | ||||||
102 | } | ||||||
103 | return takeOwnership( | ||||||
104 | std::make_unique<AggregateStorageLocation>(Type, std::move(FieldLocs))); | ||||||
105 | } | ||||||
106 | return takeOwnership(std::make_unique<ScalarStorageLocation>(Type)); | ||||||
107 | } | ||||||
108 | |||||||
109 | StorageLocation &Environment::createStorageLocation(const VarDecl &D) { | ||||||
110 | // Evaluated declarations are always assigned the same storage locations to | ||||||
111 | // ensure that the environment stabilizes across loop iterations. Storage | ||||||
112 | // locations for evaluated declarations are stored in the analysis context. | ||||||
113 | if (auto *Loc = DACtx->getStorageLocation(D)) | ||||||
114 | return *Loc; | ||||||
115 | auto &Loc = createStorageLocation(D.getType()); | ||||||
116 | DACtx->setStorageLocation(D, Loc); | ||||||
117 | return Loc; | ||||||
118 | } | ||||||
119 | |||||||
120 | StorageLocation &Environment::createStorageLocation(const Expr &E) { | ||||||
121 | // Evaluated expressions are always assigned the same storage locations to | ||||||
122 | // ensure that the environment stabilizes across loop iterations. Storage | ||||||
123 | // locations for evaluated expressions are stored in the analysis context. | ||||||
124 | if (auto *Loc = DACtx->getStorageLocation(E)) | ||||||
125 | return *Loc; | ||||||
126 | auto &Loc = createStorageLocation(E.getType()); | ||||||
127 | DACtx->setStorageLocation(E, Loc); | ||||||
128 | return Loc; | ||||||
129 | } | ||||||
130 | |||||||
131 | void Environment::setStorageLocation(const ValueDecl &D, StorageLocation &Loc) { | ||||||
132 | assert(DeclToLoc.find(&D) == DeclToLoc.end())(static_cast <bool> (DeclToLoc.find(&D) == DeclToLoc .end()) ? void (0) : __assert_fail ("DeclToLoc.find(&D) == DeclToLoc.end()" , "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp", 132, __extension__ __PRETTY_FUNCTION__)); | ||||||
133 | DeclToLoc[&D] = &Loc; | ||||||
134 | } | ||||||
135 | |||||||
136 | StorageLocation *Environment::getStorageLocation(const ValueDecl &D, | ||||||
137 | SkipPast SP) const { | ||||||
138 | auto It = DeclToLoc.find(&D); | ||||||
139 | return It == DeclToLoc.end() ? nullptr : &skip(*It->second, SP); | ||||||
140 | } | ||||||
141 | |||||||
142 | void Environment::setStorageLocation(const Expr &E, StorageLocation &Loc) { | ||||||
143 | assert(ExprToLoc.find(&E) == ExprToLoc.end())(static_cast <bool> (ExprToLoc.find(&E) == ExprToLoc .end()) ? void (0) : __assert_fail ("ExprToLoc.find(&E) == ExprToLoc.end()" , "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp", 143, __extension__ __PRETTY_FUNCTION__)); | ||||||
144 | ExprToLoc[&E] = &Loc; | ||||||
145 | } | ||||||
146 | |||||||
147 | StorageLocation *Environment::getStorageLocation(const Expr &E, | ||||||
148 | SkipPast SP) const { | ||||||
149 | auto It = ExprToLoc.find(&E); | ||||||
150 | return It == ExprToLoc.end() ? nullptr : &skip(*It->second, SP); | ||||||
151 | } | ||||||
152 | |||||||
153 | StorageLocation *Environment::getThisPointeeStorageLocation() const { | ||||||
154 | return DACtx->getThisPointeeStorageLocation(); | ||||||
155 | } | ||||||
156 | |||||||
157 | void Environment::setValue(const StorageLocation &Loc, Value &Val) { | ||||||
158 | LocToVal[&Loc] = &Val; | ||||||
159 | |||||||
160 | if (auto *StructVal = dyn_cast<StructValue>(&Val)) { | ||||||
161 | auto &AggregateLoc = *cast<AggregateStorageLocation>(&Loc); | ||||||
162 | |||||||
163 | const QualType Type = AggregateLoc.getType(); | ||||||
164 | assert(Type->isStructureOrClassType())(static_cast <bool> (Type->isStructureOrClassType()) ? void (0) : __assert_fail ("Type->isStructureOrClassType()" , "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp", 164, __extension__ __PRETTY_FUNCTION__)); | ||||||
165 | |||||||
166 | for (const FieldDecl *Field : Type->getAsRecordDecl()->fields()) { | ||||||
167 | assert(Field != nullptr)(static_cast <bool> (Field != nullptr) ? void (0) : __assert_fail ("Field != nullptr", "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp" , 167, __extension__ __PRETTY_FUNCTION__)); | ||||||
168 | setValue(AggregateLoc.getChild(*Field), StructVal->getChild(*Field)); | ||||||
169 | } | ||||||
170 | } | ||||||
171 | } | ||||||
172 | |||||||
173 | Value *Environment::getValue(const StorageLocation &Loc) const { | ||||||
174 | auto It = LocToVal.find(&Loc); | ||||||
175 | return It == LocToVal.end() ? nullptr : It->second; | ||||||
176 | } | ||||||
177 | |||||||
178 | Value *Environment::getValue(const ValueDecl &D, SkipPast SP) const { | ||||||
179 | auto *Loc = getStorageLocation(D, SP); | ||||||
180 | if (Loc == nullptr) | ||||||
181 | return nullptr; | ||||||
182 | return getValue(*Loc); | ||||||
183 | } | ||||||
184 | |||||||
185 | Value *Environment::getValue(const Expr &E, SkipPast SP) const { | ||||||
186 | auto *Loc = getStorageLocation(E, SP); | ||||||
187 | if (Loc == nullptr) | ||||||
188 | return nullptr; | ||||||
189 | return getValue(*Loc); | ||||||
190 | } | ||||||
191 | |||||||
192 | Value *Environment::initValueInStorageLocation(const StorageLocation &Loc, | ||||||
193 | QualType Type) { | ||||||
194 | llvm::DenseSet<QualType> Visited; | ||||||
195 | return initValueInStorageLocationUnlessSelfReferential(Loc, Type, Visited); | ||||||
196 | } | ||||||
197 | |||||||
198 | Value *Environment::initValueInStorageLocationUnlessSelfReferential( | ||||||
199 | const StorageLocation &Loc, QualType Type, | ||||||
200 | llvm::DenseSet<QualType> &Visited) { | ||||||
201 | assert(!Type.isNull())(static_cast <bool> (!Type.isNull()) ? void (0) : __assert_fail ("!Type.isNull()", "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp" , 201, __extension__ __PRETTY_FUNCTION__)); | ||||||
202 | |||||||
203 | if (Type->isIntegerType()) { | ||||||
204 | auto &Val = takeOwnership(std::make_unique<IntegerValue>()); | ||||||
205 | setValue(Loc, Val); | ||||||
206 | return &Val; | ||||||
207 | } | ||||||
208 | |||||||
209 | if (Type->isReferenceType()) { | ||||||
210 | QualType PointeeType = Type->getAs<ReferenceType>()->getPointeeType(); | ||||||
| |||||||
211 | auto &PointeeLoc = createStorageLocation(PointeeType); | ||||||
212 | |||||||
213 | if (!Visited.contains(PointeeType.getCanonicalType())) { | ||||||
214 | Visited.insert(PointeeType.getCanonicalType()); | ||||||
215 | initValueInStorageLocationUnlessSelfReferential(PointeeLoc, PointeeType, | ||||||
216 | Visited); | ||||||
217 | Visited.erase(PointeeType.getCanonicalType()); | ||||||
218 | } | ||||||
219 | |||||||
220 | auto &Val = takeOwnership(std::make_unique<ReferenceValue>(PointeeLoc)); | ||||||
221 | setValue(Loc, Val); | ||||||
222 | return &Val; | ||||||
223 | } | ||||||
224 | |||||||
225 | if (Type->isPointerType()) { | ||||||
226 | QualType PointeeType = Type->getAs<PointerType>()->getPointeeType(); | ||||||
227 | auto &PointeeLoc = createStorageLocation(PointeeType); | ||||||
228 | |||||||
229 | if (!Visited.contains(PointeeType.getCanonicalType())) { | ||||||
230 | Visited.insert(PointeeType.getCanonicalType()); | ||||||
231 | initValueInStorageLocationUnlessSelfReferential(PointeeLoc, PointeeType, | ||||||
232 | Visited); | ||||||
233 | Visited.erase(PointeeType.getCanonicalType()); | ||||||
234 | } | ||||||
235 | |||||||
236 | auto &Val = takeOwnership(std::make_unique<PointerValue>(PointeeLoc)); | ||||||
237 | setValue(Loc, Val); | ||||||
238 | return &Val; | ||||||
239 | } | ||||||
240 | |||||||
241 | if (Type->isStructureOrClassType()) { | ||||||
242 | auto *AggregateLoc = cast<AggregateStorageLocation>(&Loc); | ||||||
243 | |||||||
244 | // FIXME: Initialize only fields that are accessed in the context that is | ||||||
245 | // being analyzed. | ||||||
246 | llvm::DenseMap<const ValueDecl *, Value *> FieldValues; | ||||||
247 | for (const FieldDecl *Field : Type->getAsRecordDecl()->fields()) { | ||||||
248 | assert(Field != nullptr)(static_cast <bool> (Field != nullptr) ? void (0) : __assert_fail ("Field != nullptr", "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp" , 248, __extension__ __PRETTY_FUNCTION__)); | ||||||
249 | |||||||
250 | QualType FieldType = Field->getType(); | ||||||
251 | if (Visited.contains(FieldType.getCanonicalType())) | ||||||
252 | continue; | ||||||
253 | |||||||
254 | Visited.insert(FieldType.getCanonicalType()); | ||||||
255 | FieldValues.insert( | ||||||
256 | {Field, initValueInStorageLocationUnlessSelfReferential( | ||||||
257 | AggregateLoc->getChild(*Field), FieldType, Visited)}); | ||||||
258 | Visited.erase(FieldType.getCanonicalType()); | ||||||
259 | } | ||||||
260 | |||||||
261 | auto &Val = | ||||||
262 | takeOwnership(std::make_unique<StructValue>(std::move(FieldValues))); | ||||||
263 | setValue(Loc, Val); | ||||||
264 | return &Val; | ||||||
265 | } | ||||||
266 | |||||||
267 | return nullptr; | ||||||
268 | } | ||||||
269 | |||||||
270 | StorageLocation & | ||||||
271 | Environment::takeOwnership(std::unique_ptr<StorageLocation> Loc) { | ||||||
272 | return DACtx->takeOwnership(std::move(Loc)); | ||||||
273 | } | ||||||
274 | |||||||
275 | Value &Environment::takeOwnership(std::unique_ptr<Value> Val) { | ||||||
276 | return DACtx->takeOwnership(std::move(Val)); | ||||||
277 | } | ||||||
278 | |||||||
279 | StorageLocation &Environment::skip(StorageLocation &Loc, SkipPast SP) const { | ||||||
280 | switch (SP) { | ||||||
281 | case SkipPast::None: | ||||||
282 | return Loc; | ||||||
283 | case SkipPast::Reference: | ||||||
284 | // References cannot be chained so we only need to skip past one level of | ||||||
285 | // indirection. | ||||||
286 | if (auto *Val = dyn_cast_or_null<ReferenceValue>(getValue(Loc))) | ||||||
287 | return Val->getPointeeLoc(); | ||||||
288 | return Loc; | ||||||
289 | case SkipPast::ReferenceThenPointer: | ||||||
290 | StorageLocation &LocPastRef = skip(Loc, SkipPast::Reference); | ||||||
291 | if (auto *Val = dyn_cast_or_null<PointerValue>(getValue(LocPastRef))) | ||||||
292 | return Val->getPointeeLoc(); | ||||||
293 | return LocPastRef; | ||||||
294 | } | ||||||
295 | llvm_unreachable("bad SkipPast kind")::llvm::llvm_unreachable_internal("bad SkipPast kind", "clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp" , 295); | ||||||
296 | } | ||||||
297 | |||||||
298 | const StorageLocation &Environment::skip(const StorageLocation &Loc, | ||||||
299 | SkipPast SP) const { | ||||||
300 | return skip(*const_cast<StorageLocation *>(&Loc), SP); | ||||||
301 | } | ||||||
302 | |||||||
303 | } // namespace dataflow | ||||||
304 | } // namespace clang |
1 | //===- Type.h - C Language Family Type Representation -----------*- C++ -*-===// | ||||||
2 | // | ||||||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||
4 | // See https://llvm.org/LICENSE.txt for license information. | ||||||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||
6 | // | ||||||
7 | //===----------------------------------------------------------------------===// | ||||||
8 | // | ||||||
9 | /// \file | ||||||
10 | /// C Language Family Type Representation | ||||||
11 | /// | ||||||
12 | /// This file defines the clang::Type interface and subclasses, used to | ||||||
13 | /// represent types for languages in the C family. | ||||||
14 | // | ||||||
15 | //===----------------------------------------------------------------------===// | ||||||
16 | |||||||
17 | #ifndef LLVM_CLANG_AST_TYPE_H | ||||||
18 | #define LLVM_CLANG_AST_TYPE_H | ||||||
19 | |||||||
20 | #include "clang/AST/DependenceFlags.h" | ||||||
21 | #include "clang/AST/NestedNameSpecifier.h" | ||||||
22 | #include "clang/AST/TemplateName.h" | ||||||
23 | #include "clang/Basic/AddressSpaces.h" | ||||||
24 | #include "clang/Basic/AttrKinds.h" | ||||||
25 | #include "clang/Basic/Diagnostic.h" | ||||||
26 | #include "clang/Basic/ExceptionSpecificationType.h" | ||||||
27 | #include "clang/Basic/LLVM.h" | ||||||
28 | #include "clang/Basic/Linkage.h" | ||||||
29 | #include "clang/Basic/PartialDiagnostic.h" | ||||||
30 | #include "clang/Basic/SourceLocation.h" | ||||||
31 | #include "clang/Basic/Specifiers.h" | ||||||
32 | #include "clang/Basic/Visibility.h" | ||||||
33 | #include "llvm/ADT/APInt.h" | ||||||
34 | #include "llvm/ADT/APSInt.h" | ||||||
35 | #include "llvm/ADT/ArrayRef.h" | ||||||
36 | #include "llvm/ADT/FoldingSet.h" | ||||||
37 | #include "llvm/ADT/None.h" | ||||||
38 | #include "llvm/ADT/Optional.h" | ||||||
39 | #include "llvm/ADT/PointerIntPair.h" | ||||||
40 | #include "llvm/ADT/PointerUnion.h" | ||||||
41 | #include "llvm/ADT/StringRef.h" | ||||||
42 | #include "llvm/ADT/Twine.h" | ||||||
43 | #include "llvm/ADT/iterator_range.h" | ||||||
44 | #include "llvm/Support/Casting.h" | ||||||
45 | #include "llvm/Support/Compiler.h" | ||||||
46 | #include "llvm/Support/ErrorHandling.h" | ||||||
47 | #include "llvm/Support/PointerLikeTypeTraits.h" | ||||||
48 | #include "llvm/Support/TrailingObjects.h" | ||||||
49 | #include "llvm/Support/type_traits.h" | ||||||
50 | #include <cassert> | ||||||
51 | #include <cstddef> | ||||||
52 | #include <cstdint> | ||||||
53 | #include <cstring> | ||||||
54 | #include <string> | ||||||
55 | #include <type_traits> | ||||||
56 | #include <utility> | ||||||
57 | |||||||
58 | namespace clang { | ||||||
59 | |||||||
60 | class ExtQuals; | ||||||
61 | class QualType; | ||||||
62 | class ConceptDecl; | ||||||
63 | class TagDecl; | ||||||
64 | class TemplateParameterList; | ||||||
65 | class Type; | ||||||
66 | |||||||
67 | enum { | ||||||
68 | TypeAlignmentInBits = 4, | ||||||
69 | TypeAlignment = 1 << TypeAlignmentInBits | ||||||
70 | }; | ||||||
71 | |||||||
72 | namespace serialization { | ||||||
73 | template <class T> class AbstractTypeReader; | ||||||
74 | template <class T> class AbstractTypeWriter; | ||||||
75 | } | ||||||
76 | |||||||
77 | } // namespace clang | ||||||
78 | |||||||
79 | namespace llvm { | ||||||
80 | |||||||
81 | template <typename T> | ||||||
82 | struct PointerLikeTypeTraits; | ||||||
83 | template<> | ||||||
84 | struct PointerLikeTypeTraits< ::clang::Type*> { | ||||||
85 | static inline void *getAsVoidPointer(::clang::Type *P) { return P; } | ||||||
86 | |||||||
87 | static inline ::clang::Type *getFromVoidPointer(void *P) { | ||||||
88 | return static_cast< ::clang::Type*>(P); | ||||||
89 | } | ||||||
90 | |||||||
91 | static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; | ||||||
92 | }; | ||||||
93 | |||||||
94 | template<> | ||||||
95 | struct PointerLikeTypeTraits< ::clang::ExtQuals*> { | ||||||
96 | static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; } | ||||||
97 | |||||||
98 | static inline ::clang::ExtQuals *getFromVoidPointer(void *P) { | ||||||
99 | return static_cast< ::clang::ExtQuals*>(P); | ||||||
100 | } | ||||||
101 | |||||||
102 | static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; | ||||||
103 | }; | ||||||
104 | |||||||
105 | } // namespace llvm | ||||||
106 | |||||||
107 | namespace clang { | ||||||
108 | |||||||
109 | class ASTContext; | ||||||
110 | template <typename> class CanQual; | ||||||
111 | class CXXRecordDecl; | ||||||
112 | class DeclContext; | ||||||
113 | class EnumDecl; | ||||||
114 | class Expr; | ||||||
115 | class ExtQualsTypeCommonBase; | ||||||
116 | class FunctionDecl; | ||||||
117 | class IdentifierInfo; | ||||||
118 | class NamedDecl; | ||||||
119 | class ObjCInterfaceDecl; | ||||||
120 | class ObjCProtocolDecl; | ||||||
121 | class ObjCTypeParamDecl; | ||||||
122 | struct PrintingPolicy; | ||||||
123 | class RecordDecl; | ||||||
124 | class Stmt; | ||||||
125 | class TagDecl; | ||||||
126 | class TemplateArgument; | ||||||
127 | class TemplateArgumentListInfo; | ||||||
128 | class TemplateArgumentLoc; | ||||||
129 | class TemplateTypeParmDecl; | ||||||
130 | class TypedefNameDecl; | ||||||
131 | class UnresolvedUsingTypenameDecl; | ||||||
132 | class UsingShadowDecl; | ||||||
133 | |||||||
134 | using CanQualType = CanQual<Type>; | ||||||
135 | |||||||
136 | // Provide forward declarations for all of the *Type classes. | ||||||
137 | #define TYPE(Class, Base) class Class##Type; | ||||||
138 | #include "clang/AST/TypeNodes.inc" | ||||||
139 | |||||||
140 | /// The collection of all-type qualifiers we support. | ||||||
141 | /// Clang supports five independent qualifiers: | ||||||
142 | /// * C99: const, volatile, and restrict | ||||||
143 | /// * MS: __unaligned | ||||||
144 | /// * Embedded C (TR18037): address spaces | ||||||
145 | /// * Objective C: the GC attributes (none, weak, or strong) | ||||||
146 | class Qualifiers { | ||||||
147 | public: | ||||||
148 | enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ. | ||||||
149 | Const = 0x1, | ||||||
150 | Restrict = 0x2, | ||||||
151 | Volatile = 0x4, | ||||||
152 | CVRMask = Const | Volatile | Restrict | ||||||
153 | }; | ||||||
154 | |||||||
155 | enum GC { | ||||||
156 | GCNone = 0, | ||||||
157 | Weak, | ||||||
158 | Strong | ||||||
159 | }; | ||||||
160 | |||||||
161 | enum ObjCLifetime { | ||||||
162 | /// There is no lifetime qualification on this type. | ||||||
163 | OCL_None, | ||||||
164 | |||||||
165 | /// This object can be modified without requiring retains or | ||||||
166 | /// releases. | ||||||
167 | OCL_ExplicitNone, | ||||||
168 | |||||||
169 | /// Assigning into this object requires the old value to be | ||||||
170 | /// released and the new value to be retained. The timing of the | ||||||
171 | /// release of the old value is inexact: it may be moved to | ||||||
172 | /// immediately after the last known point where the value is | ||||||
173 | /// live. | ||||||
174 | OCL_Strong, | ||||||
175 | |||||||
176 | /// Reading or writing from this object requires a barrier call. | ||||||
177 | OCL_Weak, | ||||||
178 | |||||||
179 | /// Assigning into this object requires a lifetime extension. | ||||||
180 | OCL_Autoreleasing | ||||||
181 | }; | ||||||
182 | |||||||
183 | enum { | ||||||
184 | /// The maximum supported address space number. | ||||||
185 | /// 23 bits should be enough for anyone. | ||||||
186 | MaxAddressSpace = 0x7fffffu, | ||||||
187 | |||||||
188 | /// The width of the "fast" qualifier mask. | ||||||
189 | FastWidth = 3, | ||||||
190 | |||||||
191 | /// The fast qualifier mask. | ||||||
192 | FastMask = (1 << FastWidth) - 1 | ||||||
193 | }; | ||||||
194 | |||||||
195 | /// Returns the common set of qualifiers while removing them from | ||||||
196 | /// the given sets. | ||||||
197 | static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { | ||||||
198 | // If both are only CVR-qualified, bit operations are sufficient. | ||||||
199 | if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { | ||||||
200 | Qualifiers Q; | ||||||
201 | Q.Mask = L.Mask & R.Mask; | ||||||
202 | L.Mask &= ~Q.Mask; | ||||||
203 | R.Mask &= ~Q.Mask; | ||||||
204 | return Q; | ||||||
205 | } | ||||||
206 | |||||||
207 | Qualifiers Q; | ||||||
208 | unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); | ||||||
209 | Q.addCVRQualifiers(CommonCRV); | ||||||
210 | L.removeCVRQualifiers(CommonCRV); | ||||||
211 | R.removeCVRQualifiers(CommonCRV); | ||||||
212 | |||||||
213 | if (L.getObjCGCAttr() == R.getObjCGCAttr()) { | ||||||
214 | Q.setObjCGCAttr(L.getObjCGCAttr()); | ||||||
215 | L.removeObjCGCAttr(); | ||||||
216 | R.removeObjCGCAttr(); | ||||||
217 | } | ||||||
218 | |||||||
219 | if (L.getObjCLifetime() == R.getObjCLifetime()) { | ||||||
220 | Q.setObjCLifetime(L.getObjCLifetime()); | ||||||
221 | L.removeObjCLifetime(); | ||||||
222 | R.removeObjCLifetime(); | ||||||
223 | } | ||||||
224 | |||||||
225 | if (L.getAddressSpace() == R.getAddressSpace()) { | ||||||
226 | Q.setAddressSpace(L.getAddressSpace()); | ||||||
227 | L.removeAddressSpace(); | ||||||
228 | R.removeAddressSpace(); | ||||||
229 | } | ||||||
230 | return Q; | ||||||
231 | } | ||||||
232 | |||||||
233 | static Qualifiers fromFastMask(unsigned Mask) { | ||||||
234 | Qualifiers Qs; | ||||||
235 | Qs.addFastQualifiers(Mask); | ||||||
236 | return Qs; | ||||||
237 | } | ||||||
238 | |||||||
239 | static Qualifiers fromCVRMask(unsigned CVR) { | ||||||
240 | Qualifiers Qs; | ||||||
241 | Qs.addCVRQualifiers(CVR); | ||||||
242 | return Qs; | ||||||
243 | } | ||||||
244 | |||||||
245 | static Qualifiers fromCVRUMask(unsigned CVRU) { | ||||||
246 | Qualifiers Qs; | ||||||
247 | Qs.addCVRUQualifiers(CVRU); | ||||||
248 | return Qs; | ||||||
249 | } | ||||||
250 | |||||||
251 | // Deserialize qualifiers from an opaque representation. | ||||||
252 | static Qualifiers fromOpaqueValue(unsigned opaque) { | ||||||
253 | Qualifiers Qs; | ||||||
254 | Qs.Mask = opaque; | ||||||
255 | return Qs; | ||||||
256 | } | ||||||
257 | |||||||
258 | // Serialize these qualifiers into an opaque representation. | ||||||
259 | unsigned getAsOpaqueValue() const { | ||||||
260 | return Mask; | ||||||
261 | } | ||||||
262 | |||||||
263 | bool hasConst() const { return Mask & Const; } | ||||||
264 | bool hasOnlyConst() const { return Mask == Const; } | ||||||
265 | void removeConst() { Mask &= ~Const; } | ||||||
266 | void addConst() { Mask |= Const; } | ||||||
267 | |||||||
268 | bool hasVolatile() const { return Mask & Volatile; } | ||||||
269 | bool hasOnlyVolatile() const { return Mask == Volatile; } | ||||||
270 | void removeVolatile() { Mask &= ~Volatile; } | ||||||
271 | void addVolatile() { Mask |= Volatile; } | ||||||
272 | |||||||
273 | bool hasRestrict() const { return Mask & Restrict; } | ||||||
274 | bool hasOnlyRestrict() const { return Mask == Restrict; } | ||||||
275 | void removeRestrict() { Mask &= ~Restrict; } | ||||||
276 | void addRestrict() { Mask |= Restrict; } | ||||||
277 | |||||||
278 | bool hasCVRQualifiers() const { return getCVRQualifiers(); } | ||||||
279 | unsigned getCVRQualifiers() const { return Mask & CVRMask; } | ||||||
280 | unsigned getCVRUQualifiers() const { return Mask & (CVRMask | UMask); } | ||||||
281 | |||||||
282 | void setCVRQualifiers(unsigned mask) { | ||||||
283 | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits")(static_cast <bool> (!(mask & ~CVRMask) && "bitmask contains non-CVR bits" ) ? void (0) : __assert_fail ("!(mask & ~CVRMask) && \"bitmask contains non-CVR bits\"" , "clang/include/clang/AST/Type.h", 283, __extension__ __PRETTY_FUNCTION__ )); | ||||||
284 | Mask = (Mask & ~CVRMask) | mask; | ||||||
285 | } | ||||||
286 | void removeCVRQualifiers(unsigned mask) { | ||||||
287 | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits")(static_cast <bool> (!(mask & ~CVRMask) && "bitmask contains non-CVR bits" ) ? void (0) : __assert_fail ("!(mask & ~CVRMask) && \"bitmask contains non-CVR bits\"" , "clang/include/clang/AST/Type.h", 287, __extension__ __PRETTY_FUNCTION__ )); | ||||||
288 | Mask &= ~mask; | ||||||
289 | } | ||||||
290 | void removeCVRQualifiers() { | ||||||
291 | removeCVRQualifiers(CVRMask); | ||||||
292 | } | ||||||
293 | void addCVRQualifiers(unsigned mask) { | ||||||
294 | assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits")(static_cast <bool> (!(mask & ~CVRMask) && "bitmask contains non-CVR bits" ) ? void (0) : __assert_fail ("!(mask & ~CVRMask) && \"bitmask contains non-CVR bits\"" , "clang/include/clang/AST/Type.h", 294, __extension__ __PRETTY_FUNCTION__ )); | ||||||
295 | Mask |= mask; | ||||||
296 | } | ||||||
297 | void addCVRUQualifiers(unsigned mask) { | ||||||
298 | assert(!(mask & ~CVRMask & ~UMask) && "bitmask contains non-CVRU bits")(static_cast <bool> (!(mask & ~CVRMask & ~UMask ) && "bitmask contains non-CVRU bits") ? void (0) : __assert_fail ("!(mask & ~CVRMask & ~UMask) && \"bitmask contains non-CVRU bits\"" , "clang/include/clang/AST/Type.h", 298, __extension__ __PRETTY_FUNCTION__ )); | ||||||
299 | Mask |= mask; | ||||||
300 | } | ||||||
301 | |||||||
302 | bool hasUnaligned() const { return Mask & UMask; } | ||||||
303 | void setUnaligned(bool flag) { | ||||||
304 | Mask = (Mask & ~UMask) | (flag ? UMask : 0); | ||||||
305 | } | ||||||
306 | void removeUnaligned() { Mask &= ~UMask; } | ||||||
307 | void addUnaligned() { Mask |= UMask; } | ||||||
308 | |||||||
309 | bool hasObjCGCAttr() const { return Mask & GCAttrMask; } | ||||||
310 | GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); } | ||||||
311 | void setObjCGCAttr(GC type) { | ||||||
312 | Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift); | ||||||
313 | } | ||||||
314 | void removeObjCGCAttr() { setObjCGCAttr(GCNone); } | ||||||
315 | void addObjCGCAttr(GC type) { | ||||||
316 | assert(type)(static_cast <bool> (type) ? void (0) : __assert_fail ( "type", "clang/include/clang/AST/Type.h", 316, __extension__ __PRETTY_FUNCTION__ )); | ||||||
317 | setObjCGCAttr(type); | ||||||
318 | } | ||||||
319 | Qualifiers withoutObjCGCAttr() const { | ||||||
320 | Qualifiers qs = *this; | ||||||
321 | qs.removeObjCGCAttr(); | ||||||
322 | return qs; | ||||||
323 | } | ||||||
324 | Qualifiers withoutObjCLifetime() const { | ||||||
325 | Qualifiers qs = *this; | ||||||
326 | qs.removeObjCLifetime(); | ||||||
327 | return qs; | ||||||
328 | } | ||||||
329 | Qualifiers withoutAddressSpace() const { | ||||||
330 | Qualifiers qs = *this; | ||||||
331 | qs.removeAddressSpace(); | ||||||
332 | return qs; | ||||||
333 | } | ||||||
334 | |||||||
335 | bool hasObjCLifetime() const { return Mask & LifetimeMask; } | ||||||
336 | ObjCLifetime getObjCLifetime() const { | ||||||
337 | return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift); | ||||||
338 | } | ||||||
339 | void setObjCLifetime(ObjCLifetime type) { | ||||||
340 | Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift); | ||||||
341 | } | ||||||
342 | void removeObjCLifetime() { setObjCLifetime(OCL_None); } | ||||||
343 | void addObjCLifetime(ObjCLifetime type) { | ||||||
344 | assert(type)(static_cast <bool> (type) ? void (0) : __assert_fail ( "type", "clang/include/clang/AST/Type.h", 344, __extension__ __PRETTY_FUNCTION__ )); | ||||||
345 | assert(!hasObjCLifetime())(static_cast <bool> (!hasObjCLifetime()) ? void (0) : __assert_fail ("!hasObjCLifetime()", "clang/include/clang/AST/Type.h", 345 , __extension__ __PRETTY_FUNCTION__)); | ||||||
346 | Mask |= (type << LifetimeShift); | ||||||
347 | } | ||||||
348 | |||||||
349 | /// True if the lifetime is neither None or ExplicitNone. | ||||||
350 | bool hasNonTrivialObjCLifetime() const { | ||||||
351 | ObjCLifetime lifetime = getObjCLifetime(); | ||||||
352 | return (lifetime > OCL_ExplicitNone); | ||||||
353 | } | ||||||
354 | |||||||
355 | /// True if the lifetime is either strong or weak. | ||||||
356 | bool hasStrongOrWeakObjCLifetime() const { | ||||||
357 | ObjCLifetime lifetime = getObjCLifetime(); | ||||||
358 | return (lifetime == OCL_Strong || lifetime == OCL_Weak); | ||||||
359 | } | ||||||
360 | |||||||
361 | bool hasAddressSpace() const { return Mask & AddressSpaceMask; } | ||||||
362 | LangAS getAddressSpace() const { | ||||||
363 | return static_cast<LangAS>(Mask >> AddressSpaceShift); | ||||||
364 | } | ||||||
365 | bool hasTargetSpecificAddressSpace() const { | ||||||
366 | return isTargetAddressSpace(getAddressSpace()); | ||||||
367 | } | ||||||
368 | /// Get the address space attribute value to be printed by diagnostics. | ||||||
369 | unsigned getAddressSpaceAttributePrintValue() const { | ||||||
370 | auto Addr = getAddressSpace(); | ||||||
371 | // This function is not supposed to be used with language specific | ||||||
372 | // address spaces. If that happens, the diagnostic message should consider | ||||||
373 | // printing the QualType instead of the address space value. | ||||||
374 | assert(Addr == LangAS::Default || hasTargetSpecificAddressSpace())(static_cast <bool> (Addr == LangAS::Default || hasTargetSpecificAddressSpace ()) ? void (0) : __assert_fail ("Addr == LangAS::Default || hasTargetSpecificAddressSpace()" , "clang/include/clang/AST/Type.h", 374, __extension__ __PRETTY_FUNCTION__ )); | ||||||
375 | if (Addr != LangAS::Default) | ||||||
376 | return toTargetAddressSpace(Addr); | ||||||
377 | // TODO: The diagnostic messages where Addr may be 0 should be fixed | ||||||
378 | // since it cannot differentiate the situation where 0 denotes the default | ||||||
379 | // address space or user specified __attribute__((address_space(0))). | ||||||
380 | return 0; | ||||||
381 | } | ||||||
382 | void setAddressSpace(LangAS space) { | ||||||
383 | assert((unsigned)space <= MaxAddressSpace)(static_cast <bool> ((unsigned)space <= MaxAddressSpace ) ? void (0) : __assert_fail ("(unsigned)space <= MaxAddressSpace" , "clang/include/clang/AST/Type.h", 383, __extension__ __PRETTY_FUNCTION__ )); | ||||||
384 | Mask = (Mask & ~AddressSpaceMask) | ||||||
385 | | (((uint32_t) space) << AddressSpaceShift); | ||||||
386 | } | ||||||
387 | void removeAddressSpace() { setAddressSpace(LangAS::Default); } | ||||||
388 | void addAddressSpace(LangAS space) { | ||||||
389 | assert(space != LangAS::Default)(static_cast <bool> (space != LangAS::Default) ? void ( 0) : __assert_fail ("space != LangAS::Default", "clang/include/clang/AST/Type.h" , 389, __extension__ __PRETTY_FUNCTION__)); | ||||||
390 | setAddressSpace(space); | ||||||
391 | } | ||||||
392 | |||||||
393 | // Fast qualifiers are those that can be allocated directly | ||||||
394 | // on a QualType object. | ||||||
395 | bool hasFastQualifiers() const { return getFastQualifiers(); } | ||||||
396 | unsigned getFastQualifiers() const { return Mask & FastMask; } | ||||||
397 | void setFastQualifiers(unsigned mask) { | ||||||
398 | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits")(static_cast <bool> (!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits") ? void (0) : __assert_fail ("!(mask & ~FastMask) && \"bitmask contains non-fast qualifier bits\"" , "clang/include/clang/AST/Type.h", 398, __extension__ __PRETTY_FUNCTION__ )); | ||||||
399 | Mask = (Mask & ~FastMask) | mask; | ||||||
400 | } | ||||||
401 | void removeFastQualifiers(unsigned mask) { | ||||||
402 | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits")(static_cast <bool> (!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits") ? void (0) : __assert_fail ("!(mask & ~FastMask) && \"bitmask contains non-fast qualifier bits\"" , "clang/include/clang/AST/Type.h", 402, __extension__ __PRETTY_FUNCTION__ )); | ||||||
403 | Mask &= ~mask; | ||||||
404 | } | ||||||
405 | void removeFastQualifiers() { | ||||||
406 | removeFastQualifiers(FastMask); | ||||||
407 | } | ||||||
408 | void addFastQualifiers(unsigned mask) { | ||||||
409 | assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits")(static_cast <bool> (!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits") ? void (0) : __assert_fail ("!(mask & ~FastMask) && \"bitmask contains non-fast qualifier bits\"" , "clang/include/clang/AST/Type.h", 409, __extension__ __PRETTY_FUNCTION__ )); | ||||||
410 | Mask |= mask; | ||||||
411 | } | ||||||
412 | |||||||
413 | /// Return true if the set contains any qualifiers which require an ExtQuals | ||||||
414 | /// node to be allocated. | ||||||
415 | bool hasNonFastQualifiers() const { return Mask & ~FastMask; } | ||||||
416 | Qualifiers getNonFastQualifiers() const { | ||||||
417 | Qualifiers Quals = *this; | ||||||
418 | Quals.setFastQualifiers(0); | ||||||
419 | return Quals; | ||||||
420 | } | ||||||
421 | |||||||
422 | /// Return true if the set contains any qualifiers. | ||||||
423 | bool hasQualifiers() const { return Mask; } | ||||||
424 | bool empty() const { return !Mask; } | ||||||
425 | |||||||
426 | /// Add the qualifiers from the given set to this set. | ||||||
427 | void addQualifiers(Qualifiers Q) { | ||||||
428 | // If the other set doesn't have any non-boolean qualifiers, just | ||||||
429 | // bit-or it in. | ||||||
430 | if (!(Q.Mask & ~CVRMask)) | ||||||
431 | Mask |= Q.Mask; | ||||||
432 | else { | ||||||
433 | Mask |= (Q.Mask & CVRMask); | ||||||
434 | if (Q.hasAddressSpace()) | ||||||
435 | addAddressSpace(Q.getAddressSpace()); | ||||||
436 | if (Q.hasObjCGCAttr()) | ||||||
437 | addObjCGCAttr(Q.getObjCGCAttr()); | ||||||
438 | if (Q.hasObjCLifetime()) | ||||||
439 | addObjCLifetime(Q.getObjCLifetime()); | ||||||
440 | } | ||||||
441 | } | ||||||
442 | |||||||
443 | /// Remove the qualifiers from the given set from this set. | ||||||
444 | void removeQualifiers(Qualifiers Q) { | ||||||
445 | // If the other set doesn't have any non-boolean qualifiers, just | ||||||
446 | // bit-and the inverse in. | ||||||
447 | if (!(Q.Mask & ~CVRMask)) | ||||||
448 | Mask &= ~Q.Mask; | ||||||
449 | else { | ||||||
450 | Mask &= ~(Q.Mask & CVRMask); | ||||||
451 | if (getObjCGCAttr() == Q.getObjCGCAttr()) | ||||||
452 | removeObjCGCAttr(); | ||||||
453 | if (getObjCLifetime() == Q.getObjCLifetime()) | ||||||
454 | removeObjCLifetime(); | ||||||
455 | if (getAddressSpace() == Q.getAddressSpace()) | ||||||
456 | removeAddressSpace(); | ||||||
457 | } | ||||||
458 | } | ||||||
459 | |||||||
460 | /// Add the qualifiers from the given set to this set, given that | ||||||
461 | /// they don't conflict. | ||||||
462 | void addConsistentQualifiers(Qualifiers qs) { | ||||||
463 | assert(getAddressSpace() == qs.getAddressSpace() ||(static_cast <bool> (getAddressSpace() == qs.getAddressSpace () || !hasAddressSpace() || !qs.hasAddressSpace()) ? void (0) : __assert_fail ("getAddressSpace() == qs.getAddressSpace() || !hasAddressSpace() || !qs.hasAddressSpace()" , "clang/include/clang/AST/Type.h", 464, __extension__ __PRETTY_FUNCTION__ )) | ||||||
464 | !hasAddressSpace() || !qs.hasAddressSpace())(static_cast <bool> (getAddressSpace() == qs.getAddressSpace () || !hasAddressSpace() || !qs.hasAddressSpace()) ? void (0) : __assert_fail ("getAddressSpace() == qs.getAddressSpace() || !hasAddressSpace() || !qs.hasAddressSpace()" , "clang/include/clang/AST/Type.h", 464, __extension__ __PRETTY_FUNCTION__ )); | ||||||
465 | assert(getObjCGCAttr() == qs.getObjCGCAttr() ||(static_cast <bool> (getObjCGCAttr() == qs.getObjCGCAttr () || !hasObjCGCAttr() || !qs.hasObjCGCAttr()) ? void (0) : __assert_fail ("getObjCGCAttr() == qs.getObjCGCAttr() || !hasObjCGCAttr() || !qs.hasObjCGCAttr()" , "clang/include/clang/AST/Type.h", 466, __extension__ __PRETTY_FUNCTION__ )) | ||||||
466 | !hasObjCGCAttr() || !qs.hasObjCGCAttr())(static_cast <bool> (getObjCGCAttr() == qs.getObjCGCAttr () || !hasObjCGCAttr() || !qs.hasObjCGCAttr()) ? void (0) : __assert_fail ("getObjCGCAttr() == qs.getObjCGCAttr() || !hasObjCGCAttr() || !qs.hasObjCGCAttr()" , "clang/include/clang/AST/Type.h", 466, __extension__ __PRETTY_FUNCTION__ )); | ||||||
467 | assert(getObjCLifetime() == qs.getObjCLifetime() ||(static_cast <bool> (getObjCLifetime() == qs.getObjCLifetime () || !hasObjCLifetime() || !qs.hasObjCLifetime()) ? void (0) : __assert_fail ("getObjCLifetime() == qs.getObjCLifetime() || !hasObjCLifetime() || !qs.hasObjCLifetime()" , "clang/include/clang/AST/Type.h", 468, __extension__ __PRETTY_FUNCTION__ )) | ||||||
468 | !hasObjCLifetime() || !qs.hasObjCLifetime())(static_cast <bool> (getObjCLifetime() == qs.getObjCLifetime () || !hasObjCLifetime() || !qs.hasObjCLifetime()) ? void (0) : __assert_fail ("getObjCLifetime() == qs.getObjCLifetime() || !hasObjCLifetime() || !qs.hasObjCLifetime()" , "clang/include/clang/AST/Type.h", 468, __extension__ __PRETTY_FUNCTION__ )); | ||||||
469 | Mask |= qs.Mask; | ||||||
470 | } | ||||||
471 | |||||||
472 | /// Returns true if address space A is equal to or a superset of B. | ||||||
473 | /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of | ||||||
474 | /// overlapping address spaces. | ||||||
475 | /// CL1.1 or CL1.2: | ||||||
476 | /// every address space is a superset of itself. | ||||||
477 | /// CL2.0 adds: | ||||||
478 | /// __generic is a superset of any address space except for __constant. | ||||||
479 | static bool isAddressSpaceSupersetOf(LangAS A, LangAS B) { | ||||||
480 | // Address spaces must match exactly. | ||||||
481 | return A == B || | ||||||
482 | // Otherwise in OpenCLC v2.0 s6.5.5: every address space except | ||||||
483 | // for __constant can be used as __generic. | ||||||
484 | (A == LangAS::opencl_generic && B != LangAS::opencl_constant) || | ||||||
485 | // We also define global_device and global_host address spaces, | ||||||
486 | // to distinguish global pointers allocated on host from pointers | ||||||
487 | // allocated on device, which are a subset of __global. | ||||||
488 | (A == LangAS::opencl_global && (B == LangAS::opencl_global_device || | ||||||
489 | B == LangAS::opencl_global_host)) || | ||||||
490 | (A == LangAS::sycl_global && (B == LangAS::sycl_global_device || | ||||||
491 | B == LangAS::sycl_global_host)) || | ||||||
492 | // Consider pointer size address spaces to be equivalent to default. | ||||||
493 | ((isPtrSizeAddressSpace(A) || A == LangAS::Default) && | ||||||
494 | (isPtrSizeAddressSpace(B) || B == LangAS::Default)) || | ||||||
495 | // Default is a superset of SYCL address spaces. | ||||||
496 | (A == LangAS::Default && | ||||||
497 | (B == LangAS::sycl_private || B == LangAS::sycl_local || | ||||||
498 | B == LangAS::sycl_global || B == LangAS::sycl_global_device || | ||||||
499 | B == LangAS::sycl_global_host)) || | ||||||
500 | // In HIP device compilation, any cuda address space is allowed | ||||||
501 | // to implicitly cast into the default address space. | ||||||
502 | (A == LangAS::Default && | ||||||
503 | (B == LangAS::cuda_constant || B == LangAS::cuda_device || | ||||||
504 | B == LangAS::cuda_shared)); | ||||||
505 | } | ||||||
506 | |||||||
507 | /// Returns true if the address space in these qualifiers is equal to or | ||||||
508 | /// a superset of the address space in the argument qualifiers. | ||||||
509 | bool isAddressSpaceSupersetOf(Qualifiers other) const { | ||||||
510 | return isAddressSpaceSupersetOf(getAddressSpace(), other.getAddressSpace()); | ||||||
511 | } | ||||||
512 | |||||||
513 | /// Determines if these qualifiers compatibly include another set. | ||||||
514 | /// Generally this answers the question of whether an object with the other | ||||||
515 | /// qualifiers can be safely used as an object with these qualifiers. | ||||||
516 | bool compatiblyIncludes(Qualifiers other) const { | ||||||
517 | return isAddressSpaceSupersetOf(other) && | ||||||
518 | // ObjC GC qualifiers can match, be added, or be removed, but can't | ||||||
519 | // be changed. | ||||||
520 | (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() || | ||||||
521 | !other.hasObjCGCAttr()) && | ||||||
522 | // ObjC lifetime qualifiers must match exactly. | ||||||
523 | getObjCLifetime() == other.getObjCLifetime() && | ||||||
524 | // CVR qualifiers may subset. | ||||||
525 | (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)) && | ||||||
526 | // U qualifier may superset. | ||||||
527 | (!other.hasUnaligned() || hasUnaligned()); | ||||||
528 | } | ||||||
529 | |||||||
530 | /// Determines if these qualifiers compatibly include another set of | ||||||
531 | /// qualifiers from the narrow perspective of Objective-C ARC lifetime. | ||||||
532 | /// | ||||||
533 | /// One set of Objective-C lifetime qualifiers compatibly includes the other | ||||||
534 | /// if the lifetime qualifiers match, or if both are non-__weak and the | ||||||
535 | /// including set also contains the 'const' qualifier, or both are non-__weak | ||||||
536 | /// and one is None (which can only happen in non-ARC modes). | ||||||
537 | bool compatiblyIncludesObjCLifetime(Qualifiers other) const { | ||||||
538 | if (getObjCLifetime() == other.getObjCLifetime()) | ||||||
539 | return true; | ||||||
540 | |||||||
541 | if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak) | ||||||
542 | return false; | ||||||
543 | |||||||
544 | if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None) | ||||||
545 | return true; | ||||||
546 | |||||||
547 | return hasConst(); | ||||||
548 | } | ||||||
549 | |||||||
550 | /// Determine whether this set of qualifiers is a strict superset of | ||||||
551 | /// another set of qualifiers, not considering qualifier compatibility. | ||||||
552 | bool isStrictSupersetOf(Qualifiers Other) const; | ||||||
553 | |||||||
554 | bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } | ||||||
555 | bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } | ||||||
556 | |||||||
557 | explicit operator bool() const { return hasQualifiers(); } | ||||||
558 | |||||||
559 | Qualifiers &operator+=(Qualifiers R) { | ||||||
560 | addQualifiers(R); | ||||||
561 | return *this; | ||||||
562 | } | ||||||
563 | |||||||
564 | // Union two qualifier sets. If an enumerated qualifier appears | ||||||
565 | // in both sets, use the one from the right. | ||||||
566 | friend Qualifiers operator+(Qualifiers L, Qualifiers R) { | ||||||
567 | L += R; | ||||||
568 | return L; | ||||||
569 | } | ||||||
570 | |||||||
571 | Qualifiers &operator-=(Qualifiers R) { | ||||||
572 | removeQualifiers(R); | ||||||
573 | return *this; | ||||||
574 | } | ||||||
575 | |||||||
576 | /// Compute the difference between two qualifier sets. | ||||||
577 | friend Qualifiers operator-(Qualifiers L, Qualifiers R) { | ||||||
578 | L -= R; | ||||||
579 | return L; | ||||||
580 | } | ||||||
581 | |||||||
582 | std::string getAsString() const; | ||||||
583 | std::string getAsString(const PrintingPolicy &Policy) const; | ||||||
584 | |||||||
585 | static std::string getAddrSpaceAsString(LangAS AS); | ||||||
586 | |||||||
587 | bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const; | ||||||
588 | void print(raw_ostream &OS, const PrintingPolicy &Policy, | ||||||
589 | bool appendSpaceIfNonEmpty = false) const; | ||||||
590 | |||||||
591 | void Profile(llvm::FoldingSetNodeID &ID) const { | ||||||
592 | ID.AddInteger(Mask); | ||||||
593 | } | ||||||
594 | |||||||
595 | private: | ||||||
596 | // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31| | ||||||
597 | // |C R V|U|GCAttr|Lifetime|AddressSpace| | ||||||
598 | uint32_t Mask = 0; | ||||||
599 | |||||||
600 | static const uint32_t UMask = 0x8; | ||||||
601 | static const uint32_t UShift = 3; | ||||||
602 | static const uint32_t GCAttrMask = 0x30; | ||||||
603 | static const uint32_t GCAttrShift = 4; | ||||||
604 | static const uint32_t LifetimeMask = 0x1C0; | ||||||
605 | static const uint32_t LifetimeShift = 6; | ||||||
606 | static const uint32_t AddressSpaceMask = | ||||||
607 | ~(CVRMask | UMask | GCAttrMask | LifetimeMask); | ||||||
608 | static const uint32_t AddressSpaceShift = 9; | ||||||
609 | }; | ||||||
610 | |||||||
611 | /// A std::pair-like structure for storing a qualified type split | ||||||
612 | /// into its local qualifiers and its locally-unqualified type. | ||||||
613 | struct SplitQualType { | ||||||
614 | /// The locally-unqualified type. | ||||||
615 | const Type *Ty = nullptr; | ||||||
616 | |||||||
617 | /// The local qualifiers. | ||||||
618 | Qualifiers Quals; | ||||||
619 | |||||||
620 | SplitQualType() = default; | ||||||
621 | SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {} | ||||||
622 | |||||||
623 | SplitQualType getSingleStepDesugaredType() const; // end of this file | ||||||
624 | |||||||
625 | // Make std::tie work. | ||||||
626 | std::pair<const Type *,Qualifiers> asPair() const { | ||||||
627 | return std::pair<const Type *, Qualifiers>(Ty, Quals); | ||||||
628 | } | ||||||
629 | |||||||
630 | friend bool operator==(SplitQualType a, SplitQualType b) { | ||||||
631 | return a.Ty == b.Ty && a.Quals == b.Quals; | ||||||
632 | } | ||||||
633 | friend bool operator!=(SplitQualType a, SplitQualType b) { | ||||||
634 | return a.Ty != b.Ty || a.Quals != b.Quals; | ||||||
635 | } | ||||||
636 | }; | ||||||
637 | |||||||
638 | /// The kind of type we are substituting Objective-C type arguments into. | ||||||
639 | /// | ||||||
640 | /// The kind of substitution affects the replacement of type parameters when | ||||||
641 | /// no concrete type information is provided, e.g., when dealing with an | ||||||
642 | /// unspecialized type. | ||||||
643 | enum class ObjCSubstitutionContext { | ||||||
644 | /// An ordinary type. | ||||||
645 | Ordinary, | ||||||
646 | |||||||
647 | /// The result type of a method or function. | ||||||
648 | Result, | ||||||
649 | |||||||
650 | /// The parameter type of a method or function. | ||||||
651 | Parameter, | ||||||
652 | |||||||
653 | /// The type of a property. | ||||||
654 | Property, | ||||||
655 | |||||||
656 | /// The superclass of a type. | ||||||
657 | Superclass, | ||||||
658 | }; | ||||||
659 | |||||||
660 | /// A (possibly-)qualified type. | ||||||
661 | /// | ||||||
662 | /// For efficiency, we don't store CV-qualified types as nodes on their | ||||||
663 | /// own: instead each reference to a type stores the qualifiers. This | ||||||
664 | /// greatly reduces the number of nodes we need to allocate for types (for | ||||||
665 | /// example we only need one for 'int', 'const int', 'volatile int', | ||||||
666 | /// 'const volatile int', etc). | ||||||
667 | /// | ||||||
668 | /// As an added efficiency bonus, instead of making this a pair, we | ||||||
669 | /// just store the two bits we care about in the low bits of the | ||||||
670 | /// pointer. To handle the packing/unpacking, we make QualType be a | ||||||
671 | /// simple wrapper class that acts like a smart pointer. A third bit | ||||||
672 | /// indicates whether there are extended qualifiers present, in which | ||||||
673 | /// case the pointer points to a special structure. | ||||||
674 | class QualType { | ||||||
675 | friend class QualifierCollector; | ||||||
676 | |||||||
677 | // Thankfully, these are efficiently composable. | ||||||
678 | llvm::PointerIntPair<llvm::PointerUnion<const Type *, const ExtQuals *>, | ||||||
679 | Qualifiers::FastWidth> Value; | ||||||
680 | |||||||
681 | const ExtQuals *getExtQualsUnsafe() const { | ||||||
682 | return Value.getPointer().get<const ExtQuals*>(); | ||||||
683 | } | ||||||
684 | |||||||
685 | const Type *getTypePtrUnsafe() const { | ||||||
686 | return Value.getPointer().get<const Type*>(); | ||||||
687 | } | ||||||
688 | |||||||
689 | const ExtQualsTypeCommonBase *getCommonPtr() const { | ||||||
690 | assert(!isNull() && "Cannot retrieve a NULL type pointer")(static_cast <bool> (!isNull() && "Cannot retrieve a NULL type pointer" ) ? void (0) : __assert_fail ("!isNull() && \"Cannot retrieve a NULL type pointer\"" , "clang/include/clang/AST/Type.h", 690, __extension__ __PRETTY_FUNCTION__ )); | ||||||
691 | auto CommonPtrVal = reinterpret_cast<uintptr_t>(Value.getOpaqueValue()); | ||||||
692 | CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1); | ||||||
693 | return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal); | ||||||
694 | } | ||||||
695 | |||||||
696 | public: | ||||||
697 | QualType() = default; | ||||||
698 | QualType(const Type *Ptr, unsigned Quals) : Value(Ptr, Quals) {} | ||||||
699 | QualType(const ExtQuals *Ptr, unsigned Quals) : Value(Ptr, Quals) {} | ||||||
700 | |||||||
701 | unsigned getLocalFastQualifiers() const { return Value.getInt(); } | ||||||
702 | void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); } | ||||||
703 | |||||||
704 | /// Retrieves a pointer to the underlying (unqualified) type. | ||||||
705 | /// | ||||||
706 | /// This function requires that the type not be NULL. If the type might be | ||||||
707 | /// NULL, use the (slightly less efficient) \c getTypePtrOrNull(). | ||||||
708 | const Type *getTypePtr() const; | ||||||
709 | |||||||
710 | const Type *getTypePtrOrNull() const; | ||||||
711 | |||||||
712 | /// Retrieves a pointer to the name of the base type. | ||||||
713 | const IdentifierInfo *getBaseTypeIdentifier() const; | ||||||
714 | |||||||
715 | /// Divides a QualType into its unqualified type and a set of local | ||||||
716 | /// qualifiers. | ||||||
717 | SplitQualType split() const; | ||||||
718 | |||||||
719 | void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } | ||||||
720 | |||||||
721 | static QualType getFromOpaquePtr(const void *Ptr) { | ||||||
722 | QualType T; | ||||||
723 | T.Value.setFromOpaqueValue(const_cast<void*>(Ptr)); | ||||||
724 | return T; | ||||||
725 | } | ||||||
726 | |||||||
727 | const Type &operator*() const { | ||||||
728 | return *getTypePtr(); | ||||||
729 | } | ||||||
730 | |||||||
731 | const Type *operator->() const { | ||||||
732 | return getTypePtr(); | ||||||
733 | } | ||||||
734 | |||||||
735 | bool isCanonical() const; | ||||||
736 | bool isCanonicalAsParam() const; | ||||||
737 | |||||||
738 | /// Return true if this QualType doesn't point to a type yet. | ||||||
739 | bool isNull() const { | ||||||
740 | return Value.getPointer().isNull(); | ||||||
741 | } | ||||||
742 | |||||||
743 | /// Determine whether this particular QualType instance has the | ||||||
744 | /// "const" qualifier set, without looking through typedefs that may have | ||||||
745 | /// added "const" at a different level. | ||||||
746 | bool isLocalConstQualified() const { | ||||||
747 | return (getLocalFastQualifiers() & Qualifiers::Const); | ||||||
748 | } | ||||||
749 | |||||||
750 | /// Determine whether this type is const-qualified. | ||||||
751 | bool isConstQualified() const; | ||||||
752 | |||||||
753 | /// Determine whether this particular QualType instance has the | ||||||
754 | /// "restrict" qualifier set, without looking through typedefs that may have | ||||||
755 | /// added "restrict" at a different level. | ||||||
756 | bool isLocalRestrictQualified() const { | ||||||
757 | return (getLocalFastQualifiers() & Qualifiers::Restrict); | ||||||
758 | } | ||||||
759 | |||||||
760 | /// Determine whether this type is restrict-qualified. | ||||||
761 | bool isRestrictQualified() const; | ||||||
762 | |||||||
763 | /// Determine whether this particular QualType instance has the | ||||||
764 | /// "volatile" qualifier set, without looking through typedefs that may have | ||||||
765 | /// added "volatile" at a different level. | ||||||
766 | bool isLocalVolatileQualified() const { | ||||||
767 | return (getLocalFastQualifiers() & Qualifiers::Volatile); | ||||||
768 | } | ||||||
769 | |||||||
770 | /// Determine whether this type is volatile-qualified. | ||||||
771 | bool isVolatileQualified() const; | ||||||
772 | |||||||
773 | /// Determine whether this particular QualType instance has any | ||||||
774 | /// qualifiers, without looking through any typedefs that might add | ||||||
775 | /// qualifiers at a different level. | ||||||
776 | bool hasLocalQualifiers() const { | ||||||
777 | return getLocalFastQualifiers() || hasLocalNonFastQualifiers(); | ||||||
778 | } | ||||||
779 | |||||||
780 | /// Determine whether this type has any qualifiers. | ||||||
781 | bool hasQualifiers() const; | ||||||
782 | |||||||
783 | /// Determine whether this particular QualType instance has any | ||||||
784 | /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType | ||||||
785 | /// instance. | ||||||
786 | bool hasLocalNonFastQualifiers() const { | ||||||
787 | return Value.getPointer().is<const ExtQuals*>(); | ||||||
788 | } | ||||||
789 | |||||||
790 | /// Retrieve the set of qualifiers local to this particular QualType | ||||||
791 | /// instance, not including any qualifiers acquired through typedefs or | ||||||
792 | /// other sugar. | ||||||
793 | Qualifiers getLocalQualifiers() const; | ||||||
794 | |||||||
795 | /// Retrieve the set of qualifiers applied to this type. | ||||||
796 | Qualifiers getQualifiers() const; | ||||||
797 | |||||||
798 | /// Retrieve the set of CVR (const-volatile-restrict) qualifiers | ||||||
799 | /// local to this particular QualType instance, not including any qualifiers | ||||||
800 | /// acquired through typedefs or other sugar. | ||||||
801 | unsigned getLocalCVRQualifiers() const { | ||||||
802 | return getLocalFastQualifiers(); | ||||||
803 | } | ||||||
804 | |||||||
805 | /// Retrieve the set of CVR (const-volatile-restrict) qualifiers | ||||||
806 | /// applied to this type. | ||||||
807 | unsigned getCVRQualifiers() const; | ||||||
808 | |||||||
809 | bool isConstant(const ASTContext& Ctx) const { | ||||||
810 | return QualType::isConstant(*this, Ctx); | ||||||
811 | } | ||||||
812 | |||||||
813 | /// Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). | ||||||
814 | bool isPODType(const ASTContext &Context) const; | ||||||
815 | |||||||
816 | /// Return true if this is a POD type according to the rules of the C++98 | ||||||
817 | /// standard, regardless of the current compilation's language. | ||||||
818 | bool isCXX98PODType(const ASTContext &Context) const; | ||||||
819 | |||||||
820 | /// Return true if this is a POD type according to the more relaxed rules | ||||||
821 | /// of the C++11 standard, regardless of the current compilation's language. | ||||||
822 | /// (C++0x [basic.types]p9). Note that, unlike | ||||||
823 | /// CXXRecordDecl::isCXX11StandardLayout, this takes DRs into account. | ||||||
824 | bool isCXX11PODType(const ASTContext &Context) const; | ||||||
825 | |||||||
826 | /// Return true if this is a trivial type per (C++0x [basic.types]p9) | ||||||
827 | bool isTrivialType(const ASTContext &Context) const; | ||||||
828 | |||||||
829 | /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) | ||||||
830 | bool isTriviallyCopyableType(const ASTContext &Context) const; | ||||||
831 | |||||||
832 | |||||||
833 | /// Returns true if it is a class and it might be dynamic. | ||||||
834 | bool mayBeDynamicClass() const; | ||||||
835 | |||||||
836 | /// Returns true if it is not a class or if the class might not be dynamic. | ||||||
837 | bool mayBeNotDynamicClass() const; | ||||||
838 | |||||||
839 | // Don't promise in the API that anything besides 'const' can be | ||||||
840 | // easily added. | ||||||
841 | |||||||
842 | /// Add the `const` type qualifier to this QualType. | ||||||
843 | void addConst() { | ||||||
844 | addFastQualifiers(Qualifiers::Const); | ||||||
845 | } | ||||||
846 | QualType withConst() const { | ||||||
847 | return withFastQualifiers(Qualifiers::Const); | ||||||
848 | } | ||||||
849 | |||||||
850 | /// Add the `volatile` type qualifier to this QualType. | ||||||
851 | void addVolatile() { | ||||||
852 | addFastQualifiers(Qualifiers::Volatile); | ||||||
853 | } | ||||||
854 | QualType withVolatile() const { | ||||||
855 | return withFastQualifiers(Qualifiers::Volatile); | ||||||
856 | } | ||||||
857 | |||||||
858 | /// Add the `restrict` qualifier to this QualType. | ||||||
859 | void addRestrict() { | ||||||
860 | addFastQualifiers(Qualifiers::Restrict); | ||||||
861 | } | ||||||
862 | QualType withRestrict() const { | ||||||
863 | return withFastQualifiers(Qualifiers::Restrict); | ||||||
864 | } | ||||||
865 | |||||||
866 | QualType withCVRQualifiers(unsigned CVR) const { | ||||||
867 | return withFastQualifiers(CVR); | ||||||
868 | } | ||||||
869 | |||||||
870 | void addFastQualifiers(unsigned TQs) { | ||||||
871 | assert(!(TQs & ~Qualifiers::FastMask)(static_cast <bool> (!(TQs & ~Qualifiers::FastMask) && "non-fast qualifier bits set in mask!") ? void (0 ) : __assert_fail ("!(TQs & ~Qualifiers::FastMask) && \"non-fast qualifier bits set in mask!\"" , "clang/include/clang/AST/Type.h", 872, __extension__ __PRETTY_FUNCTION__ )) | ||||||
872 | && "non-fast qualifier bits set in mask!")(static_cast <bool> (!(TQs & ~Qualifiers::FastMask) && "non-fast qualifier bits set in mask!") ? void (0 ) : __assert_fail ("!(TQs & ~Qualifiers::FastMask) && \"non-fast qualifier bits set in mask!\"" , "clang/include/clang/AST/Type.h", 872, __extension__ __PRETTY_FUNCTION__ )); | ||||||
873 | Value.setInt(Value.getInt() | TQs); | ||||||
874 | } | ||||||
875 | |||||||
876 | void removeLocalConst(); | ||||||
877 | void removeLocalVolatile(); | ||||||
878 | void removeLocalRestrict(); | ||||||
879 | void removeLocalCVRQualifiers(unsigned Mask); | ||||||
880 | |||||||
881 | void removeLocalFastQualifiers() { Value.setInt(0); } | ||||||
882 | void removeLocalFastQualifiers(unsigned Mask) { | ||||||
883 | assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers")(static_cast <bool> (!(Mask & ~Qualifiers::FastMask ) && "mask has non-fast qualifiers") ? void (0) : __assert_fail ("!(Mask & ~Qualifiers::FastMask) && \"mask has non-fast qualifiers\"" , "clang/include/clang/AST/Type.h", 883, __extension__ __PRETTY_FUNCTION__ )); | ||||||
884 | Value.setInt(Value.getInt() & ~Mask); | ||||||
885 | } | ||||||
886 | |||||||
887 | // Creates a type with the given qualifiers in addition to any | ||||||
888 | // qualifiers already on this type. | ||||||
889 | QualType withFastQualifiers(unsigned TQs) const { | ||||||
890 | QualType T = *this; | ||||||
891 | T.addFastQualifiers(TQs); | ||||||
892 | return T; | ||||||
893 | } | ||||||
894 | |||||||
895 | // Creates a type with exactly the given fast qualifiers, removing | ||||||
896 | // any existing fast qualifiers. | ||||||
897 | QualType withExactLocalFastQualifiers(unsigned TQs) const { | ||||||
898 | return withoutLocalFastQualifiers().withFastQualifiers(TQs); | ||||||
899 | } | ||||||
900 | |||||||
901 | // Removes fast qualifiers, but leaves any extended qualifiers in place. | ||||||
902 | QualType withoutLocalFastQualifiers() const { | ||||||
903 | QualType T = *this; | ||||||
904 | T.removeLocalFastQualifiers(); | ||||||
905 | return T; | ||||||
906 | } | ||||||
907 | |||||||
908 | QualType getCanonicalType() const; | ||||||
909 | |||||||
910 | /// Return this type with all of the instance-specific qualifiers | ||||||
911 | /// removed, but without removing any qualifiers that may have been applied | ||||||
912 | /// through typedefs. | ||||||
913 | QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); } | ||||||
914 | |||||||
915 | /// Retrieve the unqualified variant of the given type, | ||||||
916 | /// removing as little sugar as possible. | ||||||
917 | /// | ||||||
918 | /// This routine looks through various kinds of sugar to find the | ||||||
919 | /// least-desugared type that is unqualified. For example, given: | ||||||
920 | /// | ||||||
921 | /// \code | ||||||
922 | /// typedef int Integer; | ||||||
923 | /// typedef const Integer CInteger; | ||||||
924 | /// typedef CInteger DifferenceType; | ||||||
925 | /// \endcode | ||||||
926 | /// | ||||||
927 | /// Executing \c getUnqualifiedType() on the type \c DifferenceType will | ||||||
928 | /// desugar until we hit the type \c Integer, which has no qualifiers on it. | ||||||
929 | /// | ||||||
930 | /// The resulting type might still be qualified if it's sugar for an array | ||||||
931 | /// type. To strip qualifiers even from within a sugared array type, use | ||||||
932 | /// ASTContext::getUnqualifiedArrayType. | ||||||
933 | inline QualType getUnqualifiedType() const; | ||||||
934 | |||||||
935 | /// Retrieve the unqualified variant of the given type, removing as little | ||||||
936 | /// sugar as possible. | ||||||
937 | /// | ||||||
938 | /// Like getUnqualifiedType(), but also returns the set of | ||||||
939 | /// qualifiers that were built up. | ||||||
940 | /// | ||||||
941 | /// The resulting type might still be qualified if it's sugar for an array | ||||||
942 | /// type. To strip qualifiers even from within a sugared array type, use | ||||||
943 | /// ASTContext::getUnqualifiedArrayType. | ||||||
944 | inline SplitQualType getSplitUnqualifiedType() const; | ||||||
945 | |||||||
946 | /// Determine whether this type is more qualified than the other | ||||||
947 | /// given type, requiring exact equality for non-CVR qualifiers. | ||||||
948 | bool isMoreQualifiedThan(QualType Other) const; | ||||||
949 | |||||||
950 | /// Determine whether this type is at least as qualified as the other | ||||||
951 | /// given type, requiring exact equality for non-CVR qualifiers. | ||||||
952 | bool isAtLeastAsQualifiedAs(QualType Other) const; | ||||||
953 | |||||||
954 | QualType getNonReferenceType() const; | ||||||
955 | |||||||
956 | /// Determine the type of a (typically non-lvalue) expression with the | ||||||
957 | /// specified result type. | ||||||
958 | /// | ||||||
959 | /// This routine should be used for expressions for which the return type is | ||||||
960 | /// explicitly specified (e.g., in a cast or call) and isn't necessarily | ||||||
961 | /// an lvalue. It removes a top-level reference (since there are no | ||||||
962 | /// expressions of reference type) and deletes top-level cvr-qualifiers | ||||||
963 | /// from non-class types (in C++) or all types (in C). | ||||||
964 | QualType getNonLValueExprType(const ASTContext &Context) const; | ||||||
965 | |||||||
966 | /// Remove an outer pack expansion type (if any) from this type. Used as part | ||||||
967 | /// of converting the type of a declaration to the type of an expression that | ||||||
968 | /// references that expression. It's meaningless for an expression to have a | ||||||
969 | /// pack expansion type. | ||||||
970 | QualType getNonPackExpansionType() const; | ||||||
971 | |||||||
972 | /// Return the specified type with any "sugar" removed from | ||||||
973 | /// the type. This takes off typedefs, typeof's etc. If the outer level of | ||||||
974 | /// the type is already concrete, it returns it unmodified. This is similar | ||||||
975 | /// to getting the canonical type, but it doesn't remove *all* typedefs. For | ||||||
976 | /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is | ||||||
977 | /// concrete. | ||||||
978 | /// | ||||||
979 | /// Qualifiers are left in place. | ||||||
980 | QualType getDesugaredType(const ASTContext &Context) const { | ||||||
981 | return getDesugaredType(*this, Context); | ||||||
982 | } | ||||||
983 | |||||||
984 | SplitQualType getSplitDesugaredType() const { | ||||||
985 | return getSplitDesugaredType(*this); | ||||||
986 | } | ||||||
987 | |||||||
988 | /// Return the specified type with one level of "sugar" removed from | ||||||
989 | /// the type. | ||||||
990 | /// | ||||||
991 | /// This routine takes off the first typedef, typeof, etc. If the outer level | ||||||
992 | /// of the type is already concrete, it returns it unmodified. | ||||||
993 | QualType getSingleStepDesugaredType(const ASTContext &Context) const { | ||||||
994 | return getSingleStepDesugaredTypeImpl(*this, Context); | ||||||
995 | } | ||||||
996 | |||||||
997 | /// Returns the specified type after dropping any | ||||||
998 | /// outer-level parentheses. | ||||||
999 | QualType IgnoreParens() const { | ||||||
1000 | if (isa<ParenType>(*this)) | ||||||
1001 | return QualType::IgnoreParens(*this); | ||||||
1002 | return *this; | ||||||
1003 | } | ||||||
1004 | |||||||
1005 | /// Indicate whether the specified types and qualifiers are identical. | ||||||
1006 | friend bool operator==(const QualType &LHS, const QualType &RHS) { | ||||||
1007 | return LHS.Value == RHS.Value; | ||||||
1008 | } | ||||||
1009 | friend bool operator!=(const QualType &LHS, const QualType &RHS) { | ||||||
1010 | return LHS.Value != RHS.Value; | ||||||
1011 | } | ||||||
1012 | friend bool operator<(const QualType &LHS, const QualType &RHS) { | ||||||
1013 | return LHS.Value < RHS.Value; | ||||||
1014 | } | ||||||
1015 | |||||||
1016 | static std::string getAsString(SplitQualType split, | ||||||
1017 | const PrintingPolicy &Policy) { | ||||||
1018 | return getAsString(split.Ty, split.Quals, Policy); | ||||||
1019 | } | ||||||
1020 | static std::string getAsString(const Type *ty, Qualifiers qs, | ||||||
1021 | const PrintingPolicy &Policy); | ||||||
1022 | |||||||
1023 | std::string getAsString() const; | ||||||
1024 | std::string getAsString(const PrintingPolicy &Policy) const; | ||||||
1025 | |||||||
1026 | void print(raw_ostream &OS, const PrintingPolicy &Policy, | ||||||
1027 | const Twine &PlaceHolder = Twine(), | ||||||
1028 | unsigned Indentation = 0) const; | ||||||
1029 | |||||||
1030 | static void print(SplitQualType split, raw_ostream &OS, | ||||||
1031 | const PrintingPolicy &policy, const Twine &PlaceHolder, | ||||||
1032 | unsigned Indentation = 0) { | ||||||
1033 | return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation); | ||||||
1034 | } | ||||||
1035 | |||||||
1036 | static void print(const Type *ty, Qualifiers qs, | ||||||
1037 | raw_ostream &OS, const PrintingPolicy &policy, | ||||||
1038 | const Twine &PlaceHolder, | ||||||
1039 | unsigned Indentation = 0); | ||||||
1040 | |||||||
1041 | void getAsStringInternal(std::string &Str, | ||||||
1042 | const PrintingPolicy &Policy) const; | ||||||
1043 | |||||||
1044 | static void getAsStringInternal(SplitQualType split, std::string &out, | ||||||
1045 | const PrintingPolicy &policy) { | ||||||
1046 | return getAsStringInternal(split.Ty, split.Quals, out, policy); | ||||||
1047 | } | ||||||
1048 | |||||||
1049 | static void getAsStringInternal(const Type *ty, Qualifiers qs, | ||||||
1050 | std::string &out, | ||||||
1051 | const PrintingPolicy &policy); | ||||||
1052 | |||||||
1053 | class StreamedQualTypeHelper { | ||||||
1054 | const QualType &T; | ||||||
1055 | const PrintingPolicy &Policy; | ||||||
1056 | const Twine &PlaceHolder; | ||||||
1057 | unsigned Indentation; | ||||||
1058 | |||||||
1059 | public: | ||||||
1060 | StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, | ||||||
1061 | const Twine &PlaceHolder, unsigned Indentation) | ||||||
1062 | : T(T), Policy(Policy), PlaceHolder(PlaceHolder), | ||||||
1063 | Indentation(Indentation) {} | ||||||
1064 | |||||||
1065 | friend raw_ostream &operator<<(raw_ostream &OS, | ||||||
1066 | const StreamedQualTypeHelper &SQT) { | ||||||
1067 | SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation); | ||||||
1068 | return OS; | ||||||
1069 | } | ||||||
1070 | }; | ||||||
1071 | |||||||
1072 | StreamedQualTypeHelper stream(const PrintingPolicy &Policy, | ||||||
1073 | const Twine &PlaceHolder = Twine(), | ||||||
1074 | unsigned Indentation = 0) const { | ||||||
1075 | return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation); | ||||||
1076 | } | ||||||
1077 | |||||||
1078 | void dump(const char *s) const; | ||||||
1079 | void dump() const; | ||||||
1080 | void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; | ||||||
1081 | |||||||
1082 | void Profile(llvm::FoldingSetNodeID &ID) const { | ||||||
1083 | ID.AddPointer(getAsOpaquePtr()); | ||||||
1084 | } | ||||||
1085 | |||||||
1086 | /// Check if this type has any address space qualifier. | ||||||
1087 | inline bool hasAddressSpace() const; | ||||||
1088 | |||||||
1089 | /// Return the address space of this type. | ||||||
1090 | inline LangAS getAddressSpace() const; | ||||||
1091 | |||||||
1092 | /// Returns true if address space qualifiers overlap with T address space | ||||||
1093 | /// qualifiers. | ||||||
1094 | /// OpenCL C defines conversion rules for pointers to different address spaces | ||||||
1095 | /// and notion of overlapping address spaces. | ||||||
1096 | /// CL1.1 or CL1.2: | ||||||
1097 | /// address spaces overlap iff they are they same. | ||||||
1098 | /// OpenCL C v2.0 s6.5.5 adds: | ||||||
1099 | /// __generic overlaps with any address space except for __constant. | ||||||
1100 | bool isAddressSpaceOverlapping(QualType T) const { | ||||||
1101 | Qualifiers Q = getQualifiers(); | ||||||
1102 | Qualifiers TQ = T.getQualifiers(); | ||||||
1103 | // Address spaces overlap if at least one of them is a superset of another | ||||||
1104 | return Q.isAddressSpaceSupersetOf(TQ) || TQ.isAddressSpaceSupersetOf(Q); | ||||||
1105 | } | ||||||
1106 | |||||||
1107 | /// Returns gc attribute of this type. | ||||||
1108 | inline Qualifiers::GC getObjCGCAttr() const; | ||||||
1109 | |||||||
1110 | /// true when Type is objc's weak. | ||||||
1111 | bool isObjCGCWeak() const { | ||||||
1112 | return getObjCGCAttr() == Qualifiers::Weak; | ||||||
1113 | } | ||||||
1114 | |||||||
1115 | /// true when Type is objc's strong. | ||||||
1116 | bool isObjCGCStrong() const { | ||||||
1117 | return getObjCGCAttr() == Qualifiers::Strong; | ||||||
1118 | } | ||||||
1119 | |||||||
1120 | /// Returns lifetime attribute of this type. | ||||||
1121 | Qualifiers::ObjCLifetime getObjCLifetime() const { | ||||||
1122 | return getQualifiers().getObjCLifetime(); | ||||||
1123 | } | ||||||
1124 | |||||||
1125 | bool hasNonTrivialObjCLifetime() const { | ||||||
1126 | return getQualifiers().hasNonTrivialObjCLifetime(); | ||||||
1127 | } | ||||||
1128 | |||||||
1129 | bool hasStrongOrWeakObjCLifetime() const { | ||||||
1130 | return getQualifiers().hasStrongOrWeakObjCLifetime(); | ||||||
1131 | } | ||||||
1132 | |||||||
1133 | // true when Type is objc's weak and weak is enabled but ARC isn't. | ||||||
1134 | bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const; | ||||||
1135 | |||||||
1136 | enum PrimitiveDefaultInitializeKind { | ||||||
1137 | /// The type does not fall into any of the following categories. Note that | ||||||
1138 | /// this case is zero-valued so that values of this enum can be used as a | ||||||
1139 | /// boolean condition for non-triviality. | ||||||
1140 | PDIK_Trivial, | ||||||
1141 | |||||||
1142 | /// The type is an Objective-C retainable pointer type that is qualified | ||||||
1143 | /// with the ARC __strong qualifier. | ||||||
1144 | PDIK_ARCStrong, | ||||||
1145 | |||||||
1146 | /// The type is an Objective-C retainable pointer type that is qualified | ||||||
1147 | /// with the ARC __weak qualifier. | ||||||
1148 | PDIK_ARCWeak, | ||||||
1149 | |||||||
1150 | /// The type is a struct containing a field whose type is not PCK_Trivial. | ||||||
1151 | PDIK_Struct | ||||||
1152 | }; | ||||||
1153 | |||||||
1154 | /// Functions to query basic properties of non-trivial C struct types. | ||||||
1155 | |||||||
1156 | /// Check if this is a non-trivial type that would cause a C struct | ||||||
1157 | /// transitively containing this type to be non-trivial to default initialize | ||||||
1158 | /// and return the kind. | ||||||
1159 | PrimitiveDefaultInitializeKind | ||||||
1160 | isNonTrivialToPrimitiveDefaultInitialize() const; | ||||||
1161 | |||||||
1162 | enum PrimitiveCopyKind { | ||||||
1163 | /// The type does not fall into any of the following categories. Note that | ||||||
1164 | /// this case is zero-valued so that values of this enum can be used as a | ||||||
1165 | /// boolean condition for non-triviality. | ||||||
1166 | PCK_Trivial, | ||||||
1167 | |||||||
1168 | /// The type would be trivial except that it is volatile-qualified. Types | ||||||
1169 | /// that fall into one of the other non-trivial cases may additionally be | ||||||
1170 | /// volatile-qualified. | ||||||
1171 | PCK_VolatileTrivial, | ||||||
1172 | |||||||
1173 | /// The type is an Objective-C retainable pointer type that is qualified | ||||||
1174 | /// with the ARC __strong qualifier. | ||||||
1175 | PCK_ARCStrong, | ||||||
1176 | |||||||
1177 | /// The type is an Objective-C retainable pointer type that is qualified | ||||||
1178 | /// with the ARC __weak qualifier. | ||||||
1179 | PCK_ARCWeak, | ||||||
1180 | |||||||
1181 | /// The type is a struct containing a field whose type is neither | ||||||
1182 | /// PCK_Trivial nor PCK_VolatileTrivial. | ||||||
1183 | /// Note that a C++ struct type does not necessarily match this; C++ copying | ||||||
1184 | /// semantics are too complex to express here, in part because they depend | ||||||
1185 | /// on the exact constructor or assignment operator that is chosen by | ||||||
1186 | /// overload resolution to do the copy. | ||||||
1187 | PCK_Struct | ||||||
1188 | }; | ||||||
1189 | |||||||
1190 | /// Check if this is a non-trivial type that would cause a C struct | ||||||
1191 | /// transitively containing this type to be non-trivial to copy and return the | ||||||
1192 | /// kind. | ||||||
1193 | PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const; | ||||||
1194 | |||||||
1195 | /// Check if this is a non-trivial type that would cause a C struct | ||||||
1196 | /// transitively containing this type to be non-trivial to destructively | ||||||
1197 | /// move and return the kind. Destructive move in this context is a C++-style | ||||||
1198 | /// move in which the source object is placed in a valid but unspecified state | ||||||
1199 | /// after it is moved, as opposed to a truly destructive move in which the | ||||||
1200 | /// source object is placed in an uninitialized state. | ||||||
1201 | PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const; | ||||||
1202 | |||||||
1203 | enum DestructionKind { | ||||||
1204 | DK_none, | ||||||
1205 | DK_cxx_destructor, | ||||||
1206 | DK_objc_strong_lifetime, | ||||||
1207 | DK_objc_weak_lifetime, | ||||||
1208 | DK_nontrivial_c_struct | ||||||
1209 | }; | ||||||
1210 | |||||||
1211 | /// Returns a nonzero value if objects of this type require | ||||||
1212 | /// non-trivial work to clean up after. Non-zero because it's | ||||||
1213 | /// conceivable that qualifiers (objc_gc(weak)?) could make | ||||||
1214 | /// something require destruction. | ||||||
1215 | DestructionKind isDestructedType() const { | ||||||
1216 | return isDestructedTypeImpl(*this); | ||||||
1217 | } | ||||||
1218 | |||||||
1219 | /// Check if this is or contains a C union that is non-trivial to | ||||||
1220 | /// default-initialize, which is a union that has a member that is non-trivial | ||||||
1221 | /// to default-initialize. If this returns true, | ||||||
1222 | /// isNonTrivialToPrimitiveDefaultInitialize returns PDIK_Struct. | ||||||
1223 | bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const; | ||||||
1224 | |||||||
1225 | /// Check if this is or contains a C union that is non-trivial to destruct, | ||||||
1226 | /// which is a union that has a member that is non-trivial to destruct. If | ||||||
1227 | /// this returns true, isDestructedType returns DK_nontrivial_c_struct. | ||||||
1228 | bool hasNonTrivialToPrimitiveDestructCUnion() const; | ||||||
1229 | |||||||
1230 | /// Check if this is or contains a C union that is non-trivial to copy, which | ||||||
1231 | /// is a union that has a member that is non-trivial to copy. If this returns | ||||||
1232 | /// true, isNonTrivialToPrimitiveCopy returns PCK_Struct. | ||||||
1233 | bool hasNonTrivialToPrimitiveCopyCUnion() const; | ||||||
1234 | |||||||
1235 | /// Determine whether expressions of the given type are forbidden | ||||||
1236 | /// from being lvalues in C. | ||||||
1237 | /// | ||||||
1238 | /// The expression types that are forbidden to be lvalues are: | ||||||
1239 | /// - 'void', but not qualified void | ||||||
1240 | /// - function types | ||||||
1241 | /// | ||||||
1242 | /// The exact rule here is C99 6.3.2.1: | ||||||
1243 | /// An lvalue is an expression with an object type or an incomplete | ||||||
1244 | /// type other than void. | ||||||
1245 | bool isCForbiddenLValueType() const; | ||||||
1246 | |||||||
1247 | /// Substitute type arguments for the Objective-C type parameters used in the | ||||||
1248 | /// subject type. | ||||||
1249 | /// | ||||||
1250 | /// \param ctx ASTContext in which the type exists. | ||||||
1251 | /// | ||||||
1252 | /// \param typeArgs The type arguments that will be substituted for the | ||||||
1253 | /// Objective-C type parameters in the subject type, which are generally | ||||||
1254 | /// computed via \c Type::getObjCSubstitutions. If empty, the type | ||||||
1255 | /// parameters will be replaced with their bounds or id/Class, as appropriate | ||||||
1256 | /// for the context. | ||||||
1257 | /// | ||||||
1258 | /// \param context The context in which the subject type was written. | ||||||
1259 | /// | ||||||
1260 | /// \returns the resulting type. | ||||||
1261 | QualType substObjCTypeArgs(ASTContext &ctx, | ||||||
1262 | ArrayRef<QualType> typeArgs, | ||||||
1263 | ObjCSubstitutionContext context) const; | ||||||
1264 | |||||||
1265 | /// Substitute type arguments from an object type for the Objective-C type | ||||||
1266 | /// parameters used in the subject type. | ||||||
1267 | /// | ||||||
1268 | /// This operation combines the computation of type arguments for | ||||||
1269 | /// substitution (\c Type::getObjCSubstitutions) with the actual process of | ||||||
1270 | /// substitution (\c QualType::substObjCTypeArgs) for the convenience of | ||||||
1271 | /// callers that need to perform a single substitution in isolation. | ||||||
1272 | /// | ||||||
1273 | /// \param objectType The type of the object whose member type we're | ||||||
1274 | /// substituting into. For example, this might be the receiver of a message | ||||||
1275 | /// or the base of a property access. | ||||||
1276 | /// | ||||||
1277 | /// \param dc The declaration context from which the subject type was | ||||||
1278 | /// retrieved, which indicates (for example) which type parameters should | ||||||
1279 | /// be substituted. | ||||||
1280 | /// | ||||||
1281 | /// \param context The context in which the subject type was written. | ||||||
1282 | /// | ||||||
1283 | /// \returns the subject type after replacing all of the Objective-C type | ||||||
1284 | /// parameters with their corresponding arguments. | ||||||
1285 | QualType substObjCMemberType(QualType objectType, | ||||||
1286 | const DeclContext *dc, | ||||||
1287 | ObjCSubstitutionContext context) const; | ||||||
1288 | |||||||
1289 | /// Strip Objective-C "__kindof" types from the given type. | ||||||
1290 | QualType stripObjCKindOfType(const ASTContext &ctx) const; | ||||||
1291 | |||||||
1292 | /// Remove all qualifiers including _Atomic. | ||||||
1293 | QualType getAtomicUnqualifiedType() const; | ||||||
1294 | |||||||
1295 | private: | ||||||
1296 | // These methods are implemented in a separate translation unit; | ||||||
1297 | // "static"-ize them to avoid creating temporary QualTypes in the | ||||||
1298 | // caller. | ||||||
1299 | static bool isConstant(QualType T, const ASTContext& Ctx); | ||||||
1300 | static QualType getDesugaredType(QualType T, const ASTContext &Context); | ||||||
1301 | static SplitQualType getSplitDesugaredType(QualType T); | ||||||
1302 | static SplitQualType getSplitUnqualifiedTypeImpl(QualType type); | ||||||
1303 | static QualType getSingleStepDesugaredTypeImpl(QualType type, | ||||||
1304 | const ASTContext &C); | ||||||
1305 | static QualType IgnoreParens(QualType T); | ||||||
1306 | static DestructionKind isDestructedTypeImpl(QualType type); | ||||||
1307 | |||||||
1308 | /// Check if \param RD is or contains a non-trivial C union. | ||||||
1309 | static bool hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD); | ||||||
1310 | static bool hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD); | ||||||
1311 | static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD); | ||||||
1312 | }; | ||||||
1313 | |||||||
1314 | } // namespace clang | ||||||
1315 | |||||||
1316 | namespace llvm { | ||||||
1317 | |||||||
1318 | /// Implement simplify_type for QualType, so that we can dyn_cast from QualType | ||||||
1319 | /// to a specific Type class. | ||||||
1320 | template<> struct simplify_type< ::clang::QualType> { | ||||||
1321 | using SimpleType = const ::clang::Type *; | ||||||
1322 | |||||||
1323 | static SimpleType getSimplifiedValue(::clang::QualType Val) { | ||||||
1324 | return Val.getTypePtr(); | ||||||
1325 | } | ||||||
1326 | }; | ||||||
1327 | |||||||
1328 | // Teach SmallPtrSet that QualType is "basically a pointer". | ||||||
1329 | template<> | ||||||
1330 | struct PointerLikeTypeTraits<clang::QualType> { | ||||||
1331 | static inline void *getAsVoidPointer(clang::QualType P) { | ||||||
1332 | return P.getAsOpaquePtr(); | ||||||
1333 | } | ||||||
1334 | |||||||
1335 | static inline clang::QualType getFromVoidPointer(void *P) { | ||||||
1336 | return clang::QualType::getFromOpaquePtr(P); | ||||||
1337 | } | ||||||
1338 | |||||||
1339 | // Various qualifiers go in low bits. | ||||||
1340 | static constexpr int NumLowBitsAvailable = 0; | ||||||
1341 | }; | ||||||
1342 | |||||||
1343 | } // namespace llvm | ||||||
1344 | |||||||
1345 | namespace clang { | ||||||
1346 | |||||||
1347 | /// Base class that is common to both the \c ExtQuals and \c Type | ||||||
1348 | /// classes, which allows \c QualType to access the common fields between the | ||||||
1349 | /// two. | ||||||
1350 | class ExtQualsTypeCommonBase { | ||||||
1351 | friend class ExtQuals; | ||||||
1352 | friend class QualType; | ||||||
1353 | friend class Type; | ||||||
1354 | |||||||
1355 | /// The "base" type of an extended qualifiers type (\c ExtQuals) or | ||||||
1356 | /// a self-referential pointer (for \c Type). | ||||||
1357 | /// | ||||||
1358 | /// This pointer allows an efficient mapping from a QualType to its | ||||||
1359 | /// underlying type pointer. | ||||||
1360 | const Type *const BaseType; | ||||||
1361 | |||||||
1362 | /// The canonical type of this type. A QualType. | ||||||
1363 | QualType CanonicalType; | ||||||
1364 | |||||||
1365 | ExtQualsTypeCommonBase(const Type *baseType, QualType canon) | ||||||
1366 | : BaseType(baseType), CanonicalType(canon) {} | ||||||
1367 | }; | ||||||
1368 | |||||||
1369 | /// We can encode up to four bits in the low bits of a | ||||||
1370 | /// type pointer, but there are many more type qualifiers that we want | ||||||
1371 | /// to be able to apply to an arbitrary type. Therefore we have this | ||||||
1372 | /// struct, intended to be heap-allocated and used by QualType to | ||||||
1373 | /// store qualifiers. | ||||||
1374 | /// | ||||||
1375 | /// The current design tags the 'const', 'restrict', and 'volatile' qualifiers | ||||||
1376 | /// in three low bits on the QualType pointer; a fourth bit records whether | ||||||
1377 | /// the pointer is an ExtQuals node. The extended qualifiers (address spaces, | ||||||
1378 | /// Objective-C GC attributes) are much more rare. | ||||||
1379 | class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode { | ||||||
1380 | // NOTE: changing the fast qualifiers should be straightforward as | ||||||
1381 | // long as you don't make 'const' non-fast. | ||||||
1382 | // 1. Qualifiers: | ||||||
1383 | // a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ). | ||||||
1384 | // Fast qualifiers must occupy the low-order bits. | ||||||
1385 | // b) Update Qualifiers::FastWidth and FastMask. | ||||||
1386 | // 2. QualType: | ||||||
1387 | // a) Update is{Volatile,Restrict}Qualified(), defined inline. | ||||||
1388 | // b) Update remove{Volatile,Restrict}, defined near the end of | ||||||
1389 | // this header. | ||||||
1390 | // 3. ASTContext: | ||||||
1391 | // a) Update get{Volatile,Restrict}Type. | ||||||
1392 | |||||||
1393 | /// The immutable set of qualifiers applied by this node. Always contains | ||||||
1394 | /// extended qualifiers. | ||||||
1395 | Qualifiers Quals; | ||||||
1396 | |||||||
1397 | ExtQuals *this_() { return this; } | ||||||
1398 | |||||||
1399 | public: | ||||||
1400 | ExtQuals(const Type *baseType, QualType canon, Qualifiers quals) | ||||||
1401 | : ExtQualsTypeCommonBase(baseType, | ||||||
1402 | canon.isNull() ? QualType(this_(), 0) : canon), | ||||||
1403 | Quals(quals) { | ||||||
1404 | assert(Quals.hasNonFastQualifiers()(static_cast <bool> (Quals.hasNonFastQualifiers() && "ExtQuals created with no fast qualifiers") ? void (0) : __assert_fail ("Quals.hasNonFastQualifiers() && \"ExtQuals created with no fast qualifiers\"" , "clang/include/clang/AST/Type.h", 1405, __extension__ __PRETTY_FUNCTION__ )) | ||||||
1405 | && "ExtQuals created with no fast qualifiers")(static_cast <bool> (Quals.hasNonFastQualifiers() && "ExtQuals created with no fast qualifiers") ? void (0) : __assert_fail ("Quals.hasNonFastQualifiers() && \"ExtQuals created with no fast qualifiers\"" , "clang/include/clang/AST/Type.h", 1405, __extension__ __PRETTY_FUNCTION__ )); | ||||||
1406 | assert(!Quals.hasFastQualifiers()(static_cast <bool> (!Quals.hasFastQualifiers() && "ExtQuals created with fast qualifiers") ? void (0) : __assert_fail ("!Quals.hasFastQualifiers() && \"ExtQuals created with fast qualifiers\"" , "clang/include/clang/AST/Type.h", 1407, __extension__ __PRETTY_FUNCTION__ )) | ||||||
1407 | && "ExtQuals created with fast qualifiers")(static_cast <bool> (!Quals.hasFastQualifiers() && "ExtQuals created with fast qualifiers") ? void (0) : __assert_fail ("!Quals.hasFastQualifiers() && \"ExtQuals created with fast qualifiers\"" , "clang/include/clang/AST/Type.h", 1407, __extension__ __PRETTY_FUNCTION__ )); | ||||||
1408 | } | ||||||
1409 | |||||||
1410 | Qualifiers getQualifiers() const { return Quals; } | ||||||
1411 | |||||||
1412 | bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); } | ||||||
1413 | Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); } | ||||||
1414 | |||||||
1415 | bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); } | ||||||
1416 | Qualifiers::ObjCLifetime getObjCLifetime() const { | ||||||
1417 | return Quals.getObjCLifetime(); | ||||||
1418 | } | ||||||
1419 | |||||||
1420 | bool hasAddressSpace() const { return Quals.hasAddressSpace(); } | ||||||
1421 | LangAS getAddressSpace() const { return Quals.getAddressSpace(); } | ||||||
1422 | |||||||
1423 | const Type *getBaseType() const { return BaseType; } | ||||||
1424 | |||||||
1425 | public: | ||||||
1426 | void Profile(llvm::FoldingSetNodeID &ID) const { | ||||||
1427 | Profile(ID, getBaseType(), Quals); | ||||||
1428 | } | ||||||
1429 | |||||||
1430 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
1431 | const Type *BaseType, | ||||||
1432 | Qualifiers Quals) { | ||||||
1433 | assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!")(static_cast <bool> (!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!") ? void (0) : __assert_fail ("!Quals.hasFastQualifiers() && \"fast qualifiers in ExtQuals hash!\"" , "clang/include/clang/AST/Type.h", 1433, __extension__ __PRETTY_FUNCTION__ )); | ||||||
1434 | ID.AddPointer(BaseType); | ||||||
1435 | Quals.Profile(ID); | ||||||
1436 | } | ||||||
1437 | }; | ||||||
1438 | |||||||
1439 | /// The kind of C++11 ref-qualifier associated with a function type. | ||||||
1440 | /// This determines whether a member function's "this" object can be an | ||||||
1441 | /// lvalue, rvalue, or neither. | ||||||
1442 | enum RefQualifierKind { | ||||||
1443 | /// No ref-qualifier was provided. | ||||||
1444 | RQ_None = 0, | ||||||
1445 | |||||||
1446 | /// An lvalue ref-qualifier was provided (\c &). | ||||||
1447 | RQ_LValue, | ||||||
1448 | |||||||
1449 | /// An rvalue ref-qualifier was provided (\c &&). | ||||||
1450 | RQ_RValue | ||||||
1451 | }; | ||||||
1452 | |||||||
1453 | /// Which keyword(s) were used to create an AutoType. | ||||||
1454 | enum class AutoTypeKeyword { | ||||||
1455 | /// auto | ||||||
1456 | Auto, | ||||||
1457 | |||||||
1458 | /// decltype(auto) | ||||||
1459 | DecltypeAuto, | ||||||
1460 | |||||||
1461 | /// __auto_type (GNU extension) | ||||||
1462 | GNUAutoType | ||||||
1463 | }; | ||||||
1464 | |||||||
1465 | /// The base class of the type hierarchy. | ||||||
1466 | /// | ||||||
1467 | /// A central concept with types is that each type always has a canonical | ||||||
1468 | /// type. A canonical type is the type with any typedef names stripped out | ||||||
1469 | /// of it or the types it references. For example, consider: | ||||||
1470 | /// | ||||||
1471 | /// typedef int foo; | ||||||
1472 | /// typedef foo* bar; | ||||||
1473 | /// 'int *' 'foo *' 'bar' | ||||||
1474 | /// | ||||||
1475 | /// There will be a Type object created for 'int'. Since int is canonical, its | ||||||
1476 | /// CanonicalType pointer points to itself. There is also a Type for 'foo' (a | ||||||
1477 | /// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next | ||||||
1478 | /// there is a PointerType that represents 'int*', which, like 'int', is | ||||||
1479 | /// canonical. Finally, there is a PointerType type for 'foo*' whose canonical | ||||||
1480 | /// type is 'int*', and there is a TypedefType for 'bar', whose canonical type | ||||||
1481 | /// is also 'int*'. | ||||||
1482 | /// | ||||||
1483 | /// Non-canonical types are useful for emitting diagnostics, without losing | ||||||
1484 | /// information about typedefs being used. Canonical types are useful for type | ||||||
1485 | /// comparisons (they allow by-pointer equality tests) and useful for reasoning | ||||||
1486 | /// about whether something has a particular form (e.g. is a function type), | ||||||
1487 | /// because they implicitly, recursively, strip all typedefs out of a type. | ||||||
1488 | /// | ||||||
1489 | /// Types, once created, are immutable. | ||||||
1490 | /// | ||||||
1491 | class alignas(8) Type : public ExtQualsTypeCommonBase { | ||||||
1492 | public: | ||||||
1493 | enum TypeClass { | ||||||
1494 | #define TYPE(Class, Base) Class, | ||||||
1495 | #define LAST_TYPE(Class) TypeLast = Class | ||||||
1496 | #define ABSTRACT_TYPE(Class, Base) | ||||||
1497 | #include "clang/AST/TypeNodes.inc" | ||||||
1498 | }; | ||||||
1499 | |||||||
1500 | private: | ||||||
1501 | /// Bitfields required by the Type class. | ||||||
1502 | class TypeBitfields { | ||||||
1503 | friend class Type; | ||||||
1504 | template <class T> friend class TypePropertyCache; | ||||||
1505 | |||||||
1506 | /// TypeClass bitfield - Enum that specifies what subclass this belongs to. | ||||||
1507 | unsigned TC : 8; | ||||||
1508 | |||||||
1509 | /// Store information on the type dependency. | ||||||
1510 | unsigned Dependence : llvm::BitWidth<TypeDependence>; | ||||||
1511 | |||||||
1512 | /// True if the cache (i.e. the bitfields here starting with | ||||||
1513 | /// 'Cache') is valid. | ||||||
1514 | mutable unsigned CacheValid : 1; | ||||||
1515 | |||||||
1516 | /// Linkage of this type. | ||||||
1517 | mutable unsigned CachedLinkage : 3; | ||||||
1518 | |||||||
1519 | /// Whether this type involves and local or unnamed types. | ||||||
1520 | mutable unsigned CachedLocalOrUnnamed : 1; | ||||||
1521 | |||||||
1522 | /// Whether this type comes from an AST file. | ||||||
1523 | mutable unsigned FromAST : 1; | ||||||
1524 | |||||||
1525 | bool isCacheValid() const { | ||||||
1526 | return CacheValid; | ||||||
1527 | } | ||||||
1528 | |||||||
1529 | Linkage getLinkage() const { | ||||||
1530 | assert(isCacheValid() && "getting linkage from invalid cache")(static_cast <bool> (isCacheValid() && "getting linkage from invalid cache" ) ? void (0) : __assert_fail ("isCacheValid() && \"getting linkage from invalid cache\"" , "clang/include/clang/AST/Type.h", 1530, __extension__ __PRETTY_FUNCTION__ )); | ||||||
1531 | return static_cast<Linkage>(CachedLinkage); | ||||||
1532 | } | ||||||
1533 | |||||||
1534 | bool hasLocalOrUnnamedType() const { | ||||||
1535 | assert(isCacheValid() && "getting linkage from invalid cache")(static_cast <bool> (isCacheValid() && "getting linkage from invalid cache" ) ? void (0) : __assert_fail ("isCacheValid() && \"getting linkage from invalid cache\"" , "clang/include/clang/AST/Type.h", 1535, __extension__ __PRETTY_FUNCTION__ )); | ||||||
1536 | return CachedLocalOrUnnamed; | ||||||
1537 | } | ||||||
1538 | }; | ||||||
1539 | enum { NumTypeBits = 8 + llvm::BitWidth<TypeDependence> + 6 }; | ||||||
1540 | |||||||
1541 | protected: | ||||||
1542 | // These classes allow subclasses to somewhat cleanly pack bitfields | ||||||
1543 | // into Type. | ||||||
1544 | |||||||
1545 | class ArrayTypeBitfields { | ||||||
1546 | friend class ArrayType; | ||||||
1547 | |||||||
1548 | unsigned : NumTypeBits; | ||||||
1549 | |||||||
1550 | /// CVR qualifiers from declarations like | ||||||
1551 | /// 'int X[static restrict 4]'. For function parameters only. | ||||||
1552 | unsigned IndexTypeQuals : 3; | ||||||
1553 | |||||||
1554 | /// Storage class qualifiers from declarations like | ||||||
1555 | /// 'int X[static restrict 4]'. For function parameters only. | ||||||
1556 | /// Actually an ArrayType::ArraySizeModifier. | ||||||
1557 | unsigned SizeModifier : 3; | ||||||
1558 | }; | ||||||
1559 | |||||||
1560 | class ConstantArrayTypeBitfields { | ||||||
1561 | friend class ConstantArrayType; | ||||||
1562 | |||||||
1563 | unsigned : NumTypeBits + 3 + 3; | ||||||
1564 | |||||||
1565 | /// Whether we have a stored size expression. | ||||||
1566 | unsigned HasStoredSizeExpr : 1; | ||||||
1567 | }; | ||||||
1568 | |||||||
1569 | class BuiltinTypeBitfields { | ||||||
1570 | friend class BuiltinType; | ||||||
1571 | |||||||
1572 | unsigned : NumTypeBits; | ||||||
1573 | |||||||
1574 | /// The kind (BuiltinType::Kind) of builtin type this is. | ||||||
1575 | unsigned Kind : 8; | ||||||
1576 | }; | ||||||
1577 | |||||||
1578 | /// FunctionTypeBitfields store various bits belonging to FunctionProtoType. | ||||||
1579 | /// Only common bits are stored here. Additional uncommon bits are stored | ||||||
1580 | /// in a trailing object after FunctionProtoType. | ||||||
1581 | class FunctionTypeBitfields { | ||||||
1582 | friend class FunctionProtoType; | ||||||
1583 | friend class FunctionType; | ||||||
1584 | |||||||
1585 | unsigned : NumTypeBits; | ||||||
1586 | |||||||
1587 | /// Extra information which affects how the function is called, like | ||||||
1588 | /// regparm and the calling convention. | ||||||
1589 | unsigned ExtInfo : 13; | ||||||
1590 | |||||||
1591 | /// The ref-qualifier associated with a \c FunctionProtoType. | ||||||
1592 | /// | ||||||
1593 | /// This is a value of type \c RefQualifierKind. | ||||||
1594 | unsigned RefQualifier : 2; | ||||||
1595 | |||||||
1596 | /// Used only by FunctionProtoType, put here to pack with the | ||||||
1597 | /// other bitfields. | ||||||
1598 | /// The qualifiers are part of FunctionProtoType because... | ||||||
1599 | /// | ||||||
1600 | /// C++ 8.3.5p4: The return type, the parameter type list and the | ||||||
1601 | /// cv-qualifier-seq, [...], are part of the function type. | ||||||
1602 | unsigned FastTypeQuals : Qualifiers::FastWidth; | ||||||
1603 | /// Whether this function has extended Qualifiers. | ||||||
1604 | unsigned HasExtQuals : 1; | ||||||
1605 | |||||||
1606 | /// The number of parameters this function has, not counting '...'. | ||||||
1607 | /// According to [implimits] 8 bits should be enough here but this is | ||||||
1608 | /// somewhat easy to exceed with metaprogramming and so we would like to | ||||||
1609 | /// keep NumParams as wide as reasonably possible. | ||||||
1610 | unsigned NumParams : 16; | ||||||
1611 | |||||||
1612 | /// The type of exception specification this function has. | ||||||
1613 | unsigned ExceptionSpecType : 4; | ||||||
1614 | |||||||
1615 | /// Whether this function has extended parameter information. | ||||||
1616 | unsigned HasExtParameterInfos : 1; | ||||||
1617 | |||||||
1618 | /// Whether the function is variadic. | ||||||
1619 | unsigned Variadic : 1; | ||||||
1620 | |||||||
1621 | /// Whether this function has a trailing return type. | ||||||
1622 | unsigned HasTrailingReturn : 1; | ||||||
1623 | }; | ||||||
1624 | |||||||
1625 | class ObjCObjectTypeBitfields { | ||||||
1626 | friend class ObjCObjectType; | ||||||
1627 | |||||||
1628 | unsigned : NumTypeBits; | ||||||
1629 | |||||||
1630 | /// The number of type arguments stored directly on this object type. | ||||||
1631 | unsigned NumTypeArgs : 7; | ||||||
1632 | |||||||
1633 | /// The number of protocols stored directly on this object type. | ||||||
1634 | unsigned NumProtocols : 6; | ||||||
1635 | |||||||
1636 | /// Whether this is a "kindof" type. | ||||||
1637 | unsigned IsKindOf : 1; | ||||||
1638 | }; | ||||||
1639 | |||||||
1640 | class ReferenceTypeBitfields { | ||||||
1641 | friend class ReferenceType; | ||||||
1642 | |||||||
1643 | unsigned : NumTypeBits; | ||||||
1644 | |||||||
1645 | /// True if the type was originally spelled with an lvalue sigil. | ||||||
1646 | /// This is never true of rvalue references but can also be false | ||||||
1647 | /// on lvalue references because of C++0x [dcl.typedef]p9, | ||||||
1648 | /// as follows: | ||||||
1649 | /// | ||||||
1650 | /// typedef int &ref; // lvalue, spelled lvalue | ||||||
1651 | /// typedef int &&rvref; // rvalue | ||||||
1652 | /// ref &a; // lvalue, inner ref, spelled lvalue | ||||||
1653 | /// ref &&a; // lvalue, inner ref | ||||||
1654 | /// rvref &a; // lvalue, inner ref, spelled lvalue | ||||||
1655 | /// rvref &&a; // rvalue, inner ref | ||||||
1656 | unsigned SpelledAsLValue : 1; | ||||||
1657 | |||||||
1658 | /// True if the inner type is a reference type. This only happens | ||||||
1659 | /// in non-canonical forms. | ||||||
1660 | unsigned InnerRef : 1; | ||||||
1661 | }; | ||||||
1662 | |||||||
1663 | class TypeWithKeywordBitfields { | ||||||
1664 | friend class TypeWithKeyword; | ||||||
1665 | |||||||
1666 | unsigned : NumTypeBits; | ||||||
1667 | |||||||
1668 | /// An ElaboratedTypeKeyword. 8 bits for efficient access. | ||||||
1669 | unsigned Keyword : 8; | ||||||
1670 | }; | ||||||
1671 | |||||||
1672 | enum { NumTypeWithKeywordBits = 8 }; | ||||||
1673 | |||||||
1674 | class ElaboratedTypeBitfields { | ||||||
1675 | friend class ElaboratedType; | ||||||
1676 | |||||||
1677 | unsigned : NumTypeBits; | ||||||
1678 | unsigned : NumTypeWithKeywordBits; | ||||||
1679 | |||||||
1680 | /// Whether the ElaboratedType has a trailing OwnedTagDecl. | ||||||
1681 | unsigned HasOwnedTagDecl : 1; | ||||||
1682 | }; | ||||||
1683 | |||||||
1684 | class VectorTypeBitfields { | ||||||
1685 | friend class VectorType; | ||||||
1686 | friend class DependentVectorType; | ||||||
1687 | |||||||
1688 | unsigned : NumTypeBits; | ||||||
1689 | |||||||
1690 | /// The kind of vector, either a generic vector type or some | ||||||
1691 | /// target-specific vector type such as for AltiVec or Neon. | ||||||
1692 | unsigned VecKind : 3; | ||||||
1693 | /// The number of elements in the vector. | ||||||
1694 | uint32_t NumElements; | ||||||
1695 | }; | ||||||
1696 | |||||||
1697 | class AttributedTypeBitfields { | ||||||
1698 | friend class AttributedType; | ||||||
1699 | |||||||
1700 | unsigned : NumTypeBits; | ||||||
1701 | |||||||
1702 | /// An AttributedType::Kind | ||||||
1703 | unsigned AttrKind : 32 - NumTypeBits; | ||||||
1704 | }; | ||||||
1705 | |||||||
1706 | class AutoTypeBitfields { | ||||||
1707 | friend class AutoType; | ||||||
1708 | |||||||
1709 | unsigned : NumTypeBits; | ||||||
1710 | |||||||
1711 | /// Was this placeholder type spelled as 'auto', 'decltype(auto)', | ||||||
1712 | /// or '__auto_type'? AutoTypeKeyword value. | ||||||
1713 | unsigned Keyword : 2; | ||||||
1714 | |||||||
1715 | /// The number of template arguments in the type-constraints, which is | ||||||
1716 | /// expected to be able to hold at least 1024 according to [implimits]. | ||||||
1717 | /// However as this limit is somewhat easy to hit with template | ||||||
1718 | /// metaprogramming we'd prefer to keep it as large as possible. | ||||||
1719 | /// At the moment it has been left as a non-bitfield since this type | ||||||
1720 | /// safely fits in 64 bits as an unsigned, so there is no reason to | ||||||
1721 | /// introduce the performance impact of a bitfield. | ||||||
1722 | unsigned NumArgs; | ||||||
1723 | }; | ||||||
1724 | |||||||
1725 | class SubstTemplateTypeParmPackTypeBitfields { | ||||||
1726 | friend class SubstTemplateTypeParmPackType; | ||||||
1727 | |||||||
1728 | unsigned : NumTypeBits; | ||||||
1729 | |||||||
1730 | /// The number of template arguments in \c Arguments, which is | ||||||
1731 | /// expected to be able to hold at least 1024 according to [implimits]. | ||||||
1732 | /// However as this limit is somewhat easy to hit with template | ||||||
1733 | /// metaprogramming we'd prefer to keep it as large as possible. | ||||||
1734 | /// At the moment it has been left as a non-bitfield since this type | ||||||
1735 | /// safely fits in 64 bits as an unsigned, so there is no reason to | ||||||
1736 | /// introduce the performance impact of a bitfield. | ||||||
1737 | unsigned NumArgs; | ||||||
1738 | }; | ||||||
1739 | |||||||
1740 | class TemplateSpecializationTypeBitfields { | ||||||
1741 | friend class TemplateSpecializationType; | ||||||
1742 | |||||||
1743 | unsigned : NumTypeBits; | ||||||
1744 | |||||||
1745 | /// Whether this template specialization type is a substituted type alias. | ||||||
1746 | unsigned TypeAlias : 1; | ||||||
1747 | |||||||
1748 | /// The number of template arguments named in this class template | ||||||
1749 | /// specialization, which is expected to be able to hold at least 1024 | ||||||
1750 | /// according to [implimits]. However, as this limit is somewhat easy to | ||||||
1751 | /// hit with template metaprogramming we'd prefer to keep it as large | ||||||
1752 | /// as possible. At the moment it has been left as a non-bitfield since | ||||||
1753 | /// this type safely fits in 64 bits as an unsigned, so there is no reason | ||||||
1754 | /// to introduce the performance impact of a bitfield. | ||||||
1755 | unsigned NumArgs; | ||||||
1756 | }; | ||||||
1757 | |||||||
1758 | class DependentTemplateSpecializationTypeBitfields { | ||||||
1759 | friend class DependentTemplateSpecializationType; | ||||||
1760 | |||||||
1761 | unsigned : NumTypeBits; | ||||||
1762 | unsigned : NumTypeWithKeywordBits; | ||||||
1763 | |||||||
1764 | /// The number of template arguments named in this class template | ||||||
1765 | /// specialization, which is expected to be able to hold at least 1024 | ||||||
1766 | /// according to [implimits]. However, as this limit is somewhat easy to | ||||||
1767 | /// hit with template metaprogramming we'd prefer to keep it as large | ||||||
1768 | /// as possible. At the moment it has been left as a non-bitfield since | ||||||
1769 | /// this type safely fits in 64 bits as an unsigned, so there is no reason | ||||||
1770 | /// to introduce the performance impact of a bitfield. | ||||||
1771 | unsigned NumArgs; | ||||||
1772 | }; | ||||||
1773 | |||||||
1774 | class PackExpansionTypeBitfields { | ||||||
1775 | friend class PackExpansionType; | ||||||
1776 | |||||||
1777 | unsigned : NumTypeBits; | ||||||
1778 | |||||||
1779 | /// The number of expansions that this pack expansion will | ||||||
1780 | /// generate when substituted (+1), which is expected to be able to | ||||||
1781 | /// hold at least 1024 according to [implimits]. However, as this limit | ||||||
1782 | /// is somewhat easy to hit with template metaprogramming we'd prefer to | ||||||
1783 | /// keep it as large as possible. At the moment it has been left as a | ||||||
1784 | /// non-bitfield since this type safely fits in 64 bits as an unsigned, so | ||||||
1785 | /// there is no reason to introduce the performance impact of a bitfield. | ||||||
1786 | /// | ||||||
1787 | /// This field will only have a non-zero value when some of the parameter | ||||||
1788 | /// packs that occur within the pattern have been substituted but others | ||||||
1789 | /// have not. | ||||||
1790 | unsigned NumExpansions; | ||||||
1791 | }; | ||||||
1792 | |||||||
1793 | union { | ||||||
1794 | TypeBitfields TypeBits; | ||||||
1795 | ArrayTypeBitfields ArrayTypeBits; | ||||||
1796 | ConstantArrayTypeBitfields ConstantArrayTypeBits; | ||||||
1797 | AttributedTypeBitfields AttributedTypeBits; | ||||||
1798 | AutoTypeBitfields AutoTypeBits; | ||||||
1799 | BuiltinTypeBitfields BuiltinTypeBits; | ||||||
1800 | FunctionTypeBitfields FunctionTypeBits; | ||||||
1801 | ObjCObjectTypeBitfields ObjCObjectTypeBits; | ||||||
1802 | ReferenceTypeBitfields ReferenceTypeBits; | ||||||
1803 | TypeWithKeywordBitfields TypeWithKeywordBits; | ||||||
1804 | ElaboratedTypeBitfields ElaboratedTypeBits; | ||||||
1805 | VectorTypeBitfields VectorTypeBits; | ||||||
1806 | SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits; | ||||||
1807 | TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; | ||||||
1808 | DependentTemplateSpecializationTypeBitfields | ||||||
1809 | DependentTemplateSpecializationTypeBits; | ||||||
1810 | PackExpansionTypeBitfields PackExpansionTypeBits; | ||||||
1811 | }; | ||||||
1812 | |||||||
1813 | private: | ||||||
1814 | template <class T> friend class TypePropertyCache; | ||||||
1815 | |||||||
1816 | /// Set whether this type comes from an AST file. | ||||||
1817 | void setFromAST(bool V = true) const { | ||||||
1818 | TypeBits.FromAST = V; | ||||||
1819 | } | ||||||
1820 | |||||||
1821 | protected: | ||||||
1822 | friend class ASTContext; | ||||||
1823 | |||||||
1824 | Type(TypeClass tc, QualType canon, TypeDependence Dependence) | ||||||
1825 | : ExtQualsTypeCommonBase(this, | ||||||
1826 | canon.isNull() ? QualType(this_(), 0) : canon) { | ||||||
1827 | static_assert(sizeof(*this) <= 8 + sizeof(ExtQualsTypeCommonBase), | ||||||
1828 | "changing bitfields changed sizeof(Type)!"); | ||||||
1829 | static_assert(alignof(decltype(*this)) % sizeof(void *) == 0, | ||||||
1830 | "Insufficient alignment!"); | ||||||
1831 | TypeBits.TC = tc; | ||||||
1832 | TypeBits.Dependence = static_cast<unsigned>(Dependence); | ||||||
1833 | TypeBits.CacheValid = false; | ||||||
1834 | TypeBits.CachedLocalOrUnnamed = false; | ||||||
1835 | TypeBits.CachedLinkage = NoLinkage; | ||||||
1836 | TypeBits.FromAST = false; | ||||||
1837 | } | ||||||
1838 | |||||||
1839 | // silence VC++ warning C4355: 'this' : used in base member initializer list | ||||||
1840 | Type *this_() { return this; } | ||||||
1841 | |||||||
1842 | void setDependence(TypeDependence D) { | ||||||
1843 | TypeBits.Dependence = static_cast<unsigned>(D); | ||||||
1844 | } | ||||||
1845 | |||||||
1846 | void addDependence(TypeDependence D) { setDependence(getDependence() | D); } | ||||||
1847 | |||||||
1848 | public: | ||||||
1849 | friend class ASTReader; | ||||||
1850 | friend class ASTWriter; | ||||||
1851 | template <class T> friend class serialization::AbstractTypeReader; | ||||||
1852 | template <class T> friend class serialization::AbstractTypeWriter; | ||||||
1853 | |||||||
1854 | Type(const Type &) = delete; | ||||||
1855 | Type(Type &&) = delete; | ||||||
1856 | Type &operator=(const Type &) = delete; | ||||||
1857 | Type &operator=(Type &&) = delete; | ||||||
1858 | |||||||
1859 | TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); } | ||||||
1860 | |||||||
1861 | /// Whether this type comes from an AST file. | ||||||
1862 | bool isFromAST() const { return TypeBits.FromAST; } | ||||||
1863 | |||||||
1864 | /// Whether this type is or contains an unexpanded parameter | ||||||
1865 | /// pack, used to support C++0x variadic templates. | ||||||
1866 | /// | ||||||
1867 | /// A type that contains a parameter pack shall be expanded by the | ||||||
1868 | /// ellipsis operator at some point. For example, the typedef in the | ||||||
1869 | /// following example contains an unexpanded parameter pack 'T': | ||||||
1870 | /// | ||||||
1871 | /// \code | ||||||
1872 | /// template<typename ...T> | ||||||
1873 | /// struct X { | ||||||
1874 | /// typedef T* pointer_types; // ill-formed; T is a parameter pack. | ||||||
1875 | /// }; | ||||||
1876 | /// \endcode | ||||||
1877 | /// | ||||||
1878 | /// Note that this routine does not specify which | ||||||
1879 | bool containsUnexpandedParameterPack() const { | ||||||
1880 | return getDependence() & TypeDependence::UnexpandedPack; | ||||||
1881 | } | ||||||
1882 | |||||||
1883 | /// Determines if this type would be canonical if it had no further | ||||||
1884 | /// qualification. | ||||||
1885 | bool isCanonicalUnqualified() const { | ||||||
1886 | return CanonicalType == QualType(this, 0); | ||||||
1887 | } | ||||||
1888 | |||||||
1889 | /// Pull a single level of sugar off of this locally-unqualified type. | ||||||
1890 | /// Users should generally prefer SplitQualType::getSingleStepDesugaredType() | ||||||
1891 | /// or QualType::getSingleStepDesugaredType(const ASTContext&). | ||||||
1892 | QualType getLocallyUnqualifiedSingleStepDesugaredType() const; | ||||||
1893 | |||||||
1894 | /// As an extension, we classify types as one of "sized" or "sizeless"; | ||||||
1895 | /// every type is one or the other. Standard types are all sized; | ||||||
1896 | /// sizeless types are purely an extension. | ||||||
1897 | /// | ||||||
1898 | /// Sizeless types contain data with no specified size, alignment, | ||||||
1899 | /// or layout. | ||||||
1900 | bool isSizelessType() const; | ||||||
1901 | bool isSizelessBuiltinType() const; | ||||||
1902 | |||||||
1903 | /// Determines if this is a sizeless type supported by the | ||||||
1904 | /// 'arm_sve_vector_bits' type attribute, which can be applied to a single | ||||||
1905 | /// SVE vector or predicate, excluding tuple types such as svint32x4_t. | ||||||
1906 | bool isVLSTBuiltinType() const; | ||||||
1907 | |||||||
1908 | /// Returns the representative type for the element of an SVE builtin type. | ||||||
1909 | /// This is used to represent fixed-length SVE vectors created with the | ||||||
1910 | /// 'arm_sve_vector_bits' type attribute as VectorType. | ||||||
1911 | QualType getSveEltType(const ASTContext &Ctx) const; | ||||||
1912 | |||||||
1913 | /// Types are partitioned into 3 broad categories (C99 6.2.5p1): | ||||||
1914 | /// object types, function types, and incomplete types. | ||||||
1915 | |||||||
1916 | /// Return true if this is an incomplete type. | ||||||
1917 | /// A type that can describe objects, but which lacks information needed to | ||||||
1918 | /// determine its size (e.g. void, or a fwd declared struct). Clients of this | ||||||
1919 | /// routine will need to determine if the size is actually required. | ||||||
1920 | /// | ||||||
1921 | /// Def If non-null, and the type refers to some kind of declaration | ||||||
1922 | /// that can be completed (such as a C struct, C++ class, or Objective-C | ||||||
1923 | /// class), will be set to the declaration. | ||||||
1924 | bool isIncompleteType(NamedDecl **Def = nullptr) const; | ||||||
1925 | |||||||
1926 | /// Return true if this is an incomplete or object | ||||||
1927 | /// type, in other words, not a function type. | ||||||
1928 | bool isIncompleteOrObjectType() const { | ||||||
1929 | return !isFunctionType(); | ||||||
1930 | } | ||||||
1931 | |||||||
1932 | /// Determine whether this type is an object type. | ||||||
1933 | bool isObjectType() const { | ||||||
1934 | // C++ [basic.types]p8: | ||||||
1935 | // An object type is a (possibly cv-qualified) type that is not a | ||||||
1936 | // function type, not a reference type, and not a void type. | ||||||
1937 | return !isReferenceType() && !isFunctionType() && !isVoidType(); | ||||||
1938 | } | ||||||
1939 | |||||||
1940 | /// Return true if this is a literal type | ||||||
1941 | /// (C++11 [basic.types]p10) | ||||||
1942 | bool isLiteralType(const ASTContext &Ctx) const; | ||||||
1943 | |||||||
1944 | /// Determine if this type is a structural type, per C++20 [temp.param]p7. | ||||||
1945 | bool isStructuralType() const; | ||||||
1946 | |||||||
1947 | /// Test if this type is a standard-layout type. | ||||||
1948 | /// (C++0x [basic.type]p9) | ||||||
1949 | bool isStandardLayoutType() const; | ||||||
1950 | |||||||
1951 | /// Helper methods to distinguish type categories. All type predicates | ||||||
1952 | /// operate on the canonical type, ignoring typedefs and qualifiers. | ||||||
1953 | |||||||
1954 | /// Returns true if the type is a builtin type. | ||||||
1955 | bool isBuiltinType() const; | ||||||
1956 | |||||||
1957 | /// Test for a particular builtin type. | ||||||
1958 | bool isSpecificBuiltinType(unsigned K) const; | ||||||
1959 | |||||||
1960 | /// Test for a type which does not represent an actual type-system type but | ||||||
1961 | /// is instead used as a placeholder for various convenient purposes within | ||||||
1962 | /// Clang. All such types are BuiltinTypes. | ||||||
1963 | bool isPlaceholderType() const; | ||||||
1964 | const BuiltinType *getAsPlaceholderType() const; | ||||||
1965 | |||||||
1966 | /// Test for a specific placeholder type. | ||||||
1967 | bool isSpecificPlaceholderType(unsigned K) const; | ||||||
1968 | |||||||
1969 | /// Test for a placeholder type other than Overload; see | ||||||
1970 | /// BuiltinType::isNonOverloadPlaceholderType. | ||||||
1971 | bool isNonOverloadPlaceholderType() const; | ||||||
1972 | |||||||
1973 | /// isIntegerType() does *not* include complex integers (a GCC extension). | ||||||
1974 | /// isComplexIntegerType() can be used to test for complex integers. | ||||||
1975 | bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum) | ||||||
1976 | bool isEnumeralType() const; | ||||||
1977 | |||||||
1978 | /// Determine whether this type is a scoped enumeration type. | ||||||
1979 | bool isScopedEnumeralType() const; | ||||||
1980 | bool isBooleanType() const; | ||||||
1981 | bool isCharType() const; | ||||||
1982 | bool isWideCharType() const; | ||||||
1983 | bool isChar8Type() const; | ||||||
1984 | bool isChar16Type() const; | ||||||
1985 | bool isChar32Type() const; | ||||||
1986 | bool isAnyCharacterType() const; | ||||||
1987 | bool isIntegralType(const ASTContext &Ctx) const; | ||||||
1988 | |||||||
1989 | /// Determine whether this type is an integral or enumeration type. | ||||||
1990 | bool isIntegralOrEnumerationType() const; | ||||||
1991 | |||||||
1992 | /// Determine whether this type is an integral or unscoped enumeration type. | ||||||
1993 | bool isIntegralOrUnscopedEnumerationType() const; | ||||||
1994 | bool isUnscopedEnumerationType() const; | ||||||
1995 | |||||||
1996 | /// Floating point categories. | ||||||
1997 | bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) | ||||||
1998 | /// isComplexType() does *not* include complex integers (a GCC extension). | ||||||
1999 | /// isComplexIntegerType() can be used to test for complex integers. | ||||||
2000 | bool isComplexType() const; // C99 6.2.5p11 (complex) | ||||||
2001 | bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. | ||||||
2002 | bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) | ||||||
2003 | bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) | ||||||
2004 | bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 | ||||||
2005 | bool isBFloat16Type() const; | ||||||
2006 | bool isFloat128Type() const; | ||||||
2007 | bool isIbm128Type() const; | ||||||
2008 | bool isRealType() const; // C99 6.2.5p17 (real floating + integer) | ||||||
2009 | bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) | ||||||
2010 | bool isVoidType() const; // C99 6.2.5p19 | ||||||
2011 | bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) | ||||||
2012 | bool isAggregateType() const; | ||||||
2013 | bool isFundamentalType() const; | ||||||
2014 | bool isCompoundType() const; | ||||||
2015 | |||||||
2016 | // Type Predicates: Check to see if this type is structurally the specified | ||||||
2017 | // type, ignoring typedefs and qualifiers. | ||||||
2018 | bool isFunctionType() const; | ||||||
2019 | bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); } | ||||||
2020 | bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); } | ||||||
2021 | bool isPointerType() const; | ||||||
2022 | bool isAnyPointerType() const; // Any C pointer or ObjC object pointer | ||||||
2023 | bool isBlockPointerType() const; | ||||||
2024 | bool isVoidPointerType() const; | ||||||
2025 | bool isReferenceType() const; | ||||||
2026 | bool isLValueReferenceType() const; | ||||||
2027 | bool isRValueReferenceType() const; | ||||||
2028 | bool isObjectPointerType() const; | ||||||
2029 | bool isFunctionPointerType() const; | ||||||
2030 | bool isFunctionReferenceType() const; | ||||||
2031 | bool isMemberPointerType() const; | ||||||
2032 | bool isMemberFunctionPointerType() const; | ||||||
2033 | bool isMemberDataPointerType() const; | ||||||
2034 | bool isArrayType() const; | ||||||
2035 | bool isConstantArrayType() const; | ||||||
2036 | bool isIncompleteArrayType() const; | ||||||
2037 | bool isVariableArrayType() const; | ||||||
2038 | bool isDependentSizedArrayType() const; | ||||||
2039 | bool isRecordType() const; | ||||||
2040 | bool isClassType() const; | ||||||
2041 | bool isStructureType() const; | ||||||
2042 | bool isObjCBoxableRecordType() const; | ||||||
2043 | bool isInterfaceType() const; | ||||||
2044 | bool isStructureOrClassType() const; | ||||||
2045 | bool isUnionType() const; | ||||||
2046 | bool isComplexIntegerType() const; // GCC _Complex integer type. | ||||||
2047 | bool isVectorType() const; // GCC vector type. | ||||||
2048 | bool isExtVectorType() const; // Extended vector type. | ||||||
2049 | bool isMatrixType() const; // Matrix type. | ||||||
2050 | bool isConstantMatrixType() const; // Constant matrix type. | ||||||
2051 | bool isDependentAddressSpaceType() const; // value-dependent address space qualifier | ||||||
2052 | bool isObjCObjectPointerType() const; // pointer to ObjC object | ||||||
2053 | bool isObjCRetainableType() const; // ObjC object or block pointer | ||||||
2054 | bool isObjCLifetimeType() const; // (array of)* retainable type | ||||||
2055 | bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type | ||||||
2056 | bool isObjCNSObjectType() const; // __attribute__((NSObject)) | ||||||
2057 | bool isObjCIndependentClassType() const; // __attribute__((objc_independent_class)) | ||||||
2058 | // FIXME: change this to 'raw' interface type, so we can used 'interface' type | ||||||
2059 | // for the common case. | ||||||
2060 | bool isObjCObjectType() const; // NSString or typeof(*(id)0) | ||||||
2061 | bool isObjCQualifiedInterfaceType() const; // NSString<foo> | ||||||
2062 | bool isObjCQualifiedIdType() const; // id<foo> | ||||||
2063 | bool isObjCQualifiedClassType() const; // Class<foo> | ||||||
2064 | bool isObjCObjectOrInterfaceType() const; | ||||||
2065 | bool isObjCIdType() const; // id | ||||||
2066 | bool isDecltypeType() const; | ||||||
2067 | /// Was this type written with the special inert-in-ARC __unsafe_unretained | ||||||
2068 | /// qualifier? | ||||||
2069 | /// | ||||||
2070 | /// This approximates the answer to the following question: if this | ||||||
2071 | /// translation unit were compiled in ARC, would this type be qualified | ||||||
2072 | /// with __unsafe_unretained? | ||||||
2073 | bool isObjCInertUnsafeUnretainedType() const { | ||||||
2074 | return hasAttr(attr::ObjCInertUnsafeUnretained); | ||||||
2075 | } | ||||||
2076 | |||||||
2077 | /// Whether the type is Objective-C 'id' or a __kindof type of an | ||||||
2078 | /// object type, e.g., __kindof NSView * or __kindof id | ||||||
2079 | /// <NSCopying>. | ||||||
2080 | /// | ||||||
2081 | /// \param bound Will be set to the bound on non-id subtype types, | ||||||
2082 | /// which will be (possibly specialized) Objective-C class type, or | ||||||
2083 | /// null for 'id. | ||||||
2084 | bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, | ||||||
2085 | const ObjCObjectType *&bound) const; | ||||||
2086 | |||||||
2087 | bool isObjCClassType() const; // Class | ||||||
2088 | |||||||
2089 | /// Whether the type is Objective-C 'Class' or a __kindof type of an | ||||||
2090 | /// Class type, e.g., __kindof Class <NSCopying>. | ||||||
2091 | /// | ||||||
2092 | /// Unlike \c isObjCIdOrObjectKindOfType, there is no relevant bound | ||||||
2093 | /// here because Objective-C's type system cannot express "a class | ||||||
2094 | /// object for a subclass of NSFoo". | ||||||
2095 | bool isObjCClassOrClassKindOfType() const; | ||||||
2096 | |||||||
2097 | bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const; | ||||||
2098 | bool isObjCSelType() const; // Class | ||||||
2099 | bool isObjCBuiltinType() const; // 'id' or 'Class' | ||||||
2100 | bool isObjCARCBridgableType() const; | ||||||
2101 | bool isCARCBridgableType() const; | ||||||
2102 | bool isTemplateTypeParmType() const; // C++ template type parameter | ||||||
2103 | bool isNullPtrType() const; // C++11 std::nullptr_t | ||||||
2104 | bool isNothrowT() const; // C++ std::nothrow_t | ||||||
2105 | bool isAlignValT() const; // C++17 std::align_val_t | ||||||
2106 | bool isStdByteType() const; // C++17 std::byte | ||||||
2107 | bool isAtomicType() const; // C11 _Atomic() | ||||||
2108 | bool isUndeducedAutoType() const; // C++11 auto or | ||||||
2109 | // C++14 decltype(auto) | ||||||
2110 | bool isTypedefNameType() const; // typedef or alias template | ||||||
2111 | |||||||
2112 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ | ||||||
2113 | bool is##Id##Type() const; | ||||||
2114 | #include "clang/Basic/OpenCLImageTypes.def" | ||||||
2115 | |||||||
2116 | bool isImageType() const; // Any OpenCL image type | ||||||
2117 | |||||||
2118 | bool isSamplerT() const; // OpenCL sampler_t | ||||||
2119 | bool isEventT() const; // OpenCL event_t | ||||||
2120 | bool isClkEventT() const; // OpenCL clk_event_t | ||||||
2121 | bool isQueueT() const; // OpenCL queue_t | ||||||
2122 | bool isReserveIDT() const; // OpenCL reserve_id_t | ||||||
2123 | |||||||
2124 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ | ||||||
2125 | bool is##Id##Type() const; | ||||||
2126 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||||
2127 | // Type defined in cl_intel_device_side_avc_motion_estimation OpenCL extension | ||||||
2128 | bool isOCLIntelSubgroupAVCType() const; | ||||||
2129 | bool isOCLExtOpaqueType() const; // Any OpenCL extension type | ||||||
2130 | |||||||
2131 | bool isPipeType() const; // OpenCL pipe type | ||||||
2132 | bool isBitIntType() const; // Bit-precise integer type | ||||||
2133 | bool isOpenCLSpecificType() const; // Any OpenCL specific type | ||||||
2134 | |||||||
2135 | /// Determines if this type, which must satisfy | ||||||
2136 | /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather | ||||||
2137 | /// than implicitly __strong. | ||||||
2138 | bool isObjCARCImplicitlyUnretainedType() const; | ||||||
2139 | |||||||
2140 | /// Check if the type is the CUDA device builtin surface type. | ||||||
2141 | bool isCUDADeviceBuiltinSurfaceType() const; | ||||||
2142 | /// Check if the type is the CUDA device builtin texture type. | ||||||
2143 | bool isCUDADeviceBuiltinTextureType() const; | ||||||
2144 | |||||||
2145 | /// Return the implicit lifetime for this type, which must not be dependent. | ||||||
2146 | Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; | ||||||
2147 | |||||||
2148 | enum ScalarTypeKind { | ||||||
2149 | STK_CPointer, | ||||||
2150 | STK_BlockPointer, | ||||||
2151 | STK_ObjCObjectPointer, | ||||||
2152 | STK_MemberPointer, | ||||||
2153 | STK_Bool, | ||||||
2154 | STK_Integral, | ||||||
2155 | STK_Floating, | ||||||
2156 | STK_IntegralComplex, | ||||||
2157 | STK_FloatingComplex, | ||||||
2158 | STK_FixedPoint | ||||||
2159 | }; | ||||||
2160 | |||||||
2161 | /// Given that this is a scalar type, classify it. | ||||||
2162 | ScalarTypeKind getScalarTypeKind() const; | ||||||
2163 | |||||||
2164 | TypeDependence getDependence() const { | ||||||
2165 | return static_cast<TypeDependence>(TypeBits.Dependence); | ||||||
2166 | } | ||||||
2167 | |||||||
2168 | /// Whether this type is an error type. | ||||||
2169 | bool containsErrors() const { | ||||||
2170 | return getDependence() & TypeDependence::Error; | ||||||
2171 | } | ||||||
2172 | |||||||
2173 | /// Whether this type is a dependent type, meaning that its definition | ||||||
2174 | /// somehow depends on a template parameter (C++ [temp.dep.type]). | ||||||
2175 | bool isDependentType() const { | ||||||
2176 | return getDependence() & TypeDependence::Dependent; | ||||||
2177 | } | ||||||
2178 | |||||||
2179 | /// Determine whether this type is an instantiation-dependent type, | ||||||
2180 | /// meaning that the type involves a template parameter (even if the | ||||||
2181 | /// definition does not actually depend on the type substituted for that | ||||||
2182 | /// template parameter). | ||||||
2183 | bool isInstantiationDependentType() const { | ||||||
2184 | return getDependence() & TypeDependence::Instantiation; | ||||||
2185 | } | ||||||
2186 | |||||||
2187 | /// Determine whether this type is an undeduced type, meaning that | ||||||
2188 | /// it somehow involves a C++11 'auto' type or similar which has not yet been | ||||||
2189 | /// deduced. | ||||||
2190 | bool isUndeducedType() const; | ||||||
2191 | |||||||
2192 | /// Whether this type is a variably-modified type (C99 6.7.5). | ||||||
2193 | bool isVariablyModifiedType() const { | ||||||
2194 | return getDependence() & TypeDependence::VariablyModified; | ||||||
2195 | } | ||||||
2196 | |||||||
2197 | /// Whether this type involves a variable-length array type | ||||||
2198 | /// with a definite size. | ||||||
2199 | bool hasSizedVLAType() const; | ||||||
2200 | |||||||
2201 | /// Whether this type is or contains a local or unnamed type. | ||||||
2202 | bool hasUnnamedOrLocalType() const; | ||||||
2203 | |||||||
2204 | bool isOverloadableType() const; | ||||||
2205 | |||||||
2206 | /// Determine wither this type is a C++ elaborated-type-specifier. | ||||||
2207 | bool isElaboratedTypeSpecifier() const; | ||||||
2208 | |||||||
2209 | bool canDecayToPointerType() const; | ||||||
2210 | |||||||
2211 | /// Whether this type is represented natively as a pointer. This includes | ||||||
2212 | /// pointers, references, block pointers, and Objective-C interface, | ||||||
2213 | /// qualified id, and qualified interface types, as well as nullptr_t. | ||||||
2214 | bool hasPointerRepresentation() const; | ||||||
2215 | |||||||
2216 | /// Whether this type can represent an objective pointer type for the | ||||||
2217 | /// purpose of GC'ability | ||||||
2218 | bool hasObjCPointerRepresentation() const; | ||||||
2219 | |||||||
2220 | /// Determine whether this type has an integer representation | ||||||
2221 | /// of some sort, e.g., it is an integer type or a vector. | ||||||
2222 | bool hasIntegerRepresentation() const; | ||||||
2223 | |||||||
2224 | /// Determine whether this type has an signed integer representation | ||||||
2225 | /// of some sort, e.g., it is an signed integer type or a vector. | ||||||
2226 | bool hasSignedIntegerRepresentation() const; | ||||||
2227 | |||||||
2228 | /// Determine whether this type has an unsigned integer representation | ||||||
2229 | /// of some sort, e.g., it is an unsigned integer type or a vector. | ||||||
2230 | bool hasUnsignedIntegerRepresentation() const; | ||||||
2231 | |||||||
2232 | /// Determine whether this type has a floating-point representation | ||||||
2233 | /// of some sort, e.g., it is a floating-point type or a vector thereof. | ||||||
2234 | bool hasFloatingRepresentation() const; | ||||||
2235 | |||||||
2236 | // Type Checking Functions: Check to see if this type is structurally the | ||||||
2237 | // specified type, ignoring typedefs and qualifiers, and return a pointer to | ||||||
2238 | // the best type we can. | ||||||
2239 | const RecordType *getAsStructureType() const; | ||||||
2240 | /// NOTE: getAs*ArrayType are methods on ASTContext. | ||||||
2241 | const RecordType *getAsUnionType() const; | ||||||
2242 | const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. | ||||||
2243 | const ObjCObjectType *getAsObjCInterfaceType() const; | ||||||
2244 | |||||||
2245 | // The following is a convenience method that returns an ObjCObjectPointerType | ||||||
2246 | // for object declared using an interface. | ||||||
2247 | const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; | ||||||
2248 | const ObjCObjectPointerType *getAsObjCQualifiedIdType() const; | ||||||
2249 | const ObjCObjectPointerType *getAsObjCQualifiedClassType() const; | ||||||
2250 | const ObjCObjectType *getAsObjCQualifiedInterfaceType() const; | ||||||
2251 | |||||||
2252 | /// Retrieves the CXXRecordDecl that this type refers to, either | ||||||
2253 | /// because the type is a RecordType or because it is the injected-class-name | ||||||
2254 | /// type of a class template or class template partial specialization. | ||||||
2255 | CXXRecordDecl *getAsCXXRecordDecl() const; | ||||||
2256 | |||||||
2257 | /// Retrieves the RecordDecl this type refers to. | ||||||
2258 | RecordDecl *getAsRecordDecl() const; | ||||||
2259 | |||||||
2260 | /// Retrieves the TagDecl that this type refers to, either | ||||||
2261 | /// because the type is a TagType or because it is the injected-class-name | ||||||
2262 | /// type of a class template or class template partial specialization. | ||||||
2263 | TagDecl *getAsTagDecl() const; | ||||||
2264 | |||||||
2265 | /// If this is a pointer or reference to a RecordType, return the | ||||||
2266 | /// CXXRecordDecl that the type refers to. | ||||||
2267 | /// | ||||||
2268 | /// If this is not a pointer or reference, or the type being pointed to does | ||||||
2269 | /// not refer to a CXXRecordDecl, returns NULL. | ||||||
2270 | const CXXRecordDecl *getPointeeCXXRecordDecl() const; | ||||||
2271 | |||||||
2272 | /// Get the DeducedType whose type will be deduced for a variable with | ||||||
2273 | /// an initializer of this type. This looks through declarators like pointer | ||||||
2274 | /// types, but not through decltype or typedefs. | ||||||
2275 | DeducedType *getContainedDeducedType() const; | ||||||
2276 | |||||||
2277 | /// Get the AutoType whose type will be deduced for a variable with | ||||||
2278 | /// an initializer of this type. This looks through declarators like pointer | ||||||
2279 | /// types, but not through decltype or typedefs. | ||||||
2280 | AutoType *getContainedAutoType() const { | ||||||
2281 | return dyn_cast_or_null<AutoType>(getContainedDeducedType()); | ||||||
2282 | } | ||||||
2283 | |||||||
2284 | /// Determine whether this type was written with a leading 'auto' | ||||||
2285 | /// corresponding to a trailing return type (possibly for a nested | ||||||
2286 | /// function type within a pointer to function type or similar). | ||||||
2287 | bool hasAutoForTrailingReturnType() const; | ||||||
2288 | |||||||
2289 | /// Member-template getAs<specific type>'. Look through sugar for | ||||||
2290 | /// an instance of \<specific type>. This scheme will eventually | ||||||
2291 | /// replace the specific getAsXXXX methods above. | ||||||
2292 | /// | ||||||
2293 | /// There are some specializations of this member template listed | ||||||
2294 | /// immediately following this class. | ||||||
2295 | template <typename T> const T *getAs() const; | ||||||
2296 | |||||||
2297 | /// Member-template getAsAdjusted<specific type>. Look through specific kinds | ||||||
2298 | /// of sugar (parens, attributes, etc) for an instance of \<specific type>. | ||||||
2299 | /// This is used when you need to walk over sugar nodes that represent some | ||||||
2300 | /// kind of type adjustment from a type that was written as a \<specific type> | ||||||
2301 | /// to another type that is still canonically a \<specific type>. | ||||||
2302 | template <typename T> const T *getAsAdjusted() const; | ||||||
2303 | |||||||
2304 | /// A variant of getAs<> for array types which silently discards | ||||||
2305 | /// qualifiers from the outermost type. | ||||||
2306 | const ArrayType *getAsArrayTypeUnsafe() const; | ||||||
2307 | |||||||
2308 | /// Member-template castAs<specific type>. Look through sugar for | ||||||
2309 | /// the underlying instance of \<specific type>. | ||||||
2310 | /// | ||||||
2311 | /// This method has the same relationship to getAs<T> as cast<T> has | ||||||
2312 | /// to dyn_cast<T>; which is to say, the underlying type *must* | ||||||
2313 | /// have the intended type, and this method will never return null. | ||||||
2314 | template <typename T> const T *castAs() const; | ||||||
2315 | |||||||
2316 | /// A variant of castAs<> for array type which silently discards | ||||||
2317 | /// qualifiers from the outermost type. | ||||||
2318 | const ArrayType *castAsArrayTypeUnsafe() const; | ||||||
2319 | |||||||
2320 | /// Determine whether this type had the specified attribute applied to it | ||||||
2321 | /// (looking through top-level type sugar). | ||||||
2322 | bool hasAttr(attr::Kind AK) const; | ||||||
2323 | |||||||
2324 | /// Get the base element type of this type, potentially discarding type | ||||||
2325 | /// qualifiers. This should never be used when type qualifiers | ||||||
2326 | /// are meaningful. | ||||||
2327 | const Type *getBaseElementTypeUnsafe() const; | ||||||
2328 | |||||||
2329 | /// If this is an array type, return the element type of the array, | ||||||
2330 | /// potentially with type qualifiers missing. | ||||||
2331 | /// This should never be used when type qualifiers are meaningful. | ||||||
2332 | const Type *getArrayElementTypeNoTypeQual() const; | ||||||
2333 | |||||||
2334 | /// If this is a pointer type, return the pointee type. | ||||||
2335 | /// If this is an array type, return the array element type. | ||||||
2336 | /// This should never be used when type qualifiers are meaningful. | ||||||
2337 | const Type *getPointeeOrArrayElementType() const; | ||||||
2338 | |||||||
2339 | /// If this is a pointer, ObjC object pointer, or block | ||||||
2340 | /// pointer, this returns the respective pointee. | ||||||
2341 | QualType getPointeeType() const; | ||||||
2342 | |||||||
2343 | /// Return the specified type with any "sugar" removed from the type, | ||||||
2344 | /// removing any typedefs, typeofs, etc., as well as any qualifiers. | ||||||
2345 | const Type *getUnqualifiedDesugaredType() const; | ||||||
2346 | |||||||
2347 | /// More type predicates useful for type checking/promotion | ||||||
2348 | bool isPromotableIntegerType() const; // C99 6.3.1.1p2 | ||||||
2349 | |||||||
2350 | /// Return true if this is an integer type that is | ||||||
2351 | /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], | ||||||
2352 | /// or an enum decl which has a signed representation. | ||||||
2353 | bool isSignedIntegerType() const; | ||||||
2354 | |||||||
2355 | /// Return true if this is an integer type that is | ||||||
2356 | /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], | ||||||
2357 | /// or an enum decl which has an unsigned representation. | ||||||
2358 | bool isUnsignedIntegerType() const; | ||||||
2359 | |||||||
2360 | /// Determines whether this is an integer type that is signed or an | ||||||
2361 | /// enumeration types whose underlying type is a signed integer type. | ||||||
2362 | bool isSignedIntegerOrEnumerationType() const; | ||||||
2363 | |||||||
2364 | /// Determines whether this is an integer type that is unsigned or an | ||||||
2365 | /// enumeration types whose underlying type is a unsigned integer type. | ||||||
2366 | bool isUnsignedIntegerOrEnumerationType() const; | ||||||
2367 | |||||||
2368 | /// Return true if this is a fixed point type according to | ||||||
2369 | /// ISO/IEC JTC1 SC22 WG14 N1169. | ||||||
2370 | bool isFixedPointType() const; | ||||||
2371 | |||||||
2372 | /// Return true if this is a fixed point or integer type. | ||||||
2373 | bool isFixedPointOrIntegerType() const; | ||||||
2374 | |||||||
2375 | /// Return true if this is a saturated fixed point type according to | ||||||
2376 | /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. | ||||||
2377 | bool isSaturatedFixedPointType() const; | ||||||
2378 | |||||||
2379 | /// Return true if this is a saturated fixed point type according to | ||||||
2380 | /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. | ||||||
2381 | bool isUnsaturatedFixedPointType() const; | ||||||
2382 | |||||||
2383 | /// Return true if this is a fixed point type that is signed according | ||||||
2384 | /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated. | ||||||
2385 | bool isSignedFixedPointType() const; | ||||||
2386 | |||||||
2387 | /// Return true if this is a fixed point type that is unsigned according | ||||||
2388 | /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated. | ||||||
2389 | bool isUnsignedFixedPointType() const; | ||||||
2390 | |||||||
2391 | /// Return true if this is not a variable sized type, | ||||||
2392 | /// according to the rules of C99 6.7.5p3. It is not legal to call this on | ||||||
2393 | /// incomplete types. | ||||||
2394 | bool isConstantSizeType() const; | ||||||
2395 | |||||||
2396 | /// Returns true if this type can be represented by some | ||||||
2397 | /// set of type specifiers. | ||||||
2398 | bool isSpecifierType() const; | ||||||
2399 | |||||||
2400 | /// Determine the linkage of this type. | ||||||
2401 | Linkage getLinkage() const; | ||||||
2402 | |||||||
2403 | /// Determine the visibility of this type. | ||||||
2404 | Visibility getVisibility() const { | ||||||
2405 | return getLinkageAndVisibility().getVisibility(); | ||||||
2406 | } | ||||||
2407 | |||||||
2408 | /// Return true if the visibility was explicitly set is the code. | ||||||
2409 | bool isVisibilityExplicit() const { | ||||||
2410 | return getLinkageAndVisibility().isVisibilityExplicit(); | ||||||
2411 | } | ||||||
2412 | |||||||
2413 | /// Determine the linkage and visibility of this type. | ||||||
2414 | LinkageInfo getLinkageAndVisibility() const; | ||||||
2415 | |||||||
2416 | /// True if the computed linkage is valid. Used for consistency | ||||||
2417 | /// checking. Should always return true. | ||||||
2418 | bool isLinkageValid() const; | ||||||
2419 | |||||||
2420 | /// Determine the nullability of the given type. | ||||||
2421 | /// | ||||||
2422 | /// Note that nullability is only captured as sugar within the type | ||||||
2423 | /// system, not as part of the canonical type, so nullability will | ||||||
2424 | /// be lost by canonicalization and desugaring. | ||||||
2425 | Optional<NullabilityKind> getNullability(const ASTContext &context) const; | ||||||
2426 | |||||||
2427 | /// Determine whether the given type can have a nullability | ||||||
2428 | /// specifier applied to it, i.e., if it is any kind of pointer type. | ||||||
2429 | /// | ||||||
2430 | /// \param ResultIfUnknown The value to return if we don't yet know whether | ||||||
2431 | /// this type can have nullability because it is dependent. | ||||||
2432 | bool canHaveNullability(bool ResultIfUnknown = true) const; | ||||||
2433 | |||||||
2434 | /// Retrieve the set of substitutions required when accessing a member | ||||||
2435 | /// of the Objective-C receiver type that is declared in the given context. | ||||||
2436 | /// | ||||||
2437 | /// \c *this is the type of the object we're operating on, e.g., the | ||||||
2438 | /// receiver for a message send or the base of a property access, and is | ||||||
2439 | /// expected to be of some object or object pointer type. | ||||||
2440 | /// | ||||||
2441 | /// \param dc The declaration context for which we are building up a | ||||||
2442 | /// substitution mapping, which should be an Objective-C class, extension, | ||||||
2443 | /// category, or method within. | ||||||
2444 | /// | ||||||
2445 | /// \returns an array of type arguments that can be substituted for | ||||||
2446 | /// the type parameters of the given declaration context in any type described | ||||||
2447 | /// within that context, or an empty optional to indicate that no | ||||||
2448 | /// substitution is required. | ||||||
2449 | Optional<ArrayRef<QualType>> | ||||||
2450 | getObjCSubstitutions(const DeclContext *dc) const; | ||||||
2451 | |||||||
2452 | /// Determines if this is an ObjC interface type that may accept type | ||||||
2453 | /// parameters. | ||||||
2454 | bool acceptsObjCTypeParams() const; | ||||||
2455 | |||||||
2456 | const char *getTypeClassName() const; | ||||||
2457 | |||||||
2458 | QualType getCanonicalTypeInternal() const { | ||||||
2459 | return CanonicalType; | ||||||
2460 | } | ||||||
2461 | |||||||
2462 | CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h | ||||||
2463 | void dump() const; | ||||||
2464 | void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; | ||||||
2465 | }; | ||||||
2466 | |||||||
2467 | /// This will check for a TypedefType by removing any existing sugar | ||||||
2468 | /// until it reaches a TypedefType or a non-sugared type. | ||||||
2469 | template <> const TypedefType *Type::getAs() const; | ||||||
2470 | |||||||
2471 | /// This will check for a TemplateSpecializationType by removing any | ||||||
2472 | /// existing sugar until it reaches a TemplateSpecializationType or a | ||||||
2473 | /// non-sugared type. | ||||||
2474 | template <> const TemplateSpecializationType *Type::getAs() const; | ||||||
2475 | |||||||
2476 | /// This will check for an AttributedType by removing any existing sugar | ||||||
2477 | /// until it reaches an AttributedType or a non-sugared type. | ||||||
2478 | template <> const AttributedType *Type::getAs() const; | ||||||
2479 | |||||||
2480 | // We can do canonical leaf types faster, because we don't have to | ||||||
2481 | // worry about preserving child type decoration. | ||||||
2482 | #define TYPE(Class, Base) | ||||||
2483 | #define LEAF_TYPE(Class) \ | ||||||
2484 | template <> inline const Class##Type *Type::getAs() const { \ | ||||||
2485 | return dyn_cast<Class##Type>(CanonicalType); \ | ||||||
2486 | } \ | ||||||
2487 | template <> inline const Class##Type *Type::castAs() const { \ | ||||||
2488 | return cast<Class##Type>(CanonicalType); \ | ||||||
2489 | } | ||||||
2490 | #include "clang/AST/TypeNodes.inc" | ||||||
2491 | |||||||
2492 | /// This class is used for builtin types like 'int'. Builtin | ||||||
2493 | /// types are always canonical and have a literal name field. | ||||||
2494 | class BuiltinType : public Type { | ||||||
2495 | public: | ||||||
2496 | enum Kind { | ||||||
2497 | // OpenCL image types | ||||||
2498 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id, | ||||||
2499 | #include "clang/Basic/OpenCLImageTypes.def" | ||||||
2500 | // OpenCL extension types | ||||||
2501 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id, | ||||||
2502 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||||
2503 | // SVE Types | ||||||
2504 | #define SVE_TYPE(Name, Id, SingletonId) Id, | ||||||
2505 | #include "clang/Basic/AArch64SVEACLETypes.def" | ||||||
2506 | // PPC MMA Types | ||||||
2507 | #define PPC_VECTOR_TYPE(Name, Id, Size) Id, | ||||||
2508 | #include "clang/Basic/PPCTypes.def" | ||||||
2509 | // RVV Types | ||||||
2510 | #define RVV_TYPE(Name, Id, SingletonId) Id, | ||||||
2511 | #include "clang/Basic/RISCVVTypes.def" | ||||||
2512 | // All other builtin types | ||||||
2513 | #define BUILTIN_TYPE(Id, SingletonId) Id, | ||||||
2514 | #define LAST_BUILTIN_TYPE(Id) LastKind = Id | ||||||
2515 | #include "clang/AST/BuiltinTypes.def" | ||||||
2516 | }; | ||||||
2517 | |||||||
2518 | private: | ||||||
2519 | friend class ASTContext; // ASTContext creates these. | ||||||
2520 | |||||||
2521 | BuiltinType(Kind K) | ||||||
2522 | : Type(Builtin, QualType(), | ||||||
2523 | K == Dependent ? TypeDependence::DependentInstantiation | ||||||
2524 | : TypeDependence::None) { | ||||||
2525 | BuiltinTypeBits.Kind = K; | ||||||
2526 | } | ||||||
2527 | |||||||
2528 | public: | ||||||
2529 | Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); } | ||||||
2530 | StringRef getName(const PrintingPolicy &Policy) const; | ||||||
2531 | |||||||
2532 | const char *getNameAsCString(const PrintingPolicy &Policy) const { | ||||||
2533 | // The StringRef is null-terminated. | ||||||
2534 | StringRef str = getName(Policy); | ||||||
2535 | assert(!str.empty() && str.data()[str.size()] == '\0')(static_cast <bool> (!str.empty() && str.data() [str.size()] == '\0') ? void (0) : __assert_fail ("!str.empty() && str.data()[str.size()] == '\\0'" , "clang/include/clang/AST/Type.h", 2535, __extension__ __PRETTY_FUNCTION__ )); | ||||||
2536 | return str.data(); | ||||||
2537 | } | ||||||
2538 | |||||||
2539 | bool isSugared() const { return false; } | ||||||
2540 | QualType desugar() const { return QualType(this, 0); } | ||||||
2541 | |||||||
2542 | bool isInteger() const { | ||||||
2543 | return getKind() >= Bool && getKind() <= Int128; | ||||||
2544 | } | ||||||
2545 | |||||||
2546 | bool isSignedInteger() const { | ||||||
2547 | return getKind() >= Char_S && getKind() <= Int128; | ||||||
2548 | } | ||||||
2549 | |||||||
2550 | bool isUnsignedInteger() const { | ||||||
2551 | return getKind() >= Bool && getKind() <= UInt128; | ||||||
2552 | } | ||||||
2553 | |||||||
2554 | bool isFloatingPoint() const { | ||||||
2555 | return getKind() >= Half && getKind() <= Ibm128; | ||||||
2556 | } | ||||||
2557 | |||||||
2558 | /// Determines whether the given kind corresponds to a placeholder type. | ||||||
2559 | static bool isPlaceholderTypeKind(Kind K) { | ||||||
2560 | return K >= Overload; | ||||||
2561 | } | ||||||
2562 | |||||||
2563 | /// Determines whether this type is a placeholder type, i.e. a type | ||||||
2564 | /// which cannot appear in arbitrary positions in a fully-formed | ||||||
2565 | /// expression. | ||||||
2566 | bool isPlaceholderType() const { | ||||||
2567 | return isPlaceholderTypeKind(getKind()); | ||||||
2568 | } | ||||||
2569 | |||||||
2570 | /// Determines whether this type is a placeholder type other than | ||||||
2571 | /// Overload. Most placeholder types require only syntactic | ||||||
2572 | /// information about their context in order to be resolved (e.g. | ||||||
2573 | /// whether it is a call expression), which means they can (and | ||||||
2574 | /// should) be resolved in an earlier "phase" of analysis. | ||||||
2575 | /// Overload expressions sometimes pick up further information | ||||||
2576 | /// from their context, like whether the context expects a | ||||||
2577 | /// specific function-pointer type, and so frequently need | ||||||
2578 | /// special treatment. | ||||||
2579 | bool isNonOverloadPlaceholderType() const { | ||||||
2580 | return getKind() > Overload; | ||||||
2581 | } | ||||||
2582 | |||||||
2583 | static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } | ||||||
2584 | }; | ||||||
2585 | |||||||
2586 | /// Complex values, per C99 6.2.5p11. This supports the C99 complex | ||||||
2587 | /// types (_Complex float etc) as well as the GCC integer complex extensions. | ||||||
2588 | class ComplexType : public Type, public llvm::FoldingSetNode { | ||||||
2589 | friend class ASTContext; // ASTContext creates these. | ||||||
2590 | |||||||
2591 | QualType ElementType; | ||||||
2592 | |||||||
2593 | ComplexType(QualType Element, QualType CanonicalPtr) | ||||||
2594 | : Type(Complex, CanonicalPtr, Element->getDependence()), | ||||||
2595 | ElementType(Element) {} | ||||||
2596 | |||||||
2597 | public: | ||||||
2598 | QualType getElementType() const { return ElementType; } | ||||||
2599 | |||||||
2600 | bool isSugared() const { return false; } | ||||||
2601 | QualType desugar() const { return QualType(this, 0); } | ||||||
2602 | |||||||
2603 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2604 | Profile(ID, getElementType()); | ||||||
2605 | } | ||||||
2606 | |||||||
2607 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) { | ||||||
2608 | ID.AddPointer(Element.getAsOpaquePtr()); | ||||||
2609 | } | ||||||
2610 | |||||||
2611 | static bool classof(const Type *T) { return T->getTypeClass() == Complex; } | ||||||
2612 | }; | ||||||
2613 | |||||||
2614 | /// Sugar for parentheses used when specifying types. | ||||||
2615 | class ParenType : public Type, public llvm::FoldingSetNode { | ||||||
2616 | friend class ASTContext; // ASTContext creates these. | ||||||
2617 | |||||||
2618 | QualType Inner; | ||||||
2619 | |||||||
2620 | ParenType(QualType InnerType, QualType CanonType) | ||||||
2621 | : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {} | ||||||
2622 | |||||||
2623 | public: | ||||||
2624 | QualType getInnerType() const { return Inner; } | ||||||
2625 | |||||||
2626 | bool isSugared() const { return true; } | ||||||
2627 | QualType desugar() const { return getInnerType(); } | ||||||
2628 | |||||||
2629 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2630 | Profile(ID, getInnerType()); | ||||||
2631 | } | ||||||
2632 | |||||||
2633 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) { | ||||||
2634 | Inner.Profile(ID); | ||||||
2635 | } | ||||||
2636 | |||||||
2637 | static bool classof(const Type *T) { return T->getTypeClass() == Paren; } | ||||||
2638 | }; | ||||||
2639 | |||||||
2640 | /// PointerType - C99 6.7.5.1 - Pointer Declarators. | ||||||
2641 | class PointerType : public Type, public llvm::FoldingSetNode { | ||||||
2642 | friend class ASTContext; // ASTContext creates these. | ||||||
2643 | |||||||
2644 | QualType PointeeType; | ||||||
2645 | |||||||
2646 | PointerType(QualType Pointee, QualType CanonicalPtr) | ||||||
2647 | : Type(Pointer, CanonicalPtr, Pointee->getDependence()), | ||||||
2648 | PointeeType(Pointee) {} | ||||||
2649 | |||||||
2650 | public: | ||||||
2651 | QualType getPointeeType() const { return PointeeType; } | ||||||
2652 | |||||||
2653 | bool isSugared() const { return false; } | ||||||
2654 | QualType desugar() const { return QualType(this, 0); } | ||||||
2655 | |||||||
2656 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2657 | Profile(ID, getPointeeType()); | ||||||
2658 | } | ||||||
2659 | |||||||
2660 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { | ||||||
2661 | ID.AddPointer(Pointee.getAsOpaquePtr()); | ||||||
2662 | } | ||||||
2663 | |||||||
2664 | static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } | ||||||
2665 | }; | ||||||
2666 | |||||||
2667 | /// Represents a type which was implicitly adjusted by the semantic | ||||||
2668 | /// engine for arbitrary reasons. For example, array and function types can | ||||||
2669 | /// decay, and function types can have their calling conventions adjusted. | ||||||
2670 | class AdjustedType : public Type, public llvm::FoldingSetNode { | ||||||
2671 | QualType OriginalTy; | ||||||
2672 | QualType AdjustedTy; | ||||||
2673 | |||||||
2674 | protected: | ||||||
2675 | friend class ASTContext; // ASTContext creates these. | ||||||
2676 | |||||||
2677 | AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy, | ||||||
2678 | QualType CanonicalPtr) | ||||||
2679 | : Type(TC, CanonicalPtr, OriginalTy->getDependence()), | ||||||
2680 | OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {} | ||||||
2681 | |||||||
2682 | public: | ||||||
2683 | QualType getOriginalType() const { return OriginalTy; } | ||||||
2684 | QualType getAdjustedType() const { return AdjustedTy; } | ||||||
2685 | |||||||
2686 | bool isSugared() const { return true; } | ||||||
2687 | QualType desugar() const { return AdjustedTy; } | ||||||
2688 | |||||||
2689 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2690 | Profile(ID, OriginalTy, AdjustedTy); | ||||||
2691 | } | ||||||
2692 | |||||||
2693 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) { | ||||||
2694 | ID.AddPointer(Orig.getAsOpaquePtr()); | ||||||
2695 | ID.AddPointer(New.getAsOpaquePtr()); | ||||||
2696 | } | ||||||
2697 | |||||||
2698 | static bool classof(const Type *T) { | ||||||
2699 | return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed; | ||||||
2700 | } | ||||||
2701 | }; | ||||||
2702 | |||||||
2703 | /// Represents a pointer type decayed from an array or function type. | ||||||
2704 | class DecayedType : public AdjustedType { | ||||||
2705 | friend class ASTContext; // ASTContext creates these. | ||||||
2706 | |||||||
2707 | inline | ||||||
2708 | DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical); | ||||||
2709 | |||||||
2710 | public: | ||||||
2711 | QualType getDecayedType() const { return getAdjustedType(); } | ||||||
2712 | |||||||
2713 | inline QualType getPointeeType() const; | ||||||
2714 | |||||||
2715 | static bool classof(const Type *T) { return T->getTypeClass() == Decayed; } | ||||||
2716 | }; | ||||||
2717 | |||||||
2718 | /// Pointer to a block type. | ||||||
2719 | /// This type is to represent types syntactically represented as | ||||||
2720 | /// "void (^)(int)", etc. Pointee is required to always be a function type. | ||||||
2721 | class BlockPointerType : public Type, public llvm::FoldingSetNode { | ||||||
2722 | friend class ASTContext; // ASTContext creates these. | ||||||
2723 | |||||||
2724 | // Block is some kind of pointer type | ||||||
2725 | QualType PointeeType; | ||||||
2726 | |||||||
2727 | BlockPointerType(QualType Pointee, QualType CanonicalCls) | ||||||
2728 | : Type(BlockPointer, CanonicalCls, Pointee->getDependence()), | ||||||
2729 | PointeeType(Pointee) {} | ||||||
2730 | |||||||
2731 | public: | ||||||
2732 | // Get the pointee type. Pointee is required to always be a function type. | ||||||
2733 | QualType getPointeeType() const { return PointeeType; } | ||||||
2734 | |||||||
2735 | bool isSugared() const { return false; } | ||||||
2736 | QualType desugar() const { return QualType(this, 0); } | ||||||
2737 | |||||||
2738 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2739 | Profile(ID, getPointeeType()); | ||||||
2740 | } | ||||||
2741 | |||||||
2742 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { | ||||||
2743 | ID.AddPointer(Pointee.getAsOpaquePtr()); | ||||||
2744 | } | ||||||
2745 | |||||||
2746 | static bool classof(const Type *T) { | ||||||
2747 | return T->getTypeClass() == BlockPointer; | ||||||
2748 | } | ||||||
2749 | }; | ||||||
2750 | |||||||
2751 | /// Base for LValueReferenceType and RValueReferenceType | ||||||
2752 | class ReferenceType : public Type, public llvm::FoldingSetNode { | ||||||
2753 | QualType PointeeType; | ||||||
2754 | |||||||
2755 | protected: | ||||||
2756 | ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, | ||||||
2757 | bool SpelledAsLValue) | ||||||
2758 | : Type(tc, CanonicalRef, Referencee->getDependence()), | ||||||
2759 | PointeeType(Referencee) { | ||||||
2760 | ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; | ||||||
2761 | ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); | ||||||
2762 | } | ||||||
2763 | |||||||
2764 | public: | ||||||
2765 | bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; } | ||||||
2766 | bool isInnerRef() const { return ReferenceTypeBits.InnerRef; } | ||||||
2767 | |||||||
2768 | QualType getPointeeTypeAsWritten() const { return PointeeType; } | ||||||
2769 | |||||||
2770 | QualType getPointeeType() const { | ||||||
2771 | // FIXME: this might strip inner qualifiers; okay? | ||||||
2772 | const ReferenceType *T = this; | ||||||
2773 | while (T->isInnerRef()) | ||||||
2774 | T = T->PointeeType->castAs<ReferenceType>(); | ||||||
2775 | return T->PointeeType; | ||||||
2776 | } | ||||||
2777 | |||||||
2778 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2779 | Profile(ID, PointeeType, isSpelledAsLValue()); | ||||||
2780 | } | ||||||
2781 | |||||||
2782 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
2783 | QualType Referencee, | ||||||
2784 | bool SpelledAsLValue) { | ||||||
2785 | ID.AddPointer(Referencee.getAsOpaquePtr()); | ||||||
2786 | ID.AddBoolean(SpelledAsLValue); | ||||||
2787 | } | ||||||
2788 | |||||||
2789 | static bool classof(const Type *T) { | ||||||
2790 | return T->getTypeClass() == LValueReference || | ||||||
2791 | T->getTypeClass() == RValueReference; | ||||||
2792 | } | ||||||
2793 | }; | ||||||
2794 | |||||||
2795 | /// An lvalue reference type, per C++11 [dcl.ref]. | ||||||
2796 | class LValueReferenceType : public ReferenceType { | ||||||
2797 | friend class ASTContext; // ASTContext creates these | ||||||
2798 | |||||||
2799 | LValueReferenceType(QualType Referencee, QualType CanonicalRef, | ||||||
2800 | bool SpelledAsLValue) | ||||||
2801 | : ReferenceType(LValueReference, Referencee, CanonicalRef, | ||||||
2802 | SpelledAsLValue) {} | ||||||
2803 | |||||||
2804 | public: | ||||||
2805 | bool isSugared() const { return false; } | ||||||
2806 | QualType desugar() const { return QualType(this, 0); } | ||||||
2807 | |||||||
2808 | static bool classof(const Type *T) { | ||||||
2809 | return T->getTypeClass() == LValueReference; | ||||||
2810 | } | ||||||
2811 | }; | ||||||
2812 | |||||||
2813 | /// An rvalue reference type, per C++11 [dcl.ref]. | ||||||
2814 | class RValueReferenceType : public ReferenceType { | ||||||
2815 | friend class ASTContext; // ASTContext creates these | ||||||
2816 | |||||||
2817 | RValueReferenceType(QualType Referencee, QualType CanonicalRef) | ||||||
2818 | : ReferenceType(RValueReference, Referencee, CanonicalRef, false) {} | ||||||
2819 | |||||||
2820 | public: | ||||||
2821 | bool isSugared() const { return false; } | ||||||
2822 | QualType desugar() const { return QualType(this, 0); } | ||||||
2823 | |||||||
2824 | static bool classof(const Type *T) { | ||||||
2825 | return T->getTypeClass() == RValueReference; | ||||||
2826 | } | ||||||
2827 | }; | ||||||
2828 | |||||||
2829 | /// A pointer to member type per C++ 8.3.3 - Pointers to members. | ||||||
2830 | /// | ||||||
2831 | /// This includes both pointers to data members and pointer to member functions. | ||||||
2832 | class MemberPointerType : public Type, public llvm::FoldingSetNode { | ||||||
2833 | friend class ASTContext; // ASTContext creates these. | ||||||
2834 | |||||||
2835 | QualType PointeeType; | ||||||
2836 | |||||||
2837 | /// The class of which the pointee is a member. Must ultimately be a | ||||||
2838 | /// RecordType, but could be a typedef or a template parameter too. | ||||||
2839 | const Type *Class; | ||||||
2840 | |||||||
2841 | MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) | ||||||
2842 | : Type(MemberPointer, CanonicalPtr, | ||||||
2843 | (Cls->getDependence() & ~TypeDependence::VariablyModified) | | ||||||
2844 | Pointee->getDependence()), | ||||||
2845 | PointeeType(Pointee), Class(Cls) {} | ||||||
2846 | |||||||
2847 | public: | ||||||
2848 | QualType getPointeeType() const { return PointeeType; } | ||||||
2849 | |||||||
2850 | /// Returns true if the member type (i.e. the pointee type) is a | ||||||
2851 | /// function type rather than a data-member type. | ||||||
2852 | bool isMemberFunctionPointer() const { | ||||||
2853 | return PointeeType->isFunctionProtoType(); | ||||||
2854 | } | ||||||
2855 | |||||||
2856 | /// Returns true if the member type (i.e. the pointee type) is a | ||||||
2857 | /// data type rather than a function type. | ||||||
2858 | bool isMemberDataPointer() const { | ||||||
2859 | return !PointeeType->isFunctionProtoType(); | ||||||
2860 | } | ||||||
2861 | |||||||
2862 | const Type *getClass() const { return Class; } | ||||||
2863 | CXXRecordDecl *getMostRecentCXXRecordDecl() const; | ||||||
2864 | |||||||
2865 | bool isSugared() const { return false; } | ||||||
2866 | QualType desugar() const { return QualType(this, 0); } | ||||||
2867 | |||||||
2868 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
2869 | Profile(ID, getPointeeType(), getClass()); | ||||||
2870 | } | ||||||
2871 | |||||||
2872 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee, | ||||||
2873 | const Type *Class) { | ||||||
2874 | ID.AddPointer(Pointee.getAsOpaquePtr()); | ||||||
2875 | ID.AddPointer(Class); | ||||||
2876 | } | ||||||
2877 | |||||||
2878 | static bool classof(const Type *T) { | ||||||
2879 | return T->getTypeClass() == MemberPointer; | ||||||
2880 | } | ||||||
2881 | }; | ||||||
2882 | |||||||
2883 | /// Represents an array type, per C99 6.7.5.2 - Array Declarators. | ||||||
2884 | class ArrayType : public Type, public llvm::FoldingSetNode { | ||||||
2885 | public: | ||||||
2886 | /// Capture whether this is a normal array (e.g. int X[4]) | ||||||
2887 | /// an array with a static size (e.g. int X[static 4]), or an array | ||||||
2888 | /// with a star size (e.g. int X[*]). | ||||||
2889 | /// 'static' is only allowed on function parameters. | ||||||
2890 | enum ArraySizeModifier { | ||||||
2891 | Normal, Static, Star | ||||||
2892 | }; | ||||||
2893 | |||||||
2894 | private: | ||||||
2895 | /// The element type of the array. | ||||||
2896 | QualType ElementType; | ||||||
2897 | |||||||
2898 | protected: | ||||||
2899 | friend class ASTContext; // ASTContext creates these. | ||||||
2900 | |||||||
2901 | ArrayType(TypeClass tc, QualType et, QualType can, ArraySizeModifier sm, | ||||||
2902 | unsigned tq, const Expr *sz = nullptr); | ||||||
2903 | |||||||
2904 | public: | ||||||
2905 | QualType getElementType() const { return ElementType; } | ||||||
2906 | |||||||
2907 | ArraySizeModifier getSizeModifier() const { | ||||||
2908 | return ArraySizeModifier(ArrayTypeBits.SizeModifier); | ||||||
2909 | } | ||||||
2910 | |||||||
2911 | Qualifiers getIndexTypeQualifiers() const { | ||||||
2912 | return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers()); | ||||||
2913 | } | ||||||
2914 | |||||||
2915 | unsigned getIndexTypeCVRQualifiers() const { | ||||||
2916 | return ArrayTypeBits.IndexTypeQuals; | ||||||
2917 | } | ||||||
2918 | |||||||
2919 | static bool classof(const Type *T) { | ||||||
2920 | return T->getTypeClass() == ConstantArray || | ||||||
2921 | T->getTypeClass() == VariableArray || | ||||||
2922 | T->getTypeClass() == IncompleteArray || | ||||||
2923 | T->getTypeClass() == DependentSizedArray; | ||||||
2924 | } | ||||||
2925 | }; | ||||||
2926 | |||||||
2927 | /// Represents the canonical version of C arrays with a specified constant size. | ||||||
2928 | /// For example, the canonical type for 'int A[4 + 4*100]' is a | ||||||
2929 | /// ConstantArrayType where the element type is 'int' and the size is 404. | ||||||
2930 | class ConstantArrayType final | ||||||
2931 | : public ArrayType, | ||||||
2932 | private llvm::TrailingObjects<ConstantArrayType, const Expr *> { | ||||||
2933 | friend class ASTContext; // ASTContext creates these. | ||||||
2934 | friend TrailingObjects; | ||||||
2935 | |||||||
2936 | llvm::APInt Size; // Allows us to unique the type. | ||||||
2937 | |||||||
2938 | ConstantArrayType(QualType et, QualType can, const llvm::APInt &size, | ||||||
2939 | const Expr *sz, ArraySizeModifier sm, unsigned tq) | ||||||
2940 | : ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) { | ||||||
2941 | ConstantArrayTypeBits.HasStoredSizeExpr = sz != nullptr; | ||||||
2942 | if (ConstantArrayTypeBits.HasStoredSizeExpr) { | ||||||
2943 | assert(!can.isNull() && "canonical constant array should not have size")(static_cast <bool> (!can.isNull() && "canonical constant array should not have size" ) ? void (0) : __assert_fail ("!can.isNull() && \"canonical constant array should not have size\"" , "clang/include/clang/AST/Type.h", 2943, __extension__ __PRETTY_FUNCTION__ )); | ||||||
2944 | *getTrailingObjects<const Expr*>() = sz; | ||||||
2945 | } | ||||||
2946 | } | ||||||
2947 | |||||||
2948 | unsigned numTrailingObjects(OverloadToken<const Expr*>) const { | ||||||
2949 | return ConstantArrayTypeBits.HasStoredSizeExpr; | ||||||
2950 | } | ||||||
2951 | |||||||
2952 | public: | ||||||
2953 | const llvm::APInt &getSize() const { return Size; } | ||||||
2954 | const Expr *getSizeExpr() const { | ||||||
2955 | return ConstantArrayTypeBits.HasStoredSizeExpr | ||||||
2956 | ? *getTrailingObjects<const Expr *>() | ||||||
2957 | : nullptr; | ||||||
2958 | } | ||||||
2959 | bool isSugared() const { return false; } | ||||||
2960 | QualType desugar() const { return QualType(this, 0); } | ||||||
2961 | |||||||
2962 | /// Determine the number of bits required to address a member of | ||||||
2963 | // an array with the given element type and number of elements. | ||||||
2964 | static unsigned getNumAddressingBits(const ASTContext &Context, | ||||||
2965 | QualType ElementType, | ||||||
2966 | const llvm::APInt &NumElements); | ||||||
2967 | |||||||
2968 | /// Determine the maximum number of active bits that an array's size | ||||||
2969 | /// can require, which limits the maximum size of the array. | ||||||
2970 | static unsigned getMaxSizeBits(const ASTContext &Context); | ||||||
2971 | |||||||
2972 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { | ||||||
2973 | Profile(ID, Ctx, getElementType(), getSize(), getSizeExpr(), | ||||||
2974 | getSizeModifier(), getIndexTypeCVRQualifiers()); | ||||||
2975 | } | ||||||
2976 | |||||||
2977 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx, | ||||||
2978 | QualType ET, const llvm::APInt &ArraySize, | ||||||
2979 | const Expr *SizeExpr, ArraySizeModifier SizeMod, | ||||||
2980 | unsigned TypeQuals); | ||||||
2981 | |||||||
2982 | static bool classof(const Type *T) { | ||||||
2983 | return T->getTypeClass() == ConstantArray; | ||||||
2984 | } | ||||||
2985 | }; | ||||||
2986 | |||||||
2987 | /// Represents a C array with an unspecified size. For example 'int A[]' has | ||||||
2988 | /// an IncompleteArrayType where the element type is 'int' and the size is | ||||||
2989 | /// unspecified. | ||||||
2990 | class IncompleteArrayType : public ArrayType { | ||||||
2991 | friend class ASTContext; // ASTContext creates these. | ||||||
2992 | |||||||
2993 | IncompleteArrayType(QualType et, QualType can, | ||||||
2994 | ArraySizeModifier sm, unsigned tq) | ||||||
2995 | : ArrayType(IncompleteArray, et, can, sm, tq) {} | ||||||
2996 | |||||||
2997 | public: | ||||||
2998 | friend class StmtIteratorBase; | ||||||
2999 | |||||||
3000 | bool isSugared() const { return false; } | ||||||
3001 | QualType desugar() const { return QualType(this, 0); } | ||||||
3002 | |||||||
3003 | static bool classof(const Type *T) { | ||||||
3004 | return T->getTypeClass() == IncompleteArray; | ||||||
3005 | } | ||||||
3006 | |||||||
3007 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3008 | Profile(ID, getElementType(), getSizeModifier(), | ||||||
3009 | getIndexTypeCVRQualifiers()); | ||||||
3010 | } | ||||||
3011 | |||||||
3012 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, | ||||||
3013 | ArraySizeModifier SizeMod, unsigned TypeQuals) { | ||||||
3014 | ID.AddPointer(ET.getAsOpaquePtr()); | ||||||
3015 | ID.AddInteger(SizeMod); | ||||||
3016 | ID.AddInteger(TypeQuals); | ||||||
3017 | } | ||||||
3018 | }; | ||||||
3019 | |||||||
3020 | /// Represents a C array with a specified size that is not an | ||||||
3021 | /// integer-constant-expression. For example, 'int s[x+foo()]'. | ||||||
3022 | /// Since the size expression is an arbitrary expression, we store it as such. | ||||||
3023 | /// | ||||||
3024 | /// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and | ||||||
3025 | /// should not be: two lexically equivalent variable array types could mean | ||||||
3026 | /// different things, for example, these variables do not have the same type | ||||||
3027 | /// dynamically: | ||||||
3028 | /// | ||||||
3029 | /// void foo(int x) { | ||||||
3030 | /// int Y[x]; | ||||||
3031 | /// ++x; | ||||||
3032 | /// int Z[x]; | ||||||
3033 | /// } | ||||||
3034 | class VariableArrayType : public ArrayType { | ||||||
3035 | friend class ASTContext; // ASTContext creates these. | ||||||
3036 | |||||||
3037 | /// An assignment-expression. VLA's are only permitted within | ||||||
3038 | /// a function block. | ||||||
3039 | Stmt *SizeExpr; | ||||||
3040 | |||||||
3041 | /// The range spanned by the left and right array brackets. | ||||||
3042 | SourceRange Brackets; | ||||||
3043 | |||||||
3044 | VariableArrayType(QualType et, QualType can, Expr *e, | ||||||
3045 | ArraySizeModifier sm, unsigned tq, | ||||||
3046 | SourceRange brackets) | ||||||
3047 | : ArrayType(VariableArray, et, can, sm, tq, e), | ||||||
3048 | SizeExpr((Stmt*) e), Brackets(brackets) {} | ||||||
3049 | |||||||
3050 | public: | ||||||
3051 | friend class StmtIteratorBase; | ||||||
3052 | |||||||
3053 | Expr *getSizeExpr() const { | ||||||
3054 | // We use C-style casts instead of cast<> here because we do not wish | ||||||
3055 | // to have a dependency of Type.h on Stmt.h/Expr.h. | ||||||
3056 | return (Expr*) SizeExpr; | ||||||
3057 | } | ||||||
3058 | |||||||
3059 | SourceRange getBracketsRange() const { return Brackets; } | ||||||
3060 | SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } | ||||||
3061 | SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } | ||||||
3062 | |||||||
3063 | bool isSugared() const { return false; } | ||||||
3064 | QualType desugar() const { return QualType(this, 0); } | ||||||
3065 | |||||||
3066 | static bool classof(const Type *T) { | ||||||
3067 | return T->getTypeClass() == VariableArray; | ||||||
3068 | } | ||||||
3069 | |||||||
3070 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3071 | llvm_unreachable("Cannot unique VariableArrayTypes.")::llvm::llvm_unreachable_internal("Cannot unique VariableArrayTypes." , "clang/include/clang/AST/Type.h", 3071); | ||||||
3072 | } | ||||||
3073 | }; | ||||||
3074 | |||||||
3075 | /// Represents an array type in C++ whose size is a value-dependent expression. | ||||||
3076 | /// | ||||||
3077 | /// For example: | ||||||
3078 | /// \code | ||||||
3079 | /// template<typename T, int Size> | ||||||
3080 | /// class array { | ||||||
3081 | /// T data[Size]; | ||||||
3082 | /// }; | ||||||
3083 | /// \endcode | ||||||
3084 | /// | ||||||
3085 | /// For these types, we won't actually know what the array bound is | ||||||
3086 | /// until template instantiation occurs, at which point this will | ||||||
3087 | /// become either a ConstantArrayType or a VariableArrayType. | ||||||
3088 | class DependentSizedArrayType : public ArrayType { | ||||||
3089 | friend class ASTContext; // ASTContext creates these. | ||||||
3090 | |||||||
3091 | const ASTContext &Context; | ||||||
3092 | |||||||
3093 | /// An assignment expression that will instantiate to the | ||||||
3094 | /// size of the array. | ||||||
3095 | /// | ||||||
3096 | /// The expression itself might be null, in which case the array | ||||||
3097 | /// type will have its size deduced from an initializer. | ||||||
3098 | Stmt *SizeExpr; | ||||||
3099 | |||||||
3100 | /// The range spanned by the left and right array brackets. | ||||||
3101 | SourceRange Brackets; | ||||||
3102 | |||||||
3103 | DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can, | ||||||
3104 | Expr *e, ArraySizeModifier sm, unsigned tq, | ||||||
3105 | SourceRange brackets); | ||||||
3106 | |||||||
3107 | public: | ||||||
3108 | friend class StmtIteratorBase; | ||||||
3109 | |||||||
3110 | Expr *getSizeExpr() const { | ||||||
3111 | // We use C-style casts instead of cast<> here because we do not wish | ||||||
3112 | // to have a dependency of Type.h on Stmt.h/Expr.h. | ||||||
3113 | return (Expr*) SizeExpr; | ||||||
3114 | } | ||||||
3115 | |||||||
3116 | SourceRange getBracketsRange() const { return Brackets; } | ||||||
3117 | SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } | ||||||
3118 | SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } | ||||||
3119 | |||||||
3120 | bool isSugared() const { return false; } | ||||||
3121 | QualType desugar() const { return QualType(this, 0); } | ||||||
3122 | |||||||
3123 | static bool classof(const Type *T) { | ||||||
3124 | return T->getTypeClass() == DependentSizedArray; | ||||||
3125 | } | ||||||
3126 | |||||||
3127 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3128 | Profile(ID, Context, getElementType(), | ||||||
3129 | getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr()); | ||||||
3130 | } | ||||||
3131 | |||||||
3132 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
3133 | QualType ET, ArraySizeModifier SizeMod, | ||||||
3134 | unsigned TypeQuals, Expr *E); | ||||||
3135 | }; | ||||||
3136 | |||||||
3137 | /// Represents an extended address space qualifier where the input address space | ||||||
3138 | /// value is dependent. Non-dependent address spaces are not represented with a | ||||||
3139 | /// special Type subclass; they are stored on an ExtQuals node as part of a QualType. | ||||||
3140 | /// | ||||||
3141 | /// For example: | ||||||
3142 | /// \code | ||||||
3143 | /// template<typename T, int AddrSpace> | ||||||
3144 | /// class AddressSpace { | ||||||
3145 | /// typedef T __attribute__((address_space(AddrSpace))) type; | ||||||
3146 | /// } | ||||||
3147 | /// \endcode | ||||||
3148 | class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode { | ||||||
3149 | friend class ASTContext; | ||||||
3150 | |||||||
3151 | const ASTContext &Context; | ||||||
3152 | Expr *AddrSpaceExpr; | ||||||
3153 | QualType PointeeType; | ||||||
3154 | SourceLocation loc; | ||||||
3155 | |||||||
3156 | DependentAddressSpaceType(const ASTContext &Context, QualType PointeeType, | ||||||
3157 | QualType can, Expr *AddrSpaceExpr, | ||||||
3158 | SourceLocation loc); | ||||||
3159 | |||||||
3160 | public: | ||||||
3161 | Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; } | ||||||
3162 | QualType getPointeeType() const { return PointeeType; } | ||||||
3163 | SourceLocation getAttributeLoc() const { return loc; } | ||||||
3164 | |||||||
3165 | bool isSugared() const { return false; } | ||||||
3166 | QualType desugar() const { return QualType(this, 0); } | ||||||
3167 | |||||||
3168 | static bool classof(const Type *T) { | ||||||
3169 | return T->getTypeClass() == DependentAddressSpace; | ||||||
3170 | } | ||||||
3171 | |||||||
3172 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3173 | Profile(ID, Context, getPointeeType(), getAddrSpaceExpr()); | ||||||
3174 | } | ||||||
3175 | |||||||
3176 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
3177 | QualType PointeeType, Expr *AddrSpaceExpr); | ||||||
3178 | }; | ||||||
3179 | |||||||
3180 | /// Represents an extended vector type where either the type or size is | ||||||
3181 | /// dependent. | ||||||
3182 | /// | ||||||
3183 | /// For example: | ||||||
3184 | /// \code | ||||||
3185 | /// template<typename T, int Size> | ||||||
3186 | /// class vector { | ||||||
3187 | /// typedef T __attribute__((ext_vector_type(Size))) type; | ||||||
3188 | /// } | ||||||
3189 | /// \endcode | ||||||
3190 | class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode { | ||||||
3191 | friend class ASTContext; | ||||||
3192 | |||||||
3193 | const ASTContext &Context; | ||||||
3194 | Expr *SizeExpr; | ||||||
3195 | |||||||
3196 | /// The element type of the array. | ||||||
3197 | QualType ElementType; | ||||||
3198 | |||||||
3199 | SourceLocation loc; | ||||||
3200 | |||||||
3201 | DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType, | ||||||
3202 | QualType can, Expr *SizeExpr, SourceLocation loc); | ||||||
3203 | |||||||
3204 | public: | ||||||
3205 | Expr *getSizeExpr() const { return SizeExpr; } | ||||||
3206 | QualType getElementType() const { return ElementType; } | ||||||
3207 | SourceLocation getAttributeLoc() const { return loc; } | ||||||
3208 | |||||||
3209 | bool isSugared() const { return false; } | ||||||
3210 | QualType desugar() const { return QualType(this, 0); } | ||||||
3211 | |||||||
3212 | static bool classof(const Type *T) { | ||||||
3213 | return T->getTypeClass() == DependentSizedExtVector; | ||||||
3214 | } | ||||||
3215 | |||||||
3216 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3217 | Profile(ID, Context, getElementType(), getSizeExpr()); | ||||||
3218 | } | ||||||
3219 | |||||||
3220 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
3221 | QualType ElementType, Expr *SizeExpr); | ||||||
3222 | }; | ||||||
3223 | |||||||
3224 | |||||||
3225 | /// Represents a GCC generic vector type. This type is created using | ||||||
3226 | /// __attribute__((vector_size(n)), where "n" specifies the vector size in | ||||||
3227 | /// bytes; or from an Altivec __vector or vector declaration. | ||||||
3228 | /// Since the constructor takes the number of vector elements, the | ||||||
3229 | /// client is responsible for converting the size into the number of elements. | ||||||
3230 | class VectorType : public Type, public llvm::FoldingSetNode { | ||||||
3231 | public: | ||||||
3232 | enum VectorKind { | ||||||
3233 | /// not a target-specific vector type | ||||||
3234 | GenericVector, | ||||||
3235 | |||||||
3236 | /// is AltiVec vector | ||||||
3237 | AltiVecVector, | ||||||
3238 | |||||||
3239 | /// is AltiVec 'vector Pixel' | ||||||
3240 | AltiVecPixel, | ||||||
3241 | |||||||
3242 | /// is AltiVec 'vector bool ...' | ||||||
3243 | AltiVecBool, | ||||||
3244 | |||||||
3245 | /// is ARM Neon vector | ||||||
3246 | NeonVector, | ||||||
3247 | |||||||
3248 | /// is ARM Neon polynomial vector | ||||||
3249 | NeonPolyVector, | ||||||
3250 | |||||||
3251 | /// is AArch64 SVE fixed-length data vector | ||||||
3252 | SveFixedLengthDataVector, | ||||||
3253 | |||||||
3254 | /// is AArch64 SVE fixed-length predicate vector | ||||||
3255 | SveFixedLengthPredicateVector | ||||||
3256 | }; | ||||||
3257 | |||||||
3258 | protected: | ||||||
3259 | friend class ASTContext; // ASTContext creates these. | ||||||
3260 | |||||||
3261 | /// The element type of the vector. | ||||||
3262 | QualType ElementType; | ||||||
3263 | |||||||
3264 | VectorType(QualType vecType, unsigned nElements, QualType canonType, | ||||||
3265 | VectorKind vecKind); | ||||||
3266 | |||||||
3267 | VectorType(TypeClass tc, QualType vecType, unsigned nElements, | ||||||
3268 | QualType canonType, VectorKind vecKind); | ||||||
3269 | |||||||
3270 | public: | ||||||
3271 | QualType getElementType() const { return ElementType; } | ||||||
3272 | unsigned getNumElements() const { return VectorTypeBits.NumElements; } | ||||||
3273 | |||||||
3274 | bool isSugared() const { return false; } | ||||||
3275 | QualType desugar() const { return QualType(this, 0); } | ||||||
3276 | |||||||
3277 | VectorKind getVectorKind() const { | ||||||
3278 | return VectorKind(VectorTypeBits.VecKind); | ||||||
3279 | } | ||||||
3280 | |||||||
3281 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3282 | Profile(ID, getElementType(), getNumElements(), | ||||||
3283 | getTypeClass(), getVectorKind()); | ||||||
3284 | } | ||||||
3285 | |||||||
3286 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, | ||||||
3287 | unsigned NumElements, TypeClass TypeClass, | ||||||
3288 | VectorKind VecKind) { | ||||||
3289 | ID.AddPointer(ElementType.getAsOpaquePtr()); | ||||||
3290 | ID.AddInteger(NumElements); | ||||||
3291 | ID.AddInteger(TypeClass); | ||||||
3292 | ID.AddInteger(VecKind); | ||||||
3293 | } | ||||||
3294 | |||||||
3295 | static bool classof(const Type *T) { | ||||||
3296 | return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector; | ||||||
3297 | } | ||||||
3298 | }; | ||||||
3299 | |||||||
3300 | /// Represents a vector type where either the type or size is dependent. | ||||||
3301 | //// | ||||||
3302 | /// For example: | ||||||
3303 | /// \code | ||||||
3304 | /// template<typename T, int Size> | ||||||
3305 | /// class vector { | ||||||
3306 | /// typedef T __attribute__((vector_size(Size))) type; | ||||||
3307 | /// } | ||||||
3308 | /// \endcode | ||||||
3309 | class DependentVectorType : public Type, public llvm::FoldingSetNode { | ||||||
3310 | friend class ASTContext; | ||||||
3311 | |||||||
3312 | const ASTContext &Context; | ||||||
3313 | QualType ElementType; | ||||||
3314 | Expr *SizeExpr; | ||||||
3315 | SourceLocation Loc; | ||||||
3316 | |||||||
3317 | DependentVectorType(const ASTContext &Context, QualType ElementType, | ||||||
3318 | QualType CanonType, Expr *SizeExpr, | ||||||
3319 | SourceLocation Loc, VectorType::VectorKind vecKind); | ||||||
3320 | |||||||
3321 | public: | ||||||
3322 | Expr *getSizeExpr() const { return SizeExpr; } | ||||||
3323 | QualType getElementType() const { return ElementType; } | ||||||
3324 | SourceLocation getAttributeLoc() const { return Loc; } | ||||||
3325 | VectorType::VectorKind getVectorKind() const { | ||||||
3326 | return VectorType::VectorKind(VectorTypeBits.VecKind); | ||||||
3327 | } | ||||||
3328 | |||||||
3329 | bool isSugared() const { return false; } | ||||||
3330 | QualType desugar() const { return QualType(this, 0); } | ||||||
3331 | |||||||
3332 | static bool classof(const Type *T) { | ||||||
3333 | return T->getTypeClass() == DependentVector; | ||||||
3334 | } | ||||||
3335 | |||||||
3336 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3337 | Profile(ID, Context, getElementType(), getSizeExpr(), getVectorKind()); | ||||||
3338 | } | ||||||
3339 | |||||||
3340 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
3341 | QualType ElementType, const Expr *SizeExpr, | ||||||
3342 | VectorType::VectorKind VecKind); | ||||||
3343 | }; | ||||||
3344 | |||||||
3345 | /// ExtVectorType - Extended vector type. This type is created using | ||||||
3346 | /// __attribute__((ext_vector_type(n)), where "n" is the number of elements. | ||||||
3347 | /// Unlike vector_size, ext_vector_type is only allowed on typedef's. This | ||||||
3348 | /// class enables syntactic extensions, like Vector Components for accessing | ||||||
3349 | /// points (as .xyzw), colors (as .rgba), and textures (modeled after OpenGL | ||||||
3350 | /// Shading Language). | ||||||
3351 | class ExtVectorType : public VectorType { | ||||||
3352 | friend class ASTContext; // ASTContext creates these. | ||||||
3353 | |||||||
3354 | ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) | ||||||
3355 | : VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {} | ||||||
3356 | |||||||
3357 | public: | ||||||
3358 | static int getPointAccessorIdx(char c) { | ||||||
3359 | switch (c) { | ||||||
3360 | default: return -1; | ||||||
3361 | case 'x': case 'r': return 0; | ||||||
3362 | case 'y': case 'g': return 1; | ||||||
3363 | case 'z': case 'b': return 2; | ||||||
3364 | case 'w': case 'a': return 3; | ||||||
3365 | } | ||||||
3366 | } | ||||||
3367 | |||||||
3368 | static int getNumericAccessorIdx(char c) { | ||||||
3369 | switch (c) { | ||||||
3370 | default: return -1; | ||||||
3371 | case '0': return 0; | ||||||
3372 | case '1': return 1; | ||||||
3373 | case '2': return 2; | ||||||
3374 | case '3': return 3; | ||||||
3375 | case '4': return 4; | ||||||
3376 | case '5': return 5; | ||||||
3377 | case '6': return 6; | ||||||
3378 | case '7': return 7; | ||||||
3379 | case '8': return 8; | ||||||
3380 | case '9': return 9; | ||||||
3381 | case 'A': | ||||||
3382 | case 'a': return 10; | ||||||
3383 | case 'B': | ||||||
3384 | case 'b': return 11; | ||||||
3385 | case 'C': | ||||||
3386 | case 'c': return 12; | ||||||
3387 | case 'D': | ||||||
3388 | case 'd': return 13; | ||||||
3389 | case 'E': | ||||||
3390 | case 'e': return 14; | ||||||
3391 | case 'F': | ||||||
3392 | case 'f': return 15; | ||||||
3393 | } | ||||||
3394 | } | ||||||
3395 | |||||||
3396 | static int getAccessorIdx(char c, bool isNumericAccessor) { | ||||||
3397 | if (isNumericAccessor) | ||||||
3398 | return getNumericAccessorIdx(c); | ||||||
3399 | else | ||||||
3400 | return getPointAccessorIdx(c); | ||||||
3401 | } | ||||||
3402 | |||||||
3403 | bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const { | ||||||
3404 | if (int idx = getAccessorIdx(c, isNumericAccessor)+1) | ||||||
3405 | return unsigned(idx-1) < getNumElements(); | ||||||
3406 | return false; | ||||||
3407 | } | ||||||
3408 | |||||||
3409 | bool isSugared() const { return false; } | ||||||
3410 | QualType desugar() const { return QualType(this, 0); } | ||||||
3411 | |||||||
3412 | static bool classof(const Type *T) { | ||||||
3413 | return T->getTypeClass() == ExtVector; | ||||||
3414 | } | ||||||
3415 | }; | ||||||
3416 | |||||||
3417 | /// Represents a matrix type, as defined in the Matrix Types clang extensions. | ||||||
3418 | /// __attribute__((matrix_type(rows, columns))), where "rows" specifies | ||||||
3419 | /// number of rows and "columns" specifies the number of columns. | ||||||
3420 | class MatrixType : public Type, public llvm::FoldingSetNode { | ||||||
3421 | protected: | ||||||
3422 | friend class ASTContext; | ||||||
3423 | |||||||
3424 | /// The element type of the matrix. | ||||||
3425 | QualType ElementType; | ||||||
3426 | |||||||
3427 | MatrixType(QualType ElementTy, QualType CanonElementTy); | ||||||
3428 | |||||||
3429 | MatrixType(TypeClass TypeClass, QualType ElementTy, QualType CanonElementTy, | ||||||
3430 | const Expr *RowExpr = nullptr, const Expr *ColumnExpr = nullptr); | ||||||
3431 | |||||||
3432 | public: | ||||||
3433 | /// Returns type of the elements being stored in the matrix | ||||||
3434 | QualType getElementType() const { return ElementType; } | ||||||
3435 | |||||||
3436 | /// Valid elements types are the following: | ||||||
3437 | /// * an integer type (as in C2x 6.2.5p19), but excluding enumerated types | ||||||
3438 | /// and _Bool | ||||||
3439 | /// * the standard floating types float or double | ||||||
3440 | /// * a half-precision floating point type, if one is supported on the target | ||||||
3441 | static bool isValidElementType(QualType T) { | ||||||
3442 | return T->isDependentType() || | ||||||
3443 | (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType()); | ||||||
3444 | } | ||||||
3445 | |||||||
3446 | bool isSugared() const { return false; } | ||||||
3447 | QualType desugar() const { return QualType(this, 0); } | ||||||
3448 | |||||||
3449 | static bool classof(const Type *T) { | ||||||
3450 | return T->getTypeClass() == ConstantMatrix || | ||||||
3451 | T->getTypeClass() == DependentSizedMatrix; | ||||||
3452 | } | ||||||
3453 | }; | ||||||
3454 | |||||||
3455 | /// Represents a concrete matrix type with constant number of rows and columns | ||||||
3456 | class ConstantMatrixType final : public MatrixType { | ||||||
3457 | protected: | ||||||
3458 | friend class ASTContext; | ||||||
3459 | |||||||
3460 | /// Number of rows and columns. | ||||||
3461 | unsigned NumRows; | ||||||
3462 | unsigned NumColumns; | ||||||
3463 | |||||||
3464 | static constexpr unsigned MaxElementsPerDimension = (1 << 20) - 1; | ||||||
3465 | |||||||
3466 | ConstantMatrixType(QualType MatrixElementType, unsigned NRows, | ||||||
3467 | unsigned NColumns, QualType CanonElementType); | ||||||
3468 | |||||||
3469 | ConstantMatrixType(TypeClass typeClass, QualType MatrixType, unsigned NRows, | ||||||
3470 | unsigned NColumns, QualType CanonElementType); | ||||||
3471 | |||||||
3472 | public: | ||||||
3473 | /// Returns the number of rows in the matrix. | ||||||
3474 | unsigned getNumRows() const { return NumRows; } | ||||||
3475 | |||||||
3476 | /// Returns the number of columns in the matrix. | ||||||
3477 | unsigned getNumColumns() const { return NumColumns; } | ||||||
3478 | |||||||
3479 | /// Returns the number of elements required to embed the matrix into a vector. | ||||||
3480 | unsigned getNumElementsFlattened() const { | ||||||
3481 | return getNumRows() * getNumColumns(); | ||||||
3482 | } | ||||||
3483 | |||||||
3484 | /// Returns true if \p NumElements is a valid matrix dimension. | ||||||
3485 | static constexpr bool isDimensionValid(size_t NumElements) { | ||||||
3486 | return NumElements > 0 && NumElements <= MaxElementsPerDimension; | ||||||
3487 | } | ||||||
3488 | |||||||
3489 | /// Returns the maximum number of elements per dimension. | ||||||
3490 | static constexpr unsigned getMaxElementsPerDimension() { | ||||||
3491 | return MaxElementsPerDimension; | ||||||
3492 | } | ||||||
3493 | |||||||
3494 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3495 | Profile(ID, getElementType(), getNumRows(), getNumColumns(), | ||||||
3496 | getTypeClass()); | ||||||
3497 | } | ||||||
3498 | |||||||
3499 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, | ||||||
3500 | unsigned NumRows, unsigned NumColumns, | ||||||
3501 | TypeClass TypeClass) { | ||||||
3502 | ID.AddPointer(ElementType.getAsOpaquePtr()); | ||||||
3503 | ID.AddInteger(NumRows); | ||||||
3504 | ID.AddInteger(NumColumns); | ||||||
3505 | ID.AddInteger(TypeClass); | ||||||
3506 | } | ||||||
3507 | |||||||
3508 | static bool classof(const Type *T) { | ||||||
3509 | return T->getTypeClass() == ConstantMatrix; | ||||||
3510 | } | ||||||
3511 | }; | ||||||
3512 | |||||||
3513 | /// Represents a matrix type where the type and the number of rows and columns | ||||||
3514 | /// is dependent on a template. | ||||||
3515 | class DependentSizedMatrixType final : public MatrixType { | ||||||
3516 | friend class ASTContext; | ||||||
3517 | |||||||
3518 | const ASTContext &Context; | ||||||
3519 | Expr *RowExpr; | ||||||
3520 | Expr *ColumnExpr; | ||||||
3521 | |||||||
3522 | SourceLocation loc; | ||||||
3523 | |||||||
3524 | DependentSizedMatrixType(const ASTContext &Context, QualType ElementType, | ||||||
3525 | QualType CanonicalType, Expr *RowExpr, | ||||||
3526 | Expr *ColumnExpr, SourceLocation loc); | ||||||
3527 | |||||||
3528 | public: | ||||||
3529 | Expr *getRowExpr() const { return RowExpr; } | ||||||
3530 | Expr *getColumnExpr() const { return ColumnExpr; } | ||||||
3531 | SourceLocation getAttributeLoc() const { return loc; } | ||||||
3532 | |||||||
3533 | static bool classof(const Type *T) { | ||||||
3534 | return T->getTypeClass() == DependentSizedMatrix; | ||||||
3535 | } | ||||||
3536 | |||||||
3537 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3538 | Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr()); | ||||||
3539 | } | ||||||
3540 | |||||||
3541 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
3542 | QualType ElementType, Expr *RowExpr, Expr *ColumnExpr); | ||||||
3543 | }; | ||||||
3544 | |||||||
3545 | /// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base | ||||||
3546 | /// class of FunctionNoProtoType and FunctionProtoType. | ||||||
3547 | class FunctionType : public Type { | ||||||
3548 | // The type returned by the function. | ||||||
3549 | QualType ResultType; | ||||||
3550 | |||||||
3551 | public: | ||||||
3552 | /// Interesting information about a specific parameter that can't simply | ||||||
3553 | /// be reflected in parameter's type. This is only used by FunctionProtoType | ||||||
3554 | /// but is in FunctionType to make this class available during the | ||||||
3555 | /// specification of the bases of FunctionProtoType. | ||||||
3556 | /// | ||||||
3557 | /// It makes sense to model language features this way when there's some | ||||||
3558 | /// sort of parameter-specific override (such as an attribute) that | ||||||
3559 | /// affects how the function is called. For example, the ARC ns_consumed | ||||||
3560 | /// attribute changes whether a parameter is passed at +0 (the default) | ||||||
3561 | /// or +1 (ns_consumed). This must be reflected in the function type, | ||||||
3562 | /// but isn't really a change to the parameter type. | ||||||
3563 | /// | ||||||
3564 | /// One serious disadvantage of modelling language features this way is | ||||||
3565 | /// that they generally do not work with language features that attempt | ||||||
3566 | /// to destructure types. For example, template argument deduction will | ||||||
3567 | /// not be able to match a parameter declared as | ||||||
3568 | /// T (*)(U) | ||||||
3569 | /// against an argument of type | ||||||
3570 | /// void (*)(__attribute__((ns_consumed)) id) | ||||||
3571 | /// because the substitution of T=void, U=id into the former will | ||||||
3572 | /// not produce the latter. | ||||||
3573 | class ExtParameterInfo { | ||||||
3574 | enum { | ||||||
3575 | ABIMask = 0x0F, | ||||||
3576 | IsConsumed = 0x10, | ||||||
3577 | HasPassObjSize = 0x20, | ||||||
3578 | IsNoEscape = 0x40, | ||||||
3579 | }; | ||||||
3580 | unsigned char Data = 0; | ||||||
3581 | |||||||
3582 | public: | ||||||
3583 | ExtParameterInfo() = default; | ||||||
3584 | |||||||
3585 | /// Return the ABI treatment of this parameter. | ||||||
3586 | ParameterABI getABI() const { return ParameterABI(Data & ABIMask); } | ||||||
3587 | ExtParameterInfo withABI(ParameterABI kind) const { | ||||||
3588 | ExtParameterInfo copy = *this; | ||||||
3589 | copy.Data = (copy.Data & ~ABIMask) | unsigned(kind); | ||||||
3590 | return copy; | ||||||
3591 | } | ||||||
3592 | |||||||
3593 | /// Is this parameter considered "consumed" by Objective-C ARC? | ||||||
3594 | /// Consumed parameters must have retainable object type. | ||||||
3595 | bool isConsumed() const { return (Data & IsConsumed); } | ||||||
3596 | ExtParameterInfo withIsConsumed(bool consumed) const { | ||||||
3597 | ExtParameterInfo copy = *this; | ||||||
3598 | if (consumed) | ||||||
3599 | copy.Data |= IsConsumed; | ||||||
3600 | else | ||||||
3601 | copy.Data &= ~IsConsumed; | ||||||
3602 | return copy; | ||||||
3603 | } | ||||||
3604 | |||||||
3605 | bool hasPassObjectSize() const { return Data & HasPassObjSize; } | ||||||
3606 | ExtParameterInfo withHasPassObjectSize() const { | ||||||
3607 | ExtParameterInfo Copy = *this; | ||||||
3608 | Copy.Data |= HasPassObjSize; | ||||||
3609 | return Copy; | ||||||
3610 | } | ||||||
3611 | |||||||
3612 | bool isNoEscape() const { return Data & IsNoEscape; } | ||||||
3613 | ExtParameterInfo withIsNoEscape(bool NoEscape) const { | ||||||
3614 | ExtParameterInfo Copy = *this; | ||||||
3615 | if (NoEscape) | ||||||
3616 | Copy.Data |= IsNoEscape; | ||||||
3617 | else | ||||||
3618 | Copy.Data &= ~IsNoEscape; | ||||||
3619 | return Copy; | ||||||
3620 | } | ||||||
3621 | |||||||
3622 | unsigned char getOpaqueValue() const { return Data; } | ||||||
3623 | static ExtParameterInfo getFromOpaqueValue(unsigned char data) { | ||||||
3624 | ExtParameterInfo result; | ||||||
3625 | result.Data = data; | ||||||
3626 | return result; | ||||||
3627 | } | ||||||
3628 | |||||||
3629 | friend bool operator==(ExtParameterInfo lhs, ExtParameterInfo rhs) { | ||||||
3630 | return lhs.Data == rhs.Data; | ||||||
3631 | } | ||||||
3632 | |||||||
3633 | friend bool operator!=(ExtParameterInfo lhs, ExtParameterInfo rhs) { | ||||||
3634 | return lhs.Data != rhs.Data; | ||||||
3635 | } | ||||||
3636 | }; | ||||||
3637 | |||||||
3638 | /// A class which abstracts out some details necessary for | ||||||
3639 | /// making a call. | ||||||
3640 | /// | ||||||
3641 | /// It is not actually used directly for storing this information in | ||||||
3642 | /// a FunctionType, although FunctionType does currently use the | ||||||
3643 | /// same bit-pattern. | ||||||
3644 | /// | ||||||
3645 | // If you add a field (say Foo), other than the obvious places (both, | ||||||
3646 | // constructors, compile failures), what you need to update is | ||||||
3647 | // * Operator== | ||||||
3648 | // * getFoo | ||||||
3649 | // * withFoo | ||||||
3650 | // * functionType. Add Foo, getFoo. | ||||||
3651 | // * ASTContext::getFooType | ||||||
3652 | // * ASTContext::mergeFunctionTypes | ||||||
3653 | // * FunctionNoProtoType::Profile | ||||||
3654 | // * FunctionProtoType::Profile | ||||||
3655 | // * TypePrinter::PrintFunctionProto | ||||||
3656 | // * AST read and write | ||||||
3657 | // * Codegen | ||||||
3658 | class ExtInfo { | ||||||
3659 | friend class FunctionType; | ||||||
3660 | |||||||
3661 | // Feel free to rearrange or add bits, but if you go over 16, you'll need to | ||||||
3662 | // adjust the Bits field below, and if you add bits, you'll need to adjust | ||||||
3663 | // Type::FunctionTypeBitfields::ExtInfo as well. | ||||||
3664 | |||||||
3665 | // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|cmsenscall| | ||||||
3666 | // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 | 12 | | ||||||
3667 | // | ||||||
3668 | // regparm is either 0 (no regparm attribute) or the regparm value+1. | ||||||
3669 | enum { CallConvMask = 0x1F }; | ||||||
3670 | enum { NoReturnMask = 0x20 }; | ||||||
3671 | enum { ProducesResultMask = 0x40 }; | ||||||
3672 | enum { NoCallerSavedRegsMask = 0x80 }; | ||||||
3673 | enum { | ||||||
3674 | RegParmMask = 0x700, | ||||||
3675 | RegParmOffset = 8 | ||||||
3676 | }; | ||||||
3677 | enum { NoCfCheckMask = 0x800 }; | ||||||
3678 | enum { CmseNSCallMask = 0x1000 }; | ||||||
3679 | uint16_t Bits = CC_C; | ||||||
3680 | |||||||
3681 | ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {} | ||||||
3682 | |||||||
3683 | public: | ||||||
3684 | // Constructor with no defaults. Use this when you know that you | ||||||
3685 | // have all the elements (when reading an AST file for example). | ||||||
3686 | ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, | ||||||
3687 | bool producesResult, bool noCallerSavedRegs, bool NoCfCheck, | ||||||
3688 | bool cmseNSCall) { | ||||||
3689 | assert((!hasRegParm || regParm < 7) && "Invalid regparm value")(static_cast <bool> ((!hasRegParm || regParm < 7) && "Invalid regparm value") ? void (0) : __assert_fail ("(!hasRegParm || regParm < 7) && \"Invalid regparm value\"" , "clang/include/clang/AST/Type.h", 3689, __extension__ __PRETTY_FUNCTION__ )); | ||||||
3690 | Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) | | ||||||
3691 | (producesResult ? ProducesResultMask : 0) | | ||||||
3692 | (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) | | ||||||
3693 | (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) | | ||||||
3694 | (NoCfCheck ? NoCfCheckMask : 0) | | ||||||
3695 | (cmseNSCall ? CmseNSCallMask : 0); | ||||||
3696 | } | ||||||
3697 | |||||||
3698 | // Constructor with all defaults. Use when for example creating a | ||||||
3699 | // function known to use defaults. | ||||||
3700 | ExtInfo() = default; | ||||||
3701 | |||||||
3702 | // Constructor with just the calling convention, which is an important part | ||||||
3703 | // of the canonical type. | ||||||
3704 | ExtInfo(CallingConv CC) : Bits(CC) {} | ||||||
3705 | |||||||
3706 | bool getNoReturn() const { return Bits & NoReturnMask; } | ||||||
3707 | bool getProducesResult() const { return Bits & ProducesResultMask; } | ||||||
3708 | bool getCmseNSCall() const { return Bits & CmseNSCallMask; } | ||||||
3709 | bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; } | ||||||
3710 | bool getNoCfCheck() const { return Bits & NoCfCheckMask; } | ||||||
3711 | bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; } | ||||||
3712 | |||||||
3713 | unsigned getRegParm() const { | ||||||
3714 | unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset; | ||||||
3715 | if (RegParm > 0) | ||||||
3716 | --RegParm; | ||||||
3717 | return RegParm; | ||||||
3718 | } | ||||||
3719 | |||||||
3720 | CallingConv getCC() const { return CallingConv(Bits & CallConvMask); } | ||||||
3721 | |||||||
3722 | bool operator==(ExtInfo Other) const { | ||||||
3723 | return Bits == Other.Bits; | ||||||
3724 | } | ||||||
3725 | bool operator!=(ExtInfo Other) const { | ||||||
3726 | return Bits != Other.Bits; | ||||||
3727 | } | ||||||
3728 | |||||||
3729 | // Note that we don't have setters. That is by design, use | ||||||
3730 | // the following with methods instead of mutating these objects. | ||||||
3731 | |||||||
3732 | ExtInfo withNoReturn(bool noReturn) const { | ||||||
3733 | if (noReturn) | ||||||
3734 | return ExtInfo(Bits | NoReturnMask); | ||||||
3735 | else | ||||||
3736 | return ExtInfo(Bits & ~NoReturnMask); | ||||||
3737 | } | ||||||
3738 | |||||||
3739 | ExtInfo withProducesResult(bool producesResult) const { | ||||||
3740 | if (producesResult) | ||||||
3741 | return ExtInfo(Bits | ProducesResultMask); | ||||||
3742 | else | ||||||
3743 | return ExtInfo(Bits & ~ProducesResultMask); | ||||||
3744 | } | ||||||
3745 | |||||||
3746 | ExtInfo withCmseNSCall(bool cmseNSCall) const { | ||||||
3747 | if (cmseNSCall) | ||||||
3748 | return ExtInfo(Bits | CmseNSCallMask); | ||||||
3749 | else | ||||||
3750 | return ExtInfo(Bits & ~CmseNSCallMask); | ||||||
3751 | } | ||||||
3752 | |||||||
3753 | ExtInfo withNoCallerSavedRegs(bool noCallerSavedRegs) const { | ||||||
3754 | if (noCallerSavedRegs) | ||||||
3755 | return ExtInfo(Bits | NoCallerSavedRegsMask); | ||||||
3756 | else | ||||||
3757 | return ExtInfo(Bits & ~NoCallerSavedRegsMask); | ||||||
3758 | } | ||||||
3759 | |||||||
3760 | ExtInfo withNoCfCheck(bool noCfCheck) const { | ||||||
3761 | if (noCfCheck) | ||||||
3762 | return ExtInfo(Bits | NoCfCheckMask); | ||||||
3763 | else | ||||||
3764 | return ExtInfo(Bits & ~NoCfCheckMask); | ||||||
3765 | } | ||||||
3766 | |||||||
3767 | ExtInfo withRegParm(unsigned RegParm) const { | ||||||
3768 | assert(RegParm < 7 && "Invalid regparm value")(static_cast <bool> (RegParm < 7 && "Invalid regparm value" ) ? void (0) : __assert_fail ("RegParm < 7 && \"Invalid regparm value\"" , "clang/include/clang/AST/Type.h", 3768, __extension__ __PRETTY_FUNCTION__ )); | ||||||
3769 | return ExtInfo((Bits & ~RegParmMask) | | ||||||
3770 | ((RegParm + 1) << RegParmOffset)); | ||||||
3771 | } | ||||||
3772 | |||||||
3773 | ExtInfo withCallingConv(CallingConv cc) const { | ||||||
3774 | return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc); | ||||||
3775 | } | ||||||
3776 | |||||||
3777 | void Profile(llvm::FoldingSetNodeID &ID) const { | ||||||
3778 | ID.AddInteger(Bits); | ||||||
3779 | } | ||||||
3780 | }; | ||||||
3781 | |||||||
3782 | /// A simple holder for a QualType representing a type in an | ||||||
3783 | /// exception specification. Unfortunately needed by FunctionProtoType | ||||||
3784 | /// because TrailingObjects cannot handle repeated types. | ||||||
3785 | struct ExceptionType { QualType Type; }; | ||||||
3786 | |||||||
3787 | /// A simple holder for various uncommon bits which do not fit in | ||||||
3788 | /// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the | ||||||
3789 | /// alignment of subsequent objects in TrailingObjects. You must update | ||||||
3790 | /// hasExtraBitfields in FunctionProtoType after adding extra data here. | ||||||
3791 | struct alignas(void *) FunctionTypeExtraBitfields { | ||||||
3792 | /// The number of types in the exception specification. | ||||||
3793 | /// A whole unsigned is not needed here and according to | ||||||
3794 | /// [implimits] 8 bits would be enough here. | ||||||
3795 | unsigned NumExceptionType; | ||||||
3796 | }; | ||||||
3797 | |||||||
3798 | protected: | ||||||
3799 | FunctionType(TypeClass tc, QualType res, QualType Canonical, | ||||||
3800 | TypeDependence Dependence, ExtInfo Info) | ||||||
3801 | : Type(tc, Canonical, Dependence), ResultType(res) { | ||||||
3802 | FunctionTypeBits.ExtInfo = Info.Bits; | ||||||
3803 | } | ||||||
3804 | |||||||
3805 | Qualifiers getFastTypeQuals() const { | ||||||
3806 | return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals); | ||||||
3807 | } | ||||||
3808 | |||||||
3809 | public: | ||||||
3810 | QualType getReturnType() const { return ResultType; } | ||||||
3811 | |||||||
3812 | bool getHasRegParm() const { return getExtInfo().getHasRegParm(); } | ||||||
3813 | unsigned getRegParmType() const { return getExtInfo().getRegParm(); } | ||||||
3814 | |||||||
3815 | /// Determine whether this function type includes the GNU noreturn | ||||||
3816 | /// attribute. The C++11 [[noreturn]] attribute does not affect the function | ||||||
3817 | /// type. | ||||||
3818 | bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } | ||||||
3819 | |||||||
3820 | bool getCmseNSCallAttr() const { return getExtInfo().getCmseNSCall(); } | ||||||
3821 | CallingConv getCallConv() const { return getExtInfo().getCC(); } | ||||||
3822 | ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } | ||||||
3823 | |||||||
3824 | static_assert((~Qualifiers::FastMask & Qualifiers::CVRMask) == 0, | ||||||
3825 | "Const, volatile and restrict are assumed to be a subset of " | ||||||
3826 | "the fast qualifiers."); | ||||||
3827 | |||||||
3828 | bool isConst() const { return getFastTypeQuals().hasConst(); } | ||||||
3829 | bool isVolatile() const { return getFastTypeQuals().hasVolatile(); } | ||||||
3830 | bool isRestrict() const { return getFastTypeQuals().hasRestrict(); } | ||||||
3831 | |||||||
3832 | /// Determine the type of an expression that calls a function of | ||||||
3833 | /// this type. | ||||||
3834 | QualType getCallResultType(const ASTContext &Context) const { | ||||||
3835 | return getReturnType().getNonLValueExprType(Context); | ||||||
3836 | } | ||||||
3837 | |||||||
3838 | static StringRef getNameForCallConv(CallingConv CC); | ||||||
3839 | |||||||
3840 | static bool classof(const Type *T) { | ||||||
3841 | return T->getTypeClass() == FunctionNoProto || | ||||||
3842 | T->getTypeClass() == FunctionProto; | ||||||
3843 | } | ||||||
3844 | }; | ||||||
3845 | |||||||
3846 | /// Represents a K&R-style 'int foo()' function, which has | ||||||
3847 | /// no information available about its arguments. | ||||||
3848 | class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { | ||||||
3849 | friend class ASTContext; // ASTContext creates these. | ||||||
3850 | |||||||
3851 | FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) | ||||||
3852 | : FunctionType(FunctionNoProto, Result, Canonical, | ||||||
3853 | Result->getDependence() & | ||||||
3854 | ~(TypeDependence::DependentInstantiation | | ||||||
3855 | TypeDependence::UnexpandedPack), | ||||||
3856 | Info) {} | ||||||
3857 | |||||||
3858 | public: | ||||||
3859 | // No additional state past what FunctionType provides. | ||||||
3860 | |||||||
3861 | bool isSugared() const { return false; } | ||||||
3862 | QualType desugar() const { return QualType(this, 0); } | ||||||
3863 | |||||||
3864 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
3865 | Profile(ID, getReturnType(), getExtInfo()); | ||||||
3866 | } | ||||||
3867 | |||||||
3868 | static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType, | ||||||
3869 | ExtInfo Info) { | ||||||
3870 | Info.Profile(ID); | ||||||
3871 | ID.AddPointer(ResultType.getAsOpaquePtr()); | ||||||
3872 | } | ||||||
3873 | |||||||
3874 | static bool classof(const Type *T) { | ||||||
3875 | return T->getTypeClass() == FunctionNoProto; | ||||||
3876 | } | ||||||
3877 | }; | ||||||
3878 | |||||||
3879 | /// Represents a prototype with parameter type info, e.g. | ||||||
3880 | /// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no | ||||||
3881 | /// parameters, not as having a single void parameter. Such a type can have | ||||||
3882 | /// an exception specification, but this specification is not part of the | ||||||
3883 | /// canonical type. FunctionProtoType has several trailing objects, some of | ||||||
3884 | /// which optional. For more information about the trailing objects see | ||||||
3885 | /// the first comment inside FunctionProtoType. | ||||||
3886 | class FunctionProtoType final | ||||||
3887 | : public FunctionType, | ||||||
3888 | public llvm::FoldingSetNode, | ||||||
3889 | private llvm::TrailingObjects< | ||||||
3890 | FunctionProtoType, QualType, SourceLocation, | ||||||
3891 | FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType, | ||||||
3892 | Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> { | ||||||
3893 | friend class ASTContext; // ASTContext creates these. | ||||||
3894 | friend TrailingObjects; | ||||||
3895 | |||||||
3896 | // FunctionProtoType is followed by several trailing objects, some of | ||||||
3897 | // which optional. They are in order: | ||||||
3898 | // | ||||||
3899 | // * An array of getNumParams() QualType holding the parameter types. | ||||||
3900 | // Always present. Note that for the vast majority of FunctionProtoType, | ||||||
3901 | // these will be the only trailing objects. | ||||||
3902 | // | ||||||
3903 | // * Optionally if the function is variadic, the SourceLocation of the | ||||||
3904 | // ellipsis. | ||||||
3905 | // | ||||||
3906 | // * Optionally if some extra data is stored in FunctionTypeExtraBitfields | ||||||
3907 | // (see FunctionTypeExtraBitfields and FunctionTypeBitfields): | ||||||
3908 | // a single FunctionTypeExtraBitfields. Present if and only if | ||||||
3909 | // hasExtraBitfields() is true. | ||||||
3910 | // | ||||||
3911 | // * Optionally exactly one of: | ||||||
3912 | // * an array of getNumExceptions() ExceptionType, | ||||||
3913 | // * a single Expr *, | ||||||
3914 | // * a pair of FunctionDecl *, | ||||||
3915 | // * a single FunctionDecl * | ||||||
3916 | // used to store information about the various types of exception | ||||||
3917 | // specification. See getExceptionSpecSize for the details. | ||||||
3918 | // | ||||||
3919 | // * Optionally an array of getNumParams() ExtParameterInfo holding | ||||||
3920 | // an ExtParameterInfo for each of the parameters. Present if and | ||||||
3921 | // only if hasExtParameterInfos() is true. | ||||||
3922 | // | ||||||
3923 | // * Optionally a Qualifiers object to represent extra qualifiers that can't | ||||||
3924 | // be represented by FunctionTypeBitfields.FastTypeQuals. Present if and only | ||||||
3925 | // if hasExtQualifiers() is true. | ||||||
3926 | // | ||||||
3927 | // The optional FunctionTypeExtraBitfields has to be before the data | ||||||
3928 | // related to the exception specification since it contains the number | ||||||
3929 | // of exception types. | ||||||
3930 | // | ||||||
3931 | // We put the ExtParameterInfos last. If all were equal, it would make | ||||||
3932 | // more sense to put these before the exception specification, because | ||||||
3933 | // it's much easier to skip past them compared to the elaborate switch | ||||||
3934 | // required to skip the exception specification. However, all is not | ||||||
3935 | // equal; ExtParameterInfos are used to model very uncommon features, | ||||||
3936 | // and it's better not to burden the more common paths. | ||||||
3937 | |||||||
3938 | public: | ||||||
3939 | /// Holds information about the various types of exception specification. | ||||||
3940 | /// ExceptionSpecInfo is not stored as such in FunctionProtoType but is | ||||||
3941 | /// used to group together the various bits of information about the | ||||||
3942 | /// exception specification. | ||||||
3943 | struct ExceptionSpecInfo { | ||||||
3944 | /// The kind of exception specification this is. | ||||||
3945 | ExceptionSpecificationType Type = EST_None; | ||||||
3946 | |||||||
3947 | /// Explicitly-specified list of exception types. | ||||||
3948 | ArrayRef<QualType> Exceptions; | ||||||
3949 | |||||||
3950 | /// Noexcept expression, if this is a computed noexcept specification. | ||||||
3951 | Expr *NoexceptExpr = nullptr; | ||||||
3952 | |||||||
3953 | /// The function whose exception specification this is, for | ||||||
3954 | /// EST_Unevaluated and EST_Uninstantiated. | ||||||
3955 | FunctionDecl *SourceDecl = nullptr; | ||||||
3956 | |||||||
3957 | /// The function template whose exception specification this is instantiated | ||||||
3958 | /// from, for EST_Uninstantiated. | ||||||
3959 | FunctionDecl *SourceTemplate = nullptr; | ||||||
3960 | |||||||
3961 | ExceptionSpecInfo() = default; | ||||||
3962 | |||||||
3963 | ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {} | ||||||
3964 | }; | ||||||
3965 | |||||||
3966 | /// Extra information about a function prototype. ExtProtoInfo is not | ||||||
3967 | /// stored as such in FunctionProtoType but is used to group together | ||||||
3968 | /// the various bits of extra information about a function prototype. | ||||||
3969 | struct ExtProtoInfo { | ||||||
3970 | FunctionType::ExtInfo ExtInfo; | ||||||
3971 | bool Variadic : 1; | ||||||
3972 | bool HasTrailingReturn : 1; | ||||||
3973 | Qualifiers TypeQuals; | ||||||
3974 | RefQualifierKind RefQualifier = RQ_None; | ||||||
3975 | ExceptionSpecInfo ExceptionSpec; | ||||||
3976 | const ExtParameterInfo *ExtParameterInfos = nullptr; | ||||||
3977 | SourceLocation EllipsisLoc; | ||||||
3978 | |||||||
3979 | ExtProtoInfo() : Variadic(false), HasTrailingReturn(false) {} | ||||||
3980 | |||||||
3981 | ExtProtoInfo(CallingConv CC) | ||||||
3982 | : ExtInfo(CC), Variadic(false), HasTrailingReturn(false) {} | ||||||
3983 | |||||||
3984 | ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI) { | ||||||
3985 | ExtProtoInfo Result(*this); | ||||||
3986 | Result.ExceptionSpec = ESI; | ||||||
3987 | return Result; | ||||||
3988 | } | ||||||
3989 | }; | ||||||
3990 | |||||||
3991 | private: | ||||||
3992 | unsigned numTrailingObjects(OverloadToken<QualType>) const { | ||||||
3993 | return getNumParams(); | ||||||
3994 | } | ||||||
3995 | |||||||
3996 | unsigned numTrailingObjects(OverloadToken<SourceLocation>) const { | ||||||
3997 | return isVariadic(); | ||||||
3998 | } | ||||||
3999 | |||||||
4000 | unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const { | ||||||
4001 | return hasExtraBitfields(); | ||||||
4002 | } | ||||||
4003 | |||||||
4004 | unsigned numTrailingObjects(OverloadToken<ExceptionType>) const { | ||||||
4005 | return getExceptionSpecSize().NumExceptionType; | ||||||
4006 | } | ||||||
4007 | |||||||
4008 | unsigned numTrailingObjects(OverloadToken<Expr *>) const { | ||||||
4009 | return getExceptionSpecSize().NumExprPtr; | ||||||
4010 | } | ||||||
4011 | |||||||
4012 | unsigned numTrailingObjects(OverloadToken<FunctionDecl *>) const { | ||||||
4013 | return getExceptionSpecSize().NumFunctionDeclPtr; | ||||||
4014 | } | ||||||
4015 | |||||||
4016 | unsigned numTrailingObjects(OverloadToken<ExtParameterInfo>) const { | ||||||
4017 | return hasExtParameterInfos() ? getNumParams() : 0; | ||||||
4018 | } | ||||||
4019 | |||||||
4020 | /// Determine whether there are any argument types that | ||||||
4021 | /// contain an unexpanded parameter pack. | ||||||
4022 | static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray, | ||||||
4023 | unsigned numArgs) { | ||||||
4024 | for (unsigned Idx = 0; Idx < numArgs; ++Idx) | ||||||
4025 | if (ArgArray[Idx]->containsUnexpandedParameterPack()) | ||||||
4026 | return true; | ||||||
4027 | |||||||
4028 | return false; | ||||||
4029 | } | ||||||
4030 | |||||||
4031 | FunctionProtoType(QualType result, ArrayRef<QualType> params, | ||||||
4032 | QualType canonical, const ExtProtoInfo &epi); | ||||||
4033 | |||||||
4034 | /// This struct is returned by getExceptionSpecSize and is used to | ||||||
4035 | /// translate an ExceptionSpecificationType to the number and kind | ||||||
4036 | /// of trailing objects related to the exception specification. | ||||||
4037 | struct ExceptionSpecSizeHolder { | ||||||
4038 | unsigned NumExceptionType; | ||||||
4039 | unsigned NumExprPtr; | ||||||
4040 | unsigned NumFunctionDeclPtr; | ||||||
4041 | }; | ||||||
4042 | |||||||
4043 | /// Return the number and kind of trailing objects | ||||||
4044 | /// related to the exception specification. | ||||||
4045 | static ExceptionSpecSizeHolder | ||||||
4046 | getExceptionSpecSize(ExceptionSpecificationType EST, unsigned NumExceptions) { | ||||||
4047 | switch (EST) { | ||||||
4048 | case EST_None: | ||||||
4049 | case EST_DynamicNone: | ||||||
4050 | case EST_MSAny: | ||||||
4051 | case EST_BasicNoexcept: | ||||||
4052 | case EST_Unparsed: | ||||||
4053 | case EST_NoThrow: | ||||||
4054 | return {0, 0, 0}; | ||||||
4055 | |||||||
4056 | case EST_Dynamic: | ||||||
4057 | return {NumExceptions, 0, 0}; | ||||||
4058 | |||||||
4059 | case EST_DependentNoexcept: | ||||||
4060 | case EST_NoexceptFalse: | ||||||
4061 | case EST_NoexceptTrue: | ||||||
4062 | return {0, 1, 0}; | ||||||
4063 | |||||||
4064 | case EST_Uninstantiated: | ||||||
4065 | return {0, 0, 2}; | ||||||
4066 | |||||||
4067 | case EST_Unevaluated: | ||||||
4068 | return {0, 0, 1}; | ||||||
4069 | } | ||||||
4070 | llvm_unreachable("bad exception specification kind")::llvm::llvm_unreachable_internal("bad exception specification kind" , "clang/include/clang/AST/Type.h", 4070); | ||||||
4071 | } | ||||||
4072 | |||||||
4073 | /// Return the number and kind of trailing objects | ||||||
4074 | /// related to the exception specification. | ||||||
4075 | ExceptionSpecSizeHolder getExceptionSpecSize() const { | ||||||
4076 | return getExceptionSpecSize(getExceptionSpecType(), getNumExceptions()); | ||||||
4077 | } | ||||||
4078 | |||||||
4079 | /// Whether the trailing FunctionTypeExtraBitfields is present. | ||||||
4080 | static bool hasExtraBitfields(ExceptionSpecificationType EST) { | ||||||
4081 | // If the exception spec type is EST_Dynamic then we have > 0 exception | ||||||
4082 | // types and the exact number is stored in FunctionTypeExtraBitfields. | ||||||
4083 | return EST == EST_Dynamic; | ||||||
4084 | } | ||||||
4085 | |||||||
4086 | /// Whether the trailing FunctionTypeExtraBitfields is present. | ||||||
4087 | bool hasExtraBitfields() const { | ||||||
4088 | return hasExtraBitfields(getExceptionSpecType()); | ||||||
4089 | } | ||||||
4090 | |||||||
4091 | bool hasExtQualifiers() const { | ||||||
4092 | return FunctionTypeBits.HasExtQuals; | ||||||
4093 | } | ||||||
4094 | |||||||
4095 | public: | ||||||
4096 | unsigned getNumParams() const { return FunctionTypeBits.NumParams; } | ||||||
4097 | |||||||
4098 | QualType getParamType(unsigned i) const { | ||||||
4099 | assert(i < getNumParams() && "invalid parameter index")(static_cast <bool> (i < getNumParams() && "invalid parameter index" ) ? void (0) : __assert_fail ("i < getNumParams() && \"invalid parameter index\"" , "clang/include/clang/AST/Type.h", 4099, __extension__ __PRETTY_FUNCTION__ )); | ||||||
4100 | return param_type_begin()[i]; | ||||||
4101 | } | ||||||
4102 | |||||||
4103 | ArrayRef<QualType> getParamTypes() const { | ||||||
4104 | return llvm::makeArrayRef(param_type_begin(), param_type_end()); | ||||||
4105 | } | ||||||
4106 | |||||||
4107 | ExtProtoInfo getExtProtoInfo() const { | ||||||
4108 | ExtProtoInfo EPI; | ||||||
4109 | EPI.ExtInfo = getExtInfo(); | ||||||
4110 | EPI.Variadic = isVariadic(); | ||||||
4111 | EPI.EllipsisLoc = getEllipsisLoc(); | ||||||
4112 | EPI.HasTrailingReturn = hasTrailingReturn(); | ||||||
4113 | EPI.ExceptionSpec = getExceptionSpecInfo(); | ||||||
4114 | EPI.TypeQuals = getMethodQuals(); | ||||||
4115 | EPI.RefQualifier = getRefQualifier(); | ||||||
4116 | EPI.ExtParameterInfos = getExtParameterInfosOrNull(); | ||||||
4117 | return EPI; | ||||||
4118 | } | ||||||
4119 | |||||||
4120 | /// Get the kind of exception specification on this function. | ||||||
4121 | ExceptionSpecificationType getExceptionSpecType() const { | ||||||
4122 | return static_cast<ExceptionSpecificationType>( | ||||||
4123 | FunctionTypeBits.ExceptionSpecType); | ||||||
4124 | } | ||||||
4125 | |||||||
4126 | /// Return whether this function has any kind of exception spec. | ||||||
4127 | bool hasExceptionSpec() const { return getExceptionSpecType() != EST_None; } | ||||||
4128 | |||||||
4129 | /// Return whether this function has a dynamic (throw) exception spec. | ||||||
4130 | bool hasDynamicExceptionSpec() const { | ||||||
4131 | return isDynamicExceptionSpec(getExceptionSpecType()); | ||||||
4132 | } | ||||||
4133 | |||||||
4134 | /// Return whether this function has a noexcept exception spec. | ||||||
4135 | bool hasNoexceptExceptionSpec() const { | ||||||
4136 | return isNoexceptExceptionSpec(getExceptionSpecType()); | ||||||
4137 | } | ||||||
4138 | |||||||
4139 | /// Return whether this function has a dependent exception spec. | ||||||
4140 | bool hasDependentExceptionSpec() const; | ||||||
4141 | |||||||
4142 | /// Return whether this function has an instantiation-dependent exception | ||||||
4143 | /// spec. | ||||||
4144 | bool hasInstantiationDependentExceptionSpec() const; | ||||||
4145 | |||||||
4146 | /// Return all the available information about this type's exception spec. | ||||||
4147 | ExceptionSpecInfo getExceptionSpecInfo() const { | ||||||
4148 | ExceptionSpecInfo Result; | ||||||
4149 | Result.Type = getExceptionSpecType(); | ||||||
4150 | if (Result.Type == EST_Dynamic) { | ||||||
4151 | Result.Exceptions = exceptions(); | ||||||
4152 | } else if (isComputedNoexcept(Result.Type)) { | ||||||
4153 | Result.NoexceptExpr = getNoexceptExpr(); | ||||||
4154 | } else if (Result.Type == EST_Uninstantiated) { | ||||||
4155 | Result.SourceDecl = getExceptionSpecDecl(); | ||||||
4156 | Result.SourceTemplate = getExceptionSpecTemplate(); | ||||||
4157 | } else if (Result.Type == EST_Unevaluated) { | ||||||
4158 | Result.SourceDecl = getExceptionSpecDecl(); | ||||||
4159 | } | ||||||
4160 | return Result; | ||||||
4161 | } | ||||||
4162 | |||||||
4163 | /// Return the number of types in the exception specification. | ||||||
4164 | unsigned getNumExceptions() const { | ||||||
4165 | return getExceptionSpecType() == EST_Dynamic | ||||||
4166 | ? getTrailingObjects<FunctionTypeExtraBitfields>() | ||||||
4167 | ->NumExceptionType | ||||||
4168 | : 0; | ||||||
4169 | } | ||||||
4170 | |||||||
4171 | /// Return the ith exception type, where 0 <= i < getNumExceptions(). | ||||||
4172 | QualType getExceptionType(unsigned i) const { | ||||||
4173 | assert(i < getNumExceptions() && "Invalid exception number!")(static_cast <bool> (i < getNumExceptions() && "Invalid exception number!") ? void (0) : __assert_fail ("i < getNumExceptions() && \"Invalid exception number!\"" , "clang/include/clang/AST/Type.h", 4173, __extension__ __PRETTY_FUNCTION__ )); | ||||||
4174 | return exception_begin()[i]; | ||||||
4175 | } | ||||||
4176 | |||||||
4177 | /// Return the expression inside noexcept(expression), or a null pointer | ||||||
4178 | /// if there is none (because the exception spec is not of this form). | ||||||
4179 | Expr *getNoexceptExpr() const { | ||||||
4180 | if (!isComputedNoexcept(getExceptionSpecType())) | ||||||
4181 | return nullptr; | ||||||
4182 | return *getTrailingObjects<Expr *>(); | ||||||
4183 | } | ||||||
4184 | |||||||
4185 | /// If this function type has an exception specification which hasn't | ||||||
4186 | /// been determined yet (either because it has not been evaluated or because | ||||||
4187 | /// it has not been instantiated), this is the function whose exception | ||||||
4188 | /// specification is represented by this type. | ||||||
4189 | FunctionDecl *getExceptionSpecDecl() const { | ||||||
4190 | if (getExceptionSpecType() != EST_Uninstantiated && | ||||||
4191 | getExceptionSpecType() != EST_Unevaluated) | ||||||
4192 | return nullptr; | ||||||
4193 | return getTrailingObjects<FunctionDecl *>()[0]; | ||||||
4194 | } | ||||||
4195 | |||||||
4196 | /// If this function type has an uninstantiated exception | ||||||
4197 | /// specification, this is the function whose exception specification | ||||||
4198 | /// should be instantiated to find the exception specification for | ||||||
4199 | /// this type. | ||||||
4200 | FunctionDecl *getExceptionSpecTemplate() const { | ||||||
4201 | if (getExceptionSpecType() != EST_Uninstantiated) | ||||||
4202 | return nullptr; | ||||||
4203 | return getTrailingObjects<FunctionDecl *>()[1]; | ||||||
4204 | } | ||||||
4205 | |||||||
4206 | /// Determine whether this function type has a non-throwing exception | ||||||
4207 | /// specification. | ||||||
4208 | CanThrowResult canThrow() const; | ||||||
4209 | |||||||
4210 | /// Determine whether this function type has a non-throwing exception | ||||||
4211 | /// specification. If this depends on template arguments, returns | ||||||
4212 | /// \c ResultIfDependent. | ||||||
4213 | bool isNothrow(bool ResultIfDependent = false) const { | ||||||
4214 | return ResultIfDependent ? canThrow() != CT_Can : canThrow() == CT_Cannot; | ||||||
4215 | } | ||||||
4216 | |||||||
4217 | /// Whether this function prototype is variadic. | ||||||
4218 | bool isVariadic() const { return FunctionTypeBits.Variadic; } | ||||||
4219 | |||||||
4220 | SourceLocation getEllipsisLoc() const { | ||||||
4221 | return isVariadic() ? *getTrailingObjects<SourceLocation>() | ||||||
4222 | : SourceLocation(); | ||||||
4223 | } | ||||||
4224 | |||||||
4225 | /// Determines whether this function prototype contains a | ||||||
4226 | /// parameter pack at the end. | ||||||
4227 | /// | ||||||
4228 | /// A function template whose last parameter is a parameter pack can be | ||||||
4229 | /// called with an arbitrary number of arguments, much like a variadic | ||||||
4230 | /// function. | ||||||
4231 | bool isTemplateVariadic() const; | ||||||
4232 | |||||||
4233 | /// Whether this function prototype has a trailing return type. | ||||||
4234 | bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; } | ||||||
4235 | |||||||
4236 | Qualifiers getMethodQuals() const { | ||||||
4237 | if (hasExtQualifiers()) | ||||||
4238 | return *getTrailingObjects<Qualifiers>(); | ||||||
4239 | else | ||||||
4240 | return getFastTypeQuals(); | ||||||
4241 | } | ||||||
4242 | |||||||
4243 | /// Retrieve the ref-qualifier associated with this function type. | ||||||
4244 | RefQualifierKind getRefQualifier() const { | ||||||
4245 | return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier); | ||||||
4246 | } | ||||||
4247 | |||||||
4248 | using param_type_iterator = const QualType *; | ||||||
4249 | using param_type_range = llvm::iterator_range<param_type_iterator>; | ||||||
4250 | |||||||
4251 | param_type_range param_types() const { | ||||||
4252 | return param_type_range(param_type_begin(), param_type_end()); | ||||||
4253 | } | ||||||
4254 | |||||||
4255 | param_type_iterator param_type_begin() const { | ||||||
4256 | return getTrailingObjects<QualType>(); | ||||||
4257 | } | ||||||
4258 | |||||||
4259 | param_type_iterator param_type_end() const { | ||||||
4260 | return param_type_begin() + getNumParams(); | ||||||
4261 | } | ||||||
4262 | |||||||
4263 | using exception_iterator = const QualType *; | ||||||
4264 | |||||||
4265 | ArrayRef<QualType> exceptions() const { | ||||||
4266 | return llvm::makeArrayRef(exception_begin(), exception_end()); | ||||||
4267 | } | ||||||
4268 | |||||||
4269 | exception_iterator exception_begin() const { | ||||||
4270 | return reinterpret_cast<exception_iterator>( | ||||||
4271 | getTrailingObjects<ExceptionType>()); | ||||||
4272 | } | ||||||
4273 | |||||||
4274 | exception_iterator exception_end() const { | ||||||
4275 | return exception_begin() + getNumExceptions(); | ||||||
4276 | } | ||||||
4277 | |||||||
4278 | /// Is there any interesting extra information for any of the parameters | ||||||
4279 | /// of this function type? | ||||||
4280 | bool hasExtParameterInfos() const { | ||||||
4281 | return FunctionTypeBits.HasExtParameterInfos; | ||||||
4282 | } | ||||||
4283 | |||||||
4284 | ArrayRef<ExtParameterInfo> getExtParameterInfos() const { | ||||||
4285 | assert(hasExtParameterInfos())(static_cast <bool> (hasExtParameterInfos()) ? void (0) : __assert_fail ("hasExtParameterInfos()", "clang/include/clang/AST/Type.h" , 4285, __extension__ __PRETTY_FUNCTION__)); | ||||||
4286 | return ArrayRef<ExtParameterInfo>(getTrailingObjects<ExtParameterInfo>(), | ||||||
4287 | getNumParams()); | ||||||
4288 | } | ||||||
4289 | |||||||
4290 | /// Return a pointer to the beginning of the array of extra parameter | ||||||
4291 | /// information, if present, or else null if none of the parameters | ||||||
4292 | /// carry it. This is equivalent to getExtProtoInfo().ExtParameterInfos. | ||||||
4293 | const ExtParameterInfo *getExtParameterInfosOrNull() const { | ||||||
4294 | if (!hasExtParameterInfos()) | ||||||
4295 | return nullptr; | ||||||
4296 | return getTrailingObjects<ExtParameterInfo>(); | ||||||
4297 | } | ||||||
4298 | |||||||
4299 | ExtParameterInfo getExtParameterInfo(unsigned I) const { | ||||||
4300 | assert(I < getNumParams() && "parameter index out of range")(static_cast <bool> (I < getNumParams() && "parameter index out of range" ) ? void (0) : __assert_fail ("I < getNumParams() && \"parameter index out of range\"" , "clang/include/clang/AST/Type.h", 4300, __extension__ __PRETTY_FUNCTION__ )); | ||||||
4301 | if (hasExtParameterInfos()) | ||||||
4302 | return getTrailingObjects<ExtParameterInfo>()[I]; | ||||||
4303 | return ExtParameterInfo(); | ||||||
4304 | } | ||||||
4305 | |||||||
4306 | ParameterABI getParameterABI(unsigned I) const { | ||||||
4307 | assert(I < getNumParams() && "parameter index out of range")(static_cast <bool> (I < getNumParams() && "parameter index out of range" ) ? void (0) : __assert_fail ("I < getNumParams() && \"parameter index out of range\"" , "clang/include/clang/AST/Type.h", 4307, __extension__ __PRETTY_FUNCTION__ )); | ||||||
4308 | if (hasExtParameterInfos()) | ||||||
4309 | return getTrailingObjects<ExtParameterInfo>()[I].getABI(); | ||||||
4310 | return ParameterABI::Ordinary; | ||||||
4311 | } | ||||||
4312 | |||||||
4313 | bool isParamConsumed(unsigned I) const { | ||||||
4314 | assert(I < getNumParams() && "parameter index out of range")(static_cast <bool> (I < getNumParams() && "parameter index out of range" ) ? void (0) : __assert_fail ("I < getNumParams() && \"parameter index out of range\"" , "clang/include/clang/AST/Type.h", 4314, __extension__ __PRETTY_FUNCTION__ )); | ||||||
4315 | if (hasExtParameterInfos()) | ||||||
4316 | return getTrailingObjects<ExtParameterInfo>()[I].isConsumed(); | ||||||
4317 | return false; | ||||||
4318 | } | ||||||
4319 | |||||||
4320 | bool isSugared() const { return false; } | ||||||
4321 | QualType desugar() const { return QualType(this, 0); } | ||||||
4322 | |||||||
4323 | void printExceptionSpecification(raw_ostream &OS, | ||||||
4324 | const PrintingPolicy &Policy) const; | ||||||
4325 | |||||||
4326 | static bool classof(const Type *T) { | ||||||
4327 | return T->getTypeClass() == FunctionProto; | ||||||
4328 | } | ||||||
4329 | |||||||
4330 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); | ||||||
4331 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, | ||||||
4332 | param_type_iterator ArgTys, unsigned NumArgs, | ||||||
4333 | const ExtProtoInfo &EPI, const ASTContext &Context, | ||||||
4334 | bool Canonical); | ||||||
4335 | }; | ||||||
4336 | |||||||
4337 | /// Represents the dependent type named by a dependently-scoped | ||||||
4338 | /// typename using declaration, e.g. | ||||||
4339 | /// using typename Base<T>::foo; | ||||||
4340 | /// | ||||||
4341 | /// Template instantiation turns these into the underlying type. | ||||||
4342 | class UnresolvedUsingType : public Type { | ||||||
4343 | friend class ASTContext; // ASTContext creates these. | ||||||
4344 | |||||||
4345 | UnresolvedUsingTypenameDecl *Decl; | ||||||
4346 | |||||||
4347 | UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) | ||||||
4348 | : Type(UnresolvedUsing, QualType(), | ||||||
4349 | TypeDependence::DependentInstantiation), | ||||||
4350 | Decl(const_cast<UnresolvedUsingTypenameDecl *>(D)) {} | ||||||
4351 | |||||||
4352 | public: | ||||||
4353 | UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } | ||||||
4354 | |||||||
4355 | bool isSugared() const { return false; } | ||||||
4356 | QualType desugar() const { return QualType(this, 0); } | ||||||
4357 | |||||||
4358 | static bool classof(const Type *T) { | ||||||
4359 | return T->getTypeClass() == UnresolvedUsing; | ||||||
4360 | } | ||||||
4361 | |||||||
4362 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4363 | return Profile(ID, Decl); | ||||||
4364 | } | ||||||
4365 | |||||||
4366 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
4367 | UnresolvedUsingTypenameDecl *D) { | ||||||
4368 | ID.AddPointer(D); | ||||||
4369 | } | ||||||
4370 | }; | ||||||
4371 | |||||||
4372 | class UsingType : public Type, public llvm::FoldingSetNode { | ||||||
4373 | UsingShadowDecl *Found; | ||||||
4374 | friend class ASTContext; // ASTContext creates these. | ||||||
4375 | |||||||
4376 | UsingType(const UsingShadowDecl *Found, QualType Underlying, QualType Canon); | ||||||
4377 | |||||||
4378 | public: | ||||||
4379 | UsingShadowDecl *getFoundDecl() const { return Found; } | ||||||
4380 | QualType getUnderlyingType() const; | ||||||
4381 | |||||||
4382 | bool isSugared() const { return true; } | ||||||
4383 | QualType desugar() const { return getUnderlyingType(); } | ||||||
4384 | |||||||
4385 | void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Found); } | ||||||
4386 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
4387 | const UsingShadowDecl *Found) { | ||||||
4388 | ID.AddPointer(Found); | ||||||
4389 | } | ||||||
4390 | static bool classof(const Type *T) { return T->getTypeClass() == Using; } | ||||||
4391 | }; | ||||||
4392 | |||||||
4393 | class TypedefType : public Type { | ||||||
4394 | TypedefNameDecl *Decl; | ||||||
4395 | |||||||
4396 | private: | ||||||
4397 | friend class ASTContext; // ASTContext creates these. | ||||||
4398 | |||||||
4399 | TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType underlying, | ||||||
4400 | QualType can); | ||||||
4401 | |||||||
4402 | public: | ||||||
4403 | TypedefNameDecl *getDecl() const { return Decl; } | ||||||
4404 | |||||||
4405 | bool isSugared() const { return true; } | ||||||
4406 | QualType desugar() const; | ||||||
4407 | |||||||
4408 | static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } | ||||||
4409 | }; | ||||||
4410 | |||||||
4411 | /// Sugar type that represents a type that was qualified by a qualifier written | ||||||
4412 | /// as a macro invocation. | ||||||
4413 | class MacroQualifiedType : public Type { | ||||||
4414 | friend class ASTContext; // ASTContext creates these. | ||||||
4415 | |||||||
4416 | QualType UnderlyingTy; | ||||||
4417 | const IdentifierInfo *MacroII; | ||||||
4418 | |||||||
4419 | MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy, | ||||||
4420 | const IdentifierInfo *MacroII) | ||||||
4421 | : Type(MacroQualified, CanonTy, UnderlyingTy->getDependence()), | ||||||
4422 | UnderlyingTy(UnderlyingTy), MacroII(MacroII) { | ||||||
4423 | assert(isa<AttributedType>(UnderlyingTy) &&(static_cast <bool> (isa<AttributedType>(UnderlyingTy ) && "Expected a macro qualified type to only wrap attributed types." ) ? void (0) : __assert_fail ("isa<AttributedType>(UnderlyingTy) && \"Expected a macro qualified type to only wrap attributed types.\"" , "clang/include/clang/AST/Type.h", 4424, __extension__ __PRETTY_FUNCTION__ )) | ||||||
4424 | "Expected a macro qualified type to only wrap attributed types.")(static_cast <bool> (isa<AttributedType>(UnderlyingTy ) && "Expected a macro qualified type to only wrap attributed types." ) ? void (0) : __assert_fail ("isa<AttributedType>(UnderlyingTy) && \"Expected a macro qualified type to only wrap attributed types.\"" , "clang/include/clang/AST/Type.h", 4424, __extension__ __PRETTY_FUNCTION__ )); | ||||||
4425 | } | ||||||
4426 | |||||||
4427 | public: | ||||||
4428 | const IdentifierInfo *getMacroIdentifier() const { return MacroII; } | ||||||
4429 | QualType getUnderlyingType() const { return UnderlyingTy; } | ||||||
4430 | |||||||
4431 | /// Return this attributed type's modified type with no qualifiers attached to | ||||||
4432 | /// it. | ||||||
4433 | QualType getModifiedType() const; | ||||||
4434 | |||||||
4435 | bool isSugared() const { return true; } | ||||||
4436 | QualType desugar() const; | ||||||
4437 | |||||||
4438 | static bool classof(const Type *T) { | ||||||
4439 | return T->getTypeClass() == MacroQualified; | ||||||
4440 | } | ||||||
4441 | }; | ||||||
4442 | |||||||
4443 | /// Represents a `typeof` (or __typeof__) expression (a GCC extension). | ||||||
4444 | class TypeOfExprType : public Type { | ||||||
4445 | Expr *TOExpr; | ||||||
4446 | |||||||
4447 | protected: | ||||||
4448 | friend class ASTContext; // ASTContext creates these. | ||||||
4449 | |||||||
4450 | TypeOfExprType(Expr *E, QualType can = QualType()); | ||||||
4451 | |||||||
4452 | public: | ||||||
4453 | Expr *getUnderlyingExpr() const { return TOExpr; } | ||||||
4454 | |||||||
4455 | /// Remove a single level of sugar. | ||||||
4456 | QualType desugar() const; | ||||||
4457 | |||||||
4458 | /// Returns whether this type directly provides sugar. | ||||||
4459 | bool isSugared() const; | ||||||
4460 | |||||||
4461 | static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } | ||||||
4462 | }; | ||||||
4463 | |||||||
4464 | /// Internal representation of canonical, dependent | ||||||
4465 | /// `typeof(expr)` types. | ||||||
4466 | /// | ||||||
4467 | /// This class is used internally by the ASTContext to manage | ||||||
4468 | /// canonical, dependent types, only. Clients will only see instances | ||||||
4469 | /// of this class via TypeOfExprType nodes. | ||||||
4470 | class DependentTypeOfExprType | ||||||
4471 | : public TypeOfExprType, public llvm::FoldingSetNode { | ||||||
4472 | const ASTContext &Context; | ||||||
4473 | |||||||
4474 | public: | ||||||
4475 | DependentTypeOfExprType(const ASTContext &Context, Expr *E) | ||||||
4476 | : TypeOfExprType(E), Context(Context) {} | ||||||
4477 | |||||||
4478 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4479 | Profile(ID, Context, getUnderlyingExpr()); | ||||||
4480 | } | ||||||
4481 | |||||||
4482 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
4483 | Expr *E); | ||||||
4484 | }; | ||||||
4485 | |||||||
4486 | /// Represents `typeof(type)`, a GCC extension. | ||||||
4487 | class TypeOfType : public Type { | ||||||
4488 | friend class ASTContext; // ASTContext creates these. | ||||||
4489 | |||||||
4490 | QualType TOType; | ||||||
4491 | |||||||
4492 | TypeOfType(QualType T, QualType can) | ||||||
4493 | : Type(TypeOf, can, T->getDependence()), TOType(T) { | ||||||
4494 | assert(!isa<TypedefType>(can) && "Invalid canonical type")(static_cast <bool> (!isa<TypedefType>(can) && "Invalid canonical type") ? void (0) : __assert_fail ("!isa<TypedefType>(can) && \"Invalid canonical type\"" , "clang/include/clang/AST/Type.h", 4494, __extension__ __PRETTY_FUNCTION__ )); | ||||||
4495 | } | ||||||
4496 | |||||||
4497 | public: | ||||||
4498 | QualType getUnderlyingType() const { return TOType; } | ||||||
4499 | |||||||
4500 | /// Remove a single level of sugar. | ||||||
4501 | QualType desugar() const { return getUnderlyingType(); } | ||||||
4502 | |||||||
4503 | /// Returns whether this type directly provides sugar. | ||||||
4504 | bool isSugared() const { return true; } | ||||||
4505 | |||||||
4506 | static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } | ||||||
4507 | }; | ||||||
4508 | |||||||
4509 | /// Represents the type `decltype(expr)` (C++11). | ||||||
4510 | class DecltypeType : public Type { | ||||||
4511 | Expr *E; | ||||||
4512 | QualType UnderlyingType; | ||||||
4513 | |||||||
4514 | protected: | ||||||
4515 | friend class ASTContext; // ASTContext creates these. | ||||||
4516 | |||||||
4517 | DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType()); | ||||||
4518 | |||||||
4519 | public: | ||||||
4520 | Expr *getUnderlyingExpr() const { return E; } | ||||||
4521 | QualType getUnderlyingType() const { return UnderlyingType; } | ||||||
4522 | |||||||
4523 | /// Remove a single level of sugar. | ||||||
4524 | QualType desugar() const; | ||||||
4525 | |||||||
4526 | /// Returns whether this type directly provides sugar. | ||||||
4527 | bool isSugared() const; | ||||||
4528 | |||||||
4529 | static bool classof(const Type *T) { return T->getTypeClass() == Decltype; } | ||||||
4530 | }; | ||||||
4531 | |||||||
4532 | /// Internal representation of canonical, dependent | ||||||
4533 | /// decltype(expr) types. | ||||||
4534 | /// | ||||||
4535 | /// This class is used internally by the ASTContext to manage | ||||||
4536 | /// canonical, dependent types, only. Clients will only see instances | ||||||
4537 | /// of this class via DecltypeType nodes. | ||||||
4538 | class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode { | ||||||
4539 | const ASTContext &Context; | ||||||
4540 | |||||||
4541 | public: | ||||||
4542 | DependentDecltypeType(const ASTContext &Context, Expr *E); | ||||||
4543 | |||||||
4544 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4545 | Profile(ID, Context, getUnderlyingExpr()); | ||||||
4546 | } | ||||||
4547 | |||||||
4548 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
4549 | Expr *E); | ||||||
4550 | }; | ||||||
4551 | |||||||
4552 | /// A unary type transform, which is a type constructed from another. | ||||||
4553 | class UnaryTransformType : public Type { | ||||||
4554 | public: | ||||||
4555 | enum UTTKind { | ||||||
4556 | EnumUnderlyingType | ||||||
4557 | }; | ||||||
4558 | |||||||
4559 | private: | ||||||
4560 | /// The untransformed type. | ||||||
4561 | QualType BaseType; | ||||||
4562 | |||||||
4563 | /// The transformed type if not dependent, otherwise the same as BaseType. | ||||||
4564 | QualType UnderlyingType; | ||||||
4565 | |||||||
4566 | UTTKind UKind; | ||||||
4567 | |||||||
4568 | protected: | ||||||
4569 | friend class ASTContext; | ||||||
4570 | |||||||
4571 | UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind, | ||||||
4572 | QualType CanonicalTy); | ||||||
4573 | |||||||
4574 | public: | ||||||
4575 | bool isSugared() const { return !isDependentType(); } | ||||||
4576 | QualType desugar() const { return UnderlyingType; } | ||||||
4577 | |||||||
4578 | QualType getUnderlyingType() const { return UnderlyingType; } | ||||||
4579 | QualType getBaseType() const { return BaseType; } | ||||||
4580 | |||||||
4581 | UTTKind getUTTKind() const { return UKind; } | ||||||
4582 | |||||||
4583 | static bool classof(const Type *T) { | ||||||
4584 | return T->getTypeClass() == UnaryTransform; | ||||||
4585 | } | ||||||
4586 | }; | ||||||
4587 | |||||||
4588 | /// Internal representation of canonical, dependent | ||||||
4589 | /// __underlying_type(type) types. | ||||||
4590 | /// | ||||||
4591 | /// This class is used internally by the ASTContext to manage | ||||||
4592 | /// canonical, dependent types, only. Clients will only see instances | ||||||
4593 | /// of this class via UnaryTransformType nodes. | ||||||
4594 | class DependentUnaryTransformType : public UnaryTransformType, | ||||||
4595 | public llvm::FoldingSetNode { | ||||||
4596 | public: | ||||||
4597 | DependentUnaryTransformType(const ASTContext &C, QualType BaseType, | ||||||
4598 | UTTKind UKind); | ||||||
4599 | |||||||
4600 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4601 | Profile(ID, getBaseType(), getUTTKind()); | ||||||
4602 | } | ||||||
4603 | |||||||
4604 | static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType, | ||||||
4605 | UTTKind UKind) { | ||||||
4606 | ID.AddPointer(BaseType.getAsOpaquePtr()); | ||||||
4607 | ID.AddInteger((unsigned)UKind); | ||||||
4608 | } | ||||||
4609 | }; | ||||||
4610 | |||||||
4611 | class TagType : public Type { | ||||||
4612 | friend class ASTReader; | ||||||
4613 | template <class T> friend class serialization::AbstractTypeReader; | ||||||
4614 | |||||||
4615 | /// Stores the TagDecl associated with this type. The decl may point to any | ||||||
4616 | /// TagDecl that declares the entity. | ||||||
4617 | TagDecl *decl; | ||||||
4618 | |||||||
4619 | protected: | ||||||
4620 | TagType(TypeClass TC, const TagDecl *D, QualType can); | ||||||
4621 | |||||||
4622 | public: | ||||||
4623 | TagDecl *getDecl() const; | ||||||
4624 | |||||||
4625 | /// Determines whether this type is in the process of being defined. | ||||||
4626 | bool isBeingDefined() const; | ||||||
4627 | |||||||
4628 | static bool classof(const Type *T) { | ||||||
4629 | return T->getTypeClass() == Enum || T->getTypeClass() == Record; | ||||||
4630 | } | ||||||
4631 | }; | ||||||
4632 | |||||||
4633 | /// A helper class that allows the use of isa/cast/dyncast | ||||||
4634 | /// to detect TagType objects of structs/unions/classes. | ||||||
4635 | class RecordType : public TagType { | ||||||
4636 | protected: | ||||||
4637 | friend class ASTContext; // ASTContext creates these. | ||||||
4638 | |||||||
4639 | explicit RecordType(const RecordDecl *D) | ||||||
4640 | : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) {} | ||||||
4641 | explicit RecordType(TypeClass TC, RecordDecl *D) | ||||||
4642 | : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) {} | ||||||
4643 | |||||||
4644 | public: | ||||||
4645 | RecordDecl *getDecl() const { | ||||||
4646 | return reinterpret_cast<RecordDecl*>(TagType::getDecl()); | ||||||
4647 | } | ||||||
4648 | |||||||
4649 | /// Recursively check all fields in the record for const-ness. If any field | ||||||
4650 | /// is declared const, return true. Otherwise, return false. | ||||||
4651 | bool hasConstFields() const; | ||||||
4652 | |||||||
4653 | bool isSugared() const { return false; } | ||||||
4654 | QualType desugar() const { return QualType(this, 0); } | ||||||
4655 | |||||||
4656 | static bool classof(const Type *T) { return T->getTypeClass() == Record; } | ||||||
4657 | }; | ||||||
4658 | |||||||
4659 | /// A helper class that allows the use of isa/cast/dyncast | ||||||
4660 | /// to detect TagType objects of enums. | ||||||
4661 | class EnumType : public TagType { | ||||||
4662 | friend class ASTContext; // ASTContext creates these. | ||||||
4663 | |||||||
4664 | explicit EnumType(const EnumDecl *D) | ||||||
4665 | : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) {} | ||||||
4666 | |||||||
4667 | public: | ||||||
4668 | EnumDecl *getDecl() const { | ||||||
4669 | return reinterpret_cast<EnumDecl*>(TagType::getDecl()); | ||||||
4670 | } | ||||||
4671 | |||||||
4672 | bool isSugared() const { return false; } | ||||||
4673 | QualType desugar() const { return QualType(this, 0); } | ||||||
4674 | |||||||
4675 | static bool classof(const Type *T) { return T->getTypeClass() == Enum; } | ||||||
4676 | }; | ||||||
4677 | |||||||
4678 | /// An attributed type is a type to which a type attribute has been applied. | ||||||
4679 | /// | ||||||
4680 | /// The "modified type" is the fully-sugared type to which the attributed | ||||||
4681 | /// type was applied; generally it is not canonically equivalent to the | ||||||
4682 | /// attributed type. The "equivalent type" is the minimally-desugared type | ||||||
4683 | /// which the type is canonically equivalent to. | ||||||
4684 | /// | ||||||
4685 | /// For example, in the following attributed type: | ||||||
4686 | /// int32_t __attribute__((vector_size(16))) | ||||||
4687 | /// - the modified type is the TypedefType for int32_t | ||||||
4688 | /// - the equivalent type is VectorType(16, int32_t) | ||||||
4689 | /// - the canonical type is VectorType(16, int) | ||||||
4690 | class AttributedType : public Type, public llvm::FoldingSetNode { | ||||||
4691 | public: | ||||||
4692 | using Kind = attr::Kind; | ||||||
4693 | |||||||
4694 | private: | ||||||
4695 | friend class ASTContext; // ASTContext creates these | ||||||
4696 | |||||||
4697 | QualType ModifiedType; | ||||||
4698 | QualType EquivalentType; | ||||||
4699 | |||||||
4700 | AttributedType(QualType canon, attr::Kind attrKind, QualType modified, | ||||||
4701 | QualType equivalent) | ||||||
4702 | : Type(Attributed, canon, equivalent->getDependence()), | ||||||
4703 | ModifiedType(modified), EquivalentType(equivalent) { | ||||||
4704 | AttributedTypeBits.AttrKind = attrKind; | ||||||
4705 | } | ||||||
4706 | |||||||
4707 | public: | ||||||
4708 | Kind getAttrKind() const { | ||||||
4709 | return static_cast<Kind>(AttributedTypeBits.AttrKind); | ||||||
4710 | } | ||||||
4711 | |||||||
4712 | QualType getModifiedType() const { return ModifiedType; } | ||||||
4713 | QualType getEquivalentType() const { return EquivalentType; } | ||||||
4714 | |||||||
4715 | bool isSugared() const { return true; } | ||||||
4716 | QualType desugar() const { return getEquivalentType(); } | ||||||
4717 | |||||||
4718 | /// Does this attribute behave like a type qualifier? | ||||||
4719 | /// | ||||||
4720 | /// A type qualifier adjusts a type to provide specialized rules for | ||||||
4721 | /// a specific object, like the standard const and volatile qualifiers. | ||||||
4722 | /// This includes attributes controlling things like nullability, | ||||||
4723 | /// address spaces, and ARC ownership. The value of the object is still | ||||||
4724 | /// largely described by the modified type. | ||||||
4725 | /// | ||||||
4726 | /// In contrast, many type attributes "rewrite" their modified type to | ||||||
4727 | /// produce a fundamentally different type, not necessarily related in any | ||||||
4728 | /// formalizable way to the original type. For example, calling convention | ||||||
4729 | /// and vector attributes are not simple type qualifiers. | ||||||
4730 | /// | ||||||
4731 | /// Type qualifiers are often, but not always, reflected in the canonical | ||||||
4732 | /// type. | ||||||
4733 | bool isQualifier() const; | ||||||
4734 | |||||||
4735 | bool isMSTypeSpec() const; | ||||||
4736 | |||||||
4737 | bool isCallingConv() const; | ||||||
4738 | |||||||
4739 | llvm::Optional<NullabilityKind> getImmediateNullability() const; | ||||||
4740 | |||||||
4741 | /// Retrieve the attribute kind corresponding to the given | ||||||
4742 | /// nullability kind. | ||||||
4743 | static Kind getNullabilityAttrKind(NullabilityKind kind) { | ||||||
4744 | switch (kind) { | ||||||
4745 | case NullabilityKind::NonNull: | ||||||
4746 | return attr::TypeNonNull; | ||||||
4747 | |||||||
4748 | case NullabilityKind::Nullable: | ||||||
4749 | return attr::TypeNullable; | ||||||
4750 | |||||||
4751 | case NullabilityKind::NullableResult: | ||||||
4752 | return attr::TypeNullableResult; | ||||||
4753 | |||||||
4754 | case NullabilityKind::Unspecified: | ||||||
4755 | return attr::TypeNullUnspecified; | ||||||
4756 | } | ||||||
4757 | llvm_unreachable("Unknown nullability kind.")::llvm::llvm_unreachable_internal("Unknown nullability kind." , "clang/include/clang/AST/Type.h", 4757); | ||||||
4758 | } | ||||||
4759 | |||||||
4760 | /// Strip off the top-level nullability annotation on the given | ||||||
4761 | /// type, if it's there. | ||||||
4762 | /// | ||||||
4763 | /// \param T The type to strip. If the type is exactly an | ||||||
4764 | /// AttributedType specifying nullability (without looking through | ||||||
4765 | /// type sugar), the nullability is returned and this type changed | ||||||
4766 | /// to the underlying modified type. | ||||||
4767 | /// | ||||||
4768 | /// \returns the top-level nullability, if present. | ||||||
4769 | static Optional<NullabilityKind> stripOuterNullability(QualType &T); | ||||||
4770 | |||||||
4771 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4772 | Profile(ID, getAttrKind(), ModifiedType, EquivalentType); | ||||||
4773 | } | ||||||
4774 | |||||||
4775 | static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind, | ||||||
4776 | QualType modified, QualType equivalent) { | ||||||
4777 | ID.AddInteger(attrKind); | ||||||
4778 | ID.AddPointer(modified.getAsOpaquePtr()); | ||||||
4779 | ID.AddPointer(equivalent.getAsOpaquePtr()); | ||||||
4780 | } | ||||||
4781 | |||||||
4782 | static bool classof(const Type *T) { | ||||||
4783 | return T->getTypeClass() == Attributed; | ||||||
4784 | } | ||||||
4785 | }; | ||||||
4786 | |||||||
4787 | class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { | ||||||
4788 | friend class ASTContext; // ASTContext creates these | ||||||
4789 | |||||||
4790 | // Helper data collector for canonical types. | ||||||
4791 | struct CanonicalTTPTInfo { | ||||||
4792 | unsigned Depth : 15; | ||||||
4793 | unsigned ParameterPack : 1; | ||||||
4794 | unsigned Index : 16; | ||||||
4795 | }; | ||||||
4796 | |||||||
4797 | union { | ||||||
4798 | // Info for the canonical type. | ||||||
4799 | CanonicalTTPTInfo CanTTPTInfo; | ||||||
4800 | |||||||
4801 | // Info for the non-canonical type. | ||||||
4802 | TemplateTypeParmDecl *TTPDecl; | ||||||
4803 | }; | ||||||
4804 | |||||||
4805 | /// Build a non-canonical type. | ||||||
4806 | TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) | ||||||
4807 | : Type(TemplateTypeParm, Canon, | ||||||
4808 | TypeDependence::DependentInstantiation | | ||||||
4809 | (Canon->getDependence() & TypeDependence::UnexpandedPack)), | ||||||
4810 | TTPDecl(TTPDecl) {} | ||||||
4811 | |||||||
4812 | /// Build the canonical type. | ||||||
4813 | TemplateTypeParmType(unsigned D, unsigned I, bool PP) | ||||||
4814 | : Type(TemplateTypeParm, QualType(this, 0), | ||||||
4815 | TypeDependence::DependentInstantiation | | ||||||
4816 | (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)) { | ||||||
4817 | CanTTPTInfo.Depth = D; | ||||||
4818 | CanTTPTInfo.Index = I; | ||||||
4819 | CanTTPTInfo.ParameterPack = PP; | ||||||
4820 | } | ||||||
4821 | |||||||
4822 | const CanonicalTTPTInfo& getCanTTPTInfo() const { | ||||||
4823 | QualType Can = getCanonicalTypeInternal(); | ||||||
4824 | return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo; | ||||||
4825 | } | ||||||
4826 | |||||||
4827 | public: | ||||||
4828 | unsigned getDepth() const { return getCanTTPTInfo().Depth; } | ||||||
4829 | unsigned getIndex() const { return getCanTTPTInfo().Index; } | ||||||
4830 | bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; } | ||||||
4831 | |||||||
4832 | TemplateTypeParmDecl *getDecl() const { | ||||||
4833 | return isCanonicalUnqualified() ? nullptr : TTPDecl; | ||||||
4834 | } | ||||||
4835 | |||||||
4836 | IdentifierInfo *getIdentifier() const; | ||||||
4837 | |||||||
4838 | bool isSugared() const { return false; } | ||||||
4839 | QualType desugar() const { return QualType(this, 0); } | ||||||
4840 | |||||||
4841 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4842 | Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl()); | ||||||
4843 | } | ||||||
4844 | |||||||
4845 | static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, | ||||||
4846 | unsigned Index, bool ParameterPack, | ||||||
4847 | TemplateTypeParmDecl *TTPDecl) { | ||||||
4848 | ID.AddInteger(Depth); | ||||||
4849 | ID.AddInteger(Index); | ||||||
4850 | ID.AddBoolean(ParameterPack); | ||||||
4851 | ID.AddPointer(TTPDecl); | ||||||
4852 | } | ||||||
4853 | |||||||
4854 | static bool classof(const Type *T) { | ||||||
4855 | return T->getTypeClass() == TemplateTypeParm; | ||||||
4856 | } | ||||||
4857 | }; | ||||||
4858 | |||||||
4859 | /// Represents the result of substituting a type for a template | ||||||
4860 | /// type parameter. | ||||||
4861 | /// | ||||||
4862 | /// Within an instantiated template, all template type parameters have | ||||||
4863 | /// been replaced with these. They are used solely to record that a | ||||||
4864 | /// type was originally written as a template type parameter; | ||||||
4865 | /// therefore they are never canonical. | ||||||
4866 | class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode { | ||||||
4867 | friend class ASTContext; | ||||||
4868 | |||||||
4869 | // The original type parameter. | ||||||
4870 | const TemplateTypeParmType *Replaced; | ||||||
4871 | |||||||
4872 | SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) | ||||||
4873 | : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()), | ||||||
4874 | Replaced(Param) {} | ||||||
4875 | |||||||
4876 | public: | ||||||
4877 | /// Gets the template parameter that was substituted for. | ||||||
4878 | const TemplateTypeParmType *getReplacedParameter() const { | ||||||
4879 | return Replaced; | ||||||
4880 | } | ||||||
4881 | |||||||
4882 | /// Gets the type that was substituted for the template | ||||||
4883 | /// parameter. | ||||||
4884 | QualType getReplacementType() const { | ||||||
4885 | return getCanonicalTypeInternal(); | ||||||
4886 | } | ||||||
4887 | |||||||
4888 | bool isSugared() const { return true; } | ||||||
4889 | QualType desugar() const { return getReplacementType(); } | ||||||
4890 | |||||||
4891 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
4892 | Profile(ID, getReplacedParameter(), getReplacementType()); | ||||||
4893 | } | ||||||
4894 | |||||||
4895 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
4896 | const TemplateTypeParmType *Replaced, | ||||||
4897 | QualType Replacement) { | ||||||
4898 | ID.AddPointer(Replaced); | ||||||
4899 | ID.AddPointer(Replacement.getAsOpaquePtr()); | ||||||
4900 | } | ||||||
4901 | |||||||
4902 | static bool classof(const Type *T) { | ||||||
4903 | return T->getTypeClass() == SubstTemplateTypeParm; | ||||||
4904 | } | ||||||
4905 | }; | ||||||
4906 | |||||||
4907 | /// Represents the result of substituting a set of types for a template | ||||||
4908 | /// type parameter pack. | ||||||
4909 | /// | ||||||
4910 | /// When a pack expansion in the source code contains multiple parameter packs | ||||||
4911 | /// and those parameter packs correspond to different levels of template | ||||||
4912 | /// parameter lists, this type node is used to represent a template type | ||||||
4913 | /// parameter pack from an outer level, which has already had its argument pack | ||||||
4914 | /// substituted but that still lives within a pack expansion that itself | ||||||
4915 | /// could not be instantiated. When actually performing a substitution into | ||||||
4916 | /// that pack expansion (e.g., when all template parameters have corresponding | ||||||
4917 | /// arguments), this type will be replaced with the \c SubstTemplateTypeParmType | ||||||
4918 | /// at the current pack substitution index. | ||||||
4919 | class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { | ||||||
4920 | friend class ASTContext; | ||||||
4921 | |||||||
4922 | /// The original type parameter. | ||||||
4923 | const TemplateTypeParmType *Replaced; | ||||||
4924 | |||||||
4925 | /// A pointer to the set of template arguments that this | ||||||
4926 | /// parameter pack is instantiated with. | ||||||
4927 | const TemplateArgument *Arguments; | ||||||
4928 | |||||||
4929 | SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, | ||||||
4930 | QualType Canon, | ||||||
4931 | const TemplateArgument &ArgPack); | ||||||
4932 | |||||||
4933 | public: | ||||||
4934 | IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); } | ||||||
4935 | |||||||
4936 | /// Gets the template parameter that was substituted for. | ||||||
4937 | const TemplateTypeParmType *getReplacedParameter() const { | ||||||
4938 | return Replaced; | ||||||
4939 | } | ||||||
4940 | |||||||
4941 | unsigned getNumArgs() const { | ||||||
4942 | return SubstTemplateTypeParmPackTypeBits.NumArgs; | ||||||
4943 | } | ||||||
4944 | |||||||
4945 | bool isSugared() const { return false; } | ||||||
4946 | QualType desugar() const { return QualType(this, 0); } | ||||||
4947 | |||||||
4948 | TemplateArgument getArgumentPack() const; | ||||||
4949 | |||||||
4950 | void Profile(llvm::FoldingSetNodeID &ID); | ||||||
4951 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
4952 | const TemplateTypeParmType *Replaced, | ||||||
4953 | const TemplateArgument &ArgPack); | ||||||
4954 | |||||||
4955 | static bool classof(const Type *T) { | ||||||
4956 | return T->getTypeClass() == SubstTemplateTypeParmPack; | ||||||
4957 | } | ||||||
4958 | }; | ||||||
4959 | |||||||
4960 | /// Common base class for placeholders for types that get replaced by | ||||||
4961 | /// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced | ||||||
4962 | /// class template types, and constrained type names. | ||||||
4963 | /// | ||||||
4964 | /// These types are usually a placeholder for a deduced type. However, before | ||||||
4965 | /// the initializer is attached, or (usually) if the initializer is | ||||||
4966 | /// type-dependent, there is no deduced type and the type is canonical. In | ||||||
4967 | /// the latter case, it is also a dependent type. | ||||||
4968 | class DeducedType : public Type { | ||||||
4969 | QualType DeducedAsType; | ||||||
4970 | |||||||
4971 | protected: | ||||||
4972 | DeducedType(TypeClass TC, QualType DeducedAsType, | ||||||
4973 | TypeDependence ExtraDependence, QualType Canon) | ||||||
4974 | : Type(TC, Canon, | ||||||
4975 | ExtraDependence | (DeducedAsType.isNull() | ||||||
4976 | ? TypeDependence::None | ||||||
4977 | : DeducedAsType->getDependence() & | ||||||
4978 | ~TypeDependence::VariablyModified)), | ||||||
4979 | DeducedAsType(DeducedAsType) {} | ||||||
4980 | |||||||
4981 | public: | ||||||
4982 | bool isSugared() const { return !DeducedAsType.isNull(); } | ||||||
4983 | QualType desugar() const { | ||||||
4984 | return isSugared() ? DeducedAsType : QualType(this, 0); | ||||||
4985 | } | ||||||
4986 | |||||||
4987 | /// Get the type deduced for this placeholder type, or null if it | ||||||
4988 | /// has not been deduced. | ||||||
4989 | QualType getDeducedType() const { return DeducedAsType; } | ||||||
4990 | bool isDeduced() const { | ||||||
4991 | return !DeducedAsType.isNull() || isDependentType(); | ||||||
4992 | } | ||||||
4993 | |||||||
4994 | static bool classof(const Type *T) { | ||||||
4995 | return T->getTypeClass() == Auto || | ||||||
4996 | T->getTypeClass() == DeducedTemplateSpecialization; | ||||||
4997 | } | ||||||
4998 | }; | ||||||
4999 | |||||||
5000 | /// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained | ||||||
5001 | /// by a type-constraint. | ||||||
5002 | class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode { | ||||||
5003 | friend class ASTContext; // ASTContext creates these | ||||||
5004 | |||||||
5005 | ConceptDecl *TypeConstraintConcept; | ||||||
5006 | |||||||
5007 | AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, | ||||||
5008 | TypeDependence ExtraDependence, QualType Canon, ConceptDecl *CD, | ||||||
5009 | ArrayRef<TemplateArgument> TypeConstraintArgs); | ||||||
5010 | |||||||
5011 | const TemplateArgument *getArgBuffer() const { | ||||||
5012 | return reinterpret_cast<const TemplateArgument*>(this+1); | ||||||
5013 | } | ||||||
5014 | |||||||
5015 | TemplateArgument *getArgBuffer() { | ||||||
5016 | return reinterpret_cast<TemplateArgument*>(this+1); | ||||||
5017 | } | ||||||
5018 | |||||||
5019 | public: | ||||||
5020 | /// Retrieve the template arguments. | ||||||
5021 | const TemplateArgument *getArgs() const { | ||||||
5022 | return getArgBuffer(); | ||||||
5023 | } | ||||||
5024 | |||||||
5025 | /// Retrieve the number of template arguments. | ||||||
5026 | unsigned getNumArgs() const { | ||||||
5027 | return AutoTypeBits.NumArgs; | ||||||
5028 | } | ||||||
5029 | |||||||
5030 | const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h | ||||||
5031 | |||||||
5032 | ArrayRef<TemplateArgument> getTypeConstraintArguments() const { | ||||||
5033 | return {getArgs(), getNumArgs()}; | ||||||
5034 | } | ||||||
5035 | |||||||
5036 | ConceptDecl *getTypeConstraintConcept() const { | ||||||
5037 | return TypeConstraintConcept; | ||||||
5038 | } | ||||||
5039 | |||||||
5040 | bool isConstrained() const { | ||||||
5041 | return TypeConstraintConcept != nullptr; | ||||||
5042 | } | ||||||
5043 | |||||||
5044 | bool isDecltypeAuto() const { | ||||||
5045 | return getKeyword() == AutoTypeKeyword::DecltypeAuto; | ||||||
5046 | } | ||||||
5047 | |||||||
5048 | AutoTypeKeyword getKeyword() const { | ||||||
5049 | return (AutoTypeKeyword)AutoTypeBits.Keyword; | ||||||
5050 | } | ||||||
5051 | |||||||
5052 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { | ||||||
5053 | Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(), | ||||||
5054 | getTypeConstraintConcept(), getTypeConstraintArguments()); | ||||||
5055 | } | ||||||
5056 | |||||||
5057 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
5058 | QualType Deduced, AutoTypeKeyword Keyword, | ||||||
5059 | bool IsDependent, ConceptDecl *CD, | ||||||
5060 | ArrayRef<TemplateArgument> Arguments); | ||||||
5061 | |||||||
5062 | static bool classof(const Type *T) { | ||||||
5063 | return T->getTypeClass() == Auto; | ||||||
5064 | } | ||||||
5065 | }; | ||||||
5066 | |||||||
5067 | /// Represents a C++17 deduced template specialization type. | ||||||
5068 | class DeducedTemplateSpecializationType : public DeducedType, | ||||||
5069 | public llvm::FoldingSetNode { | ||||||
5070 | friend class ASTContext; // ASTContext creates these | ||||||
5071 | |||||||
5072 | /// The name of the template whose arguments will be deduced. | ||||||
5073 | TemplateName Template; | ||||||
5074 | |||||||
5075 | DeducedTemplateSpecializationType(TemplateName Template, | ||||||
5076 | QualType DeducedAsType, | ||||||
5077 | bool IsDeducedAsDependent) | ||||||
5078 | : DeducedType(DeducedTemplateSpecialization, DeducedAsType, | ||||||
5079 | toTypeDependence(Template.getDependence()) | | ||||||
5080 | (IsDeducedAsDependent | ||||||
5081 | ? TypeDependence::DependentInstantiation | ||||||
5082 | : TypeDependence::None), | ||||||
5083 | DeducedAsType.isNull() ? QualType(this, 0) | ||||||
5084 | : DeducedAsType.getCanonicalType()), | ||||||
5085 | Template(Template) {} | ||||||
5086 | |||||||
5087 | public: | ||||||
5088 | /// Retrieve the name of the template that we are deducing. | ||||||
5089 | TemplateName getTemplateName() const { return Template;} | ||||||
5090 | |||||||
5091 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
5092 | Profile(ID, getTemplateName(), getDeducedType(), isDependentType()); | ||||||
5093 | } | ||||||
5094 | |||||||
5095 | static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template, | ||||||
5096 | QualType Deduced, bool IsDependent) { | ||||||
5097 | Template.Profile(ID); | ||||||
5098 | QualType CanonicalType = | ||||||
5099 | Deduced.isNull() ? Deduced : Deduced.getCanonicalType(); | ||||||
5100 | ID.AddPointer(CanonicalType.getAsOpaquePtr()); | ||||||
5101 | ID.AddBoolean(IsDependent || Template.isDependent()); | ||||||
5102 | } | ||||||
5103 | |||||||
5104 | static bool classof(const Type *T) { | ||||||
5105 | return T->getTypeClass() == DeducedTemplateSpecialization; | ||||||
5106 | } | ||||||
5107 | }; | ||||||
5108 | |||||||
5109 | /// Represents a type template specialization; the template | ||||||
5110 | /// must be a class template, a type alias template, or a template | ||||||
5111 | /// template parameter. A template which cannot be resolved to one of | ||||||
5112 | /// these, e.g. because it is written with a dependent scope | ||||||
5113 | /// specifier, is instead represented as a | ||||||
5114 | /// @c DependentTemplateSpecializationType. | ||||||
5115 | /// | ||||||
5116 | /// A non-dependent template specialization type is always "sugar", | ||||||
5117 | /// typically for a \c RecordType. For example, a class template | ||||||
5118 | /// specialization type of \c vector<int> will refer to a tag type for | ||||||
5119 | /// the instantiation \c std::vector<int, std::allocator<int>> | ||||||
5120 | /// | ||||||
5121 | /// Template specializations are dependent if either the template or | ||||||
5122 | /// any of the template arguments are dependent, in which case the | ||||||
5123 | /// type may also be canonical. | ||||||
5124 | /// | ||||||
5125 | /// Instances of this type are allocated with a trailing array of | ||||||
5126 | /// TemplateArguments, followed by a QualType representing the | ||||||
5127 | /// non-canonical aliased type when the template is a type alias | ||||||
5128 | /// template. | ||||||
5129 | class alignas(8) TemplateSpecializationType | ||||||
5130 | : public Type, | ||||||
5131 | public llvm::FoldingSetNode { | ||||||
5132 | friend class ASTContext; // ASTContext creates these | ||||||
5133 | |||||||
5134 | /// The name of the template being specialized. This is | ||||||
5135 | /// either a TemplateName::Template (in which case it is a | ||||||
5136 | /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a | ||||||
5137 | /// TypeAliasTemplateDecl*), a | ||||||
5138 | /// TemplateName::SubstTemplateTemplateParmPack, or a | ||||||
5139 | /// TemplateName::SubstTemplateTemplateParm (in which case the | ||||||
5140 | /// replacement must, recursively, be one of these). | ||||||
5141 | TemplateName Template; | ||||||
5142 | |||||||
5143 | TemplateSpecializationType(TemplateName T, | ||||||
5144 | ArrayRef<TemplateArgument> Args, | ||||||
5145 | QualType Canon, | ||||||
5146 | QualType Aliased); | ||||||
5147 | |||||||
5148 | public: | ||||||
5149 | /// Determine whether any of the given template arguments are dependent. | ||||||
5150 | /// | ||||||
5151 | /// The converted arguments should be supplied when known; whether an | ||||||
5152 | /// argument is dependent can depend on the conversions performed on it | ||||||
5153 | /// (for example, a 'const int' passed as a template argument might be | ||||||
5154 | /// dependent if the parameter is a reference but non-dependent if the | ||||||
5155 | /// parameter is an int). | ||||||
5156 | /// | ||||||
5157 | /// Note that the \p Args parameter is unused: this is intentional, to remind | ||||||
5158 | /// the caller that they need to pass in the converted arguments, not the | ||||||
5159 | /// specified arguments. | ||||||
5160 | static bool | ||||||
5161 | anyDependentTemplateArguments(ArrayRef<TemplateArgumentLoc> Args, | ||||||
5162 | ArrayRef<TemplateArgument> Converted); | ||||||
5163 | static bool | ||||||
5164 | anyDependentTemplateArguments(const TemplateArgumentListInfo &, | ||||||
5165 | ArrayRef<TemplateArgument> Converted); | ||||||
5166 | static bool anyInstantiationDependentTemplateArguments( | ||||||
5167 | ArrayRef<TemplateArgumentLoc> Args); | ||||||
5168 | |||||||
5169 | /// True if this template specialization type matches a current | ||||||
5170 | /// instantiation in the context in which it is found. | ||||||
5171 | bool isCurrentInstantiation() const { | ||||||
5172 | return isa<InjectedClassNameType>(getCanonicalTypeInternal()); | ||||||
5173 | } | ||||||
5174 | |||||||
5175 | /// Determine if this template specialization type is for a type alias | ||||||
5176 | /// template that has been substituted. | ||||||
5177 | /// | ||||||
5178 | /// Nearly every template specialization type whose template is an alias | ||||||
5179 | /// template will be substituted. However, this is not the case when | ||||||
5180 | /// the specialization contains a pack expansion but the template alias | ||||||
5181 | /// does not have a corresponding parameter pack, e.g., | ||||||
5182 | /// | ||||||
5183 | /// \code | ||||||
5184 | /// template<typename T, typename U, typename V> struct S; | ||||||
5185 | /// template<typename T, typename U> using A = S<T, int, U>; | ||||||
5186 | /// template<typename... Ts> struct X { | ||||||
5187 | /// typedef A<Ts...> type; // not a type alias | ||||||
5188 | /// }; | ||||||
5189 | /// \endcode | ||||||
5190 | bool isTypeAlias() const { return TemplateSpecializationTypeBits.TypeAlias; } | ||||||
5191 | |||||||
5192 | /// Get the aliased type, if this is a specialization of a type alias | ||||||
5193 | /// template. | ||||||
5194 | QualType getAliasedType() const { | ||||||
5195 | assert(isTypeAlias() && "not a type alias template specialization")(static_cast <bool> (isTypeAlias() && "not a type alias template specialization" ) ? void (0) : __assert_fail ("isTypeAlias() && \"not a type alias template specialization\"" , "clang/include/clang/AST/Type.h", 5195, __extension__ __PRETTY_FUNCTION__ )); | ||||||
5196 | return *reinterpret_cast<const QualType*>(end()); | ||||||
5197 | } | ||||||
5198 | |||||||
5199 | using iterator = const TemplateArgument *; | ||||||
5200 | |||||||
5201 | iterator begin() const { return getArgs(); } | ||||||
5202 | iterator end() const; // defined inline in TemplateBase.h | ||||||
5203 | |||||||
5204 | /// Retrieve the name of the template that we are specializing. | ||||||
5205 | TemplateName getTemplateName() const { return Template; } | ||||||
5206 | |||||||
5207 | /// Retrieve the template arguments. | ||||||
5208 | const TemplateArgument *getArgs() const { | ||||||
5209 | return reinterpret_cast<const TemplateArgument *>(this + 1); | ||||||
5210 | } | ||||||
5211 | |||||||
5212 | /// Retrieve the number of template arguments. | ||||||
5213 | unsigned getNumArgs() const { | ||||||
5214 | return TemplateSpecializationTypeBits.NumArgs; | ||||||
5215 | } | ||||||
5216 | |||||||
5217 | /// Retrieve a specific template argument as a type. | ||||||
5218 | /// \pre \c isArgType(Arg) | ||||||
5219 | const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h | ||||||
5220 | |||||||
5221 | ArrayRef<TemplateArgument> template_arguments() const { | ||||||
5222 | return {getArgs(), getNumArgs()}; | ||||||
5223 | } | ||||||
5224 | |||||||
5225 | bool isSugared() const { | ||||||
5226 | return !isDependentType() || isCurrentInstantiation() || isTypeAlias(); | ||||||
5227 | } | ||||||
5228 | |||||||
5229 | QualType desugar() const { | ||||||
5230 | return isTypeAlias() ? getAliasedType() : getCanonicalTypeInternal(); | ||||||
5231 | } | ||||||
5232 | |||||||
5233 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { | ||||||
5234 | Profile(ID, Template, template_arguments(), Ctx); | ||||||
5235 | if (isTypeAlias()) | ||||||
5236 | getAliasedType().Profile(ID); | ||||||
5237 | } | ||||||
5238 | |||||||
5239 | static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T, | ||||||
5240 | ArrayRef<TemplateArgument> Args, | ||||||
5241 | const ASTContext &Context); | ||||||
5242 | |||||||
5243 | static bool classof(const Type *T) { | ||||||
5244 | return T->getTypeClass() == TemplateSpecialization; | ||||||
5245 | } | ||||||
5246 | }; | ||||||
5247 | |||||||
5248 | /// Print a template argument list, including the '<' and '>' | ||||||
5249 | /// enclosing the template arguments. | ||||||
5250 | void printTemplateArgumentList(raw_ostream &OS, | ||||||
5251 | ArrayRef<TemplateArgument> Args, | ||||||
5252 | const PrintingPolicy &Policy, | ||||||
5253 | const TemplateParameterList *TPL = nullptr); | ||||||
5254 | |||||||
5255 | void printTemplateArgumentList(raw_ostream &OS, | ||||||
5256 | ArrayRef<TemplateArgumentLoc> Args, | ||||||
5257 | const PrintingPolicy &Policy, | ||||||
5258 | const TemplateParameterList *TPL = nullptr); | ||||||
5259 | |||||||
5260 | void printTemplateArgumentList(raw_ostream &OS, | ||||||
5261 | const TemplateArgumentListInfo &Args, | ||||||
5262 | const PrintingPolicy &Policy, | ||||||
5263 | const TemplateParameterList *TPL = nullptr); | ||||||
5264 | |||||||
5265 | /// The injected class name of a C++ class template or class | ||||||
5266 | /// template partial specialization. Used to record that a type was | ||||||
5267 | /// spelled with a bare identifier rather than as a template-id; the | ||||||
5268 | /// equivalent for non-templated classes is just RecordType. | ||||||
5269 | /// | ||||||
5270 | /// Injected class name types are always dependent. Template | ||||||
5271 | /// instantiation turns these into RecordTypes. | ||||||
5272 | /// | ||||||
5273 | /// Injected class name types are always canonical. This works | ||||||
5274 | /// because it is impossible to compare an injected class name type | ||||||
5275 | /// with the corresponding non-injected template type, for the same | ||||||
5276 | /// reason that it is impossible to directly compare template | ||||||
5277 | /// parameters from different dependent contexts: injected class name | ||||||
5278 | /// types can only occur within the scope of a particular templated | ||||||
5279 | /// declaration, and within that scope every template specialization | ||||||
5280 | /// will canonicalize to the injected class name (when appropriate | ||||||
5281 | /// according to the rules of the language). | ||||||
5282 | class InjectedClassNameType : public Type { | ||||||
5283 | friend class ASTContext; // ASTContext creates these. | ||||||
5284 | friend class ASTNodeImporter; | ||||||
5285 | friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not | ||||||
5286 | // currently suitable for AST reading, too much | ||||||
5287 | // interdependencies. | ||||||
5288 | template <class T> friend class serialization::AbstractTypeReader; | ||||||
5289 | |||||||
5290 | CXXRecordDecl *Decl; | ||||||
5291 | |||||||
5292 | /// The template specialization which this type represents. | ||||||
5293 | /// For example, in | ||||||
5294 | /// template <class T> class A { ... }; | ||||||
5295 | /// this is A<T>, whereas in | ||||||
5296 | /// template <class X, class Y> class A<B<X,Y> > { ... }; | ||||||
5297 | /// this is A<B<X,Y> >. | ||||||
5298 | /// | ||||||
5299 | /// It is always unqualified, always a template specialization type, | ||||||
5300 | /// and always dependent. | ||||||
5301 | QualType InjectedType; | ||||||
5302 | |||||||
5303 | InjectedClassNameType(CXXRecordDecl *D, QualType TST) | ||||||
5304 | : Type(InjectedClassName, QualType(), | ||||||
5305 | TypeDependence::DependentInstantiation), | ||||||
5306 | Decl(D), InjectedType(TST) { | ||||||
5307 | assert(isa<TemplateSpecializationType>(TST))(static_cast <bool> (isa<TemplateSpecializationType> (TST)) ? void (0) : __assert_fail ("isa<TemplateSpecializationType>(TST)" , "clang/include/clang/AST/Type.h", 5307, __extension__ __PRETTY_FUNCTION__ )); | ||||||
5308 | assert(!TST.hasQualifiers())(static_cast <bool> (!TST.hasQualifiers()) ? void (0) : __assert_fail ("!TST.hasQualifiers()", "clang/include/clang/AST/Type.h" , 5308, __extension__ __PRETTY_FUNCTION__)); | ||||||
5309 | assert(TST->isDependentType())(static_cast <bool> (TST->isDependentType()) ? void ( 0) : __assert_fail ("TST->isDependentType()", "clang/include/clang/AST/Type.h" , 5309, __extension__ __PRETTY_FUNCTION__)); | ||||||
5310 | } | ||||||
5311 | |||||||
5312 | public: | ||||||
5313 | QualType getInjectedSpecializationType() const { return InjectedType; } | ||||||
5314 | |||||||
5315 | const TemplateSpecializationType *getInjectedTST() const { | ||||||
5316 | return cast<TemplateSpecializationType>(InjectedType.getTypePtr()); | ||||||
5317 | } | ||||||
5318 | |||||||
5319 | TemplateName getTemplateName() const { | ||||||
5320 | return getInjectedTST()->getTemplateName(); | ||||||
5321 | } | ||||||
5322 | |||||||
5323 | CXXRecordDecl *getDecl() const; | ||||||
5324 | |||||||
5325 | bool isSugared() const { return false; } | ||||||
5326 | QualType desugar() const { return QualType(this, 0); } | ||||||
5327 | |||||||
5328 | static bool classof(const Type *T) { | ||||||
5329 | return T->getTypeClass() == InjectedClassName; | ||||||
5330 | } | ||||||
5331 | }; | ||||||
5332 | |||||||
5333 | /// The kind of a tag type. | ||||||
5334 | enum TagTypeKind { | ||||||
5335 | /// The "struct" keyword. | ||||||
5336 | TTK_Struct, | ||||||
5337 | |||||||
5338 | /// The "__interface" keyword. | ||||||
5339 | TTK_Interface, | ||||||
5340 | |||||||
5341 | /// The "union" keyword. | ||||||
5342 | TTK_Union, | ||||||
5343 | |||||||
5344 | /// The "class" keyword. | ||||||
5345 | TTK_Class, | ||||||
5346 | |||||||
5347 | /// The "enum" keyword. | ||||||
5348 | TTK_Enum | ||||||
5349 | }; | ||||||
5350 | |||||||
5351 | /// The elaboration keyword that precedes a qualified type name or | ||||||
5352 | /// introduces an elaborated-type-specifier. | ||||||
5353 | enum ElaboratedTypeKeyword { | ||||||
5354 | /// The "struct" keyword introduces the elaborated-type-specifier. | ||||||
5355 | ETK_Struct, | ||||||
5356 | |||||||
5357 | /// The "__interface" keyword introduces the elaborated-type-specifier. | ||||||
5358 | ETK_Interface, | ||||||
5359 | |||||||
5360 | /// The "union" keyword introduces the elaborated-type-specifier. | ||||||
5361 | ETK_Union, | ||||||
5362 | |||||||
5363 | /// The "class" keyword introduces the elaborated-type-specifier. | ||||||
5364 | ETK_Class, | ||||||
5365 | |||||||
5366 | /// The "enum" keyword introduces the elaborated-type-specifier. | ||||||
5367 | ETK_Enum, | ||||||
5368 | |||||||
5369 | /// The "typename" keyword precedes the qualified type name, e.g., | ||||||
5370 | /// \c typename T::type. | ||||||
5371 | ETK_Typename, | ||||||
5372 | |||||||
5373 | /// No keyword precedes the qualified type name. | ||||||
5374 | ETK_None | ||||||
5375 | }; | ||||||
5376 | |||||||
5377 | /// A helper class for Type nodes having an ElaboratedTypeKeyword. | ||||||
5378 | /// The keyword in stored in the free bits of the base class. | ||||||
5379 | /// Also provides a few static helpers for converting and printing | ||||||
5380 | /// elaborated type keyword and tag type kind enumerations. | ||||||
5381 | class TypeWithKeyword : public Type { | ||||||
5382 | protected: | ||||||
5383 | TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, | ||||||
5384 | QualType Canonical, TypeDependence Dependence) | ||||||
5385 | : Type(tc, Canonical, Dependence) { | ||||||
5386 | TypeWithKeywordBits.Keyword = Keyword; | ||||||
5387 | } | ||||||
5388 | |||||||
5389 | public: | ||||||
5390 | ElaboratedTypeKeyword getKeyword() const { | ||||||
5391 | return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword); | ||||||
5392 | } | ||||||
5393 | |||||||
5394 | /// Converts a type specifier (DeclSpec::TST) into an elaborated type keyword. | ||||||
5395 | static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec); | ||||||
5396 | |||||||
5397 | /// Converts a type specifier (DeclSpec::TST) into a tag type kind. | ||||||
5398 | /// It is an error to provide a type specifier which *isn't* a tag kind here. | ||||||
5399 | static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec); | ||||||
5400 | |||||||
5401 | /// Converts a TagTypeKind into an elaborated type keyword. | ||||||
5402 | static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag); | ||||||
5403 | |||||||
5404 | /// Converts an elaborated type keyword into a TagTypeKind. | ||||||
5405 | /// It is an error to provide an elaborated type keyword | ||||||
5406 | /// which *isn't* a tag kind here. | ||||||
5407 | static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword); | ||||||
5408 | |||||||
5409 | static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword); | ||||||
5410 | |||||||
5411 | static StringRef getKeywordName(ElaboratedTypeKeyword Keyword); | ||||||
5412 | |||||||
5413 | static StringRef getTagTypeKindName(TagTypeKind Kind) { | ||||||
5414 | return getKeywordName(getKeywordForTagTypeKind(Kind)); | ||||||
5415 | } | ||||||
5416 | |||||||
5417 | class CannotCastToThisType {}; | ||||||
5418 | static CannotCastToThisType classof(const Type *); | ||||||
5419 | }; | ||||||
5420 | |||||||
5421 | /// Represents a type that was referred to using an elaborated type | ||||||
5422 | /// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type, | ||||||
5423 | /// or both. | ||||||
5424 | /// | ||||||
5425 | /// This type is used to keep track of a type name as written in the | ||||||
5426 | /// source code, including tag keywords and any nested-name-specifiers. | ||||||
5427 | /// The type itself is always "sugar", used to express what was written | ||||||
5428 | /// in the source code but containing no additional semantic information. | ||||||
5429 | class ElaboratedType final | ||||||
5430 | : public TypeWithKeyword, | ||||||
5431 | public llvm::FoldingSetNode, | ||||||
5432 | private llvm::TrailingObjects<ElaboratedType, TagDecl *> { | ||||||
5433 | friend class ASTContext; // ASTContext creates these | ||||||
5434 | friend TrailingObjects; | ||||||
5435 | |||||||
5436 | /// The nested name specifier containing the qualifier. | ||||||
5437 | NestedNameSpecifier *NNS; | ||||||
5438 | |||||||
5439 | /// The type that this qualified name refers to. | ||||||
5440 | QualType NamedType; | ||||||
5441 | |||||||
5442 | /// The (re)declaration of this tag type owned by this occurrence is stored | ||||||
5443 | /// as a trailing object if there is one. Use getOwnedTagDecl to obtain | ||||||
5444 | /// it, or obtain a null pointer if there is none. | ||||||
5445 | |||||||
5446 | ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, | ||||||
5447 | QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl) | ||||||
5448 | : TypeWithKeyword(Keyword, Elaborated, CanonType, | ||||||
5449 | // Any semantic dependence on the qualifier will have | ||||||
5450 | // been incorporated into NamedType. We still need to | ||||||
5451 | // track syntactic (instantiation / error / pack) | ||||||
5452 | // dependence on the qualifier. | ||||||
5453 | NamedType->getDependence() | | ||||||
5454 | (NNS ? toSyntacticDependence( | ||||||
5455 | toTypeDependence(NNS->getDependence())) | ||||||
5456 | : TypeDependence::None)), | ||||||
5457 | NNS(NNS), NamedType(NamedType) { | ||||||
5458 | ElaboratedTypeBits.HasOwnedTagDecl = false; | ||||||
5459 | if (OwnedTagDecl) { | ||||||
5460 | ElaboratedTypeBits.HasOwnedTagDecl = true; | ||||||
5461 | *getTrailingObjects<TagDecl *>() = OwnedTagDecl; | ||||||
5462 | } | ||||||
5463 | assert(!(Keyword == ETK_None && NNS == nullptr) &&(static_cast <bool> (!(Keyword == ETK_None && NNS == nullptr) && "ElaboratedType cannot have elaborated type keyword " "and name qualifier both null.") ? void (0) : __assert_fail ( "!(Keyword == ETK_None && NNS == nullptr) && \"ElaboratedType cannot have elaborated type keyword \" \"and name qualifier both null.\"" , "clang/include/clang/AST/Type.h", 5465, __extension__ __PRETTY_FUNCTION__ )) | ||||||
5464 | "ElaboratedType cannot have elaborated type keyword "(static_cast <bool> (!(Keyword == ETK_None && NNS == nullptr) && "ElaboratedType cannot have elaborated type keyword " "and name qualifier both null.") ? void (0) : __assert_fail ( "!(Keyword == ETK_None && NNS == nullptr) && \"ElaboratedType cannot have elaborated type keyword \" \"and name qualifier both null.\"" , "clang/include/clang/AST/Type.h", 5465, __extension__ __PRETTY_FUNCTION__ )) | ||||||
5465 | "and name qualifier both null.")(static_cast <bool> (!(Keyword == ETK_None && NNS == nullptr) && "ElaboratedType cannot have elaborated type keyword " "and name qualifier both null.") ? void (0) : __assert_fail ( "!(Keyword == ETK_None && NNS == nullptr) && \"ElaboratedType cannot have elaborated type keyword \" \"and name qualifier both null.\"" , "clang/include/clang/AST/Type.h", 5465, __extension__ __PRETTY_FUNCTION__ )); | ||||||
5466 | } | ||||||
5467 | |||||||
5468 | public: | ||||||
5469 | /// Retrieve the qualification on this type. | ||||||
5470 | NestedNameSpecifier *getQualifier() const { return NNS; } | ||||||
5471 | |||||||
5472 | /// Retrieve the type named by the qualified-id. | ||||||
5473 | QualType getNamedType() const { return NamedType; } | ||||||
5474 | |||||||
5475 | /// Remove a single level of sugar. | ||||||
5476 | QualType desugar() const { return getNamedType(); } | ||||||
5477 | |||||||
5478 | /// Returns whether this type directly provides sugar. | ||||||
5479 | bool isSugared() const { return true; } | ||||||
5480 | |||||||
5481 | /// Return the (re)declaration of this type owned by this occurrence of this | ||||||
5482 | /// type, or nullptr if there is none. | ||||||
5483 | TagDecl *getOwnedTagDecl() const { | ||||||
5484 | return ElaboratedTypeBits.HasOwnedTagDecl ? *getTrailingObjects<TagDecl *>() | ||||||
5485 | : nullptr; | ||||||
5486 | } | ||||||
5487 | |||||||
5488 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
5489 | Profile(ID, getKeyword(), NNS, NamedType, getOwnedTagDecl()); | ||||||
5490 | } | ||||||
5491 | |||||||
5492 | static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, | ||||||
5493 | NestedNameSpecifier *NNS, QualType NamedType, | ||||||
5494 | TagDecl *OwnedTagDecl) { | ||||||
5495 | ID.AddInteger(Keyword); | ||||||
5496 | ID.AddPointer(NNS); | ||||||
5497 | NamedType.Profile(ID); | ||||||
5498 | ID.AddPointer(OwnedTagDecl); | ||||||
5499 | } | ||||||
5500 | |||||||
5501 | static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; } | ||||||
5502 | }; | ||||||
5503 | |||||||
5504 | /// Represents a qualified type name for which the type name is | ||||||
5505 | /// dependent. | ||||||
5506 | /// | ||||||
5507 | /// DependentNameType represents a class of dependent types that involve a | ||||||
5508 | /// possibly dependent nested-name-specifier (e.g., "T::") followed by a | ||||||
5509 | /// name of a type. The DependentNameType may start with a "typename" (for a | ||||||
5510 | /// typename-specifier), "class", "struct", "union", or "enum" (for a | ||||||
5511 | /// dependent elaborated-type-specifier), or nothing (in contexts where we | ||||||
5512 | /// know that we must be referring to a type, e.g., in a base class specifier). | ||||||
5513 | /// Typically the nested-name-specifier is dependent, but in MSVC compatibility | ||||||
5514 | /// mode, this type is used with non-dependent names to delay name lookup until | ||||||
5515 | /// instantiation. | ||||||
5516 | class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { | ||||||
5517 | friend class ASTContext; // ASTContext creates these | ||||||
5518 | |||||||
5519 | /// The nested name specifier containing the qualifier. | ||||||
5520 | NestedNameSpecifier *NNS; | ||||||
5521 | |||||||
5522 | /// The type that this typename specifier refers to. | ||||||
5523 | const IdentifierInfo *Name; | ||||||
5524 | |||||||
5525 | DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, | ||||||
5526 | const IdentifierInfo *Name, QualType CanonType) | ||||||
5527 | : TypeWithKeyword(Keyword, DependentName, CanonType, | ||||||
5528 | TypeDependence::DependentInstantiation | | ||||||
5529 | toTypeDependence(NNS->getDependence())), | ||||||
5530 | NNS(NNS), Name(Name) {} | ||||||
5531 | |||||||
5532 | public: | ||||||
5533 | /// Retrieve the qualification on this type. | ||||||
5534 | NestedNameSpecifier *getQualifier() const { return NNS; } | ||||||
5535 | |||||||
5536 | /// Retrieve the type named by the typename specifier as an identifier. | ||||||
5537 | /// | ||||||
5538 | /// This routine will return a non-NULL identifier pointer when the | ||||||
5539 | /// form of the original typename was terminated by an identifier, | ||||||
5540 | /// e.g., "typename T::type". | ||||||
5541 | const IdentifierInfo *getIdentifier() const { | ||||||
5542 | return Name; | ||||||
5543 | } | ||||||
5544 | |||||||
5545 | bool isSugared() const { return false; } | ||||||
5546 | QualType desugar() const { return QualType(this, 0); } | ||||||
5547 | |||||||
5548 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
5549 | Profile(ID, getKeyword(), NNS, Name); | ||||||
5550 | } | ||||||
5551 | |||||||
5552 | static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword, | ||||||
5553 | NestedNameSpecifier *NNS, const IdentifierInfo *Name) { | ||||||
5554 | ID.AddInteger(Keyword); | ||||||
5555 | ID.AddPointer(NNS); | ||||||
5556 | ID.AddPointer(Name); | ||||||
5557 | } | ||||||
5558 | |||||||
5559 | static bool classof(const Type *T) { | ||||||
5560 | return T->getTypeClass() == DependentName; | ||||||
5561 | } | ||||||
5562 | }; | ||||||
5563 | |||||||
5564 | /// Represents a template specialization type whose template cannot be | ||||||
5565 | /// resolved, e.g. | ||||||
5566 | /// A<T>::template B<T> | ||||||
5567 | class alignas(8) DependentTemplateSpecializationType | ||||||
5568 | : public TypeWithKeyword, | ||||||
5569 | public llvm::FoldingSetNode { | ||||||
5570 | friend class ASTContext; // ASTContext creates these | ||||||
5571 | |||||||
5572 | /// The nested name specifier containing the qualifier. | ||||||
5573 | NestedNameSpecifier *NNS; | ||||||
5574 | |||||||
5575 | /// The identifier of the template. | ||||||
5576 | const IdentifierInfo *Name; | ||||||
5577 | |||||||
5578 | DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, | ||||||
5579 | NestedNameSpecifier *NNS, | ||||||
5580 | const IdentifierInfo *Name, | ||||||
5581 | ArrayRef<TemplateArgument> Args, | ||||||
5582 | QualType Canon); | ||||||
5583 | |||||||
5584 | const TemplateArgument *getArgBuffer() const { | ||||||
5585 | return reinterpret_cast<const TemplateArgument*>(this+1); | ||||||
5586 | } | ||||||
5587 | |||||||
5588 | TemplateArgument *getArgBuffer() { | ||||||
5589 | return reinterpret_cast<TemplateArgument*>(this+1); | ||||||
5590 | } | ||||||
5591 | |||||||
5592 | public: | ||||||
5593 | NestedNameSpecifier *getQualifier() const { return NNS; } | ||||||
5594 | const IdentifierInfo *getIdentifier() const { return Name; } | ||||||
5595 | |||||||
5596 | /// Retrieve the template arguments. | ||||||
5597 | const TemplateArgument *getArgs() const { | ||||||
5598 | return getArgBuffer(); | ||||||
5599 | } | ||||||
5600 | |||||||
5601 | /// Retrieve the number of template arguments. | ||||||
5602 | unsigned getNumArgs() const { | ||||||
5603 | return DependentTemplateSpecializationTypeBits.NumArgs; | ||||||
5604 | } | ||||||
5605 | |||||||
5606 | const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h | ||||||
5607 | |||||||
5608 | ArrayRef<TemplateArgument> template_arguments() const { | ||||||
5609 | return {getArgs(), getNumArgs()}; | ||||||
5610 | } | ||||||
5611 | |||||||
5612 | using iterator = const TemplateArgument *; | ||||||
5613 | |||||||
5614 | iterator begin() const { return getArgs(); } | ||||||
5615 | iterator end() const; // inline in TemplateBase.h | ||||||
5616 | |||||||
5617 | bool isSugared() const { return false; } | ||||||
5618 | QualType desugar() const { return QualType(this, 0); } | ||||||
5619 | |||||||
5620 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { | ||||||
5621 | Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), getNumArgs()}); | ||||||
5622 | } | ||||||
5623 | |||||||
5624 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
5625 | const ASTContext &Context, | ||||||
5626 | ElaboratedTypeKeyword Keyword, | ||||||
5627 | NestedNameSpecifier *Qualifier, | ||||||
5628 | const IdentifierInfo *Name, | ||||||
5629 | ArrayRef<TemplateArgument> Args); | ||||||
5630 | |||||||
5631 | static bool classof(const Type *T) { | ||||||
5632 | return T->getTypeClass() == DependentTemplateSpecialization; | ||||||
5633 | } | ||||||
5634 | }; | ||||||
5635 | |||||||
5636 | /// Represents a pack expansion of types. | ||||||
5637 | /// | ||||||
5638 | /// Pack expansions are part of C++11 variadic templates. A pack | ||||||
5639 | /// expansion contains a pattern, which itself contains one or more | ||||||
5640 | /// "unexpanded" parameter packs. When instantiated, a pack expansion | ||||||
5641 | /// produces a series of types, each instantiated from the pattern of | ||||||
5642 | /// the expansion, where the Ith instantiation of the pattern uses the | ||||||
5643 | /// Ith arguments bound to each of the unexpanded parameter packs. The | ||||||
5644 | /// pack expansion is considered to "expand" these unexpanded | ||||||
5645 | /// parameter packs. | ||||||
5646 | /// | ||||||
5647 | /// \code | ||||||
5648 | /// template<typename ...Types> struct tuple; | ||||||
5649 | /// | ||||||
5650 | /// template<typename ...Types> | ||||||
5651 | /// struct tuple_of_references { | ||||||
5652 | /// typedef tuple<Types&...> type; | ||||||
5653 | /// }; | ||||||
5654 | /// \endcode | ||||||
5655 | /// | ||||||
5656 | /// Here, the pack expansion \c Types&... is represented via a | ||||||
5657 | /// PackExpansionType whose pattern is Types&. | ||||||
5658 | class PackExpansionType : public Type, public llvm::FoldingSetNode { | ||||||
5659 | friend class ASTContext; // ASTContext creates these | ||||||
5660 | |||||||
5661 | /// The pattern of the pack expansion. | ||||||
5662 | QualType Pattern; | ||||||
5663 | |||||||
5664 | PackExpansionType(QualType Pattern, QualType Canon, | ||||||
5665 | Optional<unsigned> NumExpansions) | ||||||
5666 | : Type(PackExpansion, Canon, | ||||||
5667 | (Pattern->getDependence() | TypeDependence::Dependent | | ||||||
5668 | TypeDependence::Instantiation) & | ||||||
5669 | ~TypeDependence::UnexpandedPack), | ||||||
5670 | Pattern(Pattern) { | ||||||
5671 | PackExpansionTypeBits.NumExpansions = | ||||||
5672 | NumExpansions ? *NumExpansions + 1 : 0; | ||||||
5673 | } | ||||||
5674 | |||||||
5675 | public: | ||||||
5676 | /// Retrieve the pattern of this pack expansion, which is the | ||||||
5677 | /// type that will be repeatedly instantiated when instantiating the | ||||||
5678 | /// pack expansion itself. | ||||||
5679 | QualType getPattern() const { return Pattern; } | ||||||
5680 | |||||||
5681 | /// Retrieve the number of expansions that this pack expansion will | ||||||
5682 | /// generate, if known. | ||||||
5683 | Optional<unsigned> getNumExpansions() const { | ||||||
5684 | if (PackExpansionTypeBits.NumExpansions) | ||||||
5685 | return PackExpansionTypeBits.NumExpansions - 1; | ||||||
5686 | return None; | ||||||
5687 | } | ||||||
5688 | |||||||
5689 | bool isSugared() const { return false; } | ||||||
5690 | QualType desugar() const { return QualType(this, 0); } | ||||||
5691 | |||||||
5692 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
5693 | Profile(ID, getPattern(), getNumExpansions()); | ||||||
5694 | } | ||||||
5695 | |||||||
5696 | static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern, | ||||||
5697 | Optional<unsigned> NumExpansions) { | ||||||
5698 | ID.AddPointer(Pattern.getAsOpaquePtr()); | ||||||
5699 | ID.AddBoolean(NumExpansions.hasValue()); | ||||||
5700 | if (NumExpansions) | ||||||
5701 | ID.AddInteger(*NumExpansions); | ||||||
5702 | } | ||||||
5703 | |||||||
5704 | static bool classof(const Type *T) { | ||||||
5705 | return T->getTypeClass() == PackExpansion; | ||||||
5706 | } | ||||||
5707 | }; | ||||||
5708 | |||||||
5709 | /// This class wraps the list of protocol qualifiers. For types that can | ||||||
5710 | /// take ObjC protocol qualifers, they can subclass this class. | ||||||
5711 | template <class T> | ||||||
5712 | class ObjCProtocolQualifiers { | ||||||
5713 | protected: | ||||||
5714 | ObjCProtocolQualifiers() = default; | ||||||
5715 | |||||||
5716 | ObjCProtocolDecl * const *getProtocolStorage() const { | ||||||
5717 | return const_cast<ObjCProtocolQualifiers*>(this)->getProtocolStorage(); | ||||||
5718 | } | ||||||
5719 | |||||||
5720 | ObjCProtocolDecl **getProtocolStorage() { | ||||||
5721 | return static_cast<T*>(this)->getProtocolStorageImpl(); | ||||||
5722 | } | ||||||
5723 | |||||||
5724 | void setNumProtocols(unsigned N) { | ||||||
5725 | static_cast<T*>(this)->setNumProtocolsImpl(N); | ||||||
5726 | } | ||||||
5727 | |||||||
5728 | void initialize(ArrayRef<ObjCProtocolDecl *> protocols) { | ||||||
5729 | setNumProtocols(protocols.size()); | ||||||
5730 | assert(getNumProtocols() == protocols.size() &&(static_cast <bool> (getNumProtocols() == protocols.size () && "bitfield overflow in protocol count") ? void ( 0) : __assert_fail ("getNumProtocols() == protocols.size() && \"bitfield overflow in protocol count\"" , "clang/include/clang/AST/Type.h", 5731, __extension__ __PRETTY_FUNCTION__ )) | ||||||
5731 | "bitfield overflow in protocol count")(static_cast <bool> (getNumProtocols() == protocols.size () && "bitfield overflow in protocol count") ? void ( 0) : __assert_fail ("getNumProtocols() == protocols.size() && \"bitfield overflow in protocol count\"" , "clang/include/clang/AST/Type.h", 5731, __extension__ __PRETTY_FUNCTION__ )); | ||||||
5732 | if (!protocols.empty()) | ||||||
5733 | memcpy(getProtocolStorage(), protocols.data(), | ||||||
5734 | protocols.size() * sizeof(ObjCProtocolDecl*)); | ||||||
5735 | } | ||||||
5736 | |||||||
5737 | public: | ||||||
5738 | using qual_iterator = ObjCProtocolDecl * const *; | ||||||
5739 | using qual_range = llvm::iterator_range<qual_iterator>; | ||||||
5740 | |||||||
5741 | qual_range quals() const { return qual_range(qual_begin(), qual_end()); } | ||||||
5742 | qual_iterator qual_begin() const { return getProtocolStorage(); } | ||||||
5743 | qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); } | ||||||
5744 | |||||||
5745 | bool qual_empty() const { return getNumProtocols() == 0; } | ||||||
5746 | |||||||
5747 | /// Return the number of qualifying protocols in this type, or 0 if | ||||||
5748 | /// there are none. | ||||||
5749 | unsigned getNumProtocols() const { | ||||||
5750 | return static_cast<const T*>(this)->getNumProtocolsImpl(); | ||||||
5751 | } | ||||||
5752 | |||||||
5753 | /// Fetch a protocol by index. | ||||||
5754 | ObjCProtocolDecl *getProtocol(unsigned I) const { | ||||||
5755 | assert(I < getNumProtocols() && "Out-of-range protocol access")(static_cast <bool> (I < getNumProtocols() && "Out-of-range protocol access") ? void (0) : __assert_fail ( "I < getNumProtocols() && \"Out-of-range protocol access\"" , "clang/include/clang/AST/Type.h", 5755, __extension__ __PRETTY_FUNCTION__ )); | ||||||
5756 | return qual_begin()[I]; | ||||||
5757 | } | ||||||
5758 | |||||||
5759 | /// Retrieve all of the protocol qualifiers. | ||||||
5760 | ArrayRef<ObjCProtocolDecl *> getProtocols() const { | ||||||
5761 | return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols()); | ||||||
5762 | } | ||||||
5763 | }; | ||||||
5764 | |||||||
5765 | /// Represents a type parameter type in Objective C. It can take | ||||||
5766 | /// a list of protocols. | ||||||
5767 | class ObjCTypeParamType : public Type, | ||||||
5768 | public ObjCProtocolQualifiers<ObjCTypeParamType>, | ||||||
5769 | public llvm::FoldingSetNode { | ||||||
5770 | friend class ASTContext; | ||||||
5771 | friend class ObjCProtocolQualifiers<ObjCTypeParamType>; | ||||||
5772 | |||||||
5773 | /// The number of protocols stored on this type. | ||||||
5774 | unsigned NumProtocols : 6; | ||||||
5775 | |||||||
5776 | ObjCTypeParamDecl *OTPDecl; | ||||||
5777 | |||||||
5778 | /// The protocols are stored after the ObjCTypeParamType node. In the | ||||||
5779 | /// canonical type, the list of protocols are sorted alphabetically | ||||||
5780 | /// and uniqued. | ||||||
5781 | ObjCProtocolDecl **getProtocolStorageImpl(); | ||||||
5782 | |||||||
5783 | /// Return the number of qualifying protocols in this interface type, | ||||||
5784 | /// or 0 if there are none. | ||||||
5785 | unsigned getNumProtocolsImpl() const { | ||||||
5786 | return NumProtocols; | ||||||
5787 | } | ||||||
5788 | |||||||
5789 | void setNumProtocolsImpl(unsigned N) { | ||||||
5790 | NumProtocols = N; | ||||||
5791 | } | ||||||
5792 | |||||||
5793 | ObjCTypeParamType(const ObjCTypeParamDecl *D, | ||||||
5794 | QualType can, | ||||||
5795 | ArrayRef<ObjCProtocolDecl *> protocols); | ||||||
5796 | |||||||
5797 | public: | ||||||
5798 | bool isSugared() const { return true; } | ||||||
5799 | QualType desugar() const { return getCanonicalTypeInternal(); } | ||||||
5800 | |||||||
5801 | static bool classof(const Type *T) { | ||||||
5802 | return T->getTypeClass() == ObjCTypeParam; | ||||||
5803 | } | ||||||
5804 | |||||||
5805 | void Profile(llvm::FoldingSetNodeID &ID); | ||||||
5806 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
5807 | const ObjCTypeParamDecl *OTPDecl, | ||||||
5808 | QualType CanonicalType, | ||||||
5809 | ArrayRef<ObjCProtocolDecl *> protocols); | ||||||
5810 | |||||||
5811 | ObjCTypeParamDecl *getDecl() const { return OTPDecl; } | ||||||
5812 | }; | ||||||
5813 | |||||||
5814 | /// Represents a class type in Objective C. | ||||||
5815 | /// | ||||||
5816 | /// Every Objective C type is a combination of a base type, a set of | ||||||
5817 | /// type arguments (optional, for parameterized classes) and a list of | ||||||
5818 | /// protocols. | ||||||
5819 | /// | ||||||
5820 | /// Given the following declarations: | ||||||
5821 | /// \code | ||||||
5822 | /// \@class C<T>; | ||||||
5823 | /// \@protocol P; | ||||||
5824 | /// \endcode | ||||||
5825 | /// | ||||||
5826 | /// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType | ||||||
5827 | /// with base C and no protocols. | ||||||
5828 | /// | ||||||
5829 | /// 'C<P>' is an unspecialized ObjCObjectType with base C and protocol list [P]. | ||||||
5830 | /// 'C<C*>' is a specialized ObjCObjectType with type arguments 'C*' and no | ||||||
5831 | /// protocol list. | ||||||
5832 | /// 'C<C*><P>' is a specialized ObjCObjectType with base C, type arguments 'C*', | ||||||
5833 | /// and protocol list [P]. | ||||||
5834 | /// | ||||||
5835 | /// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose | ||||||
5836 | /// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType | ||||||
5837 | /// and no protocols. | ||||||
5838 | /// | ||||||
5839 | /// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType | ||||||
5840 | /// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually | ||||||
5841 | /// this should get its own sugar class to better represent the source. | ||||||
5842 | class ObjCObjectType : public Type, | ||||||
5843 | public ObjCProtocolQualifiers<ObjCObjectType> { | ||||||
5844 | friend class ObjCProtocolQualifiers<ObjCObjectType>; | ||||||
5845 | |||||||
5846 | // ObjCObjectType.NumTypeArgs - the number of type arguments stored | ||||||
5847 | // after the ObjCObjectPointerType node. | ||||||
5848 | // ObjCObjectType.NumProtocols - the number of protocols stored | ||||||
5849 | // after the type arguments of ObjCObjectPointerType node. | ||||||
5850 | // | ||||||
5851 | // These protocols are those written directly on the type. If | ||||||
5852 | // protocol qualifiers ever become additive, the iterators will need | ||||||
5853 | // to get kindof complicated. | ||||||
5854 | // | ||||||
5855 | // In the canonical object type, these are sorted alphabetically | ||||||
5856 | // and uniqued. | ||||||
5857 | |||||||
5858 | /// Either a BuiltinType or an InterfaceType or sugar for either. | ||||||
5859 | QualType BaseType; | ||||||
5860 | |||||||
5861 | /// Cached superclass type. | ||||||
5862 | mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool> | ||||||
5863 | CachedSuperClassType; | ||||||
5864 | |||||||
5865 | QualType *getTypeArgStorage(); | ||||||
5866 | const QualType *getTypeArgStorage() const { | ||||||
5867 | return const_cast<ObjCObjectType *>(this)->getTypeArgStorage(); | ||||||
5868 | } | ||||||
5869 | |||||||
5870 | ObjCProtocolDecl **getProtocolStorageImpl(); | ||||||
5871 | /// Return the number of qualifying protocols in this interface type, | ||||||
5872 | /// or 0 if there are none. | ||||||
5873 | unsigned getNumProtocolsImpl() const { | ||||||
5874 | return ObjCObjectTypeBits.NumProtocols; | ||||||
5875 | } | ||||||
5876 | void setNumProtocolsImpl(unsigned N) { | ||||||
5877 | ObjCObjectTypeBits.NumProtocols = N; | ||||||
5878 | } | ||||||
5879 | |||||||
5880 | protected: | ||||||
5881 | enum Nonce_ObjCInterface { Nonce_ObjCInterface }; | ||||||
5882 | |||||||
5883 | ObjCObjectType(QualType Canonical, QualType Base, | ||||||
5884 | ArrayRef<QualType> typeArgs, | ||||||
5885 | ArrayRef<ObjCProtocolDecl *> protocols, | ||||||
5886 | bool isKindOf); | ||||||
5887 | |||||||
5888 | ObjCObjectType(enum Nonce_ObjCInterface) | ||||||
5889 | : Type(ObjCInterface, QualType(), TypeDependence::None), | ||||||
5890 | BaseType(QualType(this_(), 0)) { | ||||||
5891 | ObjCObjectTypeBits.NumProtocols = 0; | ||||||
5892 | ObjCObjectTypeBits.NumTypeArgs = 0; | ||||||
5893 | ObjCObjectTypeBits.IsKindOf = 0; | ||||||
5894 | } | ||||||
5895 | |||||||
5896 | void computeSuperClassTypeSlow() const; | ||||||
5897 | |||||||
5898 | public: | ||||||
5899 | /// Gets the base type of this object type. This is always (possibly | ||||||
5900 | /// sugar for) one of: | ||||||
5901 | /// - the 'id' builtin type (as opposed to the 'id' type visible to the | ||||||
5902 | /// user, which is a typedef for an ObjCObjectPointerType) | ||||||
5903 | /// - the 'Class' builtin type (same caveat) | ||||||
5904 | /// - an ObjCObjectType (currently always an ObjCInterfaceType) | ||||||
5905 | QualType getBaseType() const { return BaseType; } | ||||||
5906 | |||||||
5907 | bool isObjCId() const { | ||||||
5908 | return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId); | ||||||
5909 | } | ||||||
5910 | |||||||
5911 | bool isObjCClass() const { | ||||||
5912 | return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass); | ||||||
5913 | } | ||||||
5914 | |||||||
5915 | bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); } | ||||||
5916 | bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); } | ||||||
5917 | bool isObjCUnqualifiedIdOrClass() const { | ||||||
5918 | if (!qual_empty()) return false; | ||||||
5919 | if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>()) | ||||||
5920 | return T->getKind() == BuiltinType::ObjCId || | ||||||
5921 | T->getKind() == BuiltinType::ObjCClass; | ||||||
5922 | return false; | ||||||
5923 | } | ||||||
5924 | bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); } | ||||||
5925 | bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); } | ||||||
5926 | |||||||
5927 | /// Gets the interface declaration for this object type, if the base type | ||||||
5928 | /// really is an interface. | ||||||
5929 | ObjCInterfaceDecl *getInterface() const; | ||||||
5930 | |||||||
5931 | /// Determine whether this object type is "specialized", meaning | ||||||
5932 | /// that it has type arguments. | ||||||
5933 | bool isSpecialized() const; | ||||||
5934 | |||||||
5935 | /// Determine whether this object type was written with type arguments. | ||||||
5936 | bool isSpecializedAsWritten() const { | ||||||
5937 | return ObjCObjectTypeBits.NumTypeArgs > 0; | ||||||
5938 | } | ||||||
5939 | |||||||
5940 | /// Determine whether this object type is "unspecialized", meaning | ||||||
5941 | /// that it has no type arguments. | ||||||
5942 | bool isUnspecialized() const { return !isSpecialized(); } | ||||||
5943 | |||||||
5944 | /// Determine whether this object type is "unspecialized" as | ||||||
5945 | /// written, meaning that it has no type arguments. | ||||||
5946 | bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); } | ||||||
5947 | |||||||
5948 | /// Retrieve the type arguments of this object type (semantically). | ||||||
5949 | ArrayRef<QualType> getTypeArgs() const; | ||||||
5950 | |||||||
5951 | /// Retrieve the type arguments of this object type as they were | ||||||
5952 | /// written. | ||||||
5953 | ArrayRef<QualType> getTypeArgsAsWritten() const { | ||||||
5954 | return llvm::makeArrayRef(getTypeArgStorage(), | ||||||
5955 | ObjCObjectTypeBits.NumTypeArgs); | ||||||
5956 | } | ||||||
5957 | |||||||
5958 | /// Whether this is a "__kindof" type as written. | ||||||
5959 | bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; } | ||||||
5960 | |||||||
5961 | /// Whether this ia a "__kindof" type (semantically). | ||||||
5962 | bool isKindOfType() const; | ||||||
5963 | |||||||
5964 | /// Retrieve the type of the superclass of this object type. | ||||||
5965 | /// | ||||||
5966 | /// This operation substitutes any type arguments into the | ||||||
5967 | /// superclass of the current class type, potentially producing a | ||||||
5968 | /// specialization of the superclass type. Produces a null type if | ||||||
5969 | /// there is no superclass. | ||||||
5970 | QualType getSuperClassType() const { | ||||||
5971 | if (!CachedSuperClassType.getInt()) | ||||||
5972 | computeSuperClassTypeSlow(); | ||||||
5973 | |||||||
5974 | assert(CachedSuperClassType.getInt() && "Superclass not set?")(static_cast <bool> (CachedSuperClassType.getInt() && "Superclass not set?") ? void (0) : __assert_fail ("CachedSuperClassType.getInt() && \"Superclass not set?\"" , "clang/include/clang/AST/Type.h", 5974, __extension__ __PRETTY_FUNCTION__ )); | ||||||
5975 | return QualType(CachedSuperClassType.getPointer(), 0); | ||||||
5976 | } | ||||||
5977 | |||||||
5978 | /// Strip off the Objective-C "kindof" type and (with it) any | ||||||
5979 | /// protocol qualifiers. | ||||||
5980 | QualType stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const; | ||||||
5981 | |||||||
5982 | bool isSugared() const { return false; } | ||||||
5983 | QualType desugar() const { return QualType(this, 0); } | ||||||
5984 | |||||||
5985 | static bool classof(const Type *T) { | ||||||
5986 | return T->getTypeClass() == ObjCObject || | ||||||
5987 | T->getTypeClass() == ObjCInterface; | ||||||
5988 | } | ||||||
5989 | }; | ||||||
5990 | |||||||
5991 | /// A class providing a concrete implementation | ||||||
5992 | /// of ObjCObjectType, so as to not increase the footprint of | ||||||
5993 | /// ObjCInterfaceType. Code outside of ASTContext and the core type | ||||||
5994 | /// system should not reference this type. | ||||||
5995 | class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode { | ||||||
5996 | friend class ASTContext; | ||||||
5997 | |||||||
5998 | // If anyone adds fields here, ObjCObjectType::getProtocolStorage() | ||||||
5999 | // will need to be modified. | ||||||
6000 | |||||||
6001 | ObjCObjectTypeImpl(QualType Canonical, QualType Base, | ||||||
6002 | ArrayRef<QualType> typeArgs, | ||||||
6003 | ArrayRef<ObjCProtocolDecl *> protocols, | ||||||
6004 | bool isKindOf) | ||||||
6005 | : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {} | ||||||
6006 | |||||||
6007 | public: | ||||||
6008 | void Profile(llvm::FoldingSetNodeID &ID); | ||||||
6009 | static void Profile(llvm::FoldingSetNodeID &ID, | ||||||
6010 | QualType Base, | ||||||
6011 | ArrayRef<QualType> typeArgs, | ||||||
6012 | ArrayRef<ObjCProtocolDecl *> protocols, | ||||||
6013 | bool isKindOf); | ||||||
6014 | }; | ||||||
6015 | |||||||
6016 | inline QualType *ObjCObjectType::getTypeArgStorage() { | ||||||
6017 | return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1); | ||||||
6018 | } | ||||||
6019 | |||||||
6020 | inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorageImpl() { | ||||||
6021 | return reinterpret_cast<ObjCProtocolDecl**>( | ||||||
6022 | getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs); | ||||||
6023 | } | ||||||
6024 | |||||||
6025 | inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() { | ||||||
6026 | return reinterpret_cast<ObjCProtocolDecl**>( | ||||||
6027 | static_cast<ObjCTypeParamType*>(this)+1); | ||||||
6028 | } | ||||||
6029 | |||||||
6030 | /// Interfaces are the core concept in Objective-C for object oriented design. | ||||||
6031 | /// They basically correspond to C++ classes. There are two kinds of interface | ||||||
6032 | /// types: normal interfaces like `NSString`, and qualified interfaces, which | ||||||
6033 | /// are qualified with a protocol list like `NSString<NSCopyable, NSAmazing>`. | ||||||
6034 | /// | ||||||
6035 | /// ObjCInterfaceType guarantees the following properties when considered | ||||||
6036 | /// as a subtype of its superclass, ObjCObjectType: | ||||||
6037 | /// - There are no protocol qualifiers. To reinforce this, code which | ||||||
6038 | /// tries to invoke the protocol methods via an ObjCInterfaceType will | ||||||
6039 | /// fail to compile. | ||||||
6040 | /// - It is its own base type. That is, if T is an ObjCInterfaceType*, | ||||||
6041 | /// T->getBaseType() == QualType(T, 0). | ||||||
6042 | class ObjCInterfaceType : public ObjCObjectType { | ||||||
6043 | friend class ASTContext; // ASTContext creates these. | ||||||
6044 | friend class ASTReader; | ||||||
6045 | template <class T> friend class serialization::AbstractTypeReader; | ||||||
6046 | |||||||
6047 | ObjCInterfaceDecl *Decl; | ||||||
6048 | |||||||
6049 | ObjCInterfaceType(const ObjCInterfaceDecl *D) | ||||||
6050 | : ObjCObjectType(Nonce_ObjCInterface), | ||||||
6051 | Decl(const_cast<ObjCInterfaceDecl*>(D)) {} | ||||||
6052 | |||||||
6053 | public: | ||||||
6054 | /// Get the declaration of this interface. | ||||||
6055 | ObjCInterfaceDecl *getDecl() const; | ||||||
6056 | |||||||
6057 | bool isSugared() const { return false; } | ||||||
6058 | QualType desugar() const { return QualType(this, 0); } | ||||||
6059 | |||||||
6060 | static bool classof(const Type *T) { | ||||||
6061 | return T->getTypeClass() == ObjCInterface; | ||||||
6062 | } | ||||||
6063 | |||||||
6064 | // Nonsense to "hide" certain members of ObjCObjectType within this | ||||||
6065 | // class. People asking for protocols on an ObjCInterfaceType are | ||||||
6066 | // not going to get what they want: ObjCInterfaceTypes are | ||||||
6067 | // guaranteed to have no protocols. | ||||||
6068 | enum { | ||||||
6069 | qual_iterator, | ||||||
6070 | qual_begin, | ||||||
6071 | qual_end, | ||||||
6072 | getNumProtocols, | ||||||
6073 | getProtocol | ||||||
6074 | }; | ||||||
6075 | }; | ||||||
6076 | |||||||
6077 | inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { | ||||||
6078 | QualType baseType = getBaseType(); | ||||||
6079 | while (const auto *ObjT = baseType->getAs<ObjCObjectType>()) { | ||||||
6080 | if (const auto *T = dyn_cast<ObjCInterfaceType>(ObjT)) | ||||||
6081 | return T->getDecl(); | ||||||
6082 | |||||||
6083 | baseType = ObjT->getBaseType(); | ||||||
6084 | } | ||||||
6085 | |||||||
6086 | return nullptr; | ||||||
6087 | } | ||||||
6088 | |||||||
6089 | /// Represents a pointer to an Objective C object. | ||||||
6090 | /// | ||||||
6091 | /// These are constructed from pointer declarators when the pointee type is | ||||||
6092 | /// an ObjCObjectType (or sugar for one). In addition, the 'id' and 'Class' | ||||||
6093 | /// types are typedefs for these, and the protocol-qualified types 'id<P>' | ||||||
6094 | /// and 'Class<P>' are translated into these. | ||||||
6095 | /// | ||||||
6096 | /// Pointers to pointers to Objective C objects are still PointerTypes; | ||||||
6097 | /// only the first level of pointer gets it own type implementation. | ||||||
6098 | class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { | ||||||
6099 | friend class ASTContext; // ASTContext creates these. | ||||||
6100 | |||||||
6101 | QualType PointeeType; | ||||||
6102 | |||||||
6103 | ObjCObjectPointerType(QualType Canonical, QualType Pointee) | ||||||
6104 | : Type(ObjCObjectPointer, Canonical, Pointee->getDependence()), | ||||||
6105 | PointeeType(Pointee) {} | ||||||
6106 | |||||||
6107 | public: | ||||||
6108 | /// Gets the type pointed to by this ObjC pointer. | ||||||
6109 | /// The result will always be an ObjCObjectType or sugar thereof. | ||||||
6110 | QualType getPointeeType() const { return PointeeType; } | ||||||
6111 | |||||||
6112 | /// Gets the type pointed to by this ObjC pointer. Always returns non-null. | ||||||
6113 | /// | ||||||
6114 | /// This method is equivalent to getPointeeType() except that | ||||||
6115 | /// it discards any typedefs (or other sugar) between this | ||||||
6116 | /// type and the "outermost" object type. So for: | ||||||
6117 | /// \code | ||||||
6118 | /// \@class A; \@protocol P; \@protocol Q; | ||||||
6119 | /// typedef A<P> AP; | ||||||
6120 | /// typedef A A1; | ||||||
6121 | /// typedef A1<P> A1P; | ||||||
6122 | /// typedef A1P<Q> A1PQ; | ||||||
6123 | /// \endcode | ||||||
6124 | /// For 'A*', getObjectType() will return 'A'. | ||||||
6125 | /// For 'A<P>*', getObjectType() will return 'A<P>'. | ||||||
6126 | /// For 'AP*', getObjectType() will return 'A<P>'. | ||||||
6127 | /// For 'A1*', getObjectType() will return 'A'. | ||||||
6128 | /// For 'A1<P>*', getObjectType() will return 'A1<P>'. | ||||||
6129 | /// For 'A1P*', getObjectType() will return 'A1<P>'. | ||||||
6130 | /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because | ||||||
6131 | /// adding protocols to a protocol-qualified base discards the | ||||||
6132 | /// old qualifiers (for now). But if it didn't, getObjectType() | ||||||
6133 | /// would return 'A1P<Q>' (and we'd have to make iterating over | ||||||
6134 | /// qualifiers more complicated). | ||||||
6135 | const ObjCObjectType *getObjectType() const { | ||||||
6136 | return PointeeType->castAs<ObjCObjectType>(); | ||||||
6137 | } | ||||||
6138 | |||||||
6139 | /// If this pointer points to an Objective C | ||||||
6140 | /// \@interface type, gets the type for that interface. Any protocol | ||||||
6141 | /// qualifiers on the interface are ignored. | ||||||
6142 | /// | ||||||
6143 | /// \return null if the base type for this pointer is 'id' or 'Class' | ||||||
6144 | const ObjCInterfaceType *getInterfaceType() const; | ||||||
6145 | |||||||
6146 | /// If this pointer points to an Objective \@interface | ||||||
6147 | /// type, gets the declaration for that interface. | ||||||
6148 | /// | ||||||
6149 | /// \return null if the base type for this pointer is 'id' or 'Class' | ||||||
6150 | ObjCInterfaceDecl *getInterfaceDecl() const { | ||||||
6151 | return getObjectType()->getInterface(); | ||||||
6152 | } | ||||||
6153 | |||||||
6154 | /// True if this is equivalent to the 'id' type, i.e. if | ||||||
6155 | /// its object type is the primitive 'id' type with no protocols. | ||||||
6156 | bool isObjCIdType() const { | ||||||
6157 | return getObjectType()->isObjCUnqualifiedId(); | ||||||
6158 | } | ||||||
6159 | |||||||
6160 | /// True if this is equivalent to the 'Class' type, | ||||||
6161 | /// i.e. if its object tive is the primitive 'Class' type with no protocols. | ||||||
6162 | bool isObjCClassType() const { | ||||||
6163 | return getObjectType()->isObjCUnqualifiedClass(); | ||||||
6164 | } | ||||||
6165 | |||||||
6166 | /// True if this is equivalent to the 'id' or 'Class' type, | ||||||
6167 | bool isObjCIdOrClassType() const { | ||||||
6168 | return getObjectType()->isObjCUnqualifiedIdOrClass(); | ||||||
6169 | } | ||||||
6170 | |||||||
6171 | /// True if this is equivalent to 'id<P>' for some non-empty set of | ||||||
6172 | /// protocols. | ||||||
6173 | bool isObjCQualifiedIdType() const { | ||||||
6174 | return getObjectType()->isObjCQualifiedId(); | ||||||
6175 | } | ||||||
6176 | |||||||
6177 | /// True if this is equivalent to 'Class<P>' for some non-empty set of | ||||||
6178 | /// protocols. | ||||||
6179 | bool isObjCQualifiedClassType() const { | ||||||
6180 | return getObjectType()->isObjCQualifiedClass(); | ||||||
6181 | } | ||||||
6182 | |||||||
6183 | /// Whether this is a "__kindof" type. | ||||||
6184 | bool isKindOfType() const { return getObjectType()->isKindOfType(); } | ||||||
6185 | |||||||
6186 | /// Whether this type is specialized, meaning that it has type arguments. | ||||||
6187 | bool isSpecialized() const { return getObjectType()->isSpecialized(); } | ||||||
6188 | |||||||
6189 | /// Whether this type is specialized, meaning that it has type arguments. | ||||||
6190 | bool isSpecializedAsWritten() const { | ||||||
6191 | return getObjectType()->isSpecializedAsWritten(); | ||||||
6192 | } | ||||||
6193 | |||||||
6194 | /// Whether this type is unspecialized, meaning that is has no type arguments. | ||||||
6195 | bool isUnspecialized() const { return getObjectType()->isUnspecialized(); } | ||||||
6196 | |||||||
6197 | /// Determine whether this object type is "unspecialized" as | ||||||
6198 | /// written, meaning that it has no type arguments. | ||||||
6199 | bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); } | ||||||
6200 | |||||||
6201 | /// Retrieve the type arguments for this type. | ||||||
6202 | ArrayRef<QualType> getTypeArgs() const { | ||||||
6203 | return getObjectType()->getTypeArgs(); | ||||||
6204 | } | ||||||
6205 | |||||||
6206 | /// Retrieve the type arguments for this type. | ||||||
6207 | ArrayRef<QualType> getTypeArgsAsWritten() const { | ||||||
6208 | return getObjectType()->getTypeArgsAsWritten(); | ||||||
6209 | } | ||||||
6210 | |||||||
6211 | /// An iterator over the qualifiers on the object type. Provided | ||||||
6212 | /// for convenience. This will always iterate over the full set of | ||||||
6213 | /// protocols on a type, not just those provided directly. | ||||||
6214 | using qual_iterator = ObjCObjectType::qual_iterator; | ||||||
6215 | using qual_range = llvm::iterator_range<qual_iterator>; | ||||||
6216 | |||||||
6217 | qual_range quals() const { return qual_range(qual_begin(), qual_end()); } | ||||||
6218 | |||||||
6219 | qual_iterator qual_begin() const { | ||||||
6220 | return getObjectType()->qual_begin(); | ||||||
6221 | } | ||||||
6222 | |||||||
6223 | qual_iterator qual_end() const { | ||||||
6224 | return getObjectType()->qual_end(); | ||||||
6225 | } | ||||||
6226 | |||||||
6227 | bool qual_empty() const { return getObjectType()->qual_empty(); } | ||||||
6228 | |||||||
6229 | /// Return the number of qualifying protocols on the object type. | ||||||
6230 | unsigned getNumProtocols() const { | ||||||
6231 | return getObjectType()->getNumProtocols(); | ||||||
6232 | } | ||||||
6233 | |||||||
6234 | /// Retrieve a qualifying protocol by index on the object type. | ||||||
6235 | ObjCProtocolDecl *getProtocol(unsigned I) const { | ||||||
6236 | return getObjectType()->getProtocol(I); | ||||||
6237 | } | ||||||
6238 | |||||||
6239 | bool isSugared() const { return false; } | ||||||
6240 | QualType desugar() const { return QualType(this, 0); } | ||||||
6241 | |||||||
6242 | /// Retrieve the type of the superclass of this object pointer type. | ||||||
6243 | /// | ||||||
6244 | /// This operation substitutes any type arguments into the | ||||||
6245 | /// superclass of the current class type, potentially producing a | ||||||
6246 | /// pointer to a specialization of the superclass type. Produces a | ||||||
6247 | /// null type if there is no superclass. | ||||||
6248 | QualType getSuperClassType() const; | ||||||
6249 | |||||||
6250 | /// Strip off the Objective-C "kindof" type and (with it) any | ||||||
6251 | /// protocol qualifiers. | ||||||
6252 | const ObjCObjectPointerType *stripObjCKindOfTypeAndQuals( | ||||||
6253 | const ASTContext &ctx) const; | ||||||
6254 | |||||||
6255 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
6256 | Profile(ID, getPointeeType()); | ||||||
6257 | } | ||||||
6258 | |||||||
6259 | static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { | ||||||
6260 | ID.AddPointer(T.getAsOpaquePtr()); | ||||||
6261 | } | ||||||
6262 | |||||||
6263 | static bool classof(const Type *T) { | ||||||
6264 | return T->getTypeClass() == ObjCObjectPointer; | ||||||
6265 | } | ||||||
6266 | }; | ||||||
6267 | |||||||
6268 | class AtomicType : public Type, public llvm::FoldingSetNode { | ||||||
6269 | friend class ASTContext; // ASTContext creates these. | ||||||
6270 | |||||||
6271 | QualType ValueType; | ||||||
6272 | |||||||
6273 | AtomicType(QualType ValTy, QualType Canonical) | ||||||
6274 | : Type(Atomic, Canonical, ValTy->getDependence()), ValueType(ValTy) {} | ||||||
6275 | |||||||
6276 | public: | ||||||
6277 | /// Gets the type contained by this atomic type, i.e. | ||||||
6278 | /// the type returned by performing an atomic load of this atomic type. | ||||||
6279 | QualType getValueType() const { return ValueType; } | ||||||
6280 | |||||||
6281 | bool isSugared() const { return false; } | ||||||
6282 | QualType desugar() const { return QualType(this, 0); } | ||||||
6283 | |||||||
6284 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
6285 | Profile(ID, getValueType()); | ||||||
6286 | } | ||||||
6287 | |||||||
6288 | static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { | ||||||
6289 | ID.AddPointer(T.getAsOpaquePtr()); | ||||||
6290 | } | ||||||
6291 | |||||||
6292 | static bool classof(const Type *T) { | ||||||
6293 | return T->getTypeClass() == Atomic; | ||||||
6294 | } | ||||||
6295 | }; | ||||||
6296 | |||||||
6297 | /// PipeType - OpenCL20. | ||||||
6298 | class PipeType : public Type, public llvm::FoldingSetNode { | ||||||
6299 | friend class ASTContext; // ASTContext creates these. | ||||||
6300 | |||||||
6301 | QualType ElementType; | ||||||
6302 | bool isRead; | ||||||
6303 | |||||||
6304 | PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) | ||||||
6305 | : Type(Pipe, CanonicalPtr, elemType->getDependence()), | ||||||
6306 | ElementType(elemType), isRead(isRead) {} | ||||||
6307 | |||||||
6308 | public: | ||||||
6309 | QualType getElementType() const { return ElementType; } | ||||||
6310 | |||||||
6311 | bool isSugared() const { return false; } | ||||||
6312 | |||||||
6313 | QualType desugar() const { return QualType(this, 0); } | ||||||
6314 | |||||||
6315 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
6316 | Profile(ID, getElementType(), isReadOnly()); | ||||||
6317 | } | ||||||
6318 | |||||||
6319 | static void Profile(llvm::FoldingSetNodeID &ID, QualType T, bool isRead) { | ||||||
6320 | ID.AddPointer(T.getAsOpaquePtr()); | ||||||
6321 | ID.AddBoolean(isRead); | ||||||
6322 | } | ||||||
6323 | |||||||
6324 | static bool classof(const Type *T) { | ||||||
6325 | return T->getTypeClass() == Pipe; | ||||||
6326 | } | ||||||
6327 | |||||||
6328 | bool isReadOnly() const { return isRead; } | ||||||
6329 | }; | ||||||
6330 | |||||||
6331 | /// A fixed int type of a specified bitwidth. | ||||||
6332 | class BitIntType final : public Type, public llvm::FoldingSetNode { | ||||||
6333 | friend class ASTContext; | ||||||
6334 | unsigned IsUnsigned : 1; | ||||||
6335 | unsigned NumBits : 24; | ||||||
6336 | |||||||
6337 | protected: | ||||||
6338 | BitIntType(bool isUnsigned, unsigned NumBits); | ||||||
6339 | |||||||
6340 | public: | ||||||
6341 | bool isUnsigned() const { return IsUnsigned; } | ||||||
6342 | bool isSigned() const { return !IsUnsigned; } | ||||||
6343 | unsigned getNumBits() const { return NumBits; } | ||||||
6344 | |||||||
6345 | bool isSugared() const { return false; } | ||||||
6346 | QualType desugar() const { return QualType(this, 0); } | ||||||
6347 | |||||||
6348 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
6349 | Profile(ID, isUnsigned(), getNumBits()); | ||||||
6350 | } | ||||||
6351 | |||||||
6352 | static void Profile(llvm::FoldingSetNodeID &ID, bool IsUnsigned, | ||||||
6353 | unsigned NumBits) { | ||||||
6354 | ID.AddBoolean(IsUnsigned); | ||||||
6355 | ID.AddInteger(NumBits); | ||||||
6356 | } | ||||||
6357 | |||||||
6358 | static bool classof(const Type *T) { return T->getTypeClass() == BitInt; } | ||||||
6359 | }; | ||||||
6360 | |||||||
6361 | class DependentBitIntType final : public Type, public llvm::FoldingSetNode { | ||||||
6362 | friend class ASTContext; | ||||||
6363 | const ASTContext &Context; | ||||||
6364 | llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned; | ||||||
6365 | |||||||
6366 | protected: | ||||||
6367 | DependentBitIntType(const ASTContext &Context, bool IsUnsigned, | ||||||
6368 | Expr *NumBits); | ||||||
6369 | |||||||
6370 | public: | ||||||
6371 | bool isUnsigned() const; | ||||||
6372 | bool isSigned() const { return !isUnsigned(); } | ||||||
6373 | Expr *getNumBitsExpr() const; | ||||||
6374 | |||||||
6375 | bool isSugared() const { return false; } | ||||||
6376 | QualType desugar() const { return QualType(this, 0); } | ||||||
6377 | |||||||
6378 | void Profile(llvm::FoldingSetNodeID &ID) { | ||||||
6379 | Profile(ID, Context, isUnsigned(), getNumBitsExpr()); | ||||||
6380 | } | ||||||
6381 | static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, | ||||||
6382 | bool IsUnsigned, Expr *NumBitsExpr); | ||||||
6383 | |||||||
6384 | static bool classof(const Type *T) { | ||||||
6385 | return T->getTypeClass() == DependentBitInt; | ||||||
6386 | } | ||||||
6387 | }; | ||||||
6388 | |||||||
6389 | /// A qualifier set is used to build a set of qualifiers. | ||||||
6390 | class QualifierCollector : public Qualifiers { | ||||||
6391 | public: | ||||||
6392 | QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {} | ||||||
6393 | |||||||
6394 | /// Collect any qualifiers on the given type and return an | ||||||
6395 | /// unqualified type. The qualifiers are assumed to be consistent | ||||||
6396 | /// with those already in the type. | ||||||
6397 | const Type *strip(QualType type) { | ||||||
6398 | addFastQualifiers(type.getLocalFastQualifiers()); | ||||||
6399 | if (!type.hasLocalNonFastQualifiers()) | ||||||
6400 | return type.getTypePtrUnsafe(); | ||||||
6401 | |||||||
6402 | const ExtQuals *extQuals = type.getExtQualsUnsafe(); | ||||||
6403 | addConsistentQualifiers(extQuals->getQualifiers()); | ||||||
6404 | return extQuals->getBaseType(); | ||||||
6405 | } | ||||||
6406 | |||||||
6407 | /// Apply the collected qualifiers to the given type. | ||||||
6408 | QualType apply(const ASTContext &Context, QualType QT) const; | ||||||
6409 | |||||||
6410 | /// Apply the collected qualifiers to the given type. | ||||||
6411 | QualType apply(const ASTContext &Context, const Type* T) const; | ||||||
6412 | }; | ||||||
6413 | |||||||
6414 | /// A container of type source information. | ||||||
6415 | /// | ||||||
6416 | /// A client can read the relevant info using TypeLoc wrappers, e.g: | ||||||
6417 | /// @code | ||||||
6418 | /// TypeLoc TL = TypeSourceInfo->getTypeLoc(); | ||||||
6419 | /// TL.getBeginLoc().print(OS, SrcMgr); | ||||||
6420 | /// @endcode | ||||||
6421 | class alignas(8) TypeSourceInfo { | ||||||
6422 | // Contains a memory block after the class, used for type source information, | ||||||
6423 | // allocated by ASTContext. | ||||||
6424 | friend class ASTContext; | ||||||
6425 | |||||||
6426 | QualType Ty; | ||||||
6427 | |||||||
6428 | TypeSourceInfo(QualType ty) : Ty(ty) {} | ||||||
6429 | |||||||
6430 | public: | ||||||
6431 | /// Return the type wrapped by this type source info. | ||||||
6432 | QualType getType() const { return Ty; } | ||||||
6433 | |||||||
6434 | /// Return the TypeLoc wrapper for the type source info. | ||||||
6435 | TypeLoc getTypeLoc() const; // implemented in TypeLoc.h | ||||||
6436 | |||||||
6437 | /// Override the type stored in this TypeSourceInfo. Use with caution! | ||||||
6438 | void overrideType(QualType T) { Ty = T; } | ||||||
6439 | }; | ||||||
6440 | |||||||
6441 | // Inline function definitions. | ||||||
6442 | |||||||
6443 | inline SplitQualType SplitQualType::getSingleStepDesugaredType() const { | ||||||
6444 | SplitQualType desugar = | ||||||
6445 | Ty->getLocallyUnqualifiedSingleStepDesugaredType().split(); | ||||||
6446 | desugar.Quals.addConsistentQualifiers(Quals); | ||||||
6447 | return desugar; | ||||||
6448 | } | ||||||
6449 | |||||||
6450 | inline const Type *QualType::getTypePtr() const { | ||||||
6451 | return getCommonPtr()->BaseType; | ||||||
6452 | } | ||||||
6453 | |||||||
6454 | inline const Type *QualType::getTypePtrOrNull() const { | ||||||
6455 | return (isNull() ? nullptr : getCommonPtr()->BaseType); | ||||||
6456 | } | ||||||
6457 | |||||||
6458 | inline SplitQualType QualType::split() const { | ||||||
6459 | if (!hasLocalNonFastQualifiers()) | ||||||
6460 | return SplitQualType(getTypePtrUnsafe(), | ||||||
6461 | Qualifiers::fromFastMask(getLocalFastQualifiers())); | ||||||
6462 | |||||||
6463 | const ExtQuals *eq = getExtQualsUnsafe(); | ||||||
6464 | Qualifiers qs = eq->getQualifiers(); | ||||||
6465 | qs.addFastQualifiers(getLocalFastQualifiers()); | ||||||
6466 | return SplitQualType(eq->getBaseType(), qs); | ||||||
6467 | } | ||||||
6468 | |||||||
6469 | inline Qualifiers QualType::getLocalQualifiers() const { | ||||||
6470 | Qualifiers Quals; | ||||||
6471 | if (hasLocalNonFastQualifiers()) | ||||||
6472 | Quals = getExtQualsUnsafe()->getQualifiers(); | ||||||
6473 | Quals.addFastQualifiers(getLocalFastQualifiers()); | ||||||
6474 | return Quals; | ||||||
6475 | } | ||||||
6476 | |||||||
6477 | inline Qualifiers QualType::getQualifiers() const { | ||||||
6478 | Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers(); | ||||||
6479 | quals.addFastQualifiers(getLocalFastQualifiers()); | ||||||
6480 | return quals; | ||||||
6481 | } | ||||||
6482 | |||||||
6483 | inline unsigned QualType::getCVRQualifiers() const { | ||||||
6484 | unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers(); | ||||||
6485 | cvr |= getLocalCVRQualifiers(); | ||||||
6486 | return cvr; | ||||||
6487 | } | ||||||
6488 | |||||||
6489 | inline QualType QualType::getCanonicalType() const { | ||||||
6490 | QualType canon = getCommonPtr()->CanonicalType; | ||||||
6491 | return canon.withFastQualifiers(getLocalFastQualifiers()); | ||||||
6492 | } | ||||||
6493 | |||||||
6494 | inline bool QualType::isCanonical() const { | ||||||
6495 | return getTypePtr()->isCanonicalUnqualified(); | ||||||
6496 | } | ||||||
6497 | |||||||
6498 | inline bool QualType::isCanonicalAsParam() const { | ||||||
6499 | if (!isCanonical()) return false; | ||||||
6500 | if (hasLocalQualifiers()) return false; | ||||||
6501 | |||||||
6502 | const Type *T = getTypePtr(); | ||||||
6503 | if (T->isVariablyModifiedType() && T->hasSizedVLAType()) | ||||||
6504 | return false; | ||||||
6505 | |||||||
6506 | return !isa<FunctionType>(T) && !isa<ArrayType>(T); | ||||||
6507 | } | ||||||
6508 | |||||||
6509 | inline bool QualType::isConstQualified() const { | ||||||
6510 | return isLocalConstQualified() || | ||||||
6511 | getCommonPtr()->CanonicalType.isLocalConstQualified(); | ||||||
6512 | } | ||||||
6513 | |||||||
6514 | inline bool QualType::isRestrictQualified() const { | ||||||
6515 | return isLocalRestrictQualified() || | ||||||
6516 | getCommonPtr()->CanonicalType.isLocalRestrictQualified(); | ||||||
6517 | } | ||||||
6518 | |||||||
6519 | |||||||
6520 | inline bool QualType::isVolatileQualified() const { | ||||||
6521 | return isLocalVolatileQualified() || | ||||||
6522 | getCommonPtr()->CanonicalType.isLocalVolatileQualified(); | ||||||
6523 | } | ||||||
6524 | |||||||
6525 | inline bool QualType::hasQualifiers() const { | ||||||
6526 | return hasLocalQualifiers() || | ||||||
6527 | getCommonPtr()->CanonicalType.hasLocalQualifiers(); | ||||||
6528 | } | ||||||
6529 | |||||||
6530 | inline QualType QualType::getUnqualifiedType() const { | ||||||
6531 | if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) | ||||||
6532 | return QualType(getTypePtr(), 0); | ||||||
6533 | |||||||
6534 | return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0); | ||||||
6535 | } | ||||||
6536 | |||||||
6537 | inline SplitQualType QualType::getSplitUnqualifiedType() const { | ||||||
6538 | if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) | ||||||
6539 | return split(); | ||||||
6540 | |||||||
6541 | return getSplitUnqualifiedTypeImpl(*this); | ||||||
6542 | } | ||||||
6543 | |||||||
6544 | inline void QualType::removeLocalConst() { | ||||||
6545 | removeLocalFastQualifiers(Qualifiers::Const); | ||||||
6546 | } | ||||||
6547 | |||||||
6548 | inline void QualType::removeLocalRestrict() { | ||||||
6549 | removeLocalFastQualifiers(Qualifiers::Restrict); | ||||||
6550 | } | ||||||
6551 | |||||||
6552 | inline void QualType::removeLocalVolatile() { | ||||||
6553 | removeLocalFastQualifiers(Qualifiers::Volatile); | ||||||
6554 | } | ||||||
6555 | |||||||
6556 | inline void QualType::removeLocalCVRQualifiers(unsigned Mask) { | ||||||
6557 | assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits")(static_cast <bool> (!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits") ? void (0) : __assert_fail ("!(Mask & ~Qualifiers::CVRMask) && \"mask has non-CVR bits\"" , "clang/include/clang/AST/Type.h", 6557, __extension__ __PRETTY_FUNCTION__ )); | ||||||
6558 | static_assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask, | ||||||
6559 | "Fast bits differ from CVR bits!"); | ||||||
6560 | |||||||
6561 | // Fast path: we don't need to touch the slow qualifiers. | ||||||
6562 | removeLocalFastQualifiers(Mask); | ||||||
6563 | } | ||||||
6564 | |||||||
6565 | /// Check if this type has any address space qualifier. | ||||||
6566 | inline bool QualType::hasAddressSpace() const { | ||||||
6567 | return getQualifiers().hasAddressSpace(); | ||||||
6568 | } | ||||||
6569 | |||||||
6570 | /// Return the address space of this type. | ||||||
6571 | inline LangAS QualType::getAddressSpace() const { | ||||||
6572 | return getQualifiers().getAddressSpace(); | ||||||
6573 | } | ||||||
6574 | |||||||
6575 | /// Return the gc attribute of this type. | ||||||
6576 | inline Qualifiers::GC QualType::getObjCGCAttr() const { | ||||||
6577 | return getQualifiers().getObjCGCAttr(); | ||||||
6578 | } | ||||||
6579 | |||||||
6580 | inline bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion() const { | ||||||
6581 | if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) | ||||||
6582 | return hasNonTrivialToPrimitiveDefaultInitializeCUnion(RD); | ||||||
6583 | return false; | ||||||
6584 | } | ||||||
6585 | |||||||
6586 | inline bool QualType::hasNonTrivialToPrimitiveDestructCUnion() const { | ||||||
6587 | if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) | ||||||
6588 | return hasNonTrivialToPrimitiveDestructCUnion(RD); | ||||||
6589 | return false; | ||||||
6590 | } | ||||||
6591 | |||||||
6592 | inline bool QualType::hasNonTrivialToPrimitiveCopyCUnion() const { | ||||||
6593 | if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) | ||||||
6594 | return hasNonTrivialToPrimitiveCopyCUnion(RD); | ||||||
6595 | return false; | ||||||
6596 | } | ||||||
6597 | |||||||
6598 | inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) { | ||||||
6599 | if (const auto *PT = t.getAs<PointerType>()) { | ||||||
6600 | if (const auto *FT = PT->getPointeeType()->getAs<FunctionType>()) | ||||||
6601 | return FT->getExtInfo(); | ||||||
6602 | } else if (const auto *FT = t.getAs<FunctionType>()) | ||||||
6603 | return FT->getExtInfo(); | ||||||
6604 | |||||||
6605 | return FunctionType::ExtInfo(); | ||||||
6606 | } | ||||||
6607 | |||||||
6608 | inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) { | ||||||
6609 | return getFunctionExtInfo(*t); | ||||||
6610 | } | ||||||
6611 | |||||||
6612 | /// Determine whether this type is more | ||||||
6613 | /// qualified than the Other type. For example, "const volatile int" | ||||||
6614 | /// is more qualified than "const int", "volatile int", and | ||||||
6615 | /// "int". However, it is not more qualified than "const volatile | ||||||
6616 | /// int". | ||||||
6617 | inline bool QualType::isMoreQualifiedThan(QualType other) const { | ||||||
6618 | Qualifiers MyQuals = getQualifiers(); | ||||||
6619 | Qualifiers OtherQuals = other.getQualifiers(); | ||||||
6620 | return (MyQuals != OtherQuals && MyQuals.compatiblyIncludes(OtherQuals)); | ||||||
6621 | } | ||||||
6622 | |||||||
6623 | /// Determine whether this type is at last | ||||||
6624 | /// as qualified as the Other type. For example, "const volatile | ||||||
6625 | /// int" is at least as qualified as "const int", "volatile int", | ||||||
6626 | /// "int", and "const volatile int". | ||||||
6627 | inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const { | ||||||
6628 | Qualifiers OtherQuals = other.getQualifiers(); | ||||||
6629 | |||||||
6630 | // Ignore __unaligned qualifier if this type is a void. | ||||||
6631 | if (getUnqualifiedType()->isVoidType()) | ||||||
6632 | OtherQuals.removeUnaligned(); | ||||||
6633 | |||||||
6634 | return getQualifiers().compatiblyIncludes(OtherQuals); | ||||||
6635 | } | ||||||
6636 | |||||||
6637 | /// If Type is a reference type (e.g., const | ||||||
6638 | /// int&), returns the type that the reference refers to ("const | ||||||
6639 | /// int"). Otherwise, returns the type itself. This routine is used | ||||||
6640 | /// throughout Sema to implement C++ 5p6: | ||||||
6641 | /// | ||||||
6642 | /// If an expression initially has the type "reference to T" (8.3.2, | ||||||
6643 | /// 8.5.3), the type is adjusted to "T" prior to any further | ||||||
6644 | /// analysis, the expression designates the object or function | ||||||
6645 | /// denoted by the reference, and the expression is an lvalue. | ||||||
6646 | inline QualType QualType::getNonReferenceType() const { | ||||||
6647 | if (const auto *RefType = (*this)->getAs<ReferenceType>()) | ||||||
6648 | return RefType->getPointeeType(); | ||||||
6649 | else | ||||||
6650 | return *this; | ||||||
6651 | } | ||||||
6652 | |||||||
6653 | inline bool QualType::isCForbiddenLValueType() const { | ||||||
6654 | return ((getTypePtr()->isVoidType() && !hasQualifiers()) || | ||||||
6655 | getTypePtr()->isFunctionType()); | ||||||
6656 | } | ||||||
6657 | |||||||
6658 | /// Tests whether the type is categorized as a fundamental type. | ||||||
6659 | /// | ||||||
6660 | /// \returns True for types specified in C++0x [basic.fundamental]. | ||||||
6661 | inline bool Type::isFundamentalType() const { | ||||||
6662 | return isVoidType() || | ||||||
6663 | isNullPtrType() || | ||||||
6664 | // FIXME: It's really annoying that we don't have an | ||||||
6665 | // 'isArithmeticType()' which agrees with the standard definition. | ||||||
6666 | (isArithmeticType() && !isEnumeralType()); | ||||||
6667 | } | ||||||
6668 | |||||||
6669 | /// Tests whether the type is categorized as a compound type. | ||||||
6670 | /// | ||||||
6671 | /// \returns True for types specified in C++0x [basic.compound]. | ||||||
6672 | inline bool Type::isCompoundType() const { | ||||||
6673 | // C++0x [basic.compound]p1: | ||||||
6674 | // Compound types can be constructed in the following ways: | ||||||
6675 | // -- arrays of objects of a given type [...]; | ||||||
6676 | return isArrayType() || | ||||||
6677 | // -- functions, which have parameters of given types [...]; | ||||||
6678 | isFunctionType() || | ||||||
6679 | // -- pointers to void or objects or functions [...]; | ||||||
6680 | isPointerType() || | ||||||
6681 | // -- references to objects or functions of a given type. [...] | ||||||
6682 | isReferenceType() || | ||||||
6683 | // -- classes containing a sequence of objects of various types, [...]; | ||||||
6684 | isRecordType() || | ||||||
6685 | // -- unions, which are classes capable of containing objects of different | ||||||
6686 | // types at different times; | ||||||
6687 | isUnionType() || | ||||||
6688 | // -- enumerations, which comprise a set of named constant values. [...]; | ||||||
6689 | isEnumeralType() || | ||||||
6690 | // -- pointers to non-static class members, [...]. | ||||||
6691 | isMemberPointerType(); | ||||||
6692 | } | ||||||
6693 | |||||||
6694 | inline bool Type::isFunctionType() const { | ||||||
6695 | return isa<FunctionType>(CanonicalType); | ||||||
6696 | } | ||||||
6697 | |||||||
6698 | inline bool Type::isPointerType() const { | ||||||
6699 | return isa<PointerType>(CanonicalType); | ||||||
6700 | } | ||||||
6701 | |||||||
6702 | inline bool Type::isAnyPointerType() const { | ||||||
6703 | return isPointerType() || isObjCObjectPointerType(); | ||||||
6704 | } | ||||||
6705 | |||||||
6706 | inline bool Type::isBlockPointerType() const { | ||||||
6707 | return isa<BlockPointerType>(CanonicalType); | ||||||
6708 | } | ||||||
6709 | |||||||
6710 | inline bool Type::isReferenceType() const { | ||||||
6711 | return isa<ReferenceType>(CanonicalType); | ||||||
6712 | } | ||||||
6713 | |||||||
6714 | inline bool Type::isLValueReferenceType() const { | ||||||
6715 | return isa<LValueReferenceType>(CanonicalType); | ||||||
6716 | } | ||||||
6717 | |||||||
6718 | inline bool Type::isRValueReferenceType() const { | ||||||
6719 | return isa<RValueReferenceType>(CanonicalType); | ||||||
6720 | } | ||||||
6721 | |||||||
6722 | inline bool Type::isObjectPointerType() const { | ||||||
6723 | // Note: an "object pointer type" is not the same thing as a pointer to an | ||||||
6724 | // object type; rather, it is a pointer to an object type or a pointer to cv | ||||||
6725 | // void. | ||||||
6726 | if (const auto *T = getAs<PointerType>()) | ||||||
6727 | return !T->getPointeeType()->isFunctionType(); | ||||||
6728 | else | ||||||
6729 | return false; | ||||||
6730 | } | ||||||
6731 | |||||||
6732 | inline bool Type::isFunctionPointerType() const { | ||||||
6733 | if (const auto *T = getAs<PointerType>()) | ||||||
6734 | return T->getPointeeType()->isFunctionType(); | ||||||
6735 | else | ||||||
6736 | return false; | ||||||
6737 | } | ||||||
6738 | |||||||
6739 | inline bool Type::isFunctionReferenceType() const { | ||||||
6740 | if (const auto *T = getAs<ReferenceType>()) | ||||||
6741 | return T->getPointeeType()->isFunctionType(); | ||||||
6742 | else | ||||||
6743 | return false; | ||||||
6744 | } | ||||||
6745 | |||||||
6746 | inline bool Type::isMemberPointerType() const { | ||||||
6747 | return isa<MemberPointerType>(CanonicalType); | ||||||
6748 | } | ||||||
6749 | |||||||
6750 | inline bool Type::isMemberFunctionPointerType() const { | ||||||
6751 | if (const auto *T = getAs<MemberPointerType>()) | ||||||
6752 | return T->isMemberFunctionPointer(); | ||||||
6753 | else | ||||||
6754 | return false; | ||||||
6755 | } | ||||||
6756 | |||||||
6757 | inline bool Type::isMemberDataPointerType() const { | ||||||
6758 | if (const auto *T = getAs<MemberPointerType>()) | ||||||
6759 | return T->isMemberDataPointer(); | ||||||
6760 | else | ||||||
6761 | return false; | ||||||
6762 | } | ||||||
6763 | |||||||
6764 | inline bool Type::isArrayType() const { | ||||||
6765 | return isa<ArrayType>(CanonicalType); | ||||||
6766 | } | ||||||
6767 | |||||||
6768 | inline bool Type::isConstantArrayType() const { | ||||||
6769 | return isa<ConstantArrayType>(CanonicalType); | ||||||
6770 | } | ||||||
6771 | |||||||
6772 | inline bool Type::isIncompleteArrayType() const { | ||||||
6773 | return isa<IncompleteArrayType>(CanonicalType); | ||||||
6774 | } | ||||||
6775 | |||||||
6776 | inline bool Type::isVariableArrayType() const { | ||||||
6777 | return isa<VariableArrayType>(CanonicalType); | ||||||
6778 | } | ||||||
6779 | |||||||
6780 | inline bool Type::isDependentSizedArrayType() const { | ||||||
6781 | return isa<DependentSizedArrayType>(CanonicalType); | ||||||
6782 | } | ||||||
6783 | |||||||
6784 | inline bool Type::isBuiltinType() const { | ||||||
6785 | return isa<BuiltinType>(CanonicalType); | ||||||
6786 | } | ||||||
6787 | |||||||
6788 | inline bool Type::isRecordType() const { | ||||||
6789 | return isa<RecordType>(CanonicalType); | ||||||
6790 | } | ||||||
6791 | |||||||
6792 | inline bool Type::isEnumeralType() const { | ||||||
6793 | return isa<EnumType>(CanonicalType); | ||||||
6794 | } | ||||||
6795 | |||||||
6796 | inline bool Type::isAnyComplexType() const { | ||||||
6797 | return isa<ComplexType>(CanonicalType); | ||||||
6798 | } | ||||||
6799 | |||||||
6800 | inline bool Type::isVectorType() const { | ||||||
6801 | return isa<VectorType>(CanonicalType); | ||||||
6802 | } | ||||||
6803 | |||||||
6804 | inline bool Type::isExtVectorType() const { | ||||||
6805 | return isa<ExtVectorType>(CanonicalType); | ||||||
6806 | } | ||||||
6807 | |||||||
6808 | inline bool Type::isMatrixType() const { | ||||||
6809 | return isa<MatrixType>(CanonicalType); | ||||||
6810 | } | ||||||
6811 | |||||||
6812 | inline bool Type::isConstantMatrixType() const { | ||||||
6813 | return isa<ConstantMatrixType>(CanonicalType); | ||||||
6814 | } | ||||||
6815 | |||||||
6816 | inline bool Type::isDependentAddressSpaceType() const { | ||||||
6817 | return isa<DependentAddressSpaceType>(CanonicalType); | ||||||
6818 | } | ||||||
6819 | |||||||
6820 | inline bool Type::isObjCObjectPointerType() const { | ||||||
6821 | return isa<ObjCObjectPointerType>(CanonicalType); | ||||||
6822 | } | ||||||
6823 | |||||||
6824 | inline bool Type::isObjCObjectType() const { | ||||||
6825 | return isa<ObjCObjectType>(CanonicalType); | ||||||
6826 | } | ||||||
6827 | |||||||
6828 | inline bool Type::isObjCObjectOrInterfaceType() const { | ||||||
6829 | return isa<ObjCInterfaceType>(CanonicalType) || | ||||||
6830 | isa<ObjCObjectType>(CanonicalType); | ||||||
6831 | } | ||||||
6832 | |||||||
6833 | inline bool Type::isAtomicType() const { | ||||||
6834 | return isa<AtomicType>(CanonicalType); | ||||||
6835 | } | ||||||
6836 | |||||||
6837 | inline bool Type::isUndeducedAutoType() const { | ||||||
6838 | return isa<AutoType>(CanonicalType); | ||||||
6839 | } | ||||||
6840 | |||||||
6841 | inline bool Type::isObjCQualifiedIdType() const { | ||||||
6842 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) | ||||||
6843 | return OPT->isObjCQualifiedIdType(); | ||||||
6844 | return false; | ||||||
6845 | } | ||||||
6846 | |||||||
6847 | inline bool Type::isObjCQualifiedClassType() const { | ||||||
6848 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) | ||||||
6849 | return OPT->isObjCQualifiedClassType(); | ||||||
6850 | return false; | ||||||
6851 | } | ||||||
6852 | |||||||
6853 | inline bool Type::isObjCIdType() const { | ||||||
6854 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) | ||||||
6855 | return OPT->isObjCIdType(); | ||||||
6856 | return false; | ||||||
6857 | } | ||||||
6858 | |||||||
6859 | inline bool Type::isObjCClassType() const { | ||||||
6860 | if (const auto *OPT = getAs<ObjCObjectPointerType>()) | ||||||
6861 | return OPT->isObjCClassType(); | ||||||
6862 | return false; | ||||||
6863 | } | ||||||
6864 | |||||||
6865 | inline bool Type::isObjCSelType() const { | ||||||
6866 | if (const auto *OPT = getAs<PointerType>()) | ||||||
6867 | return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel); | ||||||
6868 | return false; | ||||||
6869 | } | ||||||
6870 | |||||||
6871 | inline bool Type::isObjCBuiltinType() const { | ||||||
6872 | return isObjCIdType() || isObjCClassType() || isObjCSelType(); | ||||||
6873 | } | ||||||
6874 | |||||||
6875 | inline bool Type::isDecltypeType() const { | ||||||
6876 | return isa<DecltypeType>(this); | ||||||
6877 | } | ||||||
6878 | |||||||
6879 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ | ||||||
6880 | inline bool Type::is##Id##Type() const { \ | ||||||
6881 | return isSpecificBuiltinType(BuiltinType::Id); \ | ||||||
6882 | } | ||||||
6883 | #include "clang/Basic/OpenCLImageTypes.def" | ||||||
6884 | |||||||
6885 | inline bool Type::isSamplerT() const { | ||||||
6886 | return isSpecificBuiltinType(BuiltinType::OCLSampler); | ||||||
6887 | } | ||||||
6888 | |||||||
6889 | inline bool Type::isEventT() const { | ||||||
6890 | return isSpecificBuiltinType(BuiltinType::OCLEvent); | ||||||
6891 | } | ||||||
6892 | |||||||
6893 | inline bool Type::isClkEventT() const { | ||||||
6894 | return isSpecificBuiltinType(BuiltinType::OCLClkEvent); | ||||||
6895 | } | ||||||
6896 | |||||||
6897 | inline bool Type::isQueueT() const { | ||||||
6898 | return isSpecificBuiltinType(BuiltinType::OCLQueue); | ||||||
6899 | } | ||||||
6900 | |||||||
6901 | inline bool Type::isReserveIDT() const { | ||||||
6902 | return isSpecificBuiltinType(BuiltinType::OCLReserveID); | ||||||
6903 | } | ||||||
6904 | |||||||
6905 | inline bool Type::isImageType() const { | ||||||
6906 | #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) is##Id##Type() || | ||||||
6907 | return | ||||||
6908 | #include "clang/Basic/OpenCLImageTypes.def" | ||||||
6909 | false; // end boolean or operation | ||||||
6910 | } | ||||||
6911 | |||||||
6912 | inline bool Type::isPipeType() const { | ||||||
6913 | return isa<PipeType>(CanonicalType); | ||||||
6914 | } | ||||||
6915 | |||||||
6916 | inline bool Type::isBitIntType() const { | ||||||
6917 | return isa<BitIntType>(CanonicalType); | ||||||
6918 | } | ||||||
6919 | |||||||
6920 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ | ||||||
6921 | inline bool Type::is##Id##Type() const { \ | ||||||
6922 | return isSpecificBuiltinType(BuiltinType::Id); \ | ||||||
6923 | } | ||||||
6924 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||||
6925 | |||||||
6926 | inline bool Type::isOCLIntelSubgroupAVCType() const { | ||||||
6927 | #define INTEL_SUBGROUP_AVC_TYPE(ExtType, Id) \ | ||||||
6928 | isOCLIntelSubgroupAVC##Id##Type() || | ||||||
6929 | return | ||||||
6930 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||||
6931 | false; // end of boolean or operation | ||||||
6932 | } | ||||||
6933 | |||||||
6934 | inline bool Type::isOCLExtOpaqueType() const { | ||||||
6935 | #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) is##Id##Type() || | ||||||
6936 | return | ||||||
6937 | #include "clang/Basic/OpenCLExtensionTypes.def" | ||||||
6938 | false; // end of boolean or operation | ||||||
6939 | } | ||||||
6940 | |||||||
6941 | inline bool Type::isOpenCLSpecificType() const { | ||||||
6942 | return isSamplerT() || isEventT() || isImageType() || isClkEventT() || | ||||||
6943 | isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType(); | ||||||
6944 | } | ||||||
6945 | |||||||
6946 | inline bool Type::isTemplateTypeParmType() const { | ||||||
6947 | return isa<TemplateTypeParmType>(CanonicalType); | ||||||
6948 | } | ||||||
6949 | |||||||
6950 | inline bool Type::isSpecificBuiltinType(unsigned K) const { | ||||||
6951 | if (const BuiltinType *BT = getAs<BuiltinType>()) { | ||||||
6952 | return BT->getKind() == static_cast<BuiltinType::Kind>(K); | ||||||
6953 | } | ||||||
6954 | return false; | ||||||
6955 | } | ||||||
6956 | |||||||
6957 | inline bool Type::isPlaceholderType() const { | ||||||
6958 | if (const auto *BT = dyn_cast<BuiltinType>(this)) | ||||||
6959 | return BT->isPlaceholderType(); | ||||||
6960 | return false; | ||||||
6961 | } | ||||||
6962 | |||||||
6963 | inline const BuiltinType *Type::getAsPlaceholderType() const { | ||||||
6964 | if (const auto *BT = dyn_cast<BuiltinType>(this)) | ||||||
6965 | if (BT->isPlaceholderType()) | ||||||
6966 | return BT; | ||||||
6967 | return nullptr; | ||||||
6968 | } | ||||||
6969 | |||||||
6970 | inline bool Type::isSpecificPlaceholderType(unsigned K) const { | ||||||
6971 | assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K))(static_cast <bool> (BuiltinType::isPlaceholderTypeKind ((BuiltinType::Kind) K)) ? void (0) : __assert_fail ("BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K)" , "clang/include/clang/AST/Type.h", 6971, __extension__ __PRETTY_FUNCTION__ )); | ||||||
6972 | return isSpecificBuiltinType(K); | ||||||
6973 | } | ||||||
6974 | |||||||
6975 | inline bool Type::isNonOverloadPlaceholderType() const { | ||||||
6976 | if (const auto *BT = dyn_cast<BuiltinType>(this)) | ||||||
6977 | return BT->isNonOverloadPlaceholderType(); | ||||||
6978 | return false; | ||||||
6979 | } | ||||||
6980 | |||||||
6981 | inline bool Type::isVoidType() const { | ||||||
6982 | return isSpecificBuiltinType(BuiltinType::Void); | ||||||
6983 | } | ||||||
6984 | |||||||
6985 | inline bool Type::isHalfType() const { | ||||||
6986 | // FIXME: Should we allow complex __fp16? Probably not. | ||||||
6987 | return isSpecificBuiltinType(BuiltinType::Half); | ||||||
6988 | } | ||||||
6989 | |||||||
6990 | inline bool Type::isFloat16Type() const { | ||||||
6991 | return isSpecificBuiltinType(BuiltinType::Float16); | ||||||
6992 | } | ||||||
6993 | |||||||
6994 | inline bool Type::isBFloat16Type() const { | ||||||
6995 | return isSpecificBuiltinType(BuiltinType::BFloat16); | ||||||
6996 | } | ||||||
6997 | |||||||
6998 | inline bool Type::isFloat128Type() const { | ||||||
6999 | return isSpecificBuiltinType(BuiltinType::Float128); | ||||||
7000 | } | ||||||
7001 | |||||||
7002 | inline bool Type::isIbm128Type() const { | ||||||
7003 | return isSpecificBuiltinType(BuiltinType::Ibm128); | ||||||
7004 | } | ||||||
7005 | |||||||
7006 | inline bool Type::isNullPtrType() const { | ||||||
7007 | return isSpecificBuiltinType(BuiltinType::NullPtr); | ||||||
7008 | } | ||||||
7009 | |||||||
7010 | bool IsEnumDeclComplete(EnumDecl *); | ||||||
7011 | bool IsEnumDeclScoped(EnumDecl *); | ||||||
7012 | |||||||
7013 | inline bool Type::isIntegerType() const { | ||||||
7014 | if (const auto *BT
| ||||||
7015 | return BT->getKind() >= BuiltinType::Bool && | ||||||
7016 | BT->getKind() <= BuiltinType::Int128; | ||||||
7017 | if (const EnumType *ET
| ||||||
7018 | // Incomplete enum types are not treated as integer types. | ||||||
7019 | // FIXME: In C++, enum types are never integer types. | ||||||
7020 | return IsEnumDeclComplete(ET->getDecl()) && | ||||||
7021 | !IsEnumDeclScoped(ET->getDecl()); | ||||||
7022 | } | ||||||
7023 | return isBitIntType(); | ||||||
7024 | } | ||||||
7025 | |||||||
7026 | inline bool Type::isFixedPointType() const { | ||||||
7027 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { | ||||||
7028 | return BT->getKind() >= BuiltinType::ShortAccum && | ||||||
7029 | BT->getKind() <= BuiltinType::SatULongFract; | ||||||
7030 | } | ||||||
7031 | return false; | ||||||
7032 | } | ||||||
7033 | |||||||
7034 | inline bool Type::isFixedPointOrIntegerType() const { | ||||||
7035 | return isFixedPointType() || isIntegerType(); | ||||||
7036 | } | ||||||
7037 | |||||||
7038 | inline bool Type::isSaturatedFixedPointType() const { | ||||||
7039 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { | ||||||
7040 | return BT->getKind() >= BuiltinType::SatShortAccum && | ||||||
7041 | BT->getKind() <= BuiltinType::SatULongFract; | ||||||
7042 | } | ||||||
7043 | return false; | ||||||
7044 | } | ||||||
7045 | |||||||
7046 | inline bool Type::isUnsaturatedFixedPointType() const { | ||||||
7047 | return isFixedPointType() && !isSaturatedFixedPointType(); | ||||||
7048 | } | ||||||
7049 | |||||||
7050 | inline bool Type::isSignedFixedPointType() const { | ||||||
7051 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { | ||||||
7052 | return ((BT->getKind() >= BuiltinType::ShortAccum && | ||||||
7053 | BT->getKind() <= BuiltinType::LongAccum) || | ||||||
7054 | (BT->getKind() >= BuiltinType::ShortFract && | ||||||
7055 | BT->getKind() <= BuiltinType::LongFract) || | ||||||
7056 | (BT->getKind() >= BuiltinType::SatShortAccum && | ||||||
7057 | BT->getKind() <= BuiltinType::SatLongAccum) || | ||||||
7058 | (BT->getKind() >= BuiltinType::SatShortFract && | ||||||
7059 | BT->getKind() <= BuiltinType::SatLongFract)); | ||||||
7060 | } | ||||||
7061 | return false; | ||||||
7062 | } | ||||||
7063 | |||||||
7064 | inline bool Type::isUnsignedFixedPointType() const { | ||||||
7065 | return isFixedPointType() && !isSignedFixedPointType(); | ||||||
7066 | } | ||||||
7067 | |||||||
7068 | inline bool Type::isScalarType() const { | ||||||
7069 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) | ||||||
7070 | return BT->getKind() > BuiltinType::Void && | ||||||
7071 | BT->getKind() <= BuiltinType::NullPtr; | ||||||
7072 | if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) | ||||||
7073 | // Enums are scalar types, but only if they are defined. Incomplete enums | ||||||
7074 | // are not treated as scalar types. | ||||||
7075 | return IsEnumDeclComplete(ET->getDecl()); | ||||||
7076 | return isa<PointerType>(CanonicalType) || | ||||||
7077 | isa<BlockPointerType>(CanonicalType) || | ||||||
7078 | isa<MemberPointerType>(CanonicalType) || | ||||||
7079 | isa<ComplexType>(CanonicalType) || | ||||||
7080 | isa<ObjCObjectPointerType>(CanonicalType) || | ||||||
7081 | isBitIntType(); | ||||||
7082 | } | ||||||
7083 | |||||||
7084 | inline bool Type::isIntegralOrEnumerationType() const { | ||||||
7085 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) | ||||||
7086 | return BT->getKind() >= BuiltinType::Bool && | ||||||
7087 | BT->getKind() <= BuiltinType::Int128; | ||||||
7088 | |||||||
7089 | // Check for a complete enum type; incomplete enum types are not properly an | ||||||
7090 | // enumeration type in the sense required here. | ||||||
7091 | if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) | ||||||
7092 | return IsEnumDeclComplete(ET->getDecl()); | ||||||
7093 | |||||||
7094 | return isBitIntType(); | ||||||
7095 | } | ||||||
7096 | |||||||
7097 | inline bool Type::isBooleanType() const { | ||||||
7098 | if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) | ||||||
7099 | return BT->getKind() == BuiltinType::Bool; | ||||||
7100 | return false; | ||||||
7101 | } | ||||||
7102 | |||||||
7103 | inline bool Type::isUndeducedType() const { | ||||||
7104 | auto *DT = getContainedDeducedType(); | ||||||
7105 | return DT && !DT->isDeduced(); | ||||||
7106 | } | ||||||
7107 | |||||||
7108 | /// Determines whether this is a type for which one can define | ||||||
7109 | /// an overloaded operator. | ||||||
7110 | inline bool Type::isOverloadableType() const { | ||||||
7111 | return isDependentType() || isRecordType() || isEnumeralType(); | ||||||
7112 | } | ||||||
7113 | |||||||
7114 | /// Determines whether this type is written as a typedef-name. | ||||||
7115 | inline bool Type::isTypedefNameType() const { | ||||||
7116 | if (getAs<TypedefType>()) | ||||||
7117 | return true; | ||||||
7118 | if (auto *TST = getAs<TemplateSpecializationType>()) | ||||||
7119 | return TST->isTypeAlias(); | ||||||
7120 | return false; | ||||||
7121 | } | ||||||
7122 | |||||||
7123 | /// Determines whether this type can decay to a pointer type. | ||||||
7124 | inline bool Type::canDecayToPointerType() const { | ||||||
7125 | return isFunctionType() || isArrayType(); | ||||||
7126 | } | ||||||
7127 | |||||||
7128 | inline bool Type::hasPointerRepresentation() const { | ||||||
7129 | return (isPointerType() || isReferenceType() || isBlockPointerType() || | ||||||
7130 | isObjCObjectPointerType() || isNullPtrType()); | ||||||
7131 | } | ||||||
7132 | |||||||
7133 | inline bool Type::hasObjCPointerRepresentation() const { | ||||||
7134 | return isObjCObjectPointerType(); | ||||||
7135 | } | ||||||
7136 | |||||||
7137 | inline const Type *Type::getBaseElementTypeUnsafe() const { | ||||||
7138 | const Type *type = this; | ||||||
7139 | while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe()) | ||||||
7140 | type = arrayType->getElementType().getTypePtr(); | ||||||
7141 | return type; | ||||||
7142 | } | ||||||
7143 | |||||||
7144 | inline const Type *Type::getPointeeOrArrayElementType() const { | ||||||
7145 | const Type *type = this; | ||||||
7146 | if (type->isAnyPointerType()) | ||||||
7147 | return type->getPointeeType().getTypePtr(); | ||||||
7148 | else if (type->isArrayType()) | ||||||
7149 | return type->getBaseElementTypeUnsafe(); | ||||||
7150 | return type; | ||||||
7151 | } | ||||||
7152 | /// Insertion operator for partial diagnostics. This allows sending adress | ||||||
7153 | /// spaces into a diagnostic with <<. | ||||||
7154 | inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, | ||||||
7155 | LangAS AS) { | ||||||
7156 | PD.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS), | ||||||
7157 | DiagnosticsEngine::ArgumentKind::ak_addrspace); | ||||||
7158 | return PD; | ||||||
7159 | } | ||||||
7160 | |||||||
7161 | /// Insertion operator for partial diagnostics. This allows sending Qualifiers | ||||||
7162 | /// into a diagnostic with <<. | ||||||
7163 | inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, | ||||||
7164 | Qualifiers Q) { | ||||||
7165 | PD.AddTaggedVal(Q.getAsOpaqueValue(), | ||||||
7166 | DiagnosticsEngine::ArgumentKind::ak_qual); | ||||||
7167 | return PD; | ||||||
7168 | } | ||||||
7169 | |||||||
7170 | /// Insertion operator for partial diagnostics. This allows sending QualType's | ||||||
7171 | /// into a diagnostic with <<. | ||||||
7172 | inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, | ||||||
7173 | QualType T) { | ||||||
7174 | PD.AddTaggedVal(reinterpret_cast<uint64_t>(T.getAsOpaquePtr()), | ||||||
7175 | DiagnosticsEngine::ak_qualtype); | ||||||
7176 | return PD; | ||||||
7177 | } | ||||||
7178 | |||||||
7179 | // Helper class template that is used by Type::getAs to ensure that one does | ||||||
7180 | // not try to look through a qualified type to get to an array type. | ||||||
7181 | template <typename T> | ||||||
7182 | using TypeIsArrayType = | ||||||
7183 | std::integral_constant<bool, std::is_same<T, ArrayType>::value || | ||||||
7184 | std::is_base_of<ArrayType, T>::value>; | ||||||
7185 | |||||||
7186 | // Member-template getAs<specific type>'. | ||||||
7187 | template <typename T> const T *Type::getAs() const { | ||||||
7188 | static_assert(!TypeIsArrayType<T>::value, | ||||||
7189 | "ArrayType cannot be used with getAs!"); | ||||||
7190 | |||||||
7191 | // If this is directly a T type, return it. | ||||||
7192 | if (const auto *Ty = dyn_cast<T>(this)) | ||||||
7193 | return Ty; | ||||||
7194 | |||||||
7195 | // If the canonical form of this type isn't the right kind, reject it. | ||||||
7196 | if (!isa<T>(CanonicalType)) | ||||||
7197 | return nullptr; | ||||||
7198 | |||||||
7199 | // If this is a typedef for the type, strip the typedef off without | ||||||
7200 | // losing all typedef information. | ||||||
7201 | return cast<T>(getUnqualifiedDesugaredType()); | ||||||
7202 | } | ||||||
7203 | |||||||
7204 | template <typename T> const T *Type::getAsAdjusted() const { | ||||||
7205 | static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!"); | ||||||
7206 | |||||||
7207 | // If this is directly a T type, return it. | ||||||
7208 | if (const auto *Ty = dyn_cast<T>(this)) | ||||||
7209 | return Ty; | ||||||
7210 | |||||||
7211 | // If the canonical form of this type isn't the right kind, reject it. | ||||||
7212 | if (!isa<T>(CanonicalType)) | ||||||
7213 | return nullptr; | ||||||
7214 | |||||||
7215 | // Strip off type adjustments that do not modify the underlying nature of the | ||||||
7216 | // type. | ||||||
7217 | const Type *Ty = this; | ||||||
7218 | while (Ty) { | ||||||
7219 | if (const auto *A = dyn_cast<AttributedType>(Ty)) | ||||||
7220 | Ty = A->getModifiedType().getTypePtr(); | ||||||
7221 | else if (const auto *E = dyn_cast<ElaboratedType>(Ty)) | ||||||
7222 | Ty = E->desugar().getTypePtr(); | ||||||
7223 | else if (const auto *P = dyn_cast<ParenType>(Ty)) | ||||||
7224 | Ty = P->desugar().getTypePtr(); | ||||||
7225 | else if (const auto *A = dyn_cast<AdjustedType>(Ty)) | ||||||
7226 | Ty = A->desugar().getTypePtr(); | ||||||
7227 | else if (const auto *M = dyn_cast<MacroQualifiedType>(Ty)) | ||||||
7228 | Ty = M->desugar().getTypePtr(); | ||||||
7229 | else | ||||||
7230 | break; | ||||||
7231 | } | ||||||
7232 | |||||||
7233 | // Just because the canonical type is correct does not mean we can use cast<>, | ||||||
7234 | // since we may not have stripped off all the sugar down to the base type. | ||||||
7235 | return dyn_cast<T>(Ty); | ||||||
7236 | } | ||||||
7237 | |||||||
7238 | inline const ArrayType *Type::getAsArrayTypeUnsafe() const { | ||||||
7239 | // If this is directly an array type, return it. | ||||||
7240 | if (const auto *arr = dyn_cast<ArrayType>(this)) | ||||||
7241 | return arr; | ||||||
7242 | |||||||
7243 | // If the canonical form of this type isn't the right kind, reject it. | ||||||
7244 | if (!isa<ArrayType>(CanonicalType)) | ||||||
7245 | return nullptr; | ||||||
7246 | |||||||
7247 | // If this is a typedef for the type, strip the typedef off without | ||||||
7248 | // losing all typedef information. | ||||||
7249 | return cast<ArrayType>(getUnqualifiedDesugaredType()); | ||||||
7250 | } | ||||||
7251 | |||||||
7252 | template <typename T> const T *Type::castAs() const { | ||||||
7253 | static_assert(!TypeIsArrayType<T>::value, | ||||||
7254 | "ArrayType cannot be used with castAs!"); | ||||||
7255 | |||||||
7256 | if (const auto *ty = dyn_cast<T>(this)) return ty; | ||||||
7257 | assert(isa<T>(CanonicalType))(static_cast <bool> (isa<T>(CanonicalType)) ? void (0) : __assert_fail ("isa<T>(CanonicalType)", "clang/include/clang/AST/Type.h" , 7257, __extension__ __PRETTY_FUNCTION__)); | ||||||
7258 | return cast<T>(getUnqualifiedDesugaredType()); | ||||||
7259 | } | ||||||
7260 | |||||||
7261 | inline const ArrayType *Type::castAsArrayTypeUnsafe() const { | ||||||
7262 | assert(isa<ArrayType>(CanonicalType))(static_cast <bool> (isa<ArrayType>(CanonicalType )) ? void (0) : __assert_fail ("isa<ArrayType>(CanonicalType)" , "clang/include/clang/AST/Type.h", 7262, __extension__ __PRETTY_FUNCTION__ )); | ||||||
7263 | if (const auto *arr = dyn_cast<ArrayType>(this)) return arr; | ||||||
7264 | return cast<ArrayType>(getUnqualifiedDesugaredType()); | ||||||
7265 | } | ||||||
7266 | |||||||
7267 | DecayedType::DecayedType(QualType OriginalType, QualType DecayedPtr, | ||||||
7268 | QualType CanonicalPtr) | ||||||
7269 | : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) { | ||||||
7270 | #ifndef NDEBUG | ||||||
7271 | QualType Adjusted = getAdjustedType(); | ||||||
7272 | (void)AttributedType::stripOuterNullability(Adjusted); | ||||||
7273 | assert(isa<PointerType>(Adjusted))(static_cast <bool> (isa<PointerType>(Adjusted)) ? void (0) : __assert_fail ("isa<PointerType>(Adjusted)" , "clang/include/clang/AST/Type.h", 7273, __extension__ __PRETTY_FUNCTION__ )); | ||||||
7274 | #endif | ||||||
7275 | } | ||||||
7276 | |||||||
7277 | QualType DecayedType::getPointeeType() const { | ||||||
7278 | QualType Decayed = getDecayedType(); | ||||||
7279 | (void)AttributedType::stripOuterNullability(Decayed); | ||||||
7280 | return cast<PointerType>(Decayed)->getPointeeType(); | ||||||
7281 | } | ||||||
7282 | |||||||
7283 | // Get the decimal string representation of a fixed point type, represented | ||||||
7284 | // as a scaled integer. | ||||||
7285 | // TODO: At some point, we should change the arguments to instead just accept an | ||||||
7286 | // APFixedPoint instead of APSInt and scale. | ||||||
7287 | void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val, | ||||||
7288 | unsigned Scale); | ||||||
7289 | |||||||
7290 | } // namespace clang | ||||||
7291 | |||||||
7292 | #endif // LLVM_CLANG_AST_TYPE_H |
1 | //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(), |
10 | // and dyn_cast_or_null<X>() templates. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_SUPPORT_CASTING_H |
15 | #define LLVM_SUPPORT_CASTING_H |
16 | |
17 | #include "llvm/Support/Compiler.h" |
18 | #include "llvm/Support/type_traits.h" |
19 | #include <cassert> |
20 | #include <memory> |
21 | #include <type_traits> |
22 | |
23 | namespace llvm { |
24 | |
25 | //===----------------------------------------------------------------------===// |
26 | // isa<x> Support Templates |
27 | //===----------------------------------------------------------------------===// |
28 | |
29 | // Define a template that can be specialized by smart pointers to reflect the |
30 | // fact that they are automatically dereferenced, and are not involved with the |
31 | // template selection process... the default implementation is a noop. |
32 | // |
33 | template<typename From> struct simplify_type { |
34 | using SimpleType = From; // The real type this represents... |
35 | |
36 | // An accessor to get the real value... |
37 | static SimpleType &getSimplifiedValue(From &Val) { return Val; } |
38 | }; |
39 | |
40 | template<typename From> struct simplify_type<const From> { |
41 | using NonConstSimpleType = typename simplify_type<From>::SimpleType; |
42 | using SimpleType = |
43 | typename add_const_past_pointer<NonConstSimpleType>::type; |
44 | using RetType = |
45 | typename add_lvalue_reference_if_not_pointer<SimpleType>::type; |
46 | |
47 | static RetType getSimplifiedValue(const From& Val) { |
48 | return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); |
49 | } |
50 | }; |
51 | |
52 | // The core of the implementation of isa<X> is here; To and From should be |
53 | // the names of classes. This template can be specialized to customize the |
54 | // implementation of isa<> without rewriting it from scratch. |
55 | template <typename To, typename From, typename Enabler = void> |
56 | struct isa_impl { |
57 | static inline bool doit(const From &Val) { |
58 | return To::classof(&Val); |
59 | } |
60 | }; |
61 | |
62 | /// Always allow upcasts, and perform no dynamic check for them. |
63 | template <typename To, typename From> |
64 | struct isa_impl<To, From, std::enable_if_t<std::is_base_of<To, From>::value>> { |
65 | static inline bool doit(const From &) { return true; } |
66 | }; |
67 | |
68 | template <typename To, typename From> struct isa_impl_cl { |
69 | static inline bool doit(const From &Val) { |
70 | return isa_impl<To, From>::doit(Val); |
71 | } |
72 | }; |
73 | |
74 | template <typename To, typename From> struct isa_impl_cl<To, const From> { |
75 | static inline bool doit(const From &Val) { |
76 | return isa_impl<To, From>::doit(Val); |
77 | } |
78 | }; |
79 | |
80 | template <typename To, typename From> |
81 | struct isa_impl_cl<To, const std::unique_ptr<From>> { |
82 | static inline bool doit(const std::unique_ptr<From> &Val) { |
83 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "llvm/include/llvm/Support/Casting.h", 83, __extension__ __PRETTY_FUNCTION__ )); |
84 | return isa_impl_cl<To, From>::doit(*Val); |
85 | } |
86 | }; |
87 | |
88 | template <typename To, typename From> struct isa_impl_cl<To, From*> { |
89 | static inline bool doit(const From *Val) { |
90 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "llvm/include/llvm/Support/Casting.h", 90, __extension__ __PRETTY_FUNCTION__ )); |
91 | return isa_impl<To, From>::doit(*Val); |
92 | } |
93 | }; |
94 | |
95 | template <typename To, typename From> struct isa_impl_cl<To, From*const> { |
96 | static inline bool doit(const From *Val) { |
97 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "llvm/include/llvm/Support/Casting.h", 97, __extension__ __PRETTY_FUNCTION__ )); |
98 | return isa_impl<To, From>::doit(*Val); |
99 | } |
100 | }; |
101 | |
102 | template <typename To, typename From> struct isa_impl_cl<To, const From*> { |
103 | static inline bool doit(const From *Val) { |
104 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "llvm/include/llvm/Support/Casting.h", 104, __extension__ __PRETTY_FUNCTION__ )); |
105 | return isa_impl<To, From>::doit(*Val); |
106 | } |
107 | }; |
108 | |
109 | template <typename To, typename From> struct isa_impl_cl<To, const From*const> { |
110 | static inline bool doit(const From *Val) { |
111 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "llvm/include/llvm/Support/Casting.h", 111, __extension__ __PRETTY_FUNCTION__ )); |
112 | return isa_impl<To, From>::doit(*Val); |
113 | } |
114 | }; |
115 | |
116 | template<typename To, typename From, typename SimpleFrom> |
117 | struct isa_impl_wrap { |
118 | // When From != SimplifiedType, we can simplify the type some more by using |
119 | // the simplify_type template. |
120 | static bool doit(const From &Val) { |
121 | return isa_impl_wrap<To, SimpleFrom, |
122 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
123 | simplify_type<const From>::getSimplifiedValue(Val)); |
124 | } |
125 | }; |
126 | |
127 | template<typename To, typename FromTy> |
128 | struct isa_impl_wrap<To, FromTy, FromTy> { |
129 | // When From == SimpleType, we are as simple as we are going to get. |
130 | static bool doit(const FromTy &Val) { |
131 | return isa_impl_cl<To,FromTy>::doit(Val); |
132 | } |
133 | }; |
134 | |
135 | // isa<X> - Return true if the parameter to the template is an instance of one |
136 | // of the template type arguments. Used like this: |
137 | // |
138 | // if (isa<Type>(myVal)) { ... } |
139 | // if (isa<Type0, Type1, Type2>(myVal)) { ... } |
140 | // |
141 | template <class X, class Y> LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) { |
142 | return isa_impl_wrap<X, const Y, |
143 | typename simplify_type<const Y>::SimpleType>::doit(Val); |
144 | } |
145 | |
146 | template <typename First, typename Second, typename... Rest, typename Y> |
147 | LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) { |
148 | return isa<First>(Val) || isa<Second, Rest...>(Val); |
149 | } |
150 | |
151 | // isa_and_nonnull<X> - Functionally identical to isa, except that a null value |
152 | // is accepted. |
153 | // |
154 | template <typename... X, class Y> |
155 | LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa_and_nonnull(const Y &Val) { |
156 | if (!Val) |
157 | return false; |
158 | return isa<X...>(Val); |
159 | } |
160 | |
161 | //===----------------------------------------------------------------------===// |
162 | // cast<x> Support Templates |
163 | //===----------------------------------------------------------------------===// |
164 | |
165 | template<class To, class From> struct cast_retty; |
166 | |
167 | // Calculate what type the 'cast' function should return, based on a requested |
168 | // type of To and a source type of From. |
169 | template<class To, class From> struct cast_retty_impl { |
170 | using ret_type = To &; // Normal case, return Ty& |
171 | }; |
172 | template<class To, class From> struct cast_retty_impl<To, const From> { |
173 | using ret_type = const To &; // Normal case, return Ty& |
174 | }; |
175 | |
176 | template<class To, class From> struct cast_retty_impl<To, From*> { |
177 | using ret_type = To *; // Pointer arg case, return Ty* |
178 | }; |
179 | |
180 | template<class To, class From> struct cast_retty_impl<To, const From*> { |
181 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
182 | }; |
183 | |
184 | template<class To, class From> struct cast_retty_impl<To, const From*const> { |
185 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
186 | }; |
187 | |
188 | template <class To, class From> |
189 | struct cast_retty_impl<To, std::unique_ptr<From>> { |
190 | private: |
191 | using PointerType = typename cast_retty_impl<To, From *>::ret_type; |
192 | using ResultType = std::remove_pointer_t<PointerType>; |
193 | |
194 | public: |
195 | using ret_type = std::unique_ptr<ResultType>; |
196 | }; |
197 | |
198 | template<class To, class From, class SimpleFrom> |
199 | struct cast_retty_wrap { |
200 | // When the simplified type and the from type are not the same, use the type |
201 | // simplifier to reduce the type, then reuse cast_retty_impl to get the |
202 | // resultant type. |
203 | using ret_type = typename cast_retty<To, SimpleFrom>::ret_type; |
204 | }; |
205 | |
206 | template<class To, class FromTy> |
207 | struct cast_retty_wrap<To, FromTy, FromTy> { |
208 | // When the simplified type is equal to the from type, use it directly. |
209 | using ret_type = typename cast_retty_impl<To,FromTy>::ret_type; |
210 | }; |
211 | |
212 | template<class To, class From> |
213 | struct cast_retty { |
214 | using ret_type = typename cast_retty_wrap< |
215 | To, From, typename simplify_type<From>::SimpleType>::ret_type; |
216 | }; |
217 | |
218 | // Ensure the non-simple values are converted using the simplify_type template |
219 | // that may be specialized by smart pointers... |
220 | // |
221 | template<class To, class From, class SimpleFrom> struct cast_convert_val { |
222 | // This is not a simple type, use the template to simplify it... |
223 | static typename cast_retty<To, From>::ret_type doit(From &Val) { |
224 | return cast_convert_val<To, SimpleFrom, |
225 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
226 | simplify_type<From>::getSimplifiedValue(Val)); |
227 | } |
228 | }; |
229 | |
230 | template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { |
231 | // This _is_ a simple type, just cast it. |
232 | static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { |
233 | typename cast_retty<To, FromTy>::ret_type Res2 |
234 | = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val); |
235 | return Res2; |
236 | } |
237 | }; |
238 | |
239 | template <class X> struct is_simple_type { |
240 | static const bool value = |
241 | std::is_same<X, typename simplify_type<X>::SimpleType>::value; |
242 | }; |
243 | |
244 | // cast<X> - Return the argument parameter cast to the specified type. This |
245 | // casting operator asserts that the type is correct, so it does not return null |
246 | // on failure. It does not allow a null argument (use cast_or_null for that). |
247 | // It is typically used like this: |
248 | // |
249 | // cast<Instruction>(myVal)->getParent() |
250 | // |
251 | template <class X, class Y> |
252 | inline std::enable_if_t<!is_simple_type<Y>::value, |
253 | typename cast_retty<X, const Y>::ret_type> |
254 | cast(const Y &Val) { |
255 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 255, __extension__ __PRETTY_FUNCTION__ )); |
256 | return cast_convert_val< |
257 | X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val); |
258 | } |
259 | |
260 | template <class X, class Y> |
261 | inline typename cast_retty<X, Y>::ret_type cast(Y &Val) { |
262 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 262, __extension__ __PRETTY_FUNCTION__ )); |
263 | return cast_convert_val<X, Y, |
264 | typename simplify_type<Y>::SimpleType>::doit(Val); |
265 | } |
266 | |
267 | template <class X, class Y> |
268 | inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) { |
269 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 269, __extension__ __PRETTY_FUNCTION__ )); |
270 | return cast_convert_val<X, Y*, |
271 | typename simplify_type<Y*>::SimpleType>::doit(Val); |
272 | } |
273 | |
274 | template <class X, class Y> |
275 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
276 | cast(std::unique_ptr<Y> &&Val) { |
277 | assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!") ? void (0 ) : __assert_fail ("isa<X>(Val.get()) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 277, __extension__ __PRETTY_FUNCTION__ )); |
278 | using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type; |
279 | return ret_type( |
280 | cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit( |
281 | Val.release())); |
282 | } |
283 | |
284 | // cast_or_null<X> - Functionally identical to cast, except that a null value is |
285 | // accepted. |
286 | // |
287 | template <class X, class Y> |
288 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t< |
289 | !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type> |
290 | cast_or_null(const Y &Val) { |
291 | if (!Val) |
292 | return nullptr; |
293 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 293, __extension__ __PRETTY_FUNCTION__ )); |
294 | return cast<X>(Val); |
295 | } |
296 | |
297 | template <class X, class Y> |
298 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t<!is_simple_type<Y>::value, |
299 | typename cast_retty<X, Y>::ret_type> |
300 | cast_or_null(Y &Val) { |
301 | if (!Val) |
302 | return nullptr; |
303 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 303, __extension__ __PRETTY_FUNCTION__ )); |
304 | return cast<X>(Val); |
305 | } |
306 | |
307 | template <class X, class Y> |
308 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
309 | cast_or_null(Y *Val) { |
310 | if (!Val) return nullptr; |
311 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 311, __extension__ __PRETTY_FUNCTION__ )); |
312 | return cast<X>(Val); |
313 | } |
314 | |
315 | template <class X, class Y> |
316 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
317 | cast_or_null(std::unique_ptr<Y> &&Val) { |
318 | if (!Val) |
319 | return nullptr; |
320 | return cast<X>(std::move(Val)); |
321 | } |
322 | |
323 | // dyn_cast<X> - Return the argument parameter cast to the specified type. This |
324 | // casting operator returns null if the argument is of the wrong type, so it can |
325 | // be used to test for a type as well as cast if successful. This should be |
326 | // used in the context of an if statement like this: |
327 | // |
328 | // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } |
329 | // |
330 | |
331 | template <class X, class Y> |
332 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t< |
333 | !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type> |
334 | dyn_cast(const Y &Val) { |
335 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
336 | } |
337 | |
338 | template <class X, class Y> |
339 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { |
340 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
341 | } |
342 | |
343 | template <class X, class Y> |
344 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) { |
345 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
346 | } |
347 | |
348 | // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null |
349 | // value is accepted. |
350 | // |
351 | template <class X, class Y> |
352 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t< |
353 | !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type> |
354 | dyn_cast_or_null(const Y &Val) { |
355 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
356 | } |
357 | |
358 | template <class X, class Y> |
359 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t<!is_simple_type<Y>::value, |
360 | typename cast_retty<X, Y>::ret_type> |
361 | dyn_cast_or_null(Y &Val) { |
362 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
363 | } |
364 | |
365 | template <class X, class Y> |
366 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
367 | dyn_cast_or_null(Y *Val) { |
368 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
369 | } |
370 | |
371 | // unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>, |
372 | // taking ownership of the input pointer iff isa<X>(Val) is true. If the |
373 | // cast is successful, From refers to nullptr on exit and the casted value |
374 | // is returned. If the cast is unsuccessful, the function returns nullptr |
375 | // and From is unchanged. |
376 | template <class X, class Y> |
377 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &Val) |
378 | -> decltype(cast<X>(Val)) { |
379 | if (!isa<X>(Val)) |
380 | return nullptr; |
381 | return cast<X>(std::move(Val)); |
382 | } |
383 | |
384 | template <class X, class Y> |
385 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) { |
386 | return unique_dyn_cast<X, Y>(Val); |
387 | } |
388 | |
389 | // dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that |
390 | // a null value is accepted. |
391 | template <class X, class Y> |
392 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) |
393 | -> decltype(cast<X>(Val)) { |
394 | if (!Val) |
395 | return nullptr; |
396 | return unique_dyn_cast<X, Y>(Val); |
397 | } |
398 | |
399 | template <class X, class Y> |
400 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) { |
401 | return unique_dyn_cast_or_null<X, Y>(Val); |
402 | } |
403 | |
404 | } // end namespace llvm |
405 | |
406 | #endif // LLVM_SUPPORT_CASTING_H |