AsmWriter: Extract writeMetadataAsOperand(), NFC
[oota-llvm.git] / lib / IR / DebugInfoMetadata.cpp
1 //===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the debug info Metadata classes.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/IR/DebugInfoMetadata.h"
15 #include "LLVMContextImpl.h"
16 #include "MetadataImpl.h"
17
18 using namespace llvm;
19
20 MDLocation::MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
21                        unsigned Column, ArrayRef<Metadata *> MDs)
22     : MDNode(C, MDLocationKind, Storage, MDs) {
23   assert((MDs.size() == 1 || MDs.size() == 2) &&
24          "Expected a scope and optional inlined-at");
25
26   // Set line and column.
27   assert(Line < (1u << 24) && "Expected 24-bit line");
28   assert(Column < (1u << 16) && "Expected 16-bit column");
29
30   SubclassData32 = Line;
31   SubclassData16 = Column;
32 }
33
34 static void adjustLine(unsigned &Line) {
35   // Set to unknown on overflow.  Still use 24 bits for now.
36   if (Line >= (1u << 24))
37     Line = 0;
38 }
39
40 static void adjustColumn(unsigned &Column) {
41   // Set to unknown on overflow.  We only have 16 bits to play with here.
42   if (Column >= (1u << 16))
43     Column = 0;
44 }
45
46 MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line,
47                                 unsigned Column, Metadata *Scope,
48                                 Metadata *InlinedAt, StorageType Storage,
49                                 bool ShouldCreate) {
50   // Fixup line/column.
51   adjustLine(Line);
52   adjustColumn(Column);
53
54   if (Storage == Uniqued) {
55     if (auto *N =
56             getUniqued(Context.pImpl->MDLocations,
57                        MDLocationInfo::KeyTy(Line, Column, Scope, InlinedAt)))
58       return N;
59     if (!ShouldCreate)
60       return nullptr;
61   } else {
62     assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
63   }
64
65   SmallVector<Metadata *, 2> Ops;
66   Ops.push_back(Scope);
67   if (InlinedAt)
68     Ops.push_back(InlinedAt);
69   return storeImpl(new (Ops.size())
70                        MDLocation(Context, Storage, Line, Column, Ops),
71                    Storage, Context.pImpl->MDLocations);
72 }
73
74 static StringRef getString(const MDString *S) {
75   if (S)
76     return S->getString();
77   return StringRef();
78 }
79
80 #ifndef NDEBUG
81 static bool isCanonical(const MDString *S) {
82   return !S || !S->getString().empty();
83 }
84 #endif
85
86 GenericDebugNode *GenericDebugNode::getImpl(LLVMContext &Context, unsigned Tag,
87                                             MDString *Header,
88                                             ArrayRef<Metadata *> DwarfOps,
89                                             StorageType Storage,
90                                             bool ShouldCreate) {
91   unsigned Hash = 0;
92   if (Storage == Uniqued) {
93     GenericDebugNodeInfo::KeyTy Key(Tag, getString(Header), DwarfOps);
94     if (auto *N = getUniqued(Context.pImpl->GenericDebugNodes, Key))
95       return N;
96     if (!ShouldCreate)
97       return nullptr;
98     Hash = Key.getHash();
99   } else {
100     assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
101   }
102
103   // Use a nullptr for empty headers.
104   assert(isCanonical(Header) && "Expected canonical MDString");
105   Metadata *PreOps[] = {Header};
106   return storeImpl(new (DwarfOps.size() + 1) GenericDebugNode(
107                        Context, Storage, Hash, Tag, PreOps, DwarfOps),
108                    Storage, Context.pImpl->GenericDebugNodes);
109 }
110
111 void GenericDebugNode::recalculateHash() {
112   setHash(GenericDebugNodeInfo::KeyTy::calculateHash(this));
113 }