 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
71.7% |
1434 / 1999 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
90.1% |
1801 / 1999 |
| |
|
Line Coverage: |
87.1% |
2135 / 2452 |
| |
 |
|
 |
1 : //===--- ASTContext.cpp - Context to hold long-lived AST nodes ------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file implements the ASTContext interface.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/AST/ASTContext.h"
15 : #include "clang/AST/CharUnits.h"
16 : #include "clang/AST/DeclCXX.h"
17 : #include "clang/AST/DeclObjC.h"
18 : #include "clang/AST/DeclTemplate.h"
19 : #include "clang/AST/TypeLoc.h"
20 : #include "clang/AST/Expr.h"
21 : #include "clang/AST/ExternalASTSource.h"
22 : #include "clang/AST/RecordLayout.h"
23 : #include "clang/Basic/Builtins.h"
24 : #include "clang/Basic/SourceManager.h"
25 : #include "clang/Basic/TargetInfo.h"
26 : #include "llvm/ADT/SmallString.h"
27 : #include "llvm/ADT/StringExtras.h"
28 : #include "llvm/Support/MathExtras.h"
29 : #include "llvm/Support/raw_ostream.h"
30 : #include "RecordLayoutBuilder.h"
31 :
32 : using namespace clang;
33 :
34 : enum FloatingRank {
35 : FloatRank, DoubleRank, LongDoubleRank
36 : };
37 :
38 : ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
39 : const TargetInfo &t,
40 : IdentifierTable &idents, SelectorTable &sels,
41 : Builtin::Context &builtins,
42 2250: bool FreeMem, unsigned size_reserve) :
43 : GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0),
44 : ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), jmp_bufDecl(0),
45 : sigjmp_bufDecl(0), BlockDescriptorType(0), BlockDescriptorExtendedType(0),
46 : SourceMgr(SM), LangOpts(LOpts),
47 : LoadedExternalComments(false), FreeMemory(FreeMem), Target(t),
48 : Idents(idents), Selectors(sels),
49 2250: BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) {
50 2250: ObjCIdRedefinitionType = QualType();
51 2250: ObjCClassRedefinitionType = QualType();
52 2250: ObjCSelRedefinitionType = QualType();
0: branch 0 not taken
2250: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
53 2250: if (size_reserve > 0) Types.reserve(size_reserve);
54 2250: TUDecl = TranslationUnitDecl::Create(*this);
55 2250: InitBuiltinTypes();
56 2250: }
57 :
58 2146: ASTContext::~ASTContext() {
2129: branch 0 taken
17: branch 1 taken
17: branch 2 taken
17: branch 3 taken
59 2146: if (FreeMemory) {
60 : // Deallocate all the types.
134110: branch 1 taken
2129: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
61 138368: while (!Types.empty()) {
62 134110: Types.back()->Destroy(*this);
63 134110: Types.pop_back();
64 : }
65 :
536: branch 1 taken
2129: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
66 4794: for (llvm::FoldingSet<ExtQuals>::iterator
67 2129: I = ExtQualNodes.begin(), E = ExtQualNodes.end(); I != E; ) {
68 : // Increment in loop to prevent using deallocated memory.
69 536: Deallocate(&*I++);
70 : }
71 : }
72 :
1582: branch 2 taken
2146: branch 3 taken
0: branch 6 not taken
0: branch 7 not taken
73 5874: for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
74 2146: I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
75 : // Increment in loop to prevent using deallocated memory.
76 1582: ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
1582: branch 0 taken
0: branch 1 not taken
1582: branch 4 taken
1582: branch 5 taken
77 1582: delete R;
78 : }
79 :
347: branch 2 taken
2146: branch 3 taken
0: branch 6 not taken
0: branch 7 not taken
80 4639: for (llvm::DenseMap<const ObjCContainerDecl*,
81 : const ASTRecordLayout*>::iterator
82 2146: I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) {
83 : // Increment in loop to prevent using deallocated memory.
84 347: ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
201: branch 0 taken
146: branch 1 taken
201: branch 4 taken
201: branch 5 taken
85 347: delete R;
86 : }
87 :
88 : // Destroy nested-name-specifiers.
2267: branch 1 taken
2146: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
89 6559: for (llvm::FoldingSet<NestedNameSpecifier>::iterator
90 2146: NNS = NestedNameSpecifiers.begin(),
91 2146: NNSEnd = NestedNameSpecifiers.end();
92 : NNS != NNSEnd; ) {
93 : // Increment in loop to prevent using deallocated memory.
94 2267: (*NNS++).Destroy(*this);
95 : }
96 :
42: branch 0 taken
2104: branch 1 taken
2104: branch 2 taken
2104: branch 3 taken
97 2146: if (GlobalNestedNameSpecifier)
98 42: GlobalNestedNameSpecifier->Destroy(*this);
99 :
100 2146: TUDecl->Destroy(*this);
101 2146: }
102 :
103 : void
104 48: ASTContext::setExternalSource(llvm::OwningPtr<ExternalASTSource> &Source) {
105 48: ExternalSource.reset(Source.take());
106 48: }
107 :
108 2: void ASTContext::PrintStats() const {
109 2: fprintf(stderr, "*** AST Context Stats:\n");
110 2: fprintf(stderr, " %d types total.\n", (int)Types.size());
111 :
112 : unsigned counts[] = {
113 : #define TYPE(Name, Parent) 0,
114 : #define ABSTRACT_TYPE(Name, Parent)
115 : #include "clang/AST/TypeNodes.def"
116 : 0 // Extra
117 2: };
118 :
67: branch 1 taken
2: branch 2 taken
119 69: for (unsigned i = 0, e = Types.size(); i != e; ++i) {
120 67: Type *T = Types[i];
121 67: counts[(unsigned)T->getTypeClass()]++;
122 : }
123 :
124 2: unsigned Idx = 0;
125 2: unsigned TotalBytes = 0;
126 : #define TYPE(Name, Parent) \
127 : if (counts[Idx]) \
128 : fprintf(stderr, " %d %s types\n", (int)counts[Idx], #Name); \
129 : TotalBytes += counts[Idx] * sizeof(Name##Type); \
130 : ++Idx;
131 : #define ABSTRACT_TYPE(Name, Parent)
132 : #include "clang/AST/TypeNodes.def"
133 :
134 2: fprintf(stderr, "Total bytes = %d\n", int(TotalBytes));
135 :
0: branch 1 not taken
2: branch 2 taken
136 2: if (ExternalSource.get()) {
137 0: fprintf(stderr, "\n");
138 0: ExternalSource->PrintStats();
139 : }
140 2: }
141 :
142 :
143 58794: void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) {
58794: branch 1 taken
0: branch 2 not taken
144 58794: BuiltinType *Ty = new (*this, TypeAlignment) BuiltinType(K);
145 58794: R = CanQualType::CreateUnsafe(QualType(Ty, 0));
146 58794: Types.push_back(Ty);
147 58794: }
148 :
149 2250: void ASTContext::InitBuiltinTypes() {
2250: branch 1 taken
0: branch 2 not taken
150 2250: assert(VoidTy.isNull() && "Context reinitialized?");
151 :
152 : // C99 6.2.5p19.
153 2250: InitBuiltinType(VoidTy, BuiltinType::Void);
154 :
155 : // C99 6.2.5p2.
156 2250: InitBuiltinType(BoolTy, BuiltinType::Bool);
157 : // C99 6.2.5p3.
2250: branch 0 taken
0: branch 1 not taken
158 2250: if (LangOpts.CharIsSigned)
159 2250: InitBuiltinType(CharTy, BuiltinType::Char_S);
160 : else
161 0: InitBuiltinType(CharTy, BuiltinType::Char_U);
162 : // C99 6.2.5p4.
163 2250: InitBuiltinType(SignedCharTy, BuiltinType::SChar);
164 2250: InitBuiltinType(ShortTy, BuiltinType::Short);
165 2250: InitBuiltinType(IntTy, BuiltinType::Int);
166 2250: InitBuiltinType(LongTy, BuiltinType::Long);
167 2250: InitBuiltinType(LongLongTy, BuiltinType::LongLong);
168 :
169 : // C99 6.2.5p6.
170 2250: InitBuiltinType(UnsignedCharTy, BuiltinType::UChar);
171 2250: InitBuiltinType(UnsignedShortTy, BuiltinType::UShort);
172 2250: InitBuiltinType(UnsignedIntTy, BuiltinType::UInt);
173 2250: InitBuiltinType(UnsignedLongTy, BuiltinType::ULong);
174 2250: InitBuiltinType(UnsignedLongLongTy, BuiltinType::ULongLong);
175 :
176 : // C99 6.2.5p10.
177 2250: InitBuiltinType(FloatTy, BuiltinType::Float);
178 2250: InitBuiltinType(DoubleTy, BuiltinType::Double);
179 2250: InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
180 :
181 : // GNU extension, 128-bit integers.
182 2250: InitBuiltinType(Int128Ty, BuiltinType::Int128);
183 2250: InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128);
184 :
848: branch 0 taken
1402: branch 1 taken
185 2250: if (LangOpts.CPlusPlus) // C++ 3.9.1p5
186 848: InitBuiltinType(WCharTy, BuiltinType::WChar);
187 : else // C99
188 1402: WCharTy = getFromTargetType(Target.getWCharType());
189 :
848: branch 0 taken
1402: branch 1 taken
190 2250: if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
191 848: InitBuiltinType(Char16Ty, BuiltinType::Char16);
192 : else // C99
193 1402: Char16Ty = getFromTargetType(Target.getChar16Type());
194 :
848: branch 0 taken
1402: branch 1 taken
195 2250: if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
196 848: InitBuiltinType(Char32Ty, BuiltinType::Char32);
197 : else // C99
198 1402: Char32Ty = getFromTargetType(Target.getChar32Type());
199 :
200 : // Placeholder type for functions.
201 2250: InitBuiltinType(OverloadTy, BuiltinType::Overload);
202 :
203 : // Placeholder type for type-dependent expressions whose type is
204 : // completely unknown. No code should ever check a type against
205 : // DependentTy and users should never see it; however, it is here to
206 : // help diagnose failures to properly check for type-dependent
207 : // expressions.
208 2250: InitBuiltinType(DependentTy, BuiltinType::Dependent);
209 :
210 : // Placeholder type for C++0x auto declarations whose real type has
211 : // not yet been deduced.
212 2250: InitBuiltinType(UndeducedAutoTy, BuiltinType::UndeducedAuto);
213 :
214 : // C99 6.2.5p11.
215 2250: FloatComplexTy = getComplexType(FloatTy);
216 2250: DoubleComplexTy = getComplexType(DoubleTy);
217 2250: LongDoubleComplexTy = getComplexType(LongDoubleTy);
218 :
219 2250: BuiltinVaListType = QualType();
220 :
221 : // "Builtin" typedefs set by Sema::ActOnTranslationUnitScope().
222 2250: ObjCIdTypedefType = QualType();
223 2250: ObjCClassTypedefType = QualType();
224 2250: ObjCSelTypedefType = QualType();
225 :
226 : // Builtin types for 'id', 'Class', and 'SEL'.
227 2250: InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);
228 2250: InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);
229 2250: InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel);
230 :
231 2250: ObjCConstantStringType = QualType();
232 :
233 : // void * type
234 2250: VoidPtrTy = getPointerType(VoidTy);
235 :
236 : // nullptr type (C++0x 2.14.7)
237 2250: InitBuiltinType(NullPtrTy, BuiltinType::NullPtr);
238 2250: }
239 :
240 : MemberSpecializationInfo *
241 2543: ASTContext::getInstantiatedFromStaticDataMember(const VarDecl *Var) {
2543: branch 1 taken
0: branch 2 not taken
242 2543: assert(Var->isStaticDataMember() && "Not a static data member");
243 : llvm::DenseMap<const VarDecl *, MemberSpecializationInfo *>::iterator Pos
244 2543: = InstantiatedFromStaticDataMember.find(Var);
1675: branch 3 taken
868: branch 4 taken
245 2543: if (Pos == InstantiatedFromStaticDataMember.end())
246 1675: return 0;
247 :
248 868: return Pos->second;
249 : }
250 :
251 : void
252 : ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
253 300: TemplateSpecializationKind TSK) {
300: branch 1 taken
0: branch 2 not taken
254 300: assert(Inst->isStaticDataMember() && "Not a static data member");
300: branch 1 taken
0: branch 2 not taken
255 300: assert(Tmpl->isStaticDataMember() && "Not a static data member");
256 : assert(!InstantiatedFromStaticDataMember[Inst] &&
300: branch 1 taken
0: branch 2 not taken
257 300: "Already noted what static data member was instantiated from");
258 : InstantiatedFromStaticDataMember[Inst]
300: branch 2 taken
0: branch 3 not taken
259 600: = new (*this) MemberSpecializationInfo(Tmpl, TSK);
260 300: }
261 :
262 : NamedDecl *
263 4: ASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) {
264 : llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos
265 4: = InstantiatedFromUsingDecl.find(UUD);
0: branch 3 not taken
4: branch 4 taken
266 4: if (Pos == InstantiatedFromUsingDecl.end())
267 0: return 0;
268 :
269 4: return Pos->second;
270 : }
271 :
272 : void
273 22: ASTContext::setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern) {
274 : assert((isa<UsingDecl>(Pattern) ||
275 : isa<UnresolvedUsingValueDecl>(Pattern) ||
276 : isa<UnresolvedUsingTypenameDecl>(Pattern)) &&
15: branch 1 taken
7: branch 2 taken
4: branch 4 taken
11: branch 5 taken
4: branch 7 taken
0: branch 8 not taken
277 22: "pattern decl is not a using decl");
22: branch 1 taken
0: branch 2 not taken
278 22: assert(!InstantiatedFromUsingDecl[Inst] && "pattern already exists");
279 22: InstantiatedFromUsingDecl[Inst] = Pattern;
280 22: }
281 :
282 : UsingShadowDecl *
283 0: ASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) {
284 : llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos
285 0: = InstantiatedFromUsingShadowDecl.find(Inst);
0: branch 3 not taken
0: branch 4 not taken
286 0: if (Pos == InstantiatedFromUsingShadowDecl.end())
287 0: return 0;
288 :
289 0: return Pos->second;
290 : }
291 :
292 : void
293 : ASTContext::setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
294 5: UsingShadowDecl *Pattern) {
5: branch 1 taken
0: branch 2 not taken
295 5: assert(!InstantiatedFromUsingShadowDecl[Inst] && "pattern already exists");
296 5: InstantiatedFromUsingShadowDecl[Inst] = Pattern;
297 5: }
298 :
299 0: FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) {
300 : llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos
301 0: = InstantiatedFromUnnamedFieldDecl.find(Field);
0: branch 3 not taken
0: branch 4 not taken
302 0: if (Pos == InstantiatedFromUnnamedFieldDecl.end())
303 0: return 0;
304 :
305 0: return Pos->second;
306 : }
307 :
308 : void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,
309 5: FieldDecl *Tmpl) {
5: branch 2 taken
0: branch 3 not taken
310 5: assert(!Inst->getDeclName() && "Instantiated field decl is not unnamed");
5: branch 2 taken
0: branch 3 not taken
311 5: assert(!Tmpl->getDeclName() && "Template field decl is not unnamed");
312 : assert(!InstantiatedFromUnnamedFieldDecl[Inst] &&
5: branch 1 taken
0: branch 2 not taken
313 5: "Already noted what unnamed field was instantiated from");
314 :
315 5: InstantiatedFromUnnamedFieldDecl[Inst] = Tmpl;
316 5: }
317 :
318 : namespace {
319 : class BeforeInTranslationUnit
320 : : std::binary_function<SourceRange, SourceRange, bool> {
321 : SourceManager *SourceMgr;
322 :
323 : public:
324 0: explicit BeforeInTranslationUnit(SourceManager *SM) : SourceMgr(SM) { }
325 :
326 0: bool operator()(SourceRange X, SourceRange Y) {
327 0: return SourceMgr->isBeforeInTranslationUnit(X.getBegin(), Y.getBegin());
328 : }
329 : };
330 : }
331 :
332 : /// \brief Determine whether the given comment is a Doxygen-style comment.
333 : ///
334 : /// \param Start the start of the comment text.
335 : ///
336 : /// \param End the end of the comment text.
337 : ///
338 : /// \param Member whether we want to check whether this is a member comment
339 : /// (which requires a < after the Doxygen-comment delimiter). Otherwise,
340 : /// we only return true when we find a non-member comment.
341 : static bool
342 : isDoxygenComment(SourceManager &SourceMgr, SourceRange Comment,
343 0: bool Member = false) {
344 : const char *BufferStart
345 0: = SourceMgr.getBufferData(SourceMgr.getFileID(Comment.getBegin())).first;
346 0: const char *Start = BufferStart + SourceMgr.getFileOffset(Comment.getBegin());
347 0: const char* End = BufferStart + SourceMgr.getFileOffset(Comment.getEnd());
348 :
0: branch 0 not taken
0: branch 1 not taken
349 0: if (End - Start < 4)
350 0: return false;
351 :
0: branch 0 not taken
0: branch 1 not taken
352 0: assert(Start[0] == '/' && "Not a comment?");
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
353 0: if (Start[1] == '*' && !(Start[2] == '!' || Start[2] == '*'))
354 0: return false;
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
355 0: if (Start[1] == '/' && !(Start[2] == '!' || Start[2] == '/'))
356 0: return false;
357 :
358 0: return (Start[3] == '<') == Member;
359 : }
360 :
361 : /// \brief Retrieve the comment associated with the given declaration, if
362 : /// it has one.
363 0: const char *ASTContext::getCommentForDecl(const Decl *D) {
0: branch 0 not taken
0: branch 1 not taken
364 0: if (!D)
365 0: return 0;
366 :
367 : // Check whether we have cached a comment string for this declaration
368 : // already.
369 : llvm::DenseMap<const Decl *, std::string>::iterator Pos
370 0: = DeclComments.find(D);
0: branch 3 not taken
0: branch 4 not taken
371 0: if (Pos != DeclComments.end())
372 0: return Pos->second.c_str();
373 :
374 : // If we have an external AST source and have not yet loaded comments from
375 : // that source, do so now.
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
376 0: if (ExternalSource && !LoadedExternalComments) {
377 0: std::vector<SourceRange> LoadedComments;
378 0: ExternalSource->ReadComments(LoadedComments);
379 :
0: branch 1 not taken
0: branch 2 not taken
380 0: if (!LoadedComments.empty())
381 : Comments.insert(Comments.begin(), LoadedComments.begin(),
382 0: LoadedComments.end());
383 :
384 0: LoadedExternalComments = true;
385 : }
386 :
387 : // If there are no comments anywhere, we won't find anything.
0: branch 1 not taken
0: branch 2 not taken
388 0: if (Comments.empty())
389 0: return 0;
390 :
391 : // If the declaration doesn't map directly to a location in a file, we
392 : // can't find the comment.
393 0: SourceLocation DeclStartLoc = D->getLocStart();
0: branch 1 not taken
0: branch 2 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
394 0: if (DeclStartLoc.isInvalid() || !DeclStartLoc.isFileID())
395 0: return 0;
396 :
397 : // Find the comment that occurs just before this declaration.
398 : std::vector<SourceRange>::iterator LastComment
399 : = std::lower_bound(Comments.begin(), Comments.end(),
400 : SourceRange(DeclStartLoc),
401 0: BeforeInTranslationUnit(&SourceMgr));
402 :
403 : // Decompose the location for the start of the declaration and find the
404 : // beginning of the file buffer.
405 : std::pair<FileID, unsigned> DeclStartDecomp
406 0: = SourceMgr.getDecomposedLoc(DeclStartLoc);
407 : const char *FileBufferStart
408 0: = SourceMgr.getBufferData(DeclStartDecomp.first).first;
409 :
410 : // First check whether we have a comment for a member.
0: branch 2 not taken
0: branch 3 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 8 not taken
0: branch 9 not taken
0: branch 12 not taken
0: branch 13 not taken
0: branch 14 not taken
0: branch 15 not taken
411 0: if (LastComment != Comments.end() &&
412 : !isa<TagDecl>(D) && !isa<NamespaceDecl>(D) &&
413 : isDoxygenComment(SourceMgr, *LastComment, true)) {
414 : std::pair<FileID, unsigned> LastCommentEndDecomp
415 0: = SourceMgr.getDecomposedLoc(LastComment->getEnd());
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
416 0: if (DeclStartDecomp.first == LastCommentEndDecomp.first &&
417 : SourceMgr.getLineNumber(DeclStartDecomp.first, DeclStartDecomp.second)
418 : == SourceMgr.getLineNumber(LastCommentEndDecomp.first,
419 : LastCommentEndDecomp.second)) {
420 : // The Doxygen member comment comes after the declaration starts and
421 : // is on the same line and in the same file as the declaration. This
422 : // is the comment we want.
423 0: std::string &Result = DeclComments[D];
424 : Result.append(FileBufferStart +
425 : SourceMgr.getFileOffset(LastComment->getBegin()),
426 0: FileBufferStart + LastCommentEndDecomp.second + 1);
427 0: return Result.c_str();
428 : }
429 : }
430 :
0: branch 2 not taken
0: branch 3 not taken
431 0: if (LastComment == Comments.begin())
432 0: return 0;
433 0: --LastComment;
434 :
435 : // Decompose the end of the comment.
436 : std::pair<FileID, unsigned> LastCommentEndDecomp
437 0: = SourceMgr.getDecomposedLoc(LastComment->getEnd());
438 :
439 : // If the comment and the declaration aren't in the same file, then they
440 : // aren't related.
0: branch 1 not taken
0: branch 2 not taken
441 0: if (DeclStartDecomp.first != LastCommentEndDecomp.first)
442 0: return 0;
443 :
444 : // Check that we actually have a Doxygen comment.
0: branch 2 not taken
0: branch 3 not taken
445 0: if (!isDoxygenComment(SourceMgr, *LastComment))
446 0: return 0;
447 :
448 : // Compute the starting line for the declaration and for the end of the
449 : // comment (this is expensive).
450 : unsigned DeclStartLine
451 0: = SourceMgr.getLineNumber(DeclStartDecomp.first, DeclStartDecomp.second);
452 : unsigned CommentEndLine
453 : = SourceMgr.getLineNumber(LastCommentEndDecomp.first,
454 0: LastCommentEndDecomp.second);
455 :
456 : // If the comment does not end on the line prior to the declaration, then
457 : // the comment is not associated with the declaration at all.
0: branch 0 not taken
0: branch 1 not taken
458 0: if (CommentEndLine + 1 != DeclStartLine)
459 0: return 0;
460 :
461 : // We have a comment, but there may be more comments on the previous lines.
462 : // Keep looking so long as the comments are still Doxygen comments and are
463 : // still adjacent.
464 : unsigned ExpectedLine
465 0: = SourceMgr.getSpellingLineNumber(LastComment->getBegin()) - 1;
466 0: std::vector<SourceRange>::iterator FirstComment = LastComment;
0: branch 2 not taken
0: branch 3 not taken
467 0: while (FirstComment != Comments.begin()) {
468 : // Look at the previous comment
469 0: --FirstComment;
470 : std::pair<FileID, unsigned> Decomp
471 0: = SourceMgr.getDecomposedLoc(FirstComment->getEnd());
472 :
473 : // If this previous comment is in a different file, we're done.
0: branch 1 not taken
0: branch 2 not taken
474 0: if (Decomp.first != DeclStartDecomp.first) {
475 0: ++FirstComment;
476 0: break;
477 : }
478 :
479 : // If this comment is not a Doxygen comment, we're done.
0: branch 2 not taken
0: branch 3 not taken
480 0: if (!isDoxygenComment(SourceMgr, *FirstComment)) {
481 0: ++FirstComment;
482 0: break;
483 : }
484 :
485 : // If the line number is not what we expected, we're done.
486 0: unsigned Line = SourceMgr.getLineNumber(Decomp.first, Decomp.second);
0: branch 0 not taken
0: branch 1 not taken
487 0: if (Line != ExpectedLine) {
488 0: ++FirstComment;
489 0: break;
490 : }
491 :
492 : // Set the next expected line number.
493 : ExpectedLine
494 0: = SourceMgr.getSpellingLineNumber(FirstComment->getBegin()) - 1;
495 : }
496 :
497 : // The iterator range [FirstComment, LastComment] contains all of the
498 : // BCPL comments that, together, are associated with this declaration.
499 : // Form a single comment block string for this declaration that concatenates
500 : // all of these comments.
501 0: std::string &Result = DeclComments[D];
0: branch 1 not taken
0: branch 2 not taken
502 0: while (FirstComment != LastComment) {
503 : std::pair<FileID, unsigned> DecompStart
504 0: = SourceMgr.getDecomposedLoc(FirstComment->getBegin());
505 : std::pair<FileID, unsigned> DecompEnd
506 0: = SourceMgr.getDecomposedLoc(FirstComment->getEnd());
507 : Result.append(FileBufferStart + DecompStart.second,
508 0: FileBufferStart + DecompEnd.second + 1);
509 0: ++FirstComment;
510 : }
511 :
512 : // Append the last comment line.
513 : Result.append(FileBufferStart +
514 : SourceMgr.getFileOffset(LastComment->getBegin()),
515 0: FileBufferStart + LastCommentEndDecomp.second + 1);
516 0: return Result.c_str();
517 : }
518 :
519 : //===----------------------------------------------------------------------===//
520 : // Type Sizing and Analysis
521 : //===----------------------------------------------------------------------===//
522 :
523 : /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
524 : /// scalar floating point type.
525 1479: const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
526 1479: const BuiltinType *BT = T->getAs<BuiltinType>();
0: branch 0 not taken
1479: branch 1 taken
527 1479: assert(BT && "Not a floating point type!");
0: branch 1 not taken
557: branch 2 taken
876: branch 3 taken
46: branch 4 taken
528 1479: switch (BT->getKind()) {
529 0: default: assert(0 && "Not a floating point type!");
530 557: case BuiltinType::Float: return Target.getFloatFormat();
531 876: case BuiltinType::Double: return Target.getDoubleFormat();
532 46: case BuiltinType::LongDouble: return Target.getLongDoubleFormat();
533 : }
534 : }
535 :
536 : /// getDeclAlign - Return a conservative estimate of the alignment of the
537 : /// specified decl. Note that bitfields do not have a valid alignment, so
538 : /// this method will assert on them.
539 : /// If @p RefAsPointee, references are treated like their underlying type
540 : /// (for alignof), else they're treated like pointers (for CodeGen).
541 1996: CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) {
542 1996: unsigned Align = Target.getCharWidth();
543 :
21: branch 1 taken
1975: branch 2 taken
544 1996: if (const AlignedAttr* AA = D->getAttr<AlignedAttr>())
545 21: Align = std::max(Align, AA->getMaxAlignment());
546 :
1996: branch 1 taken
0: branch 2 not taken
547 1996: if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
548 1996: QualType T = VD->getType();
19: branch 2 taken
1977: branch 3 taken
549 1996: if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
1: branch 0 taken
18: branch 1 taken
550 19: if (RefAsPointee)
551 1: T = RT->getPointeeType();
552 : else
553 18: T = getPointerType(RT->getPointeeType());
554 : }
1995: branch 2 taken
1: branch 3 taken
1992: branch 6 taken
3: branch 7 taken
1992: branch 8 taken
4: branch 9 taken
555 1996: if (!T->isIncompleteType() && !T->isFunctionType()) {
556 : // Incomplete or function types default to 1.
1992: branch 1 taken
11: branch 2 taken
0: branch 4 not taken
1992: branch 5 taken
11: branch 6 taken
1992: branch 7 taken
557 3995: while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
558 11: T = cast<ArrayType>(T)->getElementType();
559 :
560 1992: Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
561 : }
562 : }
563 :
564 1996: return CharUnits::fromQuantity(Align / Target.getCharWidth());
565 : }
566 :
567 : /// getTypeSize - Return the size of the specified type, in bits. This method
568 : /// does not work on incomplete types.
569 : ///
570 : /// FIXME: Pointers into different addr spaces could have different sizes and
571 : /// alignment requirements: getPointerInfo should take an AddrSpace, this
572 : /// should take a QualType, &c.
573 : std::pair<uint64_t, unsigned>
574 117147: ASTContext::getTypeInfo(const Type *T) {
575 117147: uint64_t Width=0;
576 117147: unsigned Align=8;
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
610: branch 4 taken
3102: branch 5 taken
87197: branch 6 taken
3872: branch 7 taken
93: branch 8 taken
148: branch 9 taken
12163: branch 10 taken
103: branch 11 taken
217: branch 12 taken
39: branch 13 taken
2499: branch 14 taken
144: branch 15 taken
72: branch 16 taken
6665: branch 17 taken
39: branch 18 taken
6: branch 19 taken
0: branch 20 not taken
36: branch 21 taken
142: branch 22 taken
0: branch 23 not taken
577 117147: switch (T->getTypeClass()) {
578 : #define TYPE(Class, Base)
579 : #define ABSTRACT_TYPE(Class, Base)
580 : #define NON_CANONICAL_TYPE(Class, Base)
581 : #define DEPENDENT_TYPE(Class, Base) case Type::Class:
582 : #include "clang/AST/TypeNodes.def"
583 0: assert(false && "Should not see dependent types");
584 : break;
585 :
586 : case Type::FunctionNoProto:
587 : case Type::FunctionProto:
588 : // GCC extension: alignof(function) = 32 bits
589 0: Width = 0;
590 0: Align = 32;
591 0: break;
592 :
593 : case Type::IncompleteArray:
594 : case Type::VariableArray:
595 0: Width = 0;
596 0: Align = getTypeAlign(cast<ArrayType>(T)->getElementType());
597 0: break;
598 :
599 : case Type::ConstantArray: {
600 610: const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
601 :
602 610: std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType());
603 610: Width = EltInfo.first*CAT->getSize().getZExtValue();
604 610: Align = EltInfo.second;
605 610: break;
606 : }
607 : case Type::ExtVector:
608 : case Type::Vector: {
609 3102: const VectorType *VT = cast<VectorType>(T);
610 3102: std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(VT->getElementType());
611 3102: Width = EltInfo.first*VT->getNumElements();
612 3102: Align = Width;
613 : // If the alignment is not a power of 2, round up to the next power of 2.
614 : // This happens for non-power-of-2 length vectors.
1: branch 2 taken
3101: branch 3 taken
615 3102: if (VT->getNumElements() & (VT->getNumElements()-1)) {
616 1: Align = llvm::NextPowerOf2(Align);
617 1: Width = llvm::RoundUpToAlignment(Width, Align);
618 : }
619 3102: break;
620 : }
621 :
622 : case Type::Builtin:
0: branch 2 not taken
9: branch 3 taken
564: branch 4 taken
11078: branch 5 taken
8: branch 6 taken
0: branch 7 not taken
0: branch 8 not taken
2767: branch 9 taken
58833: branch 10 taken
7641: branch 11 taken
4829: branch 12 taken
30: branch 13 taken
768: branch 14 taken
550: branch 15 taken
118: branch 16 taken
2: branch 17 taken
623 87197: switch (cast<BuiltinType>(T)->getKind()) {
624 0: default: assert(0 && "Unknown builtin type!");
625 : case BuiltinType::Void:
626 : // GCC extension: alignof(void) = 8 bits.
627 9: Width = 0;
628 9: Align = 8;
629 9: break;
630 :
631 : case BuiltinType::Bool:
632 564: Width = Target.getBoolWidth();
633 564: Align = Target.getBoolAlign();
634 564: break;
635 : case BuiltinType::Char_S:
636 : case BuiltinType::Char_U:
637 : case BuiltinType::UChar:
638 : case BuiltinType::SChar:
639 11078: Width = Target.getCharWidth();
640 11078: Align = Target.getCharAlign();
641 11078: break;
642 : case BuiltinType::WChar:
643 8: Width = Target.getWCharWidth();
644 8: Align = Target.getWCharAlign();
645 8: break;
646 : case BuiltinType::Char16:
647 0: Width = Target.getChar16Width();
648 0: Align = Target.getChar16Align();
649 0: break;
650 : case BuiltinType::Char32:
651 0: Width = Target.getChar32Width();
652 0: Align = Target.getChar32Align();
653 0: break;
654 : case BuiltinType::UShort:
655 : case BuiltinType::Short:
656 2767: Width = Target.getShortWidth();
657 2767: Align = Target.getShortAlign();
658 2767: break;
659 : case BuiltinType::UInt:
660 : case BuiltinType::Int:
661 58833: Width = Target.getIntWidth();
662 58833: Align = Target.getIntAlign();
663 58833: break;
664 : case BuiltinType::ULong:
665 : case BuiltinType::Long:
666 7641: Width = Target.getLongWidth();
667 7641: Align = Target.getLongAlign();
668 7641: break;
669 : case BuiltinType::ULongLong:
670 : case BuiltinType::LongLong:
671 4829: Width = Target.getLongLongWidth();
672 4829: Align = Target.getLongLongAlign();
673 4829: break;
674 : case BuiltinType::Int128:
675 : case BuiltinType::UInt128:
676 30: Width = 128;
677 30: Align = 128; // int128_t is 128-bit aligned on all targets.
678 30: break;
679 : case BuiltinType::Float:
680 768: Width = Target.getFloatWidth();
681 768: Align = Target.getFloatAlign();
682 768: break;
683 : case BuiltinType::Double:
684 550: Width = Target.getDoubleWidth();
685 550: Align = Target.getDoubleAlign();
686 550: break;
687 : case BuiltinType::LongDouble:
688 118: Width = Target.getLongDoubleWidth();
689 118: Align = Target.getLongDoubleAlign();
690 118: break;
691 : case BuiltinType::NullPtr:
692 2: Width = Target.getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t)
693 2: Align = Target.getPointerAlign(0); // == sizeof(void*)
694 : break;
695 : }
696 87197: break;
697 : case Type::ObjCObjectPointer:
698 3872: Width = Target.getPointerWidth(0);
699 3872: Align = Target.getPointerAlign(0);
700 3872: break;
701 : case Type::BlockPointer: {
702 93: unsigned AS = cast<BlockPointerType>(T)->getPointeeType().getAddressSpace();
703 93: Width = Target.getPointerWidth(AS);
704 93: Align = Target.getPointerAlign(AS);
705 93: break;
706 : }
707 : case Type::LValueReference:
708 : case Type::RValueReference: {
709 : // alignof and sizeof should never enter this code path here, so we go
710 : // the pointer route.
711 148: unsigned AS = cast<ReferenceType>(T)->getPointeeType().getAddressSpace();
712 148: Width = Target.getPointerWidth(AS);
713 148: Align = Target.getPointerAlign(AS);
714 148: break;
715 : }
716 : case Type::Pointer: {
717 12163: unsigned AS = cast<PointerType>(T)->getPointeeType().getAddressSpace();
718 12163: Width = Target.getPointerWidth(AS);
719 12163: Align = Target.getPointerAlign(AS);
720 12163: break;
721 : }
722 : case Type::MemberPointer: {
723 103: QualType Pointee = cast<MemberPointerType>(T)->getPointeeType();
724 : std::pair<uint64_t, unsigned> PtrDiffInfo =
725 103: getTypeInfo(getPointerDiffType());
726 103: Width = PtrDiffInfo.first;
77: branch 2 taken
26: branch 3 taken
727 103: if (Pointee->isFunctionType())
728 77: Width *= 2;
729 103: Align = PtrDiffInfo.second;
730 103: break;
731 : }
732 : case Type::Complex: {
733 : // Complex types have the same alignment as their elements, but twice the
734 : // size.
735 : std::pair<uint64_t, unsigned> EltInfo =
736 217: getTypeInfo(cast<ComplexType>(T)->getElementType());
737 217: Width = EltInfo.first*2;
738 217: Align = EltInfo.second;
739 217: break;
740 : }
741 : case Type::ObjCInterface: {
742 39: const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
743 39: const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
744 39: Width = Layout.getSize();
745 39: Align = Layout.getAlignment();
746 39: break;
747 : }
748 : case Type::Record:
749 : case Type::Enum: {
750 2499: const TagType *TT = cast<TagType>(T);
751 :
0: branch 2 not taken
2499: branch 3 taken
752 2499: if (TT->getDecl()->isInvalidDecl()) {
753 0: Width = 1;
754 0: Align = 1;
755 0: break;
756 : }
757 :
281: branch 1 taken
2218: branch 2 taken
758 2499: if (const EnumType *ET = dyn_cast<EnumType>(TT))
759 281: return getTypeInfo(ET->getDecl()->getIntegerType());
760 :
761 2218: const RecordType *RT = cast<RecordType>(TT);
762 2218: const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl());
763 2218: Width = Layout.getSize();
764 2218: Align = Layout.getAlignment();
765 2218: break;
766 : }
767 :
768 : case Type::SubstTemplateTypeParm:
769 : return getTypeInfo(cast<SubstTemplateTypeParmType>(T)->
770 144: getReplacementType().getTypePtr());
771 :
772 : case Type::Elaborated:
773 : return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType()
774 72: .getTypePtr());
775 :
776 : case Type::Typedef: {
777 6665: const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
10: branch 1 taken
6655: branch 2 taken
778 6665: if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
779 : Align = std::max(Aligned->getMaxAlignment(),
780 10: getTypeAlign(Typedef->getUnderlyingType().getTypePtr()));
781 10: Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
782 : } else
783 6655: return getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
784 10: break;
785 : }
786 :
787 : case Type::TypeOfExpr:
788 : return getTypeInfo(cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType()
789 39: .getTypePtr());
790 :
791 : case Type::TypeOf:
792 6: return getTypeInfo(cast<TypeOfType>(T)->getUnderlyingType().getTypePtr());
793 :
794 : case Type::Decltype:
795 : return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType()
796 0: .getTypePtr());
797 :
798 : case Type::QualifiedName:
799 36: return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr());
800 :
801 : case Type::TemplateSpecialization:
802 : assert(getCanonicalType(T) != T &&
142: branch 1 taken
0: branch 2 not taken
803 142: "Cannot request the size of a dependent type");
804 : // FIXME: this is likely to be wrong once we support template
805 : // aliases, since a template alias could refer to a typedef that
806 : // has an __aligned__ attribute on it.
807 142: return getTypeInfo(getCanonicalType(T));
808 : }
809 :
109772: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
109772: branch 3 taken
810 109772: assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
811 109772: return std::make_pair(Width, Align);
812 : }
813 :
814 : /// getTypeSizeInChars - Return the size of the specified type, in characters.
815 : /// This method does not work on incomplete types.
816 3071: CharUnits ASTContext::getTypeSizeInChars(QualType T) {
817 3071: return CharUnits::fromQuantity(getTypeSize(T) / getCharWidth());
818 : }
819 7: CharUnits ASTContext::getTypeSizeInChars(const Type *T) {
820 7: return CharUnits::fromQuantity(getTypeSize(T) / getCharWidth());
821 : }
822 :
823 : /// getTypeAlignInChars - Return the ABI-specified alignment of a type, in
824 : /// characters. This method does not work on incomplete types.
825 3310: CharUnits ASTContext::getTypeAlignInChars(QualType T) {
826 3310: return CharUnits::fromQuantity(getTypeAlign(T) / getCharWidth());
827 : }
828 0: CharUnits ASTContext::getTypeAlignInChars(const Type *T) {
829 0: return CharUnits::fromQuantity(getTypeAlign(T) / getCharWidth());
830 : }
831 :
832 : /// getPreferredTypeAlign - Return the "preferred" alignment of the specified
833 : /// type for the current target in bits. This can be different than the ABI
834 : /// alignment in cases where it is beneficial for performance to overalign
835 : /// a data type.
836 2113: unsigned ASTContext::getPreferredTypeAlign(const Type *T) {
837 2113: unsigned ABIAlign = getTypeAlign(T);
838 :
839 : // Double and long long should be naturally aligned if possible.
57: branch 1 taken
2056: branch 2 taken
840 2113: if (const ComplexType* CT = T->getAs<ComplexType>())
841 57: T = CT->getElementType().getTypePtr();
2072: branch 1 taken
41: branch 2 taken
8: branch 4 taken
2064: branch 5 taken
49: branch 6 taken
2064: branch 7 taken
842 2113: if (T->isSpecificBuiltinType(BuiltinType::Double) ||
843 : T->isSpecificBuiltinType(BuiltinType::LongLong))
844 49: return std::max(ABIAlign, (unsigned)getTypeSize(T));
845 :
846 2064: return ABIAlign;
847 : }
848 :
849 : static void CollectLocalObjCIvars(ASTContext *Ctx,
850 : const ObjCInterfaceDecl *OI,
851 76: llvm::SmallVectorImpl<FieldDecl*> &Fields) {
189: branch 1 taken
76: branch 2 taken
852 341: for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
853 76: E = OI->ivar_end(); I != E; ++I) {
854 189: ObjCIvarDecl *IVDecl = *I;
189: branch 1 taken
0: branch 2 not taken
855 189: if (!IVDecl->isInvalidDecl())
856 189: Fields.push_back(cast<FieldDecl>(IVDecl));
857 : }
858 76: }
859 :
860 : void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI,
861 76: llvm::SmallVectorImpl<FieldDecl*> &Fields) {
17: branch 1 taken
59: branch 2 taken
862 76: if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
863 17: CollectObjCIvars(SuperClass, Fields);
864 76: CollectLocalObjCIvars(this, OI, Fields);
865 76: }
866 :
867 : /// ShallowCollectObjCIvars -
868 : /// Collect all ivars, including those synthesized, in the current class.
869 : ///
870 : void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
871 : llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars,
872 1200: bool CollectSynthesized) {
4838: branch 1 taken
1200: branch 2 taken
873 7238: for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
874 1200: E = OI->ivar_end(); I != E; ++I) {
875 4838: Ivars.push_back(*I);
876 : }
1010: branch 0 taken
190: branch 1 taken
877 1200: if (CollectSynthesized)
878 1010: CollectSynthesizedIvars(OI, Ivars);
879 1200: }
880 :
881 : void ASTContext::CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD,
882 134: llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
104: branch 3 taken
134: branch 4 taken
883 372: for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(),
884 134: E = PD->prop_end(); I != E; ++I)
56: branch 2 taken
48: branch 3 taken
885 104: if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl())
886 56: Ivars.push_back(Ivar);
887 :
888 : // Also look into nested protocols.
28: branch 1 taken
134: branch 2 taken
889 296: for (ObjCProtocolDecl::protocol_iterator P = PD->protocol_begin(),
890 134: E = PD->protocol_end(); P != E; ++P)
891 28: CollectProtocolSynthesizedIvars(*P, Ivars);
892 134: }
893 :
894 : /// CollectSynthesizedIvars -
895 : /// This routine collect synthesized ivars for the designated class.
896 : ///
897 : void ASTContext::CollectSynthesizedIvars(const ObjCInterfaceDecl *OI,
898 1048: llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
965: branch 3 taken
1048: branch 4 taken
899 3061: for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(),
900 1048: E = OI->prop_end(); I != E; ++I) {
441: branch 2 taken
524: branch 3 taken
901 965: if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl())
902 441: Ivars.push_back(Ivar);
903 : }
904 : // Also look into interface's protocol list for properties declared
905 : // in the protocol and whose ivars are synthesized.
106: branch 1 taken
1048: branch 2 taken
906 2202: for (ObjCInterfaceDecl::protocol_iterator P = OI->protocol_begin(),
907 1048: PE = OI->protocol_end(); P != PE; ++P) {
908 106: ObjCProtocolDecl *PD = (*P);
909 106: CollectProtocolSynthesizedIvars(PD, Ivars);
910 : }
911 1048: }
912 :
913 : /// CollectInheritedProtocols - Collect all protocols in current class and
914 : /// those inherited by it.
915 : void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
916 42: llvm::SmallVectorImpl<ObjCProtocolDecl*> &Protocols) {
40: branch 1 taken
2: branch 2 taken
917 42: if (const ObjCInterfaceDecl *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
14: branch 1 taken
40: branch 2 taken
918 94: for (ObjCInterfaceDecl::protocol_iterator P = OI->protocol_begin(),
919 40: PE = OI->protocol_end(); P != PE; ++P) {
920 14: ObjCProtocolDecl *Proto = (*P);
921 14: Protocols.push_back(Proto);
0: branch 1 not taken
14: branch 2 taken
922 28: for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
923 14: PE = Proto->protocol_end(); P != PE; ++P)
924 0: CollectInheritedProtocols(*P, Protocols);
925 : }
926 :
927 : // Categories of this Interface.
2: branch 2 taken
40: branch 3 taken
928 42: for (const ObjCCategoryDecl *CDeclChain = OI->getCategoryList();
929 : CDeclChain; CDeclChain = CDeclChain->getNextClassCategory())
930 2: CollectInheritedProtocols(CDeclChain, Protocols);
20: branch 1 taken
20: branch 2 taken
931 40: if (ObjCInterfaceDecl *SD = OI->getSuperClass())
26: branch 0 taken
20: branch 1 taken
932 66: while (SD) {
933 26: CollectInheritedProtocols(SD, Protocols);
934 26: SD = SD->getSuperClass();
935 : }
936 40: return;
937 : }
2: branch 1 taken
0: branch 2 not taken
938 2: if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
2: branch 1 taken
2: branch 2 taken
939 6: for (ObjCInterfaceDecl::protocol_iterator P = OC->protocol_begin(),
940 2: PE = OC->protocol_end(); P != PE; ++P) {
941 2: ObjCProtocolDecl *Proto = (*P);
942 2: Protocols.push_back(Proto);
0: branch 1 not taken
2: branch 2 taken
943 4: for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
944 2: PE = Proto->protocol_end(); P != PE; ++P)
945 0: CollectInheritedProtocols(*P, Protocols);
946 : }
947 2: return;
948 : }
0: branch 1 not taken
0: branch 2 not taken
949 0: if (const ObjCProtocolDecl *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
0: branch 1 not taken
0: branch 2 not taken
950 0: for (ObjCProtocolDecl::protocol_iterator P = OP->protocol_begin(),
951 0: PE = OP->protocol_end(); P != PE; ++P) {
952 0: ObjCProtocolDecl *Proto = (*P);
953 0: Protocols.push_back(Proto);
0: branch 1 not taken
0: branch 2 not taken
954 0: for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
955 0: PE = Proto->protocol_end(); P != PE; ++P)
956 0: CollectInheritedProtocols(*P, Protocols);
957 : }
958 0: return;
959 : }
960 : }
961 :
962 22: unsigned ASTContext::CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD) {
963 22: unsigned count = 0;
10: branch 3 taken
22: branch 4 taken
964 54: for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(),
965 22: E = PD->prop_end(); I != E; ++I)
4: branch 2 taken
6: branch 3 taken
966 10: if ((*I)->getPropertyIvarDecl())
967 4: ++count;
968 :
969 : // Also look into nested protocols.
2: branch 1 taken
22: branch 2 taken
970 46: for (ObjCProtocolDecl::protocol_iterator P = PD->protocol_begin(),
971 22: E = PD->protocol_end(); P != E; ++P)
972 2: count += CountProtocolSynthesizedIvars(*P);
973 22: return count;
974 : }
975 :
976 252: unsigned ASTContext::CountSynthesizedIvars(const ObjCInterfaceDecl *OI) {
977 252: unsigned count = 0;
87: branch 3 taken
252: branch 4 taken
978 591: for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(),
979 252: E = OI->prop_end(); I != E; ++I) {
18: branch 2 taken
69: branch 3 taken
980 87: if ((*I)->getPropertyIvarDecl())
981 18: ++count;
982 : }
983 : // Also look into interface's protocol list for properties declared
984 : // in the protocol and whose ivars are synthesized.
20: branch 1 taken
252: branch 2 taken
985 524: for (ObjCInterfaceDecl::protocol_iterator P = OI->protocol_begin(),
986 252: PE = OI->protocol_end(); P != PE; ++P) {
987 20: ObjCProtocolDecl *PD = (*P);
988 20: count += CountProtocolSynthesizedIvars(PD);
989 : }
990 252: return count;
991 : }
992 :
993 : /// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists.
994 1075: ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) {
995 : llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
996 1075: I = ObjCImpls.find(D);
203: branch 3 taken
872: branch 4 taken
997 1075: if (I != ObjCImpls.end())
998 203: return cast<ObjCImplementationDecl>(I->second);
999 872: return 0;
1000 : }
1001 : /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists.
1002 151: ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
1003 : llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
1004 151: I = ObjCImpls.find(D);
26: branch 3 taken
125: branch 4 taken
1005 151: if (I != ObjCImpls.end())
1006 26: return cast<ObjCCategoryImplDecl>(I->second);
1007 125: return 0;
1008 : }
1009 :
1010 : /// \brief Set the implementation of ObjCInterfaceDecl.
1011 : void ASTContext::setObjCImplementation(ObjCInterfaceDecl *IFaceD,
1012 573: ObjCImplementationDecl *ImplD) {
573: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
573: branch 3 taken
1013 573: assert(IFaceD && ImplD && "Passed null params");
1014 573: ObjCImpls[IFaceD] = ImplD;
1015 573: }
1016 : /// \brief Set the implementation of ObjCCategoryDecl.
1017 : void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,
1018 64: ObjCCategoryImplDecl *ImplD) {
64: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
64: branch 3 taken
1019 64: assert(CatD && ImplD && "Passed null params");
1020 64: ObjCImpls[CatD] = ImplD;
1021 64: }
1022 :
1023 : /// \brief Allocate an uninitialized TypeSourceInfo.
1024 : ///
1025 : /// The caller should initialize the memory held by TypeSourceInfo using
1026 : /// the TypeLoc wrappers.
1027 : ///
1028 : /// \param T the type that will be the basis for type source info. This type
1029 : /// should refer to how the declarator was written in source code, not to
1030 : /// what type semantic analysis resolved the declarator to.
1031 : TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T,
1032 76294: unsigned DataSize) {
71824: branch 0 taken
4470: branch 1 taken
1033 76294: if (!DataSize)
1034 71824: DataSize = TypeLoc::getFullDataSizeForType(T);
1035 : else
1036 : assert(DataSize == TypeLoc::getFullDataSizeForType(T) &&
4470: branch 1 taken
0: branch 2 not taken
1037 4470: "incorrect data size provided to CreateTypeSourceInfo!");
1038 :
1039 : TypeSourceInfo *TInfo =
1040 76294: (TypeSourceInfo*)BumpAlloc.Allocate(sizeof(TypeSourceInfo) + DataSize, 8);
76294: branch 1 taken
0: branch 2 not taken
1041 76294: new (TInfo) TypeSourceInfo(T);
1042 76294: return TInfo;
1043 : }
1044 :
1045 : TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T,
1046 4102: SourceLocation L) {
1047 4102: TypeSourceInfo *DI = CreateTypeSourceInfo(T);
1048 4102: DI->getTypeLoc().initialize(L);
1049 4102: return DI;
1050 : }
1051 :
1052 : /// getInterfaceLayoutImpl - Get or compute information about the
1053 : /// layout of the given interface.
1054 : ///
1055 : /// \param Impl - If given, also include the layout of the interface's
1056 : /// implementation. This may differ by including synthesized ivars.
1057 : const ASTRecordLayout &
1058 : ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
1059 1167: const ObjCImplementationDecl *Impl) {
1167: branch 1 taken
0: branch 2 not taken
1060 1167: assert(!D->isForwardDecl() && "Invalid interface decl!");
1061 :
1062 : // Look up this layout, if already laid out, return what we have.
1063 : ObjCContainerDecl *Key =
312: branch 0 taken
855: branch 1 taken
1064 1479: Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D;
725: branch 1 taken
442: branch 2 taken
1065 1167: if (const ASTRecordLayout *Entry = ObjCLayouts[Key])
1066 725: return *Entry;
1067 :
1068 : // Add in synthesized ivar count if laying out an implementation.
252: branch 0 taken
190: branch 1 taken
1069 442: if (Impl) {
1070 252: unsigned SynthCount = CountSynthesizedIvars(D);
1071 : // If there aren't any sythesized ivars then reuse the interface
1072 : // entry. Note we can't cache this because we simply free all
1073 : // entries later; however we shouldn't look up implementations
1074 : // frequently.
240: branch 0 taken
12: branch 1 taken
1075 252: if (SynthCount == 0)
1076 240: return getObjCLayout(D, 0);
1077 : }
1078 :
1079 : const ASTRecordLayout *NewEntry =
1080 202: ASTRecordLayoutBuilder::ComputeLayout(*this, D, Impl);
1081 202: ObjCLayouts[Key] = NewEntry;
1082 :
1083 202: return *NewEntry;
1084 : }
1085 :
1086 : const ASTRecordLayout &
1087 615: ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) {
1088 615: return getObjCLayout(D, 0);
1089 : }
1090 :
1091 : const ASTRecordLayout &
1092 312: ASTContext::getASTObjCImplementationLayout(const ObjCImplementationDecl *D) {
1093 312: return getObjCLayout(D->getClassInterface(), D);
1094 : }
1095 :
1096 : /// getASTRecordLayout - Get or compute information about the layout of the
1097 : /// specified record (struct/union/class), which indicates its size and field
1098 : /// position information.
1099 21846: const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
1100 21846: D = D->getDefinition(*this);
0: branch 0 not taken
21846: branch 1 taken
1101 21846: assert(D && "Cannot get layout of forward declarations!");
1102 :
1103 : // Look up this layout, if already laid out, return what we have.
1104 : // Note that we can't save a reference to the entry because this function
1105 : // is recursive.
1106 21846: const ASTRecordLayout *Entry = ASTRecordLayouts[D];
20248: branch 0 taken
1598: branch 1 taken
1107 21846: if (Entry) return *Entry;
1108 :
1109 : const ASTRecordLayout *NewEntry =
1110 1598: ASTRecordLayoutBuilder::ComputeLayout(*this, D);
1111 1598: ASTRecordLayouts[D] = NewEntry;
1112 :
1113 1598: return *NewEntry;
1114 : }
1115 :
1116 2359: const CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) {
1117 2359: RD = cast<CXXRecordDecl>(RD->getDefinition(*this));
0: branch 0 not taken
2359: branch 1 taken
1118 2359: assert(RD && "Cannot get key function for forward declarations!");
1119 :
1120 2359: const CXXMethodDecl *&Entry = KeyFunctions[RD];
1784: branch 0 taken
575: branch 1 taken
1121 2359: if (!Entry)
1122 1784: Entry = ASTRecordLayoutBuilder::ComputeKeyFunction(RD);
1123 : else
1124 : assert(Entry == ASTRecordLayoutBuilder::ComputeKeyFunction(RD) &&
575: branch 1 taken
0: branch 2 not taken
1125 575: "Key function changed!");
1126 :
1127 2359: return Entry;
1128 : }
1129 :
1130 : //===----------------------------------------------------------------------===//
1131 : // Type creation/memoization methods
1132 : //===----------------------------------------------------------------------===//
1133 :
1134 14120: QualType ASTContext::getExtQualType(const Type *TypeNode, Qualifiers Quals) {
1135 14120: unsigned Fast = Quals.getFastQualifiers();
1136 14120: Quals.removeFastQualifiers();
1137 :
1138 : // Check if we've already instantiated this type.
1139 14120: llvm::FoldingSetNodeID ID;
1140 14120: ExtQuals::Profile(ID, TypeNode, Quals);
1141 14120: void *InsertPos = 0;
13576: branch 1 taken
544: branch 2 taken
1142 14120: if (ExtQuals *EQ = ExtQualNodes.FindNodeOrInsertPos(ID, InsertPos)) {
0: branch 2 not taken
13576: branch 3 taken
1143 13576: assert(EQ->getQualifiers() == Quals);
1144 13576: QualType T = QualType(EQ, Fast);
1145 13576: return T;
1146 : }
1147 :
544: branch 1 taken
0: branch 2 not taken
1148 544: ExtQuals *New = new (*this, TypeAlignment) ExtQuals(*this, TypeNode, Quals);
1149 544: ExtQualNodes.InsertNode(New, InsertPos);
1150 544: QualType T = QualType(New, Fast);
1151 544: return T;
1152 : }
1153 :
1154 4261: QualType ASTContext::getVolatileType(QualType T) {
1155 4261: QualType CanT = getCanonicalType(T);
0: branch 1 not taken
4261: branch 2 taken
1156 4261: if (CanT.isVolatileQualified()) return T;
1157 :
1158 4261: QualifierCollector Quals;
1159 4261: const Type *TypeNode = Quals.strip(T);
1160 4261: Quals.addVolatile();
1161 :
1162 4261: return getExtQualType(TypeNode, Quals);
1163 : }
1164 :
1165 50: QualType ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) {
1166 50: QualType CanT = getCanonicalType(T);
0: branch 1 not taken
50: branch 2 taken
1167 50: if (CanT.getAddressSpace() == AddressSpace)
1168 0: return T;
1169 :
1170 : // If we are composing extended qualifiers together, merge together
1171 : // into one ExtQuals node.
1172 50: QualifierCollector Quals;
1173 50: const Type *TypeNode = Quals.strip(T);
1174 :
1175 : // If this type already has an address space specified, it cannot get
1176 : // another one.
1177 : assert(!Quals.hasAddressSpace() &&
50: branch 1 taken
0: branch 2 not taken
1178 50: "Type cannot be in multiple addr spaces!");
1179 50: Quals.addAddressSpace(AddressSpace);
1180 :
1181 50: return getExtQualType(TypeNode, Quals);
1182 : }
1183 :
1184 : QualType ASTContext::getObjCGCQualType(QualType T,
1185 95: Qualifiers::GC GCAttr) {
1186 95: QualType CanT = getCanonicalType(T);
0: branch 1 not taken
95: branch 2 taken
1187 95: if (CanT.getObjCGCAttr() == GCAttr)
1188 0: return T;
1189 :
29: branch 2 taken
66: branch 3 taken
1190 95: if (T->isPointerType()) {
1191 29: QualType Pointee = T->getAs<PointerType>()->getPointeeType();
5: branch 2 taken
24: branch 3 taken
1192 29: if (Pointee->isAnyPointerType()) {
1193 5: QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
1194 5: return getPointerType(ResultType);
1195 : }
1196 : }
1197 :
1198 : // If we are composing extended qualifiers together, merge together
1199 : // into one ExtQuals node.
1200 90: QualifierCollector Quals;
1201 90: const Type *TypeNode = Quals.strip(T);
1202 :
1203 : // If this type already has an ObjCGC specified, it cannot get
1204 : // another one.
1205 : assert(!Quals.hasObjCGCAttr() &&
90: branch 1 taken
0: branch 2 not taken
1206 90: "Type cannot have multiple ObjCGCs!");
1207 90: Quals.addObjCGCAttr(GCAttr);
1208 :
1209 90: return getExtQualType(TypeNode, Quals);
1210 : }
1211 :
1212 : static QualType getNoReturnCallConvType(ASTContext& Context, QualType T,
1213 : bool AddNoReturn,
1214 8145: CallingConv CallConv) {
1215 8145: QualType ResultType;
2929: branch 2 taken
5216: branch 3 taken
1216 8145: if (const PointerType *Pointer = T->getAs<PointerType>()) {
1217 2929: QualType Pointee = Pointer->getPointeeType();
1218 : ResultType = getNoReturnCallConvType(Context, Pointee, AddNoReturn,
1219 2929: CallConv);
2902: branch 1 taken
27: branch 2 taken
1220 2929: if (ResultType == Pointee)
1221 2902: return T;
1222 :
1223 27: ResultType = Context.getPointerType(ResultType);
4: branch 0 taken
5212: branch 1 taken
1224 5216: } else if (const BlockPointerType *BlockPointer
1225 5216: = T->getAs<BlockPointerType>()) {
1226 4: QualType Pointee = BlockPointer->getPointeeType();
1227 : ResultType = getNoReturnCallConvType(Context, Pointee, AddNoReturn,
1228 4: CallConv);
2: branch 1 taken
2: branch 2 taken
1229 4: if (ResultType == Pointee)
1230 2: return T;
1231 :
1232 2: ResultType = Context.getBlockPointerType(ResultType);
3299: branch 2 taken
1913: branch 3 taken
1233 5212: } else if (const FunctionType *F = T->getAs<FunctionType>()) {
3119: branch 1 taken
180: branch 2 taken
3095: branch 4 taken
24: branch 5 taken
3095: branch 6 taken
204: branch 7 taken
1234 3299: if (F->getNoReturnAttr() == AddNoReturn && F->getCallConv() == CallConv)
1235 3095: return T;
1236 :
45: branch 1 taken
159: branch 2 taken
1237 204: if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(F)) {
1238 : ResultType = Context.getFunctionNoProtoType(FNPT->getResultType(),
1239 45: AddNoReturn, CallConv);
1240 : } else {
1241 159: const FunctionProtoType *FPT = cast<FunctionProtoType>(F);
1242 : ResultType
1243 : = Context.getFunctionType(FPT->getResultType(), FPT->arg_type_begin(),
1244 : FPT->getNumArgs(), FPT->isVariadic(),
1245 : FPT->getTypeQuals(),
1246 : FPT->hasExceptionSpec(),
1247 : FPT->hasAnyExceptionSpec(),
1248 : FPT->getNumExceptions(),
1249 : FPT->exception_begin(),
1250 159: AddNoReturn, CallConv);
1251 : }
1252 : } else
1253 1913: return T;
1254 :
1255 233: return Context.getQualifiedType(ResultType, T.getLocalQualifiers());
1256 : }
1257 :
1258 5188: QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) {
1259 5188: return getNoReturnCallConvType(*this, T, AddNoReturn, T.getCallConv());
1260 : }
1261 :
1262 24: QualType ASTContext::getCallConvType(QualType T, CallingConv CallConv) {
1263 24: return getNoReturnCallConvType(*this, T, T.getNoReturnAttr(), CallConv);
1264 : }
1265 :
1266 : /// getComplexType - Return the uniqued reference to the type for a complex
1267 : /// number with the specified element type.
1268 7031: QualType ASTContext::getComplexType(QualType T) {
1269 : // Unique pointers, to guarantee there is only one pointer of a particular
1270 : // structure.
1271 7031: llvm::FoldingSetNodeID ID;
1272 7031: ComplexType::Profile(ID, T);
1273 :
1274 7031: void *InsertPos = 0;
246: branch 1 taken
6785: branch 2 taken
1275 7031: if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
1276 246: return QualType(CT, 0);
1277 :
1278 : // If the pointee type isn't canonical, this won't be a canonical type either,
1279 : // so fill in the canonical type field.
1280 6785: QualType Canonical;
0: branch 1 not taken
6785: branch 2 taken
1281 6785: if (!T.isCanonical()) {
1282 0: Canonical = getComplexType(getCanonicalType(T));
1283 :
1284 : // Get the new insert position for the node we care about.
1285 0: ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
0: branch 1 not taken
1286 0: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1287 : }
6785: branch 1 taken
0: branch 2 not taken
1288 6785: ComplexType *New = new (*this, TypeAlignment) ComplexType(T, Canonical);
1289 6785: Types.push_back(New);
6785: branch 0 taken
0: branch 1 not taken
1290 6785: ComplexTypes.InsertNode(New, InsertPos);
1291 6785: return QualType(New, 0);
1292 : }
1293 :
1294 : /// getPointerType - Return the uniqued reference to the type for a pointer to
1295 : /// the specified type.
1296 52644: QualType ASTContext::getPointerType(QualType T) {
1297 : // Unique pointers, to guarantee there is only one pointer of a particular
1298 : // structure.
1299 52644: llvm::FoldingSetNodeID ID;
1300 52644: PointerType::Profile(ID, T);
1301 :
1302 52644: void *InsertPos = 0;
37052: branch 1 taken
15592: branch 2 taken
1303 52644: if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
1304 37052: return QualType(PT, 0);
1305 :
1306 : // If the pointee type isn't canonical, this won't be a canonical type either,
1307 : // so fill in the canonical type field.
1308 15592: QualType Canonical;
2378: branch 1 taken
13214: branch 2 taken
1309 15592: if (!T.isCanonical()) {
1310 2378: Canonical = getPointerType(getCanonicalType(T));
1311 :
1312 : // Get the new insert position for the node we care about.
1313 2378: PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
2378: branch 1 taken
1314 2378: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1315 : }
15592: branch 1 taken
0: branch 2 not taken
1316 15592: PointerType *New = new (*this, TypeAlignment) PointerType(T, Canonical);
1317 15592: Types.push_back(New);
15592: branch 0 taken
0: branch 1 not taken
1318 15592: PointerTypes.InsertNode(New, InsertPos);
1319 15592: return QualType(New, 0);
1320 : }
1321 :
1322 : /// getBlockPointerType - Return the uniqued reference to the type for
1323 : /// a pointer to the specified block.
1324 522: QualType ASTContext::getBlockPointerType(QualType T) {
522: branch 2 taken
0: branch 3 not taken
1325 522: assert(T->isFunctionType() && "block of function types only");
1326 : // Unique pointers, to guarantee there is only one block of a particular
1327 : // structure.
1328 522: llvm::FoldingSetNodeID ID;
1329 522: BlockPointerType::Profile(ID, T);
1330 :
1331 522: void *InsertPos = 0;
299: branch 0 taken
223: branch 1 taken
1332 522: if (BlockPointerType *PT =
1333 522: BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
1334 299: return QualType(PT, 0);
1335 :
1336 : // If the block pointee type isn't canonical, this won't be a canonical
1337 : // type either so fill in the canonical type field.
1338 223: QualType Canonical;
24: branch 1 taken
199: branch 2 taken
1339 223: if (!T.isCanonical()) {
1340 24: Canonical = getBlockPointerType(getCanonicalType(T));
1341 :
1342 : // Get the new insert position for the node we care about.
1343 : BlockPointerType *NewIP =
1344 24: BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
24: branch 1 taken
1345 24: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1346 : }
1347 : BlockPointerType *New
223: branch 1 taken
0: branch 2 not taken
1348 223: = new (*this, TypeAlignment) BlockPointerType(T, Canonical);
1349 223: Types.push_back(New);
223: branch 0 taken
0: branch 1 not taken
1350 223: BlockPointerTypes.InsertNode(New, InsertPos);
1351 223: return QualType(New, 0);
1352 : }
1353 :
1354 : /// getLValueReferenceType - Return the uniqued reference to the type for an
1355 : /// lvalue reference to the specified type.
1356 31120: QualType ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) {
1357 : // Unique pointers, to guarantee there is only one pointer of a particular
1358 : // structure.
1359 31120: llvm::FoldingSetNodeID ID;
1360 31120: ReferenceType::Profile(ID, T, SpelledAsLValue);
1361 :
1362 31120: void *InsertPos = 0;
21556: branch 0 taken
9564: branch 1 taken
1363 31120: if (LValueReferenceType *RT =
1364 31120: LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
1365 21556: return QualType(RT, 0);
1366 :
1367 9564: const ReferenceType *InnerRef = T->getAs<ReferenceType>();
1368 :
1369 : // If the referencee type isn't canonical, this won't be a canonical type
1370 : // either, so fill in the canonical type field.
1371 9564: QualType Canonical;
9561: branch 0 taken
3: branch 1 taken
9548: branch 2 taken
13: branch 3 taken
466: branch 5 taken
9082: branch 6 taken
482: branch 7 taken
9082: branch 8 taken
1372 9564: if (!SpelledAsLValue || InnerRef || !T.isCanonical()) {
16: branch 0 taken
466: branch 1 taken
1373 482: QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T);
1374 482: Canonical = getLValueReferenceType(getCanonicalType(PointeeType));
1375 :
1376 : // Get the new insert position for the node we care about.
1377 : LValueReferenceType *NewIP =
1378 482: LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
482: branch 1 taken
1379 482: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1380 : }
1381 :
1382 : LValueReferenceType *New
1383 : = new (*this, TypeAlignment) LValueReferenceType(T, Canonical,
9564: branch 1 taken
0: branch 2 not taken
1384 9564: SpelledAsLValue);
1385 9564: Types.push_back(New);
9564: branch 0 taken
0: branch 1 not taken
1386 9564: LValueReferenceTypes.InsertNode(New, InsertPos);
1387 :
1388 9564: return QualType(New, 0);
1389 : }
1390 :
1391 : /// getRValueReferenceType - Return the uniqued reference to the type for an
1392 : /// rvalue reference to the specified type.
1393 41: QualType ASTContext::getRValueReferenceType(QualType T) {
1394 : // Unique pointers, to guarantee there is only one pointer of a particular
1395 : // structure.
1396 41: llvm::FoldingSetNodeID ID;
1397 41: ReferenceType::Profile(ID, T, false);
1398 :
1399 41: void *InsertPos = 0;
24: branch 0 taken
17: branch 1 taken
1400 41: if (RValueReferenceType *RT =
1401 41: RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
1402 24: return QualType(RT, 0);
1403 :
1404 17: const ReferenceType *InnerRef = T->getAs<ReferenceType>();
1405 :
1406 : // If the referencee type isn't canonical, this won't be a canonical type
1407 : // either, so fill in the canonical type field.
1408 17: QualType Canonical;
16: branch 0 taken
1: branch 1 taken
2: branch 3 taken
14: branch 4 taken
3: branch 5 taken
14: branch 6 taken
1409 17: if (InnerRef || !T.isCanonical()) {
1: branch 0 taken
2: branch 1 taken
1410 3: QualType PointeeType = (InnerRef ? InnerRef->getPointeeType() : T);
1411 3: Canonical = getRValueReferenceType(getCanonicalType(PointeeType));
1412 :
1413 : // Get the new insert position for the node we care about.
1414 : RValueReferenceType *NewIP =
1415 3: RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
3: branch 1 taken
1416 3: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1417 : }
1418 :
1419 : RValueReferenceType *New
17: branch 1 taken
0: branch 2 not taken
1420 17: = new (*this, TypeAlignment) RValueReferenceType(T, Canonical);
1421 17: Types.push_back(New);
17: branch 0 taken
0: branch 1 not taken
1422 17: RValueReferenceTypes.InsertNode(New, InsertPos);
1423 17: return QualType(New, 0);
1424 : }
1425 :
1426 : /// getMemberPointerType - Return the uniqued reference to the type for a
1427 : /// member pointer to the specified type, in the specified class.
1428 679: QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) {
1429 : // Unique pointers, to guarantee there is only one pointer of a particular
1430 : // structure.
1431 679: llvm::FoldingSetNodeID ID;
1432 679: MemberPointerType::Profile(ID, T, Cls);
1433 :
1434 679: void *InsertPos = 0;
355: branch 0 taken
324: branch 1 taken
1435 679: if (MemberPointerType *PT =
1436 679: MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
1437 355: return QualType(PT, 0);
1438 :
1439 : // If the pointee or class type isn't canonical, this won't be a canonical
1440 : // type either, so fill in the canonical type field.
1441 324: QualType Canonical;
290: branch 1 taken
34: branch 2 taken
12: branch 4 taken
278: branch 5 taken
46: branch 6 taken
278: branch 7 taken
1442 324: if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) {
1443 46: Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
1444 :
1445 : // Get the new insert position for the node we care about.
1446 : MemberPointerType *NewIP =
1447 46: MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
46: branch 1 taken
1448 46: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1449 : }
1450 : MemberPointerType *New
324: branch 1 taken
0: branch 2 not taken
1451 324: = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical);
1452 324: Types.push_back(New);
324: branch 0 taken
0: branch 1 not taken
1453 324: MemberPointerTypes.InsertNode(New, InsertPos);
1454 324: return QualType(New, 0);
1455 : }
1456 :
1457 : /// getConstantArrayType - Return the unique reference to the type for an
1458 : /// array of the specified element type.
1459 : QualType ASTContext::getConstantArrayType(QualType EltTy,
1460 : const llvm::APInt &ArySizeIn,
1461 : ArrayType::ArraySizeModifier ASM,
1462 4680: unsigned EltTypeQuals) {
1463 : assert((EltTy->isDependentType() ||
1464 : EltTy->isIncompleteType() || EltTy->isConstantSizeType()) &&
4669: branch 2 taken
11: branch 3 taken
4662: branch 6 taken
7: branch 7 taken
4662: branch 10 taken
0: branch 11 not taken
1465 4680: "Constant array of VLAs is illegal!");
1466 :
1467 : // Convert the array size into a canonical width matching the pointer size for
1468 : // the target.
1469 4680: llvm::APInt ArySize(ArySizeIn);
1470 4680: ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace()));
1471 :
1472 4680: llvm::FoldingSetNodeID ID;
1473 4680: ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, EltTypeQuals);
1474 :
1475 4680: void *InsertPos = 0;
2303: branch 0 taken
2377: branch 1 taken
1476 4680: if (ConstantArrayType *ATP =
1477 4680: ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
1478 2303: return QualType(ATP, 0);
1479 :
1480 : // If the element type isn't canonical, this won't be a canonical type either,
1481 : // so fill in the canonical type field.
1482 2377: QualType Canonical;
290: branch 1 taken
2087: branch 2 taken
1483 2377: if (!EltTy.isCanonical()) {
1484 : Canonical = getConstantArrayType(getCanonicalType(EltTy), ArySize,
1485 290: ASM, EltTypeQuals);
1486 : // Get the new insert position for the node we care about.
1487 : ConstantArrayType *NewIP =
1488 290: ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
290: branch 1 taken
1489 290: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1490 : }
1491 :
1492 : ConstantArrayType *New = new(*this,TypeAlignment)
2377: branch 1 taken
0: branch 2 not taken
1493 2377: ConstantArrayType(EltTy, Canonical, ArySize, ASM, EltTypeQuals);
2377: branch 0 taken
0: branch 1 not taken
1494 2377: ConstantArrayTypes.InsertNode(New, InsertPos);
1495 2377: Types.push_back(New);
1496 2377: return QualType(New, 0);
1497 : }
1498 :
1499 : /// getVariableArrayType - Returns a non-unique reference to the type for a
1500 : /// variable array of the specified element type.
1501 : QualType ASTContext::getVariableArrayType(QualType EltTy,
1502 : Expr *NumElts,
1503 : ArrayType::ArraySizeModifier ASM,
1504 : unsigned EltTypeQuals,
1505 207: SourceRange Brackets) {
1506 : // Since we don't unique expressions, it isn't possible to unique VLA's
1507 : // that have an expression provided for their size.
1508 :
1509 : VariableArrayType *New = new(*this, TypeAlignment)
207: branch 2 taken
0: branch 3 not taken
1510 207: VariableArrayType(EltTy, QualType(), NumElts, ASM, EltTypeQuals, Brackets);
1511 :
1512 207: VariableArrayTypes.push_back(New);
1513 207: Types.push_back(New);
1514 207: return QualType(New, 0);
1515 : }
1516 :
1517 : /// getDependentSizedArrayType - Returns a non-unique reference to
1518 : /// the type for a dependently-sized array of the specified element
1519 : /// type.
1520 : QualType ASTContext::getDependentSizedArrayType(QualType EltTy,
1521 : Expr *NumElts,
1522 : ArrayType::ArraySizeModifier ASM,
1523 : unsigned EltTypeQuals,
1524 64: SourceRange Brackets) {
1525 : assert((!NumElts || NumElts->isTypeDependent() ||
1526 : NumElts->isValueDependent()) &&
63: branch 0 taken
1: branch 1 taken
63: branch 3 taken
0: branch 4 not taken
63: branch 6 taken
0: branch 7 not taken
1527 64: "Size must be type- or value-dependent!");
1528 :
1529 64: void *InsertPos = 0;
1530 64: DependentSizedArrayType *Canon = 0;
1531 64: llvm::FoldingSetNodeID ID;
1532 :
63: branch 0 taken
1: branch 1 taken
1533 64: if (NumElts) {
1534 : // Dependently-sized array types that do not have a specified
1535 : // number of elements will have their sizes deduced from an
1536 : // initializer.
1537 : DependentSizedArrayType::Profile(ID, *this, getCanonicalType(EltTy), ASM,
1538 63: EltTypeQuals, NumElts);
1539 :
1540 63: Canon = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
1541 : }
1542 :
1543 : DependentSizedArrayType *New;
7: branch 0 taken
57: branch 1 taken
1544 64: if (Canon) {
1545 : // We already have a canonical version of this array type; use it as
1546 : // the canonical type for a newly-built type.
1547 : New = new (*this, TypeAlignment)
1548 : DependentSizedArrayType(*this, EltTy, QualType(Canon, 0),
7: branch 2 taken
0: branch 3 not taken
1549 7: NumElts, ASM, EltTypeQuals, Brackets);
1550 : } else {
1551 57: QualType CanonEltTy = getCanonicalType(EltTy);
44: branch 1 taken
13: branch 2 taken
1552 57: if (CanonEltTy == EltTy) {
1553 : New = new (*this, TypeAlignment)
1554 : DependentSizedArrayType(*this, EltTy, QualType(),
44: branch 2 taken
0: branch 3 not taken
1555 44: NumElts, ASM, EltTypeQuals, Brackets);
1556 :
43: branch 0 taken
1: branch 1 taken
1557 44: if (NumElts) {
1558 : DependentSizedArrayType *CanonCheck
1559 43: = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
43: branch 1 taken
1560 43: assert(!CanonCheck && "Dependent-sized canonical array type broken");
1561 : (void)CanonCheck;
43: branch 0 taken
0: branch 1 not taken
1562 43: DependentSizedArrayTypes.InsertNode(New, InsertPos);
1563 : }
1564 : } else {
1565 : QualType Canon = getDependentSizedArrayType(CanonEltTy, NumElts,
1566 : ASM, EltTypeQuals,
1567 13: SourceRange());
1568 : New = new (*this, TypeAlignment)
1569 : DependentSizedArrayType(*this, EltTy, Canon,
13: branch 1 taken
0: branch 2 not taken
1570 13: NumElts, ASM, EltTypeQuals, Brackets);
1571 : }
1572 : }
1573 :
1574 64: Types.push_back(New);
1575 64: return QualType(New, 0);
1576 : }
1577 :
1578 : QualType ASTContext::getIncompleteArrayType(QualType EltTy,
1579 : ArrayType::ArraySizeModifier ASM,
1580 395: unsigned EltTypeQuals) {
1581 395: llvm::FoldingSetNodeID ID;
1582 395: IncompleteArrayType::Profile(ID, EltTy, ASM, EltTypeQuals);
1583 :
1584 395: void *InsertPos = 0;
120: branch 0 taken
275: branch 1 taken
1585 395: if (IncompleteArrayType *ATP =
1586 395: IncompleteArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
1587 120: return QualType(ATP, 0);
1588 :
1589 : // If the element type isn't canonical, this won't be a canonical type
1590 : // either, so fill in the canonical type field.
1591 275: QualType Canonical;
1592 :
27: branch 1 taken
248: branch 2 taken
1593 275: if (!EltTy.isCanonical()) {
1594 : Canonical = getIncompleteArrayType(getCanonicalType(EltTy),
1595 27: ASM, EltTypeQuals);
1596 :
1597 : // Get the new insert position for the node we care about.
1598 : IncompleteArrayType *NewIP =
1599 27: IncompleteArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
27: branch 1 taken
1600 27: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1601 : }
1602 :
1603 : IncompleteArrayType *New = new (*this, TypeAlignment)
275: branch 1 taken
0: branch 2 not taken
1604 275: IncompleteArrayType(EltTy, Canonical, ASM, EltTypeQuals);
1605 :
275: branch 0 taken
0: branch 1 not taken
1606 275: IncompleteArrayTypes.InsertNode(New, InsertPos);
1607 275: Types.push_back(New);
1608 275: return QualType(New, 0);
1609 : }
1610 :
1611 : /// getVectorType - Return the unique reference to a vector type of
1612 : /// the specified element type and size. VectorType must be a built-in type.
1613 : QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
1614 2665: bool IsAltiVec, bool IsPixel) {
1615 : BuiltinType *baseType;
1616 :
1617 2665: baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr());
0: branch 0 not taken
2665: branch 1 taken
1618 2665: assert(baseType != 0 && "getVectorType(): Expecting a built-in type");
1619 :
1620 : // Check if we've already instantiated a vector of this type.
1621 2665: llvm::FoldingSetNodeID ID;
1622 : VectorType::Profile(ID, vecType, NumElts, Type::Vector,
1623 2665: IsAltiVec, IsPixel);
1624 2665: void *InsertPos = 0;
2479: branch 1 taken
186: branch 2 taken
1625 2665: if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
1626 2479: return QualType(VTP, 0);
1627 :
1628 : // If the element type isn't canonical, this won't be a canonical type either,
1629 : // so fill in the canonical type field.
1630 186: QualType Canonical;
185: branch 1 taken
1: branch 2 taken
157: branch 3 taken
28: branch 4 taken
0: branch 5 not taken
157: branch 6 taken
29: branch 7 taken
157: branch 8 taken
1631 186: if (!vecType.isCanonical() || IsAltiVec || IsPixel) {
1632 : Canonical = getVectorType(getCanonicalType(vecType),
1633 29: NumElts, false, false);
1634 :
1635 : // Get the new insert position for the node we care about.
1636 29: VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
29: branch 1 taken
1637 29: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1638 : }
1639 : VectorType *New = new (*this, TypeAlignment)
186: branch 1 taken
0: branch 2 not taken
1640 186: VectorType(vecType, NumElts, Canonical, IsAltiVec, IsPixel);
186: branch 0 taken
0: branch 1 not taken
1641 186: VectorTypes.InsertNode(New, InsertPos);
1642 186: Types.push_back(New);
1643 186: return QualType(New, 0);
1644 : }
1645 :
1646 : /// getExtVectorType - Return the unique reference to an extended vector type of
1647 : /// the specified element type and size. VectorType must be a built-in type.
1648 160: QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) {
1649 : BuiltinType *baseType;
1650 :
1651 160: baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr());
0: branch 0 not taken
160: branch 1 taken
1652 160: assert(baseType != 0 && "getExtVectorType(): Expecting a built-in type");
1653 :
1654 : // Check if we've already instantiated a vector of this type.
1655 160: llvm::FoldingSetNodeID ID;
1656 160: VectorType::Profile(ID, vecType, NumElts, Type::ExtVector, false, false);
1657 160: void *InsertPos = 0;
93: branch 1 taken
67: branch 2 taken
1658 160: if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
1659 93: return QualType(VTP, 0);
1660 :
1661 : // If the element type isn't canonical, this won't be a canonical type either,
1662 : // so fill in the canonical type field.
1663 67: QualType Canonical;
2: branch 1 taken
65: branch 2 taken
1664 67: if (!vecType.isCanonical()) {
1665 2: Canonical = getExtVectorType(getCanonicalType(vecType), NumElts);
1666 :
1667 : // Get the new insert position for the node we care about.
1668 2: VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
2: branch 1 taken
1669 2: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1670 : }
1671 : ExtVectorType *New = new (*this, TypeAlignment)
67: branch 1 taken
0: branch 2 not taken
1672 67: ExtVectorType(vecType, NumElts, Canonical);
67: branch 0 taken
0: branch 1 not taken
1673 67: VectorTypes.InsertNode(New, InsertPos);
1674 67: Types.push_back(New);
1675 67: return QualType(New, 0);
1676 : }
1677 :
1678 : QualType ASTContext::getDependentSizedExtVectorType(QualType vecType,
1679 : Expr *SizeExpr,
1680 12: SourceLocation AttrLoc) {
1681 12: llvm::FoldingSetNodeID ID;
1682 : DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType),
1683 12: SizeExpr);
1684 :
1685 12: void *InsertPos = 0;
1686 : DependentSizedExtVectorType *Canon
1687 12: = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
1688 : DependentSizedExtVectorType *New;
3: branch 0 taken
9: branch 1 taken
1689 12: if (Canon) {
1690 : // We already have a canonical version of this array type; use it as
1691 : // the canonical type for a newly-built type.
1692 : New = new (*this, TypeAlignment)
1693 : DependentSizedExtVectorType(*this, vecType, QualType(Canon, 0),
3: branch 2 taken
0: branch 3 not taken
1694 3: SizeExpr, AttrLoc);
1695 : } else {
1696 9: QualType CanonVecTy = getCanonicalType(vecType);
5: branch 1 taken
4: branch 2 taken
1697 9: if (CanonVecTy == vecType) {
1698 : New = new (*this, TypeAlignment)
1699 : DependentSizedExtVectorType(*this, vecType, QualType(), SizeExpr,
5: branch 2 taken
0: branch 3 not taken
1700 5: AttrLoc);
1701 :
1702 : DependentSizedExtVectorType *CanonCheck
1703 5: = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
5: branch 1 taken
1704 5: assert(!CanonCheck && "Dependent-sized ext_vector canonical type broken");
1705 : (void)CanonCheck;
5: branch 0 taken
0: branch 1 not taken
1706 5: DependentSizedExtVectorTypes.InsertNode(New, InsertPos);
1707 : } else {
1708 : QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr,
1709 4: SourceLocation());
1710 : New = new (*this, TypeAlignment)
4: branch 1 taken
0: branch 2 not taken
1711 4: DependentSizedExtVectorType(*this, vecType, Canon, SizeExpr, AttrLoc);
1712 : }
1713 : }
1714 :
1715 12: Types.push_back(New);
1716 12: return QualType(New, 0);
1717 : }
1718 :
1719 : /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
1720 : ///
1721 : QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn,
1722 2526: CallingConv CallConv) {
1723 : // Unique functions, to guarantee there is only one function of a particular
1724 : // structure.
1725 2526: llvm::FoldingSetNodeID ID;
1726 2526: FunctionNoProtoType::Profile(ID, ResultTy, NoReturn, CallConv);
1727 :
1728 2526: void *InsertPos = 0;
1442: branch 0 taken
1084: branch 1 taken
1729 2526: if (FunctionNoProtoType *FT =
1730 2526: FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
1731 1442: return QualType(FT, 0);
1732 :
1733 1084: QualType Canonical;
995: branch 1 taken
89: branch 2 taken
1: branch 4 taken
994: branch 5 taken
90: branch 6 taken
994: branch 7 taken
1734 1084: if (!ResultTy.isCanonical() ||
1735 : getCanonicalCallConv(CallConv) != CallConv) {
1736 : Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn,
1737 90: getCanonicalCallConv(CallConv));
1738 :
1739 : // Get the new insert position for the node we care about.
1740 : FunctionNoProtoType *NewIP =
1741 90: FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
90: branch 1 taken
1742 90: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1743 : }
1744 :
1745 : FunctionNoProtoType *New = new (*this, TypeAlignment)
1084: branch 1 taken
0: branch 2 not taken
1746 1084: FunctionNoProtoType(ResultTy, Canonical, NoReturn, CallConv);
1747 1084: Types.push_back(New);
1084: branch 0 taken
0: branch 1 not taken
1748 1084: FunctionNoProtoTypes.InsertNode(New, InsertPos);
1749 1084: return QualType(New, 0);
1750 : }
1751 :
1752 : /// getFunctionType - Return a normal function type with a typed argument
1753 : /// list. isVariadic indicates whether the argument list includes '...'.
1754 : QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
1755 : unsigned NumArgs, bool isVariadic,
1756 : unsigned TypeQuals, bool hasExceptionSpec,
1757 : bool hasAnyExceptionSpec, unsigned NumExs,
1758 : const QualType *ExArray, bool NoReturn,
1759 38747: CallingConv CallConv) {
1760 : // Unique functions, to guarantee there is only one function of a particular
1761 : // structure.
1762 38747: llvm::FoldingSetNodeID ID;
1763 : FunctionProtoType::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic,
1764 : TypeQuals, hasExceptionSpec, hasAnyExceptionSpec,
1765 38747: NumExs, ExArray, NoReturn, CallConv);
1766 :
1767 38747: void *InsertPos = 0;
18251: branch 0 taken
20496: branch 1 taken
1768 38747: if (FunctionProtoType *FTP =
1769 38747: FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
1770 18251: return QualType(FTP, 0);
1771 :
1772 : // Determine whether the type being created is already canonical or not.
20165: branch 0 taken
331: branch 1 taken
18656: branch 3 taken
1509: branch 4 taken
1773 20496: bool isCanonical = !hasExceptionSpec && ResultTy.isCanonical();
22285: branch 0 taken
18405: branch 1 taken
20194: branch 2 taken
2091: branch 3 taken
1774 40690: for (unsigned i = 0; i != NumArgs && isCanonical; ++i)
1918: branch 1 taken
18276: branch 2 taken
1775 20194: if (!ArgArray[i].isCanonicalAsParam())
1776 1918: isCanonical = false;
1777 :
1778 : // If this type isn't canonical, get the canonical version of it.
1779 : // The exception spec is not part of the canonical type.
1780 20496: QualType Canonical;
16738: branch 0 taken
3758: branch 1 taken
1: branch 3 taken
16737: branch 4 taken
3759: branch 5 taken
16737: branch 6 taken
1781 20496: if (!isCanonical || getCanonicalCallConv(CallConv) != CallConv) {
1782 3759: llvm::SmallVector<QualType, 16> CanonicalArgs;
1783 3759: CanonicalArgs.reserve(NumArgs);
5859: branch 0 taken
3759: branch 1 taken
1784 9618: for (unsigned i = 0; i != NumArgs; ++i)
1785 5859: CanonicalArgs.push_back(getCanonicalParamType(ArgArray[i]));
1786 :
1787 : Canonical = getFunctionType(getCanonicalType(ResultTy),
1788 : CanonicalArgs.data(), NumArgs,
1789 : isVariadic, TypeQuals, false,
1790 : false, 0, 0, NoReturn,
1791 3759: getCanonicalCallConv(CallConv));
1792 :
1793 : // Get the new insert position for the node we care about.
1794 : FunctionProtoType *NewIP =
1795 3759: FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
3759: branch 1 taken
1796 3759: assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
1797 : }
1798 :
1799 : // FunctionProtoType objects are allocated with extra bytes after them
1800 : // for two variable size arrays (for parameter and exception types) at the
1801 : // end of them.
1802 : FunctionProtoType *FTP =
1803 : (FunctionProtoType*)Allocate(sizeof(FunctionProtoType) +
1804 : NumArgs*sizeof(QualType) +
1805 20496: NumExs*sizeof(QualType), TypeAlignment);
1806 : new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic,
1807 : TypeQuals, hasExceptionSpec, hasAnyExceptionSpec,
20496: branch 1 taken
0: branch 2 not taken
1808 20496: ExArray, NumExs, Canonical, NoReturn, CallConv);
1809 20496: Types.push_back(FTP);
20496: branch 0 taken
0: branch 1 not taken
1810 20496: FunctionProtoTypes.InsertNode(FTP, InsertPos);
1811 20496: return QualType(FTP, 0);
1812 : }
1813 :
1814 : /// getTypeDeclType - Return the unique reference to the type for the
1815 : /// specified type declaration.
1816 103308: QualType ASTContext::getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl) {
0: branch 0 not taken
103308: branch 1 taken
1817 103308: assert(Decl && "Passed null for Decl param");
85341: branch 0 taken
17967: branch 1 taken
1818 103308: if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
1819 :
4824: branch 1 taken
13143: branch 2 taken
1820 17967: if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl))
1821 4824: return getTypedefType(Typedef);
0: branch 1 not taken
13143: branch 2 taken
1822 13143: else if (isa<TemplateTypeParmDecl>(Decl)) {
1823 0: assert(false && "Template type parameter types are always available.");
0: branch 0 not taken
13143: branch 1 taken
1824 13143: } else if (ObjCInterfaceDecl *ObjCInterface
1825 13143: = dyn_cast<ObjCInterfaceDecl>(Decl))
1826 0: return getObjCInterfaceType(ObjCInterface);
1827 :
12453: branch 1 taken
690: branch 2 taken
1828 13143: if (RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) {
4879: branch 0 taken
7574: branch 1 taken
1829 12453: if (PrevDecl)
1830 4879: Decl->TypeForDecl = PrevDecl->TypeForDecl;
1831 : else
7574: branch 1 taken
0: branch 2 not taken
1832 7574: Decl->TypeForDecl = new (*this, TypeAlignment) RecordType(Record);
689: branch 1 taken
1: branch 2 taken
1833 690: } else if (EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) {
4: branch 0 taken
685: branch 1 taken
1834 689: if (PrevDecl)
1835 4: Decl->TypeForDecl = PrevDecl->TypeForDecl;
1836 : else
685: branch 1 taken
0: branch 2 not taken
1837 685: Decl->TypeForDecl = new (*this, TypeAlignment) EnumType(Enum);
1: branch 0 taken
0: branch 1 not taken
1838 1: } else if (UnresolvedUsingTypenameDecl *Using =
1839 1: dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
1: branch 1 taken
0: branch 2 not taken
1840 1: Decl->TypeForDecl = new (*this, TypeAlignment) UnresolvedUsingType(Using);
1841 : } else
1842 0: assert(false && "TypeDecl without a type?");
1843 :
8260: branch 0 taken
4883: branch 1 taken
1844 13143: if (!PrevDecl) Types.push_back(Decl->TypeForDecl);
1845 13143: return QualType(Decl->TypeForDecl, 0);
1846 : }
1847 :
1848 : /// getTypedefType - Return the unique reference to the type for the
1849 : /// specified typename decl.
1850 4936: QualType ASTContext::getTypedefType(TypedefDecl *Decl) {
97: branch 0 taken
4839: branch 1 taken
1851 4936: if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
1852 :
1853 4839: QualType Canonical = getCanonicalType(Decl->getUnderlyingType());
1854 : Decl->TypeForDecl = new(*this, TypeAlignment)
4839: branch 1 taken
0: branch 2 not taken
1855 4839: TypedefType(Type::Typedef, Decl, Canonical);
1856 4839: Types.push_back(Decl->TypeForDecl);
1857 4839: return QualType(Decl->TypeForDecl, 0);
1858 : }
1859 :
1860 : /// \brief Retrieve a substitution-result type.
1861 : QualType
1862 : ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
1863 2697: QualType Replacement) {
1864 : assert(Replacement.isCanonical()
2697: branch 1 taken
0: branch 2 not taken
1865 2697: && "replacement types must always be canonical");
1866 :
1867 2697: llvm::FoldingSetNodeID ID;
1868 2697: SubstTemplateTypeParmType::Profile(ID, Parm, Replacement);
1869 2697: void *InsertPos = 0;
1870 : SubstTemplateTypeParmType *SubstParm
1871 2697: = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
1872 :
911: branch 0 taken
1786: branch 1 taken
1873 2697: if (!SubstParm) {
1874 : SubstParm = new (*this, TypeAlignment)
911: branch 1 taken
0: branch 2 not taken
1875 911: SubstTemplateTypeParmType(Parm, Replacement);
1876 911: Types.push_back(SubstParm);
911: branch 0 taken
0: branch 1 not taken
1877 911: SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);
1878 : }
1879 :
1880 2697: return QualType(SubstParm, 0);
1881 : }
1882 :
1883 : /// \brief Retrieve the template type parameter type for a template
1884 : /// parameter or parameter pack with the given depth, index, and (optionally)
1885 : /// name.
1886 : QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
1887 : bool ParameterPack,
1888 2594: IdentifierInfo *Name) {
1889 2594: llvm::FoldingSetNodeID ID;
1890 2594: TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, Name);
1891 2594: void *InsertPos = 0;
1892 : TemplateTypeParmType *TypeParm
1893 2594: = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
1894 :
1401: branch 0 taken
1193: branch 1 taken
1895 2594: if (TypeParm)
1896 1401: return QualType(TypeParm, 0);
1897 :
658: branch 0 taken
535: branch 1 taken
1898 1193: if (Name) {
1899 658: QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack);
1900 : TypeParm = new (*this, TypeAlignment)
658: branch 1 taken
0: branch 2 not taken
1901 658: TemplateTypeParmType(Depth, Index, ParameterPack, Name, Canon);
1902 :
1903 : TemplateTypeParmType *TypeCheck
1904 658: = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
658: branch 1 taken
1905 658: assert(!TypeCheck && "Template type parameter canonical type broken");
1906 : (void)TypeCheck;
1907 : } else
1908 : TypeParm = new (*this, TypeAlignment)
535: branch 1 taken
0: branch 2 not taken
1909 535: TemplateTypeParmType(Depth, Index, ParameterPack);
1910 :
1911 1193: Types.push_back(TypeParm);
1193: branch 0 taken
0: branch 1 not taken
1912 1193: TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos);
1913 :
1914 1193: return QualType(TypeParm, 0);
1915 : }
1916 :
1917 : QualType
1918 : ASTContext::getTemplateSpecializationType(TemplateName Template,
1919 : const TemplateArgumentListInfo &Args,
1920 3552: QualType Canon) {
1921 3552: unsigned NumArgs = Args.size();
1922 :
1923 3552: llvm::SmallVector<TemplateArgument, 4> ArgVec;
1924 3552: ArgVec.reserve(NumArgs);
4661: branch 0 taken
3552: branch 1 taken
1925 8213: for (unsigned i = 0; i != NumArgs; ++i)
1926 4661: ArgVec.push_back(Args[i].getArgument());
1927 :
1928 3552: return getTemplateSpecializationType(Template, ArgVec.data(), NumArgs, Canon);
1929 : }
1930 :
1931 : QualType
1932 : ASTContext::getTemplateSpecializationType(TemplateName Template,
1933 : const TemplateArgument *Args,
1934 : unsigned NumArgs,
1935 4465: QualType Canon) {
3518: branch 1 taken
947: branch 2 taken
1936 4465: if (!Canon.isNull())
1937 3518: Canon = getCanonicalType(Canon);
1938 : else {
1939 : // Build the canonical template specialization type.
1940 947: TemplateName CanonTemplate = getCanonicalTemplateName(Template);
1941 947: llvm::SmallVector<TemplateArgument, 4> CanonArgs;
1942 947: CanonArgs.reserve(NumArgs);
1213: branch 0 taken
947: branch 1 taken
1943 2160: for (unsigned I = 0; I != NumArgs; ++I)
1944 1213: CanonArgs.push_back(getCanonicalTemplateArgument(Args[I]));
1945 :
1946 : // Determine whether this canonical template specialization type already
1947 : // exists.
1948 947: llvm::FoldingSetNodeID ID;
1949 : TemplateSpecializationType::Profile(ID, CanonTemplate,
1950 947: CanonArgs.data(), NumArgs, *this);
1951 :
1952 947: void *InsertPos = 0;
1953 : TemplateSpecializationType *Spec
1954 947: = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
1955 :
552: branch 0 taken
395: branch 1 taken
1956 947: if (!Spec) {
1957 : // Allocate a new canonical template specialization type.
1958 : void *Mem = Allocate((sizeof(TemplateSpecializationType) +
1959 : sizeof(TemplateArgument) * NumArgs),
1960 552: TypeAlignment);
1961 : Spec = new (Mem) TemplateSpecializationType(*this, CanonTemplate,
1962 : CanonArgs.data(), NumArgs,
552: branch 2 taken
0: branch 3 not taken
1963 552: Canon);
1964 552: Types.push_back(Spec);
552: branch 0 taken
0: branch 1 not taken
1965 552: TemplateSpecializationTypes.InsertNode(Spec, InsertPos);
1966 : }
1967 :
947: branch 1 taken
0: branch 2 not taken
1968 947: if (Canon.isNull())
1969 947: Canon = QualType(Spec, 0);
1970 : assert(Canon->isDependentType() &&
947: branch 2 taken
0: branch 3 not taken
1971 947: "Non-dependent template-id type must have a canonical type");
1972 : }
1973 :
1974 : // Allocate the (non-canonical) template specialization type, but don't
1975 : // try to unique it: these types typically have location information that
1976 : // we don't unique and don't want to lose.
1977 : void *Mem = Allocate((sizeof(TemplateSpecializationType) +
1978 : sizeof(TemplateArgument) * NumArgs),
1979 4465: TypeAlignment);
1980 : TemplateSpecializationType *Spec
1981 : = new (Mem) TemplateSpecializationType(*this, Template, Args, NumArgs,
4465: branch 1 taken
0: branch 2 not taken
1982 4465: Canon);
1983 :
1984 4465: Types.push_back(Spec);
1985 4465: return QualType(Spec, 0);
1986 : }
1987 :
1988 : QualType
1989 : ASTContext::getQualifiedNameType(NestedNameSpecifier *NNS,
1990 552: QualType NamedType) {
1991 552: llvm::FoldingSetNodeID ID;
1992 552: QualifiedNameType::Profile(ID, NNS, NamedType);
1993 :
1994 552: void *InsertPos = 0;
1995 : QualifiedNameType *T
1996 552: = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos);
117: branch 0 taken
435: branch 1 taken
1997 552: if (T)
1998 117: return QualType(T, 0);
1999 :
2000 435: QualType Canon = NamedType;
262: branch 1 taken
173: branch 2 taken
2001 435: if (!Canon.isCanonical()) {
2002 262: Canon = getCanonicalType(NamedType);
2003 : QualifiedNameType *CheckT
2004 262: = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
262: branch 1 taken
2005 262: assert(!CheckT && "Qualified name canonical type broken");
2006 : (void)CheckT;
2007 : }
2008 :
435: branch 1 taken
0: branch 2 not taken
2009 435: T = new (*this) QualifiedNameType(NNS, NamedType, Canon);
2010 435: Types.push_back(T);
435: branch 0 taken
0: branch 1 not taken
2011 435: QualifiedNameTypes.InsertNode(T, InsertPos);
2012 435: return QualType(T, 0);
2013 : }
2014 :
2015 : QualType ASTContext::getTypenameType(NestedNameSpecifier *NNS,
2016 : const IdentifierInfo *Name,
2017 163: QualType Canon) {
163: branch 1 taken
0: branch 2 not taken
2018 163: assert(NNS->isDependent() && "nested-name-specifier must be dependent");
2019 :
163: branch 1 taken
0: branch 2 not taken
2020 163: if (Canon.isNull()) {
2021 163: NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
80: branch 0 taken
83: branch 1 taken
2022 163: if (CanonNNS != NNS)
2023 80: Canon = getTypenameType(CanonNNS, Name);
2024 : }
2025 :
2026 163: llvm::FoldingSetNodeID ID;
2027 163: TypenameType::Profile(ID, NNS, Name);
2028 :
2029 163: void *InsertPos = 0;
2030 : TypenameType *T
2031 163: = TypenameTypes.FindNodeOrInsertPos(ID, InsertPos);
16: branch 0 taken
147: branch 1 taken
2032 163: if (T)
2033 16: return QualType(T, 0);
2034 :
147: branch 1 taken
0: branch 2 not taken
2035 147: T = new (*this) TypenameType(NNS, Name, Canon);
2036 147: Types.push_back(T);
147: branch 0 taken
0: branch 1 not taken
2037 147: TypenameTypes.InsertNode(T, InsertPos);
2038 147: return QualType(T, 0);
2039 : }
2040 :
2041 : QualType
2042 : ASTContext::getTypenameType(NestedNameSpecifier *NNS,
2043 : const TemplateSpecializationType *TemplateId,
2044 38: QualType Canon) {
38: branch 1 taken
0: branch 2 not taken
2045 38: assert(NNS->isDependent() && "nested-name-specifier must be dependent");
2046 :
2047 38: llvm::FoldingSetNodeID ID;
2048 38: TypenameType::Profile(ID, NNS, TemplateId);
2049 :
2050 38: void *InsertPos = 0;
2051 : TypenameType *T
2052 38: = TypenameTypes.FindNodeOrInsertPos(ID, InsertPos);
10: branch 0 taken
28: branch 1 taken
2053 38: if (T)
2054 10: return QualType(T, 0);
2055 :
28: branch 1 taken
0: branch 2 not taken
2056 28: if (Canon.isNull()) {
2057 28: NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
2058 28: QualType CanonType = getCanonicalType(QualType(TemplateId, 0));
9: branch 0 taken
19: branch 1 taken
0: branch 4 not taken
9: branch 5 taken
19: branch 6 taken
9: branch 7 taken
2059 28: if (CanonNNS != NNS || CanonType != QualType(TemplateId, 0)) {
2060 : const TemplateSpecializationType *CanonTemplateId
2061 19: = CanonType->getAs<TemplateSpecializationType>();
2062 : assert(CanonTemplateId &&
0: branch 0 not taken
19: branch 1 taken
2063 19: "Canonical type must also be a template specialization type");
2064 19: Canon = getTypenameType(CanonNNS, CanonTemplateId);
2065 : }
2066 :
2067 : TypenameType *CheckT
2068 28: = TypenameTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
28: branch 1 taken
2069 28: assert(!CheckT && "Typename canonical type is broken"); (void)CheckT;
2070 : }
2071 :
28: branch 1 taken
0: branch 2 not taken
2072 28: T = new (*this) TypenameType(NNS, TemplateId, Canon);
2073 28: Types.push_back(T);
28: branch 0 taken
0: branch 1 not taken
2074 28: TypenameTypes.InsertNode(T, InsertPos);
2075 28: return QualType(T, 0);
2076 : }
2077 :
2078 : QualType
2079 : ASTContext::getElaboratedType(QualType UnderlyingType,
2080 492: ElaboratedType::TagKind Tag) {
2081 492: llvm::FoldingSetNodeID ID;
2082 492: ElaboratedType::Profile(ID, UnderlyingType, Tag);
2083 :
2084 492: void *InsertPos = 0;
2085 492: ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
51: branch 0 taken
441: branch 1 taken
2086 492: if (T)
2087 51: return QualType(T, 0);
2088 :
2089 441: QualType Canon = UnderlyingType;
13: branch 1 taken
428: branch 2 taken
2090 441: if (!Canon.isCanonical()) {
2091 13: Canon = getCanonicalType(Canon);
2092 13: ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
0: branch 0 not taken
13: branch 1 taken
2093 13: assert(!CheckT && "Elaborated canonical type is broken"); (void)CheckT;
2094 : }
2095 :
441: branch 1 taken
0: branch 2 not taken
2096 441: T = new (*this) ElaboratedType(UnderlyingType, Tag, Canon);
2097 441: Types.push_back(T);
441: branch 0 taken
0: branch 1 not taken
2098 441: ElaboratedTypes.InsertNode(T, InsertPos);
2099 441: return QualType(T, 0);
2100 : }
2101 :
2102 : /// CmpProtocolNames - Comparison predicate for sorting protocols
2103 : /// alphabetically.
2104 : static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,
2105 125: const ObjCProtocolDecl *RHS) {
2106 125: return LHS->getDeclName() < RHS->getDeclName();
2107 : }
2108 :
2109 : static bool areSortedAndUniqued(ObjCProtocolDecl **Protocols,
2110 2764: unsigned NumProtocols) {
2485: branch 0 taken
279: branch 1 taken
2111 2764: if (NumProtocols == 0) return true;
2112 :
92: branch 0 taken
262: branch 1 taken
2113 354: for (unsigned i = 1; i != NumProtocols; ++i)
17: branch 1 taken
75: branch 2 taken
2114 92: if (!CmpProtocolNames(Protocols[i-1], Protocols[i]))
2115 17: return false;
2116 262: return true;
2117 : }
2118 :
2119 : static void SortAndUniqueProtocols(ObjCProtocolDecl **Protocols,
2120 14: unsigned &NumProtocols) {
2121 14: ObjCProtocolDecl **ProtocolsEnd = Protocols+NumProtocols;
2122 :
2123 : // Sort protocols, keyed by name.
2124 14: std::sort(Protocols, Protocols+NumProtocols, CmpProtocolNames);
2125 :
2126 : // Remove duplicates.
2127 14: ProtocolsEnd = std::unique(Protocols, ProtocolsEnd);
2128 14: NumProtocols = ProtocolsEnd-Protocols;
2129 14: }
2130 :
2131 : /// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
2132 : /// the given interface decl and the conforming protocol list.
2133 : QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT,
2134 : ObjCProtocolDecl **Protocols,
2135 4665: unsigned NumProtocols) {
2136 4665: llvm::FoldingSetNodeID ID;
2137 4665: ObjCObjectPointerType::Profile(ID, InterfaceT, Protocols, NumProtocols);
2138 :
2139 4665: void *InsertPos = 0;
1979: branch 0 taken
2686: branch 1 taken
2140 4665: if (ObjCObjectPointerType *QT =
2141 4665: ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
2142 1979: return QualType(QT, 0);
2143 :
2144 : // Sort the protocol list alphabetically to canonicalize it.
2145 2686: QualType Canonical;
2669: branch 1 taken
17: branch 2 taken
3: branch 4 taken
2666: branch 5 taken
20: branch 6 taken
2666: branch 7 taken
2146 2686: if (!InterfaceT.isCanonical() ||
2147 : !areSortedAndUniqued(Protocols, NumProtocols)) {
3: branch 1 taken
17: branch 2 taken
2148 20: if (!areSortedAndUniqued(Protocols, NumProtocols)) {
2149 3: llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(NumProtocols);
2150 3: unsigned UniqueCount = NumProtocols;
2151 :
2152 3: std::copy(Protocols, Protocols + NumProtocols, Sorted.begin());
2153 3: SortAndUniqueProtocols(&Sorted[0], UniqueCount);
2154 :
2155 : Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT),
2156 3: &Sorted[0], UniqueCount);
2157 : } else {
2158 : Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT),
2159 17: Protocols, NumProtocols);
2160 : }
2161 :
2162 : // Regenerate InsertPos.
2163 20: ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
2164 : }
2165 :
2166 : // No match.
2167 : unsigned Size = sizeof(ObjCObjectPointerType)
2168 2686: + NumProtocols * sizeof(ObjCProtocolDecl *);
2169 2686: void *Mem = Allocate(Size, TypeAlignment);
2170 : ObjCObjectPointerType *QType = new (Mem) ObjCObjectPointerType(Canonical,
2171 : InterfaceT,
2172 : Protocols,
2686: branch 1 taken
0: branch 2 not taken
2173 2686: NumProtocols);
2174 :
2175 2686: Types.push_back(QType);
2686: branch 0 taken
0: branch 1 not taken
2176 2686: ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
2177 2686: return QualType(QType, 0);
2178 : }
2179 :
2180 : /// getObjCInterfaceType - Return the unique reference to the type for the
2181 : /// specified ObjC interface decl. The list of protocols is optional.
2182 : QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
2183 4551: ObjCProtocolDecl **Protocols, unsigned NumProtocols) {
2184 4551: llvm::FoldingSetNodeID ID;
2185 4551: ObjCInterfaceType::Profile(ID, Decl, Protocols, NumProtocols);
2186 :
2187 4551: void *InsertPos = 0;
2587: branch 0 taken
1964: branch 1 taken
2188 4551: if (ObjCInterfaceType *QT =
2189 4551: ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos))
2190 2587: return QualType(QT, 0);
2191 :
2192 : // Sort the protocol list alphabetically to canonicalize it.
2193 1964: QualType Canonical;
75: branch 0 taken
1889: branch 1 taken
11: branch 3 taken
64: branch 4 taken
11: branch 5 taken
1953: branch 6 taken
2194 1964: if (NumProtocols && !areSortedAndUniqued(Protocols, NumProtocols)) {
2195 11: llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(NumProtocols);
2196 11: std::copy(Protocols, Protocols + NumProtocols, Sorted.begin());
2197 :
2198 11: unsigned UniqueCount = NumProtocols;
2199 11: SortAndUniqueProtocols(&Sorted[0], UniqueCount);
2200 :
2201 11: Canonical = getObjCInterfaceType(Decl, &Sorted[0], UniqueCount);
2202 :
2203 11: ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos);
2204 : }
2205 :
2206 : unsigned Size = sizeof(ObjCInterfaceType)
2207 1964: + NumProtocols * sizeof(ObjCProtocolDecl *);
2208 1964: void *Mem = Allocate(Size, TypeAlignment);
2209 : ObjCInterfaceType *QType = new (Mem) ObjCInterfaceType(Canonical,
2210 : const_cast<ObjCInterfaceDecl*>(Decl),
2211 : Protocols,
1964: branch 1 taken
0: branch 2 not taken
2212 1964: NumProtocols);
2213 :
2214 1964: Types.push_back(QType);
1964: branch 0 taken
0: branch 1 not taken
2215 1964: ObjCInterfaceTypes.InsertNode(QType, InsertPos);
2216 1964: return QualType(QType, 0);
2217 : }
2218 :
2219 : /// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
2220 : /// TypeOfExprType AST's (since expression's are never shared). For example,
2221 : /// multiple declarations that refer to "typeof(x)" all contain different
2222 : /// DeclRefExpr's. This doesn't effect the type checker, since it operates
2223 : /// on canonical type's (which are always unique).
2224 282: QualType ASTContext::getTypeOfExprType(Expr *tofExpr) {
2225 : TypeOfExprType *toe;
7: branch 1 taken
275: branch 2 taken
2226 282: if (tofExpr->isTypeDependent()) {
2227 7: llvm::FoldingSetNodeID ID;
2228 7: DependentTypeOfExprType::Profile(ID, *this, tofExpr);
2229 :
2230 7: void *InsertPos = 0;
2231 : DependentTypeOfExprType *Canon
2232 7: = DependentTypeOfExprTypes.FindNodeOrInsertPos(ID, InsertPos);
3: branch 0 taken
4: branch 1 taken
2233 7: if (Canon) {
2234 : // We already have a "canonical" version of an identical, dependent
2235 : // typeof(expr) type. Use that as our canonical type.
2236 : toe = new (*this, TypeAlignment) TypeOfExprType(tofExpr,
3: branch 2 taken
0: branch 3 not taken
2237 3: QualType((TypeOfExprType*)Canon, 0));
2238 : }
2239 : else {
2240 : // Build a new, canonical typeof(expr) type.
2241 : Canon
4: branch 1 taken
0: branch 2 not taken
2242 4: = new (*this, TypeAlignment) DependentTypeOfExprType(*this, tofExpr);
4: branch 0 taken
0: branch 1 not taken
2243 4: DependentTypeOfExprTypes.InsertNode(Canon, InsertPos);
2244 4: toe = Canon;
2245 7: }
2246 : } else {
2247 275: QualType Canonical = getCanonicalType(tofExpr->getType());
275: branch 1 taken
0: branch 2 not taken
2248 275: toe = new (*this, TypeAlignment) TypeOfExprType(tofExpr, Canonical);
2249 : }
2250 282: Types.push_back(toe);
2251 282: return QualType(toe, 0);
2252 : }
2253 :
2254 : /// getTypeOfType - Unlike many "get<Type>" functions, we don't unique
2255 : /// TypeOfType AST's. The only motivation to unique these nodes would be
2256 : /// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
2257 : /// an issue. This doesn't effect the type checker, since it operates
2258 : /// on canonical type's (which are always unique).
2259 23: QualType ASTContext::getTypeOfType(QualType tofType) {
2260 23: QualType Canonical = getCanonicalType(tofType);
23: branch 1 taken
0: branch 2 not taken
2261 23: TypeOfType *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
2262 23: Types.push_back(tot);
2263 23: return QualType(tot, 0);
2264 : }
2265 :
2266 : /// getDecltypeForExpr - Given an expr, will return the decltype for that
2267 : /// expression, according to the rules in C++0x [dcl.type.simple]p4
2268 10: static QualType getDecltypeForExpr(const Expr *e, ASTContext &Context) {
0: branch 1 not taken
10: branch 2 taken
2269 10: if (e->isTypeDependent())
2270 0: return Context.DependentTy;
2271 :
2272 : // If e is an id expression or a class member access, decltype(e) is defined
2273 : // as the type of the entity named by e.
2: branch 1 taken
8: branch 2 taken
2274 10: if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(e)) {
2: branch 2 taken
0: branch 3 not taken
2275 2: if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl()))
2276 2: return VD->getType();
2277 : }
1: branch 1 taken
7: branch 2 taken
2278 8: if (const MemberExpr *ME = dyn_cast<MemberExpr>(e)) {
1: branch 2 taken
0: branch 3 not taken
2279 1: if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
2280 1: return FD->getType();
2281 : }
2282 : // If e is a function call or an invocation of an overloaded operator,
2283 : // (parentheses around e are ignored), decltype(e) is defined as the
2284 : // return type of that function.
1: branch 2 taken
6: branch 3 taken
2285 7: if (const CallExpr *CE = dyn_cast<CallExpr>(e->IgnoreParens()))
2286 1: return CE->getCallReturnType();
2287 :
2288 6: QualType T = e->getType();
2289 :
2290 : // Otherwise, where T is the type of e, if e is an lvalue, decltype(e) is
2291 : // defined as T&, otherwise decltype(e) is defined as T.
1: branch 1 taken
5: branch 2 taken
2292 6: if (e->isLvalue(Context) == Expr::LV_Valid)
2293 1: T = Context.getLValueReferenceType(T);
2294 :
2295 6: return T;
2296 : }
2297 :
2298 : /// getDecltypeType - Unlike many "get<Type>" functions, we don't unique
2299 : /// DecltypeType AST's. The only motivation to unique these nodes would be
2300 : /// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
2301 : /// an issue. This doesn't effect the type checker, since it operates
2302 : /// on canonical type's (which are always unique).
2303 16: QualType ASTContext::getDecltypeType(Expr *e) {
2304 : DecltypeType *dt;
6: branch 1 taken
10: branch 2 taken
2305 16: if (e->isTypeDependent()) {
2306 6: llvm::FoldingSetNodeID ID;
2307 6: DependentDecltypeType::Profile(ID, *this, e);
2308 :
2309 6: void *InsertPos = 0;
2310 : DependentDecltypeType *Canon
2311 6: = DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos);
1: branch 0 taken
5: branch 1 taken
2312 6: if (Canon) {
2313 : // We already have a "canonical" version of an equivalent, dependent
2314 : // decltype type. Use that as our canonical type.
2315 : dt = new (*this, TypeAlignment) DecltypeType(e, DependentTy,
1: branch 3 taken
0: branch 4 not taken
2316 1: QualType((DecltypeType*)Canon, 0));
2317 : }
2318 : else {
2319 : // Build a new, canonical typeof(expr) type.
5: branch 1 taken
0: branch 2 not taken
2320 5: Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e);
5: branch 0 taken
0: branch 1 not taken
2321 5: DependentDecltypeTypes.InsertNode(Canon, InsertPos);
2322 5: dt = Canon;
2323 6: }
2324 : } else {
2325 10: QualType T = getDecltypeForExpr(e, *this);
10: branch 3 taken
0: branch 4 not taken
2326 10: dt = new (*this, TypeAlignment) DecltypeType(e, T, getCanonicalType(T));
2327 : }
2328 16: Types.push_back(dt);
2329 16: return QualType(dt, 0);
2330 : }
2331 :
2332 : /// getTagDeclType - Return the unique reference to the type for the
2333 : /// specified TagDecl (struct/union/class/enum) decl.
2334 18548: QualType ASTContext::getTagDeclType(const TagDecl *Decl) {
0: branch 0 not taken
18548: branch 1 taken
2335 18548: assert (Decl);
2336 : // FIXME: What is the design on getTagDeclType when it requires casting
2337 : // away const? mutable?
2338 18548: return getTypeDeclType(const_cast<TagDecl*>(Decl));
2339 : }
2340 :
2341 : /// getSizeType - Return the unique type for "size_t" (C99 7.17), the result
2342 : /// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and
2343 : /// needs to agree with the definition in <stddef.h>.
2344 1784: CanQualType ASTContext::getSizeType() const {
2345 1784: return getFromTargetType(Target.getSizeType());
2346 : }
2347 :
2348 : /// getSignedWCharType - Return the type of "signed wchar_t".
2349 : /// Used when in C++, as a GCC extension.
2350 1: QualType ASTContext::getSignedWCharType() const {
2351 : // FIXME: derive from "Target" ?
2352 1: return WCharTy;
2353 : }
2354 :
2355 : /// getUnsignedWCharType - Return the type of "unsigned wchar_t".
2356 : /// Used when in C++, as a GCC extension.
2357 1: QualType ASTContext::getUnsignedWCharType() const {
2358 : // FIXME: derive from "Target" ?
2359 1: return UnsignedIntTy;
2360 : }
2361 :
2362 : /// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
2363 : /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
2364 795: QualType ASTContext::getPointerDiffType() const {
2365 795: return getFromTargetType(Target.getPtrDiffType(0));
2366 : }
2367 :
2368 : //===----------------------------------------------------------------------===//
2369 : // Type Operators
2370 : //===----------------------------------------------------------------------===//
2371 :
2372 5859: CanQualType ASTContext::getCanonicalParamType(QualType T) {
2373 : // Push qualifiers into arrays, and then discard any remaining
2374 : // qualifiers.
2375 5859: T = getCanonicalType(T);
2376 5859: const Type *Ty = T.getTypePtr();
2377 :
2378 5859: QualType Result;
0: branch 1 not taken
5859: branch 2 taken
2379 5859: if (isa<ArrayType>(Ty)) {
2380 0: Result = getArrayDecayedType(QualType(Ty,0));
0: branch 1 not taken
5859: branch 2 taken
2381 5859: } else if (isa<FunctionType>(Ty)) {
2382 0: Result = getPointerType(QualType(Ty, 0));
2383 : } else {
2384 5859: Result = QualType(Ty, 0);
2385 : }
2386 :
2387 5859: return CanQualType::CreateUnsafe(Result);
2388 : }
2389 :
2390 : /// getCanonicalType - Return the canonical (structural) type corresponding to
2391 : /// the specified potentially non-canonical type. The non-canonical version
2392 : /// of a type may have many "decorated" versions of types. Decorators can
2393 : /// include typedefs, 'typeof' operators, etc. The returned type is guaranteed
2394 : /// to be free of any of these, allowing two canonical types to be compared
2395 : /// for exact equality with a simple pointer comparison.
2396 929284: CanQualType ASTContext::getCanonicalType(QualType T) {
2397 929284: QualifierCollector Quals;
2398 929284: const Type *Ptr = Quals.strip(T);
2399 929284: QualType CanType = Ptr->getCanonicalTypeInternal();
2400 :
2401 : // The canonical internal type will be the canonical type *except*
2402 : // that we push type qualifiers down through array types.
2403 :
2404 : // If there are no new qualifiers to push down, stop here.
894731: branch 1 taken
34553: branch 2 taken
2405 929284: if (!Quals.hasQualifiers())
2406 894731: return CanQualType::CreateUnsafe(CanType);
2407 :
2408 : // If the type qualifiers are on an array type, get the canonical
2409 : // type of the array with the qualifiers applied to the element
2410 : // type.
2411 34553: ArrayType *AT = dyn_cast<ArrayType>(CanType);
34392: branch 0 taken
161: branch 1 taken
2412 34553: if (!AT)
2413 34392: return CanQualType::CreateUnsafe(getQualifiedType(CanType, Quals));
2414 :
2415 : // Get the canonical version of the element with the extra qualifiers on it.
2416 : // This can recursively sink qualifiers through multiple levels of arrays.
2417 161: QualType NewEltTy = getQualifiedType(AT->getElementType(), Quals);
2418 161: NewEltTy = getCanonicalType(NewEltTy);
2419 :
142: branch 1 taken
19: branch 2 taken
2420 161: if (ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
2421 : return CanQualType::CreateUnsafe(
2422 : getConstantArrayType(NewEltTy, CAT->getSize(),
2423 : CAT->getSizeModifier(),
2424 142: CAT->getIndexTypeCVRQualifiers()));
8: branch 1 taken
11: branch 2 taken
2425 19: if (IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT))
2426 : return CanQualType::CreateUnsafe(
2427 : getIncompleteArrayType(NewEltTy, IAT->getSizeModifier(),
2428 8: IAT->getIndexTypeCVRQualifiers()));
2429 :
0: branch 1 not taken
11: branch 2 taken
2430 11: if (DependentSizedArrayType *DSAT = dyn_cast<DependentSizedArrayType>(AT))
2431 : return CanQualType::CreateUnsafe(
2432 : getDependentSizedArrayType(NewEltTy,
2433 : DSAT->getSizeExpr() ?
2434 : DSAT->getSizeExpr()->Retain() : 0,
2435 : DSAT->getSizeModifier(),
2436 : DSAT->getIndexTypeCVRQualifiers(),
0: branch 4 not taken
0: branch 5 not taken
2437 0: DSAT->getBracketsRange())->getCanonicalTypeInternal());
2438 :
2439 11: VariableArrayType *VAT = cast<VariableArrayType>(AT);
2440 : return CanQualType::CreateUnsafe(getVariableArrayType(NewEltTy,
2441 : VAT->getSizeExpr() ?
2442 : VAT->getSizeExpr()->Retain() : 0,
2443 : VAT->getSizeModifier(),
2444 : VAT->getIndexTypeCVRQualifiers(),
11: branch 4 taken
0: branch 5 not taken
2445 11: VAT->getBracketsRange()));
2446 : }
2447 :
2448 : QualType ASTContext::getUnqualifiedArrayType(QualType T,
2449 184178: Qualifiers &Quals) {
2450 184178: Quals = T.getQualifiers();
183420: branch 1 taken
758: branch 2 taken
2451 184178: if (!isa<ArrayType>(T)) {
2452 183420: return T.getUnqualifiedType();
2453 : }
2454 :
2455 758: const ArrayType *AT = cast<ArrayType>(T);
2456 758: QualType Elt = AT->getElementType();
2457 758: QualType UnqualElt = getUnqualifiedArrayType(Elt, Quals);
628: branch 1 taken
130: branch 2 taken
2458 758: if (Elt == UnqualElt)
2459 628: return T;
2460 :
122: branch 1 taken
8: branch 2 taken
2461 130: if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T)) {
2462 : return getConstantArrayType(UnqualElt, CAT->getSize(),
2463 122: CAT->getSizeModifier(), 0);
2464 : }
2465 :
4: branch 1 taken
4: branch 2 taken
2466 8: if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(T)) {
2467 4: return getIncompleteArrayType(UnqualElt, IAT->getSizeModifier(), 0);
2468 : }
2469 :
2470 4: const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(T);
2471 : return getDependentSizedArrayType(UnqualElt, DSAT->getSizeExpr()->Retain(),
2472 : DSAT->getSizeModifier(), 0,
2473 4: SourceRange());
2474 : }
2475 :
2476 244: DeclarationName ASTContext::getNameForTemplate(TemplateName Name) {
209: branch 1 taken
35: branch 2 taken
2477 244: if (TemplateDecl *TD = Name.getAsTemplateDecl())
2478 209: return TD->getDeclName();
2479 :
6: branch 1 taken
29: branch 2 taken
2480 35: if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4: branch 1 taken
2: branch 2 taken
2481 6: if (DTN->isIdentifier()) {
2482 4: return DeclarationNames.getIdentifier(DTN->getIdentifier());
2483 : } else {
2484 2: return DeclarationNames.getCXXOperatorName(DTN->getOperator());
2485 : }
2486 : }
2487 :
2488 29: OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate();
0: branch 0 not taken
29: branch 1 taken
2489 29: assert(Storage);
2490 29: return (*Storage->begin())->getDeclName();
2491 : }
2492 :
2493 1934: TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) {
2494 : // If this template name refers to a template, the canonical
2495 : // template name merely stores the template itself.
1900: branch 1 taken
34: branch 2 taken
2496 1934: if (TemplateDecl *Template = Name.getAsTemplateDecl())
2497 1900: return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl()));
2498 :
0: branch 1 not taken
34: branch 2 taken
2499 34: assert(!Name.getAsOverloadedTemplate());
2500 :
2501 34: DependentTemplateName *DTN = Name.getAsDependentTemplateName();
0: branch 0 not taken
34: branch 1 taken
2502 34: assert(DTN && "Non-dependent template names must refer to template decls.");
2503 34: return DTN->CanonicalTemplateName;
2504 : }
2505 :
2506 142: bool ASTContext::hasSameTemplateName(TemplateName X, TemplateName Y) {
2507 142: X = getCanonicalTemplateName(X);
2508 142: Y = getCanonicalTemplateName(Y);
2509 142: return X.getAsVoidPointer() == Y.getAsVoidPointer();
2510 : }
2511 :
2512 : TemplateArgument
2513 1213: ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) {
0: branch 1 not taken
124: branch 2 taken
0: branch 3 not taken
8: branch 4 taken
19: branch 5 taken
1062: branch 6 taken
0: branch 7 not taken
0: branch 8 not taken
2514 1213: switch (Arg.getKind()) {
2515 : case TemplateArgument::Null:
2516 0: return Arg;
2517 :
2518 : case TemplateArgument::Expression:
2519 124: return Arg;
2520 :
2521 : case TemplateArgument::Declaration:
2522 0: return TemplateArgument(Arg.getAsDecl()->getCanonicalDecl());
2523 :
2524 : case TemplateArgument::Template:
2525 8: return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate()));
2526 :
2527 : case TemplateArgument::Integral:
2528 : return TemplateArgument(*Arg.getAsIntegral(),
2529 19: getCanonicalType(Arg.getIntegralType()));
2530 :
2531 : case TemplateArgument::Type:
2532 1062: return TemplateArgument(getCanonicalType(Arg.getAsType()));
2533 :
2534 : case TemplateArgument::Pack: {
2535 : // FIXME: Allocate in ASTContext
0: branch 3 not taken
0: branch 4 not taken
2536 0: TemplateArgument *CanonArgs = new TemplateArgument[Arg.pack_size()];
2537 0: unsigned Idx = 0;
0: branch 1 not taken
0: branch 2 not taken
2538 0: for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
2539 0: AEnd = Arg.pack_end();
2540 : A != AEnd; (void)++A, ++Idx)
2541 0: CanonArgs[Idx] = getCanonicalTemplateArgument(*A);
2542 :
2543 0: TemplateArgument Result;
2544 0: Result.setArgumentPack(CanonArgs, Arg.pack_size(), false);
2545 0: return Result;
2546 : }
2547 : }
2548 :
2549 : // Silence GCC warning
2550 0: assert(false && "Unhandled template argument kind");
2551 : return TemplateArgument();
2552 : }
2553 :
2554 : NestedNameSpecifier *
2555 565: ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) {
310: branch 0 taken
255: branch 1 taken
2556 565: if (!NNS)
2557 310: return 0;
2558 :
7: branch 1 taken
0: branch 2 not taken
248: branch 3 taken
0: branch 4 not taken
0: branch 5 not taken
2559 255: switch (NNS->getKind()) {
2560 : case NestedNameSpecifier::Identifier:
2561 : // Canonicalize the prefix but keep the identifier the same.
2562 : return NestedNameSpecifier::Create(*this,
2563 : getCanonicalNestedNameSpecifier(NNS->getPrefix()),
2564 7: NNS->getAsIdentifier());
2565 :
2566 : case NestedNameSpecifier::Namespace:
2567 : // A namespace is canonical; build a nested-name-specifier with
2568 : // this namespace and no prefix.
2569 0: return NestedNameSpecifier::Create(*this, 0, NNS->getAsNamespace());
2570 :
2571 : case NestedNameSpecifier::TypeSpec:
2572 : case NestedNameSpecifier::TypeSpecWithTemplate: {
2573 248: QualType T = getCanonicalType(QualType(NNS->getAsType(), 0));
2574 : return NestedNameSpecifier::Create(*this, 0,
2575 : NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
2576 248: T.getTypePtr());
2577 : }
2578 :
2579 : case NestedNameSpecifier::Global:
2580 : // The global specifier is canonical and unique.
2581 0: return NNS;
2582 : }
2583 :
2584 : // Required to silence a GCC warning
2585 0: return 0;
2586 : }
2587 :
2588 :
2589 142515: const ArrayType *ASTContext::getAsArrayType(QualType T) {
2590 : // Handle the non-qualified case efficiently.
139004: branch 1 taken
3511: branch 2 taken
2591 142515: if (!T.hasLocalQualifiers()) {
2592 : // Handle the common positive case fast.
13798: branch 1 taken
125206: branch 2 taken
2593 139004: if (const ArrayType *AT = dyn_cast<ArrayType>(T))
2594 13798: return AT;
2595 : }
2596 :
2597 : // Handle the common negative case fast.
2598 128717: QualType CType = T->getCanonicalTypeInternal();
128271: branch 1 taken
446: branch 2 taken
2599 128717: if (!isa<ArrayType>(CType))
2600 128271: return 0;
2601 :
2602 : // Apply any qualifiers from the array type to the element type. This
2603 : // implements C99 6.7.3p8: "If the specification of an array type includes
2604 : // any type qualifiers, the element type is so qualified, not the array type."
2605 :
2606 : // If we get here, we either have type qualifiers on the type, or we have
2607 : // sugar such as a typedef in the way. If we have type qualifiers on the type
2608 : // we must propagate them down into the element type.
2609 :
2610 446: QualifierCollector Qs;
2611 446: const Type *Ty = Qs.strip(T.getDesugaredType());
2612 :
2613 : // If we have a simple case, just return now.
2614 446: const ArrayType *ATy = dyn_cast<ArrayType>(Ty);
446: branch 0 taken
0: branch 1 not taken
329: branch 3 taken
117: branch 4 taken
329: branch 5 taken
117: branch 6 taken
2615 446: if (ATy == 0 || Qs.empty())
2616 329: return ATy;
2617 :
2618 : // Otherwise, we have an array and we have qualifiers on it. Push the
2619 : // qualifiers into the array element type and return a new array type.
2620 : // Get the canonical version of the element with the extra qualifiers on it.
2621 : // This can recursively sink qualifiers through multiple levels of arrays.
2622 117: QualType NewEltTy = getQualifiedType(ATy->getElementType(), Qs);
2623 :
100: branch 1 taken
17: branch 2 taken
2624 117: if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(ATy))
2625 : return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(),
2626 : CAT->getSizeModifier(),
2627 100: CAT->getIndexTypeCVRQualifiers()));
11: branch 1 taken
6: branch 2 taken
2628 17: if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(ATy))
2629 : return cast<ArrayType>(getIncompleteArrayType(NewEltTy,
2630 : IAT->getSizeModifier(),
2631 11: IAT->getIndexTypeCVRQualifiers()));
2632 :
2: branch 0 taken
4: branch 1 taken
2633 6: if (const DependentSizedArrayType *DSAT
2634 6: = dyn_cast<DependentSizedArrayType>(ATy))
2635 : return cast<ArrayType>(
2636 : getDependentSizedArrayType(NewEltTy,
2637 : DSAT->getSizeExpr() ?
2638 : DSAT->getSizeExpr()->Retain() : 0,
2639 : DSAT->getSizeModifier(),
2640 : DSAT->getIndexTypeCVRQualifiers(),
2: branch 4 taken
0: branch 5 not taken
2641 2: DSAT->getBracketsRange()));
2642 :
2643 4: const VariableArrayType *VAT = cast<VariableArrayType>(ATy);
2644 : return cast<ArrayType>(getVariableArrayType(NewEltTy,
2645 : VAT->getSizeExpr() ?
2646 : VAT->getSizeExpr()->Retain() : 0,
2647 : VAT->getSizeModifier(),
2648 : VAT->getIndexTypeCVRQualifiers(),
4: branch 4 taken
0: branch 5 not taken
2649 4: VAT->getBracketsRange()));
2650 : }
2651 :
2652 :
2653 : /// getArrayDecayedType - Return the properly qualified result of decaying the
2654 : /// specified array type to a pointer. This operation is non-trivial when
2655 : /// handling typedefs etc. The canonical type of "T" must be an array type,
2656 : /// this returns a pointer to a properly qualified element of the array.
2657 : ///
2658 : /// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
2659 2974: QualType ASTContext::getArrayDecayedType(QualType Ty) {
2660 : // Get the element type with 'getAsArrayType' so that we don't lose any
2661 : // typedefs in the element type of the array. This also handles propagation
2662 : // of type qualifiers from the array type into the element type if present
2663 : // (C99 6.7.3p8).
2664 2974: const ArrayType *PrettyArrayType = getAsArrayType(Ty);
0: branch 0 not taken
2974: branch 1 taken
2665 2974: assert(PrettyArrayType && "Not an array type!");
2666 :
2667 2974: QualType PtrTy = getPointerType(PrettyArrayType->getElementType());
2668 :
2669 : // int x[restrict 4] -> int *restrict
2670 2974: return getQualifiedType(PtrTy, PrettyArrayType->getIndexTypeQualifiers());
2671 : }
2672 :
2673 10031: QualType ASTContext::getBaseElementType(QualType QT) {
2674 10031: QualifierCollector Qs;
2675 1570: while (true) {
2676 11601: const Type *UT = Qs.strip(QT);
1570: branch 2 taken
10031: branch 3 taken
2677 11601: if (const ArrayType *AT = getAsArrayType(QualType(UT,0))) {
2678 1570: QT = AT->getElementType();
2679 : } else {
2680 10031: return Qs.apply(QT);
2681 : }
2682 : }
2683 : }
2684 :
2685 618: QualType ASTContext::getBaseElementType(const ArrayType *AT) {
2686 618: QualType ElemTy = AT->getElementType();
2687 :
108: branch 1 taken
510: branch 2 taken
2688 618: if (const ArrayType *AT = getAsArrayType(ElemTy))
2689 108: return getBaseElementType(AT);
2690 :
2691 510: return ElemTy;
2692 : }
2693 :
2694 : /// getConstantArrayElementCount - Returns number of constant array elements.
2695 : uint64_t
2696 98: ASTContext::getConstantArrayElementCount(const ConstantArrayType *CA) const {
2697 98: uint64_t ElementCount = 1;
73: branch 0 taken
98: branch 1 taken
2698 171: do {
2699 171: ElementCount *= CA->getSize().getZExtValue();
2700 171: CA = dyn_cast<ConstantArrayType>(CA->getElementType());
2701 : } while (CA);
2702 98: return ElementCount;
2703 : }
2704 :
2705 : /// getFloatingRank - Return a relative rank for floating point types.
2706 : /// This routine will assert if passed a built-in type that isn't a float.
2707 1399: static FloatingRank getFloatingRank(QualType T) {
71: branch 2 taken
1328: branch 3 taken
2708 1399: if (const ComplexType *CT = T->getAs<ComplexType>())
2709 71: return getFloatingRank(CT->getElementType());
2710 :
1328: branch 2 taken
0: branch 3 not taken
2711 1328: assert(T->getAs<BuiltinType>() && "getFloatingRank(): not a floating type");
0: branch 3 not taken
454: branch 4 taken
493: branch 5 taken
381: branch 6 taken
2712 1328: switch (T->getAs<BuiltinType>()->getKind()) {
2713 0: default: assert(0 && "getFloatingRank(): not a floating type");
2714 454: case BuiltinType::Float: return FloatRank;
2715 493: case BuiltinType::Double: return DoubleRank;
2716 381: case BuiltinType::LongDouble: return LongDoubleRank;
2717 : }
2718 : }
2719 :
2720 : /// getFloatingTypeOfSizeWithinDomain - Returns a real floating
2721 : /// point or a complex type (based on typeDomain/typeSize).
2722 : /// 'typeDomain' is a real floating point or complex type.
2723 : /// 'typeSize' is a real floating point or complex type.
2724 : QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
2725 18: QualType Domain) const {
2726 18: FloatingRank EltRank = getFloatingRank(Size);
15: branch 2 taken
3: branch 3 taken
2727 18: if (Domain->isComplexType()) {
0: branch 0 not taken
0: branch 1 not taken
15: branch 2 taken
0: branch 3 not taken
2728 15: switch (EltRank) {
2729 0: default: assert(0 && "getFloatingRank(): illegal value for rank");
2730 0: case FloatRank: return FloatComplexTy;
2731 15: case DoubleRank: return DoubleComplexTy;
2732 0: case LongDoubleRank: return LongDoubleComplexTy;
2733 : }
2734 : }
2735 :
3: branch 2 taken
0: branch 3 not taken
2736 3: assert(Domain->isRealFloatingType() && "Unknown domain!");
0: branch 0 not taken
0: branch 1 not taken
3: branch 2 taken
0: branch 3 not taken
2737 3: switch (EltRank) {
2738 0: default: assert(0 && "getFloatingRank(): illegal value for rank");
2739 0: case FloatRank: return FloatTy;
2740 3: case DoubleRank: return DoubleTy;
2741 0: case LongDoubleRank: return LongDoubleTy;
2742 : }
2743 : }
2744 :
2745 : /// getFloatingTypeOrder - Compare the rank of the two specified floating
2746 : /// point types, ignoring the domain of the type (i.e. 'double' ==
2747 : /// '_Complex double'). If LHS > RHS, return 1. If LHS == RHS, return 0. If
2748 : /// LHS < RHS, return -1.
2749 655: int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) {
2750 655: FloatingRank LHSR = getFloatingRank(LHS);
2751 655: FloatingRank RHSR = getFloatingRank(RHS);
2752 :
40: branch 0 taken
615: branch 1 taken
2753 655: if (LHSR == RHSR)
2754 40: return 0;
293: branch 0 taken
322: branch 1 taken
2755 615: if (LHSR > RHSR)
2756 293: return 1;
2757 322: return -1;
2758 : }
2759 :
2760 : /// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This
2761 : /// routine will assert if passed a built-in type that isn't an integer or enum,
2762 : /// or if it is not canonicalized.
2763 9282: unsigned ASTContext::getIntegerRank(Type *T) {
9282: branch 1 taken
0: branch 2 not taken
2764 9282: assert(T->isCanonicalUnqualified() && "T should be canonicalized");
0: branch 1 not taken
9282: branch 2 taken
2765 9282: if (EnumType* ET = dyn_cast<EnumType>(T))
2766 0: T = ET->getDecl()->getPromotionType().getTypePtr();
2767 :
0: branch 1 not taken
9282: branch 2 taken
2768 9282: if (T->isSpecificBuiltinType(BuiltinType::WChar))
2769 0: T = getFromTargetType(Target.getWCharType()).getTypePtr();
2770 :
0: branch 1 not taken
9282: branch 2 taken
2771 9282: if (T->isSpecificBuiltinType(BuiltinType::Char16))
2772 0: T = getFromTargetType(Target.getChar16Type()).getTypePtr();
2773 :
0: branch 1 not taken
9282: branch 2 taken
2774 9282: if (T->isSpecificBuiltinType(BuiltinType::Char32))
2775 0: T = getFromTargetType(Target.getChar32Type()).getTypePtr();
2776 :
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
5: branch 5 taken
4575: branch 6 taken
2565: branch 7 taken
2133: branch 8 taken
4: branch 9 taken
2777 9282: switch (cast<BuiltinType>(T)->getKind()) {
2778 0: default: assert(0 && "getIntegerRank(): not a built-in integer");
2779 : case BuiltinType::Bool:
2780 0: return 1 + (getIntWidth(BoolTy) << 3);
2781 : case BuiltinType::Char_S:
2782 : case BuiltinType::Char_U:
2783 : case BuiltinType::SChar:
2784 : case BuiltinType::UChar:
2785 0: return 2 + (getIntWidth(CharTy) << 3);
2786 : case BuiltinType::Short:
2787 : case BuiltinType::UShort:
2788 5: return 3 + (getIntWidth(ShortTy) << 3);
2789 : case BuiltinType::Int:
2790 : case BuiltinType::UInt:
2791 4575: return 4 + (getIntWidth(IntTy) << 3);
2792 : case BuiltinType::Long:
2793 : case BuiltinType::ULong:
2794 2565: return 5 + (getIntWidth(LongTy) << 3);
2795 : case BuiltinType::LongLong:
2796 : case BuiltinType::ULongLong:
2797 2133: return 6 + (getIntWidth(LongLongTy) << 3);
2798 : case BuiltinType::Int128:
2799 : case BuiltinType::UInt128:
2800 4: return 7 + (getIntWidth(Int128Ty) << 3);
2801 : }
2802 : }
2803 :
2804 : /// \brief Whether this is a promotable bitfield reference according
2805 : /// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
2806 : ///
2807 : /// \returns the type this bit-field will promote to, or NULL if no
2808 : /// promotion occurs.
2809 29305: QualType ASTContext::isPromotableBitField(Expr *E) {
2810 29305: FieldDecl *Field = E->getBitField();
29236: branch 0 taken
69: branch 1 taken
2811 29305: if (!Field)
2812 29236: return QualType();
2813 :
2814 69: QualType FT = Field->getType();
2815 :
2816 69: llvm::APSInt BitWidthAP = Field->getBitWidth()->EvaluateAsInt(*this);
2817 69: uint64_t BitWidth = BitWidthAP.getZExtValue();
2818 69: uint64_t IntSize = getTypeSize(IntTy);
2819 : // GCC extension compatibility: if the bit-field size is less than or equal
2820 : // to the size of int, it gets promoted no matter what its type is.
2821 : // For instance, unsigned long bf : 4 gets promoted to signed int.
51: branch 0 taken
18: branch 1 taken
2822 69: if (BitWidth < IntSize)
2823 51: return IntTy;
2824 :
10: branch 0 taken
8: branch 1 taken
2825 18: if (BitWidth == IntSize)
0: branch 2 not taken
10: branch 3 taken
2826 10: return FT->isSignedIntegerType() ? IntTy : UnsignedIntTy;
2827 :
2828 : // Types bigger than int are not subject to promotions, and therefore act
2829 : // like the base type.
2830 : // FIXME: This doesn't quite match what gcc does, but what gcc does here
2831 : // is ridiculous.
2832 8: return QualType();
2833 : }
2834 :
2835 : /// getPromotedIntegerType - Returns the type that Promotable will
2836 : /// promote to: C99 6.3.1.1p2, assuming that Promotable is a promotable
2837 : /// integer type.
2838 676: QualType ASTContext::getPromotedIntegerType(QualType Promotable) {
0: branch 1 not taken
676: branch 2 taken
2839 676: assert(!Promotable.isNull());
0: branch 2 not taken
676: branch 3 taken
2840 676: assert(Promotable->isPromotableIntegerType());
37: branch 2 taken
639: branch 3 taken
2841 676: if (const EnumType *ET = Promotable->getAs<EnumType>())
2842 37: return ET->getDecl()->getPromotionType();
290: branch 2 taken
349: branch 3 taken
2843 639: if (Promotable->isSignedIntegerType())
2844 290: return IntTy;
2845 349: uint64_t PromotableSize = getTypeSize(Promotable);
2846 349: uint64_t IntSize = getTypeSize(IntTy);
349: branch 2 taken
0: branch 3 not taken
0: branch 4 not taken
349: branch 5 taken
2847 349: assert(Promotable->isUnsignedIntegerType() && PromotableSize <= IntSize);
348: branch 0 taken
1: branch 1 taken
2848 349: return (PromotableSize != IntSize) ? IntTy : UnsignedIntTy;
2849 : }
2850 :
2851 : /// getIntegerTypeOrder - Returns the highest ranked integer type:
2852 : /// C99 6.3.1.8p1. If LHS > RHS, return 1. If LHS == RHS, return 0. If
2853 : /// LHS < RHS, return -1.
2854 4654: int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) {
2855 4654: Type *LHSC = getCanonicalType(LHS).getTypePtr();
2856 4654: Type *RHSC = getCanonicalType(RHS).getTypePtr();
13: branch 0 taken
4641: branch 1 taken
2857 4654: if (LHSC == RHSC) return 0;
2858 :
2859 4641: bool LHSUnsigned = LHSC->isUnsignedIntegerType();
2860 4641: bool RHSUnsigned = RHSC->isUnsignedIntegerType();
2861 :
2862 4641: unsigned LHSRank = getIntegerRank(LHSC);
2863 4641: unsigned RHSRank = getIntegerRank(RHSC);
2864 :
1367: branch 0 taken
3274: branch 1 taken
2865 4641: if (LHSUnsigned == RHSUnsigned) { // Both signed or both unsigned.
0: branch 0 not taken
1367: branch 1 taken
2866 1367: if (LHSRank == RHSRank) return 0;
708: branch 0 taken
659: branch 1 taken
2867 1367: return LHSRank > RHSRank ? 1 : -1;
2868 : }
2869 :
2870 : // Otherwise, the LHS is signed and the RHS is unsigned or visa versa.
2051: branch 0 taken
1223: branch 1 taken
2871 3274: if (LHSUnsigned) {
2872 : // If the unsigned [LHS] type is larger, return it.
1734: branch 0 taken
317: branch 1 taken
2873 2051: if (LHSRank >= RHSRank)
2874 1734: return 1;
2875 :
2876 : // If the signed type can represent all values of the unsigned type, it
2877 : // wins. Because we are dealing with 2's complement and types that are
2878 : // powers of two larger than each other, this is always safe.
2879 317: return -1;
2880 : }
2881 :
2882 : // If the unsigned [RHS] type is larger, return it.
891: branch 0 taken
332: branch 1 taken
2883 1223: if (RHSRank >= LHSRank)
2884 891: return -1;
2885 :
2886 : // If the signed type can represent all values of the unsigned type, it
2887 : // wins. Because we are dealing with 2's complement and types that are
2888 : // powers of two larger than each other, this is always safe.
2889 332: return 1;
2890 : }
2891 :
2892 : static RecordDecl *
2893 : CreateRecordDecl(ASTContext &Ctx, RecordDecl::TagKind TK, DeclContext *DC,
2894 105: SourceLocation L, IdentifierInfo *Id) {
1: branch 1 taken
104: branch 2 taken
2895 105: if (Ctx.getLangOptions().CPlusPlus)
2896 1: return CXXRecordDecl::Create(Ctx, TK, DC, L, Id);
2897 : else
2898 104: return RecordDecl::Create(Ctx, TK, DC, L, Id);
2899 : }
2900 :
2901 : // getCFConstantStringType - Return the type used for constant CFStrings.
2902 97: QualType ASTContext::getCFConstantStringType() {
21: branch 0 taken
76: branch 1 taken
2903 97: if (!CFConstantStringTypeDecl) {
2904 : CFConstantStringTypeDecl =
2905 : CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
21: branch 3 taken
0: branch 4 not taken
2906 21: &Idents.get("NSConstantString"));
2907 21: CFConstantStringTypeDecl->startDefinition();
2908 :
84: branch 1 taken
21: branch 2 taken
2909 21: QualType FieldTypes[4];
2910 :
2911 : // const int *isa;
2912 21: FieldTypes[0] = getPointerType(IntTy.withConst());
2913 : // int flags;
2914 21: FieldTypes[1] = IntTy;
2915 : // const char *str;
2916 21: FieldTypes[2] = getPointerType(CharTy.withConst());
2917 : // long length;
2918 21: FieldTypes[3] = LongTy;
2919 :
2920 : // Create fields
84: branch 0 taken
21: branch 1 taken
2921 105: for (unsigned i = 0; i < 4; ++i) {
2922 : FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl,
2923 : SourceLocation(), 0,
2924 : FieldTypes[i], /*TInfo=*/0,
2925 : /*BitWidth=*/0,
84: branch 1 taken
0: branch 2 not taken
2926 84: /*Mutable=*/false);
2927 84: CFConstantStringTypeDecl->addDecl(Field);
2928 : }
2929 :
2930 21: CFConstantStringTypeDecl->completeDefinition(*this);
2931 : }
2932 :
2933 97: return getTagDeclType(CFConstantStringTypeDecl);
2934 : }
2935 :
2936 0: void ASTContext::setCFConstantStringType(QualType T) {
2937 0: const RecordType *Rec = T->getAs<RecordType>();
0: branch 0 not taken
0: branch 1 not taken
2938 0: assert(Rec && "Invalid CFConstantStringType");
2939 0: CFConstantStringTypeDecl = Rec->getDecl();
2940 0: }
2941 :
2942 5: QualType ASTContext::getObjCFastEnumerationStateType() {
4: branch 0 taken
1: branch 1 taken
2943 5: if (!ObjCFastEnumerationStateTypeDecl) {
2944 : ObjCFastEnumerationStateTypeDecl =
2945 : CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
4: branch 3 taken
0: branch 4 not taken
2946 4: &Idents.get("__objcFastEnumerationState"));
2947 4: ObjCFastEnumerationStateTypeDecl->startDefinition();
2948 :
2949 : QualType FieldTypes[] = {
2950 : UnsignedLongTy,
2951 : getPointerType(ObjCIdTypedefType),
2952 : getPointerType(UnsignedLongTy),
2953 : getConstantArrayType(UnsignedLongTy,
2954 : llvm::APInt(32, 5), ArrayType::Normal, 0)
2955 4: };
2956 :
16: branch 0 taken
4: branch 1 taken
2957 20: for (size_t i = 0; i < 4; ++i) {
2958 : FieldDecl *Field = FieldDecl::Create(*this,
2959 : ObjCFastEnumerationStateTypeDecl,
2960 : SourceLocation(), 0,
2961 : FieldTypes[i], /*TInfo=*/0,
2962 : /*BitWidth=*/0,
16: branch 1 taken
0: branch 2 not taken
2963 16: /*Mutable=*/false);
2964 16: ObjCFastEnumerationStateTypeDecl->addDecl(Field);
2965 : }
2966 :
2967 4: ObjCFastEnumerationStateTypeDecl->completeDefinition(*this);
2968 : }
2969 :
2970 5: return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
2971 : }
2972 :
2973 15: QualType ASTContext::getBlockDescriptorType() {
5: branch 0 taken
10: branch 1 taken
2974 15: if (BlockDescriptorType)
2975 5: return getTagDeclType(BlockDescriptorType);
2976 :
2977 : RecordDecl *T;
2978 : // FIXME: Needs the FlagAppleBlock bit.
2979 : T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
10: branch 3 taken
0: branch 4 not taken
2980 10: &Idents.get("__block_descriptor"));
2981 10: T->startDefinition();
2982 :
2983 : QualType FieldTypes[] = {
2984 : UnsignedLongTy,
2985 : UnsignedLongTy,
2986 10: };
2987 :
2988 : const char *FieldNames[] = {
2989 : "reserved",
2990 : "Size"
2991 10: };
2992 :
20: branch 0 taken
10: branch 1 taken
2993 30: for (size_t i = 0; i < 2; ++i) {
2994 : FieldDecl *Field = FieldDecl::Create(*this,
2995 : T,
2996 : SourceLocation(),
2997 : &Idents.get(FieldNames[i]),
2998 : FieldTypes[i], /*TInfo=*/0,
2999 : /*BitWidth=*/0,
20: branch 3 taken
0: branch 4 not taken
3000 20: /*Mutable=*/false);
3001 20: T->addDecl(Field);
3002 : }
3003 :
3004 10: T->completeDefinition(*this);
3005 :
3006 10: BlockDescriptorType = T;
3007 :
3008 10: return getTagDeclType(BlockDescriptorType);
3009 : }
3010 :
3011 0: void ASTContext::setBlockDescriptorType(QualType T) {
3012 0: const RecordType *Rec = T->getAs<RecordType>();
0: branch 0 not taken
0: branch 1 not taken
3013 0: assert(Rec && "Invalid BlockDescriptorType");
3014 0: BlockDescriptorType = Rec->getDecl();
3015 0: }
3016 :
3017 20: QualType ASTContext::getBlockDescriptorExtendedType() {
8: branch 0 taken
12: branch 1 taken
3018 20: if (BlockDescriptorExtendedType)
3019 8: return getTagDeclType(BlockDescriptorExtendedType);
3020 :
3021 : RecordDecl *T;
3022 : // FIXME: Needs the FlagAppleBlock bit.
3023 : T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
12: branch 3 taken
0: branch 4 not taken
3024 12: &Idents.get("__block_descriptor_withcopydispose"));
3025 12: T->startDefinition();
3026 :
3027 : QualType FieldTypes[] = {
3028 : UnsignedLongTy,
3029 : UnsignedLongTy,
3030 : getPointerType(VoidPtrTy),
3031 : getPointerType(VoidPtrTy)
3032 12: };
3033 :
3034 : const char *FieldNames[] = {
3035 : "reserved",
3036 : "Size",
3037 : "CopyFuncPtr",
3038 : "DestroyFuncPtr"
3039 12: };
3040 :
48: branch 0 taken
12: branch 1 taken
3041 60: for (size_t i = 0; i < 4; ++i) {
3042 : FieldDecl *Field = FieldDecl::Create(*this,
3043 : T,
3044 : SourceLocation(),
3045 : &Idents.get(FieldNames[i]),
3046 : FieldTypes[i], /*TInfo=*/0,
3047 : /*BitWidth=*/0,
48: branch 3 taken
0: branch 4 not taken
3048 48: /*Mutable=*/false);
3049 48: T->addDecl(Field);
3050 : }
3051 :
3052 12: T->completeDefinition(*this);
3053 :
3054 12: BlockDescriptorExtendedType = T;
3055 :
3056 12: return getTagDeclType(BlockDescriptorExtendedType);
3057 : }
3058 :
3059 0: void ASTContext::setBlockDescriptorExtendedType(QualType T) {
3060 0: const RecordType *Rec = T->getAs<RecordType>();
0: branch 0 not taken
0: branch 1 not taken
3061 0: assert(Rec && "Invalid BlockDescriptorType");
3062 0: BlockDescriptorExtendedType = Rec->getDecl();
3063 0: }
3064 :
3065 141: bool ASTContext::BlockRequiresCopying(QualType Ty) {
10: branch 2 taken
131: branch 3 taken
3066 141: if (Ty->isBlockPointerType())
3067 10: return true;
0: branch 1 not taken
131: branch 2 taken
3068 131: if (isObjCNSObjectType(Ty))
3069 0: return true;
65: branch 2 taken
66: branch 3 taken
3070 131: if (Ty->isObjCObjectPointerType())
3071 65: return true;
3072 66: return false;
3073 : }
3074 :
3075 23: QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) {
3076 : // type = struct __Block_byref_1_X {
3077 : // void *__isa;
3078 : // struct __Block_byref_1_X *__forwarding;
3079 : // unsigned int __flags;
3080 : // unsigned int __size;
3081 : // void *__copy_helper; // as needed
3082 : // void *__destroy_help // as needed
3083 : // int X;
3084 : // } *
3085 :
3086 23: bool HasCopyAndDispose = BlockRequiresCopying(Ty);
3087 :
3088 : // FIXME: Move up
3089 : static unsigned int UniqueBlockByRefTypeID = 0;
3090 23: llvm::SmallString<36> Name;
3091 : llvm::raw_svector_ostream(Name) << "__Block_byref_" <<
3092 23: ++UniqueBlockByRefTypeID << '_'