| 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" | 
| Daniel Dunbar | e91593e | 2008-08-11 04:54:23 +0000 | [diff] [blame] | 17 | #include "clang/AST/Decl.h" | 
|  | 18 | #include "clang/AST/RecordLayout.h" | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 19 | #include "clang/Basic/SourceManager.h" | 
|  | 20 | #include "clang/Basic/FileManager.h" | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 21 | #include "llvm/Constants.h" | 
|  | 22 | #include "llvm/DerivedTypes.h" | 
|  | 23 | #include "llvm/Instructions.h" | 
|  | 24 | #include "llvm/Intrinsics.h" | 
|  | 25 | #include "llvm/Module.h" | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 26 | #include "llvm/ADT/StringExtras.h" | 
|  | 27 | #include "llvm/ADT/SmallVector.h" | 
|  | 28 | #include "llvm/CodeGen/MachineModuleInfo.h" | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 29 | #include "llvm/Support/Dwarf.h" | 
|  | 30 | #include "llvm/Support/IRBuilder.h" | 
|  | 31 | #include "llvm/Target/TargetMachine.h" | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 32 | using namespace clang; | 
|  | 33 | using namespace clang::CodeGen; | 
|  | 34 |  | 
|  | 35 | CGDebugInfo::CGDebugInfo(CodeGenModule *m) | 
|  | 36 | : M(m) | 
|  | 37 | , CurLoc() | 
|  | 38 | , PrevLoc() | 
|  | 39 | , CompileUnitCache() | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 40 | , TypeCache() | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 41 | , StopPointFn(NULL) | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 42 | , FuncStartFn(NULL) | 
|  | 43 | , DeclareFn(NULL) | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 44 | , RegionStartFn(NULL) | 
|  | 45 | , RegionEndFn(NULL) | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 46 | , CompileUnitAnchor(NULL) | 
|  | 47 | , SubprogramAnchor(NULL) | 
| Sanjiv Gupta | 686226b | 2008-06-05 08:59:10 +0000 | [diff] [blame] | 48 | , GlobalVariableAnchor(NULL) | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 49 | , RegionStack() | 
| Sanjiv Gupta | cc9b163 | 2008-05-30 10:30:31 +0000 | [diff] [blame] | 50 | , VariableDescList() | 
| Nuno Lopes | 3cd1a2d | 2008-06-08 10:16:34 +0000 | [diff] [blame] | 51 | , GlobalVarDescList() | 
|  | 52 | , EnumDescList() | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 53 | , SubrangeDescList() | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 54 | , Subprogram(NULL) | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 55 | { | 
|  | 56 | SR = new llvm::DISerializer(); | 
|  | 57 | SR->setModule (&M->getModule()); | 
|  | 58 | } | 
|  | 59 |  | 
|  | 60 | CGDebugInfo::~CGDebugInfo() | 
|  | 61 | { | 
|  | 62 | delete SR; | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 63 |  | 
|  | 64 | // Free CompileUnitCache. | 
|  | 65 | for (std::map<unsigned, llvm::CompileUnitDesc *>::iterator I | 
|  | 66 | = CompileUnitCache.begin(); I != CompileUnitCache.end(); ++I) { | 
|  | 67 | delete I->second; | 
|  | 68 | } | 
|  | 69 | CompileUnitCache.clear(); | 
|  | 70 |  | 
|  | 71 | // Free TypeCache. | 
|  | 72 | for (std::map<void *, llvm::TypeDesc *>::iterator I | 
|  | 73 | = TypeCache.begin(); I != TypeCache.end(); ++I) { | 
|  | 74 | delete I->second; | 
|  | 75 | } | 
|  | 76 | TypeCache.clear(); | 
|  | 77 |  | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 78 | // Free region descriptors. | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 79 | for (std::vector<llvm::DebugInfoDesc *>::iterator I | 
|  | 80 | = RegionStack.begin(); I != RegionStack.end(); ++I) { | 
|  | 81 | delete *I; | 
|  | 82 | } | 
| Sanjiv Gupta | cc9b163 | 2008-05-30 10:30:31 +0000 | [diff] [blame] | 83 |  | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 84 | // Free local var descriptors. | 
| Sanjiv Gupta | cc9b163 | 2008-05-30 10:30:31 +0000 | [diff] [blame] | 85 | for (std::vector<llvm::VariableDesc *>::iterator I | 
|  | 86 | = VariableDescList.begin(); I != VariableDescList.end(); ++I) { | 
|  | 87 | delete *I; | 
|  | 88 | } | 
|  | 89 |  | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 90 | // Free global var descriptors. | 
| Sanjiv Gupta | 686226b | 2008-06-05 08:59:10 +0000 | [diff] [blame] | 91 | for (std::vector<llvm::GlobalVariableDesc *>::iterator I | 
|  | 92 | = GlobalVarDescList.begin(); I != GlobalVarDescList.end(); ++I) { | 
|  | 93 | delete *I; | 
|  | 94 | } | 
|  | 95 |  | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 96 | // Free enum constants descriptors. | 
|  | 97 | for (std::vector<llvm::EnumeratorDesc *>::iterator I | 
|  | 98 | = EnumDescList.begin(); I != EnumDescList.end(); ++I) { | 
|  | 99 | delete *I; | 
|  | 100 | } | 
|  | 101 |  | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 102 | // Free subrange descriptors. | 
|  | 103 | for (std::vector<llvm::SubrangeDesc *>::iterator I | 
|  | 104 | = SubrangeDescList.begin(); I != SubrangeDescList.end(); ++I) { | 
|  | 105 | delete *I; | 
|  | 106 | } | 
|  | 107 |  | 
| Eli Friedman | 3f2af10 | 2008-05-22 01:40:10 +0000 | [diff] [blame] | 108 | delete CompileUnitAnchor; | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 109 | delete SubprogramAnchor; | 
| Sanjiv Gupta | 686226b | 2008-06-05 08:59:10 +0000 | [diff] [blame] | 110 | delete GlobalVariableAnchor; | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 111 | } | 
|  | 112 |  | 
| Chris Lattner | c63a1f2 | 2008-08-04 07:31:14 +0000 | [diff] [blame] | 113 | void CGDebugInfo::setLocation(SourceLocation loc) { | 
|  | 114 | CurLoc = M->getContext().getSourceManager().getLogicalLoc(loc); | 
| Eli Friedman | 32ea35f | 2008-05-29 11:08:17 +0000 | [diff] [blame] | 115 | } | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 116 |  | 
|  | 117 | /// getCastValueFor - Return a llvm representation for a given debug information | 
|  | 118 | /// descriptor cast to an empty struct pointer. | 
|  | 119 | llvm::Value *CGDebugInfo::getCastValueFor(llvm::DebugInfoDesc *DD) { | 
|  | 120 | return llvm::ConstantExpr::getBitCast(SR->Serialize(DD), | 
| Eli Friedman | 86eb311 | 2008-05-13 14:40:48 +0000 | [diff] [blame] | 121 | SR->getEmptyStructPtrType()); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 122 | } | 
|  | 123 |  | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 124 | /// getValueFor - Return a llvm representation for a given debug information | 
|  | 125 | /// descriptor. | 
|  | 126 | llvm::Value *CGDebugInfo::getValueFor(llvm::DebugInfoDesc *DD) { | 
|  | 127 | return SR->Serialize(DD); | 
|  | 128 | } | 
|  | 129 |  | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 130 | /// getOrCreateCompileUnit - Get the compile unit from the cache or create a new | 
|  | 131 | /// one if necessary. | 
|  | 132 | llvm::CompileUnitDesc | 
|  | 133 | *CGDebugInfo::getOrCreateCompileUnit(const SourceLocation Loc) { | 
|  | 134 |  | 
|  | 135 | // See if this compile unit has been used before. | 
|  | 136 | llvm::CompileUnitDesc *&Slot = CompileUnitCache[Loc.getFileID()]; | 
|  | 137 | if (Slot) return Slot; | 
|  | 138 |  | 
|  | 139 | // Create new compile unit. | 
|  | 140 | // FIXME: Where to free these? | 
|  | 141 | // One way is to iterate over the CompileUnitCache in ~CGDebugInfo. | 
|  | 142 | llvm::CompileUnitDesc *Unit = new llvm::CompileUnitDesc(); | 
|  | 143 |  | 
|  | 144 | // Make sure we have an anchor. | 
|  | 145 | if (!CompileUnitAnchor) { | 
|  | 146 | CompileUnitAnchor = new llvm::AnchorDesc(Unit); | 
|  | 147 | } | 
|  | 148 |  | 
|  | 149 | // Get source file information. | 
|  | 150 | SourceManager &SM = M->getContext().getSourceManager(); | 
|  | 151 | const FileEntry *FE = SM.getFileEntryForLoc(Loc); | 
| Eli Friedman | 3f2af10 | 2008-05-22 01:40:10 +0000 | [diff] [blame] | 152 | const char *FileName, *DirName; | 
|  | 153 | if (FE) { | 
|  | 154 | FileName = FE->getName(); | 
|  | 155 | DirName = FE->getDir()->getName(); | 
|  | 156 | } else { | 
|  | 157 | FileName = SM.getSourceName(Loc); | 
|  | 158 | DirName = ""; | 
|  | 159 | } | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 160 |  | 
|  | 161 | Unit->setAnchor(CompileUnitAnchor); | 
|  | 162 | Unit->setFileName(FileName); | 
|  | 163 | Unit->setDirectory(DirName); | 
|  | 164 |  | 
|  | 165 | // Set up producer name. | 
|  | 166 | // FIXME: Do not know how to get clang version yet. | 
|  | 167 | Unit->setProducer("clang"); | 
|  | 168 |  | 
|  | 169 | // Set up Language number. | 
|  | 170 | // FIXME: Handle other languages as well. | 
|  | 171 | Unit->setLanguage(llvm::dwarf::DW_LANG_C89); | 
|  | 172 |  | 
|  | 173 | // Update cache. | 
|  | 174 | Slot = Unit; | 
|  | 175 |  | 
|  | 176 | return Unit; | 
|  | 177 | } | 
|  | 178 |  | 
|  | 179 |  | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 180 | /// getOrCreateCVRType - Get the CVR qualified type from the cache or create | 
|  | 181 | /// a new one if necessary. | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 182 | llvm::TypeDesc * | 
|  | 183 | CGDebugInfo::getOrCreateCVRType(QualType type, llvm::CompileUnitDesc *Unit) | 
|  | 184 | { | 
|  | 185 | // We will create a Derived type. | 
|  | 186 | llvm::DerivedTypeDesc *DTy = NULL; | 
|  | 187 | llvm::TypeDesc *FromTy = NULL; | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 188 |  | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 189 | if (type.isConstQualified()) { | 
|  | 190 | DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_const_type); | 
|  | 191 | type.removeConst(); | 
|  | 192 | FromTy = getOrCreateType(type, Unit); | 
|  | 193 | } else if (type.isVolatileQualified()) { | 
|  | 194 | DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_volatile_type); | 
|  | 195 | type.removeVolatile(); | 
|  | 196 | FromTy = getOrCreateType(type, Unit); | 
|  | 197 | } else if (type.isRestrictQualified()) { | 
|  | 198 | DTy = new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_restrict_type); | 
|  | 199 | type.removeRestrict(); | 
|  | 200 | FromTy = getOrCreateType(type, Unit); | 
|  | 201 | } | 
|  | 202 |  | 
|  | 203 | // No need to fill in the Name, Line, Size, Alignment, Offset in case of        // CVR derived types. | 
|  | 204 | DTy->setContext(Unit); | 
|  | 205 | DTy->setFromType(FromTy); | 
|  | 206 |  | 
|  | 207 | return DTy; | 
|  | 208 | } | 
|  | 209 |  | 
|  | 210 |  | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 211 | /// getOrCreateBuiltinType - Get the Basic type from the cache or create a new | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 212 | /// one if necessary. | 
|  | 213 | llvm::TypeDesc * | 
|  | 214 | CGDebugInfo::getOrCreateBuiltinType(QualType type, llvm::CompileUnitDesc *Unit) | 
|  | 215 | { | 
|  | 216 | assert (type->getTypeClass() == Type::Builtin); | 
|  | 217 |  | 
|  | 218 | const BuiltinType *BT = type->getAsBuiltinType(); | 
|  | 219 |  | 
|  | 220 | unsigned Encoding = 0; | 
|  | 221 | switch (BT->getKind()) | 
|  | 222 | { | 
|  | 223 | case BuiltinType::Void: | 
|  | 224 | return NULL; | 
|  | 225 | case BuiltinType::UChar: | 
|  | 226 | case BuiltinType::Char_U: | 
|  | 227 | Encoding = llvm::dwarf::DW_ATE_unsigned_char; | 
|  | 228 | break; | 
|  | 229 | case BuiltinType::Char_S: | 
|  | 230 | case BuiltinType::SChar: | 
|  | 231 | Encoding = llvm::dwarf::DW_ATE_signed_char; | 
|  | 232 | break; | 
|  | 233 | case BuiltinType::UShort: | 
|  | 234 | case BuiltinType::UInt: | 
|  | 235 | case BuiltinType::ULong: | 
|  | 236 | case BuiltinType::ULongLong: | 
|  | 237 | Encoding = llvm::dwarf::DW_ATE_unsigned; | 
|  | 238 | break; | 
|  | 239 | case BuiltinType::Short: | 
|  | 240 | case BuiltinType::Int: | 
|  | 241 | case BuiltinType::Long: | 
|  | 242 | case BuiltinType::LongLong: | 
|  | 243 | Encoding = llvm::dwarf::DW_ATE_signed; | 
|  | 244 | break; | 
|  | 245 | case BuiltinType::Bool: | 
|  | 246 | Encoding = llvm::dwarf::DW_ATE_boolean; | 
|  | 247 | break; | 
|  | 248 | case BuiltinType::Float: | 
|  | 249 | case BuiltinType::Double: | 
|  | 250 | Encoding = llvm::dwarf::DW_ATE_float; | 
|  | 251 | break; | 
|  | 252 | default: | 
|  | 253 | Encoding = llvm::dwarf::DW_ATE_signed; | 
|  | 254 | break; | 
|  | 255 | } | 
|  | 256 |  | 
|  | 257 | // Ty will have contain the resulting type. | 
|  | 258 | llvm::BasicTypeDesc *BTy = new llvm::BasicTypeDesc(); | 
|  | 259 |  | 
|  | 260 | // Get the name and location early to assist debugging. | 
|  | 261 | const char *TyName = BT->getName(); | 
|  | 262 |  | 
|  | 263 | // Bit size, align and offset of the type. | 
|  | 264 | uint64_t Size = M->getContext().getTypeSize(type); | 
|  | 265 | uint64_t Align = M->getContext().getTypeAlign(type); | 
|  | 266 | uint64_t Offset = 0; | 
|  | 267 |  | 
|  | 268 | // If the type is defined, fill in the details. | 
|  | 269 | if (BTy) { | 
|  | 270 | BTy->setContext(Unit); | 
|  | 271 | BTy->setName(TyName); | 
|  | 272 | BTy->setSize(Size); | 
|  | 273 | BTy->setAlign(Align); | 
|  | 274 | BTy->setOffset(Offset); | 
|  | 275 | BTy->setEncoding(Encoding); | 
|  | 276 | } | 
|  | 277 |  | 
|  | 278 | return BTy; | 
|  | 279 | } | 
|  | 280 |  | 
|  | 281 | llvm::TypeDesc * | 
|  | 282 | CGDebugInfo::getOrCreatePointerType(QualType type, llvm::CompileUnitDesc *Unit) | 
|  | 283 | { | 
|  | 284 | // type* | 
|  | 285 | llvm::DerivedTypeDesc *DTy = | 
|  | 286 | new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_pointer_type); | 
|  | 287 |  | 
|  | 288 | // Handle the derived type. | 
|  | 289 | const PointerType *PTRT = type->getAsPointerType(); | 
|  | 290 | llvm::TypeDesc *FromTy = getOrCreateType(PTRT->getPointeeType(), Unit); | 
|  | 291 |  | 
|  | 292 | // Get the name and location early to assist debugging. | 
|  | 293 | SourceManager &SM = M->getContext().getSourceManager(); | 
|  | 294 | uint64_t Line = SM.getLogicalLineNumber(CurLoc); | 
|  | 295 |  | 
|  | 296 | // Bit size, align and offset of the type. | 
|  | 297 | uint64_t Size = M->getContext().getTypeSize(type); | 
|  | 298 | uint64_t Align = M->getContext().getTypeAlign(type); | 
|  | 299 | uint64_t Offset = 0; | 
|  | 300 |  | 
|  | 301 | // If the type is defined, fill in the details. | 
|  | 302 | if (DTy) { | 
|  | 303 | DTy->setContext(Unit); | 
|  | 304 | DTy->setLine(Line); | 
|  | 305 | DTy->setSize(Size); | 
|  | 306 | DTy->setAlign(Align); | 
|  | 307 | DTy->setOffset(Offset); | 
|  | 308 | DTy->setFromType(FromTy); | 
|  | 309 | } | 
|  | 310 |  | 
|  | 311 | return DTy; | 
|  | 312 | } | 
|  | 313 |  | 
|  | 314 | llvm::TypeDesc * | 
|  | 315 | CGDebugInfo::getOrCreateTypedefType(QualType type, llvm::CompileUnitDesc *Unit) | 
|  | 316 | { | 
|  | 317 | // typedefs are derived from some other type. | 
|  | 318 | llvm::DerivedTypeDesc *DTy = | 
|  | 319 | new llvm::DerivedTypeDesc(llvm::dwarf::DW_TAG_typedef); | 
|  | 320 |  | 
|  | 321 | // Handle derived type. | 
|  | 322 | const TypedefType *TDT = type->getAsTypedefType(); | 
|  | 323 | llvm::TypeDesc *FromTy = getOrCreateType(TDT->LookThroughTypedefs(), | 
|  | 324 | Unit); | 
|  | 325 |  | 
|  | 326 | // Get the name and location early to assist debugging. | 
|  | 327 | const char *TyName = TDT->getDecl()->getName(); | 
|  | 328 | SourceManager &SM = M->getContext().getSourceManager(); | 
|  | 329 | uint64_t Line = SM.getLogicalLineNumber(TDT->getDecl()->getLocation()); | 
|  | 330 |  | 
|  | 331 | // If the type is defined, fill in the details. | 
|  | 332 | if (DTy) { | 
|  | 333 | DTy->setContext(Unit); | 
|  | 334 | DTy->setFile(getOrCreateCompileUnit(TDT->getDecl()->getLocation())); | 
|  | 335 | DTy->setLine(Line); | 
|  | 336 | DTy->setName(TyName); | 
|  | 337 | DTy->setFromType(FromTy); | 
|  | 338 | } | 
|  | 339 |  | 
|  | 340 | return DTy; | 
|  | 341 | } | 
|  | 342 |  | 
|  | 343 | llvm::TypeDesc * | 
|  | 344 | CGDebugInfo::getOrCreateFunctionType(QualType type, llvm::CompileUnitDesc *Unit) | 
|  | 345 | { | 
|  | 346 | llvm::CompositeTypeDesc *SubrTy = | 
|  | 347 | new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_subroutine_type); | 
|  | 348 |  | 
|  | 349 | // Prepare to add the arguments for the subroutine. | 
|  | 350 | std::vector<llvm::DebugInfoDesc *> &Elements = SubrTy->getElements(); | 
|  | 351 |  | 
|  | 352 | // Get result type. | 
|  | 353 | const FunctionType *FT = type->getAsFunctionType(); | 
|  | 354 | llvm::TypeDesc *ArgTy = getOrCreateType(FT->getResultType(), Unit); | 
|  | 355 | if (ArgTy) Elements.push_back(ArgTy); | 
|  | 356 |  | 
|  | 357 | // Set up remainder of arguments. | 
|  | 358 | if (type->getTypeClass() == Type::FunctionProto) { | 
|  | 359 | const FunctionTypeProto *FTPro = dyn_cast<FunctionTypeProto>(type); | 
|  | 360 | for (unsigned int i =0; i < FTPro->getNumArgs(); i++) { | 
|  | 361 | QualType ParamType = FTPro->getArgType(i); | 
|  | 362 | ArgTy = getOrCreateType(ParamType, Unit); | 
|  | 363 | if (ArgTy) Elements.push_back(ArgTy); | 
|  | 364 | } | 
|  | 365 | } | 
|  | 366 |  | 
| Mike Stump | 9ea5884 | 2008-06-19 20:57:50 +0000 | [diff] [blame] | 367 | // FIXME: set other fields file, line here. | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 368 | SubrTy->setContext(Unit); | 
|  | 369 |  | 
|  | 370 | return SubrTy; | 
|  | 371 | } | 
|  | 372 |  | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 373 | /// getOrCreateRecordType - get structure or union type. | 
|  | 374 | llvm::TypeDesc * | 
|  | 375 | CGDebugInfo::getOrCreateRecordType(QualType type, llvm::CompileUnitDesc *Unit) | 
|  | 376 | { | 
|  | 377 | llvm::CompositeTypeDesc *RecType; | 
|  | 378 | if(type->isStructureType()) | 
|  | 379 | RecType = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_structure_type); | 
|  | 380 | else if(type->isUnionType()) | 
|  | 381 | RecType = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_union_type); | 
|  | 382 | else | 
|  | 383 | return NULL; | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 384 |  | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 385 | RecordDecl *RecDecl = type->getAsRecordType()->getDecl(); | 
| Daniel Dunbar | 5273f51 | 2008-10-17 01:07:56 +0000 | [diff] [blame^] | 386 | // We can not get the type for forward declarations. | 
|  | 387 | // FIXME: What *should* we be doing here? | 
|  | 388 | if (!RecDecl->getDefinition(M->getContext())) | 
|  | 389 | return NULL; | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 390 | const ASTRecordLayout &RL = M->getContext().getASTRecordLayout(RecDecl); | 
|  | 391 |  | 
|  | 392 | SourceManager &SM = M->getContext().getSourceManager(); | 
|  | 393 | uint64_t Line = SM.getLogicalLineNumber(RecDecl->getLocation()); | 
|  | 394 |  | 
|  | 395 | std::vector<llvm::DebugInfoDesc *> &Elements = RecType->getElements(); | 
|  | 396 |  | 
|  | 397 | // Add the members. | 
|  | 398 | int NumMembers = RecDecl->getNumMembers(); | 
|  | 399 | for (int i = 0; i < NumMembers; i++) { | 
|  | 400 | FieldDecl *Member = RecDecl->getMember(i); | 
|  | 401 | llvm::TypeDesc *MemberTy = getOrCreateType(Member->getType(), Unit); | 
|  | 402 | MemberTy->setOffset(RL.getFieldOffset(i)); | 
|  | 403 | Elements.push_back(MemberTy); | 
|  | 404 | } | 
|  | 405 |  | 
|  | 406 | // Fill in the blanks. | 
|  | 407 | if(RecType) { | 
|  | 408 | RecType->setContext(Unit); | 
|  | 409 | RecType->setName(RecDecl->getName()); | 
|  | 410 | RecType->setFile(getOrCreateCompileUnit(RecDecl->getLocation())); | 
|  | 411 | RecType->setLine(Line); | 
|  | 412 | RecType->setSize(RL.getSize()); | 
|  | 413 | RecType->setAlign(RL.getAlignment()); | 
|  | 414 | RecType->setOffset(0); | 
|  | 415 | } | 
|  | 416 | return(RecType); | 
|  | 417 | } | 
|  | 418 |  | 
|  | 419 | /// getOrCreateEnumType - get Enum type. | 
|  | 420 | llvm::TypeDesc * | 
|  | 421 | CGDebugInfo::getOrCreateEnumType(QualType type, llvm::CompileUnitDesc *Unit) | 
|  | 422 | { | 
|  | 423 | llvm::CompositeTypeDesc *EnumTy | 
|  | 424 | = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_enumeration_type); | 
|  | 425 |  | 
|  | 426 | EnumType *EType = dyn_cast<EnumType>(type); | 
|  | 427 | if (!EType) return(NULL); | 
|  | 428 |  | 
|  | 429 | EnumDecl *EDecl = EType->getDecl(); | 
|  | 430 | SourceManager &SM = M->getContext().getSourceManager(); | 
|  | 431 | uint64_t Line = SM.getLogicalLineNumber(EDecl->getLocation()); | 
|  | 432 |  | 
|  | 433 | // Size, align and offset of the type. | 
|  | 434 | uint64_t Size = M->getContext().getTypeSize(type); | 
|  | 435 | uint64_t Align = M->getContext().getTypeAlign(type); | 
|  | 436 |  | 
|  | 437 | // Create descriptors for enum members. | 
|  | 438 | std::vector<llvm::DebugInfoDesc *> &Elements = EnumTy->getElements(); | 
|  | 439 | EnumConstantDecl *ElementList = EDecl->getEnumConstantList(); | 
|  | 440 | while (ElementList) { | 
|  | 441 | llvm::EnumeratorDesc *EnumDesc = new llvm::EnumeratorDesc(); | 
|  | 442 | // push it to the enum desc list so that we can free it later. | 
|  | 443 | EnumDescList.push_back(EnumDesc); | 
|  | 444 |  | 
|  | 445 | const char *ElementName = ElementList->getName(); | 
|  | 446 | uint64_t Value = ElementList->getInitVal().getZExtValue(); | 
|  | 447 |  | 
|  | 448 | EnumDesc->setName(ElementName); | 
|  | 449 | EnumDesc->setValue(Value); | 
|  | 450 | Elements.push_back(EnumDesc); | 
|  | 451 | if (ElementList->getNextDeclarator()) | 
|  | 452 | ElementList | 
|  | 453 | = dyn_cast<EnumConstantDecl>(ElementList->getNextDeclarator()); | 
|  | 454 | else | 
|  | 455 | break; | 
|  | 456 | } | 
|  | 457 |  | 
|  | 458 | // Fill in the blanks. | 
|  | 459 | if (EnumTy) { | 
|  | 460 | EnumTy->setContext(Unit); | 
|  | 461 | EnumTy->setName(EDecl->getName()); | 
|  | 462 | EnumTy->setSize(Size); | 
|  | 463 | EnumTy->setAlign(Align); | 
|  | 464 | EnumTy->setOffset(0); | 
|  | 465 | EnumTy->setFile(getOrCreateCompileUnit(EDecl->getLocation())); | 
|  | 466 | EnumTy->setLine(Line); | 
|  | 467 | } | 
|  | 468 | return EnumTy; | 
|  | 469 | } | 
|  | 470 |  | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 471 | /// getOrCreateArrayType - get or create array types. | 
|  | 472 | llvm::TypeDesc * | 
|  | 473 | CGDebugInfo::getOrCreateArrayType(QualType type, llvm::CompileUnitDesc *Unit) | 
|  | 474 | { | 
|  | 475 | llvm::CompositeTypeDesc *ArrayTy | 
|  | 476 | = new llvm::CompositeTypeDesc(llvm::dwarf::DW_TAG_array_type); | 
|  | 477 |  | 
|  | 478 | // Size, align and offset of the type. | 
|  | 479 | uint64_t Size = M->getContext().getTypeSize(type); | 
|  | 480 | uint64_t Align = M->getContext().getTypeAlign(type); | 
|  | 481 |  | 
|  | 482 | SourceManager &SM = M->getContext().getSourceManager(); | 
|  | 483 | uint64_t Line = SM.getLogicalLineNumber(CurLoc); | 
|  | 484 |  | 
|  | 485 | // Add the dimensions of the array. | 
|  | 486 | std::vector<llvm::DebugInfoDesc *> &Elements = ArrayTy->getElements(); | 
|  | 487 | do { | 
| Chris Lattner | c63a1f2 | 2008-08-04 07:31:14 +0000 | [diff] [blame] | 488 | const ArrayType *AT = M->getContext().getAsArrayType(type); | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 489 | llvm::SubrangeDesc *Subrange = new llvm::SubrangeDesc(); | 
|  | 490 |  | 
|  | 491 | // push it back on the subrange desc list so that we can free it later. | 
|  | 492 | SubrangeDescList.push_back(Subrange); | 
|  | 493 |  | 
|  | 494 | uint64_t Upper = 0; | 
| Chris Lattner | c63a1f2 | 2008-08-04 07:31:14 +0000 | [diff] [blame] | 495 | if (const ConstantArrayType *ConstArrTy = dyn_cast<ConstantArrayType>(AT)) { | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 496 | Upper = ConstArrTy->getSize().getZExtValue() - 1; | 
|  | 497 | } | 
|  | 498 | Subrange->setLo(0); | 
|  | 499 | Subrange->setHi(Upper); | 
|  | 500 | Elements.push_back(Subrange); | 
| Chris Lattner | c63a1f2 | 2008-08-04 07:31:14 +0000 | [diff] [blame] | 501 | type = AT->getElementType(); | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 502 | } while (type->isArrayType()); | 
|  | 503 |  | 
|  | 504 | ArrayTy->setFromType(getOrCreateType(type, Unit)); | 
|  | 505 |  | 
|  | 506 | if (ArrayTy) { | 
|  | 507 | ArrayTy->setContext(Unit); | 
|  | 508 | ArrayTy->setSize(Size); | 
|  | 509 | ArrayTy->setAlign(Align); | 
|  | 510 | ArrayTy->setOffset(0); | 
|  | 511 | ArrayTy->setFile(getOrCreateCompileUnit(CurLoc)); | 
|  | 512 | ArrayTy->setLine(Line); | 
|  | 513 | } | 
|  | 514 | return ArrayTy; | 
|  | 515 | } | 
|  | 516 |  | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 517 |  | 
|  | 518 | /// getOrCreateTaggedType - get or create structure/union/Enum type. | 
|  | 519 | llvm::TypeDesc * | 
|  | 520 | CGDebugInfo::getOrCreateTaggedType(QualType type, llvm::CompileUnitDesc *Unit) | 
|  | 521 | { | 
|  | 522 | if (type->isStructureType() || type->isUnionType()) | 
|  | 523 | return getOrCreateRecordType(type, Unit); | 
|  | 524 | else if (type->isEnumeralType()) | 
|  | 525 | return getOrCreateEnumType(type, Unit); | 
|  | 526 | else | 
|  | 527 | return NULL; | 
|  | 528 | } | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 529 |  | 
|  | 530 | /// getOrCreateType - Get the type from the cache or create a new | 
|  | 531 | /// one if necessary. | 
|  | 532 | llvm::TypeDesc * | 
|  | 533 | CGDebugInfo::getOrCreateType(QualType type, llvm::CompileUnitDesc *Unit) | 
|  | 534 | { | 
|  | 535 | if (type.isNull()) | 
|  | 536 | return NULL; | 
|  | 537 |  | 
|  | 538 | // Check to see if the compile unit already has created this type. | 
|  | 539 | llvm::TypeDesc *&Slot = TypeCache[type.getAsOpaquePtr()]; | 
|  | 540 | if (Slot) return Slot; | 
|  | 541 |  | 
|  | 542 | // We need to check for the CVR qualifiers as the first thing. | 
|  | 543 | if (type.getCVRQualifiers()) { | 
|  | 544 | Slot = getOrCreateCVRType (type, Unit); | 
|  | 545 | return Slot; | 
|  | 546 | } | 
|  | 547 |  | 
|  | 548 | // Work out details of type. | 
|  | 549 | switch(type->getTypeClass()) { | 
|  | 550 | case Type::Complex: | 
|  | 551 | case Type::Reference: | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 552 | case Type::Vector: | 
|  | 553 | case Type::ExtVector: | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 554 | case Type::ASQual: | 
|  | 555 | case Type::ObjCInterface: | 
|  | 556 | case Type::ObjCQualifiedInterface: | 
|  | 557 | case Type::ObjCQualifiedId: | 
|  | 558 | case Type::TypeOfExp: | 
|  | 559 | case Type::TypeOfTyp: | 
|  | 560 | default: | 
|  | 561 | { | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 562 | return NULL; | 
|  | 563 | } | 
|  | 564 |  | 
|  | 565 | case Type::TypeName: | 
|  | 566 | Slot = getOrCreateTypedefType(type, Unit); | 
|  | 567 | break; | 
|  | 568 |  | 
|  | 569 | case Type::FunctionProto: | 
|  | 570 | case Type::FunctionNoProto: | 
|  | 571 | Slot = getOrCreateFunctionType(type, Unit); | 
|  | 572 | break; | 
|  | 573 |  | 
|  | 574 | case Type::Builtin: | 
|  | 575 | Slot = getOrCreateBuiltinType(type, Unit); | 
|  | 576 | break; | 
|  | 577 |  | 
|  | 578 | case Type::Pointer: | 
|  | 579 | Slot = getOrCreatePointerType(type, Unit); | 
|  | 580 | break; | 
| Sanjiv Gupta | f58c27a | 2008-06-07 04:46:53 +0000 | [diff] [blame] | 581 |  | 
|  | 582 | case Type::Tagged: | 
|  | 583 | Slot = getOrCreateTaggedType(type, Unit); | 
|  | 584 | break; | 
| Sanjiv Gupta | 507de85 | 2008-06-09 10:47:41 +0000 | [diff] [blame] | 585 |  | 
|  | 586 | case Type::ConstantArray: | 
|  | 587 | case Type::VariableArray: | 
|  | 588 | case Type::IncompleteArray: | 
|  | 589 | Slot = getOrCreateArrayType(type, Unit); | 
|  | 590 | break; | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 591 | } | 
|  | 592 |  | 
|  | 593 | return Slot; | 
|  | 594 | } | 
|  | 595 |  | 
|  | 596 | /// EmitFunctionStart - Constructs the debug code for entering a function - | 
|  | 597 | /// "llvm.dbg.func.start.". | 
|  | 598 | void CGDebugInfo::EmitFunctionStart(const FunctionDecl *FnDecl, | 
|  | 599 | llvm::Function *Fn, | 
| Chris Lattner | 85e3568 | 2008-08-08 19:57:58 +0000 | [diff] [blame] | 600 | llvm::IRBuilder<> &Builder) | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 601 | { | 
|  | 602 | // Create subprogram descriptor. | 
|  | 603 | Subprogram = new llvm::SubprogramDesc(); | 
|  | 604 |  | 
|  | 605 | // Make sure we have an anchor. | 
|  | 606 | if (!SubprogramAnchor) { | 
|  | 607 | SubprogramAnchor = new llvm::AnchorDesc(Subprogram); | 
|  | 608 | } | 
|  | 609 |  | 
|  | 610 | // Get name information. | 
|  | 611 | Subprogram->setName(FnDecl->getName()); | 
|  | 612 | Subprogram->setFullName(FnDecl->getName()); | 
|  | 613 |  | 
|  | 614 | // Gather location information. | 
|  | 615 | llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc); | 
|  | 616 | SourceManager &SM = M->getContext().getSourceManager(); | 
|  | 617 | uint64_t Loc = SM.getLogicalLineNumber(CurLoc); | 
|  | 618 |  | 
|  | 619 | // Get Function Type. | 
|  | 620 | QualType type = FnDecl->getResultType(); | 
|  | 621 | llvm::TypeDesc *SPTy = getOrCreateType(type, Unit); | 
|  | 622 |  | 
|  | 623 | Subprogram->setAnchor(SubprogramAnchor); | 
|  | 624 | Subprogram->setContext(Unit); | 
|  | 625 | Subprogram->setFile(Unit); | 
|  | 626 | Subprogram->setLine(Loc); | 
|  | 627 | Subprogram->setType(SPTy); | 
|  | 628 | Subprogram->setIsStatic(Fn->hasInternalLinkage()); | 
|  | 629 | Subprogram->setIsDefinition(true); | 
|  | 630 |  | 
|  | 631 | // Lazily construct llvm.dbg.func.start. | 
|  | 632 | if (!FuncStartFn) | 
|  | 633 | FuncStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(), | 
|  | 634 | llvm::Intrinsic::dbg_func_start); | 
|  | 635 |  | 
|  | 636 | // Call llvm.dbg.func.start which also implicitly calls llvm.dbg.stoppoint. | 
|  | 637 | Builder.CreateCall(FuncStartFn, getCastValueFor(Subprogram), ""); | 
|  | 638 |  | 
|  | 639 | // Push function on region stack. | 
|  | 640 | RegionStack.push_back(Subprogram); | 
|  | 641 | } | 
|  | 642 |  | 
|  | 643 |  | 
|  | 644 | void | 
| Chris Lattner | 85e3568 | 2008-08-08 19:57:58 +0000 | [diff] [blame] | 645 | CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder<> &Builder) | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 646 | { | 
|  | 647 | if (CurLoc.isInvalid() || CurLoc.isMacroID()) return; | 
|  | 648 |  | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 649 | // Don't bother if things are the same as last time. | 
|  | 650 | SourceManager &SM = M->getContext().getSourceManager(); | 
|  | 651 | if (CurLoc == PrevLoc | 
|  | 652 | || (SM.getLineNumber(CurLoc) == SM.getLineNumber(PrevLoc) | 
|  | 653 | && SM.isFromSameFile(CurLoc, PrevLoc))) | 
|  | 654 | return; | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 655 |  | 
|  | 656 | // Update last state. | 
|  | 657 | PrevLoc = CurLoc; | 
|  | 658 |  | 
|  | 659 | // Get the appropriate compile unit. | 
|  | 660 | llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc); | 
|  | 661 |  | 
|  | 662 | // Lazily construct llvm.dbg.stoppoint function. | 
|  | 663 | if (!StopPointFn) | 
|  | 664 | StopPointFn = llvm::Intrinsic::getDeclaration(&M->getModule(), | 
| Eli Friedman | 86eb311 | 2008-05-13 14:40:48 +0000 | [diff] [blame] | 665 | llvm::Intrinsic::dbg_stoppoint); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 666 |  | 
|  | 667 | uint64_t CurLineNo = SM.getLogicalLineNumber(CurLoc); | 
|  | 668 | uint64_t ColumnNo = SM.getLogicalColumnNumber(CurLoc); | 
|  | 669 |  | 
|  | 670 | // Invoke llvm.dbg.stoppoint | 
|  | 671 | Builder.CreateCall3(StopPointFn, | 
| Eli Friedman | 86eb311 | 2008-05-13 14:40:48 +0000 | [diff] [blame] | 672 | llvm::ConstantInt::get(llvm::Type::Int32Ty, CurLineNo), | 
|  | 673 | llvm::ConstantInt::get(llvm::Type::Int32Ty, ColumnNo), | 
|  | 674 | getCastValueFor(Unit), ""); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 675 | } | 
|  | 676 |  | 
|  | 677 | /// EmitRegionStart- Constructs the debug code for entering a declarative | 
|  | 678 | /// region - "llvm.dbg.region.start.". | 
| Chris Lattner | 85e3568 | 2008-08-08 19:57:58 +0000 | [diff] [blame] | 679 | void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, | 
|  | 680 | llvm::IRBuilder<> &Builder) | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 681 | { | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 682 | llvm::BlockDesc *Block = new llvm::BlockDesc(); | 
| Daniel Dunbar | 5273f51 | 2008-10-17 01:07:56 +0000 | [diff] [blame^] | 683 | if (!RegionStack.empty()) | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 684 | Block->setContext(RegionStack.back()); | 
|  | 685 | RegionStack.push_back(Block); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 686 |  | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 687 | // Lazily construct llvm.dbg.region.start function. | 
|  | 688 | if (!RegionStartFn) | 
|  | 689 | RegionStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(), | 
|  | 690 | llvm::Intrinsic::dbg_region_start); | 
|  | 691 |  | 
|  | 692 | // Call llvm.dbg.func.start. | 
|  | 693 | Builder.CreateCall(RegionStartFn, getCastValueFor(Block), ""); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 694 | } | 
|  | 695 |  | 
|  | 696 | /// EmitRegionEnd - Constructs the debug code for exiting a declarative | 
|  | 697 | /// region - "llvm.dbg.region.end." | 
| Chris Lattner | 85e3568 | 2008-08-08 19:57:58 +0000 | [diff] [blame] | 698 | void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder<> &Builder) | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 699 | { | 
| Daniel Dunbar | 5273f51 | 2008-10-17 01:07:56 +0000 | [diff] [blame^] | 700 | assert(!RegionStack.empty() && "Region stack mismatch, stack empty!"); | 
|  | 701 |  | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 702 | // Lazily construct llvm.dbg.region.end function. | 
|  | 703 | if (!RegionEndFn) | 
|  | 704 | RegionEndFn =llvm::Intrinsic::getDeclaration(&M->getModule(), | 
| Eli Friedman | 86eb311 | 2008-05-13 14:40:48 +0000 | [diff] [blame] | 705 | llvm::Intrinsic::dbg_region_end); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 706 |  | 
|  | 707 | // Provide an region stop point. | 
|  | 708 | EmitStopPoint(Fn, Builder); | 
|  | 709 |  | 
|  | 710 | // Call llvm.dbg.func.end. | 
| Sanjiv Gupta | 1c6a38b | 2008-05-25 05:15:42 +0000 | [diff] [blame] | 711 | llvm::DebugInfoDesc *DID = RegionStack.back(); | 
|  | 712 | Builder.CreateCall(RegionEndFn, getCastValueFor(DID), ""); | 
|  | 713 | RegionStack.pop_back(); | 
| Sanjiv Gupta | e8b9f5b | 2008-05-08 08:54:20 +0000 | [diff] [blame] | 714 | } | 
|  | 715 |  | 
| Sanjiv Gupta | cc9b163 | 2008-05-30 10:30:31 +0000 | [diff] [blame] | 716 | /// EmitDeclare - Emit local variable declaration debug info. | 
|  | 717 | void CGDebugInfo::EmitDeclare(const VarDecl *decl, unsigned Tag, | 
|  | 718 | llvm::Value *AI, | 
| Chris Lattner | 85e3568 | 2008-08-08 19:57:58 +0000 | [diff] [blame] | 719 | llvm::IRBuilder<> &Builder) | 
| Sanjiv Gupta | cc9b163 | 2008-05-30 10:30:31 +0000 | [diff] [blame] | 720 | { | 
| Daniel Dunbar | 5273f51 | 2008-10-17 01:07:56 +0000 | [diff] [blame^] | 721 | assert(!RegionStack.empty() && "Region stack mismatch, stack empty!"); | 
|  | 722 |  | 
| Sanjiv Gupta | cc9b163 | 2008-05-30 10:30:31 +0000 | [diff] [blame] | 723 | // FIXME: If it is a compiler generated temporary then return. | 
|  | 724 |  | 
|  | 725 | // Construct llvm.dbg.declare function. | 
|  | 726 | if (!DeclareFn) | 
|  | 727 | DeclareFn = llvm::Intrinsic::getDeclaration(&M->getModule(), | 
| Mike Stump | 9ea5884 | 2008-06-19 20:57:50 +0000 | [diff] [blame] | 728 | llvm::Intrinsic::dbg_declare); | 
| Sanjiv Gupta | cc9b163 | 2008-05-30 10:30:31 +0000 | [diff] [blame] | 729 |  | 
|  | 730 | // Get type information. | 
|  | 731 | llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc); | 
|  | 732 | llvm::TypeDesc *TyDesc = getOrCreateType(decl->getType(), Unit); | 
|  | 733 |  | 
|  | 734 | SourceManager &SM = M->getContext().getSourceManager(); | 
|  | 735 | uint64_t Loc = SM.getLogicalLineNumber(CurLoc); | 
|  | 736 |  | 
|  | 737 | // Construct variable. | 
|  | 738 | llvm::VariableDesc *Variable = new llvm::VariableDesc(Tag); | 
|  | 739 | Variable->setContext(RegionStack.back()); | 
|  | 740 | Variable->setName(decl->getName()); | 
|  | 741 | Variable->setFile(Unit); | 
|  | 742 | Variable->setLine(Loc); | 
|  | 743 | Variable->setType(TyDesc); | 
|  | 744 |  | 
|  | 745 | // Push it onto the list so that we can free it. | 
|  | 746 | VariableDescList.push_back(Variable); | 
|  | 747 |  | 
|  | 748 | // Cast the AllocA result to a {}* for the call to llvm.dbg.declare. | 
|  | 749 | // These bit cast instructions will get freed when the basic block is | 
|  | 750 | // deleted. So do not need to free them explicity. | 
|  | 751 | const llvm::PointerType *EmpPtr = SR->getEmptyStructPtrType(); | 
|  | 752 | llvm::Value *AllocACast =  new llvm::BitCastInst(AI, EmpPtr, decl->getName(), | 
|  | 753 | Builder.GetInsertBlock()); | 
|  | 754 |  | 
|  | 755 | // Call llvm.dbg.declare. | 
|  | 756 | Builder.CreateCall2(DeclareFn, AllocACast, getCastValueFor(Variable), ""); | 
|  | 757 | } | 
|  | 758 |  | 
| Sanjiv Gupta | 686226b | 2008-06-05 08:59:10 +0000 | [diff] [blame] | 759 | /// EmitGlobalVariable - Emit information about a global variable. | 
|  | 760 | void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *GV, | 
|  | 761 | const VarDecl *decl) | 
|  | 762 | { | 
|  | 763 | // Create global variable debug descriptor. | 
|  | 764 | llvm::GlobalVariableDesc *Global = new llvm::GlobalVariableDesc(); | 
|  | 765 |  | 
|  | 766 | // Push it onto the list so that we can free it. | 
|  | 767 | GlobalVarDescList.push_back(Global); | 
|  | 768 |  | 
|  | 769 | // Make sure we have an anchor. | 
|  | 770 | if (!GlobalVariableAnchor) | 
|  | 771 | GlobalVariableAnchor = new llvm::AnchorDesc(Global); | 
|  | 772 |  | 
|  | 773 | // Get name information. | 
|  | 774 | Global->setName(decl->getName()); | 
|  | 775 | Global->setFullName(decl->getName()); | 
|  | 776 |  | 
|  | 777 | llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc); | 
|  | 778 | SourceManager &SM = M->getContext().getSourceManager(); | 
|  | 779 | uint64_t Loc = SM.getLogicalLineNumber(CurLoc); | 
|  | 780 |  | 
|  | 781 | llvm::TypeDesc *TyD = getOrCreateType(decl->getType(), Unit); | 
|  | 782 |  | 
|  | 783 | // Fill in the Global information. | 
|  | 784 | Global->setAnchor(GlobalVariableAnchor); | 
|  | 785 | Global->setContext(Unit); | 
|  | 786 | Global->setFile(Unit); | 
|  | 787 | Global->setLine(Loc); | 
|  | 788 | Global->setType(TyD); | 
|  | 789 | Global->setIsDefinition(true); | 
|  | 790 | Global->setIsStatic(GV->hasInternalLinkage()); | 
|  | 791 | Global->setGlobalVariable(GV); | 
|  | 792 |  | 
|  | 793 | // Make sure global is created if needed. | 
|  | 794 | getValueFor(Global); | 
|  | 795 | } | 
|  | 796 |  |