| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 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 "CodeGenModule.h" | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 16 | #include "clang/AST/ASTContext.h" | 
| Devang Patel | 9ca36b6 | 2009-02-26 21:10:26 +0000 | [diff] [blame] | 17 | #include "clang/AST/DeclObjC.h" | 
| Chris Lattner | 3cc5c40 | 2008-11-11 07:01:36 +0000 | [diff] [blame] | 18 | #include "clang/AST/Expr.h" | 
| Daniel Dunbar | e91593e | 2008-08-11 04:54:23 +0000 | [diff] [blame] | 19 | #include "clang/AST/RecordLayout.h" | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 20 | #include "clang/Basic/SourceManager.h" | 
 | 21 | #include "clang/Basic/FileManager.h" | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 22 | #include "llvm/Constants.h" | 
 | 23 | #include "llvm/DerivedTypes.h" | 
 | 24 | #include "llvm/Instructions.h" | 
 | 25 | #include "llvm/Intrinsics.h" | 
 | 26 | #include "llvm/Module.h" | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 27 | #include "llvm/ADT/StringExtras.h" | 
 | 28 | #include "llvm/ADT/SmallVector.h" | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 29 | #include "llvm/Support/Dwarf.h" | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 30 | #include "llvm/Target/TargetMachine.h" | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 31 | using namespace clang; | 
 | 32 | using namespace clang::CodeGen; | 
 | 33 |  | 
 | 34 | CGDebugInfo::CGDebugInfo(CodeGenModule *m) | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 35 |   : M(m), DebugFactory(M->getModule()) { | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 36 | } | 
 | 37 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 38 | CGDebugInfo::~CGDebugInfo() { | 
| Daniel Dunbar | 66031a5 | 2008-10-17 16:15:48 +0000 | [diff] [blame] | 39 |   assert(RegionStack.empty() && "Region stack mismatch, stack not empty!"); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 40 | } | 
 | 41 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 42 | void CGDebugInfo::setLocation(SourceLocation Loc) { | 
 | 43 |   if (Loc.isValid()) | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 44 |     CurLoc = M->getContext().getSourceManager().getInstantiationLoc(Loc); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 45 | } | 
 | 46 |  | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 47 | /// getOrCreateCompileUnit - Get the compile unit from the cache or create a new | 
| Daniel Dunbar | 25f51dd | 2008-10-24 08:38:36 +0000 | [diff] [blame] | 48 | /// one if necessary. This returns null for invalid source locations. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 49 | llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) { | 
| Daniel Dunbar | 831570c | 2009-01-22 00:09:25 +0000 | [diff] [blame] | 50 |   // FIXME: Until we do a complete job of emitting debug information, | 
 | 51 |   // we need to support making dummy compile units so that we generate | 
 | 52 |   // "well formed" debug info. | 
 | 53 |   const FileEntry *FE = 0; | 
| Daniel Dunbar | 25f51dd | 2008-10-24 08:38:36 +0000 | [diff] [blame] | 54 |  | 
| Devang Patel | 7782022 | 2009-02-24 23:16:03 +0000 | [diff] [blame] | 55 |   SourceManager &SM = M->getContext().getSourceManager(); | 
| Daniel Dunbar | 831570c | 2009-01-22 00:09:25 +0000 | [diff] [blame] | 56 |   if (Loc.isValid()) { | 
| Daniel Dunbar | 831570c | 2009-01-22 00:09:25 +0000 | [diff] [blame] | 57 |     Loc = SM.getInstantiationLoc(Loc); | 
 | 58 |     FE = SM.getFileEntryForID(SM.getFileID(Loc)); | 
| Devang Patel | 7782022 | 2009-02-24 23:16:03 +0000 | [diff] [blame] | 59 |   } else { | 
 | 60 |     // If Loc is not valid then use main file id. | 
 | 61 |     FE = SM.getFileEntryForID(SM.getMainFileID()); | 
| Daniel Dunbar | 831570c | 2009-01-22 00:09:25 +0000 | [diff] [blame] | 62 |   } | 
 | 63 |     | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 64 |   // See if this compile unit has been used before. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 65 |   llvm::DICompileUnit &Unit = CompileUnitCache[FE]; | 
 | 66 |   if (!Unit.isNull()) return Unit; | 
 | 67 |    | 
 | 68 |   // Get source file information. | 
| Daniel Dunbar | 831570c | 2009-01-22 00:09:25 +0000 | [diff] [blame] | 69 |   const char *FileName = FE ? FE->getName() : "<unknown>"; | 
| Daniel Dunbar | f8e58d0 | 2009-02-07 00:40:41 +0000 | [diff] [blame] | 70 |   const char *DirName = FE ? FE->getDir()->getName() : "<unknown>"; | 
| Daniel Dunbar | 2104bf9 | 2008-10-24 00:46:51 +0000 | [diff] [blame] | 71 |    | 
| Devang Patel | 4db4c9c | 2009-03-05 01:55:07 +0000 | [diff] [blame] | 72 |   bool isMain = (FE == SM.getFileEntryForID(SM.getMainFileID())); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 73 |   // Create new compile unit. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 74 |   // FIXME: Handle other language IDs as well. | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 75 |   // FIXME: Do not know how to get clang version yet. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 76 |   return Unit = DebugFactory.CreateCompileUnit(llvm::dwarf::DW_LANG_C89, | 
| Devang Patel | 4db4c9c | 2009-03-05 01:55:07 +0000 | [diff] [blame] | 77 |                                                FileName, DirName, "clang", | 
 | 78 |                                                isMain); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 79 | } | 
 | 80 |  | 
| Devang Patel | 65e99f2 | 2009-02-25 01:36:11 +0000 | [diff] [blame] | 81 | /// CreateType - Get the Basic type from the cache or create a new | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 82 | /// one if necessary. | 
 | 83 | llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT, | 
| Devang Patel | 65e99f2 | 2009-02-25 01:36:11 +0000 | [diff] [blame] | 84 |                                      llvm::DICompileUnit Unit) { | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 85 |   unsigned Encoding = 0; | 
 | 86 |   switch (BT->getKind()) { | 
 | 87 |   default: | 
 | 88 |   case BuiltinType::Void: | 
 | 89 |     return llvm::DIType(); | 
 | 90 |   case BuiltinType::UChar: | 
 | 91 |   case BuiltinType::Char_U: Encoding = llvm::dwarf::DW_ATE_unsigned_char; break; | 
 | 92 |   case BuiltinType::Char_S: | 
 | 93 |   case BuiltinType::SChar: Encoding = llvm::dwarf::DW_ATE_signed_char; break; | 
 | 94 |   case BuiltinType::UShort: | 
 | 95 |   case BuiltinType::UInt: | 
 | 96 |   case BuiltinType::ULong: | 
 | 97 |   case BuiltinType::ULongLong: Encoding = llvm::dwarf::DW_ATE_unsigned; break; | 
 | 98 |   case BuiltinType::Short: | 
 | 99 |   case BuiltinType::Int: | 
 | 100 |   case BuiltinType::Long: | 
 | 101 |   case BuiltinType::LongLong:  Encoding = llvm::dwarf::DW_ATE_signed; break; | 
 | 102 |   case BuiltinType::Bool:      Encoding = llvm::dwarf::DW_ATE_boolean; break; | 
 | 103 |   case BuiltinType::Float: | 
 | 104 |   case BuiltinType::Double:    Encoding = llvm::dwarf::DW_ATE_float; break; | 
 | 105 |   }  | 
 | 106 |   // Bit size, align and offset of the type. | 
 | 107 |   uint64_t Size = M->getContext().getTypeSize(BT); | 
 | 108 |   uint64_t Align = M->getContext().getTypeAlign(BT); | 
 | 109 |   uint64_t Offset = 0; | 
 | 110 |    | 
 | 111 |   return DebugFactory.CreateBasicType(Unit, BT->getName(), Unit, 0, Size, Align, | 
 | 112 |                                       Offset, /*flags*/ 0, Encoding); | 
 | 113 | } | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 114 |  | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 115 | /// getOrCreateCVRType - Get the CVR qualified type from the cache or create  | 
 | 116 | /// a new one if necessary. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 117 | llvm::DIType CGDebugInfo::CreateCVRType(QualType Ty, llvm::DICompileUnit Unit) { | 
 | 118 |   // We will create one Derived type for one qualifier and recurse to handle any | 
 | 119 |   // additional ones. | 
 | 120 |   llvm::DIType FromTy; | 
 | 121 |   unsigned Tag; | 
 | 122 |   if (Ty.isConstQualified()) { | 
 | 123 |     Tag = llvm::dwarf::DW_TAG_const_type; | 
 | 124 |     Ty.removeConst();  | 
 | 125 |     FromTy = getOrCreateType(Ty, Unit); | 
 | 126 |   } else if (Ty.isVolatileQualified()) { | 
 | 127 |     Tag = llvm::dwarf::DW_TAG_volatile_type; | 
 | 128 |     Ty.removeVolatile();  | 
 | 129 |     FromTy = getOrCreateType(Ty, Unit); | 
 | 130 |   } else { | 
 | 131 |     assert(Ty.isRestrictQualified() && "Unknown type qualifier for debug info"); | 
 | 132 |     Tag = llvm::dwarf::DW_TAG_restrict_type; | 
 | 133 |     Ty.removeRestrict();  | 
 | 134 |     FromTy = getOrCreateType(Ty, Unit); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 135 |   } | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 136 |    | 
| Daniel Dunbar | 3845f86 | 2008-10-31 03:54:29 +0000 | [diff] [blame] | 137 |   // No need to fill in the Name, Line, Size, Alignment, Offset in case of | 
 | 138 |   // CVR derived types. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 139 |   return DebugFactory.CreateDerivedType(Tag, Unit, "", llvm::DICompileUnit(), | 
 | 140 |                                         0, 0, 0, 0, 0, FromTy); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 141 | } | 
 | 142 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 143 | llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty, | 
 | 144 |                                      llvm::DICompileUnit Unit) { | 
 | 145 |   llvm::DIType EltTy = getOrCreateType(Ty->getPointeeType(), Unit); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 146 |   | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 147 |   // Bit size, align and offset of the type. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 148 |   uint64_t Size = M->getContext().getTypeSize(Ty); | 
 | 149 |   uint64_t Align = M->getContext().getTypeAlign(Ty); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 150 |                                                                                 | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 151 |   return DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit, | 
 | 152 |                                         "", llvm::DICompileUnit(), | 
 | 153 |                                         0, Size, Align, 0, 0, EltTy); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 154 | } | 
 | 155 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 156 | llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, | 
 | 157 |                                      llvm::DICompileUnit Unit) { | 
 | 158 |   // Typedefs are derived from some other type.  If we have a typedef of a | 
 | 159 |   // typedef, make sure to emit the whole chain. | 
 | 160 |   llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit); | 
 | 161 |    | 
 | 162 |   // We don't set size information, but do specify where the typedef was | 
 | 163 |   // declared. | 
| Chris Lattner | 8ec03f5 | 2008-11-24 03:54:41 +0000 | [diff] [blame] | 164 |   std::string TyName = Ty->getDecl()->getNameAsString(); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 165 |   SourceLocation DefLoc = Ty->getDecl()->getLocation(); | 
 | 166 |   llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 167 |  | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 168 |   SourceManager &SM = M->getContext().getSourceManager(); | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 169 |   uint64_t Line = SM.getInstantiationLineNumber(DefLoc); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 170 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 171 |   return DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_typedef, Unit, | 
 | 172 |                                         TyName, DefUnit, Line, 0, 0, 0, 0, Src); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 173 | } | 
 | 174 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 175 | llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty, | 
 | 176 |                                      llvm::DICompileUnit Unit) { | 
 | 177 |   llvm::SmallVector<llvm::DIDescriptor, 16> EltTys; | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 178 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 179 |   // Add the result type at least. | 
 | 180 |   EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit)); | 
 | 181 |    | 
 | 182 |   // Set up remainder of arguments if there is a prototype. | 
 | 183 |   // FIXME: IF NOT, HOW IS THIS REPRESENTED?  llvm-gcc doesn't represent '...'! | 
| Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 184 |   if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(Ty)) { | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 185 |     for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) | 
 | 186 |       EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit)); | 
 | 187 |   } else { | 
 | 188 |     // FIXME: Handle () case in C.  llvm-gcc doesn't do it either. | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 189 |   } | 
 | 190 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 191 |   llvm::DIArray EltTypeArray = | 
 | 192 |     DebugFactory.GetOrCreateArray(&EltTys[0], EltTys.size()); | 
 | 193 |    | 
 | 194 |   return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type, | 
 | 195 |                                           Unit, "", llvm::DICompileUnit(), | 
 | 196 |                                           0, 0, 0, 0, 0, | 
 | 197 |                                           llvm::DIType(), EltTypeArray); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 198 | } | 
 | 199 |  | 
| Devang Patel | 65e99f2 | 2009-02-25 01:36:11 +0000 | [diff] [blame] | 200 | /// CreateType - get structure or union type. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 201 | llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, | 
 | 202 |                                      llvm::DICompileUnit Unit) { | 
| Douglas Gregor | a4c46df | 2008-12-11 17:59:21 +0000 | [diff] [blame] | 203 |   RecordDecl *Decl = Ty->getDecl(); | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 204 |    | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 205 |   unsigned Tag; | 
 | 206 |   if (Decl->isStruct()) | 
 | 207 |     Tag = llvm::dwarf::DW_TAG_structure_type; | 
 | 208 |   else if (Decl->isUnion()) | 
 | 209 |     Tag = llvm::dwarf::DW_TAG_union_type; | 
 | 210 |   else { | 
 | 211 |     assert(Decl->isClass() && "Unknown RecordType!"); | 
 | 212 |     Tag = llvm::dwarf::DW_TAG_class_type; | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 213 |   } | 
 | 214 |  | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 215 |   SourceManager &SM = M->getContext().getSourceManager(); | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 216 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 217 |   // Get overall information about the record type for the debug info. | 
| Chris Lattner | 8ec03f5 | 2008-11-24 03:54:41 +0000 | [diff] [blame] | 218 |   std::string Name = Decl->getNameAsString(); | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 219 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 220 |   llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(Decl->getLocation()); | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 221 |   unsigned Line = SM.getInstantiationLineNumber(Decl->getLocation()); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 222 |    | 
 | 223 |    | 
 | 224 |   // Records and classes and unions can all be recursive.  To handle them, we | 
 | 225 |   // first generate a debug descriptor for the struct as a forward declaration. | 
 | 226 |   // Then (if it is a definition) we go through and get debug info for all of | 
 | 227 |   // its members.  Finally, we create a descriptor for the complete type (which | 
 | 228 |   // may refer to the forward decl if the struct is recursive) and replace all | 
 | 229 |   // uses of the forward declaration with the final definition. | 
 | 230 |   llvm::DIType FwdDecl = | 
 | 231 |     DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, 0, 0, 0, 0, | 
 | 232 |                                      llvm::DIType(), llvm::DIArray()); | 
 | 233 |    | 
 | 234 |   // If this is just a forward declaration, return it. | 
 | 235 |   if (!Decl->getDefinition(M->getContext())) | 
 | 236 |     return FwdDecl; | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 237 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 238 |   // Otherwise, insert it into the TypeCache so that recursive uses will find | 
 | 239 |   // it. | 
 | 240 |   TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl; | 
 | 241 |  | 
 | 242 |   // Convert all the elements. | 
 | 243 |   llvm::SmallVector<llvm::DIDescriptor, 16> EltTys; | 
 | 244 |  | 
 | 245 |   const ASTRecordLayout &RL = M->getContext().getASTRecordLayout(Decl); | 
 | 246 |  | 
 | 247 |   unsigned FieldNo = 0; | 
| Douglas Gregor | a4c46df | 2008-12-11 17:59:21 +0000 | [diff] [blame] | 248 |   for (RecordDecl::field_iterator I = Decl->field_begin(), | 
 | 249 |                                   E = Decl->field_end();  | 
 | 250 |        I != E; ++I, ++FieldNo) { | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 251 |     FieldDecl *Field = *I; | 
 | 252 |     llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit); | 
| Chris Lattner | 8ec03f5 | 2008-11-24 03:54:41 +0000 | [diff] [blame] | 253 |  | 
 | 254 |     std::string FieldName = Field->getNameAsString(); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 255 |  | 
 | 256 |     // Get the location for the field. | 
 | 257 |     SourceLocation FieldDefLoc = Field->getLocation(); | 
 | 258 |     llvm::DICompileUnit FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc); | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 259 |     unsigned FieldLine = SM.getInstantiationLineNumber(FieldDefLoc); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 260 |      | 
 | 261 |     // Bit size, align and offset of the type. | 
 | 262 |     uint64_t FieldSize = M->getContext().getTypeSize(Ty); | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 263 |     unsigned FieldAlign = M->getContext().getTypeAlign(Ty); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 264 |     uint64_t FieldOffset = RL.getFieldOffset(FieldNo);     | 
 | 265 |      | 
 | 266 |     // Create a DW_TAG_member node to remember the offset of this field in the | 
 | 267 |     // struct.  FIXME: This is an absolutely insane way to capture this | 
 | 268 |     // information.  When we gut debug info, this should be fixed. | 
 | 269 |     FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, | 
 | 270 |                                              FieldName, FieldDefUnit, | 
 | 271 |                                              FieldLine, FieldSize, FieldAlign, | 
 | 272 |                                              FieldOffset, 0, FieldTy); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 273 |     EltTys.push_back(FieldTy); | 
 | 274 |   } | 
 | 275 |    | 
 | 276 |   llvm::DIArray Elements = | 
 | 277 |     DebugFactory.GetOrCreateArray(&EltTys[0], EltTys.size()); | 
 | 278 |  | 
 | 279 |   // Bit size, align and offset of the type. | 
 | 280 |   uint64_t Size = M->getContext().getTypeSize(Ty); | 
 | 281 |   uint64_t Align = M->getContext().getTypeAlign(Ty); | 
 | 282 |    | 
 | 283 |   llvm::DIType RealDecl = | 
 | 284 |     DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, Size, | 
 | 285 |                                      Align, 0, 0, llvm::DIType(), Elements); | 
 | 286 |  | 
 | 287 |   // Now that we have a real decl for the struct, replace anything using the | 
 | 288 |   // old decl with the new one.  This will recursively update the debug info. | 
 | 289 |   FwdDecl.getGV()->replaceAllUsesWith(RealDecl.getGV()); | 
 | 290 |   FwdDecl.getGV()->eraseFromParent(); | 
 | 291 |    | 
 | 292 |   return RealDecl; | 
 | 293 | } | 
 | 294 |  | 
| Devang Patel | 9ca36b6 | 2009-02-26 21:10:26 +0000 | [diff] [blame] | 295 | /// CreateType - get objective-c interface type. | 
 | 296 | llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, | 
 | 297 |                                      llvm::DICompileUnit Unit) { | 
 | 298 |   ObjCInterfaceDecl *Decl = Ty->getDecl(); | 
 | 299 |    | 
 | 300 |   unsigned Tag = llvm::dwarf::DW_TAG_structure_type; | 
 | 301 |   SourceManager &SM = M->getContext().getSourceManager(); | 
 | 302 |  | 
 | 303 |   // Get overall information about the record type for the debug info. | 
 | 304 |   std::string Name = Decl->getNameAsString(); | 
 | 305 |  | 
 | 306 |   llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(Decl->getLocation()); | 
 | 307 |   unsigned Line = SM.getInstantiationLineNumber(Decl->getLocation()); | 
 | 308 |    | 
 | 309 |    | 
 | 310 |   // To handle recursive interface, we | 
 | 311 |   // first generate a debug descriptor for the struct as a forward declaration. | 
 | 312 |   // Then (if it is a definition) we go through and get debug info for all of | 
 | 313 |   // its members.  Finally, we create a descriptor for the complete type (which | 
 | 314 |   // may refer to the forward decl if the struct is recursive) and replace all | 
 | 315 |   // uses of the forward declaration with the final definition. | 
 | 316 |   llvm::DIType FwdDecl = | 
 | 317 |     DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, 0, 0, 0, 0, | 
 | 318 |                                      llvm::DIType(), llvm::DIArray()); | 
 | 319 |    | 
 | 320 |   // If this is just a forward declaration, return it. | 
 | 321 |   if (Decl->isForwardDecl()) | 
 | 322 |     return FwdDecl; | 
 | 323 |  | 
 | 324 |   // Otherwise, insert it into the TypeCache so that recursive uses will find | 
 | 325 |   // it. | 
 | 326 |   TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl; | 
 | 327 |  | 
 | 328 |   // Convert all the elements. | 
 | 329 |   llvm::SmallVector<llvm::DIDescriptor, 16> EltTys; | 
 | 330 |  | 
| Devang Patel | fbe899f | 2009-03-10 21:30:26 +0000 | [diff] [blame] | 331 |   ObjCInterfaceDecl *SClass = Decl->getSuperClass(); | 
 | 332 |   if (SClass) { | 
 | 333 |     llvm::DIType SClassTy =  | 
 | 334 |       getOrCreateType(M->getContext().getObjCInterfaceType(SClass), Unit); | 
 | 335 |     llvm::DIType InhTag =  | 
 | 336 |       DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_inheritance, | 
 | 337 |                                      Unit, "", Unit, 0, 0, 0, | 
 | 338 |                                      0 /* offset */, 0, SClassTy); | 
 | 339 |     EltTys.push_back(InhTag); | 
 | 340 |   } | 
 | 341 |  | 
| Devang Patel | 9ca36b6 | 2009-02-26 21:10:26 +0000 | [diff] [blame] | 342 |   const ASTRecordLayout &RL = M->getContext().getASTObjCInterfaceLayout(Decl); | 
 | 343 |  | 
 | 344 |   unsigned FieldNo = 0; | 
 | 345 |   for (ObjCInterfaceDecl::ivar_iterator I = Decl->ivar_begin(), | 
 | 346 |          E = Decl->ivar_end();  I != E; ++I, ++FieldNo) { | 
 | 347 |     ObjCIvarDecl *Field = *I; | 
 | 348 |     llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit); | 
 | 349 |  | 
 | 350 |     std::string FieldName = Field->getNameAsString(); | 
 | 351 |  | 
 | 352 |     // Get the location for the field. | 
 | 353 |     SourceLocation FieldDefLoc = Field->getLocation(); | 
 | 354 |     llvm::DICompileUnit FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc); | 
 | 355 |     unsigned FieldLine = SM.getInstantiationLineNumber(FieldDefLoc); | 
 | 356 |      | 
 | 357 |     // Bit size, align and offset of the type. | 
 | 358 |     uint64_t FieldSize = M->getContext().getTypeSize(Ty); | 
 | 359 |     unsigned FieldAlign = M->getContext().getTypeAlign(Ty); | 
 | 360 |     uint64_t FieldOffset = RL.getFieldOffset(FieldNo);     | 
 | 361 |      | 
 | 362 |     // Create a DW_TAG_member node to remember the offset of this field in the | 
 | 363 |     // struct.  FIXME: This is an absolutely insane way to capture this | 
 | 364 |     // information.  When we gut debug info, this should be fixed. | 
 | 365 |     FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit, | 
 | 366 |                                              FieldName, FieldDefUnit, | 
 | 367 |                                              FieldLine, FieldSize, FieldAlign, | 
 | 368 |                                              FieldOffset, 0, FieldTy); | 
 | 369 |     EltTys.push_back(FieldTy); | 
 | 370 |   } | 
 | 371 |    | 
 | 372 |   llvm::DIArray Elements = | 
 | 373 |     DebugFactory.GetOrCreateArray(&EltTys[0], EltTys.size()); | 
 | 374 |  | 
 | 375 |   // Bit size, align and offset of the type. | 
 | 376 |   uint64_t Size = M->getContext().getTypeSize(Ty); | 
 | 377 |   uint64_t Align = M->getContext().getTypeAlign(Ty); | 
 | 378 |    | 
 | 379 |   llvm::DIType RealDecl = | 
 | 380 |     DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, Size, | 
 | 381 |                                      Align, 0, 0, llvm::DIType(), Elements); | 
 | 382 |  | 
 | 383 |   // Now that we have a real decl for the struct, replace anything using the | 
 | 384 |   // old decl with the new one.  This will recursively update the debug info. | 
 | 385 |   FwdDecl.getGV()->replaceAllUsesWith(RealDecl.getGV()); | 
 | 386 |   FwdDecl.getGV()->eraseFromParent(); | 
 | 387 |    | 
 | 388 |   return RealDecl; | 
 | 389 | } | 
 | 390 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 391 | llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty, | 
 | 392 |                                      llvm::DICompileUnit Unit) { | 
 | 393 |   EnumDecl *Decl = Ty->getDecl(); | 
 | 394 |  | 
 | 395 |   llvm::SmallVector<llvm::DIDescriptor, 32> Enumerators; | 
 | 396 |  | 
 | 397 |   // Create DIEnumerator elements for each enumerator. | 
| Douglas Gregor | 44b4321 | 2008-12-11 16:49:14 +0000 | [diff] [blame] | 398 |   for (EnumDecl::enumerator_iterator Enum = Decl->enumerator_begin(), | 
 | 399 |                                   EnumEnd = Decl->enumerator_end(); | 
 | 400 |        Enum != EnumEnd; ++Enum) { | 
 | 401 |     Enumerators.push_back(DebugFactory.CreateEnumerator(Enum->getNameAsString(), | 
 | 402 |                                             Enum->getInitVal().getZExtValue())); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 403 |   } | 
 | 404 |    | 
 | 405 |   // Return a CompositeType for the enum itself. | 
 | 406 |   llvm::DIArray EltArray = | 
 | 407 |     DebugFactory.GetOrCreateArray(&Enumerators[0], Enumerators.size()); | 
 | 408 |  | 
| Chris Lattner | 8ec03f5 | 2008-11-24 03:54:41 +0000 | [diff] [blame] | 409 |   std::string EnumName = Decl->getNameAsString(); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 410 |   SourceLocation DefLoc = Decl->getLocation(); | 
 | 411 |   llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc); | 
 | 412 |   SourceManager &SM = M->getContext().getSourceManager(); | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 413 |   unsigned Line = SM.getInstantiationLineNumber(DefLoc); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 414 |    | 
 | 415 |   // Size and align of the type. | 
 | 416 |   uint64_t Size = M->getContext().getTypeSize(Ty); | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 417 |   unsigned Align = M->getContext().getTypeAlign(Ty); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 418 |    | 
 | 419 |   return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_enumeration_type, | 
 | 420 |                                           Unit, EnumName, DefUnit, Line, | 
 | 421 |                                           Size, Align, 0, 0, | 
 | 422 |                                           llvm::DIType(), EltArray); | 
 | 423 | } | 
 | 424 |  | 
 | 425 | llvm::DIType CGDebugInfo::CreateType(const TagType *Ty, | 
 | 426 |                                      llvm::DICompileUnit Unit) { | 
 | 427 |   if (const RecordType *RT = dyn_cast<RecordType>(Ty)) | 
 | 428 |     return CreateType(RT, Unit); | 
 | 429 |   else if (const EnumType *ET = dyn_cast<EnumType>(Ty)) | 
 | 430 |     return CreateType(ET, Unit); | 
 | 431 |    | 
 | 432 |   return llvm::DIType(); | 
 | 433 | } | 
 | 434 |  | 
 | 435 | llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty, | 
 | 436 |                                      llvm::DICompileUnit Unit) { | 
| Anders Carlsson | 835c909 | 2009-01-05 01:23:29 +0000 | [diff] [blame] | 437 |   uint64_t Size; | 
 | 438 |   uint64_t Align; | 
 | 439 |    | 
 | 440 |    | 
| Nuno Lopes | 010d514 | 2009-01-28 00:35:17 +0000 | [diff] [blame] | 441 |   // FIXME: make getTypeAlign() aware of VLAs and incomplete array types | 
| Anders Carlsson | 835c909 | 2009-01-05 01:23:29 +0000 | [diff] [blame] | 442 |   if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(Ty)) { | 
| Anders Carlsson | 835c909 | 2009-01-05 01:23:29 +0000 | [diff] [blame] | 443 |     Size = 0; | 
 | 444 |     Align = | 
| Nuno Lopes | 010d514 | 2009-01-28 00:35:17 +0000 | [diff] [blame] | 445 |       M->getContext().getTypeAlign(M->getContext().getBaseElementType(VAT)); | 
 | 446 |   } else if (Ty->isIncompleteArrayType()) { | 
 | 447 |     Size = 0; | 
 | 448 |     Align = M->getContext().getTypeAlign(Ty->getElementType()); | 
| Anders Carlsson | 835c909 | 2009-01-05 01:23:29 +0000 | [diff] [blame] | 449 |   } else { | 
 | 450 |     // Size and align of the whole array, not the element type. | 
 | 451 |     Size = M->getContext().getTypeSize(Ty); | 
 | 452 |     Align = M->getContext().getTypeAlign(Ty); | 
 | 453 |   } | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 454 |    | 
 | 455 |   // Add the dimensions of the array.  FIXME: This loses CV qualifiers from | 
 | 456 |   // interior arrays, do we care?  Why aren't nested arrays represented the | 
 | 457 |   // obvious/recursive way? | 
 | 458 |   llvm::SmallVector<llvm::DIDescriptor, 8> Subscripts; | 
 | 459 |   QualType EltTy(Ty, 0); | 
 | 460 |   while ((Ty = dyn_cast<ArrayType>(EltTy))) { | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 461 |     uint64_t Upper = 0; | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 462 |     if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty)) | 
 | 463 |       Upper = CAT->getSize().getZExtValue() - 1; | 
 | 464 |     // FIXME: Verify this is right for VLAs. | 
 | 465 |     Subscripts.push_back(DebugFactory.GetOrCreateSubrange(0, Upper)); | 
 | 466 |     EltTy = Ty->getElementType(); | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 467 |   } | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 468 |    | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 469 |   llvm::DIArray SubscriptArray = | 
 | 470 |     DebugFactory.GetOrCreateArray(&Subscripts[0], Subscripts.size()); | 
 | 471 |  | 
 | 472 |   return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_array_type, | 
 | 473 |                                           Unit, "", llvm::DICompileUnit(), | 
 | 474 |                                           0, Size, Align, 0, 0, | 
 | 475 |                                           getOrCreateType(EltTy, Unit), | 
 | 476 |                                           SubscriptArray); | 
 | 477 | } | 
 | 478 |  | 
 | 479 |  | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 480 | /// getOrCreateType - Get the type from the cache or create a new | 
 | 481 | /// one if necessary. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 482 | llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, | 
 | 483 |                                           llvm::DICompileUnit Unit) { | 
 | 484 |   if (Ty.isNull()) | 
 | 485 |     return llvm::DIType(); | 
 | 486 |    | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 487 |   // Check to see if the compile unit already has created this type. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 488 |   llvm::DIType &Slot = TypeCache[Ty.getAsOpaquePtr()]; | 
 | 489 |   if (!Slot.isNull()) return Slot; | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 490 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 491 |   // Handle CVR qualifiers, which recursively handles what they refer to. | 
 | 492 |   if (Ty.getCVRQualifiers()) | 
 | 493 |     return Slot = CreateCVRType(Ty, Unit); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 494 |  | 
 | 495 |   // Work out details of type. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 496 |   switch (Ty->getTypeClass()) { | 
| Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 497 | #define TYPE(Class, Base) | 
 | 498 | #define ABSTRACT_TYPE(Class, Base) | 
 | 499 | #define NON_CANONICAL_TYPE(Class, Base) | 
 | 500 | #define DEPENDENT_TYPE(Class, Base) case Type::Class: | 
 | 501 | #include "clang/AST/TypeNodes.def" | 
 | 502 |     assert(false && "Dependent types cannot show up in debug information"); | 
 | 503 |      | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 504 |   case Type::Complex: | 
 | 505 |   case Type::Reference: | 
 | 506 |   case Type::Vector: | 
 | 507 |   case Type::ExtVector: | 
| Fariborz Jahanian | f11284a | 2009-02-17 18:27:45 +0000 | [diff] [blame] | 508 |   case Type::ExtQual: | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 509 |   case Type::ObjCQualifiedInterface: | 
 | 510 |   case Type::ObjCQualifiedId: | 
| Eli Friedman | 00524e3 | 2009-02-27 23:15:07 +0000 | [diff] [blame] | 511 |   case Type::FixedWidthInt: | 
 | 512 |   case Type::BlockPointer: | 
 | 513 |   case Type::MemberPointer: | 
 | 514 |   case Type::ClassTemplateSpecialization: | 
 | 515 |   case Type::ObjCQualifiedClass: | 
 | 516 |     // Unsupported types | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 517 |     return llvm::DIType(); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 518 |  | 
| Devang Patel | e798706 | 2009-03-02 17:58:28 +0000 | [diff] [blame] | 519 |   case Type::ObjCInterface:  | 
 | 520 |     Slot = CreateType(cast<ObjCInterfaceType>(Ty), Unit); break; | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 521 |   case Type::Builtin: Slot = CreateType(cast<BuiltinType>(Ty), Unit); break; | 
 | 522 |   case Type::Pointer: Slot = CreateType(cast<PointerType>(Ty), Unit); break; | 
| Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 523 |   case Type::Typedef: Slot = CreateType(cast<TypedefType>(Ty), Unit); break; | 
 | 524 |   case Type::Record: | 
| Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 525 |   case Type::Enum: | 
 | 526 |     Slot = CreateType(cast<TagType>(Ty), Unit);  | 
 | 527 |     break; | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 528 |   case Type::FunctionProto: | 
 | 529 |   case Type::FunctionNoProto: | 
| Chris Lattner | 3cc5c40 | 2008-11-11 07:01:36 +0000 | [diff] [blame] | 530 |     return Slot = CreateType(cast<FunctionType>(Ty), Unit); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 531 |      | 
 | 532 |   case Type::ConstantArray: | 
 | 533 |   case Type::VariableArray: | 
 | 534 |   case Type::IncompleteArray: | 
| Chris Lattner | 3cc5c40 | 2008-11-11 07:01:36 +0000 | [diff] [blame] | 535 |     return Slot = CreateType(cast<ArrayType>(Ty), Unit); | 
| Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 536 |   case Type::TypeOfExpr: | 
 | 537 |     return Slot = getOrCreateType(cast<TypeOfExprType>(Ty)->getUnderlyingExpr() | 
| Chris Lattner | 3cc5c40 | 2008-11-11 07:01:36 +0000 | [diff] [blame] | 538 |                                   ->getType(), Unit); | 
| Douglas Gregor | 72564e7 | 2009-02-26 23:50:07 +0000 | [diff] [blame] | 539 |   case Type::TypeOf: | 
| Chris Lattner | 3cc5c40 | 2008-11-11 07:01:36 +0000 | [diff] [blame] | 540 |     return Slot = getOrCreateType(cast<TypeOfType>(Ty)->getUnderlyingType(), | 
 | 541 |                                   Unit); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 542 |   } | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 543 |    | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 544 |   return Slot; | 
 | 545 | } | 
 | 546 |  | 
 | 547 | /// EmitFunctionStart - Constructs the debug code for entering a function - | 
 | 548 | /// "llvm.dbg.func.start.". | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 549 | void CGDebugInfo::EmitFunctionStart(const char *Name, QualType ReturnType, | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 550 |                                     llvm::Function *Fn, | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 551 |                                     CGBuilderTy &Builder) { | 
 | 552 |   // FIXME: Why is this using CurLoc??? | 
 | 553 |   llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 554 |   SourceManager &SM = M->getContext().getSourceManager(); | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 555 |   unsigned LineNo = SM.getInstantiationLineNumber(CurLoc); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 556 |    | 
 | 557 |   llvm::DISubprogram SP = | 
 | 558 |     DebugFactory.CreateSubprogram(Unit, Name, Name, "", Unit, LineNo, | 
 | 559 |                                   getOrCreateType(ReturnType, Unit), | 
 | 560 |                                   Fn->hasInternalLinkage(), true/*definition*/); | 
 | 561 |    | 
 | 562 |   DebugFactory.InsertSubprogramStart(SP, Builder.GetInsertBlock()); | 
 | 563 |                                                          | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 564 |   // Push function on region stack. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 565 |   RegionStack.push_back(SP); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 566 | } | 
 | 567 |  | 
 | 568 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 569 | void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) { | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 570 |   if (CurLoc.isInvalid() || CurLoc.isMacroID()) return; | 
 | 571 |    | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 572 |   // Don't bother if things are the same as last time. | 
 | 573 |   SourceManager &SM = M->getContext().getSourceManager(); | 
 | 574 |   if (CurLoc == PrevLoc  | 
| Chris Lattner | 30fc933 | 2009-02-04 01:06:56 +0000 | [diff] [blame] | 575 |        || (SM.getInstantiationLineNumber(CurLoc) == | 
 | 576 |            SM.getInstantiationLineNumber(PrevLoc) | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 577 |            && SM.isFromSameFile(CurLoc, PrevLoc))) | 
 | 578 |     return; | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 579 |  | 
 | 580 |   // Update last state. | 
 | 581 |   PrevLoc = CurLoc; | 
 | 582 |  | 
 | 583 |   // Get the appropriate compile unit. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 584 |   llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc); | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 585 |   DebugFactory.InsertStopPoint(Unit, SM.getInstantiationLineNumber(CurLoc), | 
 | 586 |                                SM.getInstantiationColumnNumber(CurLoc), | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 587 |                                Builder.GetInsertBlock());  | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 588 | } | 
 | 589 |  | 
 | 590 | /// EmitRegionStart- Constructs the debug code for entering a declarative | 
 | 591 | /// region - "llvm.dbg.region.start.". | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 592 | void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, CGBuilderTy &Builder) { | 
 | 593 |   llvm::DIDescriptor D; | 
| Daniel Dunbar | 5273f51 | 2008-10-17 01:07:56 +0000 | [diff] [blame] | 594 |   if (!RegionStack.empty()) | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 595 |     D = RegionStack.back(); | 
 | 596 |   D = DebugFactory.CreateBlock(D); | 
 | 597 |   RegionStack.push_back(D); | 
 | 598 |   DebugFactory.InsertRegionStart(D, Builder.GetInsertBlock()); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 599 | } | 
 | 600 |  | 
 | 601 | /// EmitRegionEnd - Constructs the debug code for exiting a declarative | 
 | 602 | /// region - "llvm.dbg.region.end." | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 603 | void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, CGBuilderTy &Builder) { | 
| Daniel Dunbar | 5273f51 | 2008-10-17 01:07:56 +0000 | [diff] [blame] | 604 |   assert(!RegionStack.empty() && "Region stack mismatch, stack empty!"); | 
 | 605 |  | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 606 |   // Provide an region stop point. | 
 | 607 |   EmitStopPoint(Fn, Builder); | 
 | 608 |    | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 609 |   DebugFactory.InsertRegionEnd(RegionStack.back(), Builder.GetInsertBlock()); | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 610 |   RegionStack.pop_back(); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 611 | } | 
 | 612 |  | 
| Sanjiv Gupta | cc9b163 | 2008-05-30 10:30:31 +0000 | [diff] [blame] | 613 | /// EmitDeclare - Emit local variable declaration debug info. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 614 | void CGDebugInfo::EmitDeclare(const VarDecl *Decl, unsigned Tag, | 
 | 615 |                               llvm::Value *Storage, CGBuilderTy &Builder) { | 
| Daniel Dunbar | 5273f51 | 2008-10-17 01:07:56 +0000 | [diff] [blame] | 616 |   assert(!RegionStack.empty() && "Region stack mismatch, stack empty!"); | 
 | 617 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 618 |   // Get location information. | 
| Sanjiv Gupta | cc9b163 | 2008-05-30 10:30:31 +0000 | [diff] [blame] | 619 |   SourceManager &SM = M->getContext().getSourceManager(); | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 620 |   unsigned Line = SM.getInstantiationLineNumber(Decl->getLocation()); | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 621 |   llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation()); | 
 | 622 |    | 
 | 623 |   // Create the descriptor for the variable. | 
 | 624 |   llvm::DIVariable D =  | 
| Chris Lattner | d9d22dd | 2008-11-24 05:29:24 +0000 | [diff] [blame] | 625 |     DebugFactory.CreateVariable(Tag, RegionStack.back(),Decl->getNameAsString(), | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 626 |                                 Unit, Line, | 
 | 627 |                                 getOrCreateType(Decl->getType(), Unit)); | 
 | 628 |   // Insert an llvm.dbg.declare into the current block. | 
 | 629 |   DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock()); | 
| Sanjiv Gupta | cc9b163 | 2008-05-30 10:30:31 +0000 | [diff] [blame] | 630 | } | 
 | 631 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 632 | void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *Decl, | 
 | 633 |                                             llvm::Value *Storage, | 
 | 634 |                                             CGBuilderTy &Builder) { | 
 | 635 |   EmitDeclare(Decl, llvm::dwarf::DW_TAG_auto_variable, Storage, Builder); | 
 | 636 | } | 
 | 637 |  | 
 | 638 | /// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument | 
 | 639 | /// variable declaration. | 
 | 640 | void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, | 
 | 641 |                                            CGBuilderTy &Builder) { | 
 | 642 |   EmitDeclare(Decl, llvm::dwarf::DW_TAG_arg_variable, AI, Builder); | 
 | 643 | } | 
 | 644 |  | 
 | 645 |  | 
 | 646 |  | 
| Sanjiv Gupta | 686226b | 2008-06-05 08:59:10 +0000 | [diff] [blame] | 647 | /// EmitGlobalVariable - Emit information about a global variable. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 648 | void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,  | 
 | 649 |                                      const VarDecl *Decl) { | 
| Sanjiv Gupta | 686226b | 2008-06-05 08:59:10 +0000 | [diff] [blame] | 650 |   // Create global variable debug descriptor. | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 651 |   llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation()); | 
| Sanjiv Gupta | 686226b | 2008-06-05 08:59:10 +0000 | [diff] [blame] | 652 |   SourceManager &SM = M->getContext().getSourceManager(); | 
| Chris Lattner | f7cf85b | 2009-01-16 07:36:28 +0000 | [diff] [blame] | 653 |   unsigned LineNo = SM.getInstantiationLineNumber(Decl->getLocation()); | 
| Chris Lattner | 8ec03f5 | 2008-11-24 03:54:41 +0000 | [diff] [blame] | 654 |  | 
 | 655 |   std::string Name = Decl->getNameAsString(); | 
| Anders Carlsson | 4d6e8dd | 2008-11-26 17:40:42 +0000 | [diff] [blame] | 656 |  | 
 | 657 |   QualType T = Decl->getType(); | 
 | 658 |   if (T->isIncompleteArrayType()) { | 
 | 659 |      | 
 | 660 |     // CodeGen turns int[] into int[1] so we'll do the same here. | 
 | 661 |     llvm::APSInt ConstVal(32); | 
 | 662 |      | 
 | 663 |     ConstVal = 1; | 
 | 664 |     QualType ET = M->getContext().getAsArrayType(T)->getElementType(); | 
 | 665 |      | 
 | 666 |     T = M->getContext().getConstantArrayType(ET, ConstVal,  | 
 | 667 |                                            ArrayType::Normal, 0); | 
 | 668 |   } | 
 | 669 |  | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 670 |   DebugFactory.CreateGlobalVariable(Unit, Name, Name, "", Unit, LineNo, | 
| Anders Carlsson | 4d6e8dd | 2008-11-26 17:40:42 +0000 | [diff] [blame] | 671 |                                     getOrCreateType(T, Unit), | 
| Chris Lattner | 9c85ba3 | 2008-11-10 06:08:34 +0000 | [diff] [blame] | 672 |                                     Var->hasInternalLinkage(), | 
 | 673 |                                     true/*definition*/, Var); | 
| Sanjiv Gupta | 686226b | 2008-06-05 08:59:10 +0000 | [diff] [blame] | 674 | } | 
 | 675 |  | 
| Devang Patel | 9ca36b6 | 2009-02-26 21:10:26 +0000 | [diff] [blame] | 676 | /// EmitGlobalVariable - Emit information about an objective-c interface. | 
 | 677 | void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,  | 
 | 678 |                                      ObjCInterfaceDecl *Decl) { | 
 | 679 |   // Create global variable debug descriptor. | 
 | 680 |   llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation()); | 
 | 681 |   SourceManager &SM = M->getContext().getSourceManager(); | 
 | 682 |   unsigned LineNo = SM.getInstantiationLineNumber(Decl->getLocation()); | 
 | 683 |  | 
 | 684 |   std::string Name = Decl->getNameAsString(); | 
 | 685 |  | 
 | 686 |   QualType T = M->getContext().buildObjCInterfaceType(Decl); | 
 | 687 |   if (T->isIncompleteArrayType()) { | 
 | 688 |      | 
 | 689 |     // CodeGen turns int[] into int[1] so we'll do the same here. | 
 | 690 |     llvm::APSInt ConstVal(32); | 
 | 691 |      | 
 | 692 |     ConstVal = 1; | 
 | 693 |     QualType ET = M->getContext().getAsArrayType(T)->getElementType(); | 
 | 694 |      | 
 | 695 |     T = M->getContext().getConstantArrayType(ET, ConstVal,  | 
 | 696 |                                            ArrayType::Normal, 0); | 
 | 697 |   } | 
 | 698 |  | 
 | 699 |   DebugFactory.CreateGlobalVariable(Unit, Name, Name, "", Unit, LineNo, | 
 | 700 |                                     getOrCreateType(T, Unit), | 
 | 701 |                                     Var->hasInternalLinkage(), | 
 | 702 |                                     true/*definition*/, Var); | 
 | 703 | } | 
 | 704 |  |