#include "llvm/ADT/SmallString.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
return DbgNode &&
(DIDerivedType(DbgNode).Verify() ||
DICompositeType(DbgNode).Verify() || DIBasicType(DbgNode).Verify() ||
- DITrivialType(DbgNode).Verify() ||
DIVariable(DbgNode).Verify() || DISubprogram(DbgNode).Verify() ||
DIGlobalVariable(DbgNode).Verify() || DIFile(DbgNode).Verify() ||
DICompileUnit(DbgNode).Verify() || DINameSpace(DbgNode).Verify() ||
/// getInlinedAt - If this variable is inlined then return inline location.
MDNode *DIVariable::getInlinedAt() const { return getNodeField(DbgNode, 7); }
+bool DIVariable::isVariablePiece() const {
+ return hasComplexAddress() && getAddrElement(0) == DIBuilder::OpPiece;
+}
+
+uint64_t DIVariable::getPieceOffset() const {
+ assert(isVariablePiece());
+ return getAddrElement(1);
+}
+
+uint64_t DIVariable::getPieceSize() const {
+ assert(isVariablePiece());
+ return getAddrElement(2);
+}
+
+/// 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();
+}
+
+
+
+
//===----------------------------------------------------------------------===//
// Predicates
//===----------------------------------------------------------------------===//
-bool DIDescriptor::isTrivialType() const {
- return DbgNode && getTag() == dwarf::DW_TAG_unspecified_parameters;
-}
-
bool DIDescriptor::isSubroutineType() const {
return isCompositeType() && getTag() == dwarf::DW_TAG_subroutine_type;
}
/// isType - Return true if the specified tag is legal for DIType.
bool DIDescriptor::isType() const {
- return isBasicType() || isCompositeType() || isDerivedType() ||
- isTrivialType();
+ return isBasicType() || isCompositeType() || isDerivedType();
}
/// isSubprogram - Return true if the specified tag is legal for
getTag() == dwarf::DW_TAG_constant);
}
-/// isUnspecifiedParmeter - Return true if the specified tag is
-/// DW_TAG_unspecified_parameters.
-bool DIDescriptor::isUnspecifiedParameter() const {
- return DbgNode && getTag() == dwarf::DW_TAG_unspecified_parameters;
-}
-
/// isScope - Return true if the specified tag is one of the scope
/// related tag.
bool DIDescriptor::isScope() const {
/// lexical block with an extra file.
bool DIDescriptor::isLexicalBlockFile() const {
return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
- (DbgNode->getNumOperands() == 3);
+ (DbgNode->getNumOperands() == 4);
}
/// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block.
// FIXME: Sink this into the various subclass verifies.
uint16_t Tag = getTag();
- if (!isBasicType() && !isTrivialType() && Tag != dwarf::DW_TAG_const_type &&
+ if (!isBasicType() && 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_inheritance && Tag != dwarf::DW_TAG_friend &&
getFilename().empty())
return false;
+
// DIType is abstract, it should be a BasicType, a DerivedType or
// a CompositeType.
if (isBasicType())
return DIBasicType(DbgNode).Verify();
- else if (isTrivialType())
- return DITrivialType(DbgNode).Verify();
else if (isCompositeType())
return DICompositeType(DbgNode).Verify();
else if (isDerivedType())
return isBasicType() && DbgNode->getNumOperands() == 10;
}
-bool DITrivialType::Verify() const {
- return isTrivialType() && DbgNode->getNumOperands() == 1;
-}
-
/// Verify - Verify that a derived type descriptor is well formed.
bool DIDerivedType::Verify() const {
// Make sure DerivedFrom @ field 9 is TypeRef.
/// \brief Verify that the lexical block descriptor is well formed.
bool DILexicalBlock::Verify() const {
- return isLexicalBlock() && DbgNode->getNumOperands() == 7;
+ return isLexicalBlock() && DbgNode->getNumOperands() == 6;
}
/// \brief Verify that the file-scoped lexical block descriptor is well formed.
bool DILexicalBlockFile::Verify() const {
- return isLexicalBlockFile() && DbgNode->getNumOperands() == 3;
+ return isLexicalBlockFile() && DbgNode->getNumOperands() == 4;
}
/// \brief Verify that the template type parameter descriptor is well formed.
/// copyWithNewScope - Return a copy of this location, replacing the
/// current scope with the given one.
DILocation DILocation::copyWithNewScope(LLVMContext &Ctx,
- DILexicalBlock NewScope) {
+ DILexicalBlockFile NewScope) {
SmallVector<Value *, 10> Elts;
assert(Verify());
for (unsigned I = 0; I < DbgNode->getNumOperands(); ++I) {
return DIVariable(MDNode::get(VMContext, Elts));
}
+
+/// getEntireVariable - Remove OpPiece exprs from the variable.
+DIVariable llvm::getEntireVariable(DIVariable DV) {
+ if (!DV.isVariablePiece())
+ return DV;
+
+ SmallVector<Value *, 8> Elts;
+ for (unsigned i = 0; i < 8; ++i)
+ Elts.push_back(DV->getOperand(i));
+
+ return DIVariable(MDNode::get(DV->getContext(), Elts));
+}
+
/// getDISubprogram - Find subprogram that is enclosing this scope.
DISubprogram llvm::getDISubprogram(const MDNode *Scope) {
DIDescriptor D(Scope);
}
void DIType::printInternal(raw_ostream &OS) const {
- if (!DbgNode || isTrivialType())
+ if (!DbgNode)
return;
StringRef Res = getName();
OS << " [private]";
else if (isProtected())
OS << " [protected]";
+ else if (isPublic())
+ OS << " [public]";
if (isArtificial())
OS << " [artificial]";
OS << " [private]";
else if (isProtected())
OS << " [protected]";
+ else if (isPublic())
+ OS << " [public]";
if (isLValueReference())
OS << " [reference]";
OS << " [" << Res << ']';
OS << " [line " << getLineNumber() << ']';
+
+ if (isVariablePiece())
+ OS << " [piece, size " << getPieceSize()
+ << ", offset " << getPieceOffset() << ']';
}
void DIObjCProperty::printInternal(raw_ostream &OS) const {