DILexicalBlockFile(DbgNode).Verify() ||
DISubrange(DbgNode).Verify() || DIEnumerator(DbgNode).Verify() ||
DIObjCProperty(DbgNode).Verify() ||
+ DIUnspecifiedParameter(DbgNode).Verify() ||
DITemplateTypeParameter(DbgNode).Verify() ||
DITemplateValueParameter(DbgNode).Verify() ||
DIImportedEntity(DbgNode).Verify());
if (getFilename().empty())
return false;
- return DbgNode->getNumOperands() == 13;
+ return DbgNode->getNumOperands() == 14;
}
/// Verify - Verify that an ObjC property is well formed.
// DIType is abstract, it should be a BasicType, a DerivedType or
// a CompositeType.
if (isBasicType())
- DIBasicType(DbgNode).Verify();
+ return DIBasicType(DbgNode).Verify();
else if (isCompositeType())
- DICompositeType(DbgNode).Verify();
+ return DICompositeType(DbgNode).Verify();
else if (isDerivedType())
- DIDerivedType(DbgNode).Verify();
+ return DIDerivedType(DbgNode).Verify();
else
return false;
- return true;
}
/// Verify - Verify that a basic type descriptor is well formed.
if (!fieldIsMDString(DbgNode, 14))
return false;
+ // A subroutine type can't be both & and &&.
+ if (isLValueReference() && isRValueReference())
+ return false;
+
return DbgNode->getNumOperands() == 15;
}
// Containing type @ field 12.
if (!fieldIsTypeRef(DbgNode, 12))
return false;
+
+ // A subprogram can't be both & and &&.
+ if (isLValueReference() && isRValueReference())
+ return false;
+
return DbgNode->getNumOperands() == 20;
}
return isLexicalBlockFile() && DbgNode->getNumOperands() == 3;
}
+/// \brief Verify that an unspecified parameter descriptor is well formed.
+bool DIUnspecifiedParameter::Verify() const {
+ return isUnspecifiedParameter() && DbgNode->getNumOperands() == 1;
+}
+
/// \brief Verify that the template type parameter descriptor is well formed.
bool DITemplateTypeParameter::Verify() const {
return isTemplateTypeParameter() && DbgNode->getNumOperands() == 7;
DbgNode = N;
}
-void DICompositeType::addMember(DIDescriptor D) {
- SmallVector<llvm::Value *, 16> M;
- DIArray OrigM = getTypeArray();
- unsigned Elements = OrigM.getNumElements();
- if (Elements == 1 && !OrigM.getElement(0))
- Elements = 0;
- M.reserve(Elements + 1);
- for (unsigned i = 0; i != Elements; ++i)
- M.push_back(OrigM.getElement(i));
- M.push_back(D);
- setTypeArray(DIArray(MDNode::get(DbgNode->getContext(), M)));
-}
-
/// Generate a reference to this DIType. Uses the type identifier instead
/// of the actual MDNode if possible, to help type uniquing.
DIScopeRef DIScope::getRef() const {
Scopes.clear();
NodesSeen.clear();
TypeIdentifierMap.clear();
+ TypeMapInitialized = false;
+}
+
+void DebugInfoFinder::InitializeTypeMap(const Module &M) {
+ if (!TypeMapInitialized)
+ if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) {
+ TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
+ TypeMapInitialized = true;
+ }
}
/// processModule - Process entire module and collect debug info.
void DebugInfoFinder::processModule(const Module &M) {
+ InitializeTypeMap(M);
if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) {
- TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
DICompileUnit CU(CU_Nodes->getOperand(i));
addCompileUnit(CU);
}
/// processLocation - Process DILocation.
-void DebugInfoFinder::processLocation(DILocation Loc) {
+void DebugInfoFinder::processLocation(const Module &M, DILocation Loc) {
if (!Loc)
return;
+ InitializeTypeMap(M);
processScope(Loc.getScope());
- processLocation(Loc.getOrigLocation());
+ processLocation(M, Loc.getOrigLocation());
}
/// processType - Process DIType.
}
/// processDeclare - Process DbgDeclareInst.
-void DebugInfoFinder::processDeclare(const DbgDeclareInst *DDI) {
+void DebugInfoFinder::processDeclare(const Module &M,
+ const DbgDeclareInst *DDI) {
MDNode *N = dyn_cast<MDNode>(DDI->getVariable());
if (!N)
return;
+ InitializeTypeMap(M);
DIDescriptor DV(N);
if (!DV.isVariable())
processType(DIVariable(N).getType());
}
-void DebugInfoFinder::processValue(const DbgValueInst *DVI) {
+void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) {
MDNode *N = dyn_cast<MDNode>(DVI->getVariable());
if (!N)
return;
+ InitializeTypeMap(M);
DIDescriptor DV(N);
if (!DV.isVariable())
OS << " [vector]";
if (isStaticMember())
OS << " [static]";
+
+ if (isLValueReference())
+ OS << " [reference]";
+
+ if (isRValueReference())
+ OS << " [rvalue reference]";
}
void DIDerivedType::printInternal(raw_ostream &OS) const {
else if (isProtected())
OS << " [protected]";
+ if (isLValueReference())
+ OS << " [reference]";
+
+ if (isRValueReference())
+ OS << " [rvalue reference]";
+
StringRef Res = getName();
if (!Res.empty())
OS << " [" << Res << ']';
template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const {
return DITypeRef(getField(DbgNode, Elt));
}
+
+/// Strip debug info in the module if it exists.
+/// To do this, we remove all calls to the debugger intrinsics and any named
+/// metadata for debugging. We also remove debug locations for instructions.
+/// Return true if module is modified.
+bool llvm::StripDebugInfo(Module &M) {
+
+ bool Changed = false;
+
+ // Remove all of the calls to the debugger intrinsics, and remove them from
+ // the module.
+ if (Function *Declare = M.getFunction("llvm.dbg.declare")) {
+ while (!Declare->use_empty()) {
+ CallInst *CI = cast<CallInst>(Declare->use_back());
+ CI->eraseFromParent();
+ }
+ Declare->eraseFromParent();
+ Changed = true;
+ }
+
+ if (Function *DbgVal = M.getFunction("llvm.dbg.value")) {
+ while (!DbgVal->use_empty()) {
+ CallInst *CI = cast<CallInst>(DbgVal->use_back());
+ CI->eraseFromParent();
+ }
+ DbgVal->eraseFromParent();
+ Changed = true;
+ }
+
+ for (Module::named_metadata_iterator NMI = M.named_metadata_begin(),
+ NME = M.named_metadata_end(); NMI != NME;) {
+ NamedMDNode *NMD = NMI;
+ ++NMI;
+ if (NMD->getName().startswith("llvm.dbg.")) {
+ NMD->eraseFromParent();
+ Changed = true;
+ }
+ }
+
+ 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());
+ }
+ }
+
+ return Changed;
+}
+
+/// Return Debug Info Metadata Version by checking module flags.
+unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
+ Value *Val = M.getModuleFlag("Debug Info Version");
+ if (!Val)
+ return 0;
+ return cast<ConstantInt>(Val)->getZExtValue();
+}