summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/IR/DebugInfo.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-11-24 17:02:24 +0000
committerdim <dim@FreeBSD.org>2014-11-24 17:02:24 +0000
commit2c8643c6396b0a3db33430cf9380e70bbb9efce0 (patch)
tree4df130b28021d86e13bf4565ef58c1c5a5e093b4 /contrib/llvm/lib/IR/DebugInfo.cpp
parent678318cd20f7db4e6c6b85d83fe00fa327b04fca (diff)
parente27feadae0885aa074df58ebfda2e7a7f7a7d590 (diff)
downloadFreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.zip
FreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.tar.gz
Merge llvm 3.5.0 release from ^/vendor/llvm/dist, resolve conflicts, and
preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/lib/IR/DebugInfo.cpp')
-rw-r--r--contrib/llvm/lib/IR/DebugInfo.cpp226
1 files changed, 143 insertions, 83 deletions
diff --git a/contrib/llvm/lib/IR/DebugInfo.cpp b/contrib/llvm/lib/IR/DebugInfo.cpp
index 70a756f..5e39b24 100644
--- a/contrib/llvm/lib/IR/DebugInfo.cpp
+++ b/contrib/llvm/lib/IR/DebugInfo.cpp
@@ -12,7 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo.h"
+#include "llvm/IR/DebugInfo.h"
+#include "LLVMContextImpl.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
@@ -23,9 +24,9 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::dwarf;
@@ -45,14 +46,15 @@ bool DIDescriptor::Verify() const {
DILexicalBlockFile(DbgNode).Verify() ||
DISubrange(DbgNode).Verify() || DIEnumerator(DbgNode).Verify() ||
DIObjCProperty(DbgNode).Verify() ||
+ DIUnspecifiedParameter(DbgNode).Verify() ||
DITemplateTypeParameter(DbgNode).Verify() ||
DITemplateValueParameter(DbgNode).Verify() ||
DIImportedEntity(DbgNode).Verify());
}
static Value *getField(const MDNode *DbgNode, unsigned Elt) {
- if (DbgNode == 0 || Elt >= DbgNode->getNumOperands())
- return 0;
+ if (!DbgNode || Elt >= DbgNode->getNumOperands())
+ return nullptr;
return DbgNode->getOperand(Elt);
}
@@ -71,7 +73,7 @@ StringRef DIDescriptor::getStringField(unsigned Elt) const {
}
uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
- if (DbgNode == 0)
+ if (!DbgNode)
return 0;
if (Elt < DbgNode->getNumOperands())
@@ -83,7 +85,7 @@ uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
}
int64_t DIDescriptor::getInt64Field(unsigned Elt) const {
- if (DbgNode == 0)
+ if (!DbgNode)
return 0;
if (Elt < DbgNode->getNumOperands())
@@ -100,34 +102,34 @@ DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const {
}
GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const {
- if (DbgNode == 0)
- return 0;
+ if (!DbgNode)
+ return nullptr;
if (Elt < DbgNode->getNumOperands())
return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt));
- return 0;
+ return nullptr;
}
Constant *DIDescriptor::getConstantField(unsigned Elt) const {
- if (DbgNode == 0)
- return 0;
+ if (!DbgNode)
+ return nullptr;
if (Elt < DbgNode->getNumOperands())
return dyn_cast_or_null<Constant>(DbgNode->getOperand(Elt));
- return 0;
+ return nullptr;
}
Function *DIDescriptor::getFunctionField(unsigned Elt) const {
- if (DbgNode == 0)
- return 0;
+ if (!DbgNode)
+ return nullptr;
if (Elt < DbgNode->getNumOperands())
return dyn_cast_or_null<Function>(DbgNode->getOperand(Elt));
- return 0;
+ return nullptr;
}
void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) {
- if (DbgNode == 0)
+ if (!DbgNode)
return;
if (Elt < DbgNode->getNumOperands()) {
@@ -136,8 +138,14 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) {
}
}
-unsigned DIVariable::getNumAddrElements() const {
- return DbgNode->getNumOperands() - 8;
+uint64_t DIVariable::getAddrElement(unsigned Idx) const {
+ DIDescriptor ComplexExpr = getDescriptorField(8);
+ if (Idx < ComplexExpr->getNumOperands())
+ if (auto *CI = dyn_cast_or_null<ConstantInt>(ComplexExpr->getOperand(Idx)))
+ return CI->getZExtValue();
+
+ assert(false && "non-existing complex address element requested");
+ return 0;
}
/// getInlinedAt - If this variable is inlined then return inline location.
@@ -333,7 +341,7 @@ unsigned DIArray::getNumElements() const {
/// replaceAllUsesWith - Replace all uses of the MDNode used by this
/// type with the one in the passed descriptor.
-void DIType::replaceAllUsesWith(DIDescriptor &D) {
+void DIType::replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D) {
assert(DbgNode && "Trying to replace an unverified type!");
@@ -342,13 +350,19 @@ void DIType::replaceAllUsesWith(DIDescriptor &D) {
// which, due to uniquing, has merged with the source. We shield clients from
// this detail by allowing a value to be replaced with replaceAllUsesWith()
// itself.
- if (DbgNode != D) {
- MDNode *Node = const_cast<MDNode *>(DbgNode);
- const MDNode *DN = D;
- const Value *V = cast_or_null<Value>(DN);
- Node->replaceAllUsesWith(const_cast<Value *>(V));
- MDNode::deleteTemporary(Node);
+ const MDNode *DN = D;
+ if (DbgNode == DN) {
+ SmallVector<Value*, 10> Ops(DbgNode->getNumOperands());
+ for (size_t i = 0; i != Ops.size(); ++i)
+ Ops[i] = DbgNode->getOperand(i);
+ DN = MDNode::get(VMContext, Ops);
}
+
+ MDNode *Node = const_cast<MDNode *>(DbgNode);
+ const Value *V = cast_or_null<Value>(DN);
+ Node->replaceAllUsesWith(const_cast<Value *>(V));
+ MDNode::deleteTemporary(Node);
+ DbgNode = D;
}
/// replaceAllUsesWith - Replace all uses of the MDNode used by this
@@ -356,19 +370,12 @@ void DIType::replaceAllUsesWith(DIDescriptor &D) {
void DIType::replaceAllUsesWith(MDNode *D) {
assert(DbgNode && "Trying to replace an unverified type!");
-
- // Since we use a TrackingVH for the node, its easy for clients to manufacture
- // legitimate situations where they want to replaceAllUsesWith() on something
- // which, due to uniquing, has merged with the source. We shield clients from
- // this detail by allowing a value to be replaced with replaceAllUsesWith()
- // itself.
- if (DbgNode != D) {
- MDNode *Node = const_cast<MDNode *>(DbgNode);
- const MDNode *DN = D;
- const Value *V = cast_or_null<Value>(DN);
- Node->replaceAllUsesWith(const_cast<Value *>(V));
- MDNode::deleteTemporary(Node);
- }
+ assert(DbgNode != D && "This replacement should always happen");
+ MDNode *Node = const_cast<MDNode *>(DbgNode);
+ const MDNode *DN = D;
+ const Value *V = cast_or_null<Value>(DN);
+ Node->replaceAllUsesWith(const_cast<Value *>(V));
+ MDNode::deleteTemporary(Node);
}
/// Verify - Verify that a compile unit is well formed.
@@ -381,7 +388,7 @@ bool DICompileUnit::Verify() const {
if (getFilename().empty())
return false;
- return DbgNode->getNumOperands() == 13;
+ return DbgNode->getNumOperands() == 14;
}
/// Verify - Verify that an ObjC property is well formed.
@@ -427,8 +434,10 @@ static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) {
/// Check if a value can be a ScopeRef.
static bool isScopeRef(const Value *Val) {
return !Val ||
- (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||
- (isa<MDNode>(Val) && DIScope(cast<MDNode>(Val)).isScope());
+ (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||
+ // Not checking for Val->isScope() here, because it would work
+ // only for lexical scopes and not all subclasses of DIScope.
+ isa<MDNode>(Val);
}
/// Check if a field at position Elt of a MDNode can be a ScopeRef.
@@ -461,14 +470,13 @@ bool DIType::Verify() const {
// DIType is abstract, it should be a BasicType, a DerivedType or
// a CompositeType.
if (isBasicType())
- DIBasicType(DbgNode).Verify();
+ return DIBasicType(DbgNode).Verify();
else if (isCompositeType())
- DICompositeType(DbgNode).Verify();
+ return DICompositeType(DbgNode).Verify();
else if (isDerivedType())
- DIDerivedType(DbgNode).Verify();
+ return DIDerivedType(DbgNode).Verify();
else
return false;
- return true;
}
/// Verify - Verify that a basic type descriptor is well formed.
@@ -505,6 +513,10 @@ bool DICompositeType::Verify() const {
if (!fieldIsMDString(DbgNode, 14))
return false;
+ // A subroutine type can't be both & and &&.
+ if (isLValueReference() && isRValueReference())
+ return false;
+
return DbgNode->getNumOperands() == 15;
}
@@ -521,6 +533,11 @@ bool DISubprogram::Verify() const {
// Containing type @ field 12.
if (!fieldIsTypeRef(DbgNode, 12))
return false;
+
+ // A subprogram can't be both & and &&.
+ if (isLValueReference() && isRValueReference())
+ return false;
+
return DbgNode->getNumOperands() == 20;
}
@@ -531,10 +548,11 @@ bool DIGlobalVariable::Verify() const {
if (getDisplayName().empty())
return false;
- // Make sure context @ field 2 and type @ field 8 are MDNodes.
+ // Make sure context @ field 2 is an MDNode.
if (!fieldIsMDNode(DbgNode, 2))
return false;
- if (!fieldIsMDNode(DbgNode, 8))
+ // Make sure that type @ field 8 is a DITypeRef.
+ if (!fieldIsTypeRef(DbgNode, 8))
return false;
// Make sure StaticDataMemberDeclaration @ field 12 is MDNode.
if (!fieldIsMDNode(DbgNode, 12))
@@ -548,12 +566,19 @@ bool DIVariable::Verify() const {
if (!isVariable())
return false;
- // Make sure context @ field 1 and type @ field 5 are MDNodes.
+ // Make sure context @ field 1 is an MDNode.
if (!fieldIsMDNode(DbgNode, 1))
return false;
- if (!fieldIsMDNode(DbgNode, 5))
+ // Make sure that type @ field 5 is a DITypeRef.
+ if (!fieldIsTypeRef(DbgNode, 5))
return false;
- return DbgNode->getNumOperands() >= 8;
+
+ // Variable without a complex expression.
+ if (DbgNode->getNumOperands() == 8)
+ return true;
+
+ // Make sure the complex expression is an MDNode.
+ return (DbgNode->getNumOperands() == 9 && fieldIsMDNode(DbgNode, 8));
}
/// Verify - Verify that a location descriptor is well formed.
@@ -591,7 +616,7 @@ bool DISubrange::Verify() const {
/// \brief Verify that the lexical block descriptor is well formed.
bool DILexicalBlock::Verify() const {
- return isLexicalBlock() && DbgNode->getNumOperands() == 6;
+ return isLexicalBlock() && DbgNode->getNumOperands() == 7;
}
/// \brief Verify that the file-scoped lexical block descriptor is well formed.
@@ -599,6 +624,11 @@ bool DILexicalBlockFile::Verify() const {
return isLexicalBlockFile() && DbgNode->getNumOperands() == 3;
}
+/// \brief Verify that an unspecified parameter descriptor is well formed.
+bool DIUnspecifiedParameter::Verify() const {
+ return isUnspecifiedParameter() && DbgNode->getNumOperands() == 1;
+}
+
/// \brief Verify that the template type parameter descriptor is well formed.
bool DITemplateTypeParameter::Verify() const {
return isTemplateTypeParameter() && DbgNode->getNumOperands() == 7;
@@ -658,19 +688,6 @@ void DICompositeType::setTypeArray(DIArray Elements, DIArray TParams) {
DbgNode = N;
}
-void DICompositeType::addMember(DIDescriptor D) {
- SmallVector<llvm::Value *, 16> M;
- DIArray OrigM = getTypeArray();
- unsigned Elements = OrigM.getNumElements();
- if (Elements == 1 && !OrigM.getElement(0))
- Elements = 0;
- M.reserve(Elements + 1);
- for (unsigned i = 0; i != Elements; ++i)
- M.push_back(OrigM.getElement(i));
- M.push_back(D);
- setTypeArray(DIArray(MDNode::get(DbgNode->getContext(), M)));
-}
-
/// Generate a reference to this DIType. Uses the type identifier instead
/// of the actual MDNode if possible, to help type uniquing.
DIScopeRef DIScope::getRef() const {
@@ -753,7 +770,7 @@ DIScopeRef DIScope::getContext() const {
return DIScopeRef(DINameSpace(DbgNode).getContext());
assert((isFile() || isCompileUnit()) && "Unhandled type of scope.");
- return DIScopeRef(NULL);
+ return DIScopeRef(nullptr);
}
// If the scope node has a name, return that, else return an empty string.
@@ -817,6 +834,29 @@ DIArray DICompileUnit::getImportedEntities() const {
return DIArray(getNodeField(DbgNode, 11));
}
+/// copyWithNewScope - Return a copy of this location, replacing the
+/// current scope with the given one.
+DILocation DILocation::copyWithNewScope(LLVMContext &Ctx,
+ DILexicalBlock NewScope) {
+ SmallVector<Value *, 10> Elts;
+ assert(Verify());
+ for (unsigned I = 0; I < DbgNode->getNumOperands(); ++I) {
+ if (I != 2)
+ Elts.push_back(DbgNode->getOperand(I));
+ else
+ Elts.push_back(NewScope);
+ }
+ MDNode *NewDIL = MDNode::get(Ctx, Elts);
+ return DILocation(NewDIL);
+}
+
+/// computeNewDiscriminator - Generate a new discriminator value for this
+/// file and line location.
+unsigned DILocation::computeNewDiscriminator(LLVMContext &Ctx) {
+ std::pair<const char *, unsigned> Key(getFilename().data(), getLineNumber());
+ return ++Ctx.pImpl->DiscriminatorTable[Key];
+}
+
/// fixupSubprogramName - Replace contains special characters used
/// in a typical Objective-C names with '.' in a given string.
static void fixupSubprogramName(DISubprogram Fn, SmallVectorImpl<char> &Out) {
@@ -974,7 +1014,7 @@ void DebugInfoFinder::processModule(const Module &M) {
DIGlobalVariable DIG(GVs.getElement(i));
if (addGlobalVariable(DIG)) {
processScope(DIG.getContext());
- processType(DIG.getType());
+ processType(DIG.getType().resolve(TypeIdentifierMap));
}
}
DIArray SPs = CU.getSubprograms();
@@ -989,7 +1029,7 @@ void DebugInfoFinder::processModule(const Module &M) {
DIArray Imports = CU.getImportedEntities();
for (unsigned i = 0, e = Imports.getNumElements(); i != e; ++i) {
DIImportedEntity Import = DIImportedEntity(Imports.getElement(i));
- DIDescriptor Entity = Import.getEntity();
+ DIDescriptor Entity = Import.getEntity().resolve(TypeIdentifierMap);
if (Entity.isType())
processType(DIType(Entity));
else if (Entity.isSubprogram())
@@ -1060,18 +1100,6 @@ void DebugInfoFinder::processScope(DIScope Scope) {
}
}
-/// processLexicalBlock
-void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) {
- DIScope Context = LB.getContext();
- if (Context.isLexicalBlock())
- return processLexicalBlock(DILexicalBlock(Context));
- else if (Context.isLexicalBlockFile()) {
- DILexicalBlockFile DBF = DILexicalBlockFile(Context);
- return processLexicalBlock(DILexicalBlock(DBF.getScope()));
- } else
- return processSubprogram(DISubprogram(Context));
-}
-
/// processSubprogram - Process DISubprogram.
void DebugInfoFinder::processSubprogram(DISubprogram SP) {
if (!addSubprogram(SP))
@@ -1108,7 +1136,7 @@ void DebugInfoFinder::processDeclare(const Module &M,
if (!NodesSeen.insert(DV))
return;
processScope(DIVariable(N).getContext());
- processType(DIVariable(N).getType());
+ processType(DIVariable(N).getType().resolve(TypeIdentifierMap));
}
void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) {
@@ -1124,7 +1152,7 @@ void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) {
if (!NodesSeen.insert(DV))
return;
processScope(DIVariable(N).getContext());
- processType(DIVariable(N).getType());
+ processType(DIVariable(N).getType().resolve(TypeIdentifierMap));
}
/// addType - Add type into Tys.
@@ -1298,6 +1326,12 @@ void DIType::printInternal(raw_ostream &OS) const {
OS << " [vector]";
if (isStaticMember())
OS << " [static]";
+
+ if (isLValueReference())
+ OS << " [reference]";
+
+ if (isRValueReference())
+ OS << " [rvalue reference]";
}
void DIDerivedType::printInternal(raw_ostream &OS) const {
@@ -1337,6 +1371,12 @@ void DISubprogram::printInternal(raw_ostream &OS) const {
else if (isProtected())
OS << " [protected]";
+ if (isLValueReference())
+ OS << " [reference]";
+
+ if (isRValueReference())
+ OS << " [rvalue reference]";
+
StringRef Res = getName();
if (!Res.empty())
OS << " [" << Res << ']';
@@ -1439,7 +1479,7 @@ bool llvm::StripDebugInfo(Module &M) {
// the module.
if (Function *Declare = M.getFunction("llvm.dbg.declare")) {
while (!Declare->use_empty()) {
- CallInst *CI = cast<CallInst>(Declare->use_back());
+ CallInst *CI = cast<CallInst>(Declare->user_back());
CI->eraseFromParent();
}
Declare->eraseFromParent();
@@ -1448,7 +1488,7 @@ bool llvm::StripDebugInfo(Module &M) {
if (Function *DbgVal = M.getFunction("llvm.dbg.value")) {
while (!DbgVal->use_empty()) {
- CallInst *CI = cast<CallInst>(DbgVal->use_back());
+ CallInst *CI = cast<CallInst>(DbgVal->user_back());
CI->eraseFromParent();
}
DbgVal->eraseFromParent();
@@ -1486,3 +1526,23 @@ unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
return 0;
return cast<ConstantInt>(Val)->getZExtValue();
}
+
+llvm::DenseMap<const llvm::Function *, llvm::DISubprogram>
+llvm::makeSubprogramMap(const Module &M) {
+ DenseMap<const Function *, DISubprogram> R;
+
+ NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu");
+ if (!CU_Nodes)
+ return R;
+
+ for (MDNode *N : CU_Nodes->operands()) {
+ DICompileUnit CUNode(N);
+ DIArray SPs = CUNode.getSubprograms();
+ for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
+ DISubprogram SP(SPs.getElement(i));
+ if (Function *F = SP.getFunction())
+ R.insert(std::make_pair(F, SP));
+ }
+ }
+ return R;
+}
OpenPOWER on IntegriCloud