aboutsummaryrefslogtreecommitdiffstats
path: root/lib/IR
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR')
-rw-r--r--lib/IR/Android.mk1
-rw-r--r--lib/IR/AsmWriter.cpp156
-rw-r--r--lib/IR/AttributeImpl.h8
-rw-r--r--lib/IR/Attributes.cpp85
-rw-r--r--lib/IR/AutoUpgrade.cpp51
-rw-r--r--lib/IR/BasicBlock.cpp4
-rw-r--r--lib/IR/CMakeLists.txt1
-rw-r--r--lib/IR/ConstantFold.cpp39
-rw-r--r--lib/IR/Constants.cpp27
-rw-r--r--lib/IR/Core.cpp16
-rw-r--r--lib/IR/DIBuilder.cpp702
-rw-r--r--lib/IR/DebugInfo.cpp828
-rw-r--r--lib/IR/DebugInfoMetadata.cpp148
-rw-r--r--lib/IR/DebugLoc.cpp126
-rw-r--r--lib/IR/DiagnosticInfo.cpp12
-rw-r--r--lib/IR/Function.cpp13
-rw-r--r--lib/IR/GCOV.cpp2
-rw-r--r--lib/IR/IRBuilder.cpp3
-rw-r--r--lib/IR/IRPrintingPasses.cpp19
-rw-r--r--lib/IR/InlineAsm.cpp4
-rw-r--r--lib/IR/Instruction.cpp4
-rw-r--r--lib/IR/Instructions.cpp38
-rw-r--r--lib/IR/LLVMContextImpl.h189
-rw-r--r--lib/IR/LegacyPassManager.cpp2
-rw-r--r--lib/IR/Metadata.cpp8
-rw-r--r--lib/IR/UseListOrder.cpp43
-rw-r--r--lib/IR/Value.cpp4
-rw-r--r--lib/IR/Verifier.cpp566
28 files changed, 1499 insertions, 1600 deletions
diff --git a/lib/IR/Android.mk b/lib/IR/Android.mk
index 2ca02f7..32ebfae 100644
--- a/lib/IR/Android.mk
+++ b/lib/IR/Android.mk
@@ -43,7 +43,6 @@ vmcore_SRC_FILES := \
Type.cpp \
TypeFinder.cpp \
Use.cpp \
- UseListOrder.cpp \
User.cpp \
Value.cpp \
ValueSymbolTable.cpp \
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp
index ae0beba..48737b5 100644
--- a/lib/IR/AsmWriter.cpp
+++ b/lib/IR/AsmWriter.cpp
@@ -401,9 +401,7 @@ public:
/// NumberedTypes - The numbered types, along with their value.
DenseMap<StructType*, unsigned> NumberedTypes;
-
- TypePrinting() {}
- ~TypePrinting() {}
+ TypePrinting() = default;
void incorporateTypes(const Module &M);
@@ -1443,11 +1441,11 @@ void MDFieldPrinter::printDIFlags(StringRef Name, unsigned Flags) {
Out << FS << Name << ": ";
SmallVector<unsigned, 8> SplitFlags;
- unsigned Extra = DIDescriptor::splitFlags(Flags, SplitFlags);
+ unsigned Extra = DebugNode::splitFlags(Flags, SplitFlags);
FieldSeparator FlagsFS(" | ");
for (unsigned F : SplitFlags) {
- const char *StringF = DIDescriptor::getFlagString(F);
+ const char *StringF = DebugNode::getFlagString(F);
assert(StringF && "Expected valid flag");
Out << FlagsFS << StringF;
}
@@ -1505,7 +1503,7 @@ static void writeMDSubrange(raw_ostream &Out, const MDSubrange *N,
Out << "!MDSubrange(";
MDFieldPrinter Printer(Out);
Printer.printInt("count", N->getCount(), /* ShouldSkipZero */ false);
- Printer.printInt("lowerBound", N->getLo());
+ Printer.printInt("lowerBound", N->getLowerBound());
Out << ")";
}
@@ -1539,16 +1537,16 @@ static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printTag(N);
Printer.printString("name", N->getName());
- Printer.printMetadata("scope", N->getScope());
- Printer.printMetadata("file", N->getFile());
+ Printer.printMetadata("scope", N->getRawScope());
+ Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
- Printer.printMetadata("baseType", N->getBaseType(),
+ Printer.printMetadata("baseType", N->getRawBaseType(),
/* ShouldSkipNull */ false);
Printer.printInt("size", N->getSizeInBits());
Printer.printInt("align", N->getAlignInBits());
Printer.printInt("offset", N->getOffsetInBits());
Printer.printDIFlags("flags", N->getFlags());
- Printer.printMetadata("extraData", N->getExtraData());
+ Printer.printMetadata("extraData", N->getRawExtraData());
Out << ")";
}
@@ -1559,19 +1557,19 @@ static void writeMDCompositeType(raw_ostream &Out, const MDCompositeType *N,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printTag(N);
Printer.printString("name", N->getName());
- Printer.printMetadata("scope", N->getScope());
- Printer.printMetadata("file", N->getFile());
+ Printer.printMetadata("scope", N->getRawScope());
+ Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
- Printer.printMetadata("baseType", N->getBaseType());
+ Printer.printMetadata("baseType", N->getRawBaseType());
Printer.printInt("size", N->getSizeInBits());
Printer.printInt("align", N->getAlignInBits());
Printer.printInt("offset", N->getOffsetInBits());
Printer.printDIFlags("flags", N->getFlags());
- Printer.printMetadata("elements", N->getElements());
+ Printer.printMetadata("elements", N->getRawElements());
Printer.printDwarfEnum("runtimeLang", N->getRuntimeLang(),
dwarf::LanguageString);
- Printer.printMetadata("vtableHolder", N->getVTableHolder());
- Printer.printMetadata("templateParams", N->getTemplateParams());
+ Printer.printMetadata("vtableHolder", N->getRawVTableHolder());
+ Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printString("identifier", N->getIdentifier());
Out << ")";
}
@@ -1582,7 +1580,8 @@ static void writeMDSubroutineType(raw_ostream &Out, const MDSubroutineType *N,
Out << "!MDSubroutineType(";
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printDIFlags("flags", N->getFlags());
- Printer.printMetadata("types", N->getTypeArray(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("types", N->getRawTypeArray(),
+ /* ShouldSkipNull */ false);
Out << ")";
}
@@ -1604,7 +1603,7 @@ static void writeMDCompileUnit(raw_ostream &Out, const MDCompileUnit *N,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printDwarfEnum("language", N->getSourceLanguage(),
dwarf::LanguageString, /* ShouldSkipZero */ false);
- Printer.printMetadata("file", N->getFile(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
Printer.printString("producer", N->getProducer());
Printer.printBool("isOptimized", N->isOptimized());
Printer.printString("flags", N->getFlags());
@@ -1613,11 +1612,11 @@ static void writeMDCompileUnit(raw_ostream &Out, const MDCompileUnit *N,
Printer.printString("splitDebugFilename", N->getSplitDebugFilename());
Printer.printInt("emissionKind", N->getEmissionKind(),
/* ShouldSkipZero */ false);
- Printer.printMetadata("enums", N->getEnumTypes());
- Printer.printMetadata("retainedTypes", N->getRetainedTypes());
- Printer.printMetadata("subprograms", N->getSubprograms());
- Printer.printMetadata("globals", N->getGlobalVariables());
- Printer.printMetadata("imports", N->getImportedEntities());
+ Printer.printMetadata("enums", N->getRawEnumTypes());
+ Printer.printMetadata("retainedTypes", N->getRawRetainedTypes());
+ Printer.printMetadata("subprograms", N->getRawSubprograms());
+ Printer.printMetadata("globals", N->getRawGlobalVariables());
+ Printer.printMetadata("imports", N->getRawImportedEntities());
Out << ")";
}
@@ -1628,23 +1627,23 @@ static void writeMDSubprogram(raw_ostream &Out, const MDSubprogram *N,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printString("name", N->getName());
Printer.printString("linkageName", N->getLinkageName());
- Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
- Printer.printMetadata("file", N->getFile());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
- Printer.printMetadata("type", N->getType());
+ Printer.printMetadata("type", N->getRawType());
Printer.printBool("isLocal", N->isLocalToUnit());
Printer.printBool("isDefinition", N->isDefinition());
Printer.printInt("scopeLine", N->getScopeLine());
- Printer.printMetadata("containingType", N->getContainingType());
+ Printer.printMetadata("containingType", N->getRawContainingType());
Printer.printDwarfEnum("virtuality", N->getVirtuality(),
dwarf::VirtualityString);
Printer.printInt("virtualIndex", N->getVirtualIndex());
Printer.printDIFlags("flags", N->getFlags());
Printer.printBool("isOptimized", N->isOptimized());
- Printer.printMetadata("function", N->getFunction());
- Printer.printMetadata("templateParams", N->getTemplateParams());
- Printer.printMetadata("declaration", N->getDeclaration());
- Printer.printMetadata("variables", N->getVariables());
+ Printer.printMetadata("function", N->getRawFunction());
+ Printer.printMetadata("templateParams", N->getRawTemplateParams());
+ Printer.printMetadata("declaration", N->getRawDeclaration());
+ Printer.printMetadata("variables", N->getRawVariables());
Out << ")";
}
@@ -1653,8 +1652,8 @@ static void writeMDLexicalBlock(raw_ostream &Out, const MDLexicalBlock *N,
const Module *Context) {
Out << "!MDLexicalBlock(";
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
- Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
- Printer.printMetadata("file", N->getFile());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
Printer.printInt("column", N->getColumn());
Out << ")";
@@ -1667,8 +1666,8 @@ static void writeMDLexicalBlockFile(raw_ostream &Out,
const Module *Context) {
Out << "!MDLexicalBlockFile(";
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
- Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
- Printer.printMetadata("file", N->getFile());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
Printer.printInt("discriminator", N->getDiscriminator(),
/* ShouldSkipZero */ false);
Out << ")";
@@ -1680,8 +1679,8 @@ static void writeMDNamespace(raw_ostream &Out, const MDNamespace *N,
Out << "!MDNamespace(";
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printString("name", N->getName());
- Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
- Printer.printMetadata("file", N->getFile());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
Out << ")";
}
@@ -1694,7 +1693,7 @@ static void writeMDTemplateTypeParameter(raw_ostream &Out,
Out << "!MDTemplateTypeParameter(";
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printString("name", N->getName());
- Printer.printMetadata("type", N->getType(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false);
Out << ")";
}
@@ -1708,7 +1707,7 @@ static void writeMDTemplateValueParameter(raw_ostream &Out,
if (N->getTag() != dwarf::DW_TAG_template_value_parameter)
Printer.printTag(N);
Printer.printString("name", N->getName());
- Printer.printMetadata("type", N->getType());
+ Printer.printMetadata("type", N->getRawType());
Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false);
Out << ")";
}
@@ -1720,14 +1719,14 @@ static void writeMDGlobalVariable(raw_ostream &Out, const MDGlobalVariable *N,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printString("name", N->getName());
Printer.printString("linkageName", N->getLinkageName());
- Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
- Printer.printMetadata("file", N->getFile());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
- Printer.printMetadata("type", N->getType());
+ Printer.printMetadata("type", N->getRawType());
Printer.printBool("isLocal", N->isLocalToUnit());
Printer.printBool("isDefinition", N->isDefinition());
- Printer.printMetadata("variable", N->getVariable());
- Printer.printMetadata("declaration", N->getStaticDataMemberDeclaration());
+ Printer.printMetadata("variable", N->getRawVariable());
+ Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
Out << ")";
}
@@ -1741,12 +1740,11 @@ static void writeMDLocalVariable(raw_ostream &Out, const MDLocalVariable *N,
Printer.printInt("arg", N->getArg(),
/* ShouldSkipZero */
N->getTag() == dwarf::DW_TAG_auto_variable);
- Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
- Printer.printMetadata("file", N->getFile());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
- Printer.printMetadata("type", N->getType());
+ Printer.printMetadata("type", N->getRawType());
Printer.printDIFlags("flags", N->getFlags());
- Printer.printMetadata("inlinedAt", N->getInlinedAt());
Out << ")";
}
@@ -1777,12 +1775,12 @@ static void writeMDObjCProperty(raw_ostream &Out, const MDObjCProperty *N,
Out << "!MDObjCProperty(";
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printString("name", N->getName());
- Printer.printMetadata("file", N->getFile());
+ Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
Printer.printString("setter", N->getSetterName());
Printer.printString("getter", N->getGetterName());
Printer.printInt("attributes", N->getAttributes());
- Printer.printMetadata("type", N->getType());
+ Printer.printMetadata("type", N->getRawType());
Out << ")";
}
@@ -1793,8 +1791,8 @@ static void writeMDImportedEntity(raw_ostream &Out, const MDImportedEntity *N,
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
Printer.printTag(N);
Printer.printString("name", N->getName());
- Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
- Printer.printMetadata("entity", N->getEntity());
+ Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("entity", N->getRawEntity());
Printer.printInt("line", N->getLine());
Out << ")";
}
@@ -1943,16 +1941,19 @@ class AssemblyWriter {
TypePrinting TypePrinter;
AssemblyAnnotationWriter *AnnotationWriter;
SetVector<const Comdat *> Comdats;
+ bool ShouldPreserveUseListOrder;
UseListOrderStack UseListOrders;
public:
/// Construct an AssemblyWriter with an external SlotTracker
- AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
- const Module *M, AssemblyAnnotationWriter *AAW);
+ AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M,
+ AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder = false);
/// Construct an AssemblyWriter with an internally allocated SlotTracker
AssemblyWriter(formatted_raw_ostream &o, const Module *M,
- AssemblyAnnotationWriter *AAW);
+ AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder = false);
void printMDNodeBody(const MDNode *MD);
void printNamedMDNode(const NamedMDNode *NMD);
@@ -2004,18 +2005,20 @@ void AssemblyWriter::init() {
Comdats.insert(C);
}
-
AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
- const Module *M,
- AssemblyAnnotationWriter *AAW)
- : Out(o), TheModule(M), Machine(Mac), AnnotationWriter(AAW) {
+ const Module *M, AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder)
+ : Out(o), TheModule(M), Machine(Mac), AnnotationWriter(AAW),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
init();
}
AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, const Module *M,
- AssemblyAnnotationWriter *AAW)
- : Out(o), TheModule(M), ModuleSlotTracker(createSlotTracker(M)),
- Machine(*ModuleSlotTracker), AnnotationWriter(AAW) {
+ AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder)
+ : Out(o), TheModule(M), ModuleSlotTracker(createSlotTracker(M)),
+ Machine(*ModuleSlotTracker), AnnotationWriter(AAW),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
init();
}
@@ -2103,7 +2106,7 @@ void AssemblyWriter::writeParamOperand(const Value *Operand,
void AssemblyWriter::printModule(const Module *M) {
Machine.initialize();
- if (shouldPreserveAssemblyUseListOrder())
+ if (ShouldPreserveUseListOrder)
UseListOrders = predictUseListOrder(M);
if (!M->getModuleIdentifier().empty() &&
@@ -2778,8 +2781,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
}
Operand = CI->getCalledValue();
- PointerType *PTy = cast<PointerType>(Operand->getType());
- FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+ FunctionType *FTy = cast<FunctionType>(CI->getFunctionType());
Type *RetTy = FTy->getReturnType();
const AttributeSet &PAL = CI->getAttributes();
@@ -2791,15 +2793,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
// and if the return type is not a pointer to a function.
//
Out << ' ';
- if (!FTy->isVarArg() &&
- (!RetTy->isPointerTy() ||
- !cast<PointerType>(RetTy)->getElementType()->isFunctionTy())) {
- TypePrinter.print(RetTy, Out);
- Out << ' ';
- writeOperand(Operand, false);
- } else {
- writeOperand(Operand, true);
- }
+ TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
+ Out << ' ';
+ writeOperand(Operand, false);
Out << '(';
for (unsigned op = 0, Eop = CI->getNumArgOperands(); op < Eop; ++op) {
if (op > 0)
@@ -3060,10 +3056,18 @@ void AssemblyWriter::printUseLists(const Function *F) {
// External Interface declarations
//===----------------------------------------------------------------------===//
-void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const {
+void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const {
+ SlotTracker SlotTable(this->getParent());
+ formatted_raw_ostream OS(ROS);
+ AssemblyWriter W(OS, SlotTable, this->getParent(), AAW);
+ W.printFunction(this);
+}
+
+void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder) const {
SlotTracker SlotTable(this);
formatted_raw_ostream OS(ROS);
- AssemblyWriter W(OS, SlotTable, this, AAW);
+ AssemblyWriter W(OS, SlotTable, this, AAW, ShouldPreserveUseListOrder);
W.printModule(this);
}
diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h
index 199c318..d544689 100644
--- a/lib/IR/AttributeImpl.h
+++ b/lib/IR/AttributeImpl.h
@@ -115,10 +115,10 @@ class IntAttributeImpl : public EnumAttributeImpl {
public:
IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val)
: EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) {
- assert(
- (Kind == Attribute::Alignment || Kind == Attribute::StackAlignment ||
- Kind == Attribute::Dereferenceable) &&
- "Wrong kind for int attribute!");
+ assert((Kind == Attribute::Alignment || Kind == Attribute::StackAlignment ||
+ Kind == Attribute::Dereferenceable ||
+ Kind == Attribute::DereferenceableOrNull) &&
+ "Wrong kind for int attribute!");
}
uint64_t getValue() const { return Val; }
diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp
index daac6b5..be5b74f 100644
--- a/lib/IR/Attributes.cpp
+++ b/lib/IR/Attributes.cpp
@@ -94,6 +94,12 @@ Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
return get(Context, Dereferenceable, Bytes);
}
+Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
+ uint64_t Bytes) {
+ assert(Bytes && "Bytes must be non-zero.");
+ return get(Context, DereferenceableOrNull, Bytes);
+}
+
//===----------------------------------------------------------------------===//
// Attribute Accessor Methods
//===----------------------------------------------------------------------===//
@@ -170,6 +176,13 @@ uint64_t Attribute::getDereferenceableBytes() const {
return pImpl->getValueAsInt();
}
+uint64_t Attribute::getDereferenceableOrNullBytes() const {
+ assert(hasAttribute(Attribute::DereferenceableOrNull) &&
+ "Trying to get dereferenceable bytes from "
+ "non-dereferenceable attribute!");
+ return pImpl->getValueAsInt();
+}
+
std::string Attribute::getAsString(bool InAttrGrp) const {
if (!pImpl) return "";
@@ -263,9 +276,9 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return Result;
}
- if (hasAttribute(Attribute::StackAlignment)) {
+ auto AttrWithBytesToString = [&](const char *Name) {
std::string Result;
- Result += "alignstack";
+ Result += Name;
if (InAttrGrp) {
Result += "=";
Result += utostr(getValueAsInt());
@@ -275,21 +288,16 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
Result += ")";
}
return Result;
- }
+ };
- if (hasAttribute(Attribute::Dereferenceable)) {
- std::string Result;
- Result += "dereferenceable";
- if (InAttrGrp) {
- Result += "=";
- Result += utostr(getValueAsInt());
- } else {
- Result += "(";
- Result += utostr(getValueAsInt());
- Result += ")";
- }
- return Result;
- }
+ if (hasAttribute(Attribute::StackAlignment))
+ return AttrWithBytesToString("alignstack");
+
+ if (hasAttribute(Attribute::Dereferenceable))
+ return AttrWithBytesToString("dereferenceable");
+
+ if (hasAttribute(Attribute::DereferenceableOrNull))
+ return AttrWithBytesToString("dereferenceable_or_null");
// Convert target-dependent attributes to strings of the form:
//
@@ -298,12 +306,12 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
//
if (isStringAttribute()) {
std::string Result;
- Result += '\"' + getKindAsString().str() + '"';
+ Result += (Twine('"') + getKindAsString() + Twine('"')).str();
StringRef Val = pImpl->getValueAsString();
if (Val.empty()) return Result;
- Result += "=\"" + Val.str() + '"';
+ Result += ("=\"" + Val + Twine('"')).str();
return Result;
}
@@ -428,6 +436,11 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
case Attribute::JumpTable: return 1ULL << 45;
case Attribute::Dereferenceable:
llvm_unreachable("dereferenceable attribute not supported in raw format");
+ break;
+ case Attribute::DereferenceableOrNull:
+ llvm_unreachable("dereferenceable_or_null attribute not supported in raw "
+ "format");
+ break;
}
llvm_unreachable("Unsupported attribute type");
}
@@ -663,6 +676,10 @@ AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
Attrs.push_back(std::make_pair(Index,
Attribute::getWithDereferenceableBytes(C,
B.getDereferenceableBytes())));
+ else if (Kind == Attribute::DereferenceableOrNull)
+ Attrs.push_back(
+ std::make_pair(Index, Attribute::getWithDereferenceableOrNullBytes(
+ C, B.getDereferenceableOrNullBytes())));
else
Attrs.push_back(std::make_pair(Index, Attribute::get(C, Kind)));
}
@@ -842,6 +859,14 @@ AttributeSet AttributeSet::addDereferenceableAttr(LLVMContext &C, unsigned Index
return addAttributes(C, Index, AttributeSet::get(C, Index, B));
}
+AttributeSet AttributeSet::addDereferenceableOrNullAttr(LLVMContext &C,
+ unsigned Index,
+ uint64_t Bytes) const {
+ llvm::AttrBuilder B;
+ B.addDereferenceableOrNullAttr(Bytes);
+ return addAttributes(C, Index, AttributeSet::get(C, Index, B));
+}
+
//===----------------------------------------------------------------------===//
// AttributeSet Accessor Methods
//===----------------------------------------------------------------------===//
@@ -1011,7 +1036,8 @@ void AttributeSet::dump() const {
//===----------------------------------------------------------------------===//
AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index)
- : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {
+ : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0),
+ DerefOrNullBytes(0) {
AttributeSetImpl *pImpl = AS.pImpl;
if (!pImpl) return;
@@ -1028,7 +1054,7 @@ AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index)
void AttrBuilder::clear() {
Attrs.reset();
- Alignment = StackAlignment = DerefBytes = 0;
+ Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
}
AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
@@ -1055,6 +1081,8 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
StackAlignment = Attr.getStackAlignment();
else if (Kind == Attribute::Dereferenceable)
DerefBytes = Attr.getDereferenceableBytes();
+ else if (Kind == Attribute::DereferenceableOrNull)
+ DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
return *this;
}
@@ -1073,6 +1101,8 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
StackAlignment = 0;
else if (Val == Attribute::Dereferenceable)
DerefBytes = 0;
+ else if (Val == Attribute::DereferenceableOrNull)
+ DerefOrNullBytes = 0;
return *this;
}
@@ -1099,6 +1129,8 @@ AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) {
StackAlignment = 0;
else if (Kind == Attribute::Dereferenceable)
DerefBytes = 0;
+ else if (Kind == Attribute::DereferenceableOrNull)
+ DerefOrNullBytes = 0;
} else {
assert(Attr.isStringAttribute() && "Invalid attribute type!");
std::map<std::string, std::string>::iterator
@@ -1149,6 +1181,15 @@ AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
return *this;
}
+AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
+ if (Bytes == 0)
+ return *this;
+
+ Attrs[Attribute::DereferenceableOrNull] = true;
+ DerefOrNullBytes = Bytes;
+ return *this;
+}
+
AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
// FIXME: What if both have alignments, but they don't match?!
if (!Alignment)
@@ -1225,7 +1266,8 @@ AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) {
for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
I = Attribute::AttrKind(I + 1)) {
- if (I == Attribute::Dereferenceable)
+ if (I == Attribute::Dereferenceable ||
+ I == Attribute::DereferenceableOrNull)
continue;
if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) {
Attrs[I] = true;
@@ -1261,6 +1303,7 @@ AttributeSet AttributeFuncs::typeIncompatible(Type *Ty, uint64_t Index) {
.addAttribute(Attribute::NoCapture)
.addAttribute(Attribute::NonNull)
.addDereferenceableAttr(1) // the int here is ignored
+ .addDereferenceableOrNullAttr(1) // the int here is ignored
.addAttribute(Attribute::ReadNone)
.addAttribute(Attribute::ReadOnly)
.addAttribute(Attribute::StructRet)
diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp
index d2dfeaa..bb23d2c 100644
--- a/lib/IR/AutoUpgrade.cpp
+++ b/lib/IR/AutoUpgrade.cpp
@@ -124,19 +124,6 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
break;
}
- case 'd': {
- if (Name.startswith("dbg.declare") && F->arg_size() == 2) {
- F->setName(Name + ".old");
- NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_declare);
- return true;
- }
- if (Name.startswith("dbg.value") && F->arg_size() == 3) {
- F->setName(Name + ".old");
- NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value);
- return true;
- }
- break;
- }
case 'o':
// We only need to change the name to match the mangling including the
@@ -354,23 +341,6 @@ bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
return false;
}
-static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) {
- if (!DbgNode || Elt >= DbgNode->getNumOperands())
- return nullptr;
- return dyn_cast_or_null<MDNode>(DbgNode->getOperand(Elt));
-}
-
-static MetadataAsValue *getExpression(Value *VarOperand, Function *F) {
- // Old-style DIVariables have an optional expression as the 8th element.
- DIExpression Expr(getNodeField(
- cast<MDNode>(cast<MetadataAsValue>(VarOperand)->getMetadata()), 8));
- if (!Expr) {
- DIBuilder DIB(*F->getParent(), /*AllowUnresolved*/ false);
- Expr = DIB.createExpression();
- }
- return MetadataAsValue::get(F->getContext(), Expr);
-}
-
// Handles upgrading SSE2 and AVX2 PSLLDQ intrinsics by converting them
// to byte shuffles.
static Value *UpgradeX86PSLLDQIntrinsics(IRBuilder<> &Builder, LLVMContext &C,
@@ -745,7 +715,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
return;
}
- std::string Name = CI->getName().str();
+ std::string Name = CI->getName();
if (!Name.empty())
CI->setName(Name + ".old");
@@ -753,25 +723,6 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
default:
llvm_unreachable("Unknown function for CallInst upgrade.");
- // Upgrade debug intrinsics to use an additional DIExpression argument.
- case Intrinsic::dbg_declare: {
- auto NewCI =
- Builder.CreateCall3(NewFn, CI->getArgOperand(0), CI->getArgOperand(1),
- getExpression(CI->getArgOperand(1), F), Name);
- NewCI->setDebugLoc(CI->getDebugLoc());
- CI->replaceAllUsesWith(NewCI);
- CI->eraseFromParent();
- return;
- }
- case Intrinsic::dbg_value: {
- auto NewCI = Builder.CreateCall4(
- NewFn, CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2),
- getExpression(CI->getArgOperand(2), F), Name);
- NewCI->setDebugLoc(CI->getDebugLoc());
- CI->replaceAllUsesWith(NewCI);
- CI->eraseFromParent();
- return;
- }
case Intrinsic::ctlz:
case Intrinsic::cttz:
assert(CI->getNumArgOperands() == 1 &&
diff --git a/lib/IR/BasicBlock.cpp b/lib/IR/BasicBlock.cpp
index fe38385..23ec705 100644
--- a/lib/IR/BasicBlock.cpp
+++ b/lib/IR/BasicBlock.cpp
@@ -94,8 +94,8 @@ void BasicBlock::removeFromParent() {
getParent()->getBasicBlockList().remove(this);
}
-void BasicBlock::eraseFromParent() {
- getParent()->getBasicBlockList().erase(this);
+iplist<BasicBlock>::iterator BasicBlock::eraseFromParent() {
+ return getParent()->getBasicBlockList().erase(this);
}
/// Unlink this basic block from its current function and
diff --git a/lib/IR/CMakeLists.txt b/lib/IR/CMakeLists.txt
index 9fef0b2..d2e0c38 100644
--- a/lib/IR/CMakeLists.txt
+++ b/lib/IR/CMakeLists.txt
@@ -41,7 +41,6 @@ add_llvm_library(LLVMCore
Type.cpp
TypeFinder.cpp
Use.cpp
- UseListOrder.cpp
User.cpp
Value.cpp
ValueSymbolTable.cpp
diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp
index d97d2c4..d3caf04 100644
--- a/lib/IR/ConstantFold.cpp
+++ b/lib/IR/ConstantFold.cpp
@@ -132,7 +132,8 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
if (ElTy == DPTy->getElementType())
// This GEP is inbounds because all indices are zero.
- return ConstantExpr::getInBoundsGetElementPtr(V, IdxList);
+ return ConstantExpr::getInBoundsGetElementPtr(PTy->getElementType(),
+ V, IdxList);
}
// Handle casts from one vector constant to another. We know that the src
@@ -169,7 +170,8 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
// be the same. Consequently, we just fold to V.
return V;
- if (DestTy->isFloatingPointTy())
+ // See note below regarding the PPC_FP128 restriction.
+ if (DestTy->isFloatingPointTy() && !DestTy->isPPC_FP128Ty())
return ConstantFP::get(DestTy->getContext(),
APFloat(DestTy->getFltSemantics(),
CI->getValue()));
@@ -179,9 +181,19 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
}
// Handle ConstantFP input: FP -> Integral.
- if (ConstantFP *FP = dyn_cast<ConstantFP>(V))
+ if (ConstantFP *FP = dyn_cast<ConstantFP>(V)) {
+ // PPC_FP128 is really the sum of two consecutive doubles, where the first
+ // double is always stored first in memory, regardless of the target
+ // endianness. The memory layout of i128, however, depends on the target
+ // endianness, and so we can't fold this without target endianness
+ // information. This should instead be handled by
+ // Analysis/ConstantFolding.cpp
+ if (FP->getType()->isPPC_FP128Ty())
+ return nullptr;
+
return ConstantInt::get(FP->getContext(),
FP->getValueAPF().bitcastToAPInt());
+ }
return nullptr;
}
@@ -2020,7 +2032,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
if (isa<UndefValue>(C)) {
PointerType *Ptr = cast<PointerType>(C->getType());
- Type *Ty = GetElementPtrInst::getIndexedType(Ptr, Idxs);
+ Type *Ty = GetElementPtrInst::getIndexedType(
+ cast<PointerType>(Ptr->getScalarType())->getElementType(), Idxs);
assert(Ty && "Invalid indices for GEP!");
return UndefValue::get(PointerType::get(Ty, Ptr->getAddressSpace()));
}
@@ -2034,7 +2047,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
}
if (isNull) {
PointerType *Ptr = cast<PointerType>(C->getType());
- Type *Ty = GetElementPtrInst::getIndexedType(Ptr, Idxs);
+ Type *Ty = GetElementPtrInst::getIndexedType(
+ cast<PointerType>(Ptr->getScalarType())->getElementType(), Idxs);
assert(Ty && "Invalid indices for GEP!");
return ConstantPointerNull::get(PointerType::get(Ty,
Ptr->getAddressSpace()));
@@ -2107,10 +2121,9 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
NewIndices.push_back(Combined);
NewIndices.append(Idxs.begin() + 1, Idxs.end());
- return
- ConstantExpr::getGetElementPtr(CE->getOperand(0), NewIndices,
- inBounds &&
- cast<GEPOperator>(CE)->isInBounds());
+ return ConstantExpr::getGetElementPtr(
+ cast<GEPOperator>(CE)->getSourceElementType(), CE->getOperand(0),
+ NewIndices, inBounds && cast<GEPOperator>(CE)->isInBounds());
}
}
@@ -2135,8 +2148,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
if (SrcArrayTy && DstArrayTy
&& SrcArrayTy->getElementType() == DstArrayTy->getElementType()
&& SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace())
- return ConstantExpr::getGetElementPtr((Constant*)CE->getOperand(0),
- Idxs, inBounds);
+ return ConstantExpr::getGetElementPtr(
+ SrcArrayTy, (Constant *)CE->getOperand(0), Idxs, inBounds);
}
}
}
@@ -2202,7 +2215,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
if (!NewIdxs.empty()) {
for (unsigned i = 0, e = Idxs.size(); i != e; ++i)
if (!NewIdxs[i]) NewIdxs[i] = cast<Constant>(Idxs[i]);
- return ConstantExpr::getGetElementPtr(C, NewIdxs, inBounds);
+ return ConstantExpr::getGetElementPtr(nullptr, C, NewIdxs, inBounds);
}
// If all indices are known integers and normalized, we can do a simple
@@ -2210,7 +2223,7 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
if (!Unknown && !inBounds)
if (auto *GV = dyn_cast<GlobalVariable>(C))
if (!GV->hasExternalWeakLinkage() && isInBoundsIndices(Idxs))
- return ConstantExpr::getInBoundsGetElementPtr(C, Idxs);
+ return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idxs);
return nullptr;
}
diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp
index e51a396..3f8d1f1 100644
--- a/lib/IR/Constants.cpp
+++ b/lib/IR/Constants.cpp
@@ -1252,7 +1252,7 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2],
OnlyIfReducedTy);
case Instruction::GetElementPtr:
- return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1),
+ return ConstantExpr::getGetElementPtr(nullptr, Ops[0], Ops.slice(1),
cast<GEPOperator>(this)->isInBounds(),
OnlyIfReducedTy);
case Instruction::ICmp:
@@ -1925,7 +1925,7 @@ Constant *ConstantExpr::getSizeOf(Type* Ty) {
// Note that a non-inbounds gep is used, as null isn't within any object.
Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *GEP = getGetElementPtr(
- Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
+ Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
return getPtrToInt(GEP,
Type::getInt64Ty(Ty->getContext()));
}
@@ -1939,7 +1939,7 @@ Constant *ConstantExpr::getAlignOf(Type* Ty) {
Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0);
Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *Indices[2] = { Zero, One };
- Constant *GEP = getGetElementPtr(NullPtr, Indices);
+ Constant *GEP = getGetElementPtr(AligningTy, NullPtr, Indices);
return getPtrToInt(GEP,
Type::getInt64Ty(Ty->getContext()));
}
@@ -1957,7 +1957,7 @@ Constant *ConstantExpr::getOffsetOf(Type* Ty, Constant *FieldNo) {
FieldNo
};
Constant *GEP = getGetElementPtr(
- Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
+ Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
return getPtrToInt(GEP,
Type::getInt64Ty(Ty->getContext()));
}
@@ -2001,19 +2001,22 @@ Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2,
return pImpl->ExprConstants.getOrCreate(V1->getType(), Key);
}
-Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs,
- bool InBounds, Type *OnlyIfReducedTy) {
- assert(C->getType()->isPtrOrPtrVectorTy() &&
- "Non-pointer type for constant GetElementPtr expression");
-
+Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
+ ArrayRef<Value *> Idxs, bool InBounds,
+ Type *OnlyIfReducedTy) {
if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs))
return FC; // Fold a few common cases.
+ if (!Ty)
+ Ty = cast<PointerType>(C->getType()->getScalarType())->getElementType();
+ else
+ assert(Ty ==
+ cast<PointerType>(C->getType()->getScalarType())->getElementType());
// Get the result type of the getelementptr!
- Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), Idxs);
- assert(Ty && "GEP indices invalid!");
+ Type *DestTy = GetElementPtrInst::getIndexedType(Ty, Idxs);
+ assert(DestTy && "GEP indices invalid!");
unsigned AS = C->getType()->getPointerAddressSpace();
- Type *ReqTy = Ty->getPointerTo(AS);
+ Type *ReqTy = DestTy->getPointerTo(AS);
if (VectorType *VecTy = dyn_cast<VectorType>(C->getType()))
ReqTy = VectorType::get(ReqTy, VecTy->getNumElements());
diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp
index 613147e..7fe7beb 100644
--- a/lib/IR/Core.cpp
+++ b/lib/IR/Core.cpp
@@ -1153,8 +1153,8 @@ LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal,
LLVMValueRef *ConstantIndices, unsigned NumIndices) {
ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
NumIndices);
- return wrap(ConstantExpr::getGetElementPtr(unwrap<Constant>(ConstantVal),
- IdxList));
+ return wrap(ConstantExpr::getGetElementPtr(
+ nullptr, unwrap<Constant>(ConstantVal), IdxList));
}
LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal,
@@ -1163,7 +1163,7 @@ LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal,
Constant* Val = unwrap<Constant>(ConstantVal);
ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
NumIndices);
- return wrap(ConstantExpr::getInBoundsGetElementPtr(Val, IdxList));
+ return wrap(ConstantExpr::getInBoundsGetElementPtr(nullptr, Val, IdxList));
}
LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
@@ -2181,14 +2181,13 @@ void LLVMDisposeBuilder(LLVMBuilderRef Builder) {
void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) {
MDNode *Loc =
L ? cast<MDNode>(unwrap<MetadataAsValue>(L)->getMetadata()) : nullptr;
- unwrap(Builder)->SetCurrentDebugLocation(DebugLoc::getFromDILocation(Loc));
+ unwrap(Builder)->SetCurrentDebugLocation(DebugLoc(Loc));
}
LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) {
LLVMContext &Context = unwrap(Builder)->getContext();
return wrap(MetadataAsValue::get(
- Context,
- unwrap(Builder)->getCurrentDebugLocation().getAsMDNode(Context)));
+ Context, unwrap(Builder)->getCurrentDebugLocation().getAsMDNode()));
}
void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst) {
@@ -2513,12 +2512,13 @@ LLVMValueRef LLVMBuildInBoundsGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
LLVMValueRef *Indices, unsigned NumIndices,
const char *Name) {
ArrayRef<Value *> IdxList(unwrap(Indices), NumIndices);
- return wrap(unwrap(B)->CreateInBoundsGEP(unwrap(Pointer), IdxList, Name));
+ return wrap(
+ unwrap(B)->CreateInBoundsGEP(nullptr, unwrap(Pointer), IdxList, Name));
}
LLVMValueRef LLVMBuildStructGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
unsigned Idx, const char *Name) {
- return wrap(unwrap(B)->CreateStructGEP(unwrap(Pointer), Idx, Name));
+ return wrap(unwrap(B)->CreateStructGEP(nullptr, unwrap(Pointer), Idx, Name));
}
LLVMValueRef LLVMBuildGlobalString(LLVMBuilderRef B, const char *Str,
diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp
index 9677de4..891fb86 100644
--- a/lib/IR/DIBuilder.cpp
+++ b/lib/IR/DIBuilder.cpp
@@ -74,8 +74,7 @@ void DIBuilder::trackIfUnresolved(MDNode *N) {
}
void DIBuilder::finalize() {
- DIArray Enums = getOrCreateArray(AllEnumTypes);
- DIType(TempEnumTypes).replaceAllUsesWith(Enums);
+ TempEnumTypes->replaceAllUsesWith(MDTuple::get(VMContext, AllEnumTypes));
SmallVector<Metadata *, 16> RetainValues;
// Declarations and definitions of the same type may be retained. Some
@@ -86,28 +85,24 @@ void DIBuilder::finalize() {
for (unsigned I = 0, E = AllRetainTypes.size(); I < E; I++)
if (RetainSet.insert(AllRetainTypes[I]).second)
RetainValues.push_back(AllRetainTypes[I]);
- DIArray RetainTypes = getOrCreateArray(RetainValues);
- DIType(TempRetainTypes).replaceAllUsesWith(RetainTypes);
-
- DIArray SPs = getOrCreateArray(AllSubprograms);
- DIType(TempSubprograms).replaceAllUsesWith(SPs);
- for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
- DISubprogram SP(SPs.getElement(i));
- if (MDNode *Temp = SP.getVariablesNodes()) {
+ TempRetainTypes->replaceAllUsesWith(MDTuple::get(VMContext, RetainValues));
+
+ MDSubprogramArray SPs = MDTuple::get(VMContext, AllSubprograms);
+ TempSubprograms->replaceAllUsesWith(SPs.get());
+ for (auto *SP : SPs) {
+ if (MDTuple *Temp = SP->getVariables().get()) {
const auto &PV = PreservedVariables.lookup(SP);
SmallVector<Metadata *, 4> Variables(PV.begin(), PV.end());
DIArray AV = getOrCreateArray(Variables);
- DIType(Temp).replaceAllUsesWith(AV);
+ TempMDTuple(Temp)->replaceAllUsesWith(AV.get());
}
}
- DIArray GVs = getOrCreateArray(AllGVs);
- DIType(TempGVs).replaceAllUsesWith(GVs);
+ TempGVs->replaceAllUsesWith(MDTuple::get(VMContext, AllGVs));
- SmallVector<Metadata *, 16> RetainValuesI(AllImportedModules.begin(),
- AllImportedModules.end());
- DIArray IMs = getOrCreateArray(RetainValuesI);
- DIType(TempImportedModules).replaceAllUsesWith(IMs);
+ TempImportedModules->replaceAllUsesWith(MDTuple::get(
+ VMContext, SmallVector<Metadata *, 16>(AllImportedModules.begin(),
+ AllImportedModules.end())));
// Now that all temp nodes have been replaced or deleted, resolve remaining
// cycles.
@@ -121,19 +116,16 @@ void DIBuilder::finalize() {
}
/// If N is compile unit return NULL otherwise return N.
-static MDScope *getNonCompileUnitScope(MDNode *N) {
+static MDScope *getNonCompileUnitScope(MDScope *N) {
if (!N || isa<MDCompileUnit>(N))
return nullptr;
return cast<MDScope>(N);
}
-DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
- StringRef Directory,
- StringRef Producer, bool isOptimized,
- StringRef Flags, unsigned RunTimeVer,
- StringRef SplitName,
- DebugEmissionKind Kind,
- bool EmitDebugInfo) {
+MDCompileUnit *DIBuilder::createCompileUnit(
+ unsigned Lang, StringRef Filename, StringRef Directory, StringRef Producer,
+ bool isOptimized, StringRef Flags, unsigned RunTimeVer, StringRef SplitName,
+ DebugEmissionKind Kind, bool EmitDebugInfo) {
assert(((Lang <= dwarf::DW_LANG_Fortran08 && Lang >= dwarf::DW_LANG_C89) ||
(Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) &&
@@ -143,18 +135,19 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
// TODO: Once we make MDCompileUnit distinct, stop using temporaries here
// (just start with operands assigned to nullptr).
- TempEnumTypes = MDTuple::getTemporary(VMContext, None).release();
- TempRetainTypes = MDTuple::getTemporary(VMContext, None).release();
- TempSubprograms = MDTuple::getTemporary(VMContext, None).release();
- TempGVs = MDTuple::getTemporary(VMContext, None).release();
- TempImportedModules = MDTuple::getTemporary(VMContext, None).release();
+ TempEnumTypes = MDTuple::getTemporary(VMContext, None);
+ TempRetainTypes = MDTuple::getTemporary(VMContext, None);
+ TempSubprograms = MDTuple::getTemporary(VMContext, None);
+ TempGVs = MDTuple::getTemporary(VMContext, None);
+ TempImportedModules = MDTuple::getTemporary(VMContext, None);
// TODO: Switch to getDistinct(). We never want to merge compile units based
// on contents.
- MDNode *CUNode = MDCompileUnit::get(
+ MDCompileUnit *CUNode = MDCompileUnit::get(
VMContext, Lang, MDFile::get(VMContext, Filename, Directory), Producer,
- isOptimized, Flags, RunTimeVer, SplitName, Kind, TempEnumTypes,
- TempRetainTypes, TempSubprograms, TempGVs, TempImportedModules);
+ isOptimized, Flags, RunTimeVer, SplitName, Kind, TempEnumTypes.get(),
+ TempRetainTypes.get(), TempSubprograms.get(), TempGVs.get(),
+ TempImportedModules.get());
// Create a named metadata so that it is easier to find cu in a module.
// Note that we only generate this when the caller wants to actually
@@ -167,141 +160,136 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
}
trackIfUnresolved(CUNode);
- return DICompileUnit(CUNode);
+ return CUNode;
}
-static DIImportedEntity
-createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope Context,
+static MDImportedEntity*
+createImportedModule(LLVMContext &C, dwarf::Tag Tag, MDScope* Context,
Metadata *NS, unsigned Line, StringRef Name,
SmallVectorImpl<TrackingMDNodeRef> &AllImportedModules) {
- DIImportedEntity M = MDImportedEntity::get(C, Tag, Context, NS, Line, Name);
- assert(M.Verify() && "Imported module should be valid");
- AllImportedModules.emplace_back(M.get());
+ auto *M =
+ MDImportedEntity::get(C, Tag, Context, DebugNodeRef(NS), Line, Name);
+ AllImportedModules.emplace_back(M);
return M;
}
-DIImportedEntity DIBuilder::createImportedModule(DIScope Context,
- DINameSpace NS,
+MDImportedEntity* DIBuilder::createImportedModule(MDScope* Context,
+ MDNamespace* NS,
unsigned Line) {
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
Context, NS, Line, StringRef(), AllImportedModules);
}
-DIImportedEntity DIBuilder::createImportedModule(DIScope Context,
- DIImportedEntity NS,
+MDImportedEntity* DIBuilder::createImportedModule(MDScope* Context,
+ MDImportedEntity* NS,
unsigned Line) {
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
Context, NS, Line, StringRef(), AllImportedModules);
}
-DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context,
- DIDescriptor Decl,
- unsigned Line, StringRef Name) {
+MDImportedEntity *DIBuilder::createImportedDeclaration(MDScope *Context,
+ DebugNode *Decl,
+ unsigned Line,
+ StringRef Name) {
// Make sure to use the unique identifier based metadata reference for
// types that have one.
- Metadata *V =
- Decl.isType() ? static_cast<Metadata *>(DIType(Decl).getRef()) : Decl;
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration,
- Context, V, Line, Name,
+ Context, DebugNodeRef::get(Decl), Line, Name,
AllImportedModules);
}
-DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context,
- DIImportedEntity Imp,
- unsigned Line, StringRef Name) {
- return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration,
- Context, Imp, Line, Name, AllImportedModules);
-}
-
-DIFile DIBuilder::createFile(StringRef Filename, StringRef Directory) {
+MDFile* DIBuilder::createFile(StringRef Filename, StringRef Directory) {
return MDFile::get(VMContext, Filename, Directory);
}
-DIEnumerator DIBuilder::createEnumerator(StringRef Name, int64_t Val) {
+MDEnumerator *DIBuilder::createEnumerator(StringRef Name, int64_t Val) {
assert(!Name.empty() && "Unable to create enumerator without name");
return MDEnumerator::get(VMContext, Val, Name);
}
-DIBasicType DIBuilder::createUnspecifiedType(StringRef Name) {
+MDBasicType *DIBuilder::createUnspecifiedType(StringRef Name) {
assert(!Name.empty() && "Unable to create type without name");
return MDBasicType::get(VMContext, dwarf::DW_TAG_unspecified_type, Name);
}
-DIBasicType DIBuilder::createNullPtrType() {
+MDBasicType *DIBuilder::createNullPtrType() {
return createUnspecifiedType("decltype(nullptr)");
}
-DIBasicType
-DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
- uint64_t AlignInBits, unsigned Encoding) {
+MDBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ unsigned Encoding) {
assert(!Name.empty() && "Unable to create type without name");
return MDBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits,
AlignInBits, Encoding);
}
-DIDerivedType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) {
+MDDerivedType *DIBuilder::createQualifiedType(unsigned Tag, MDType *FromTy) {
return MDDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr,
- FromTy.getRef(), 0, 0, 0, 0);
+ MDTypeRef::get(FromTy), 0, 0, 0, 0);
}
-DIDerivedType
-DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits,
- uint64_t AlignInBits, StringRef Name) {
+MDDerivedType *DIBuilder::createPointerType(MDType *PointeeTy,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ StringRef Name) {
// FIXME: Why is there a name here?
return MDDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name,
- nullptr, 0, nullptr, PointeeTy.getRef(), SizeInBits,
- AlignInBits, 0, 0);
+ nullptr, 0, nullptr, MDTypeRef::get(PointeeTy),
+ SizeInBits, AlignInBits, 0, 0);
}
-DIDerivedType
-DIBuilder::createMemberPointerType(DIType PointeeTy, DIType Base,
- uint64_t SizeInBits, uint64_t AlignInBits) {
+MDDerivedType *DIBuilder::createMemberPointerType(MDType *PointeeTy,
+ MDType *Base,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits) {
return MDDerivedType::get(VMContext, dwarf::DW_TAG_ptr_to_member_type, "",
- nullptr, 0, nullptr, PointeeTy.getRef(), SizeInBits,
- AlignInBits, 0, 0, Base.getRef());
+ nullptr, 0, nullptr, MDTypeRef::get(PointeeTy),
+ SizeInBits, AlignInBits, 0, 0, MDTypeRef::get(Base));
}
-DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) {
- assert(RTy.isType() && "Unable to create reference type");
+MDDerivedType *DIBuilder::createReferenceType(unsigned Tag, MDType *RTy) {
+ assert(RTy && "Unable to create reference type");
return MDDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr,
- RTy.getRef(), 0, 0, 0, 0);
+ MDTypeRef::get(RTy), 0, 0, 0, 0);
}
-DIDerivedType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File,
- unsigned LineNo, DIDescriptor Context) {
- return MDDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name,
- File.getFileNode(), LineNo,
- DIScope(getNonCompileUnitScope(Context)).getRef(),
- Ty.getRef(), 0, 0, 0, 0);
+MDDerivedType *DIBuilder::createTypedef(MDType *Ty, StringRef Name,
+ MDFile *File, unsigned LineNo,
+ MDScope *Context) {
+ return MDDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File,
+ LineNo,
+ MDScopeRef::get(getNonCompileUnitScope(Context)),
+ MDTypeRef::get(Ty), 0, 0, 0, 0);
}
-DIDerivedType DIBuilder::createFriend(DIType Ty, DIType FriendTy) {
- // typedefs are encoded in DIDerivedType format.
- assert(Ty.isType() && "Invalid type!");
- assert(FriendTy.isType() && "Invalid friend type!");
+MDDerivedType *DIBuilder::createFriend(MDType *Ty, MDType *FriendTy) {
+ assert(Ty && "Invalid type!");
+ assert(FriendTy && "Invalid friend type!");
return MDDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0,
- Ty.getRef(), FriendTy.getRef(), 0, 0, 0, 0);
+ MDTypeRef::get(Ty), MDTypeRef::get(FriendTy), 0, 0,
+ 0, 0);
}
-DIDerivedType DIBuilder::createInheritance(DIType Ty, DIType BaseTy,
- uint64_t BaseOffset,
- unsigned Flags) {
- assert(Ty.isType() && "Unable to create inheritance");
+MDDerivedType *DIBuilder::createInheritance(MDType *Ty, MDType *BaseTy,
+ uint64_t BaseOffset,
+ unsigned Flags) {
+ assert(Ty && "Unable to create inheritance");
return MDDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr,
- 0, Ty.getRef(), BaseTy.getRef(), 0, 0, BaseOffset,
- Flags);
+ 0, MDTypeRef::get(Ty), MDTypeRef::get(BaseTy), 0, 0,
+ BaseOffset, Flags);
}
-DIDerivedType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNumber,
- uint64_t SizeInBits,
- uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- DIType Ty) {
+MDDerivedType *DIBuilder::createMemberType(MDScope *Scope, StringRef Name,
+ MDFile *File, unsigned LineNumber,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ uint64_t OffsetInBits,
+ unsigned Flags, MDType *Ty) {
return MDDerivedType::get(
VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,
- DIScope(getNonCompileUnitScope(Scope)).getRef(), Ty.getRef(), SizeInBits,
- AlignInBits, OffsetInBits, Flags);
+ MDScopeRef::get(getNonCompileUnitScope(Scope)), MDTypeRef::get(Ty),
+ SizeInBits, AlignInBits, OffsetInBits, Flags);
}
static ConstantAsMetadata *getConstantOrNull(Constant *C) {
@@ -310,135 +298,124 @@ static ConstantAsMetadata *getConstantOrNull(Constant *C) {
return nullptr;
}
-DIDerivedType DIBuilder::createStaticMemberType(DIDescriptor Scope,
- StringRef Name, DIFile File,
- unsigned LineNumber, DIType Ty,
- unsigned Flags,
- llvm::Constant *Val) {
- // TAG_member is encoded in DIDerivedType format.
- Flags |= DIDescriptor::FlagStaticMember;
+MDDerivedType *DIBuilder::createStaticMemberType(MDScope *Scope, StringRef Name,
+ MDFile *File,
+ unsigned LineNumber,
+ MDType *Ty, unsigned Flags,
+ llvm::Constant *Val) {
+ Flags |= DebugNode::FlagStaticMember;
return MDDerivedType::get(
VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,
- DIScope(getNonCompileUnitScope(Scope)).getRef(), Ty.getRef(), 0, 0, 0,
- Flags, getConstantOrNull(Val));
+ MDScopeRef::get(getNonCompileUnitScope(Scope)), MDTypeRef::get(Ty), 0, 0,
+ 0, Flags, getConstantOrNull(Val));
}
-DIDerivedType DIBuilder::createObjCIVar(StringRef Name, DIFile File,
- unsigned LineNumber,
- uint64_t SizeInBits,
- uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- DIType Ty, MDNode *PropertyNode) {
- return MDDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,
- LineNumber, getNonCompileUnitScope(File),
- Ty.getRef(), SizeInBits, AlignInBits, OffsetInBits,
- Flags, PropertyNode);
+MDDerivedType *DIBuilder::createObjCIVar(StringRef Name, MDFile *File,
+ unsigned LineNumber,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ MDType *Ty, MDNode *PropertyNode) {
+ return MDDerivedType::get(
+ VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,
+ MDScopeRef::get(getNonCompileUnitScope(File)), MDTypeRef::get(Ty),
+ SizeInBits, AlignInBits, OffsetInBits, Flags, PropertyNode);
}
-DIObjCProperty
-DIBuilder::createObjCProperty(StringRef Name, DIFile File, unsigned LineNumber,
+MDObjCProperty *
+DIBuilder::createObjCProperty(StringRef Name, MDFile *File, unsigned LineNumber,
StringRef GetterName, StringRef SetterName,
- unsigned PropertyAttributes, DIType Ty) {
+ unsigned PropertyAttributes, MDType *Ty) {
return MDObjCProperty::get(VMContext, Name, File, LineNumber, GetterName,
SetterName, PropertyAttributes, Ty);
}
-DITemplateTypeParameter
-DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name,
- DIType Ty) {
- assert(!DIScope(getNonCompileUnitScope(Context)).getRef() &&
- "Expected compile unit");
- return MDTemplateTypeParameter::get(VMContext, Name, Ty.getRef());
+MDTemplateTypeParameter *
+DIBuilder::createTemplateTypeParameter(MDScope *Context, StringRef Name,
+ MDType *Ty) {
+ assert((!Context || isa<MDCompileUnit>(Context)) && "Expected compile unit");
+ return MDTemplateTypeParameter::get(VMContext, Name, MDTypeRef::get(Ty));
}
-static DITemplateValueParameter
+static MDTemplateValueParameter *
createTemplateValueParameterHelper(LLVMContext &VMContext, unsigned Tag,
- DIDescriptor Context, StringRef Name,
- DIType Ty, Metadata *MD) {
- assert(!DIScope(getNonCompileUnitScope(Context)).getRef() &&
- "Expected compile unit");
- return MDTemplateValueParameter::get(VMContext, Tag, Name, Ty.getRef(), MD);
+ MDScope *Context, StringRef Name, MDType *Ty,
+ Metadata *MD) {
+ assert((!Context || isa<MDCompileUnit>(Context)) && "Expected compile unit");
+ return MDTemplateValueParameter::get(VMContext, Tag, Name, MDTypeRef::get(Ty),
+ MD);
}
-DITemplateValueParameter
-DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name,
- DIType Ty, Constant *Val) {
+MDTemplateValueParameter *
+DIBuilder::createTemplateValueParameter(MDScope *Context, StringRef Name,
+ MDType *Ty, Constant *Val) {
return createTemplateValueParameterHelper(
VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty,
getConstantOrNull(Val));
}
-DITemplateValueParameter
-DIBuilder::createTemplateTemplateParameter(DIDescriptor Context, StringRef Name,
- DIType Ty, StringRef Val) {
+MDTemplateValueParameter *
+DIBuilder::createTemplateTemplateParameter(MDScope *Context, StringRef Name,
+ MDType *Ty, StringRef Val) {
return createTemplateValueParameterHelper(
VMContext, dwarf::DW_TAG_GNU_template_template_param, Context, Name, Ty,
MDString::get(VMContext, Val));
}
-DITemplateValueParameter
-DIBuilder::createTemplateParameterPack(DIDescriptor Context, StringRef Name,
- DIType Ty, DIArray Val) {
+MDTemplateValueParameter *
+DIBuilder::createTemplateParameterPack(MDScope *Context, StringRef Name,
+ MDType *Ty, DIArray Val) {
return createTemplateValueParameterHelper(
VMContext, dwarf::DW_TAG_GNU_template_parameter_pack, Context, Name, Ty,
- Val);
+ Val.get());
}
-DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name,
- DIFile File, unsigned LineNumber,
- uint64_t SizeInBits,
- uint64_t AlignInBits,
- uint64_t OffsetInBits,
- unsigned Flags, DIType DerivedFrom,
- DIArray Elements,
- DIType VTableHolder,
- MDNode *TemplateParams,
- StringRef UniqueIdentifier) {
- assert((!Context || Context.isScope() || Context.isType()) &&
+MDCompositeType *DIBuilder::createClassType(
+ MDScope *Context, StringRef Name, MDFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, MDType *DerivedFrom, DIArray Elements, MDType *VTableHolder,
+ MDNode *TemplateParams, StringRef UniqueIdentifier) {
+ assert((!Context || isa<MDScope>(Context)) &&
"createClassType should be called with a valid Context");
- // TAG_class_type is encoded in DICompositeType format.
- DICompositeType R = MDCompositeType::get(
+
+ auto *R = MDCompositeType::get(
VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,
- DIScope(getNonCompileUnitScope(Context)).getRef(), DerivedFrom.getRef(),
- SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, 0,
- VTableHolder.getRef(), TemplateParams, UniqueIdentifier);
+ MDScopeRef::get(getNonCompileUnitScope(Context)),
+ MDTypeRef::get(DerivedFrom), SizeInBits, AlignInBits, OffsetInBits, Flags,
+ Elements, 0, MDTypeRef::get(VTableHolder),
+ cast_or_null<MDTuple>(TemplateParams), UniqueIdentifier);
if (!UniqueIdentifier.empty())
retainType(R);
trackIfUnresolved(R);
return R;
}
-DICompositeType DIBuilder::createStructType(DIDescriptor Context,
- StringRef Name, DIFile File,
- unsigned LineNumber,
- uint64_t SizeInBits,
- uint64_t AlignInBits,
- unsigned Flags, DIType DerivedFrom,
- DIArray Elements,
- unsigned RunTimeLang,
- DIType VTableHolder,
- StringRef UniqueIdentifier) {
- DICompositeType R = MDCompositeType::get(
+MDCompositeType *DIBuilder::createStructType(
+ MDScope *Context, StringRef Name, MDFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
+ MDType *DerivedFrom, DIArray Elements, unsigned RunTimeLang,
+ MDType *VTableHolder, StringRef UniqueIdentifier) {
+ auto *R = MDCompositeType::get(
VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,
- DIScope(getNonCompileUnitScope(Context)).getRef(), DerivedFrom.getRef(),
- SizeInBits, AlignInBits, 0, Flags, Elements, RunTimeLang,
- VTableHolder.getRef(), nullptr, UniqueIdentifier);
+ MDScopeRef::get(getNonCompileUnitScope(Context)),
+ MDTypeRef::get(DerivedFrom), SizeInBits, AlignInBits, 0, Flags, Elements,
+ RunTimeLang, MDTypeRef::get(VTableHolder), nullptr, UniqueIdentifier);
if (!UniqueIdentifier.empty())
retainType(R);
trackIfUnresolved(R);
return R;
}
-DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNumber,
+MDCompositeType* DIBuilder::createUnionType(MDScope * Scope, StringRef Name,
+ MDFile* File, unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits, unsigned Flags,
DIArray Elements,
unsigned RunTimeLang,
StringRef UniqueIdentifier) {
- DICompositeType R = MDCompositeType::get(
+ auto *R = MDCompositeType::get(
VMContext, dwarf::DW_TAG_union_type, Name, File, LineNumber,
- DIScope(getNonCompileUnitScope(Scope)).getRef(), nullptr, SizeInBits,
+ MDScopeRef::get(getNonCompileUnitScope(Scope)), nullptr, SizeInBits,
AlignInBits, 0, Flags, Elements, RunTimeLang, nullptr, nullptr,
UniqueIdentifier);
if (!UniqueIdentifier.empty())
@@ -447,21 +424,21 @@ DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name,
return R;
}
-DISubroutineType DIBuilder::createSubroutineType(DIFile File,
- DITypeArray ParameterTypes,
- unsigned Flags) {
+MDSubroutineType *DIBuilder::createSubroutineType(MDFile *File,
+ DITypeArray ParameterTypes,
+ unsigned Flags) {
return MDSubroutineType::get(VMContext, Flags, ParameterTypes);
}
-DICompositeType DIBuilder::createEnumerationType(
- DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber,
+MDCompositeType *DIBuilder::createEnumerationType(
+ MDScope *Scope, StringRef Name, MDFile *File, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements,
- DIType UnderlyingType, StringRef UniqueIdentifier) {
- DICompositeType CTy = MDCompositeType::get(
+ MDType *UnderlyingType, StringRef UniqueIdentifier) {
+ auto *CTy = MDCompositeType::get(
VMContext, dwarf::DW_TAG_enumeration_type, Name, File, LineNumber,
- DIScope(getNonCompileUnitScope(Scope)).getRef(), UnderlyingType.getRef(),
- SizeInBits, AlignInBits, 0, 0, Elements, 0, nullptr, nullptr,
- UniqueIdentifier);
+ MDScopeRef::get(getNonCompileUnitScope(Scope)),
+ MDTypeRef::get(UnderlyingType), SizeInBits, AlignInBits, 0, 0, Elements,
+ 0, nullptr, nullptr, UniqueIdentifier);
AllEnumTypes.push_back(CTy);
if (!UniqueIdentifier.empty())
retainType(CTy);
@@ -469,63 +446,66 @@ DICompositeType DIBuilder::createEnumerationType(
return CTy;
}
-DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits,
- DIType Ty, DIArray Subscripts) {
+MDCompositeType *DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits,
+ MDType *Ty, DIArray Subscripts) {
auto *R = MDCompositeType::get(VMContext, dwarf::DW_TAG_array_type, "",
- nullptr, 0, nullptr, Ty.getRef(), Size,
+ nullptr, 0, nullptr, MDTypeRef::get(Ty), Size,
AlignInBits, 0, 0, Subscripts, 0, nullptr);
trackIfUnresolved(R);
return R;
}
-DICompositeType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits,
- DIType Ty, DIArray Subscripts) {
- auto *R = MDCompositeType::get(
- VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0, nullptr, Ty.getRef(),
- Size, AlignInBits, 0, DIType::FlagVector, Subscripts, 0, nullptr);
+MDCompositeType *DIBuilder::createVectorType(uint64_t Size,
+ uint64_t AlignInBits, MDType *Ty,
+ DIArray Subscripts) {
+ auto *R =
+ MDCompositeType::get(VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0,
+ nullptr, MDTypeRef::get(Ty), Size, AlignInBits, 0,
+ DebugNode::FlagVector, Subscripts, 0, nullptr);
trackIfUnresolved(R);
return R;
}
-static DIType createTypeWithFlags(LLVMContext &Context, DIType Ty,
- unsigned FlagsToSet) {
- TempMDType NewTy = cast<MDType>(static_cast<MDNode *>(Ty))->clone();
+static MDType *createTypeWithFlags(LLVMContext &Context, MDType *Ty,
+ unsigned FlagsToSet) {
+ auto NewTy = Ty->clone();
NewTy->setFlags(NewTy->getFlags() | FlagsToSet);
return MDNode::replaceWithUniqued(std::move(NewTy));
}
-DIType DIBuilder::createArtificialType(DIType Ty) {
+MDType *DIBuilder::createArtificialType(MDType *Ty) {
// FIXME: Restrict this to the nodes where it's valid.
- if (Ty.isArtificial())
+ if (Ty->isArtificial())
return Ty;
- return createTypeWithFlags(VMContext, Ty, DIType::FlagArtificial);
+ return createTypeWithFlags(VMContext, Ty, DebugNode::FlagArtificial);
}
-DIType DIBuilder::createObjectPointerType(DIType Ty) {
+MDType *DIBuilder::createObjectPointerType(MDType *Ty) {
// FIXME: Restrict this to the nodes where it's valid.
- if (Ty.isObjectPointer())
+ if (Ty->isObjectPointer())
return Ty;
- unsigned Flags = DIType::FlagObjectPointer | DIType::FlagArtificial;
+ unsigned Flags = DebugNode::FlagObjectPointer | DebugNode::FlagArtificial;
return createTypeWithFlags(VMContext, Ty, Flags);
}
-void DIBuilder::retainType(DIType T) { AllRetainTypes.emplace_back(T); }
-
-DIBasicType DIBuilder::createUnspecifiedParameter() {
- return DIBasicType();
+void DIBuilder::retainType(MDType *T) {
+ assert(T && "Expected non-null type");
+ AllRetainTypes.emplace_back(T);
}
-DICompositeType
-DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope,
- DIFile F, unsigned Line, unsigned RuntimeLang,
+MDBasicType *DIBuilder::createUnspecifiedParameter() { return nullptr; }
+
+MDCompositeType*
+DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, MDScope * Scope,
+ MDFile* F, unsigned Line, unsigned RuntimeLang,
uint64_t SizeInBits, uint64_t AlignInBits,
StringRef UniqueIdentifier) {
// FIXME: Define in terms of createReplaceableForwardDecl() by calling
// replaceWithUniqued().
- DICompositeType RetTy = MDCompositeType::get(
- VMContext, Tag, Name, F.getFileNode(), Line,
- DIScope(getNonCompileUnitScope(Scope)).getRef(), nullptr, SizeInBits,
- AlignInBits, 0, DIDescriptor::FlagFwdDecl, nullptr, RuntimeLang, nullptr,
+ auto *RetTy = MDCompositeType::get(
+ VMContext, Tag, Name, F, Line,
+ MDScopeRef::get(getNonCompileUnitScope(Scope)), nullptr, SizeInBits,
+ AlignInBits, 0, DebugNode::FlagFwdDecl, nullptr, RuntimeLang, nullptr,
nullptr, UniqueIdentifier);
if (!UniqueIdentifier.empty())
retainType(RetTy);
@@ -533,16 +513,15 @@ DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope,
return RetTy;
}
-DICompositeType DIBuilder::createReplaceableCompositeType(
- unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F, unsigned Line,
+MDCompositeType* DIBuilder::createReplaceableCompositeType(
+ unsigned Tag, StringRef Name, MDScope * Scope, MDFile* F, unsigned Line,
unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits,
unsigned Flags, StringRef UniqueIdentifier) {
- DICompositeType RetTy =
- MDCompositeType::getTemporary(
- VMContext, Tag, Name, F.getFileNode(), Line,
- DIScope(getNonCompileUnitScope(Scope)).getRef(), nullptr, SizeInBits,
- AlignInBits, 0, Flags, nullptr, RuntimeLang,
- nullptr, nullptr, UniqueIdentifier).release();
+ auto *RetTy = MDCompositeType::getTemporary(
+ VMContext, Tag, Name, F, Line,
+ MDScopeRef::get(getNonCompileUnitScope(Scope)), nullptr,
+ SizeInBits, AlignInBits, 0, Flags, nullptr, RuntimeLang,
+ nullptr, nullptr, UniqueIdentifier).release();
if (!UniqueIdentifier.empty())
retainType(RetTy);
trackIfUnresolved(RetTy);
@@ -550,102 +529,102 @@ DICompositeType DIBuilder::createReplaceableCompositeType(
}
DIArray DIBuilder::getOrCreateArray(ArrayRef<Metadata *> Elements) {
- return DIArray(MDNode::get(VMContext, Elements));
+ return MDTuple::get(VMContext, Elements);
}
DITypeArray DIBuilder::getOrCreateTypeArray(ArrayRef<Metadata *> Elements) {
SmallVector<llvm::Metadata *, 16> Elts;
for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
if (Elements[i] && isa<MDNode>(Elements[i]))
- Elts.push_back(DIType(cast<MDNode>(Elements[i])).getRef());
+ Elts.push_back(MDTypeRef::get(cast<MDType>(Elements[i])));
else
Elts.push_back(Elements[i]);
}
return DITypeArray(MDNode::get(VMContext, Elts));
}
-DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) {
+MDSubrange *DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) {
return MDSubrange::get(VMContext, Count, Lo);
}
-static void checkGlobalVariableScope(DIDescriptor Context) {
- MDNode *TheCtx = getNonCompileUnitScope(Context);
- if (DIScope(TheCtx).isCompositeType()) {
- assert(!DICompositeType(TheCtx).getIdentifier() &&
+static void checkGlobalVariableScope(MDScope * Context) {
+#ifndef NDEBUG
+ if (auto *CT =
+ dyn_cast_or_null<MDCompositeType>(getNonCompileUnitScope(Context)))
+ assert(CT->getIdentifier().empty() &&
"Context of a global variable should not be a type with identifier");
- }
+#endif
}
-DIGlobalVariable DIBuilder::createGlobalVariable(
- DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile F,
- unsigned LineNumber, DITypeRef Ty, bool isLocalToUnit, Constant *Val,
+MDGlobalVariable *DIBuilder::createGlobalVariable(
+ MDScope *Context, StringRef Name, StringRef LinkageName, MDFile *F,
+ unsigned LineNumber, MDType *Ty, bool isLocalToUnit, Constant *Val,
MDNode *Decl) {
checkGlobalVariableScope(Context);
- auto *N = MDGlobalVariable::get(VMContext, Context, Name, LinkageName, F,
- LineNumber, Ty, isLocalToUnit, true,
- getConstantOrNull(Val), Decl);
+ auto *N = MDGlobalVariable::get(VMContext, cast_or_null<MDScope>(Context),
+ Name, LinkageName, F, LineNumber,
+ MDTypeRef::get(Ty), isLocalToUnit, true, Val,
+ cast_or_null<MDDerivedType>(Decl));
AllGVs.push_back(N);
return N;
}
-DIGlobalVariable DIBuilder::createTempGlobalVariableFwdDecl(
- DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile F,
- unsigned LineNumber, DITypeRef Ty, bool isLocalToUnit, Constant *Val,
+MDGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(
+ MDScope *Context, StringRef Name, StringRef LinkageName, MDFile *F,
+ unsigned LineNumber, MDType *Ty, bool isLocalToUnit, Constant *Val,
MDNode *Decl) {
checkGlobalVariableScope(Context);
- return MDGlobalVariable::getTemporary(VMContext, Context, Name, LinkageName,
- F, LineNumber, Ty, isLocalToUnit, false,
- getConstantOrNull(Val), Decl).release();
+ return MDGlobalVariable::getTemporary(
+ VMContext, cast_or_null<MDScope>(Context), Name, LinkageName, F,
+ LineNumber, MDTypeRef::get(Ty), isLocalToUnit, false, Val,
+ cast_or_null<MDDerivedType>(Decl))
+ .release();
}
-DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope,
- StringRef Name, DIFile File,
- unsigned LineNo, DITypeRef Ty,
- bool AlwaysPreserve, unsigned Flags,
- unsigned ArgNo) {
+MDLocalVariable *DIBuilder::createLocalVariable(
+ unsigned Tag, MDScope *Scope, StringRef Name, MDFile *File, unsigned LineNo,
+ MDType *Ty, bool AlwaysPreserve, unsigned Flags, unsigned ArgNo) {
// FIXME: Why getNonCompileUnitScope()?
// FIXME: Why is "!Context" okay here?
// FIXME: WHy doesn't this check for a subprogram or lexical block (AFAICT
// the only valid scopes)?
- DIDescriptor Context(getNonCompileUnitScope(Scope));
- assert((!Context || Context.isScope()) &&
- "createLocalVariable should be called with a valid Context");
+ MDScope* Context = getNonCompileUnitScope(Scope);
- auto *Node =
- MDLocalVariable::get(VMContext, Tag, getNonCompileUnitScope(Scope), Name,
- File, LineNo, Ty, ArgNo, Flags);
+ auto *Node = MDLocalVariable::get(
+ VMContext, Tag, cast_or_null<MDLocalScope>(Context), Name, File, LineNo,
+ MDTypeRef::get(Ty), ArgNo, Flags);
if (AlwaysPreserve) {
// The optimizer may remove local variable. If there is an interest
// to preserve variable info in such situation then stash it in a
// named mdnode.
- DISubprogram Fn(getDISubprogram(Scope));
+ MDSubprogram *Fn = getDISubprogram(Scope);
assert(Fn && "Missing subprogram for local variable");
PreservedVariables[Fn].emplace_back(Node);
}
return Node;
}
-DIExpression DIBuilder::createExpression(ArrayRef<uint64_t> Addr) {
+MDExpression* DIBuilder::createExpression(ArrayRef<uint64_t> Addr) {
return MDExpression::get(VMContext, Addr);
}
-DIExpression DIBuilder::createExpression(ArrayRef<int64_t> Signed) {
+MDExpression* DIBuilder::createExpression(ArrayRef<int64_t> Signed) {
// TODO: Remove the callers of this signed version and delete.
SmallVector<uint64_t, 8> Addr(Signed.begin(), Signed.end());
return createExpression(Addr);
}
-DIExpression DIBuilder::createBitPieceExpression(unsigned OffsetInBytes,
+MDExpression* DIBuilder::createBitPieceExpression(unsigned OffsetInBytes,
unsigned SizeInBytes) {
uint64_t Addr[] = {dwarf::DW_OP_bit_piece, OffsetInBytes, SizeInBytes};
return MDExpression::get(VMContext, Addr);
}
-DISubprogram DIBuilder::createFunction(DIScopeRef Context, StringRef Name,
- StringRef LinkageName, DIFile File,
- unsigned LineNo, DICompositeType Ty,
+MDSubprogram* DIBuilder::createFunction(DIScopeRef Context, StringRef Name,
+ StringRef LinkageName, MDFile* File,
+ unsigned LineNo, MDSubroutineType* Ty,
bool isLocalToUnit, bool isDefinition,
unsigned ScopeLine, unsigned Flags,
bool isOptimized, Function *Fn,
@@ -658,20 +637,21 @@ DISubprogram DIBuilder::createFunction(DIScopeRef Context, StringRef Name,
Flags, isOptimized, Fn, TParams, Decl);
}
-DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name,
- StringRef LinkageName, DIFile File,
- unsigned LineNo, DICompositeType Ty,
+MDSubprogram* DIBuilder::createFunction(MDScope * Context, StringRef Name,
+ StringRef LinkageName, MDFile* File,
+ unsigned LineNo, MDSubroutineType* Ty,
bool isLocalToUnit, bool isDefinition,
unsigned ScopeLine, unsigned Flags,
bool isOptimized, Function *Fn,
MDNode *TParams, MDNode *Decl) {
- assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type &&
+ assert(Ty->getTag() == dwarf::DW_TAG_subroutine_type &&
"function types should be subroutines");
auto *Node = MDSubprogram::get(
- VMContext, DIScope(getNonCompileUnitScope(Context)).getRef(), Name,
- LinkageName, File.getFileNode(), LineNo, Ty, isLocalToUnit, isDefinition,
- ScopeLine, nullptr, 0, 0, Flags, isOptimized, getConstantOrNull(Fn),
- TParams, Decl, MDNode::getTemporary(VMContext, None).release());
+ VMContext, MDScopeRef::get(getNonCompileUnitScope(Context)), Name,
+ LinkageName, File, LineNo, Ty,
+ isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, Flags, isOptimized,
+ Fn, cast_or_null<MDTuple>(TParams), cast_or_null<MDSubprogram>(Decl),
+ MDTuple::getTemporary(VMContext, None).release());
if (isDefinition)
AllSubprograms.push_back(Node);
@@ -679,78 +659,64 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name,
return Node;
}
-DISubprogram
-DIBuilder::createTempFunctionFwdDecl(DIDescriptor Context, StringRef Name,
- StringRef LinkageName, DIFile File,
- unsigned LineNo, DICompositeType Ty,
+MDSubprogram*
+DIBuilder::createTempFunctionFwdDecl(MDScope * Context, StringRef Name,
+ StringRef LinkageName, MDFile* File,
+ unsigned LineNo, MDSubroutineType* Ty,
bool isLocalToUnit, bool isDefinition,
unsigned ScopeLine, unsigned Flags,
bool isOptimized, Function *Fn,
MDNode *TParams, MDNode *Decl) {
return MDSubprogram::getTemporary(
- VMContext, DIScope(getNonCompileUnitScope(Context)).getRef(), Name,
- LinkageName, File.getFileNode(), LineNo, Ty, isLocalToUnit,
- isDefinition, ScopeLine, nullptr, 0, 0, Flags, isOptimized,
- getConstantOrNull(Fn), TParams, Decl, nullptr).release();
-}
-
-DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name,
- StringRef LinkageName, DIFile F,
- unsigned LineNo, DICompositeType Ty,
- bool isLocalToUnit, bool isDefinition,
- unsigned VK, unsigned VIndex,
- DIType VTableHolder, unsigned Flags,
- bool isOptimized, Function *Fn,
- MDNode *TParam) {
- assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type &&
+ VMContext, MDScopeRef::get(getNonCompileUnitScope(Context)), Name,
+ LinkageName, File, LineNo, Ty,
+ isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, Flags,
+ isOptimized, Fn, cast_or_null<MDTuple>(TParams),
+ cast_or_null<MDSubprogram>(Decl), nullptr).release();
+}
+
+MDSubprogram *
+DIBuilder::createMethod(MDScope *Context, StringRef Name, StringRef LinkageName,
+ MDFile *F, unsigned LineNo, MDSubroutineType *Ty,
+ bool isLocalToUnit, bool isDefinition, unsigned VK,
+ unsigned VIndex, MDType *VTableHolder, unsigned Flags,
+ bool isOptimized, Function *Fn, MDNode *TParam) {
+ assert(Ty->getTag() == dwarf::DW_TAG_subroutine_type &&
"function types should be subroutines");
assert(getNonCompileUnitScope(Context) &&
"Methods should have both a Context and a context that isn't "
"the compile unit.");
// FIXME: Do we want to use different scope/lines?
- auto *Node = MDSubprogram::get(
- VMContext, DIScope(Context).getRef(), Name, LinkageName, F.getFileNode(),
- LineNo, Ty, isLocalToUnit, isDefinition, LineNo, VTableHolder.getRef(),
- VK, VIndex, Flags, isOptimized, getConstantOrNull(Fn), TParam, nullptr,
- nullptr);
+ auto *SP = MDSubprogram::get(
+ VMContext, MDScopeRef::get(cast<MDScope>(Context)), Name, LinkageName, F,
+ LineNo, Ty, isLocalToUnit, isDefinition, LineNo,
+ MDTypeRef::get(VTableHolder), VK, VIndex, Flags, isOptimized, Fn,
+ cast_or_null<MDTuple>(TParam), nullptr, nullptr);
if (isDefinition)
- AllSubprograms.push_back(Node);
- DISubprogram S(Node);
- assert(S.isSubprogram() && "createMethod should return a valid DISubprogram");
- trackIfUnresolved(S);
- return S;
-}
-
-DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNo) {
- DINameSpace R = MDNamespace::get(VMContext, getNonCompileUnitScope(Scope),
- File.getFileNode(), Name, LineNo);
- assert(R.Verify() &&
- "createNameSpace should return a verifiable DINameSpace");
- return R;
+ AllSubprograms.push_back(SP);
+ trackIfUnresolved(SP);
+ return SP;
+}
+
+MDNamespace* DIBuilder::createNameSpace(MDScope * Scope, StringRef Name,
+ MDFile* File, unsigned LineNo) {
+ return MDNamespace::get(VMContext, getNonCompileUnitScope(Scope), File, Name,
+ LineNo);
}
-DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope,
- DIFile File,
+MDLexicalBlockFile* DIBuilder::createLexicalBlockFile(MDScope * Scope,
+ MDFile* File,
unsigned Discriminator) {
- DILexicalBlockFile R = MDLexicalBlockFile::get(
- VMContext, Scope, File.getFileNode(), Discriminator);
- assert(
- R.Verify() &&
- "createLexicalBlockFile should return a verifiable DILexicalBlockFile");
- return R;
+ return MDLexicalBlockFile::get(VMContext, Scope, File, Discriminator);
}
-DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File,
+MDLexicalBlock* DIBuilder::createLexicalBlock(MDScope * Scope, MDFile* File,
unsigned Line, unsigned Col) {
// Make these distinct, to avoid merging two lexical blocks on the same
// file/line/column.
- DILexicalBlock R = MDLexicalBlock::getDistinct(
- VMContext, getNonCompileUnitScope(Scope), File.getFileNode(), Line, Col);
- assert(R.Verify() &&
- "createLexicalBlock should return a verifiable DILexicalBlock");
- return R;
+ return MDLexicalBlock::getDistinct(VMContext, getNonCompileUnitScope(Scope),
+ File, Line, Col);
}
static Value *getDbgIntrinsicValueImpl(LLVMContext &VMContext, Value *V) {
@@ -758,11 +724,19 @@ static Value *getDbgIntrinsicValueImpl(LLVMContext &VMContext, Value *V) {
return MetadataAsValue::get(VMContext, ValueAsMetadata::get(V));
}
-Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,
- DIExpression Expr,
+static Instruction *withDebugLoc(Instruction *I, const MDLocation *DL) {
+ I->setDebugLoc(const_cast<MDLocation *>(DL));
+ return I;
+}
+
+Instruction *DIBuilder::insertDeclare(Value *Storage, MDLocalVariable* VarInfo,
+ MDExpression* Expr, const MDLocation *DL,
Instruction *InsertBefore) {
- assert(VarInfo.isVariable() &&
- "empty or invalid DIVariable passed to dbg.declare");
+ assert(VarInfo && "empty or invalid MDLocalVariable* passed to dbg.declare");
+ assert(DL && "Expected debug loc");
+ assert(DL->getScope()->getSubprogram() ==
+ VarInfo->getScope()->getSubprogram() &&
+ "Expected matching subprograms");
if (!DeclareFn)
DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
@@ -771,14 +745,17 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,
Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, Storage),
MetadataAsValue::get(VMContext, VarInfo),
MetadataAsValue::get(VMContext, Expr)};
- return CallInst::Create(DeclareFn, Args, "", InsertBefore);
+ return withDebugLoc(CallInst::Create(DeclareFn, Args, "", InsertBefore), DL);
}
-Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,
- DIExpression Expr,
+Instruction *DIBuilder::insertDeclare(Value *Storage, MDLocalVariable* VarInfo,
+ MDExpression* Expr, const MDLocation *DL,
BasicBlock *InsertAtEnd) {
- assert(VarInfo.isVariable() &&
- "empty or invalid DIVariable passed to dbg.declare");
+ assert(VarInfo && "empty or invalid MDLocalVariable* passed to dbg.declare");
+ assert(DL && "Expected debug loc");
+ assert(DL->getScope()->getSubprogram() ==
+ VarInfo->getScope()->getSubprogram() &&
+ "Expected matching subprograms");
if (!DeclareFn)
DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
@@ -791,18 +768,21 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,
// If this block already has a terminator then insert this intrinsic
// before the terminator.
if (TerminatorInst *T = InsertAtEnd->getTerminator())
- return CallInst::Create(DeclareFn, Args, "", T);
- else
- return CallInst::Create(DeclareFn, Args, "", InsertAtEnd);
+ return withDebugLoc(CallInst::Create(DeclareFn, Args, "", T), DL);
+ return withDebugLoc(CallInst::Create(DeclareFn, Args, "", InsertAtEnd), DL);
}
Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,
- DIVariable VarInfo,
- DIExpression Expr,
+ MDLocalVariable* VarInfo,
+ MDExpression* Expr,
+ const MDLocation *DL,
Instruction *InsertBefore) {
assert(V && "no value passed to dbg.value");
- assert(VarInfo.isVariable() &&
- "empty or invalid DIVariable passed to dbg.value");
+ assert(VarInfo && "empty or invalid MDLocalVariable* passed to dbg.value");
+ assert(DL && "Expected debug loc");
+ assert(DL->getScope()->getSubprogram() ==
+ VarInfo->getScope()->getSubprogram() &&
+ "Expected matching subprograms");
if (!ValueFn)
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
@@ -812,16 +792,20 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,
ConstantInt::get(Type::getInt64Ty(VMContext), Offset),
MetadataAsValue::get(VMContext, VarInfo),
MetadataAsValue::get(VMContext, Expr)};
- return CallInst::Create(ValueFn, Args, "", InsertBefore);
+ return withDebugLoc(CallInst::Create(ValueFn, Args, "", InsertBefore), DL);
}
Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,
- DIVariable VarInfo,
- DIExpression Expr,
+ MDLocalVariable* VarInfo,
+ MDExpression* Expr,
+ const MDLocation *DL,
BasicBlock *InsertAtEnd) {
assert(V && "no value passed to dbg.value");
- assert(VarInfo.isVariable() &&
- "empty or invalid DIVariable passed to dbg.value");
+ assert(VarInfo && "empty or invalid MDLocalVariable* passed to dbg.value");
+ assert(DL && "Expected debug loc");
+ assert(DL->getScope()->getSubprogram() ==
+ VarInfo->getScope()->getSubprogram() &&
+ "Expected matching subprograms");
if (!ValueFn)
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
@@ -831,11 +815,16 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,
ConstantInt::get(Type::getInt64Ty(VMContext), Offset),
MetadataAsValue::get(VMContext, VarInfo),
MetadataAsValue::get(VMContext, Expr)};
- return CallInst::Create(ValueFn, Args, "", InsertAtEnd);
+
+ return withDebugLoc(CallInst::Create(ValueFn, Args, "", InsertAtEnd), DL);
}
-void DIBuilder::replaceVTableHolder(DICompositeType &T, DICompositeType VTableHolder) {
- T.setContainingType(VTableHolder);
+void DIBuilder::replaceVTableHolder(MDCompositeType* &T, MDCompositeType* VTableHolder) {
+ {
+ TypedTrackingMDRef<MDCompositeType> N(T);
+ N->replaceVTableHolder(MDTypeRef::get(VTableHolder));
+ T = N.get();
+ }
// If this didn't create a self-reference, just return.
if (T != VTableHolder)
@@ -849,9 +838,16 @@ void DIBuilder::replaceVTableHolder(DICompositeType &T, DICompositeType VTableHo
trackIfUnresolved(N);
}
-void DIBuilder::replaceArrays(DICompositeType &T, DIArray Elements,
+void DIBuilder::replaceArrays(MDCompositeType* &T, DIArray Elements,
DIArray TParams) {
- T.setArrays(Elements, TParams);
+ {
+ TypedTrackingMDRef<MDCompositeType> N(T);
+ if (Elements)
+ N->replaceElements(Elements);
+ if (TParams)
+ N->replaceTemplateParams(MDTemplateParameterArray(TParams));
+ T = N.get();
+ }
// If T isn't resolved, there's no problem.
if (!T->isResolved())
@@ -861,7 +857,7 @@ void DIBuilder::replaceArrays(DICompositeType &T, DIArray Elements,
// arrays explicitly if they're unresolved, or else the cycles will be
// orphaned.
if (Elements)
- trackIfUnresolved(Elements);
+ trackIfUnresolved(Elements.get());
if (TParams)
- trackIfUnresolved(TParams);
+ trackIfUnresolved(TParams.get());
}
diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp
index 9a6b953..719c28b 100644
--- a/lib/IR/DebugInfo.cpp
+++ b/lib/IR/DebugInfo.cpp
@@ -17,7 +17,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DIBuilder.h"
@@ -25,6 +24,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Debug.h"
@@ -33,612 +33,62 @@
using namespace llvm;
using namespace llvm::dwarf;
-//===----------------------------------------------------------------------===//
-// DIDescriptor
-//===----------------------------------------------------------------------===//
-
-unsigned DIDescriptor::getFlag(StringRef Flag) {
- return StringSwitch<unsigned>(Flag)
-#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
-#include "llvm/IR/DebugInfoFlags.def"
- .Default(0);
-}
-
-const char *DIDescriptor::getFlagString(unsigned Flag) {
- switch (Flag) {
- default:
- return "";
-#define HANDLE_DI_FLAG(ID, NAME) \
- case Flag##NAME: \
- return "DIFlag" #NAME;
-#include "llvm/IR/DebugInfoFlags.def"
- }
-}
-
-unsigned DIDescriptor::splitFlags(unsigned Flags,
- SmallVectorImpl<unsigned> &SplitFlags) {
- // Accessibility flags need to be specially handled, since they're packed
- // together.
- if (unsigned A = Flags & FlagAccessibility) {
- if (A == FlagPrivate)
- SplitFlags.push_back(FlagPrivate);
- else if (A == FlagProtected)
- SplitFlags.push_back(FlagProtected);
- else
- SplitFlags.push_back(FlagPublic);
- Flags &= ~A;
- }
-
-#define HANDLE_DI_FLAG(ID, NAME) \
- if (unsigned Bit = Flags & ID) { \
- SplitFlags.push_back(Bit); \
- Flags &= ~Bit; \
- }
-#include "llvm/IR/DebugInfoFlags.def"
-
- return Flags;
-}
-
-bool DIDescriptor::Verify() const {
- return DbgNode &&
- (DIDerivedType(DbgNode).Verify() ||
- DICompositeType(DbgNode).Verify() || DIBasicType(DbgNode).Verify() ||
- DIVariable(DbgNode).Verify() || DISubprogram(DbgNode).Verify() ||
- DIGlobalVariable(DbgNode).Verify() || DIFile(DbgNode).Verify() ||
- DICompileUnit(DbgNode).Verify() || DINameSpace(DbgNode).Verify() ||
- DILexicalBlock(DbgNode).Verify() ||
- DILexicalBlockFile(DbgNode).Verify() ||
- DISubrange(DbgNode).Verify() || DIEnumerator(DbgNode).Verify() ||
- DIObjCProperty(DbgNode).Verify() ||
- DITemplateTypeParameter(DbgNode).Verify() ||
- DITemplateValueParameter(DbgNode).Verify() ||
- DIImportedEntity(DbgNode).Verify());
-}
-
-static Metadata *getField(const MDNode *DbgNode, unsigned Elt) {
- if (!DbgNode || Elt >= DbgNode->getNumOperands())
- return nullptr;
- return DbgNode->getOperand(Elt);
-}
-
-static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) {
- return dyn_cast_or_null<MDNode>(getField(DbgNode, Elt));
-}
-
-static StringRef getStringField(const MDNode *DbgNode, unsigned Elt) {
- if (MDString *MDS = dyn_cast_or_null<MDString>(getField(DbgNode, Elt)))
- return MDS->getString();
- return StringRef();
-}
-
-StringRef DIDescriptor::getStringField(unsigned Elt) const {
- return ::getStringField(DbgNode, Elt);
-}
-
-uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
- if (auto *C = getConstantField(Elt))
- if (ConstantInt *CI = dyn_cast<ConstantInt>(C))
- return CI->getZExtValue();
-
- return 0;
-}
-
-int64_t DIDescriptor::getInt64Field(unsigned Elt) const {
- if (auto *C = getConstantField(Elt))
- if (ConstantInt *CI = dyn_cast<ConstantInt>(C))
- return CI->getZExtValue();
-
- return 0;
-}
-
-DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const {
- MDNode *Field = getNodeField(DbgNode, Elt);
- return DIDescriptor(Field);
-}
-
-GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const {
- return dyn_cast_or_null<GlobalVariable>(getConstantField(Elt));
-}
-
-Constant *DIDescriptor::getConstantField(unsigned Elt) const {
- if (!DbgNode)
- return nullptr;
-
- if (Elt < DbgNode->getNumOperands())
- if (auto *C =
- dyn_cast_or_null<ConstantAsMetadata>(DbgNode->getOperand(Elt)))
- return C->getValue();
- return nullptr;
-}
-
-Function *DIDescriptor::getFunctionField(unsigned Elt) const {
- return dyn_cast_or_null<Function>(getConstantField(Elt));
-}
-
-/// \brief Return the size reported by the variable's type.
-unsigned DIVariable::getSizeInBits(const DITypeIdentifierMap &Map) {
- DIType Ty = getType().resolve(Map);
- // Follow derived types until we reach a type that
- // reports back a size.
- while (Ty.isDerivedType() && !Ty.getSizeInBits()) {
- DIDerivedType DT(&*Ty);
- Ty = DT.getTypeDerivedFrom().resolve(Map);
- }
- assert(Ty.getSizeInBits() && "type with size 0");
- return Ty.getSizeInBits();
-}
-
-bool DIExpression::isBitPiece() const {
- unsigned N = getNumElements();
- return N >=3 && getElement(N-3) == dwarf::DW_OP_bit_piece;
-}
-
-uint64_t DIExpression::getBitPieceOffset() const {
- assert(isBitPiece() && "not a piece");
- return getElement(getNumElements()-2);
-}
-
-uint64_t DIExpression::getBitPieceSize() const {
- assert(isBitPiece() && "not a piece");
- return getElement(getNumElements()-1);
-}
-
-DIExpression::iterator DIExpression::Operand::getNext() const {
- iterator it(I);
- return ++it;
-}
-
-//===----------------------------------------------------------------------===//
-// Simple Descriptor Constructors and other Methods
-//===----------------------------------------------------------------------===//
-
-void DIDescriptor::replaceAllUsesWith(LLVMContext &, DIDescriptor D) {
- assert(DbgNode && "Trying to replace an unverified type!");
- assert(DbgNode->isTemporary() && "Expected temporary node");
- TempMDNode Temp(get());
-
- // 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 (Temp.get() == D.get()) {
- DbgNode = MDNode::replaceWithUniqued(std::move(Temp));
- return;
- }
-
- Temp->replaceAllUsesWith(D.get());
- DbgNode = D.get();
-}
-
-void DIDescriptor::replaceAllUsesWith(MDNode *D) {
- assert(DbgNode && "Trying to replace an unverified type!");
- assert(DbgNode != D && "This replacement should always happen");
- assert(DbgNode->isTemporary() && "Expected temporary node");
- TempMDNode Node(get());
- Node->replaceAllUsesWith(D);
-}
-
-bool DICompileUnit::Verify() const {
- if (!isCompileUnit())
- return false;
-
- // Don't bother verifying the compilation directory or producer string
- // as those could be empty.
- return !getFilename().empty();
-}
-
-bool DIObjCProperty::Verify() const { return isObjCProperty(); }
-
-/// \brief Check if a value can be a reference to a type.
-static bool isTypeRef(const Metadata *MD) {
- if (!MD)
- return true;
- if (auto *S = dyn_cast<MDString>(MD))
- return !S->getString().empty();
- return isa<MDType>(MD);
-}
-
-/// \brief Check if a value can be a ScopeRef.
-static bool isScopeRef(const Metadata *MD) {
- if (!MD)
- return true;
- if (auto *S = dyn_cast<MDString>(MD))
- return !S->getString().empty();
- return isa<MDScope>(MD);
-}
-
-#ifndef NDEBUG
-/// \brief Check if a value can be a DescriptorRef.
-static bool isDescriptorRef(const Metadata *MD) {
- if (!MD)
- return true;
- if (auto *S = dyn_cast<MDString>(MD))
- return !S->getString().empty();
- return isa<MDNode>(MD);
-}
-#endif
-
-bool DIType::Verify() const {
- auto *N = dyn_cast_or_null<MDType>(DbgNode);
- if (!N)
- return false;
- if (!isScopeRef(N->getScope()))
- return false;
-
- // DIType is abstract, it should be a BasicType, a DerivedType or
- // a CompositeType.
- if (isBasicType())
- return DIBasicType(DbgNode).Verify();
-
- // FIXME: Sink this into the various subclass verifies.
- if (getFilename().empty()) {
- // Check whether the filename is allowed to be empty.
- uint16_t Tag = getTag();
- if (Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
- Tag != dwarf::DW_TAG_pointer_type &&
- Tag != dwarf::DW_TAG_ptr_to_member_type &&
- Tag != dwarf::DW_TAG_reference_type &&
- Tag != dwarf::DW_TAG_rvalue_reference_type &&
- Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_array_type &&
- Tag != dwarf::DW_TAG_enumeration_type &&
- Tag != dwarf::DW_TAG_subroutine_type &&
- Tag != dwarf::DW_TAG_inheritance && Tag != dwarf::DW_TAG_friend &&
- Tag != dwarf::DW_TAG_structure_type && Tag != dwarf::DW_TAG_member &&
- Tag != dwarf::DW_TAG_typedef)
- return false;
- }
-
- if (isCompositeType())
- return DICompositeType(DbgNode).Verify();
- if (isDerivedType())
- return DIDerivedType(DbgNode).Verify();
- return false;
-}
-
-bool DIBasicType::Verify() const {
- return dyn_cast_or_null<MDBasicType>(DbgNode);
-}
-
-bool DIDerivedType::Verify() const {
- auto *N = dyn_cast_or_null<MDDerivedTypeBase>(DbgNode);
- if (!N)
- return false;
- if (getTag() == dwarf::DW_TAG_ptr_to_member_type) {
- auto *D = dyn_cast<MDDerivedType>(N);
- if (!D)
- return false;
- if (!isTypeRef(D->getExtraData()))
- return false;
- }
- return isTypeRef(N->getBaseType());
-}
-
-bool DICompositeType::Verify() const {
- auto *N = dyn_cast_or_null<MDCompositeTypeBase>(DbgNode);
- return N && isTypeRef(N->getBaseType()) && isTypeRef(N->getVTableHolder()) &&
- !(isLValueReference() && isRValueReference());
-}
-
-bool DISubprogram::Verify() const {
- auto *N = dyn_cast_or_null<MDSubprogram>(DbgNode);
- if (!N)
- return false;
-
- if (!isScopeRef(N->getScope()))
- return false;
-
- if (auto *Op = N->getType())
- if (!isa<MDNode>(Op))
- return false;
-
- if (!isTypeRef(getContainingType()))
- return false;
-
- if (isLValueReference() && isRValueReference())
- return false;
-
- // If a DISubprogram has an llvm::Function*, then scope chains from all
- // instructions within the function should lead to this DISubprogram.
- if (auto *F = getFunction()) {
- for (auto &BB : *F) {
- for (auto &I : BB) {
- DebugLoc DL = I.getDebugLoc();
- if (DL.isUnknown())
- continue;
-
- MDNode *Scope = nullptr;
- MDNode *IA = nullptr;
- // walk the inlined-at scopes
- while ((IA = DL.getInlinedAt()))
- DL = DebugLoc::getFromDILocation(IA);
- DL.getScopeAndInlinedAt(Scope, IA);
- if (!Scope)
- return false;
- assert(!IA);
- while (!DIDescriptor(Scope).isSubprogram()) {
- DILexicalBlockFile D(Scope);
- Scope = D.isLexicalBlockFile()
- ? D.getScope()
- : DebugLoc::getFromDILexicalBlock(Scope).getScope();
- if (!Scope)
- return false;
- }
- if (!DISubprogram(Scope).describes(F))
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool DIGlobalVariable::Verify() const {
- auto *N = dyn_cast_or_null<MDGlobalVariable>(DbgNode);
-
- if (!N)
- return false;
-
- if (N->getDisplayName().empty())
- return false;
-
- if (auto *Op = N->getScope())
- if (!isa<MDNode>(Op))
- return false;
-
- if (auto *Op = N->getStaticDataMemberDeclaration())
- if (!isa<MDNode>(Op))
- return false;
-
- return isTypeRef(N->getType());
-}
-
-bool DIVariable::Verify() const {
- auto *N = dyn_cast_or_null<MDLocalVariable>(DbgNode);
-
- if (!N)
- return false;
-
- if (auto *Op = N->getScope())
- if (!isa<MDNode>(Op))
- return false;
-
- return isTypeRef(N->getType());
-}
-
-bool DILocation::Verify() const {
- return dyn_cast_or_null<MDLocation>(DbgNode);
-}
-bool DINameSpace::Verify() const {
- return dyn_cast_or_null<MDNamespace>(DbgNode);
-}
-bool DIFile::Verify() const { return dyn_cast_or_null<MDFile>(DbgNode); }
-bool DIEnumerator::Verify() const {
- return dyn_cast_or_null<MDEnumerator>(DbgNode);
-}
-bool DISubrange::Verify() const {
- return dyn_cast_or_null<MDSubrange>(DbgNode);
-}
-bool DILexicalBlock::Verify() const {
- return dyn_cast_or_null<MDLexicalBlock>(DbgNode);
-}
-bool DILexicalBlockFile::Verify() const {
- return dyn_cast_or_null<MDLexicalBlockFile>(DbgNode);
-}
-bool DITemplateTypeParameter::Verify() const {
- return dyn_cast_or_null<MDTemplateTypeParameter>(DbgNode);
-}
-bool DITemplateValueParameter::Verify() const {
- return dyn_cast_or_null<MDTemplateValueParameter>(DbgNode);
-}
-bool DIImportedEntity::Verify() const {
- return dyn_cast_or_null<MDImportedEntity>(DbgNode);
-}
-
-void DICompositeType::setArraysHelper(MDNode *Elements, MDNode *TParams) {
- TypedTrackingMDRef<MDCompositeTypeBase> N(get());
- if (Elements)
- N->replaceElements(cast<MDTuple>(Elements));
- if (TParams)
- N->replaceTemplateParams(cast<MDTuple>(TParams));
- DbgNode = N;
-}
-
-DIScopeRef DIScope::getRef() const {
- if (!isCompositeType())
- return DIScopeRef(*this);
- DICompositeType DTy(DbgNode);
- if (!DTy.getIdentifier())
- return DIScopeRef(*this);
- return DIScopeRef(DTy.getIdentifier());
-}
-
-void DICompositeType::setContainingType(DICompositeType ContainingType) {
- TypedTrackingMDRef<MDCompositeTypeBase> N(get());
- N->replaceVTableHolder(ContainingType.getRef());
- DbgNode = N;
-}
-
-bool DIVariable::isInlinedFnArgument(const Function *CurFn) {
- assert(CurFn && "Invalid function");
- if (!getContext().isSubprogram())
- return false;
- // This variable is not inlined function argument if its scope
- // does not describe current function.
- return !DISubprogram(getContext()).describes(CurFn);
-}
-
-Function *DISubprogram::getFunction() const {
- if (auto *N = get())
- if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getFunction()))
- return dyn_cast<Function>(C->getValue());
- return nullptr;
-}
-
-bool DISubprogram::describes(const Function *F) {
- assert(F && "Invalid function");
- if (F == getFunction())
- return true;
- StringRef Name = getLinkageName();
- if (Name.empty())
- Name = getName();
- if (F->getName() == Name)
- return true;
- return false;
-}
-
-GlobalVariable *DIGlobalVariable::getGlobal() const {
- return dyn_cast_or_null<GlobalVariable>(getConstant());
-}
-
-DIScopeRef DIScope::getContext() const {
-
- if (isType())
- return DIType(DbgNode).getContext();
-
- if (isSubprogram())
- return DIScopeRef(DISubprogram(DbgNode).getContext());
-
- if (isLexicalBlock())
- return DIScopeRef(DILexicalBlock(DbgNode).getContext());
-
- if (isLexicalBlockFile())
- return DIScopeRef(DILexicalBlockFile(DbgNode).getContext());
-
- if (isNameSpace())
- return DIScopeRef(DINameSpace(DbgNode).getContext());
-
- assert((isFile() || isCompileUnit()) && "Unhandled type of scope.");
- return DIScopeRef(nullptr);
-}
-
-StringRef DIScope::getName() const {
- if (isType())
- return DIType(DbgNode).getName();
- if (isSubprogram())
- return DISubprogram(DbgNode).getName();
- if (isNameSpace())
- return DINameSpace(DbgNode).getName();
- assert((isLexicalBlock() || isLexicalBlockFile() || isFile() ||
- isCompileUnit()) &&
- "Unhandled type of scope.");
- return StringRef();
-}
-
-StringRef DIScope::getFilename() const {
- if (auto *N = get())
- return ::getStringField(dyn_cast_or_null<MDNode>(N->getFile()), 0);
- return "";
-}
-
-StringRef DIScope::getDirectory() const {
- if (auto *N = get())
- return ::getStringField(dyn_cast_or_null<MDNode>(N->getFile()), 1);
- return "";
-}
-
-void DICompileUnit::replaceSubprograms(DIArray Subprograms) {
- assert(Verify() && "Expected compile unit");
- get()->replaceSubprograms(cast_or_null<MDTuple>(Subprograms.get()));
-}
-
-void DICompileUnit::replaceGlobalVariables(DIArray GlobalVariables) {
- assert(Verify() && "Expected compile unit");
- get()->replaceGlobalVariables(cast_or_null<MDTuple>(GlobalVariables.get()));
-}
-
-DILocation DILocation::copyWithNewScope(LLVMContext &Ctx,
- DILexicalBlockFile NewScope) {
- assert(Verify());
- assert(NewScope && "Expected valid scope");
-
- const auto *Old = cast<MDLocation>(DbgNode);
- return DILocation(MDLocation::get(Ctx, Old->getLine(), Old->getColumn(),
- NewScope, Old->getInlinedAt()));
-}
-
-unsigned DILocation::computeNewDiscriminator(LLVMContext &Ctx) {
- std::pair<const char *, unsigned> Key(getFilename().data(), getLineNumber());
- return ++Ctx.pImpl->DiscriminatorTable[Key];
-}
-
-DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
- LLVMContext &VMContext) {
- assert(DIVariable(DV).Verify() && "Expected a DIVariable");
- return cast<MDLocalVariable>(DV)
- ->withInline(cast_or_null<MDLocation>(InlinedScope));
-}
-
-DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) {
- assert(DIVariable(DV).Verify() && "Expected a DIVariable");
- return cast<MDLocalVariable>(DV)->withoutInline();
-}
-
DISubprogram llvm::getDISubprogram(const MDNode *Scope) {
- DIDescriptor D(Scope);
- if (D.isSubprogram())
- return DISubprogram(Scope);
-
- if (D.isLexicalBlockFile())
- return getDISubprogram(DILexicalBlockFile(Scope).getContext());
-
- if (D.isLexicalBlock())
- return getDISubprogram(DILexicalBlock(Scope).getContext());
-
- return DISubprogram();
+ if (auto *LocalScope = dyn_cast_or_null<MDLocalScope>(Scope))
+ return LocalScope->getSubprogram();
+ return nullptr;
}
DISubprogram llvm::getDISubprogram(const Function *F) {
// We look for the first instr that has a debug annotation leading back to F.
for (auto &BB : *F) {
auto Inst = std::find_if(BB.begin(), BB.end(), [](const Instruction &Inst) {
- return !Inst.getDebugLoc().isUnknown();
+ return Inst.getDebugLoc();
});
if (Inst == BB.end())
continue;
DebugLoc DLoc = Inst->getDebugLoc();
- const MDNode *Scope = DLoc.getScopeNode();
+ const MDNode *Scope = DLoc.getInlinedAtScope();
DISubprogram Subprogram = getDISubprogram(Scope);
- return Subprogram.describes(F) ? Subprogram : DISubprogram();
+ return Subprogram->describes(F) ? Subprogram : DISubprogram();
}
return DISubprogram();
}
DICompositeType llvm::getDICompositeType(DIType T) {
- if (T.isCompositeType())
- return DICompositeType(T);
+ if (auto *C = dyn_cast_or_null<MDCompositeTypeBase>(T))
+ return C;
- if (T.isDerivedType()) {
+ if (auto *D = dyn_cast_or_null<MDDerivedTypeBase>(T)) {
// This function is currently used by dragonegg and dragonegg does
// not generate identifier for types, so using an empty map to resolve
// DerivedFrom should be fine.
DITypeIdentifierMap EmptyMap;
- return getDICompositeType(
- DIDerivedType(T).getTypeDerivedFrom().resolve(EmptyMap));
+ return getDICompositeType(D->getBaseType().resolve(EmptyMap));
}
- return DICompositeType();
+ return nullptr;
}
DITypeIdentifierMap
llvm::generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes) {
DITypeIdentifierMap Map;
for (unsigned CUi = 0, CUe = CU_Nodes->getNumOperands(); CUi != CUe; ++CUi) {
- DICompileUnit CU(CU_Nodes->getOperand(CUi));
- DIArray Retain = CU.getRetainedTypes();
- for (unsigned Ti = 0, Te = Retain.getNumElements(); Ti != Te; ++Ti) {
- if (!Retain.getElement(Ti).isCompositeType())
+ auto *CU = cast<MDCompileUnit>(CU_Nodes->getOperand(CUi));
+ DIArray Retain = CU->getRetainedTypes();
+ for (unsigned Ti = 0, Te = Retain.size(); Ti != Te; ++Ti) {
+ if (!isa<MDCompositeType>(Retain[Ti]))
continue;
- DICompositeType Ty(Retain.getElement(Ti));
- if (MDString *TypeId = Ty.getIdentifier()) {
+ auto *Ty = cast<MDCompositeType>(Retain[Ti]);
+ if (MDString *TypeId = Ty->getRawIdentifier()) {
// Definition has priority over declaration.
// Try to insert (TypeId, Ty) to Map.
std::pair<DITypeIdentifierMap::iterator, bool> P =
Map.insert(std::make_pair(TypeId, Ty));
// If TypeId already exists in Map and this is a definition, replace
// whatever we had (declaration or definition) with the definition.
- if (!P.second && !Ty.isForwardDecl())
+ if (!P.second && !Ty->isForwardDecl())
P.first->second = Ty;
}
}
@@ -673,37 +123,28 @@ void DebugInfoFinder::processModule(const Module &M) {
InitializeTypeMap(M);
if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) {
for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
- DICompileUnit CU(CU_Nodes->getOperand(i));
+ DICompileUnit CU = cast<MDCompileUnit>(CU_Nodes->getOperand(i));
addCompileUnit(CU);
- DIArray GVs = CU.getGlobalVariables();
- for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) {
- DIGlobalVariable DIG(GVs.getElement(i));
+ for (DIGlobalVariable DIG : CU->getGlobalVariables()) {
if (addGlobalVariable(DIG)) {
- processScope(DIG.getContext());
- processType(DIG.getType().resolve(TypeIdentifierMap));
+ processScope(DIG->getScope());
+ processType(DIG->getType().resolve(TypeIdentifierMap));
}
}
- DIArray SPs = CU.getSubprograms();
- for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i)
- processSubprogram(DISubprogram(SPs.getElement(i)));
- DIArray EnumTypes = CU.getEnumTypes();
- for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i)
- processType(DIType(EnumTypes.getElement(i)));
- DIArray RetainedTypes = CU.getRetainedTypes();
- for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i)
- processType(DIType(RetainedTypes.getElement(i)));
- DIArray Imports = CU.getImportedEntities();
- for (unsigned i = 0, e = Imports.getNumElements(); i != e; ++i) {
- DIImportedEntity Import = DIImportedEntity(Imports.getElement(i));
- if (!Import)
- continue;
- DIDescriptor Entity = Import.getEntity().resolve(TypeIdentifierMap);
- if (Entity.isType())
- processType(DIType(Entity));
- else if (Entity.isSubprogram())
- processSubprogram(DISubprogram(Entity));
- else if (Entity.isNameSpace())
- processScope(DINameSpace(Entity).getContext());
+ for (auto *SP : CU->getSubprograms())
+ processSubprogram(SP);
+ for (auto *ET : CU->getEnumTypes())
+ processType(ET);
+ for (auto *RT : CU->getRetainedTypes())
+ processType(RT);
+ for (DIImportedEntity Import : CU->getImportedEntities()) {
+ auto *Entity = Import->getEntity().resolve(TypeIdentifierMap);
+ if (auto *T = dyn_cast<MDType>(Entity))
+ processType(T);
+ else if (auto *SP = dyn_cast<MDSubprogram>(Entity))
+ processSubprogram(SP);
+ else if (auto *NS = dyn_cast<MDNamespace>(Entity))
+ processScope(NS->getScope());
}
}
}
@@ -713,79 +154,66 @@ void DebugInfoFinder::processLocation(const Module &M, DILocation Loc) {
if (!Loc)
return;
InitializeTypeMap(M);
- processScope(Loc.getScope());
- processLocation(M, Loc.getOrigLocation());
+ processScope(Loc->getScope());
+ processLocation(M, Loc->getInlinedAt());
}
void DebugInfoFinder::processType(DIType DT) {
if (!addType(DT))
return;
- processScope(DT.getContext().resolve(TypeIdentifierMap));
- if (DT.isCompositeType()) {
- DICompositeType DCT(DT);
- processType(DCT.getTypeDerivedFrom().resolve(TypeIdentifierMap));
- if (DT.isSubroutineType()) {
- DITypeArray DTA = DISubroutineType(DT).getTypeArray();
- for (unsigned i = 0, e = DTA.getNumElements(); i != e; ++i)
- processType(DTA.getElement(i).resolve(TypeIdentifierMap));
+ processScope(DT->getScope().resolve(TypeIdentifierMap));
+ if (auto *DCT = dyn_cast<MDCompositeTypeBase>(DT)) {
+ processType(DCT->getBaseType().resolve(TypeIdentifierMap));
+ if (auto *ST = dyn_cast<MDSubroutineType>(DCT)) {
+ for (MDTypeRef Ref : ST->getTypeArray())
+ processType(Ref.resolve(TypeIdentifierMap));
return;
}
- DIArray DA = DCT.getElements();
- for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {
- DIDescriptor D = DA.getElement(i);
- if (D.isType())
- processType(DIType(D));
- else if (D.isSubprogram())
- processSubprogram(DISubprogram(D));
+ for (Metadata *D : DCT->getElements()) {
+ if (auto *T = dyn_cast<MDType>(D))
+ processType(T);
+ else if (DISubprogram SP = dyn_cast<MDSubprogram>(D))
+ processSubprogram(SP);
}
- } else if (DT.isDerivedType()) {
- DIDerivedType DDT(DT);
- processType(DDT.getTypeDerivedFrom().resolve(TypeIdentifierMap));
+ } else if (auto *DDT = dyn_cast<MDDerivedTypeBase>(DT)) {
+ processType(DDT->getBaseType().resolve(TypeIdentifierMap));
}
}
void DebugInfoFinder::processScope(DIScope Scope) {
- if (Scope.isType()) {
- DIType Ty(Scope);
+ if (!Scope)
+ return;
+ if (DIType Ty = dyn_cast<MDType>(Scope)) {
processType(Ty);
return;
}
- if (Scope.isCompileUnit()) {
- addCompileUnit(DICompileUnit(Scope));
+ if (DICompileUnit CU = dyn_cast<MDCompileUnit>(Scope)) {
+ addCompileUnit(CU);
return;
}
- if (Scope.isSubprogram()) {
- processSubprogram(DISubprogram(Scope));
+ if (DISubprogram SP = dyn_cast<MDSubprogram>(Scope)) {
+ processSubprogram(SP);
return;
}
if (!addScope(Scope))
return;
- if (Scope.isLexicalBlock()) {
- DILexicalBlock LB(Scope);
- processScope(LB.getContext());
- } else if (Scope.isLexicalBlockFile()) {
- DILexicalBlockFile LBF = DILexicalBlockFile(Scope);
- processScope(LBF.getScope());
- } else if (Scope.isNameSpace()) {
- DINameSpace NS(Scope);
- processScope(NS.getContext());
+ if (auto *LB = dyn_cast<MDLexicalBlockBase>(Scope)) {
+ processScope(LB->getScope());
+ } else if (auto *NS = dyn_cast<MDNamespace>(Scope)) {
+ processScope(NS->getScope());
}
}
void DebugInfoFinder::processSubprogram(DISubprogram SP) {
if (!addSubprogram(SP))
return;
- processScope(SP.getContext().resolve(TypeIdentifierMap));
- processType(SP.getType());
- DIArray TParams = SP.getTemplateParams();
- for (unsigned I = 0, E = TParams.getNumElements(); I != E; ++I) {
- DIDescriptor Element = TParams.getElement(I);
- if (Element.isTemplateTypeParameter()) {
- DITemplateTypeParameter TType(Element);
- processType(TType.getType().resolve(TypeIdentifierMap));
- } else if (Element.isTemplateValueParameter()) {
- DITemplateValueParameter TVal(Element);
- processType(TVal.getType().resolve(TypeIdentifierMap));
+ processScope(SP->getScope().resolve(TypeIdentifierMap));
+ processType(SP->getType());
+ for (auto *Element : SP->getTemplateParams()) {
+ if (auto *TType = dyn_cast<MDTemplateTypeParameter>(Element)) {
+ processType(TType->getType().resolve(TypeIdentifierMap));
+ } else if (auto *TVal = dyn_cast<MDTemplateValueParameter>(Element)) {
+ processType(TVal->getType().resolve(TypeIdentifierMap));
}
}
}
@@ -797,14 +225,14 @@ void DebugInfoFinder::processDeclare(const Module &M,
return;
InitializeTypeMap(M);
- DIDescriptor DV(N);
- if (!DV.isVariable())
+ DIVariable DV = dyn_cast<MDLocalVariable>(N);
+ if (!DV)
return;
if (!NodesSeen.insert(DV).second)
return;
- processScope(DIVariable(N).getContext());
- processType(DIVariable(N).getType().resolve(TypeIdentifierMap));
+ processScope(DV->getScope());
+ processType(DV->getType().resolve(TypeIdentifierMap));
}
void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) {
@@ -813,14 +241,14 @@ void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) {
return;
InitializeTypeMap(M);
- DIDescriptor DV(N);
- if (!DV.isVariable())
+ DIVariable DV = dyn_cast<MDLocalVariable>(N);
+ if (!DV)
return;
if (!NodesSeen.insert(DV).second)
return;
- processScope(DIVariable(N).getContext());
- processType(DIVariable(N).getType().resolve(TypeIdentifierMap));
+ processScope(DV->getScope());
+ processType(DV->getType().resolve(TypeIdentifierMap));
}
bool DebugInfoFinder::addType(DIType DT) {
@@ -879,76 +307,17 @@ bool DebugInfoFinder::addScope(DIScope Scope) {
return true;
}
-//===----------------------------------------------------------------------===//
-// DIDescriptor: dump routines for all descriptors.
-//===----------------------------------------------------------------------===//
-
-void DIDescriptor::dump() const {
- print(dbgs());
- dbgs() << '\n';
-}
-
-void DIDescriptor::print(raw_ostream &OS) const {
- if (!get())
- return;
- get()->print(OS);
-}
-
-static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,
- const LLVMContext &Ctx) {
- if (!DL.isUnknown()) { // Print source line info.
- DIScope Scope(DL.getScope(Ctx));
- assert(Scope.isScope() && "Scope of a DebugLoc should be a DIScope.");
- // Omit the directory, because it's likely to be long and uninteresting.
- CommentOS << Scope.getFilename();
- CommentOS << ':' << DL.getLine();
- if (DL.getCol() != 0)
- CommentOS << ':' << DL.getCol();
- DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx));
- if (!InlinedAtDL.isUnknown()) {
- CommentOS << " @[ ";
- printDebugLoc(InlinedAtDL, CommentOS, Ctx);
- CommentOS << " ]";
- }
- }
-}
-
-void DIVariable::printExtendedName(raw_ostream &OS) const {
- const LLVMContext &Ctx = DbgNode->getContext();
- StringRef Res = getName();
- if (!Res.empty())
- OS << Res << "," << getLineNumber();
- if (MDNode *InlinedAt = getInlinedAt()) {
- DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt);
- if (!InlinedAtDL.isUnknown()) {
- OS << " @[";
- printDebugLoc(InlinedAtDL, OS, Ctx);
- OS << "]";
+bool llvm::stripDebugInfo(Function &F) {
+ bool Changed = false;
+ for (BasicBlock &BB : F) {
+ for (Instruction &I : BB) {
+ if (I.getDebugLoc()) {
+ Changed = true;
+ I.setDebugLoc(DebugLoc());
+ }
}
}
-}
-
-template <> DIRef<DIDescriptor>::DIRef(const Metadata *V) : Val(V) {
- assert(isDescriptorRef(V) &&
- "DIDescriptorRef should be a MDString or MDNode");
-}
-template <> DIRef<DIScope>::DIRef(const Metadata *V) : Val(V) {
- assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode");
-}
-template <> DIRef<DIType>::DIRef(const Metadata *V) : Val(V) {
- assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode");
-}
-
-template <>
-DIDescriptorRef DIDescriptor::getFieldAs<DIDescriptorRef>(unsigned Elt) const {
- return DIDescriptorRef(cast_or_null<Metadata>(getField(DbgNode, Elt)));
-}
-template <>
-DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const {
- return DIScopeRef(cast_or_null<Metadata>(getField(DbgNode, Elt)));
-}
-template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const {
- return DITypeRef(cast_or_null<Metadata>(getField(DbgNode, Elt)));
+ return Changed;
}
bool llvm::StripDebugInfo(Module &M) {
@@ -984,16 +353,11 @@ bool llvm::StripDebugInfo(Module &M) {
}
}
- for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
- for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE;
- ++FI)
- for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE;
- ++BI) {
- if (!BI->getDebugLoc().isUnknown()) {
- Changed = true;
- BI->setDebugLoc(DebugLoc());
- }
- }
+ for (Function &F : M)
+ Changed |= stripDebugInfo(F);
+
+ if (GVMaterializer *Materializer = M.getMaterializer())
+ Materializer->setStripDebugInfo();
return Changed;
}
@@ -1014,11 +378,9 @@ llvm::makeSubprogramMap(const Module &M) {
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())
+ DICompileUnit CUNode = cast<MDCompileUnit>(N);
+ for (DISubprogram SP : CUNode->getSubprograms()) {
+ if (Function *F = SP->getFunction())
R.insert(std::make_pair(F, SP));
}
}
diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp
index 89ec1bc..f6f2ff2 100644
--- a/lib/IR/DebugInfoMetadata.cpp
+++ b/lib/IR/DebugInfoMetadata.cpp
@@ -14,6 +14,7 @@
#include "llvm/IR/DebugInfoMetadata.h"
#include "LLVMContextImpl.h"
#include "MetadataImpl.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Function.h"
using namespace llvm;
@@ -44,6 +45,7 @@ MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line,
// Fixup column.
adjustColumn(Column);
+ assert(Scope && "Expected scope");
if (Storage == Uniqued) {
if (auto *N =
getUniqued(Context.pImpl->MDLocations,
@@ -64,6 +66,96 @@ MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line,
Storage, Context.pImpl->MDLocations);
}
+unsigned MDLocation::computeNewDiscriminator() const {
+ // FIXME: This seems completely wrong.
+ //
+ // 1. If two modules are generated in the same context, then the second
+ // Module will get different discriminators than it would have if it were
+ // generated in its own context.
+ // 2. If this function is called after round-tripping to bitcode instead of
+ // before, it will give a different (and potentially incorrect!) return.
+ //
+ // The discriminator should instead be calculated from local information
+ // where it's actually needed. This logic should be moved to
+ // AddDiscriminators::runOnFunction(), where it doesn't pollute the
+ // LLVMContext.
+ std::pair<const char *, unsigned> Key(getFilename().data(), getLine());
+ return ++getContext().pImpl->DiscriminatorTable[Key];
+}
+
+unsigned DebugNode::getFlag(StringRef Flag) {
+ return StringSwitch<unsigned>(Flag)
+#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
+#include "llvm/IR/DebugInfoFlags.def"
+ .Default(0);
+}
+
+const char *DebugNode::getFlagString(unsigned Flag) {
+ switch (Flag) {
+ default:
+ return "";
+#define HANDLE_DI_FLAG(ID, NAME) \
+ case Flag##NAME: \
+ return "DIFlag" #NAME;
+#include "llvm/IR/DebugInfoFlags.def"
+ }
+}
+
+unsigned DebugNode::splitFlags(unsigned Flags,
+ SmallVectorImpl<unsigned> &SplitFlags) {
+ // Accessibility flags need to be specially handled, since they're packed
+ // together.
+ if (unsigned A = Flags & FlagAccessibility) {
+ if (A == FlagPrivate)
+ SplitFlags.push_back(FlagPrivate);
+ else if (A == FlagProtected)
+ SplitFlags.push_back(FlagProtected);
+ else
+ SplitFlags.push_back(FlagPublic);
+ Flags &= ~A;
+ }
+
+#define HANDLE_DI_FLAG(ID, NAME) \
+ if (unsigned Bit = Flags & ID) { \
+ SplitFlags.push_back(Bit); \
+ Flags &= ~Bit; \
+ }
+#include "llvm/IR/DebugInfoFlags.def"
+
+ return Flags;
+}
+
+MDScopeRef MDScope::getScope() const {
+ if (auto *T = dyn_cast<MDType>(this))
+ return T->getScope();
+
+ if (auto *SP = dyn_cast<MDSubprogram>(this))
+ return SP->getScope();
+
+ if (auto *LB = dyn_cast<MDLexicalBlockBase>(this))
+ return MDScopeRef(LB->getScope());
+
+ if (auto *NS = dyn_cast<MDNamespace>(this))
+ return MDScopeRef(NS->getScope());
+
+ assert((isa<MDFile>(this) || isa<MDCompileUnit>(this)) &&
+ "Unhandled type of scope.");
+ return nullptr;
+}
+
+StringRef MDScope::getName() const {
+ if (auto *T = dyn_cast<MDType>(this))
+ return T->getName();
+ if (auto *SP = dyn_cast<MDSubprogram>(this))
+ return SP->getName();
+ if (auto *NS = dyn_cast<MDNamespace>(this))
+ return NS->getName();
+ assert((isa<MDLexicalBlockBase>(this) || isa<MDFile>(this) ||
+ isa<MDCompileUnit>(this)) &&
+ "Unhandled type of scope.");
+ return "";
+}
+
static StringRef getString(const MDString *S) {
if (S)
return S->getString();
@@ -237,6 +329,12 @@ MDCompileUnit *MDCompileUnit::getImpl(
(SourceLanguage, IsOptimized, RuntimeVersion, EmissionKind), Ops);
}
+MDSubprogram *MDLocalScope::getSubprogram() const {
+ if (auto *Block = dyn_cast<MDLexicalBlockBase>(this))
+ return Block->getScope()->getSubprogram();
+ return const_cast<MDSubprogram *>(cast<MDSubprogram>(this));
+}
+
MDSubprogram *MDSubprogram::getImpl(
LLVMContext &Context, Metadata *Scope, MDString *Name,
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
@@ -262,6 +360,21 @@ MDSubprogram *MDSubprogram::getImpl(
Ops);
}
+Function *MDSubprogram::getFunction() const {
+ // FIXME: Should this be looking through bitcasts?
+ return dyn_cast_or_null<Function>(getFunctionConstant());
+}
+
+bool MDSubprogram::describes(const Function *F) const {
+ assert(F && "Invalid function");
+ if (F == getFunction())
+ return true;
+ StringRef Name = getLinkageName();
+ if (Name.empty())
+ Name = getName();
+ return F->getName() == Name;
+}
+
void MDSubprogram::replaceFunction(Function *F) {
replaceFunction(F ? ConstantAsMetadata::get(F)
: static_cast<ConstantAsMetadata *>(nullptr));
@@ -271,6 +384,7 @@ MDLexicalBlock *MDLexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Line,
unsigned Column, StorageType Storage,
bool ShouldCreate) {
+ assert(Scope && "Expected scope");
DEFINE_GETIMPL_LOOKUP(MDLexicalBlock, (Scope, File, Line, Column));
Metadata *Ops[] = {File, Scope};
DEFINE_GETIMPL_STORE(MDLexicalBlock, (Line, Column), Ops);
@@ -281,6 +395,7 @@ MDLexicalBlockFile *MDLexicalBlockFile::getImpl(LLVMContext &Context,
unsigned Discriminator,
StorageType Storage,
bool ShouldCreate) {
+ assert(Scope && "Expected scope");
DEFINE_GETIMPL_LOOKUP(MDLexicalBlockFile, (Scope, File, Discriminator));
Metadata *Ops[] = {File, Scope};
DEFINE_GETIMPL_STORE(MDLexicalBlockFile, (Discriminator), Ops);
@@ -335,20 +450,23 @@ MDGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
Ops);
}
-MDLocalVariable *MDLocalVariable::getImpl(
- LLVMContext &Context, unsigned Tag, Metadata *Scope, MDString *Name,
- Metadata *File, unsigned Line, Metadata *Type, unsigned Arg, unsigned Flags,
- Metadata *InlinedAt, StorageType Storage, bool ShouldCreate) {
+MDLocalVariable *MDLocalVariable::getImpl(LLVMContext &Context, unsigned Tag,
+ Metadata *Scope, MDString *Name,
+ Metadata *File, unsigned Line,
+ Metadata *Type, unsigned Arg,
+ unsigned Flags, StorageType Storage,
+ bool ShouldCreate) {
// Truncate Arg to 8 bits.
//
// FIXME: This is gross (and should be changed to an assert or removed), but
// it matches historical behaviour for now.
Arg &= (1u << 8) - 1;
+ assert(Scope && "Expected scope");
assert(isCanonical(Name) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(MDLocalVariable, (Tag, Scope, getString(Name), File,
- Line, Type, Arg, Flags, InlinedAt));
- Metadata *Ops[] = {Scope, Name, File, Type, InlinedAt};
+ Line, Type, Arg, Flags));
+ Metadata *Ops[] = {Scope, Name, File, Type};
DEFINE_GETIMPL_STORE(MDLocalVariable, (Tag, Line, Arg, Flags), Ops);
}
@@ -391,6 +509,24 @@ bool MDExpression::isValid() const {
return true;
}
+bool MDExpression::isBitPiece() const {
+ assert(isValid() && "Expected valid expression");
+ if (unsigned N = getNumElements())
+ if (N >= 3)
+ return getElement(N - 3) == dwarf::DW_OP_bit_piece;
+ return false;
+}
+
+uint64_t MDExpression::getBitPieceOffset() const {
+ assert(isBitPiece() && "Expected bit piece");
+ return getElement(getNumElements() - 2);
+}
+
+uint64_t MDExpression::getBitPieceSize() const {
+ assert(isBitPiece() && "Expected bit piece");
+ return getElement(getNumElements() - 1);
+}
+
MDObjCProperty *MDObjCProperty::getImpl(
LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
MDString *GetterName, MDString *SetterName, unsigned Attributes,
diff --git a/lib/IR/DebugLoc.cpp b/lib/IR/DebugLoc.cpp
index e1bf795..4cf7e9e 100644
--- a/lib/IR/DebugLoc.cpp
+++ b/lib/IR/DebugLoc.cpp
@@ -16,101 +16,87 @@ using namespace llvm;
//===----------------------------------------------------------------------===//
// DebugLoc Implementation
//===----------------------------------------------------------------------===//
+DebugLoc::DebugLoc(const MDLocation *L) : Loc(const_cast<MDLocation *>(L)) {}
+DebugLoc::DebugLoc(const MDNode *L) : Loc(const_cast<MDNode *>(L)) {}
-unsigned DebugLoc::getLine() const { return DILocation(Loc).getLineNumber(); }
-unsigned DebugLoc::getCol() const { return DILocation(Loc).getColumnNumber(); }
+MDLocation *DebugLoc::get() const {
+ return cast_or_null<MDLocation>(Loc.get());
+}
-MDNode *DebugLoc::getScope() const { return DILocation(Loc).getScope(); }
+unsigned DebugLoc::getLine() const {
+ assert(get() && "Expected valid DebugLoc");
+ return get()->getLine();
+}
-MDNode *DebugLoc::getInlinedAt() const {
- return DILocation(Loc).getOrigLocation();
+unsigned DebugLoc::getCol() const {
+ assert(get() && "Expected valid DebugLoc");
+ return get()->getColumn();
}
-/// Return both the Scope and the InlinedAt values.
-void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const {
- Scope = getScope();
- IA = getInlinedAt();
+MDNode *DebugLoc::getScope() const {
+ assert(get() && "Expected valid DebugLoc");
+ return get()->getScope();
}
-MDNode *DebugLoc::getScopeNode() const {
- if (MDNode *InlinedAt = getInlinedAt())
- return DebugLoc::getFromDILocation(InlinedAt).getScopeNode();
- return getScope();
+MDLocation *DebugLoc::getInlinedAt() const {
+ assert(get() && "Expected valid DebugLoc");
+ return get()->getInlinedAt();
+}
+
+MDNode *DebugLoc::getInlinedAtScope() const {
+ return cast<MDLocation>(Loc)->getInlinedAtScope();
}
DebugLoc DebugLoc::getFnDebugLoc() const {
- const MDNode *Scope = getScopeNode();
- DISubprogram SP = getDISubprogram(Scope);
- if (SP.isSubprogram())
- return DebugLoc::get(SP.getScopeLineNumber(), 0, SP);
+ // FIXME: Add a method on \a MDLocation that does this work.
+ const MDNode *Scope = getInlinedAtScope();
+ if (DISubprogram SP = getDISubprogram(Scope))
+ return DebugLoc::get(SP->getScopeLine(), 0, SP);
return DebugLoc();
}
-DebugLoc DebugLoc::get(unsigned Line, unsigned Col,
- MDNode *Scope, MDNode *InlinedAt) {
+DebugLoc DebugLoc::get(unsigned Line, unsigned Col, const MDNode *Scope,
+ const MDNode *InlinedAt) {
// If no scope is available, this is an unknown location.
if (!Scope)
return DebugLoc();
- return getFromDILocation(
- MDLocation::get(Scope->getContext(), Line, Col, Scope, InlinedAt));
-}
-
-/// getAsMDNode - This method converts the compressed DebugLoc node into a
-/// DILocation-compatible MDNode.
-MDNode *DebugLoc::getAsMDNode() const { return Loc; }
-
-/// getFromDILocation - Translate the DILocation quad into a DebugLoc.
-DebugLoc DebugLoc::getFromDILocation(MDNode *N) {
- DebugLoc Loc;
- Loc.Loc.reset(N);
- return Loc;
-}
-
-/// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
-DebugLoc DebugLoc::getFromDILexicalBlock(MDNode *N) {
- DILexicalBlock LexBlock(N);
- MDNode *Scope = LexBlock.getContext();
- if (!Scope) return DebugLoc();
- return get(LexBlock.getLineNumber(), LexBlock.getColumnNumber(), Scope,
- nullptr);
+ return MDLocation::get(Scope->getContext(), Line, Col,
+ const_cast<MDNode *>(Scope),
+ const_cast<MDNode *>(InlinedAt));
}
void DebugLoc::dump() const {
#ifndef NDEBUG
- if (!isUnknown()) {
- dbgs() << getLine();
- if (getCol() != 0)
- dbgs() << ',' << getCol();
- DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt());
- if (!InlinedAtDL.isUnknown()) {
- dbgs() << " @ ";
- InlinedAtDL.dump();
- } else
- dbgs() << "\n";
- }
+ if (!Loc)
+ return;
+
+ dbgs() << getLine();
+ if (getCol() != 0)
+ dbgs() << ',' << getCol();
+ if (DebugLoc InlinedAtDL = DebugLoc(getInlinedAt())) {
+ dbgs() << " @ ";
+ InlinedAtDL.dump();
+ } else
+ dbgs() << "\n";
#endif
}
void DebugLoc::print(raw_ostream &OS) const {
- if (!isUnknown()) {
- // Print source line info.
- DIScope Scope(getScope());
- assert((!Scope || Scope.isScope()) &&
- "Scope of a DebugLoc should be null or a DIScope.");
- if (Scope)
- OS << Scope.getFilename();
- else
- OS << "<unknown>";
- OS << ':' << getLine();
- if (getCol() != 0)
- OS << ':' << getCol();
- DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt());
- if (!InlinedAtDL.isUnknown()) {
- OS << " @[ ";
- InlinedAtDL.print(OS);
- OS << " ]";
- }
+ if (!Loc)
+ return;
+
+ // Print source line info.
+ auto *Scope = cast<MDScope>(getScope());
+ OS << Scope->getFilename();
+ OS << ':' << getLine();
+ if (getCol() != 0)
+ OS << ':' << getCol();
+
+ if (DebugLoc InlinedAtDL = getInlinedAt()) {
+ OS << " @[ ";
+ InlinedAtDL.print(OS);
+ OS << " ]";
}
}
diff --git a/lib/IR/DiagnosticInfo.cpp b/lib/IR/DiagnosticInfo.cpp
index 5608589..91635f6 100644
--- a/lib/IR/DiagnosticInfo.cpp
+++ b/lib/IR/DiagnosticInfo.cpp
@@ -129,16 +129,16 @@ void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
}
bool DiagnosticInfoOptimizationBase::isLocationAvailable() const {
- return !getDebugLoc().isUnknown();
+ return getDebugLoc();
}
void DiagnosticInfoOptimizationBase::getLocation(StringRef *Filename,
unsigned *Line,
unsigned *Column) const {
- DILocation DIL(getDebugLoc().getAsMDNode(getFunction().getContext()));
- *Filename = DIL.getFilename();
- *Line = DIL.getLineNumber();
- *Column = DIL.getColumnNumber();
+ MDLocation *L = getDebugLoc();
+ *Filename = L->getFilename();
+ *Line = L->getLine();
+ *Column = L->getColumn();
}
const std::string DiagnosticInfoOptimizationBase::getLocationStr() const {
@@ -147,7 +147,7 @@ const std::string DiagnosticInfoOptimizationBase::getLocationStr() const {
unsigned Column = 0;
if (isLocationAvailable())
getLocation(&Filename, &Line, &Column);
- return Twine(Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
+ return (Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
}
void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp
index 33e1526..d3a0934 100644
--- a/lib/IR/Function.cpp
+++ b/lib/IR/Function.cpp
@@ -215,9 +215,7 @@ LLVMContext &Function::getContext() const {
return getType()->getContext();
}
-FunctionType *Function::getFunctionType() const {
- return cast<FunctionType>(getType()->getElementType());
-}
+FunctionType *Function::getFunctionType() const { return Ty; }
bool Function::isVarArg() const {
return getFunctionType()->isVarArg();
@@ -242,7 +240,8 @@ void Function::eraseFromParent() {
Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name,
Module *ParentModule)
: GlobalObject(PointerType::getUnqual(Ty), Value::FunctionVal, nullptr, 0,
- Linkage, name) {
+ Linkage, name),
+ Ty(Ty) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
"invalid return type");
setIsMaterializable(false);
@@ -349,6 +348,12 @@ void Function::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
setAttributes(PAL);
}
+void Function::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
+ AttributeSet PAL = getAttributes();
+ PAL = PAL.addDereferenceableOrNullAttr(getContext(), i, Bytes);
+ setAttributes(PAL);
+}
+
// Maintain the GC name for each function in an on-the-side table. This saves
// allocating an additional word in Function for programs which do not use GC
// (i.e., most programs) at the cost of increased overhead for clients which do
diff --git a/lib/IR/GCOV.cpp b/lib/IR/GCOV.cpp
index 7010ceb..6ed5891 100644
--- a/lib/IR/GCOV.cpp
+++ b/lib/IR/GCOV.cpp
@@ -555,7 +555,7 @@ FileInfo::openCoveragePath(StringRef CoveragePath) {
return llvm::make_unique<raw_null_ostream>();
std::error_code EC;
- auto OS = llvm::make_unique<raw_fd_ostream>(CoveragePath.str(), EC,
+ auto OS = llvm::make_unique<raw_fd_ostream>(CoveragePath, EC,
sys::fs::F_Text);
if (EC) {
errs() << EC.message() << "\n";
diff --git a/lib/IR/IRBuilder.cpp b/lib/IR/IRBuilder.cpp
index 90303b2..06f54c7 100644
--- a/lib/IR/IRBuilder.cpp
+++ b/lib/IR/IRBuilder.cpp
@@ -23,7 +23,8 @@ using namespace llvm;
/// has array of i8 type filled in with the nul terminated string value
/// specified. If Name is specified, it is the name of the global variable
/// created.
-Value *IRBuilderBase::CreateGlobalString(StringRef Str, const Twine &Name) {
+GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
+ const Twine &Name) {
Constant *StrConstant = ConstantDataArray::getString(Context, Str);
Module &M = *BB->getParent()->getParent();
GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(),
diff --git a/lib/IR/IRPrintingPasses.cpp b/lib/IR/IRPrintingPasses.cpp
index 91ccfbb..c1ac336 100644
--- a/lib/IR/IRPrintingPasses.cpp
+++ b/lib/IR/IRPrintingPasses.cpp
@@ -21,11 +21,14 @@
using namespace llvm;
PrintModulePass::PrintModulePass() : OS(dbgs()) {}
-PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner)
- : OS(OS), Banner(Banner) {}
+PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
+ bool ShouldPreserveUseListOrder)
+ : OS(OS), Banner(Banner),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
PreservedAnalyses PrintModulePass::run(Module &M) {
- OS << Banner << M;
+ OS << Banner;
+ M.print(OS, nullptr, ShouldPreserveUseListOrder);
return PreservedAnalyses::all();
}
@@ -46,8 +49,9 @@ class PrintModulePassWrapper : public ModulePass {
public:
static char ID;
PrintModulePassWrapper() : ModulePass(ID) {}
- PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner)
- : ModulePass(ID), P(OS, Banner) {}
+ PrintModulePassWrapper(raw_ostream &OS, const std::string &Banner,
+ bool ShouldPreserveUseListOrder)
+ : ModulePass(ID), P(OS, Banner, ShouldPreserveUseListOrder) {}
bool runOnModule(Module &M) override {
P.run(M);
@@ -112,8 +116,9 @@ INITIALIZE_PASS(PrintBasicBlockPass, "print-bb", "Print BB to stderr", false,
false)
ModulePass *llvm::createPrintModulePass(llvm::raw_ostream &OS,
- const std::string &Banner) {
- return new PrintModulePassWrapper(OS, Banner);
+ const std::string &Banner,
+ bool ShouldPreserveUseListOrder) {
+ return new PrintModulePassWrapper(OS, Banner, ShouldPreserveUseListOrder);
}
FunctionPass *llvm::createPrintFunctionPass(llvm::raw_ostream &OS,
diff --git a/lib/IR/InlineAsm.cpp b/lib/IR/InlineAsm.cpp
index b456d9f..aa9e027 100644
--- a/lib/IR/InlineAsm.cpp
+++ b/lib/IR/InlineAsm.cpp
@@ -167,7 +167,9 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str,
// Note that operand #n has a matching input.
scInfo.MatchingInput = ConstraintsSoFar.size();
} else {
- if (ConstraintsSoFar[N].hasMatchingInput())
+ if (ConstraintsSoFar[N].hasMatchingInput() &&
+ (size_t)ConstraintsSoFar[N].MatchingInput !=
+ ConstraintsSoFar.size())
return true;
// Note that operand #n has a matching input.
ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size();
diff --git a/lib/IR/Instruction.cpp b/lib/IR/Instruction.cpp
index 7d9bd7e..57c143c 100644
--- a/lib/IR/Instruction.cpp
+++ b/lib/IR/Instruction.cpp
@@ -62,8 +62,8 @@ void Instruction::removeFromParent() {
getParent()->getInstList().remove(this);
}
-void Instruction::eraseFromParent() {
- getParent()->getInstList().erase(this);
+iplist<Instruction>::iterator Instruction::eraseFromParent() {
+ return getParent()->getInstList().erase(this);
}
/// insertBefore - Insert an unlinked instructions into a basic block
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp
index af2aeb9..85b7521 100644
--- a/lib/IR/Instructions.cpp
+++ b/lib/IR/Instructions.cpp
@@ -352,6 +352,12 @@ void CallInst::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
setAttributes(PAL);
}
+void CallInst::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
+ AttributeSet PAL = getAttributes();
+ PAL = PAL.addDereferenceableOrNullAttr(getContext(), i, Bytes);
+ setAttributes(PAL);
+}
+
bool CallInst::hasFnAttrImpl(Attribute::AttrKind A) const {
if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A))
return true;
@@ -617,6 +623,12 @@ void InvokeInst::addDereferenceableAttr(unsigned i, uint64_t Bytes) {
setAttributes(PAL);
}
+void InvokeInst::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
+ AttributeSet PAL = getAttributes();
+ PAL = PAL.addDereferenceableOrNullAttr(getContext(), i, Bytes);
+ setAttributes(PAL);
+}
+
LandingPadInst *InvokeInst::getLandingPadInst() const {
return cast<LandingPadInst>(getUnwindDest()->getFirstNonPHI());
}
@@ -943,12 +955,10 @@ LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
: LoadInst(Ptr, Name, isVolatile, Align, NotAtomic, CrossThread, InsertAE) {
}
-LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
+LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile,
unsigned Align, AtomicOrdering Order,
- SynchronizationScope SynchScope,
- Instruction *InsertBef)
- : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
- Load, Ptr, InsertBef) {
+ SynchronizationScope SynchScope, Instruction *InsertBef)
+ : UnaryInstruction(Ty, Load, Ptr, InsertBef) {
setVolatile(isVolatile);
setAlignment(Align);
setAtomic(Order, SynchScope);
@@ -1258,11 +1268,7 @@ GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI)
/// pointer type.
///
template <typename IndexTy>
-static Type *getIndexedTypeInternal(Type *Ptr, ArrayRef<IndexTy> IdxList) {
- PointerType *PTy = dyn_cast<PointerType>(Ptr->getScalarType());
- if (!PTy) return nullptr; // Type isn't a pointer type!
- Type *Agg = PTy->getElementType();
-
+static Type *getIndexedTypeInternal(Type *Agg, ArrayRef<IndexTy> IdxList) {
// Handle the special case of the empty set index set, which is always valid.
if (IdxList.empty())
return Agg;
@@ -1283,17 +1289,17 @@ static Type *getIndexedTypeInternal(Type *Ptr, ArrayRef<IndexTy> IdxList) {
return CurIdx == IdxList.size() ? Agg : nullptr;
}
-Type *GetElementPtrInst::getIndexedType(Type *Ptr, ArrayRef<Value *> IdxList) {
- return getIndexedTypeInternal(Ptr, IdxList);
+Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef<Value *> IdxList) {
+ return getIndexedTypeInternal(Ty, IdxList);
}
-Type *GetElementPtrInst::getIndexedType(Type *Ptr,
+Type *GetElementPtrInst::getIndexedType(Type *Ty,
ArrayRef<Constant *> IdxList) {
- return getIndexedTypeInternal(Ptr, IdxList);
+ return getIndexedTypeInternal(Ty, IdxList);
}
-Type *GetElementPtrInst::getIndexedType(Type *Ptr, ArrayRef<uint64_t> IdxList) {
- return getIndexedTypeInternal(Ptr, IdxList);
+Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList) {
+ return getIndexedTypeInternal(Ty, IdxList);
}
/// hasAllZeroIndices - Return true if all of the indices of this GEP are
diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h
index e380665..c096a83 100644
--- a/lib/IR/LLVMContextImpl.h
+++ b/lib/IR/LLVMContextImpl.h
@@ -275,15 +275,17 @@ template <> struct MDNodeKeyImpl<GenericDebugNode> : MDNodeOpsKey {
template <> struct MDNodeKeyImpl<MDSubrange> {
int64_t Count;
- int64_t Lo;
+ int64_t LowerBound;
- MDNodeKeyImpl(int64_t Count, int64_t Lo) : Count(Count), Lo(Lo) {}
- MDNodeKeyImpl(const MDSubrange *N) : Count(N->getCount()), Lo(N->getLo()) {}
+ MDNodeKeyImpl(int64_t Count, int64_t LowerBound)
+ : Count(Count), LowerBound(LowerBound) {}
+ MDNodeKeyImpl(const MDSubrange *N)
+ : Count(N->getCount()), LowerBound(N->getLowerBound()) {}
bool isKeyOf(const MDSubrange *RHS) const {
- return Count == RHS->getCount() && Lo == RHS->getLo();
+ return Count == RHS->getCount() && LowerBound == RHS->getLowerBound();
}
- unsigned getHashValue() const { return hash_combine(Count, Lo); }
+ unsigned getHashValue() const { return hash_combine(Count, LowerBound); }
};
template <> struct MDNodeKeyImpl<MDEnumerator> {
@@ -347,20 +349,20 @@ template <> struct MDNodeKeyImpl<MDDerivedType> {
BaseType(BaseType), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
OffsetInBits(OffsetInBits), Flags(Flags), ExtraData(ExtraData) {}
MDNodeKeyImpl(const MDDerivedType *N)
- : Tag(N->getTag()), Name(N->getName()), File(N->getFile()),
- Line(N->getLine()), Scope(N->getScope()), BaseType(N->getBaseType()),
- SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
- OffsetInBits(N->getOffsetInBits()), Flags(N->getFlags()),
- ExtraData(N->getExtraData()) {}
+ : Tag(N->getTag()), Name(N->getName()), File(N->getRawFile()),
+ Line(N->getLine()), Scope(N->getRawScope()),
+ BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
+ AlignInBits(N->getAlignInBits()), OffsetInBits(N->getOffsetInBits()),
+ Flags(N->getFlags()), ExtraData(N->getRawExtraData()) {}
bool isKeyOf(const MDDerivedType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getName() &&
- File == RHS->getFile() && Line == RHS->getLine() &&
- Scope == RHS->getScope() && BaseType == RHS->getBaseType() &&
+ File == RHS->getRawFile() && Line == RHS->getLine() &&
+ Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
SizeInBits == RHS->getSizeInBits() &&
AlignInBits == RHS->getAlignInBits() &&
OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
- ExtraData == RHS->getExtraData();
+ ExtraData == RHS->getRawExtraData();
}
unsigned getHashValue() const {
return hash_combine(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
@@ -397,26 +399,26 @@ template <> struct MDNodeKeyImpl<MDCompositeType> {
RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
TemplateParams(TemplateParams), Identifier(Identifier) {}
MDNodeKeyImpl(const MDCompositeType *N)
- : Tag(N->getTag()), Name(N->getName()), File(N->getFile()),
- Line(N->getLine()), Scope(N->getScope()), BaseType(N->getBaseType()),
- SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
- OffsetInBits(N->getOffsetInBits()), Flags(N->getFlags()),
- Elements(N->getElements()), RuntimeLang(N->getRuntimeLang()),
- VTableHolder(N->getVTableHolder()),
- TemplateParams(N->getTemplateParams()), Identifier(N->getIdentifier()) {
- }
+ : Tag(N->getTag()), Name(N->getName()), File(N->getRawFile()),
+ Line(N->getLine()), Scope(N->getRawScope()),
+ BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
+ AlignInBits(N->getAlignInBits()), OffsetInBits(N->getOffsetInBits()),
+ Flags(N->getFlags()), Elements(N->getRawElements()),
+ RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
+ TemplateParams(N->getRawTemplateParams()),
+ Identifier(N->getIdentifier()) {}
bool isKeyOf(const MDCompositeType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getName() &&
- File == RHS->getFile() && Line == RHS->getLine() &&
- Scope == RHS->getScope() && BaseType == RHS->getBaseType() &&
+ File == RHS->getRawFile() && Line == RHS->getLine() &&
+ Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
SizeInBits == RHS->getSizeInBits() &&
AlignInBits == RHS->getAlignInBits() &&
OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
- Elements == RHS->getElements() &&
+ Elements == RHS->getRawElements() &&
RuntimeLang == RHS->getRuntimeLang() &&
- VTableHolder == RHS->getVTableHolder() &&
- TemplateParams == RHS->getTemplateParams() &&
+ VTableHolder == RHS->getRawVTableHolder() &&
+ TemplateParams == RHS->getRawTemplateParams() &&
Identifier == RHS->getIdentifier();
}
unsigned getHashValue() const {
@@ -433,10 +435,10 @@ template <> struct MDNodeKeyImpl<MDSubroutineType> {
MDNodeKeyImpl(int64_t Flags, Metadata *TypeArray)
: Flags(Flags), TypeArray(TypeArray) {}
MDNodeKeyImpl(const MDSubroutineType *N)
- : Flags(N->getFlags()), TypeArray(N->getTypeArray()) {}
+ : Flags(N->getFlags()), TypeArray(N->getRawTypeArray()) {}
bool isKeyOf(const MDSubroutineType *RHS) const {
- return Flags == RHS->getFlags() && TypeArray == RHS->getTypeArray();
+ return Flags == RHS->getFlags() && TypeArray == RHS->getRawTypeArray();
}
unsigned getHashValue() const { return hash_combine(Flags, TypeArray); }
};
@@ -484,27 +486,28 @@ template <> struct MDNodeKeyImpl<MDCompileUnit> {
Subprograms(Subprograms), GlobalVariables(GlobalVariables),
ImportedEntities(ImportedEntities) {}
MDNodeKeyImpl(const MDCompileUnit *N)
- : SourceLanguage(N->getSourceLanguage()), File(N->getFile()),
+ : SourceLanguage(N->getSourceLanguage()), File(N->getRawFile()),
Producer(N->getProducer()), IsOptimized(N->isOptimized()),
Flags(N->getFlags()), RuntimeVersion(N->getRuntimeVersion()),
SplitDebugFilename(N->getSplitDebugFilename()),
- EmissionKind(N->getEmissionKind()), EnumTypes(N->getEnumTypes()),
- RetainedTypes(N->getRetainedTypes()), Subprograms(N->getSubprograms()),
- GlobalVariables(N->getGlobalVariables()),
- ImportedEntities(N->getImportedEntities()) {}
+ EmissionKind(N->getEmissionKind()), EnumTypes(N->getRawEnumTypes()),
+ RetainedTypes(N->getRawRetainedTypes()),
+ Subprograms(N->getRawSubprograms()),
+ GlobalVariables(N->getRawGlobalVariables()),
+ ImportedEntities(N->getRawImportedEntities()) {}
bool isKeyOf(const MDCompileUnit *RHS) const {
return SourceLanguage == RHS->getSourceLanguage() &&
- File == RHS->getFile() && Producer == RHS->getProducer() &&
+ File == RHS->getRawFile() && Producer == RHS->getProducer() &&
IsOptimized == RHS->isOptimized() && Flags == RHS->getFlags() &&
RuntimeVersion == RHS->getRuntimeVersion() &&
SplitDebugFilename == RHS->getSplitDebugFilename() &&
EmissionKind == RHS->getEmissionKind() &&
- EnumTypes == RHS->getEnumTypes() &&
- RetainedTypes == RHS->getRetainedTypes() &&
- Subprograms == RHS->getSubprograms() &&
- GlobalVariables == RHS->getGlobalVariables() &&
- ImportedEntities == RHS->getImportedEntities();
+ EnumTypes == RHS->getRawEnumTypes() &&
+ RetainedTypes == RHS->getRawRetainedTypes() &&
+ Subprograms == RHS->getRawSubprograms() &&
+ GlobalVariables == RHS->getRawGlobalVariables() &&
+ ImportedEntities == RHS->getRawImportedEntities();
}
unsigned getHashValue() const {
return hash_combine(SourceLanguage, File, Producer, IsOptimized, Flags,
@@ -549,31 +552,32 @@ template <> struct MDNodeKeyImpl<MDSubprogram> {
Function(Function), TemplateParams(TemplateParams),
Declaration(Declaration), Variables(Variables) {}
MDNodeKeyImpl(const MDSubprogram *N)
- : Scope(N->getScope()), Name(N->getName()),
- LinkageName(N->getLinkageName()), File(N->getFile()),
- Line(N->getLine()), Type(N->getType()),
+ : Scope(N->getRawScope()), Name(N->getName()),
+ LinkageName(N->getLinkageName()), File(N->getRawFile()),
+ Line(N->getLine()), Type(N->getRawType()),
IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
- ScopeLine(N->getScopeLine()), ContainingType(N->getContainingType()),
+ ScopeLine(N->getScopeLine()), ContainingType(N->getRawContainingType()),
Virtuality(N->getVirtuality()), VirtualIndex(N->getVirtualIndex()),
Flags(N->getFlags()), IsOptimized(N->isOptimized()),
- Function(N->getFunction()), TemplateParams(N->getTemplateParams()),
- Declaration(N->getDeclaration()), Variables(N->getVariables()) {}
+ Function(N->getRawFunction()),
+ TemplateParams(N->getRawTemplateParams()),
+ Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()) {}
bool isKeyOf(const MDSubprogram *RHS) const {
- return Scope == RHS->getScope() && Name == RHS->getName() &&
- LinkageName == RHS->getLinkageName() && File == RHS->getFile() &&
- Line == RHS->getLine() && Type == RHS->getType() &&
+ return Scope == RHS->getRawScope() && Name == RHS->getName() &&
+ LinkageName == RHS->getLinkageName() && File == RHS->getRawFile() &&
+ Line == RHS->getLine() && Type == RHS->getRawType() &&
IsLocalToUnit == RHS->isLocalToUnit() &&
IsDefinition == RHS->isDefinition() &&
ScopeLine == RHS->getScopeLine() &&
- ContainingType == RHS->getContainingType() &&
+ ContainingType == RHS->getRawContainingType() &&
Virtuality == RHS->getVirtuality() &&
VirtualIndex == RHS->getVirtualIndex() && Flags == RHS->getFlags() &&
IsOptimized == RHS->isOptimized() &&
- Function == RHS->getFunction() &&
- TemplateParams == RHS->getTemplateParams() &&
- Declaration == RHS->getDeclaration() &&
- Variables == RHS->getVariables();
+ Function == RHS->getRawFunction() &&
+ TemplateParams == RHS->getRawTemplateParams() &&
+ Declaration == RHS->getRawDeclaration() &&
+ Variables == RHS->getRawVariables();
}
unsigned getHashValue() const {
return hash_combine(Scope, Name, LinkageName, File, Line, Type,
@@ -592,11 +596,11 @@ template <> struct MDNodeKeyImpl<MDLexicalBlock> {
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
: Scope(Scope), File(File), Line(Line), Column(Column) {}
MDNodeKeyImpl(const MDLexicalBlock *N)
- : Scope(N->getScope()), File(N->getFile()), Line(N->getLine()),
+ : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
Column(N->getColumn()) {}
bool isKeyOf(const MDLexicalBlock *RHS) const {
- return Scope == RHS->getScope() && File == RHS->getFile() &&
+ return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
Line == RHS->getLine() && Column == RHS->getColumn();
}
unsigned getHashValue() const {
@@ -612,11 +616,11 @@ template <> struct MDNodeKeyImpl<MDLexicalBlockFile> {
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
: Scope(Scope), File(File), Discriminator(Discriminator) {}
MDNodeKeyImpl(const MDLexicalBlockFile *N)
- : Scope(N->getScope()), File(N->getFile()),
+ : Scope(N->getRawScope()), File(N->getRawFile()),
Discriminator(N->getDiscriminator()) {}
bool isKeyOf(const MDLexicalBlockFile *RHS) const {
- return Scope == RHS->getScope() && File == RHS->getFile() &&
+ return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
Discriminator == RHS->getDiscriminator();
}
unsigned getHashValue() const {
@@ -633,11 +637,11 @@ template <> struct MDNodeKeyImpl<MDNamespace> {
MDNodeKeyImpl(Metadata *Scope, Metadata *File, StringRef Name, unsigned Line)
: Scope(Scope), File(File), Name(Name), Line(Line) {}
MDNodeKeyImpl(const MDNamespace *N)
- : Scope(N->getScope()), File(N->getFile()), Name(N->getName()),
+ : Scope(N->getRawScope()), File(N->getRawFile()), Name(N->getName()),
Line(N->getLine()) {}
bool isKeyOf(const MDNamespace *RHS) const {
- return Scope == RHS->getScope() && File == RHS->getFile() &&
+ return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
Name == RHS->getName() && Line == RHS->getLine();
}
unsigned getHashValue() const {
@@ -651,10 +655,10 @@ template <> struct MDNodeKeyImpl<MDTemplateTypeParameter> {
MDNodeKeyImpl(StringRef Name, Metadata *Type) : Name(Name), Type(Type) {}
MDNodeKeyImpl(const MDTemplateTypeParameter *N)
- : Name(N->getName()), Type(N->getType()) {}
+ : Name(N->getName()), Type(N->getRawType()) {}
bool isKeyOf(const MDTemplateTypeParameter *RHS) const {
- return Name == RHS->getName() && Type == RHS->getType();
+ return Name == RHS->getName() && Type == RHS->getRawType();
}
unsigned getHashValue() const { return hash_combine(Name, Type); }
};
@@ -668,12 +672,12 @@ template <> struct MDNodeKeyImpl<MDTemplateValueParameter> {
MDNodeKeyImpl(unsigned Tag, StringRef Name, Metadata *Type, Metadata *Value)
: Tag(Tag), Name(Name), Type(Type), Value(Value) {}
MDNodeKeyImpl(const MDTemplateValueParameter *N)
- : Tag(N->getTag()), Name(N->getName()), Type(N->getType()),
+ : Tag(N->getTag()), Name(N->getName()), Type(N->getRawType()),
Value(N->getValue()) {}
bool isKeyOf(const MDTemplateValueParameter *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getName() &&
- Type == RHS->getType() && Value == RHS->getValue();
+ Type == RHS->getRawType() && Value == RHS->getValue();
}
unsigned getHashValue() const { return hash_combine(Tag, Name, Type, Value); }
};
@@ -699,21 +703,22 @@ template <> struct MDNodeKeyImpl<MDGlobalVariable> {
IsDefinition(IsDefinition), Variable(Variable),
StaticDataMemberDeclaration(StaticDataMemberDeclaration) {}
MDNodeKeyImpl(const MDGlobalVariable *N)
- : Scope(N->getScope()), Name(N->getName()),
- LinkageName(N->getLinkageName()), File(N->getFile()),
- Line(N->getLine()), Type(N->getType()),
+ : Scope(N->getRawScope()), Name(N->getName()),
+ LinkageName(N->getLinkageName()), File(N->getRawFile()),
+ Line(N->getLine()), Type(N->getRawType()),
IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
- Variable(N->getVariable()),
- StaticDataMemberDeclaration(N->getStaticDataMemberDeclaration()) {}
+ Variable(N->getRawVariable()),
+ StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()) {}
bool isKeyOf(const MDGlobalVariable *RHS) const {
- return Scope == RHS->getScope() && Name == RHS->getName() &&
- LinkageName == RHS->getLinkageName() && File == RHS->getFile() &&
- Line == RHS->getLine() && Type == RHS->getType() &&
+ return Scope == RHS->getRawScope() && Name == RHS->getName() &&
+ LinkageName == RHS->getLinkageName() && File == RHS->getRawFile() &&
+ Line == RHS->getLine() && Type == RHS->getRawType() &&
IsLocalToUnit == RHS->isLocalToUnit() &&
IsDefinition == RHS->isDefinition() &&
- Variable == RHS->getVariable() &&
- StaticDataMemberDeclaration == RHS->getStaticDataMemberDeclaration();
+ Variable == RHS->getRawVariable() &&
+ StaticDataMemberDeclaration ==
+ RHS->getRawStaticDataMemberDeclaration();
}
unsigned getHashValue() const {
return hash_combine(Scope, Name, LinkageName, File, Line, Type,
@@ -731,28 +736,24 @@ template <> struct MDNodeKeyImpl<MDLocalVariable> {
Metadata *Type;
unsigned Arg;
unsigned Flags;
- Metadata *InlinedAt;
MDNodeKeyImpl(unsigned Tag, Metadata *Scope, StringRef Name, Metadata *File,
- unsigned Line, Metadata *Type, unsigned Arg, unsigned Flags,
- Metadata *InlinedAt)
+ unsigned Line, Metadata *Type, unsigned Arg, unsigned Flags)
: Tag(Tag), Scope(Scope), Name(Name), File(File), Line(Line), Type(Type),
- Arg(Arg), Flags(Flags), InlinedAt(InlinedAt) {}
+ Arg(Arg), Flags(Flags) {}
MDNodeKeyImpl(const MDLocalVariable *N)
- : Tag(N->getTag()), Scope(N->getScope()), Name(N->getName()),
- File(N->getFile()), Line(N->getLine()), Type(N->getType()),
- Arg(N->getArg()), Flags(N->getFlags()), InlinedAt(N->getInlinedAt()) {}
+ : Tag(N->getTag()), Scope(N->getRawScope()), Name(N->getName()),
+ File(N->getRawFile()), Line(N->getLine()), Type(N->getRawType()),
+ Arg(N->getArg()), Flags(N->getFlags()) {}
bool isKeyOf(const MDLocalVariable *RHS) const {
- return Tag == RHS->getTag() && Scope == RHS->getScope() &&
- Name == RHS->getName() && File == RHS->getFile() &&
- Line == RHS->getLine() && Type == RHS->getType() &&
- Arg == RHS->getArg() && Flags == RHS->getFlags() &&
- InlinedAt == RHS->getInlinedAt();
+ return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
+ Name == RHS->getName() && File == RHS->getRawFile() &&
+ Line == RHS->getLine() && Type == RHS->getRawType() &&
+ Arg == RHS->getArg() && Flags == RHS->getFlags();
}
unsigned getHashValue() const {
- return hash_combine(Tag, Scope, Name, File, Line, Type, Arg, Flags,
- InlinedAt);
+ return hash_combine(Tag, Scope, Name, File, Line, Type, Arg, Flags);
}
};
@@ -785,15 +786,15 @@ template <> struct MDNodeKeyImpl<MDObjCProperty> {
: Name(Name), File(File), Line(Line), GetterName(GetterName),
SetterName(SetterName), Attributes(Attributes), Type(Type) {}
MDNodeKeyImpl(const MDObjCProperty *N)
- : Name(N->getName()), File(N->getFile()), Line(N->getLine()),
+ : Name(N->getName()), File(N->getRawFile()), Line(N->getLine()),
GetterName(N->getGetterName()), SetterName(N->getSetterName()),
- Attributes(N->getAttributes()), Type(N->getType()) {}
+ Attributes(N->getAttributes()), Type(N->getRawType()) {}
bool isKeyOf(const MDObjCProperty *RHS) const {
- return Name == RHS->getName() && File == RHS->getFile() &&
+ return Name == RHS->getName() && File == RHS->getRawFile() &&
Line == RHS->getLine() && GetterName == RHS->getGetterName() &&
SetterName == RHS->getSetterName() &&
- Attributes == RHS->getAttributes() && Type == RHS->getType();
+ Attributes == RHS->getAttributes() && Type == RHS->getRawType();
}
unsigned getHashValue() const {
return hash_combine(Name, File, Line, GetterName, SetterName, Attributes,
@@ -812,12 +813,12 @@ template <> struct MDNodeKeyImpl<MDImportedEntity> {
StringRef Name)
: Tag(Tag), Scope(Scope), Entity(Entity), Line(Line), Name(Name) {}
MDNodeKeyImpl(const MDImportedEntity *N)
- : Tag(N->getTag()), Scope(N->getScope()), Entity(N->getEntity()),
+ : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
Line(N->getLine()), Name(N->getName()) {}
bool isKeyOf(const MDImportedEntity *RHS) const {
- return Tag == RHS->getTag() && Scope == RHS->getScope() &&
- Entity == RHS->getEntity() && Line == RHS->getLine() &&
+ return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
+ Entity == RHS->getRawEntity() && Line == RHS->getLine() &&
Name == RHS->getName();
}
unsigned getHashValue() const {
diff --git a/lib/IR/LegacyPassManager.cpp b/lib/IR/LegacyPassManager.cpp
index 9a365d1..6870032 100644
--- a/lib/IR/LegacyPassManager.cpp
+++ b/lib/IR/LegacyPassManager.cpp
@@ -293,7 +293,7 @@ public:
Pass(PT_PassManager, ID), PMDataManager() { }
// Delete on the fly managers.
- virtual ~MPPassManager() {
+ ~MPPassManager() override {
for (std::map<Pass *, FunctionPassManagerImpl *>::iterator
I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end();
I != E; ++I) {
diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp
index 0ad3c5c..93098b9 100644
--- a/lib/IR/Metadata.cpp
+++ b/lib/IR/Metadata.cpp
@@ -446,6 +446,10 @@ void MDNode::makeUniqued() {
assert(isTemporary() && "Expected this to be temporary");
assert(!isResolved() && "Expected this to be unresolved");
+ // Enable uniquing callbacks.
+ for (auto &Op : mutable_operands())
+ Op.reset(Op.get(), this);
+
// Make this 'uniqued'.
Storage = Uniqued;
if (!countUnresolvedOperands())
@@ -1035,7 +1039,7 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
// Handle 'dbg' as a special case since it is not stored in the hash table.
if (KindID == LLVMContext::MD_dbg) {
- DbgLoc = DebugLoc::getFromDILocation(Node);
+ DbgLoc = DebugLoc(Node);
return;
}
@@ -1114,7 +1118,7 @@ void Instruction::getAllMetadataImpl(
Result.clear();
// Handle 'dbg' as a special case since it is not stored in the hash table.
- if (!DbgLoc.isUnknown()) {
+ if (DbgLoc) {
Result.push_back(
std::make_pair((unsigned)LLVMContext::MD_dbg, DbgLoc.getAsMDNode()));
if (!hasMetadataHashEntry()) return;
diff --git a/lib/IR/UseListOrder.cpp b/lib/IR/UseListOrder.cpp
deleted file mode 100644
index d064e67..0000000
--- a/lib/IR/UseListOrder.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//===- UseListOrder.cpp - Implement Use List Order ------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Implement structures and command-line options for preserving use-list order.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/UseListOrder.h"
-#include "llvm/Support/CommandLine.h"
-
-using namespace llvm;
-
-static cl::opt<bool> PreserveBitcodeUseListOrder(
- "preserve-bc-use-list-order",
- cl::desc("Experimental support to preserve bitcode use-list order."),
- cl::init(false), cl::Hidden);
-
-static cl::opt<bool> PreserveAssemblyUseListOrder(
- "preserve-ll-use-list-order",
- cl::desc("Experimental support to preserve assembly use-list order."),
- cl::init(false), cl::Hidden);
-
-bool llvm::shouldPreserveBitcodeUseListOrder() {
- return PreserveBitcodeUseListOrder;
-}
-
-bool llvm::shouldPreserveAssemblyUseListOrder() {
- return PreserveAssemblyUseListOrder;
-}
-
-void llvm::setPreserveBitcodeUseListOrder(bool ShouldPreserve) {
- PreserveBitcodeUseListOrder = ShouldPreserve;
-}
-
-void llvm::setPreserveAssemblyUseListOrder(bool ShouldPreserve) {
- PreserveAssemblyUseListOrder = ShouldPreserve;
-}
diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp
index 78bfca4..f6eb427 100644
--- a/lib/IR/Value.cpp
+++ b/lib/IR/Value.cpp
@@ -525,7 +525,7 @@ static bool isDereferenceablePointer(const Value *V, const DataLayout &DL,
// Return values from call sites specifically marked as dereferenceable are
// also okay.
- if (ImmutableCallSite CS = V) {
+ if (auto CS = ImmutableCallSite(V)) {
if (uint64_t Bytes = CS.getDereferenceableBytes(0)) {
Type *Ty = V->getType()->getPointerElementType();
if (Ty->isSized() && DL.getTypeStoreSize(Ty) <= Bytes)
@@ -595,7 +595,7 @@ bool Value::isDereferenceablePointer(const DataLayout &DL) const {
APInt DerefBytes(Offset.getBitWidth(), 0);
if (const Argument *A = dyn_cast<Argument>(BV))
DerefBytes = A->getDereferenceableBytes();
- else if (ImmutableCallSite CS = BV)
+ else if (auto CS = ImmutableCallSite(BV))
DerefBytes = CS.getDereferenceableBytes(0);
if (DerefBytes.getBoolValue() && Offset.isNonNegative()) {
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index fcf48c4..fba78e9 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -87,10 +87,9 @@ struct VerifierSupport {
/// \brief Track the brokenness of the module while recursively visiting.
bool Broken;
- bool EverBroken;
explicit VerifierSupport(raw_ostream &OS)
- : OS(OS), M(nullptr), Broken(false), EverBroken(false) {}
+ : OS(OS), M(nullptr), Broken(false) {}
private:
void Write(const Value *V) {
@@ -111,6 +110,10 @@ private:
OS << '\n';
}
+ template <class T> void Write(const MDTupleTypedArrayWrapper<T> &MD) {
+ Write(MD.get());
+ }
+
void Write(const NamedMDNode *NMD) {
if (!NMD)
return;
@@ -145,7 +148,7 @@ public:
/// something is not correct.
void CheckFailed(const Twine &Message) {
OS << Message << '\n';
- EverBroken = Broken = true;
+ Broken = true;
}
/// \brief A check failed (with values to print).
@@ -175,6 +178,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
/// \brief Keep track of the metadata nodes that have been checked already.
SmallPtrSet<const Metadata *, 32> MDNodes;
+ /// \brief Track unresolved string-based type references.
+ SmallDenseMap<const MDString *, const MDNode *, 32> UnresolvedTypeRefs;
+
/// \brief The personality function referenced by the LandingPadInsts.
/// All LandingPadInsts within the same function must use the same
/// personality function.
@@ -268,8 +274,8 @@ public:
visitModuleFlags(M);
visitModuleIdents(M);
- // Verify debug info last.
- verifyDebugInfo();
+ // Verify type referneces last.
+ verifyTypeRefs();
return !Broken;
}
@@ -296,8 +302,37 @@ private:
void visitBasicBlock(BasicBlock &BB);
void visitRangeMetadata(Instruction& I, MDNode* Range, Type* Ty);
+ template <class Ty> bool isValidMetadataArray(const MDTuple &N);
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
#include "llvm/IR/Metadata.def"
+ void visitMDScope(const MDScope &N);
+ void visitMDDerivedTypeBase(const MDDerivedTypeBase &N);
+ void visitMDVariable(const MDVariable &N);
+ void visitMDLexicalBlockBase(const MDLexicalBlockBase &N);
+ void visitMDTemplateParameter(const MDTemplateParameter &N);
+
+ void visitTemplateParams(const MDNode &N, const Metadata &RawParams);
+
+ /// \brief Check for a valid string-based type reference.
+ ///
+ /// Checks if \c MD is a string-based type reference. If it is, keeps track
+ /// of it (and its user, \c N) for error messages later.
+ bool isValidUUID(const MDNode &N, const Metadata *MD);
+
+ /// \brief Check for a valid type reference.
+ ///
+ /// Checks for subclasses of \a MDType, or \a isValidUUID().
+ bool isTypeRef(const MDNode &N, const Metadata *MD);
+
+ /// \brief Check for a valid scope reference.
+ ///
+ /// Checks for subclasses of \a MDScope, or \a isValidUUID().
+ bool isScopeRef(const MDNode &N, const Metadata *MD);
+
+ /// \brief Check for a valid debug info reference.
+ ///
+ /// Checks for subclasses of \a DebugNode, or \a isValidUUID().
+ bool isDIRef(const MDNode &N, const Metadata *MD);
// InstVisitor overrides...
using InstVisitor<Verifier>::visit;
@@ -371,9 +406,11 @@ private:
void verifyFrameRecoverIndices();
// Module-level debug info verification...
- void verifyDebugInfo();
- void processInstructions(DebugInfoFinder &Finder);
- void processCallInst(DebugInfoFinder &Finder, const CallInst &CI);
+ void verifyTypeRefs();
+ template <class MapTy>
+ void verifyBitPieceExpression(const DbgInfoIntrinsic &I,
+ const MapTy &TypeRefs);
+ void visitUnresolvedTypeRef(const MDString *S, const MDNode *N);
};
} // End anonymous namespace
@@ -566,13 +603,14 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) {
void Verifier::visitNamedMDNode(const NamedMDNode &NMD) {
for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i) {
MDNode *MD = NMD.getOperand(i);
- if (!MD)
- continue;
if (NMD.getName() == "llvm.dbg.cu") {
- Assert(isa<MDCompileUnit>(MD), "invalid compile unit", &NMD, MD);
+ Assert(MD && isa<MDCompileUnit>(MD), "invalid compile unit", &NMD, MD);
}
+ if (!MD)
+ continue;
+
visitMDNode(*MD);
}
}
@@ -658,6 +696,58 @@ void Verifier::visitMetadataAsValue(const MetadataAsValue &MDV, Function *F) {
visitValueAsMetadata(*V, F);
}
+bool Verifier::isValidUUID(const MDNode &N, const Metadata *MD) {
+ auto *S = dyn_cast<MDString>(MD);
+ if (!S)
+ return false;
+ if (S->getString().empty())
+ return false;
+
+ // Keep track of names of types referenced via UUID so we can check that they
+ // actually exist.
+ UnresolvedTypeRefs.insert(std::make_pair(S, &N));
+ return true;
+}
+
+/// \brief Check if a value can be a reference to a type.
+bool Verifier::isTypeRef(const MDNode &N, const Metadata *MD) {
+ return !MD || isValidUUID(N, MD) || isa<MDType>(MD);
+}
+
+/// \brief Check if a value can be a ScopeRef.
+bool Verifier::isScopeRef(const MDNode &N, const Metadata *MD) {
+ return !MD || isValidUUID(N, MD) || isa<MDScope>(MD);
+}
+
+/// \brief Check if a value can be a debug info ref.
+bool Verifier::isDIRef(const MDNode &N, const Metadata *MD) {
+ return !MD || isValidUUID(N, MD) || isa<DebugNode>(MD);
+}
+
+template <class Ty>
+bool isValidMetadataArrayImpl(const MDTuple &N, bool AllowNull) {
+ for (Metadata *MD : N.operands()) {
+ if (MD) {
+ if (!isa<Ty>(MD))
+ return false;
+ } else {
+ if (!AllowNull)
+ return false;
+ }
+ }
+ return true;
+}
+
+template <class Ty>
+bool isValidMetadataArray(const MDTuple &N) {
+ return isValidMetadataArrayImpl<Ty>(N, /* AllowNull */ false);
+}
+
+template <class Ty>
+bool isValidMetadataNullArray(const MDTuple &N) {
+ return isValidMetadataArrayImpl<Ty>(N, /* AllowNull */ true);
+}
+
void Verifier::visitMDLocation(const MDLocation &N) {
Assert(N.getRawScope() && isa<MDLocalScope>(N.getRawScope()),
"location requires a valid scope", &N, N.getRawScope());
@@ -669,8 +759,14 @@ void Verifier::visitGenericDebugNode(const GenericDebugNode &N) {
Assert(N.getTag(), "invalid tag", &N);
}
+void Verifier::visitMDScope(const MDScope &N) {
+ if (auto *F = N.getRawFile())
+ Assert(isa<MDFile>(F), "invalid file", &N, F);
+}
+
void Verifier::visitMDSubrange(const MDSubrange &N) {
Assert(N.getTag() == dwarf::DW_TAG_subrange_type, "invalid tag", &N);
+ Assert(N.getCount() >= -1, "invalid subrange count", &N);
}
void Verifier::visitMDEnumerator(const MDEnumerator &N) {
@@ -683,7 +779,39 @@ void Verifier::visitMDBasicType(const MDBasicType &N) {
"invalid tag", &N);
}
+void Verifier::visitMDDerivedTypeBase(const MDDerivedTypeBase &N) {
+ // Common scope checks.
+ visitMDScope(N);
+
+ Assert(isScopeRef(N, N.getScope()), "invalid scope", &N, N.getScope());
+ Assert(isTypeRef(N, N.getBaseType()), "invalid base type", &N,
+ N.getBaseType());
+
+ // FIXME: Sink this into the subclass verifies.
+ if (!N.getFile() || N.getFile()->getFilename().empty()) {
+ // Check whether the filename is allowed to be empty.
+ uint16_t Tag = N.getTag();
+ Assert(
+ Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type ||
+ Tag == dwarf::DW_TAG_pointer_type ||
+ Tag == dwarf::DW_TAG_ptr_to_member_type ||
+ Tag == dwarf::DW_TAG_reference_type ||
+ Tag == dwarf::DW_TAG_rvalue_reference_type ||
+ Tag == dwarf::DW_TAG_restrict_type ||
+ Tag == dwarf::DW_TAG_array_type ||
+ Tag == dwarf::DW_TAG_enumeration_type ||
+ Tag == dwarf::DW_TAG_subroutine_type ||
+ Tag == dwarf::DW_TAG_inheritance || Tag == dwarf::DW_TAG_friend ||
+ Tag == dwarf::DW_TAG_structure_type ||
+ Tag == dwarf::DW_TAG_member || Tag == dwarf::DW_TAG_typedef,
+ "derived/composite type requires a filename", &N, N.getFile());
+ }
+}
+
void Verifier::visitMDDerivedType(const MDDerivedType &N) {
+ // Common derived type checks.
+ visitMDDerivedTypeBase(N);
+
Assert(N.getTag() == dwarf::DW_TAG_typedef ||
N.getTag() == dwarf::DW_TAG_pointer_type ||
N.getTag() == dwarf::DW_TAG_ptr_to_member_type ||
@@ -696,9 +824,30 @@ void Verifier::visitMDDerivedType(const MDDerivedType &N) {
N.getTag() == dwarf::DW_TAG_inheritance ||
N.getTag() == dwarf::DW_TAG_friend,
"invalid tag", &N);
+ if (N.getTag() == dwarf::DW_TAG_ptr_to_member_type) {
+ Assert(isTypeRef(N, N.getExtraData()), "invalid pointer to member type", &N,
+ N.getExtraData());
+ }
+}
+
+static bool hasConflictingReferenceFlags(unsigned Flags) {
+ return (Flags & DebugNode::FlagLValueReference) &&
+ (Flags & DebugNode::FlagRValueReference);
+}
+
+void Verifier::visitTemplateParams(const MDNode &N, const Metadata &RawParams) {
+ auto *Params = dyn_cast<MDTuple>(&RawParams);
+ Assert(Params, "invalid template params", &N, &RawParams);
+ for (Metadata *Op : Params->operands()) {
+ Assert(Op && isa<MDTemplateParameter>(Op), "invalid template parameter", &N,
+ Params, Op);
+ }
}
void Verifier::visitMDCompositeType(const MDCompositeType &N) {
+ // Common derived type checks.
+ visitMDDerivedTypeBase(N);
+
Assert(N.getTag() == dwarf::DW_TAG_array_type ||
N.getTag() == dwarf::DW_TAG_structure_type ||
N.getTag() == dwarf::DW_TAG_union_type ||
@@ -706,10 +855,29 @@ void Verifier::visitMDCompositeType(const MDCompositeType &N) {
N.getTag() == dwarf::DW_TAG_subroutine_type ||
N.getTag() == dwarf::DW_TAG_class_type,
"invalid tag", &N);
+
+ Assert(!N.getRawElements() || isa<MDTuple>(N.getRawElements()),
+ "invalid composite elements", &N, N.getRawElements());
+ Assert(isTypeRef(N, N.getRawVTableHolder()), "invalid vtable holder", &N,
+ N.getRawVTableHolder());
+ Assert(!N.getRawElements() || isa<MDTuple>(N.getRawElements()),
+ "invalid composite elements", &N, N.getRawElements());
+ Assert(!hasConflictingReferenceFlags(N.getFlags()), "invalid reference flags",
+ &N);
+ if (auto *Params = N.getRawTemplateParams())
+ visitTemplateParams(N, *Params);
}
void Verifier::visitMDSubroutineType(const MDSubroutineType &N) {
Assert(N.getTag() == dwarf::DW_TAG_subroutine_type, "invalid tag", &N);
+ if (auto *Types = N.getRawTypeArray()) {
+ Assert(isa<MDTuple>(Types), "invalid composite elements", &N, Types);
+ for (Metadata *Ty : N.getTypeArray()->operands()) {
+ Assert(isTypeRef(N, Ty), "invalid subroutine type ref", &N, Types, Ty);
+ }
+ }
+ Assert(!hasConflictingReferenceFlags(N.getFlags()), "invalid reference flags",
+ &N);
}
void Verifier::visitMDFile(const MDFile &N) {
@@ -718,45 +886,195 @@ void Verifier::visitMDFile(const MDFile &N) {
void Verifier::visitMDCompileUnit(const MDCompileUnit &N) {
Assert(N.getTag() == dwarf::DW_TAG_compile_unit, "invalid tag", &N);
+
+ // Don't bother verifying the compilation directory or producer string
+ // as those could be empty.
+ Assert(N.getRawFile() && isa<MDFile>(N.getRawFile()),
+ "invalid file", &N, N.getRawFile());
+ Assert(!N.getFile()->getFilename().empty(), "invalid filename", &N,
+ N.getFile());
+
+ if (auto *Array = N.getRawEnumTypes()) {
+ Assert(isa<MDTuple>(Array), "invalid enum list", &N, Array);
+ for (Metadata *Op : N.getEnumTypes()->operands()) {
+ auto *Enum = dyn_cast_or_null<MDCompositeType>(Op);
+ Assert(Enum && Enum->getTag() == dwarf::DW_TAG_enumeration_type,
+ "invalid enum type", &N, N.getEnumTypes(), Op);
+ }
+ }
+ if (auto *Array = N.getRawRetainedTypes()) {
+ Assert(isa<MDTuple>(Array), "invalid retained type list", &N, Array);
+ for (Metadata *Op : N.getRetainedTypes()->operands()) {
+ Assert(Op && isa<MDType>(Op), "invalid retained type", &N, Op);
+ }
+ }
+ if (auto *Array = N.getRawSubprograms()) {
+ Assert(isa<MDTuple>(Array), "invalid subprogram list", &N, Array);
+ for (Metadata *Op : N.getSubprograms()->operands()) {
+ Assert(Op && isa<MDSubprogram>(Op), "invalid subprogram ref", &N, Op);
+ }
+ }
+ if (auto *Array = N.getRawGlobalVariables()) {
+ Assert(isa<MDTuple>(Array), "invalid global variable list", &N, Array);
+ for (Metadata *Op : N.getGlobalVariables()->operands()) {
+ Assert(Op && isa<MDGlobalVariable>(Op), "invalid global variable ref", &N,
+ Op);
+ }
+ }
+ if (auto *Array = N.getRawImportedEntities()) {
+ Assert(isa<MDTuple>(Array), "invalid imported entity list", &N, Array);
+ for (Metadata *Op : N.getImportedEntities()->operands()) {
+ Assert(Op && isa<MDImportedEntity>(Op), "invalid imported entity ref", &N,
+ Op);
+ }
+ }
}
void Verifier::visitMDSubprogram(const MDSubprogram &N) {
Assert(N.getTag() == dwarf::DW_TAG_subprogram, "invalid tag", &N);
+ Assert(isScopeRef(N, N.getRawScope()), "invalid scope", &N, N.getRawScope());
+ if (auto *T = N.getRawType())
+ Assert(isa<MDSubroutineType>(T), "invalid subroutine type", &N, T);
+ Assert(isTypeRef(N, N.getRawContainingType()), "invalid containing type", &N,
+ N.getRawContainingType());
+ if (auto *RawF = N.getRawFunction()) {
+ auto *FMD = dyn_cast<ConstantAsMetadata>(RawF);
+ auto *F = FMD ? FMD->getValue() : nullptr;
+ auto *FT = F ? dyn_cast<PointerType>(F->getType()) : nullptr;
+ Assert(F && FT && isa<FunctionType>(FT->getElementType()),
+ "invalid function", &N, F, FT);
+ }
+ if (auto *Params = N.getRawTemplateParams())
+ visitTemplateParams(N, *Params);
+ if (auto *S = N.getRawDeclaration()) {
+ Assert(isa<MDSubprogram>(S) && !cast<MDSubprogram>(S)->isDefinition(),
+ "invalid subprogram declaration", &N, S);
+ }
+ if (auto *RawVars = N.getRawVariables()) {
+ auto *Vars = dyn_cast<MDTuple>(RawVars);
+ Assert(Vars, "invalid variable list", &N, RawVars);
+ for (Metadata *Op : Vars->operands()) {
+ Assert(Op && isa<MDLocalVariable>(Op), "invalid local variable", &N, Vars,
+ Op);
+ }
+ }
+ Assert(!hasConflictingReferenceFlags(N.getFlags()), "invalid reference flags",
+ &N);
+
+ auto *F = N.getFunction();
+ if (!F)
+ return;
+
+ // Check that all !dbg attachments lead to back to N (or, at least, another
+ // subprogram that describes the same function).
+ //
+ // FIXME: Check this incrementally while visiting !dbg attachments.
+ // FIXME: Only check when N is the canonical subprogram for F.
+ SmallPtrSet<const MDNode *, 32> Seen;
+ for (auto &BB : *F)
+ for (auto &I : BB) {
+ // Be careful about using MDLocation here since we might be dealing with
+ // broken code (this is the Verifier after all).
+ MDLocation *DL =
+ dyn_cast_or_null<MDLocation>(I.getDebugLoc().getAsMDNode());
+ if (!DL)
+ continue;
+ if (!Seen.insert(DL).second)
+ continue;
+
+ MDLocalScope *Scope = DL->getInlinedAtScope();
+ if (Scope && !Seen.insert(Scope).second)
+ continue;
+
+ MDSubprogram *SP = Scope ? Scope->getSubprogram() : nullptr;
+ if (SP && !Seen.insert(SP).second)
+ continue;
+
+ // FIXME: Once N is canonical, check "SP == &N".
+ Assert(SP->describes(F),
+ "!dbg attachment points at wrong subprogram for function", &N, F,
+ &I, DL, Scope, SP);
+ }
}
-void Verifier::visitMDLexicalBlock(const MDLexicalBlock &N) {
+void Verifier::visitMDLexicalBlockBase(const MDLexicalBlockBase &N) {
Assert(N.getTag() == dwarf::DW_TAG_lexical_block, "invalid tag", &N);
+ Assert(N.getRawScope() && isa<MDLocalScope>(N.getRawScope()),
+ "invalid local scope", &N, N.getRawScope());
+}
+
+void Verifier::visitMDLexicalBlock(const MDLexicalBlock &N) {
+ visitMDLexicalBlockBase(N);
+
+ Assert(N.getLine() || !N.getColumn(),
+ "cannot have column info without line info", &N);
}
void Verifier::visitMDLexicalBlockFile(const MDLexicalBlockFile &N) {
- Assert(N.getTag() == dwarf::DW_TAG_lexical_block, "invalid tag", &N);
+ visitMDLexicalBlockBase(N);
}
void Verifier::visitMDNamespace(const MDNamespace &N) {
Assert(N.getTag() == dwarf::DW_TAG_namespace, "invalid tag", &N);
+ if (auto *S = N.getRawScope())
+ Assert(isa<MDScope>(S), "invalid scope ref", &N, S);
+}
+
+void Verifier::visitMDTemplateParameter(const MDTemplateParameter &N) {
+ Assert(isTypeRef(N, N.getType()), "invalid type ref", &N, N.getType());
}
void Verifier::visitMDTemplateTypeParameter(const MDTemplateTypeParameter &N) {
+ visitMDTemplateParameter(N);
+
Assert(N.getTag() == dwarf::DW_TAG_template_type_parameter, "invalid tag",
&N);
}
void Verifier::visitMDTemplateValueParameter(
const MDTemplateValueParameter &N) {
+ visitMDTemplateParameter(N);
+
Assert(N.getTag() == dwarf::DW_TAG_template_value_parameter ||
N.getTag() == dwarf::DW_TAG_GNU_template_template_param ||
N.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack,
"invalid tag", &N);
}
+void Verifier::visitMDVariable(const MDVariable &N) {
+ if (auto *S = N.getRawScope())
+ Assert(isa<MDScope>(S), "invalid scope", &N, S);
+ Assert(isTypeRef(N, N.getRawType()), "invalid type ref", &N, N.getRawType());
+ if (auto *F = N.getRawFile())
+ Assert(isa<MDFile>(F), "invalid file", &N, F);
+}
+
void Verifier::visitMDGlobalVariable(const MDGlobalVariable &N) {
+ // Checks common to all variables.
+ visitMDVariable(N);
+
Assert(N.getTag() == dwarf::DW_TAG_variable, "invalid tag", &N);
+ Assert(!N.getName().empty(), "missing global variable name", &N);
+ if (auto *V = N.getRawVariable()) {
+ Assert(isa<ConstantAsMetadata>(V) &&
+ !isa<Function>(cast<ConstantAsMetadata>(V)->getValue()),
+ "invalid global varaible ref", &N, V);
+ }
+ if (auto *Member = N.getRawStaticDataMemberDeclaration()) {
+ Assert(isa<MDDerivedType>(Member), "invalid static data member declaration",
+ &N, Member);
+ }
}
void Verifier::visitMDLocalVariable(const MDLocalVariable &N) {
+ // Checks common to all variables.
+ visitMDVariable(N);
+
Assert(N.getTag() == dwarf::DW_TAG_auto_variable ||
N.getTag() == dwarf::DW_TAG_arg_variable,
"invalid tag", &N);
+ Assert(N.getRawScope() && isa<MDLocalScope>(N.getRawScope()),
+ "local variable requires a valid scope", &N, N.getRawScope());
}
void Verifier::visitMDExpression(const MDExpression &N) {
@@ -765,12 +1083,20 @@ void Verifier::visitMDExpression(const MDExpression &N) {
void Verifier::visitMDObjCProperty(const MDObjCProperty &N) {
Assert(N.getTag() == dwarf::DW_TAG_APPLE_property, "invalid tag", &N);
+ if (auto *T = N.getRawType())
+ Assert(isa<MDType>(T), "invalid type ref", &N, T);
+ if (auto *F = N.getRawFile())
+ Assert(isa<MDFile>(F), "invalid file", &N, F);
}
void Verifier::visitMDImportedEntity(const MDImportedEntity &N) {
Assert(N.getTag() == dwarf::DW_TAG_imported_module ||
N.getTag() == dwarf::DW_TAG_imported_declaration,
"invalid tag", &N);
+ if (auto *S = N.getRawScope())
+ Assert(isa<MDScope>(S), "invalid scope for imported entity", &N, S);
+ Assert(isDIRef(N, N.getEntity()), "invalid imported entity", &N,
+ N.getEntity());
}
void Verifier::visitComdat(const Comdat &C) {
@@ -2133,7 +2459,7 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) {
SmallVector<Value*, 16> Idxs(GEP.idx_begin(), GEP.idx_end());
Type *ElTy =
- GetElementPtrInst::getIndexedType(GEP.getPointerOperandType(), Idxs);
+ GetElementPtrInst::getIndexedType(GEP.getSourceElementType(), Idxs);
Assert(ElTy, "Invalid indices for GEP pointer type!", &GEP);
Assert(GEP.getType()->getScalarType()->isPointerTy() &&
@@ -2214,9 +2540,7 @@ void Verifier::visitRangeMetadata(Instruction& I,
void Verifier::visitLoadInst(LoadInst &LI) {
PointerType *PTy = dyn_cast<PointerType>(LI.getOperand(0)->getType());
Assert(PTy, "Load operand must be a pointer.", &LI);
- Type *ElTy = PTy->getElementType();
- Assert(ElTy == LI.getType(),
- "Load result type does not match pointer operand type!", &LI, ElTy);
+ Type *ElTy = LI.getType();
Assert(LI.getAlignment() <= Value::MaximumAlignment,
"huge alignment values are unsupported", &LI);
if (LI.isAtomic()) {
@@ -2885,6 +3209,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
Assert(!SawFrameEscape,
"multiple calls to llvm.frameescape in one function", &CI);
for (Value *Arg : CI.arg_operands()) {
+ if (isa<ConstantPointerNull>(Arg))
+ continue; // Null values are allowed as placeholders.
auto *AI = dyn_cast<AllocaInst>(Arg->stripPointerCasts());
Assert(AI && AI->isStaticAlloca(),
"llvm.frameescape only accepts static allocas", &CI);
@@ -2909,16 +3235,11 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
break;
}
- case Intrinsic::eh_unwindhelp: {
- auto *AI = dyn_cast<AllocaInst>(CI.getArgOperand(0)->stripPointerCasts());
- Assert(AI && AI->isStaticAlloca(),
- "llvm.eh.unwindhelp requires a static alloca", &CI);
- break;
- }
-
case Intrinsic::experimental_gc_statepoint:
Assert(!CI.isInlineAsm(),
"gc.statepoint support for inline assembly unimplemented", &CI);
+ Assert(CI.getParent()->getParent()->hasGC(),
+ "Enclosing function does not use GC.", &CI);
VerifyStatepoint(ImmutableCallSite(&CI));
break;
@@ -2926,6 +3247,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
case Intrinsic::experimental_gc_result_float:
case Intrinsic::experimental_gc_result_ptr:
case Intrinsic::experimental_gc_result: {
+ Assert(CI.getParent()->getParent()->hasGC(),
+ "Enclosing function does not use GC.", &CI);
// Are we tied to a statepoint properly?
CallSite StatepointCS(CI.getArgOperand(0));
const Function *StatepointFn =
@@ -3035,6 +3358,25 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
};
}
+/// \brief Carefully grab the subprogram from a local scope.
+///
+/// This carefully grabs the subprogram from a local scope, avoiding the
+/// built-in assertions that would typically fire.
+static MDSubprogram *getSubprogram(Metadata *LocalScope) {
+ if (!LocalScope)
+ return nullptr;
+
+ if (auto *SP = dyn_cast<MDSubprogram>(LocalScope))
+ return SP;
+
+ if (auto *LB = dyn_cast<MDLexicalBlockBase>(LocalScope))
+ return getSubprogram(LB->getRawScope());
+
+ // Just return null; broken scope chains are checked elsewhere.
+ assert(!isa<MDLocalScope>(LocalScope) && "Unknown type of local scope");
+ return nullptr;
+}
+
template <class DbgIntrinsicTy>
void Verifier::visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII) {
auto *MD = cast<MetadataAsValue>(DII.getArgOperand(0))->getMetadata();
@@ -3047,61 +3389,145 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII) {
Assert(isa<MDExpression>(DII.getRawExpression()),
"invalid llvm.dbg." + Kind + " intrinsic expression", &DII,
DII.getRawExpression());
-}
-void Verifier::verifyDebugInfo() {
- // Run the debug info verifier only if the regular verifier succeeds, since
- // sometimes checks that have already failed will cause crashes here.
- if (EverBroken || !VerifyDebugInfo)
- return;
+ // Ignore broken !dbg attachments; they're checked elsewhere.
+ if (MDNode *N = DII.getDebugLoc().getAsMDNode())
+ if (!isa<MDLocation>(N))
+ return;
- DebugInfoFinder Finder;
- Finder.processModule(*M);
- processInstructions(Finder);
+ BasicBlock *BB = DII.getParent();
+ Function *F = BB ? BB->getParent() : nullptr;
+
+ // The scopes for variables and !dbg attachments must agree.
+ MDLocalVariable *Var = DII.getVariable();
+ MDLocation *Loc = DII.getDebugLoc();
+ Assert(Loc, "llvm.dbg." + Kind + " intrinsic requires a !dbg attachment",
+ &DII, BB, F);
+
+ MDSubprogram *VarSP = getSubprogram(Var->getRawScope());
+ MDSubprogram *LocSP = getSubprogram(Loc->getRawScope());
+ if (!VarSP || !LocSP)
+ return; // Broken scope chains are checked elsewhere.
+
+ Assert(VarSP == LocSP, "mismatched subprogram between llvm.dbg." + Kind +
+ " variable and !dbg attachment",
+ &DII, BB, F, Var, Var->getScope()->getSubprogram(), Loc,
+ Loc->getScope()->getSubprogram());
+}
+
+template <class MapTy>
+static uint64_t getVariableSize(const MDLocalVariable &V, const MapTy &Map) {
+ // Be careful of broken types (checked elsewhere).
+ const Metadata *RawType = V.getRawType();
+ while (RawType) {
+ // Try to get the size directly.
+ if (auto *T = dyn_cast<MDType>(RawType))
+ if (uint64_t Size = T->getSizeInBits())
+ return Size;
+
+ if (auto *DT = dyn_cast<MDDerivedType>(RawType)) {
+ // Look at the base type.
+ RawType = DT->getRawBaseType();
+ continue;
+ }
- // Verify Debug Info.
- //
- // NOTE: The loud braces are necessary for MSVC compatibility.
- for (DICompileUnit CU : Finder.compile_units()) {
- Assert(CU.Verify(), "DICompileUnit does not Verify!", CU);
- }
- for (DISubprogram S : Finder.subprograms()) {
- Assert(S.Verify(), "DISubprogram does not Verify!", S);
- }
- for (DIGlobalVariable GV : Finder.global_variables()) {
- Assert(GV.Verify(), "DIGlobalVariable does not Verify!", GV);
- }
- for (DIType T : Finder.types()) {
- Assert(T.Verify(), "DIType does not Verify!", T);
+ if (auto *S = dyn_cast<MDString>(RawType)) {
+ // Don't error on missing types (checked elsewhere).
+ RawType = Map.lookup(S);
+ continue;
+ }
+
+ // Missing type or size.
+ break;
}
- for (DIScope S : Finder.scopes()) {
- Assert(S.Verify(), "DIScope does not Verify!", S);
+
+ // Fail gracefully.
+ return 0;
+}
+
+template <class MapTy>
+void Verifier::verifyBitPieceExpression(const DbgInfoIntrinsic &I,
+ const MapTy &TypeRefs) {
+ MDLocalVariable *V;
+ MDExpression *E;
+ if (auto *DVI = dyn_cast<DbgValueInst>(&I)) {
+ V = dyn_cast_or_null<MDLocalVariable>(DVI->getRawVariable());
+ E = dyn_cast_or_null<MDExpression>(DVI->getRawExpression());
+ } else {
+ auto *DDI = cast<DbgDeclareInst>(&I);
+ V = dyn_cast_or_null<MDLocalVariable>(DDI->getRawVariable());
+ E = dyn_cast_or_null<MDExpression>(DDI->getRawExpression());
}
+
+ // We don't know whether this intrinsic verified correctly.
+ if (!V || !E || !E->isValid())
+ return;
+
+ // Nothing to do if this isn't a bit piece expression.
+ if (!E->isBitPiece())
+ return;
+
+ // If there's no size, the type is broken, but that should be checked
+ // elsewhere.
+ uint64_t VarSize = getVariableSize(*V, TypeRefs);
+ if (!VarSize)
+ return;
+
+ unsigned PieceSize = E->getBitPieceSize();
+ unsigned PieceOffset = E->getBitPieceOffset();
+ Assert(PieceSize + PieceOffset <= VarSize,
+ "piece is larger than or outside of variable", &I, V, E);
+ Assert(PieceSize != VarSize, "piece covers entire variable", &I, V, E);
}
-void Verifier::processInstructions(DebugInfoFinder &Finder) {
- for (const Function &F : *M)
- for (auto I = inst_begin(&F), E = inst_end(&F); I != E; ++I) {
- if (MDNode *MD = I->getMetadata(LLVMContext::MD_dbg))
- Finder.processLocation(*M, DILocation(MD));
- if (const CallInst *CI = dyn_cast<CallInst>(&*I))
- processCallInst(Finder, *CI);
- }
+void Verifier::visitUnresolvedTypeRef(const MDString *S, const MDNode *N) {
+ // This is in its own function so we get an error for each bad type ref (not
+ // just the first).
+ Assert(false, "unresolved type ref", S, N);
}
-void Verifier::processCallInst(DebugInfoFinder &Finder, const CallInst &CI) {
- if (Function *F = CI.getCalledFunction())
- if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
- switch (ID) {
- case Intrinsic::dbg_declare:
- Finder.processDeclare(*M, cast<DbgDeclareInst>(&CI));
- break;
- case Intrinsic::dbg_value:
- Finder.processValue(*M, cast<DbgValueInst>(&CI));
- break;
- default:
- break;
- }
+void Verifier::verifyTypeRefs() {
+ auto *CUs = M->getNamedMetadata("llvm.dbg.cu");
+ if (!CUs)
+ return;
+
+ // Visit all the compile units again to map the type references.
+ SmallDenseMap<const MDString *, const MDType *, 32> TypeRefs;
+ for (auto *CU : CUs->operands())
+ if (auto Ts = cast<MDCompileUnit>(CU)->getRetainedTypes())
+ for (MDType *Op : Ts)
+ if (auto *T = dyn_cast<MDCompositeType>(Op))
+ if (auto *S = T->getRawIdentifier()) {
+ UnresolvedTypeRefs.erase(S);
+ TypeRefs.insert(std::make_pair(S, T));
+ }
+
+ // Verify debug info intrinsic bit piece expressions. This needs a second
+ // pass through the intructions, since we haven't built TypeRefs yet when
+ // verifying functions, and simply queuing the DbgInfoIntrinsics to evaluate
+ // later/now would queue up some that could be later deleted.
+ for (const Function &F : *M)
+ for (const BasicBlock &BB : F)
+ for (const Instruction &I : BB)
+ if (auto *DII = dyn_cast<DbgInfoIntrinsic>(&I))
+ verifyBitPieceExpression(*DII, TypeRefs);
+
+ // Return early if all typerefs were resolved.
+ if (UnresolvedTypeRefs.empty())
+ return;
+
+ // Sort the unresolved references by name so the output is deterministic.
+ typedef std::pair<const MDString *, const MDNode *> TypeRef;
+ SmallVector<TypeRef, 32> Unresolved(UnresolvedTypeRefs.begin(),
+ UnresolvedTypeRefs.end());
+ std::sort(Unresolved.begin(), Unresolved.end(),
+ [](const TypeRef &LHS, const TypeRef &RHS) {
+ return LHS.first->getString() < RHS.first->getString();
+ });
+
+ // Visit the unresolved refs (printing out the errors).
+ for (const TypeRef &TR : Unresolved)
+ visitUnresolvedTypeRef(TR.first, TR.second);
}
//===----------------------------------------------------------------------===//