 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
64.1% |
209 / 326 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
89.0% |
290 / 326 |
| |
|
Line Coverage: |
72.5% |
626 / 864 |
| |
 |
|
 |
1 : //===--- CGDebugInfo.cpp - Emit Debug Information for a Module ------------===//
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 coordinates the debug information generation while generating code.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "CGDebugInfo.h"
15 : #include "CodeGenFunction.h"
16 : #include "CodeGenModule.h"
17 : #include "clang/AST/ASTContext.h"
18 : #include "clang/AST/DeclObjC.h"
19 : #include "clang/AST/Expr.h"
20 : #include "clang/AST/RecordLayout.h"
21 : #include "clang/Basic/SourceManager.h"
22 : #include "clang/Basic/FileManager.h"
23 : #include "clang/Basic/Version.h"
24 : #include "clang/CodeGen/CodeGenOptions.h"
25 : #include "llvm/Constants.h"
26 : #include "llvm/DerivedTypes.h"
27 : #include "llvm/Instructions.h"
28 : #include "llvm/Intrinsics.h"
29 : #include "llvm/Module.h"
30 : #include "llvm/ADT/StringExtras.h"
31 : #include "llvm/ADT/SmallVector.h"
32 : #include "llvm/Support/Dwarf.h"
33 : #include "llvm/System/Path.h"
34 : #include "llvm/Target/TargetMachine.h"
35 : using namespace clang;
36 : using namespace clang::CodeGen;
37 :
38 39: CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
39 : : CGM(CGM), isMainCompileUnitCreated(false), DebugFactory(CGM.getModule()),
40 39: BlockLiteralGenericSet(false) {
41 39: }
42 :
43 36: CGDebugInfo::~CGDebugInfo() {
36: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
44 36: assert(RegionStack.empty() && "Region stack mismatch, stack not empty!");
45 72: }
46 :
47 747: void CGDebugInfo::setLocation(SourceLocation Loc) {
711: branch 1 taken
36: branch 2 taken
48 747: if (Loc.isValid())
49 711: CurLoc = CGM.getContext().getSourceManager().getInstantiationLoc(Loc);
50 747: }
51 :
52 : /// getContextDescriptor - Get context info for the decl.
53 : llvm::DIDescriptor CGDebugInfo::getContextDescriptor(const Decl *Context,
54 124: llvm::DIDescriptor &CompileUnit) {
0: branch 0 not taken
124: branch 1 taken
55 124: if (!Context)
56 0: return CompileUnit;
57 :
58 : llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator
59 124: I = RegionMap.find(Context);
19: branch 3 taken
105: branch 4 taken
60 124: if (I != RegionMap.end())
61 19: return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(I->second));
62 :
63 : // Check namespace.
14: branch 1 taken
91: branch 2 taken
64 105: if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context))
65 14: return llvm::DIDescriptor(getOrCreateNameSpace(NSDecl, CompileUnit));
66 :
67 91: return CompileUnit;
68 : }
69 :
70 : /// getFunctionName - Get function name for the given FunctionDecl. If the
71 : /// name is constructred on demand (e.g. C++ destructor) then the name
72 : /// is stored on the side.
73 56: llvm::StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) {
0: branch 0 not taken
56: branch 1 taken
74 56: assert (FD && "Invalid FunctionDecl!");
75 56: IdentifierInfo *FII = FD->getIdentifier();
43: branch 0 taken
13: branch 1 taken
76 56: if (FII)
77 43: return FII->getName();
78 :
79 : // Otherwise construct human readable name for debug info.
80 13: std::string NS = FD->getNameAsString();
81 :
82 : // Copy this name on the side and use its reference.
83 13: char *StrPtr = DebugInfoNames.Allocate<char>(NS.length());
84 13: memcpy(StrPtr, NS.data(), NS.length());
85 13: return llvm::StringRef(StrPtr, NS.length());
86 : }
87 :
88 : /// getOrCreateCompileUnit - Get the compile unit from the cache or create a new
89 : /// one if necessary. This returns null for invalid source locations.
90 899: llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) {
91 : // Get source file information.
92 899: const char *FileName = "<unknown>";
93 899: SourceManager &SM = CGM.getContext().getSourceManager();
867: branch 1 taken
32: branch 2 taken
94 899: if (Loc.isValid()) {
95 867: PresumedLoc PLoc = SM.getPresumedLoc(Loc);
96 867: FileName = PLoc.getFilename();
97 867: unsigned FID = PLoc.getIncludeLoc().getRawEncoding();
98 :
99 : // See if this compile unit has been used before for this valid location.
100 867: llvm::DICompileUnit &Unit = CompileUnitCache[FID];
0: branch 1 not taken
867: branch 2 taken
101 867: if (!Unit.isNull()) return Unit;
102 : }
103 :
104 : // Get absolute path name.
105 899: llvm::sys::Path AbsFileName(FileName);
106 899: AbsFileName.makeAbsolute();
107 :
108 : // See if thie compile unit is representing main source file. Each source
109 : // file has corresponding compile unit. There is only one main source
110 : // file at a time.
111 899: bool isMain = false;
112 899: const LangOptions &LO = CGM.getLangOptions();
113 899: const CodeGenOptions &CGO = CGM.getCodeGenOpts();
592: branch 0 taken
307: branch 1 taken
114 899: if (isMainCompileUnitCreated == false) {
3: branch 1 taken
589: branch 2 taken
115 592: if (!CGO.MainFileName.empty()) {
3: branch 3 taken
0: branch 4 not taken
116 3: if (AbsFileName.getLast() == CGO.MainFileName)
117 3: isMain = true;
118 : } else {
583: branch 1 taken
6: branch 2 taken
14: branch 4 taken
569: branch 5 taken
14: branch 6 taken
575: branch 7 taken
119 589: if (Loc.isValid() && SM.isFromMainFile(Loc))
120 14: isMain = true;
121 : }
17: branch 0 taken
575: branch 1 taken
122 592: if (isMain)
123 17: isMainCompileUnitCreated = true;
124 : }
125 :
126 : unsigned LangTag;
71: branch 0 taken
828: branch 1 taken
127 899: if (LO.CPlusPlus) {
0: branch 0 not taken
71: branch 1 taken
128 71: if (LO.ObjC1)
129 0: LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
130 : else
131 71: LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
166: branch 0 taken
662: branch 1 taken
132 828: } else if (LO.ObjC1) {
133 166: LangTag = llvm::dwarf::DW_LANG_ObjC;
662: branch 0 taken
0: branch 1 not taken
134 662: } else if (LO.C99) {
135 662: LangTag = llvm::dwarf::DW_LANG_C99;
136 : } else {
137 0: LangTag = llvm::dwarf::DW_LANG_C89;
138 : }
139 :
140 : const char *Producer =
141 : #ifdef CLANG_VENDOR
142 : CLANG_VENDOR
143 : #endif
144 899: "clang " CLANG_VERSION_STRING;
145 :
146 : // Figure out which version of the ObjC runtime we have.
147 899: unsigned RuntimeVers = 0;
166: branch 0 taken
733: branch 1 taken
148 899: if (LO.ObjC1)
0: branch 0 not taken
166: branch 1 taken
149 166: RuntimeVers = LO.ObjCNonFragileABI ? 2 : 1;
150 :
151 : // Create new compile unit.
152 : return DebugFactory.CreateCompileUnit(
153 : LangTag, AbsFileName.getLast(), AbsFileName.getDirname(), Producer, isMain,
154 899: LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers);
155 : }
156 :
157 : /// CreateType - Get the Basic type from the cache or create a new
158 : /// one if necessary.
159 : llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,
160 65: llvm::DICompileUnit Unit) {
161 65: unsigned Encoding = 0;
30: branch 1 taken
0: branch 2 not taken
5: branch 3 taken
5: branch 4 taken
18: branch 5 taken
0: branch 6 not taken
7: branch 7 taken
162 65: switch (BT->getKind()) {
163 : default:
164 : case BuiltinType::Void:
165 30: return llvm::DIType();
166 : case BuiltinType::UChar:
167 0: case BuiltinType::Char_U: Encoding = llvm::dwarf::DW_ATE_unsigned_char; break;
168 : case BuiltinType::Char_S:
169 5: case BuiltinType::SChar: Encoding = llvm::dwarf::DW_ATE_signed_char; break;
170 : case BuiltinType::UShort:
171 : case BuiltinType::UInt:
172 : case BuiltinType::ULong:
173 5: case BuiltinType::ULongLong: Encoding = llvm::dwarf::DW_ATE_unsigned; break;
174 : case BuiltinType::Short:
175 : case BuiltinType::Int:
176 : case BuiltinType::Long:
177 18: case BuiltinType::LongLong: Encoding = llvm::dwarf::DW_ATE_signed; break;
178 0: case BuiltinType::Bool: Encoding = llvm::dwarf::DW_ATE_boolean; break;
179 : case BuiltinType::Float:
180 : case BuiltinType::LongDouble:
181 7: case BuiltinType::Double: Encoding = llvm::dwarf::DW_ATE_float; break;
182 : }
183 : // Bit size, align and offset of the type.
184 35: uint64_t Size = CGM.getContext().getTypeSize(BT);
185 35: uint64_t Align = CGM.getContext().getTypeAlign(BT);
186 35: uint64_t Offset = 0;
187 :
188 : llvm::DIType DbgTy =
189 : DebugFactory.CreateBasicType(Unit,
190 : BT->getName(CGM.getContext().getLangOptions()),
191 : Unit, 0, Size, Align,
192 35: Offset, /*flags*/ 0, Encoding);
193 35: return DbgTy;
194 : }
195 :
196 : llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty,
197 2: llvm::DICompileUnit Unit) {
198 : // Bit size, align and offset of the type.
199 2: unsigned Encoding = llvm::dwarf::DW_ATE_complex_float;
0: branch 1 not taken
2: branch 2 taken
200 2: if (Ty->isComplexIntegerType())
201 0: Encoding = llvm::dwarf::DW_ATE_lo_user;
202 :
203 2: uint64_t Size = CGM.getContext().getTypeSize(Ty);
204 2: uint64_t Align = CGM.getContext().getTypeAlign(Ty);
205 2: uint64_t Offset = 0;
206 :
207 : llvm::DIType DbgTy =
208 : DebugFactory.CreateBasicType(Unit, "complex",
209 : Unit, 0, Size, Align,
210 2: Offset, /*flags*/ 0, Encoding);
211 : return DbgTy;
212 : }
213 :
214 : /// CreateCVRType - Get the qualified type from the cache or create
215 : /// a new one if necessary.
216 7: llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DICompileUnit Unit) {
217 7: QualifierCollector Qc;
218 7: const Type *T = Qc.strip(Ty);
219 :
220 : // Ignore these qualifiers for now.
221 7: Qc.removeObjCGCAttr();
222 7: Qc.removeAddressSpace();
223 :
224 : // We will create one Derived type for one qualifier and recurse to handle any
225 : // additional ones.
226 : unsigned Tag;
5: branch 1 taken
2: branch 2 taken
227 7: if (Qc.hasConst()) {
228 5: Tag = llvm::dwarf::DW_TAG_const_type;
229 5: Qc.removeConst();
0: branch 1 not taken
2: branch 2 taken
230 2: } else if (Qc.hasVolatile()) {
231 0: Tag = llvm::dwarf::DW_TAG_volatile_type;
232 0: Qc.removeVolatile();
0: branch 1 not taken
2: branch 2 taken
233 2: } else if (Qc.hasRestrict()) {
234 0: Tag = llvm::dwarf::DW_TAG_restrict_type;
235 0: Qc.removeRestrict();
236 : } else {
2: branch 1 taken
0: branch 2 not taken
237 2: assert(Qc.empty() && "Unknown type qualifier for debug info");
238 2: return getOrCreateType(QualType(T, 0), Unit);
239 : }
240 :
241 5: llvm::DIType FromTy = getOrCreateType(Qc.apply(T), Unit);
242 :
243 : // No need to fill in the Name, Line, Size, Alignment, Offset in case of
244 : // CVR derived types.
245 : llvm::DIType DbgTy =
246 : DebugFactory.CreateDerivedType(Tag, Unit, "", llvm::DICompileUnit(),
247 5: 0, 0, 0, 0, 0, FromTy);
248 5: return DbgTy;
249 : }
250 :
251 : llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,
252 23: llvm::DICompileUnit Unit) {
253 : llvm::DIType DbgTy =
254 : CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
255 23: Ty->getPointeeType(), Unit);
256 : return DbgTy;
257 : }
258 :
259 : llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,
260 55: llvm::DICompileUnit Unit) {
261 : return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
262 55: Ty->getPointeeType(), Unit);
263 : }
264 :
265 : llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
266 : const Type *Ty,
267 : QualType PointeeTy,
268 79: llvm::DICompileUnit Unit) {
269 79: llvm::DIType EltTy = getOrCreateType(PointeeTy, Unit);
270 :
271 : // Bit size, align and offset of the type.
272 :
273 : // Size is always the size of a pointer. We can't use getTypeSize here
274 : // because that does not return the correct value for references.
275 : uint64_t Size =
276 79: CGM.getContext().Target.getPointerWidth(PointeeTy.getAddressSpace());
277 79: uint64_t Align = CGM.getContext().getTypeAlign(Ty);
278 :
279 : return
280 : DebugFactory.CreateDerivedType(Tag, Unit, "", llvm::DICompileUnit(),
281 79: 0, Size, Align, 0, 0, EltTy);
282 :
283 : }
284 :
285 : llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
286 1: llvm::DICompileUnit Unit) {
0: branch 0 not taken
1: branch 1 taken
287 1: if (BlockLiteralGenericSet)
288 0: return BlockLiteralGeneric;
289 :
290 1: llvm::DICompileUnit DefUnit;
291 1: unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
292 :
293 1: llvm::SmallVector<llvm::DIDescriptor, 5> EltTys;
294 :
295 1: llvm::DIType FieldTy;
296 :
297 1: QualType FType;
298 : uint64_t FieldSize, FieldOffset;
299 : unsigned FieldAlign;
300 :
301 1: llvm::DIArray Elements;
302 1: llvm::DIType EltTy, DescTy;
303 :
304 1: FieldOffset = 0;
305 1: FType = CGM.getContext().UnsignedLongTy;
306 1: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
307 1: FieldSize = CGM.getContext().getTypeSize(FType);
308 1: FieldAlign = CGM.getContext().getTypeAlign(FType);
309 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
310 : "reserved", DefUnit,
311 : 0, FieldSize, FieldAlign,
312 1: FieldOffset, 0, FieldTy);
313 1: EltTys.push_back(FieldTy);
314 :
315 1: FieldOffset += FieldSize;
316 1: FType = CGM.getContext().UnsignedLongTy;
317 1: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
318 1: FieldSize = CGM.getContext().getTypeSize(FType);
319 1: FieldAlign = CGM.getContext().getTypeAlign(FType);
320 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
321 : "Size", DefUnit,
322 : 0, FieldSize, FieldAlign,
323 1: FieldOffset, 0, FieldTy);
324 1: EltTys.push_back(FieldTy);
325 :
326 1: FieldOffset += FieldSize;
327 1: Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
328 1: EltTys.clear();
329 :
330 1: unsigned Flags = llvm::DIType::FlagAppleBlock;
331 :
332 : EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_descriptor",
333 : DefUnit, 0, FieldOffset, 0, 0, Flags,
334 1: llvm::DIType(), Elements);
335 :
336 : // Bit size, align and offset of the type.
337 1: uint64_t Size = CGM.getContext().getTypeSize(Ty);
338 1: uint64_t Align = CGM.getContext().getTypeAlign(Ty);
339 :
340 : DescTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
341 : Unit, "", llvm::DICompileUnit(),
342 1: 0, Size, Align, 0, 0, EltTy);
343 :
344 1: FieldOffset = 0;
345 1: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
346 1: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
347 1: FieldSize = CGM.getContext().getTypeSize(FType);
348 1: FieldAlign = CGM.getContext().getTypeAlign(FType);
349 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
350 : "__isa", DefUnit,
351 : 0, FieldSize, FieldAlign,
352 1: FieldOffset, 0, FieldTy);
353 1: EltTys.push_back(FieldTy);
354 :
355 1: FieldOffset += FieldSize;
356 1: FType = CGM.getContext().IntTy;
357 1: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
358 1: FieldSize = CGM.getContext().getTypeSize(FType);
359 1: FieldAlign = CGM.getContext().getTypeAlign(FType);
360 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
361 : "__flags", DefUnit,
362 : 0, FieldSize, FieldAlign,
363 1: FieldOffset, 0, FieldTy);
364 1: EltTys.push_back(FieldTy);
365 :
366 1: FieldOffset += FieldSize;
367 1: FType = CGM.getContext().IntTy;
368 1: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
369 1: FieldSize = CGM.getContext().getTypeSize(FType);
370 1: FieldAlign = CGM.getContext().getTypeAlign(FType);
371 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
372 : "__reserved", DefUnit,
373 : 0, FieldSize, FieldAlign,
374 1: FieldOffset, 0, FieldTy);
375 1: EltTys.push_back(FieldTy);
376 :
377 1: FieldOffset += FieldSize;
378 1: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
379 1: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
380 1: FieldSize = CGM.getContext().getTypeSize(FType);
381 1: FieldAlign = CGM.getContext().getTypeAlign(FType);
382 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
383 : "__FuncPtr", DefUnit,
384 : 0, FieldSize, FieldAlign,
385 1: FieldOffset, 0, FieldTy);
386 1: EltTys.push_back(FieldTy);
387 :
388 1: FieldOffset += FieldSize;
389 1: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
390 1: FieldTy = DescTy;
391 1: FieldSize = CGM.getContext().getTypeSize(Ty);
392 1: FieldAlign = CGM.getContext().getTypeAlign(Ty);
393 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
394 : "__descriptor", DefUnit,
395 : 0, FieldSize, FieldAlign,
396 1: FieldOffset, 0, FieldTy);
397 1: EltTys.push_back(FieldTy);
398 :
399 1: FieldOffset += FieldSize;
400 1: Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
401 :
402 : EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_literal_generic",
403 : DefUnit, 0, FieldOffset, 0, 0, Flags,
404 1: llvm::DIType(), Elements);
405 :
406 1: BlockLiteralGenericSet = true;
407 : BlockLiteralGeneric
408 : = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit,
409 : "", llvm::DICompileUnit(),
410 1: 0, Size, Align, 0, 0, EltTy);
411 1: return BlockLiteralGeneric;
412 : }
413 :
414 : llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty,
415 32: llvm::DICompileUnit Unit) {
416 : // Typedefs are derived from some other type. If we have a typedef of a
417 : // typedef, make sure to emit the whole chain.
418 32: llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit);
419 :
420 : // We don't set size information, but do specify where the typedef was
421 : // declared.
422 32: SourceManager &SM = CGM.getContext().getSourceManager();
423 32: PresumedLoc PLoc = SM.getPresumedLoc(Ty->getDecl()->getLocation());
10: branch 1 taken
22: branch 2 taken
424 32: unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine();
425 :
426 : llvm::DIDescriptor TyContext
427 : = getContextDescriptor(dyn_cast<Decl>(Ty->getDecl()->getDeclContext()),
428 32: Unit);
429 : llvm::DIType DbgTy =
430 : DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_typedef,
431 : TyContext,
432 : Ty->getDecl()->getName(), Unit,
433 32: Line, 0, 0, 0, 0, Src);
434 32: return DbgTy;
435 : }
436 :
437 : llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
438 27: llvm::DICompileUnit Unit) {
439 27: llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
440 :
441 : // Add the result type at least.
442 27: EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit));
443 :
444 : // Set up remainder of arguments if there is a prototype.
445 : // FIXME: IF NOT, HOW IS THIS REPRESENTED? llvm-gcc doesn't represent '...'!
27: branch 1 taken
0: branch 2 not taken
446 27: if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(Ty)) {
0: branch 1 not taken
27: branch 2 taken
447 27: for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
448 0: EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit));
449 : } else {
450 : // FIXME: Handle () case in C. llvm-gcc doesn't do it either.
451 : }
452 :
453 : llvm::DIArray EltTypeArray =
454 27: DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
455 :
456 : llvm::DIType DbgTy =
457 : DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
458 : Unit, "", llvm::DICompileUnit(),
459 : 0, 0, 0, 0, 0,
460 27: llvm::DIType(), EltTypeArray);
461 27: return DbgTy;
462 : }
463 :
464 : /// CollectRecordFields - A helper function to collect debug info for
465 : /// record fields. This is used while creating debug info entry for a Record.
466 : void CGDebugInfo::
467 : CollectRecordFields(const RecordDecl *RD, llvm::DICompileUnit Unit,
468 31: llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys) {
469 31: unsigned FieldNo = 0;
470 31: SourceManager &SM = CGM.getContext().getSourceManager();
471 31: const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
60: branch 3 taken
0: branch 4 not taken
60: branch 7 taken
31: branch 8 taken
472 182: for (RecordDecl::field_iterator I = RD->field_begin(),
473 31: E = RD->field_end();
474 : I != E; ++I, ++FieldNo) {
475 60: FieldDecl *Field = *I;
476 60: llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
477 :
478 60: llvm::StringRef FieldName = Field->getName();
479 :
480 : // Ignore unnamed fields.
0: branch 1 not taken
60: branch 2 taken
481 60: if (FieldName.empty())
482 0: continue;
483 :
484 : // Get the location for the field.
485 60: SourceLocation FieldDefLoc = Field->getLocation();
486 60: PresumedLoc PLoc = SM.getPresumedLoc(FieldDefLoc);
487 60: llvm::DICompileUnit FieldDefUnit;
488 60: unsigned FieldLine = 0;
489 :
25: branch 1 taken
35: branch 2 taken
490 60: if (!PLoc.isInvalid()) {
491 25: FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc);
492 25: FieldLine = PLoc.getLine();
493 : }
494 :
495 60: QualType FType = Field->getType();
496 60: uint64_t FieldSize = 0;
497 60: unsigned FieldAlign = 0;
59: branch 2 taken
1: branch 3 taken
498 60: if (!FType->isIncompleteArrayType()) {
499 :
500 : // Bit size, align and offset of the type.
501 59: FieldSize = CGM.getContext().getTypeSize(FType);
502 59: Expr *BitWidth = Field->getBitWidth();
0: branch 0 not taken
59: branch 1 taken
503 59: if (BitWidth)
504 0: FieldSize = BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
505 :
506 59: FieldAlign = CGM.getContext().getTypeAlign(FType);
507 : }
508 :
509 60: uint64_t FieldOffset = RL.getFieldOffset(FieldNo);
510 :
511 : // Create a DW_TAG_member node to remember the offset of this field in the
512 : // struct. FIXME: This is an absolutely insane way to capture this
513 : // information. When we gut debug info, this should be fixed.
514 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
515 : FieldName, FieldDefUnit,
516 : FieldLine, FieldSize, FieldAlign,
517 60: FieldOffset, 0, FieldTy);
518 60: EltTys.push_back(FieldTy);
519 : }
520 31: }
521 :
522 : /// getOrCreateMethodType - CXXMethodDecl's type is a FunctionType. This
523 : /// function type is not updated to include implicit "this" pointer. Use this
524 : /// routine to get a method type which includes "this" pointer.
525 : llvm::DIType
526 : CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
527 6: llvm::DICompileUnit Unit) {
528 6: llvm::DIType FnTy = getOrCreateType(Method->getType(), Unit);
529 :
530 : // Static methods do not need "this" pointer argument.
0: branch 1 not taken
6: branch 2 taken
531 6: if (Method->isStatic())
532 0: return FnTy;
533 :
534 : // Add "this" pointer.
535 :
536 6: llvm::DIArray Args = llvm::DICompositeType(FnTy.getNode()).getTypeArray();
6: branch 1 taken
0: branch 2 not taken
537 6: assert (Args.getNumElements() && "Invalid number of arguments!");
538 :
539 6: llvm::SmallVector<llvm::DIDescriptor, 16> Elts;
540 :
541 : // First element is always return type. For 'void' functions it is NULL.
542 6: Elts.push_back(Args.getElement(0));
543 :
544 : // "this" pointer is always first argument.
545 6: ASTContext &Context = CGM.getContext();
546 : QualType ThisPtr =
547 6: Context.getPointerType(Context.getTagDeclType(Method->getParent()));
548 : llvm::DIType ThisPtrType =
549 6: DebugFactory.CreateArtificialType(getOrCreateType(ThisPtr, Unit));
550 6: TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType.getNode();
551 6: Elts.push_back(ThisPtrType);
552 :
553 : // Copy rest of the arguments.
0: branch 1 not taken
6: branch 2 taken
554 6: for (unsigned i = 1, e = Args.getNumElements(); i != e; ++i)
555 0: Elts.push_back(Args.getElement(i));
556 :
557 : llvm::DIArray EltTypeArray =
558 6: DebugFactory.GetOrCreateArray(Elts.data(), Elts.size());
559 :
560 : return
561 : DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
562 : Unit, "", llvm::DICompileUnit(),
563 : 0, 0, 0, 0, 0,
564 6: llvm::DIType(), EltTypeArray);
565 : }
566 :
567 : /// CreateCXXMemberFunction - A helper function to create a DISubprogram for
568 : /// a single member function GlobalDecl.
569 : llvm::DISubprogram
570 : CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,
571 : llvm::DICompileUnit Unit,
572 6: llvm::DICompositeType &RecordTy) {
573 : bool IsCtorOrDtor =
2: branch 1 taken
4: branch 2 taken
2: branch 4 taken
0: branch 5 not taken
574 6: isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
575 :
576 6: llvm::StringRef MethodName = getFunctionName(Method);
577 6: llvm::StringRef MethodLinkageName;
578 6: llvm::DIType MethodTy = getOrCreateMethodType(Method, Unit);
579 :
580 : // Since a single ctor/dtor corresponds to multiple functions, it doesn't
581 : // make sense to give a single ctor/dtor a linkage name.
0: branch 0 not taken
6: branch 1 taken
582 6: if (!IsCtorOrDtor)
583 0: MethodLinkageName = CGM.getMangledName(Method);
584 :
585 6: SourceManager &SM = CGM.getContext().getSourceManager();
586 :
587 : // Get the location for the method.
588 6: SourceLocation MethodDefLoc = Method->getLocation();
589 6: PresumedLoc PLoc = SM.getPresumedLoc(MethodDefLoc);
590 6: llvm::DICompileUnit MethodDefUnit;
591 6: unsigned MethodLine = 0;
592 :
6: branch 1 taken
0: branch 2 not taken
593 6: if (!PLoc.isInvalid()) {
594 6: MethodDefUnit = getOrCreateCompileUnit(MethodDefLoc);
595 6: MethodLine = PLoc.getLine();
596 : }
597 :
598 : // Collect virtual method info.
599 6: llvm::DIType ContainingType;
600 6: unsigned Virtuality = 0;
601 6: unsigned VIndex = 0;
602 :
1: branch 1 taken
5: branch 2 taken
603 6: if (Method->isVirtual()) {
0: branch 1 not taken
1: branch 2 taken
604 1: if (Method->isPure())
605 0: Virtuality = llvm::dwarf::DW_VIRTUALITY_pure_virtual;
606 : else
607 1: Virtuality = llvm::dwarf::DW_VIRTUALITY_virtual;
608 :
609 : // It doesn't make sense to give a virtual destructor a vtable index,
610 : // since a single destructor has two entries in the vtable.
0: branch 1 not taken
1: branch 2 taken
611 1: if (!isa<CXXDestructorDecl>(Method))
612 0: VIndex = CGM.getVtableInfo().getMethodVtableIndex(Method);
613 1: ContainingType = RecordTy;
614 : }
615 :
616 : llvm::DISubprogram SP =
617 : DebugFactory.CreateSubprogram(RecordTy , MethodName, MethodName,
618 : MethodLinkageName,
619 : MethodDefUnit, MethodLine,
620 : MethodTy, /*isLocalToUnit=*/false,
621 : Method->isThisDeclarationADefinition(),
622 6: Virtuality, VIndex, ContainingType);
623 :
624 : // Don't cache ctors or dtors since we have to emit multiple functions for
625 : // a single ctor or dtor.
0: branch 0 not taken
6: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
6: branch 6 taken
626 6: if (!IsCtorOrDtor && Method->isThisDeclarationADefinition())
627 0: SPCache[Method] = llvm::WeakVH(SP.getNode());
628 :
629 6: return SP;
630 : }
631 :
632 : /// CollectCXXMemberFunctions - A helper function to collect debug info for
633 : /// C++ member functions.This is used while creating debug info entry for
634 : /// a Record.
635 : void CGDebugInfo::
636 : CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
637 : llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
638 8: llvm::DICompositeType &RecordTy) {
32: branch 3 taken
8: branch 4 taken
639 48: for(CXXRecordDecl::method_iterator I = RD->method_begin(),
640 8: E = RD->method_end(); I != E; ++I) {
641 32: const CXXMethodDecl *Method = *I;
642 :
29: branch 1 taken
3: branch 2 taken
26: branch 4 taken
3: branch 5 taken
26: branch 6 taken
6: branch 7 taken
643 32: if (Method->isImplicit() && !Method->isUsed())
644 26: continue;
645 :
646 6: EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));
647 : }
648 8: }
649 :
650 : /// CollectCXXBases - A helper function to collect debug info for
651 : /// C++ base classes. This is used while creating debug info entry for
652 : /// a Record.
653 : void CGDebugInfo::
654 : CollectCXXBases(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
655 : llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
656 8: llvm::DICompositeType &RecordTy) {
657 :
658 8: const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
1: branch 2 taken
8: branch 3 taken
659 17: for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(),
660 8: BE = RD->bases_end(); BI != BE; ++BI) {
661 1: unsigned BFlags = 0;
662 : uint64_t BaseOffset;
663 :
664 : const CXXRecordDecl *Base =
665 1: cast<CXXRecordDecl>(BI->getType()->getAs<RecordType>()->getDecl());
666 :
1: branch 1 taken
0: branch 2 not taken
667 1: if (BI->isVirtual()) {
668 : // virtual base offset index is -ve. The code generator emits dwarf
669 : // expression where it expects +ve number.
670 1: BaseOffset = 0 - CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
671 1: BFlags = llvm::DIType::FlagVirtual;
672 : } else
673 0: BaseOffset = RL.getBaseClassOffset(Base);
674 :
675 1: AccessSpecifier Access = BI->getAccessSpecifier();
0: branch 0 not taken
1: branch 1 taken
676 1: if (Access == clang::AS_private)
677 0: BFlags |= llvm::DIType::FlagPrivate;
0: branch 0 not taken
1: branch 1 taken
678 1: else if (Access == clang::AS_protected)
679 0: BFlags |= llvm::DIType::FlagProtected;
680 :
681 : llvm::DIType DTy =
682 : DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_inheritance,
683 : RecordTy, llvm::StringRef(),
684 : llvm::DICompileUnit(), 0, 0, 0,
685 : BaseOffset, BFlags,
686 : getOrCreateType(BI->getType(),
687 1: Unit));
688 1: EltTys.push_back(DTy);
689 : }
690 8: }
691 :
692 : /// getOrCreateVTablePtrType - Return debug info descriptor for vtable.
693 2: llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DICompileUnit Unit) {
1: branch 1 taken
1: branch 2 taken
694 2: if (!VTablePtrType.isNull())
695 1: return VTablePtrType;
696 :
697 1: ASTContext &Context = CGM.getContext();
698 :
699 : /* Function type */
700 1: llvm::SmallVector<llvm::DIDescriptor, 16> STys;
701 1: STys.push_back(getOrCreateType(Context.IntTy, Unit));
702 : llvm::DIArray SElements =
703 1: DebugFactory.GetOrCreateArray(STys.data(), STys.size());
704 : llvm::DIType SubTy =
705 : DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
706 : Unit, "", llvm::DICompileUnit(),
707 1: 0, 0, 0, 0, 0, llvm::DIType(), SElements);
708 :
709 1: unsigned Size = Context.getTypeSize(Context.VoidPtrTy);
710 : llvm::DIType vtbl_ptr_type
711 : = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
712 : Unit, "__vtbl_ptr_type", llvm::DICompileUnit(),
713 1: 0, Size, 0, 0, 0, SubTy);
714 :
715 : VTablePtrType = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
716 : Unit, "", llvm::DICompileUnit(),
717 1: 0, Size, 0, 0, 0, vtbl_ptr_type);
718 1: return VTablePtrType;
719 : }
720 :
721 : /// getVtableName - Get vtable name for the given Class.
722 2: llvm::StringRef CGDebugInfo::getVtableName(const CXXRecordDecl *RD) {
723 : // Otherwise construct gdb compatible name name.
724 2: std::string Name = "_vptr$" + RD->getNameAsString();
725 :
726 : // Copy this name on the side and use its reference.
727 2: char *StrPtr = DebugInfoNames.Allocate<char>(Name.length());
728 2: memcpy(StrPtr, Name.data(), Name.length());
729 2: return llvm::StringRef(StrPtr, Name.length());
730 : }
731 :
732 :
733 : /// CollectVtableInfo - If the C++ class has vtable info then insert appropriate
734 : /// debug info entry in EltTys vector.
735 : void CGDebugInfo::
736 : CollectVtableInfo(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
737 8: llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys) {
738 8: const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
739 :
740 : // If there is a primary base then it will hold vtable info.
0: branch 1 not taken
8: branch 2 taken
741 8: if (RL.getPrimaryBase())
742 0: return;
743 :
744 : // If this class is not dynamic then there is not any vtable info to collect.
6: branch 1 taken
2: branch 2 taken
745 8: if (!RD->isDynamicClass())
746 6: return;
747 :
748 2: unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
749 : llvm::DIType VPTR
750 : = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
751 : getVtableName(RD), llvm::DICompileUnit(),
752 : 0, Size, 0, 0, 0,
753 2: getOrCreateVTablePtrType(Unit));
754 2: EltTys.push_back(VPTR);
755 : }
756 :
757 : /// CreateType - get structure or union type.
758 : llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
759 34: llvm::DICompileUnit Unit) {
760 34: RecordDecl *RD = Ty->getDecl();
761 :
762 : unsigned Tag;
34: branch 1 taken
0: branch 2 not taken
763 34: if (RD->isStruct())
764 34: Tag = llvm::dwarf::DW_TAG_structure_type;
0: branch 1 not taken
0: branch 2 not taken
765 0: else if (RD->isUnion())
766 0: Tag = llvm::dwarf::DW_TAG_union_type;
767 : else {
0: branch 1 not taken
0: branch 2 not taken
768 0: assert(RD->isClass() && "Unknown RecordType!");
769 0: Tag = llvm::dwarf::DW_TAG_class_type;
770 : }
771 :
772 34: SourceManager &SM = CGM.getContext().getSourceManager();
773 :
774 : // Get overall information about the record type for the debug info.
775 34: PresumedLoc PLoc = SM.getPresumedLoc(RD->getLocation());
776 34: llvm::DICompileUnit DefUnit;
777 34: unsigned Line = 0;
26: branch 1 taken
8: branch 2 taken
778 34: if (!PLoc.isInvalid()) {
779 26: DefUnit = getOrCreateCompileUnit(RD->getLocation());
780 26: Line = PLoc.getLine();
781 : }
782 :
783 : // Records and classes and unions can all be recursive. To handle them, we
784 : // first generate a debug descriptor for the struct as a forward declaration.
785 : // Then (if it is a definition) we go through and get debug info for all of
786 : // its members. Finally, we create a descriptor for the complete type (which
787 : // may refer to the forward decl if the struct is recursive) and replace all
788 : // uses of the forward declaration with the final definition.
789 :
790 : // A RD->getName() is not unique. However, the debug info descriptors
791 : // are uniqued so use type name to ensure uniquness.
792 34: std::string STy = QualType(Ty, 0).getAsString();
793 : llvm::DIDescriptor FDContext =
794 34: getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()), Unit);
795 : llvm::DICompositeType FwdDecl =
796 : DebugFactory.CreateCompositeType(Tag, FDContext,
797 : STy.c_str(),
798 : DefUnit, Line, 0, 0, 0, 0,
799 34: llvm::DIType(), llvm::DIArray());
800 :
801 : // If this is just a forward declaration, return it.
3: branch 2 taken
31: branch 3 taken
802 34: if (!RD->getDefinition(CGM.getContext()))
803 3: return FwdDecl;
804 :
805 31: llvm::TrackingVH<llvm::MDNode> FwdDeclNode = FwdDecl.getNode();
806 : // Otherwise, insert it into the TypeCache so that recursive uses will find
807 : // it.
808 31: TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl.getNode();
809 :
810 : // Convert all the elements.
811 31: llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
812 :
813 31: const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
8: branch 0 taken
23: branch 1 taken
814 31: if (CXXDecl) {
815 8: CollectCXXBases(CXXDecl, Unit, EltTys, FwdDecl);
816 8: CollectVtableInfo(CXXDecl, Unit, EltTys);
817 : }
818 31: CollectRecordFields(RD, Unit, EltTys);
819 31: llvm::MDNode *ContainingType = NULL;
8: branch 0 taken
23: branch 1 taken
820 31: if (CXXDecl) {
821 8: CollectCXXMemberFunctions(CXXDecl, Unit, EltTys, FwdDecl);
822 :
823 : // A class's primary base or the class itself contains the vtable.
824 8: const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
0: branch 1 not taken
8: branch 2 taken
825 8: if (const CXXRecordDecl *PBase = RL.getPrimaryBase())
826 : ContainingType =
827 0: getOrCreateType(QualType(PBase->getTypeForDecl(), 0), Unit).getNode();
2: branch 1 taken
6: branch 2 taken
828 8: else if (CXXDecl->isDynamicClass())
829 2: ContainingType = FwdDecl.getNode();
830 : }
831 :
832 : llvm::DIArray Elements =
833 31: DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
834 :
835 : // Bit size, align and offset of the type.
836 31: uint64_t Size = CGM.getContext().getTypeSize(Ty);
837 31: uint64_t Align = CGM.getContext().getTypeAlign(Ty);
838 :
839 : llvm::DIDescriptor RDContext =
840 31: getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()), Unit);
841 : llvm::DICompositeType RealDecl =
842 : DebugFactory.CreateCompositeType(Tag, RDContext,
843 : RD->getName(),
844 : DefUnit, Line, Size, Align, 0, 0,
845 : llvm::DIType(), Elements,
846 31: 0, ContainingType);
847 :
848 : // Now that we have a real decl for the struct, replace anything using the
849 : // old decl with the new one. This will recursively update the debug info.
850 31: llvm::DIDerivedType(FwdDeclNode).replaceAllUsesWith(RealDecl);
851 :
852 31: return RealDecl;
853 : }
854 :
855 : /// CreateType - get objective-c interface type.
856 : llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
857 16: llvm::DICompileUnit Unit) {
858 16: ObjCInterfaceDecl *ID = Ty->getDecl();
859 :
860 16: unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
861 16: SourceManager &SM = CGM.getContext().getSourceManager();
862 :
863 : // Get overall information about the record type for the debug info.
864 16: llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(ID->getLocation());
865 16: PresumedLoc PLoc = SM.getPresumedLoc(ID->getLocation());
0: branch 1 not taken
16: branch 2 taken
866 16: unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine();
867 :
868 :
869 16: unsigned RuntimeLang = DefUnit.getLanguage();
870 :
871 : // To handle recursive interface, we
872 : // first generate a debug descriptor for the struct as a forward declaration.
873 : // Then (if it is a definition) we go through and get debug info for all of
874 : // its members. Finally, we create a descriptor for the complete type (which
875 : // may refer to the forward decl if the struct is recursive) and replace all
876 : // uses of the forward declaration with the final definition.
877 : llvm::DICompositeType FwdDecl =
878 : DebugFactory.CreateCompositeType(Tag, Unit, ID->getName(),
879 : DefUnit, Line, 0, 0, 0, 0,
880 : llvm::DIType(), llvm::DIArray(),
881 16: RuntimeLang);
882 :
883 : // If this is just a forward declaration, return it.
3: branch 1 taken
13: branch 2 taken
884 16: if (ID->isForwardDecl())
885 3: return FwdDecl;
886 :
887 13: llvm::TrackingVH<llvm::MDNode> FwdDeclNode = FwdDecl.getNode();
888 : // Otherwise, insert it into the TypeCache so that recursive uses will find
889 : // it.
890 13: TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl.getNode();
891 :
892 : // Convert all the elements.
893 13: llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
894 :
895 13: ObjCInterfaceDecl *SClass = ID->getSuperClass();
2: branch 0 taken
11: branch 1 taken
896 13: if (SClass) {
897 : llvm::DIType SClassTy =
898 2: getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
899 : llvm::DIType InhTag =
900 : DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_inheritance,
901 : Unit, "", llvm::DICompileUnit(), 0, 0, 0,
902 2: 0 /* offset */, 0, SClassTy);
903 2: EltTys.push_back(InhTag);
904 : }
905 :
906 13: const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);
907 :
908 13: unsigned FieldNo = 0;
7: branch 3 taken
0: branch 4 not taken
7: branch 5 taken
13: branch 6 taken
909 40: for (ObjCInterfaceDecl::ivar_iterator I = ID->ivar_begin(),
910 13: E = ID->ivar_end(); I != E; ++I, ++FieldNo) {
911 7: ObjCIvarDecl *Field = *I;
912 7: llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
913 :
914 7: llvm::StringRef FieldName = Field->getName();
915 :
916 : // Ignore unnamed fields.
0: branch 1 not taken
7: branch 2 taken
917 7: if (FieldName.empty())
918 0: continue;
919 :
920 : // Get the location for the field.
921 7: SourceLocation FieldDefLoc = Field->getLocation();
922 7: llvm::DICompileUnit FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc);
923 7: PresumedLoc PLoc = SM.getPresumedLoc(FieldDefLoc);
0: branch 1 not taken
7: branch 2 taken
924 7: unsigned FieldLine = PLoc.isInvalid() ? 0 : PLoc.getLine();
925 :
926 :
927 7: QualType FType = Field->getType();
928 7: uint64_t FieldSize = 0;
929 7: unsigned FieldAlign = 0;
930 :
7: branch 2 taken
0: branch 3 not taken
931 7: if (!FType->isIncompleteArrayType()) {
932 :
933 : // Bit size, align and offset of the type.
934 7: FieldSize = CGM.getContext().getTypeSize(FType);
935 7: Expr *BitWidth = Field->getBitWidth();
0: branch 0 not taken
7: branch 1 taken
936 7: if (BitWidth)
937 0: FieldSize = BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
938 :
939 7: FieldAlign = CGM.getContext().getTypeAlign(FType);
940 : }
941 :
942 7: uint64_t FieldOffset = RL.getFieldOffset(FieldNo);
943 :
944 7: unsigned Flags = 0;
5: branch 1 taken
2: branch 2 taken
945 7: if (Field->getAccessControl() == ObjCIvarDecl::Protected)
946 5: Flags = llvm::DIType::FlagProtected;
0: branch 1 not taken
2: branch 2 taken
947 2: else if (Field->getAccessControl() == ObjCIvarDecl::Private)
948 0: Flags = llvm::DIType::FlagPrivate;
949 :
950 : // Create a DW_TAG_member node to remember the offset of this field in the
951 : // struct. FIXME: This is an absolutely insane way to capture this
952 : // information. When we gut debug info, this should be fixed.
953 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
954 : FieldName, FieldDefUnit,
955 : FieldLine, FieldSize, FieldAlign,
956 7: FieldOffset, Flags, FieldTy);
957 7: EltTys.push_back(FieldTy);
958 : }
959 :
960 : llvm::DIArray Elements =
961 13: DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
962 :
963 : // Bit size, align and offset of the type.
964 13: uint64_t Size = CGM.getContext().getTypeSize(Ty);
965 13: uint64_t Align = CGM.getContext().getTypeAlign(Ty);
966 :
967 : llvm::DICompositeType RealDecl =
968 : DebugFactory.CreateCompositeType(Tag, Unit, ID->getName(), DefUnit,
969 : Line, Size, Align, 0, 0, llvm::DIType(),
970 13: Elements, RuntimeLang);
971 :
972 : // Now that we have a real decl for the struct, replace anything using the
973 : // old decl with the new one. This will recursively update the debug info.
974 13: llvm::DIDerivedType(FwdDeclNode).replaceAllUsesWith(RealDecl);
975 :
976 13: return RealDecl;
977 : }
978 :
979 : llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
980 1: llvm::DICompileUnit Unit) {
981 1: EnumDecl *ED = Ty->getDecl();
982 :
983 1: llvm::SmallVector<llvm::DIDescriptor, 32> Enumerators;
984 :
985 : // Create DIEnumerator elements for each enumerator.
0: branch 2 not taken
1: branch 3 taken
986 1: for (EnumDecl::enumerator_iterator
987 1: Enum = ED->enumerator_begin(), EnumEnd = ED->enumerator_end();
988 : Enum != EnumEnd; ++Enum) {
989 : Enumerators.push_back(DebugFactory.CreateEnumerator(Enum->getName(),
990 0: Enum->getInitVal().getZExtValue()));
991 : }
992 :
993 : // Return a CompositeType for the enum itself.
994 : llvm::DIArray EltArray =
995 1: DebugFactory.GetOrCreateArray(Enumerators.data(), Enumerators.size());
996 :
997 1: SourceLocation DefLoc = ED->getLocation();
998 1: llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc);
999 1: SourceManager &SM = CGM.getContext().getSourceManager();
1000 1: PresumedLoc PLoc = SM.getPresumedLoc(DefLoc);
0: branch 1 not taken
1: branch 2 taken
1001 1: unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine();
1002 :
1003 :
1004 : // Size and align of the type.
1005 1: uint64_t Size = 0;
1006 1: unsigned Align = 0;
0: branch 1 not taken
1: branch 2 taken
1007 1: if (!Ty->isIncompleteType()) {
1008 0: Size = CGM.getContext().getTypeSize(Ty);
1009 0: Align = CGM.getContext().getTypeAlign(Ty);
1010 : }
1011 :
1012 : llvm::DIType DbgTy =
1013 : DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_enumeration_type,
1014 : Unit, ED->getName(), DefUnit, Line,
1015 : Size, Align, 0, 0,
1016 1: llvm::DIType(), EltArray);
1017 1: return DbgTy;
1018 : }
1019 :
1020 : llvm::DIType CGDebugInfo::CreateType(const TagType *Ty,
1021 35: llvm::DICompileUnit Unit) {
34: branch 1 taken
1: branch 2 taken
1022 35: if (const RecordType *RT = dyn_cast<RecordType>(Ty))
1023 34: return CreateType(RT, Unit);
1: branch 1 taken
0: branch 2 not taken
1024 1: else if (const EnumType *ET = dyn_cast<EnumType>(Ty))
1025 1: return CreateType(ET, Unit);
1026 :
1027 0: return llvm::DIType();
1028 : }
1029 :
1030 : llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
1031 12: llvm::DICompileUnit Unit) {
1032 : uint64_t Size;
1033 : uint64_t Align;
1034 :
1035 :
1036 : // FIXME: make getTypeAlign() aware of VLAs and incomplete array types
0: branch 1 not taken
12: branch 2 taken
1037 12: if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(Ty)) {
1038 0: Size = 0;
1039 : Align =
1040 0: CGM.getContext().getTypeAlign(CGM.getContext().getBaseElementType(VAT));
1: branch 1 taken
11: branch 2 taken
1041 12: } else if (Ty->isIncompleteArrayType()) {
1042 1: Size = 0;
1043 1: Align = CGM.getContext().getTypeAlign(Ty->getElementType());
1044 : } else {
1045 : // Size and align of the whole array, not the element type.
1046 11: Size = CGM.getContext().getTypeSize(Ty);
1047 11: Align = CGM.getContext().getTypeAlign(Ty);
1048 : }
1049 :
1050 : // Add the dimensions of the array. FIXME: This loses CV qualifiers from
1051 : // interior arrays, do we care? Why aren't nested arrays represented the
1052 : // obvious/recursive way?
1053 12: llvm::SmallVector<llvm::DIDescriptor, 8> Subscripts;
1054 12: QualType EltTy(Ty, 0);
12: branch 1 taken
12: branch 2 taken
1055 36: while ((Ty = dyn_cast<ArrayType>(EltTy))) {
1056 12: uint64_t Upper = 0;
11: branch 1 taken
1: branch 2 taken
1057 12: if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))
11: branch 2 taken
0: branch 3 not taken
1058 11: if (CAT->getSize().getZExtValue())
1059 11: Upper = CAT->getSize().getZExtValue() - 1;
1060 : // FIXME: Verify this is right for VLAs.
1061 12: Subscripts.push_back(DebugFactory.GetOrCreateSubrange(0, Upper));
1062 12: EltTy = Ty->getElementType();
1063 : }
1064 :
1065 : llvm::DIArray SubscriptArray =
1066 12: DebugFactory.GetOrCreateArray(Subscripts.data(), Subscripts.size());
1067 :
1068 : llvm::DIType DbgTy =
1069 : DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_array_type,
1070 : Unit, "", llvm::DICompileUnit(),
1071 : 0, Size, Align, 0, 0,
1072 : getOrCreateType(EltTy, Unit),
1073 12: SubscriptArray);
1074 12: return DbgTy;
1075 : }
1076 :
1077 : llvm::DIType CGDebugInfo::CreateType(const LValueReferenceType *Ty,
1078 1: llvm::DICompileUnit Unit) {
1079 : return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type,
1080 1: Ty, Ty->getPointeeType(), Unit);
1081 : }
1082 :
1083 : llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty,
1084 2: llvm::DICompileUnit U) {
1085 2: QualType PointerDiffTy = CGM.getContext().getPointerDiffType();
1086 2: llvm::DIType PointerDiffDITy = getOrCreateType(PointerDiffTy, U);
1087 :
1: branch 3 taken
1: branch 4 taken
1088 2: if (!Ty->getPointeeType()->isFunctionType()) {
1089 : // We have a data member pointer type.
1090 1: return PointerDiffDITy;
1091 : }
1092 :
1093 : // We have a member function pointer type. Treat it as a struct with two
1094 : // ptrdiff_t members.
1095 1: std::pair<uint64_t, unsigned> Info = CGM.getContext().getTypeInfo(Ty);
1096 :
1097 1: uint64_t FieldOffset = 0;
2: branch 1 taken
1: branch 2 taken
1098 1: llvm::DIDescriptor ElementTypes[2];
1099 :
1100 : // FIXME: This should probably be a function type instead.
1101 : ElementTypes[0] =
1102 : DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, U,
1103 : "ptr", llvm::DICompileUnit(), 0,
1104 : Info.first, Info.second, FieldOffset, 0,
1105 1: PointerDiffDITy);
1106 1: FieldOffset += Info.first;
1107 :
1108 : ElementTypes[1] =
1109 : DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, U,
1110 : "ptr", llvm::DICompileUnit(), 0,
1111 : Info.first, Info.second, FieldOffset, 0,
1112 1: PointerDiffDITy);
1113 :
1114 : llvm::DIArray Elements =
1115 : DebugFactory.GetOrCreateArray(&ElementTypes[0],
1116 1: llvm::array_lengthof(ElementTypes));
1117 :
1118 : return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_structure_type,
1119 : U, llvm::StringRef("test"),
1120 : llvm::DICompileUnit(), 0, FieldOffset,
1121 1: 0, 0, 0, llvm::DIType(), Elements);
1122 : }
1123 :
1124 554: static QualType UnwrapTypeForDebugInfo(QualType T) {
1125 7: do {
1126 554: QualType LastT = T;
547: branch 2 taken
3: branch 3 taken
1: branch 4 taken
0: branch 5 not taken
0: branch 6 not taken
1: branch 7 taken
1: branch 8 taken
1: branch 9 taken
1127 554: switch (T->getTypeClass()) {
1128 : default:
1129 547: return T;
1130 : case Type::TemplateSpecialization:
1131 3: T = cast<TemplateSpecializationType>(T)->desugar();
1132 3: break;
1133 : case Type::TypeOfExpr: {
1134 1: TypeOfExprType *Ty = cast<TypeOfExprType>(T);
1135 1: T = Ty->getUnderlyingExpr()->getType();
1136 1: break;
1137 : }
1138 : case Type::TypeOf:
1139 0: T = cast<TypeOfType>(T)->getUnderlyingType();
1140 0: break;
1141 : case Type::Decltype:
1142 0: T = cast<DecltypeType>(T)->getUnderlyingType();
1143 0: break;
1144 : case Type::QualifiedName:
1145 1: T = cast<QualifiedNameType>(T)->getNamedType();
1146 1: break;
1147 : case Type::SubstTemplateTypeParm:
1148 1: T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
1149 1: break;
1150 : case Type::Elaborated:
1151 1: T = cast<ElaboratedType>(T)->getUnderlyingType();
1152 : break;
1153 : }
1154 :
7: branch 1 taken
0: branch 2 not taken
1155 7: assert(T != LastT && "Type unwrapping failed to unwrap!");
0: branch 1 not taken
7: branch 2 taken
1156 7: if (T == LastT)
1157 0: return T;
1158 : } while (true);
1159 :
1160 : return T;
1161 : }
1162 :
1163 : /// getOrCreateType - Get the type from the cache or create a new
1164 : /// one if necessary.
1165 : llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
1166 547: llvm::DICompileUnit Unit) {
0: branch 1 not taken
547: branch 2 taken
1167 547: if (Ty.isNull())
1168 0: return llvm::DIType();
1169 :
1170 : // Unwrap the type as needed for debug information.
1171 547: Ty = UnwrapTypeForDebugInfo(Ty);
1172 :
1173 : // Check for existing entry.
1174 : std::map<void *, llvm::WeakVH>::iterator it =
1175 547: TypeCache.find(Ty.getAsOpaquePtr());
269: branch 2 taken
278: branch 3 taken
1176 547: if (it != TypeCache.end()) {
1177 : // Verify that the debug info still exists.
263: branch 2 taken
6: branch 3 taken
1178 269: if (&*it->second)
1179 263: return llvm::DIType(cast<llvm::MDNode>(it->second));
1180 : }
1181 :
1182 : // Otherwise create the type.
1183 284: llvm::DIType Res = CreateTypeNode(Ty, Unit);
1184 :
1185 : // And update the type cache.
1186 284: TypeCache[Ty.getAsOpaquePtr()] = Res.getNode();
1187 284: return Res;
1188 : }
1189 :
1190 : /// CreateTypeNode - Create a new debug type node.
1191 : llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty,
1192 284: llvm::DICompileUnit Unit) {
1193 : // Handle qualifiers, which recursively handles what they refer to.
7: branch 1 taken
277: branch 2 taken
1194 284: if (Ty.hasLocalQualifiers())
1195 7: return CreateQualifiedType(Ty, Unit);
1196 :
1197 277: const char *Diag = 0;
1198 :
1199 : // Work out details of type.
0: branch 2 not taken
6: branch 3 taken
23: branch 4 taken
16: branch 5 taken
65: branch 6 taken
2: branch 7 taken
55: branch 8 taken
1: branch 9 taken
32: branch 10 taken
35: branch 11 taken
27: branch 12 taken
12: branch 13 taken
1: branch 14 taken
2: branch 15 taken
0: branch 16 not taken
0: branch 17 not taken
0: branch 18 not taken
1200 277: switch (Ty->getTypeClass()) {
1201 : #define TYPE(Class, Base)
1202 : #define ABSTRACT_TYPE(Class, Base)
1203 : #define NON_CANONICAL_TYPE(Class, Base)
1204 : #define DEPENDENT_TYPE(Class, Base) case Type::Class:
1205 : #include "clang/AST/TypeNodes.def"
1206 0: assert(false && "Dependent types cannot show up in debug information");
1207 :
1208 : // FIXME: Handle these.
1209 : case Type::ExtVector:
1210 : case Type::Vector:
1211 6: return llvm::DIType();
1212 :
1213 : case Type::ObjCObjectPointer:
1214 23: return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
1215 : case Type::ObjCInterface:
1216 16: return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
1217 65: case Type::Builtin: return CreateType(cast<BuiltinType>(Ty), Unit);
1218 2: case Type::Complex: return CreateType(cast<ComplexType>(Ty), Unit);
1219 55: case Type::Pointer: return CreateType(cast<PointerType>(Ty), Unit);
1220 : case Type::BlockPointer:
1221 1: return CreateType(cast<BlockPointerType>(Ty), Unit);
1222 32: case Type::Typedef: return CreateType(cast<TypedefType>(Ty), Unit);
1223 : case Type::Record:
1224 : case Type::Enum:
1225 35: return CreateType(cast<TagType>(Ty), Unit);
1226 : case Type::FunctionProto:
1227 : case Type::FunctionNoProto:
1228 27: return CreateType(cast<FunctionType>(Ty), Unit);
1229 : case Type::ConstantArray:
1230 : case Type::VariableArray:
1231 : case Type::IncompleteArray:
1232 12: return CreateType(cast<ArrayType>(Ty), Unit);
1233 :
1234 : case Type::LValueReference:
1235 1: return CreateType(cast<LValueReferenceType>(Ty), Unit);
1236 :
1237 : case Type::MemberPointer:
1238 2: return CreateType(cast<MemberPointerType>(Ty), Unit);
1239 :
1240 : case Type::TemplateSpecialization:
1241 : case Type::Elaborated:
1242 : case Type::QualifiedName:
1243 : case Type::SubstTemplateTypeParm:
1244 : case Type::TypeOfExpr:
1245 : case Type::TypeOf:
1246 : case Type::Decltype:
1247 0: llvm_unreachable("type should have been unwrapped!");
1248 : return llvm::DIType();
1249 :
1250 : case Type::RValueReference:
1251 : // FIXME: Implement!
1252 0: Diag = "rvalue references";
1253 : break;
1254 : }
1255 :
0: branch 0 not taken
0: branch 1 not taken
1256 0: assert(Diag && "Fall through without a diagnostic?");
1257 : unsigned DiagID = CGM.getDiags().getCustomDiagID(Diagnostic::Error,
1258 0: "debug information for %0 is not yet supported");
1259 : CGM.getDiags().Report(FullSourceLoc(), DiagID)
1260 0: << Diag;
1261 0: return llvm::DIType();
1262 : }
1263 :
1264 : /// EmitFunctionStart - Constructs the debug code for entering a function -
1265 : /// "llvm.dbg.func.start.".
1266 : void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
1267 : llvm::Function *Fn,
1268 64: CGBuilderTy &Builder) {
1269 :
1270 64: llvm::StringRef Name;
1271 64: llvm::StringRef LinkageName;
1272 :
1273 64: const Decl *D = GD.getDecl();
50: branch 1 taken
14: branch 2 taken
1274 64: if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1275 : // If there is a DISubprogram for this function available then use it.
1276 : llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
1277 50: FI = SPCache.find(FD);
0: branch 3 not taken
50: branch 4 taken
1278 50: if (FI != SPCache.end()) {
1279 0: llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(FI->second));
0: branch 1 not taken
0: branch 2 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 9 not taken
0: branch 10 not taken
1280 0: if (!SP.isNull() && SP.isSubprogram() && SP.isDefinition()) {
1281 0: RegionStack.push_back(SP.getNode());
1282 0: RegionMap[D] = llvm::WeakVH(SP.getNode());
1283 0: return;
0: branch 1 not taken
0: branch 2 not taken
1284 0: }
1285 : }
1286 50: Name = getFunctionName(FD);
49: branch 1 taken
1: branch 2 taken
0: branch 4 not taken
49: branch 5 taken
0: branch 6 not taken
50: branch 7 taken
1287 50: if (!Name.empty() && Name[0] == '\01')
1288 0: Name = Name.substr(1);
1289 : // Use mangled name as linkage name for c/c++ functions.
1290 50: LinkageName = CGM.getMangledName(GD);
1291 : } else {
1292 : // Use llvm function name as linkage name.
1293 14: Name = Fn->getName();
1294 14: LinkageName = Name;
14: branch 1 taken
0: branch 2 not taken
10: branch 4 taken
4: branch 5 taken
10: branch 6 taken
4: branch 7 taken
1295 14: if (!Name.empty() && Name[0] == '\01')
1296 10: Name = Name.substr(1);
1297 : }
1298 :
1299 : // It is expected that CurLoc is set before using EmitFunctionStart.
1300 : // Usually, CurLoc points to the left bracket location of compound
1301 : // statement representing function body.
1302 64: llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc);
1303 64: SourceManager &SM = CGM.getContext().getSourceManager();
1304 64: unsigned LineNo = SM.getPresumedLoc(CurLoc).getLine();
1305 :
1306 : llvm::DISubprogram SP =
1307 : DebugFactory.CreateSubprogram(Unit, Name, Name, LinkageName, Unit, LineNo,
1308 : getOrCreateType(FnType, Unit),
1309 64: Fn->hasInternalLinkage(), true/*definition*/);
1310 :
1311 : // Push function on region stack.
1312 64: RegionStack.push_back(SP.getNode());
1313 64: RegionMap[D] = llvm::WeakVH(SP.getNode());
1314 : }
1315 :
1316 :
1317 366: void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) {
366: branch 1 taken
0: branch 2 not taken
0: branch 4 not taken
366: branch 5 taken
366: branch 6 taken
0: branch 7 not taken
1318 366: if (CurLoc.isInvalid() || CurLoc.isMacroID()) return;
1319 :
1320 : // Don't bother if things are the same as last time.
1321 366: SourceManager &SM = CGM.getContext().getSourceManager();
361: branch 1 taken
5: branch 2 taken
51: branch 5 taken
310: branch 6 taken
51: branch 8 taken
0: branch 9 not taken
56: branch 10 taken
310: branch 11 taken
1322 366: if (CurLoc == PrevLoc
1323 : || (SM.getInstantiationLineNumber(CurLoc) ==
1324 : SM.getInstantiationLineNumber(PrevLoc)
1325 : && SM.isFromSameFile(CurLoc, PrevLoc)))
1326 56: return;
1327 :
1328 : // Update last state.
1329 310: PrevLoc = CurLoc;
1330 :
1331 : // Get the appropriate compile unit.
1332 310: llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc);
1333 310: PresumedLoc PLoc = SM.getPresumedLoc(CurLoc);
1334 :
1335 310: llvm::DIDescriptor DR(RegionStack.back());
1336 310: llvm::DIScope DS = llvm::DIScope(DR.getNode());
1337 310: llvm::DILocation DO(NULL);
1338 : llvm::DILocation DL =
1339 : DebugFactory.CreateLocation(PLoc.getLine(), PLoc.getColumn(),
1340 310: DS, DO);
1341 310: Builder.SetCurrentDebugLocation(DL.getNode());
1342 : }
1343 :
1344 : /// EmitRegionStart- Constructs the debug code for entering a declarative
1345 : /// region - "llvm.dbg.region.start.".
1346 82: void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, CGBuilderTy &Builder) {
1347 : llvm::DIDescriptor D =
1348 : DebugFactory.CreateLexicalBlock(RegionStack.empty() ?
1349 : llvm::DIDescriptor() :
0: branch 1 not taken
82: branch 2 taken
1350 82: llvm::DIDescriptor(RegionStack.back()));
1351 82: RegionStack.push_back(D.getNode());
1352 82: }
1353 :
1354 : /// EmitRegionEnd - Constructs the debug code for exiting a declarative
1355 : /// region - "llvm.dbg.region.end."
1356 146: void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, CGBuilderTy &Builder) {
146: branch 1 taken
0: branch 2 not taken
1357 146: assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
1358 :
1359 : // Provide an region stop point.
1360 146: EmitStopPoint(Fn, Builder);
1361 :
1362 146: RegionStack.pop_back();
1363 146: }
1364 :
1365 : /// EmitDeclare - Emit local variable declaration debug info.
1366 : void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,
1367 209: llvm::Value *Storage, CGBuilderTy &Builder) {
209: branch 1 taken
0: branch 2 not taken
1368 209: assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
1369 :
1370 : // Do not emit variable debug information while generating optimized code.
1371 : // The llvm optimizer and code generator are not yet ready to support
1372 : // optimized code debugging.
1373 209: const CodeGenOptions &CGO = CGM.getCodeGenOpts();
0: branch 0 not taken
209: branch 1 taken
1374 209: if (CGO.OptimizationLevel)
1375 0: return;
1376 :
1377 209: llvm::DICompileUnit Unit = getOrCreateCompileUnit(VD->getLocation());
1378 209: QualType Type = VD->getType();
1379 209: llvm::DIType Ty = getOrCreateType(Type, Unit);
0: branch 1 not taken
209: branch 2 taken
1380 209: if (VD->hasAttr<BlocksAttr>()) {
1381 0: llvm::DICompileUnit DefUnit;
1382 0: unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
1383 :
1384 0: llvm::SmallVector<llvm::DIDescriptor, 5> EltTys;
1385 :
1386 0: llvm::DIType FieldTy;
1387 :
1388 0: QualType FType;
1389 : uint64_t FieldSize, FieldOffset;
1390 : unsigned FieldAlign;
1391 :
1392 0: llvm::DIArray Elements;
1393 0: llvm::DIType EltTy;
1394 :
1395 : // Build up structure for the byref. See BuildByRefType.
1396 0: FieldOffset = 0;
1397 0: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1398 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1399 0: FieldSize = CGM.getContext().getTypeSize(FType);
1400 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1401 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1402 : "__isa", DefUnit,
1403 : 0, FieldSize, FieldAlign,
1404 0: FieldOffset, 0, FieldTy);
1405 0: EltTys.push_back(FieldTy);
1406 0: FieldOffset += FieldSize;
1407 :
1408 0: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1409 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1410 0: FieldSize = CGM.getContext().getTypeSize(FType);
1411 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1412 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1413 : "__forwarding", DefUnit,
1414 : 0, FieldSize, FieldAlign,
1415 0: FieldOffset, 0, FieldTy);
1416 0: EltTys.push_back(FieldTy);
1417 0: FieldOffset += FieldSize;
1418 :
1419 0: FType = CGM.getContext().IntTy;
1420 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1421 0: FieldSize = CGM.getContext().getTypeSize(FType);
1422 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1423 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1424 : "__flags", DefUnit,
1425 : 0, FieldSize, FieldAlign,
1426 0: FieldOffset, 0, FieldTy);
1427 0: EltTys.push_back(FieldTy);
1428 0: FieldOffset += FieldSize;
1429 :
1430 0: FType = CGM.getContext().IntTy;
1431 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1432 0: FieldSize = CGM.getContext().getTypeSize(FType);
1433 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1434 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1435 : "__size", DefUnit,
1436 : 0, FieldSize, FieldAlign,
1437 0: FieldOffset, 0, FieldTy);
1438 0: EltTys.push_back(FieldTy);
1439 0: FieldOffset += FieldSize;
1440 :
1441 0: bool HasCopyAndDispose = CGM.BlockRequiresCopying(Type);
0: branch 0 not taken
0: branch 1 not taken
1442 0: if (HasCopyAndDispose) {
1443 0: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1444 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1445 0: FieldSize = CGM.getContext().getTypeSize(FType);
1446 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1447 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1448 : "__copy_helper", DefUnit,
1449 : 0, FieldSize, FieldAlign,
1450 0: FieldOffset, 0, FieldTy);
1451 0: EltTys.push_back(FieldTy);
1452 0: FieldOffset += FieldSize;
1453 :
1454 0: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1455 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1456 0: FieldSize = CGM.getContext().getTypeSize(FType);
1457 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1458 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1459 : "__destroy_helper", DefUnit,
1460 : 0, FieldSize, FieldAlign,
1461 0: FieldOffset, 0, FieldTy);
1462 0: EltTys.push_back(FieldTy);
1463 0: FieldOffset += FieldSize;
1464 : }
1465 :
1466 0: CharUnits Align = CGM.getContext().getDeclAlign(VD);
0: branch 4 not taken
0: branch 5 not taken
1467 0: if (Align > CharUnits::fromQuantity(
1468 : CGM.getContext().Target.getPointerAlign(0) / 8)) {
1469 : unsigned AlignedOffsetInBytes
1470 0: = llvm::RoundUpToAlignment(FieldOffset/8, Align.getQuantity());
1471 : unsigned NumPaddingBytes
1472 0: = AlignedOffsetInBytes - FieldOffset/8;
1473 :
0: branch 0 not taken
0: branch 1 not taken
1474 0: if (NumPaddingBytes > 0) {
1475 0: llvm::APInt pad(32, NumPaddingBytes);
1476 : FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy,
1477 0: pad, ArrayType::Normal, 0);
1478 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1479 0: FieldSize = CGM.getContext().getTypeSize(FType);
1480 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1481 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member,
1482 : Unit, "", DefUnit,
1483 : 0, FieldSize, FieldAlign,
1484 0: FieldOffset, 0, FieldTy);
1485 0: EltTys.push_back(FieldTy);
1486 0: FieldOffset += FieldSize;
1487 : }
1488 : }
1489 :
1490 0: FType = Type;
1491 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1492 0: FieldSize = CGM.getContext().getTypeSize(FType);
1493 0: FieldAlign = Align.getQuantity()*8;
1494 :
1495 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1496 : VD->getName(), DefUnit,
1497 : 0, FieldSize, FieldAlign,
1498 0: FieldOffset, 0, FieldTy);
1499 0: EltTys.push_back(FieldTy);
1500 0: FieldOffset += FieldSize;
1501 :
1502 0: Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
1503 :
1504 0: unsigned Flags = llvm::DIType::FlagBlockByrefStruct;
1505 :
1506 : Ty = DebugFactory.CreateCompositeType(Tag, Unit, "",
1507 : llvm::DICompileUnit(),
1508 : 0, FieldOffset, 0, 0, Flags,
1509 0: llvm::DIType(), Elements);
1510 : }
1511 :
1512 : // Get location information.
1513 209: SourceManager &SM = CGM.getContext().getSourceManager();
1514 209: PresumedLoc PLoc = SM.getPresumedLoc(VD->getLocation());
1515 209: unsigned Line = 0;
1516 209: unsigned Column = 0;
31: branch 1 taken
178: branch 2 taken
1517 209: if (PLoc.isInvalid())
1518 31: PLoc = SM.getPresumedLoc(CurLoc);
209: branch 1 taken
0: branch 2 not taken
1519 209: if (PLoc.isValid()) {
1520 209: Line = PLoc.getLine();
1521 209: Column = PLoc.getColumn();
1522 209: Unit = getOrCreateCompileUnit(CurLoc);
1523 : } else {
1524 0: Unit = llvm::DICompileUnit();
1525 : }
1526 :
1527 : // Create the descriptor for the variable.
1528 : llvm::DIVariable D =
1529 : DebugFactory.CreateVariable(Tag, llvm::DIDescriptor(RegionStack.back()),
1530 : VD->getName(),
1531 209: Unit, Line, Ty);
1532 : // Insert an llvm.dbg.declare into the current block.
1533 : llvm::Instruction *Call =
1534 209: DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
1535 :
1536 209: llvm::DIScope DS(RegionStack.back());
1537 209: llvm::DILocation DO(NULL);
1538 209: llvm::DILocation DL = DebugFactory.CreateLocation(Line, Column, DS, DO);
1539 :
1540 209: Call->setMetadata("dbg", DL.getNode());
1541 : }
1542 :
1543 : /// EmitDeclare - Emit local variable declaration debug info.
1544 : void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag,
1545 : llvm::Value *Storage, CGBuilderTy &Builder,
1546 3: CodeGenFunction *CGF) {
1547 3: const ValueDecl *VD = BDRE->getDecl();
3: branch 1 taken
0: branch 2 not taken
1548 3: assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");
1549 :
1550 : // Do not emit variable debug information while generating optimized code.
1551 : // The llvm optimizer and code generator are not yet ready to support
1552 : // optimized code debugging.
1553 3: const CodeGenOptions &CGO = CGM.getCodeGenOpts();
3: branch 0 taken
0: branch 1 not taken
0: branch 3 not taken
3: branch 4 taken
0: branch 5 not taken
3: branch 6 taken
1554 6: if (CGO.OptimizationLevel || Builder.GetInsertBlock() == 0)
1555 0: return;
1556 :
1557 3: uint64_t XOffset = 0;
1558 3: llvm::DICompileUnit Unit = getOrCreateCompileUnit(VD->getLocation());
1559 3: QualType Type = VD->getType();
1560 3: llvm::DIType Ty = getOrCreateType(Type, Unit);
0: branch 1 not taken
3: branch 2 taken
1561 3: if (VD->hasAttr<BlocksAttr>()) {
1562 0: llvm::DICompileUnit DefUnit;
1563 0: unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
1564 :
1565 0: llvm::SmallVector<llvm::DIDescriptor, 5> EltTys;
1566 :
1567 0: llvm::DIType FieldTy;
1568 :
1569 0: QualType FType;
1570 : uint64_t FieldSize, FieldOffset;
1571 : unsigned FieldAlign;
1572 :
1573 0: llvm::DIArray Elements;
1574 0: llvm::DIType EltTy;
1575 :
1576 : // Build up structure for the byref. See BuildByRefType.
1577 0: FieldOffset = 0;
1578 0: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1579 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1580 0: FieldSize = CGM.getContext().getTypeSize(FType);
1581 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1582 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1583 : "__isa", DefUnit,
1584 : 0, FieldSize, FieldAlign,
1585 0: FieldOffset, 0, FieldTy);
1586 0: EltTys.push_back(FieldTy);
1587 0: FieldOffset += FieldSize;
1588 :
1589 0: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1590 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1591 0: FieldSize = CGM.getContext().getTypeSize(FType);
1592 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1593 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1594 : "__forwarding", DefUnit,
1595 : 0, FieldSize, FieldAlign,
1596 0: FieldOffset, 0, FieldTy);
1597 0: EltTys.push_back(FieldTy);
1598 0: FieldOffset += FieldSize;
1599 :
1600 0: FType = CGM.getContext().IntTy;
1601 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1602 0: FieldSize = CGM.getContext().getTypeSize(FType);
1603 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1604 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1605 : "__flags", DefUnit,
1606 : 0, FieldSize, FieldAlign,
1607 0: FieldOffset, 0, FieldTy);
1608 0: EltTys.push_back(FieldTy);
1609 0: FieldOffset += FieldSize;
1610 :
1611 0: FType = CGM.getContext().IntTy;
1612 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1613 0: FieldSize = CGM.getContext().getTypeSize(FType);
1614 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1615 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1616 : "__size", DefUnit,
1617 : 0, FieldSize, FieldAlign,
1618 0: FieldOffset, 0, FieldTy);
1619 0: EltTys.push_back(FieldTy);
1620 0: FieldOffset += FieldSize;
1621 :
1622 0: bool HasCopyAndDispose = CGM.BlockRequiresCopying(Type);
0: branch 0 not taken
0: branch 1 not taken
1623 0: if (HasCopyAndDispose) {
1624 0: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1625 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1626 0: FieldSize = CGM.getContext().getTypeSize(FType);
1627 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1628 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1629 : "__copy_helper", DefUnit,
1630 : 0, FieldSize, FieldAlign,
1631 0: FieldOffset, 0, FieldTy);
1632 0: EltTys.push_back(FieldTy);
1633 0: FieldOffset += FieldSize;
1634 :
1635 0: FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
1636 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1637 0: FieldSize = CGM.getContext().getTypeSize(FType);
1638 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1639 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1640 : "__destroy_helper", DefUnit,
1641 : 0, FieldSize, FieldAlign,
1642 0: FieldOffset, 0, FieldTy);
1643 0: EltTys.push_back(FieldTy);
1644 0: FieldOffset += FieldSize;
1645 : }
1646 :
1647 0: CharUnits Align = CGM.getContext().getDeclAlign(VD);
0: branch 4 not taken
0: branch 5 not taken
1648 0: if (Align > CharUnits::fromQuantity(
1649 : CGM.getContext().Target.getPointerAlign(0) / 8)) {
1650 : unsigned AlignedOffsetInBytes
1651 0: = llvm::RoundUpToAlignment(FieldOffset/8, Align.getQuantity());
1652 : unsigned NumPaddingBytes
1653 0: = AlignedOffsetInBytes - FieldOffset/8;
1654 :
0: branch 0 not taken
0: branch 1 not taken
1655 0: if (NumPaddingBytes > 0) {
1656 0: llvm::APInt pad(32, NumPaddingBytes);
1657 : FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy,
1658 0: pad, ArrayType::Normal, 0);
1659 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1660 0: FieldSize = CGM.getContext().getTypeSize(FType);
1661 0: FieldAlign = CGM.getContext().getTypeAlign(FType);
1662 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member,
1663 : Unit, "", DefUnit,
1664 : 0, FieldSize, FieldAlign,
1665 0: FieldOffset, 0, FieldTy);
1666 0: EltTys.push_back(FieldTy);
1667 0: FieldOffset += FieldSize;
1668 : }
1669 : }
1670 :
1671 0: FType = Type;
1672 0: FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
1673 0: FieldSize = CGM.getContext().getTypeSize(FType);
1674 0: FieldAlign = Align.getQuantity()*8;
1675 :
1676 0: XOffset = FieldOffset;
1677 : FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
1678 : VD->getName(), DefUnit,
1679 : 0, FieldSize, FieldAlign,
1680 0: FieldOffset, 0, FieldTy);
1681 0: EltTys.push_back(FieldTy);
1682 0: FieldOffset += FieldSize;
1683 :
1684 0: Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
1685 :
1686 0: unsigned Flags = llvm::DIType::FlagBlockByrefStruct;
1687 :
1688 : Ty = DebugFactory.CreateCompositeType(Tag, Unit, "",
1689 : llvm::DICompileUnit(),
1690 : 0, FieldOffset, 0, 0, Flags,
1691 0: llvm::DIType(), Elements);
1692 : }
1693 :
1694 : // Get location information.
1695 3: SourceManager &SM = CGM.getContext().getSourceManager();
1696 3: PresumedLoc PLoc = SM.getPresumedLoc(VD->getLocation());
1697 3: unsigned Line = 0;
2: branch 1 taken
1: branch 2 taken
1698 3: if (!PLoc.isInvalid())
1699 2: Line = PLoc.getLine();
1700 : else
1701 1: Unit = llvm::DICompileUnit();
1702 :
1703 3: CharUnits offset = CGF->BlockDecls[VD];
1704 3: llvm::SmallVector<llvm::Value *, 9> addr;
1705 3: const llvm::Type *Int64Ty = llvm::Type::getInt64Ty(CGM.getLLVMContext());
1706 3: addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpDeref));
1707 3: addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpPlus));
1708 3: addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
0: branch 1 not taken
3: branch 2 taken
1709 3: if (BDRE->isByRef()) {
1710 0: addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpDeref));
1711 0: addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpPlus));
1712 : // offset of __forwarding field
1713 0: offset = CharUnits::fromQuantity(CGF->LLVMPointerWidth/8);
1714 0: addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
1715 0: addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpDeref));
1716 0: addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIFactory::OpPlus));
1717 : // offset of x field
1718 0: offset = CharUnits::fromQuantity(XOffset/8);
1719 0: addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
1720 : }
1721 :
1722 : // Create the descriptor for the variable.
1723 : llvm::DIVariable D =
1724 : DebugFactory.CreateComplexVariable(Tag,
1725 : llvm::DIDescriptor(RegionStack.back()),
1726 : VD->getName(), Unit, Line, Ty,
1727 3: addr);
1728 : // Insert an llvm.dbg.declare into the current block.
1729 : llvm::Instruction *Call =
1730 3: DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
1731 :
1732 3: llvm::DIScope DS(RegionStack.back());
1733 3: llvm::DILocation DO(NULL);
1734 : llvm::DILocation DL =
1735 3: DebugFactory.CreateLocation(Line, PLoc.getColumn(), DS, DO);
1736 :
1737 3: Call->setMetadata("dbg", DL.getNode());
1738 : }
1739 :
1740 : void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,
1741 : llvm::Value *Storage,
1742 138: CGBuilderTy &Builder) {
1743 138: EmitDeclare(VD, llvm::dwarf::DW_TAG_auto_variable, Storage, Builder);
1744 138: }
1745 :
1746 : void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
1747 : const BlockDeclRefExpr *BDRE, llvm::Value *Storage, CGBuilderTy &Builder,
1748 3: CodeGenFunction *CGF) {
1749 3: EmitDeclare(BDRE, llvm::dwarf::DW_TAG_auto_variable, Storage, Builder, CGF);
1750 3: }
1751 :
1752 : /// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
1753 : /// variable declaration.
1754 : void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI,
1755 71: CGBuilderTy &Builder) {
1756 71: EmitDeclare(VD, llvm::dwarf::DW_TAG_arg_variable, AI, Builder);
1757 71: }
1758 :
1759 :
1760 :
1761 : /// EmitGlobalVariable - Emit information about a global variable.
1762 : void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
1763 23: const VarDecl *D) {
1764 :
1765 : // Create global variable debug descriptor.
1766 23: llvm::DICompileUnit Unit = getOrCreateCompileUnit(D->getLocation());
1767 23: SourceManager &SM = CGM.getContext().getSourceManager();
1768 23: PresumedLoc PLoc = SM.getPresumedLoc(D->getLocation());
0: branch 1 not taken
23: branch 2 taken
1769 23: unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine();
1770 :
1771 23: QualType T = D->getType();
0: branch 2 not taken
23: branch 3 taken
1772 23: if (T->isIncompleteArrayType()) {
1773 :
1774 : // CodeGen turns int[] into int[1] so we'll do the same here.
1775 0: llvm::APSInt ConstVal(32);
1776 :
1777 0: ConstVal = 1;
1778 0: QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
1779 :
1780 : T = CGM.getContext().getConstantArrayType(ET, ConstVal,
1781 0: ArrayType::Normal, 0);
1782 : }
1783 23: llvm::StringRef DeclName = D->getName();
1784 : llvm::DIDescriptor DContext =
1785 23: getContextDescriptor(dyn_cast<Decl>(D->getDeclContext()), Unit);
1786 : DebugFactory.CreateGlobalVariable(DContext, DeclName,
1787 : DeclName, llvm::StringRef(), Unit, LineNo,
1788 : getOrCreateType(T, Unit),
1789 : Var->hasInternalLinkage(),
1790 23: true/*definition*/, Var);
1791 23: }
1792 :
1793 : /// EmitGlobalVariable - Emit information about an objective-c interface.
1794 : void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
1795 0: ObjCInterfaceDecl *ID) {
1796 : // Create global variable debug descriptor.
1797 0: llvm::DICompileUnit Unit = getOrCreateCompileUnit(ID->getLocation());
1798 0: SourceManager &SM = CGM.getContext().getSourceManager();
1799 0: PresumedLoc PLoc = SM.getPresumedLoc(ID->getLocation());
0: branch 1 not taken
0: branch 2 not taken
1800 0: unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine();
1801 :
1802 0: llvm::StringRef Name = ID->getName();
1803 :
1804 0: QualType T = CGM.getContext().getObjCInterfaceType(ID);
0: branch 2 not taken
0: branch 3 not taken
1805 0: if (T->isIncompleteArrayType()) {
1806 :
1807 : // CodeGen turns int[] into int[1] so we'll do the same here.
1808 0: llvm::APSInt ConstVal(32);
1809 :
1810 0: ConstVal = 1;
1811 0: QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
1812 :
1813 : T = CGM.getContext().getConstantArrayType(ET, ConstVal,
1814 0: ArrayType::Normal, 0);
1815 : }
1816 :
1817 : DebugFactory.CreateGlobalVariable(Unit, Name, Name, Name, Unit, LineNo,
1818 : getOrCreateType(T, Unit),
1819 : Var->hasInternalLinkage(),
1820 0: true/*definition*/, Var);
1821 0: }
1822 :
1823 : /// getOrCreateNamesSpace - Return namespace descriptor for the given
1824 : /// namespace decl.
1825 : llvm::DINameSpace
1826 : CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl,
1827 14: llvm::DIDescriptor Unit) {
1828 : llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH>::iterator I =
1829 14: NameSpaceCache.find(NSDecl);
10: branch 3 taken
4: branch 4 taken
1830 14: if (I != NameSpaceCache.end())
1831 10: return llvm::DINameSpace(cast<llvm::MDNode>(I->second));
1832 :
1833 4: SourceManager &SM = CGM.getContext().getSourceManager();
1834 4: PresumedLoc PLoc = SM.getPresumedLoc(NSDecl->getLocation());
0: branch 1 not taken
4: branch 2 taken
1835 4: unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine();
1836 :
1837 : llvm::DIDescriptor Context =
1838 4: getContextDescriptor(dyn_cast<Decl>(NSDecl->getDeclContext()), Unit);
1839 : llvm::DINameSpace NS =
1840 : DebugFactory.CreateNameSpace(Context, NSDecl->getName(),
1841 4: llvm::DICompileUnit(Unit.getNode()), LineNo);
1842 4: NameSpaceCache[NSDecl] = llvm::WeakVH(NS.getNode());
1843 4: return NS;
1844 : }
Generated: 2010-02-10 01:31 by zcov