- /// Apply - Set the value of each of the fields.
- ///
- virtual void Apply(int &Field) {
- Elements.push_back(ConstantInt::get(Type::Int32Ty, int32_t(Field)));
- }
- virtual void Apply(unsigned &Field) {
- Elements.push_back(ConstantInt::get(Type::Int32Ty, uint32_t(Field)));
- }
- virtual void Apply(int64_t &Field) {
- Elements.push_back(ConstantInt::get(Type::Int64Ty, int64_t(Field)));
- }
- virtual void Apply(uint64_t &Field) {
- Elements.push_back(ConstantInt::get(Type::Int64Ty, uint64_t(Field)));
- }
- virtual void Apply(bool &Field) {
- Elements.push_back(ConstantInt::get(Type::Int1Ty, Field));
- }
- virtual void Apply(std::string &Field) {
- Elements.push_back(SR.getString(Field));
- }
- virtual void Apply(DebugInfoDesc *&Field) {
- GlobalVariable *GV = NULL;
-
- // If non-NULL then convert to global.
- if (Field) GV = SR.Serialize(Field);
-
- // FIXME - At some point should use specific type.
- const PointerType *EmptyTy = SR.getEmptyStructPtrType();
-
- if (GV) {
- // Set to pointer to global.
- Elements.push_back(ConstantExpr::getBitCast(GV, EmptyTy));
- } else {
- // Use NULL.
- Elements.push_back(ConstantPointerNull::get(EmptyTy));
- }
- }
- virtual void Apply(GlobalVariable *&Field) {
- const PointerType *EmptyTy = SR.getEmptyStructPtrType();
- if (Field) {
- Elements.push_back(ConstantExpr::getBitCast(Field, EmptyTy));
- } else {
- Elements.push_back(ConstantPointerNull::get(EmptyTy));
- }
- }
- virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
- const PointerType *EmptyTy = SR.getEmptyStructPtrType();
- unsigned N = Field.size();
- ArrayType *AT = ArrayType::get(EmptyTy, N);
- std::vector<Constant *> ArrayElements;
-
- for (unsigned i = 0, N = Field.size(); i < N; ++i) {
- if (DebugInfoDesc *Element = Field[i]) {
- GlobalVariable *GVE = SR.Serialize(Element);
- Constant *CE = ConstantExpr::getBitCast(GVE, EmptyTy);
- ArrayElements.push_back(cast<Constant>(CE));
- } else {
- ArrayElements.push_back(ConstantPointerNull::get(EmptyTy));
- }
- }
-
- Constant *CA = ConstantArray::get(AT, ArrayElements);
- GlobalVariable *CAGV = new GlobalVariable(AT, true,
- GlobalValue::InternalLinkage,
- CA, "llvm.dbg.array",
- SR.getModule());
- CAGV->setSection("llvm.metadata");
- Constant *CAE = ConstantExpr::getBitCast(CAGV, EmptyTy);
- Elements.push_back(CAE);
- }
-};
-
-//===----------------------------------------------------------------------===//
-/// DIGetTypesVisitor - This DIVisitor gathers all the field types in
-/// the supplied DebugInfoDesc.
-class DIGetTypesVisitor : public DIVisitor {
-private:
- DISerializer &SR; // Active serializer.
- std::vector<const Type*> &Fields; // Type accumulator.
-
-public:
- DIGetTypesVisitor(DISerializer &S, std::vector<const Type*> &F)
- : DIVisitor()
- , SR(S)
- , Fields(F)
- {}
-
- /// Apply - Set the value of each of the fields.
- ///
- virtual void Apply(int &Field) {
- Fields.push_back(Type::Int32Ty);
- }
- virtual void Apply(unsigned &Field) {
- Fields.push_back(Type::Int32Ty);
- }
- virtual void Apply(int64_t &Field) {
- Fields.push_back(Type::Int64Ty);
- }
- virtual void Apply(uint64_t &Field) {
- Fields.push_back(Type::Int64Ty);
- }
- virtual void Apply(bool &Field) {
- Fields.push_back(Type::Int1Ty);
- }
- virtual void Apply(std::string &Field) {
- Fields.push_back(SR.getStrPtrType());
- }
- virtual void Apply(DebugInfoDesc *&Field) {
- // FIXME - At some point should use specific type.
- const PointerType *EmptyTy = SR.getEmptyStructPtrType();
- Fields.push_back(EmptyTy);
- }
- virtual void Apply(GlobalVariable *&Field) {
- const PointerType *EmptyTy = SR.getEmptyStructPtrType();
- Fields.push_back(EmptyTy);
- }
- virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
- const PointerType *EmptyTy = SR.getEmptyStructPtrType();
- Fields.push_back(EmptyTy);
- }
-};
-
-//===----------------------------------------------------------------------===//
-/// DIVerifyVisitor - This DIVisitor verifies all the field types against
-/// a constant initializer.
-class DIVerifyVisitor : public DIVisitor {
-private:
- DIVerifier &VR; // Active verifier.
- bool IsValid; // Validity status.
- unsigned I; // Current operand index.
- ConstantStruct *CI; // GlobalVariable constant initializer.
-
-public:
- DIVerifyVisitor(DIVerifier &V, GlobalVariable *GV)
- : DIVisitor()
- , VR(V)
- , IsValid(true)
- , I(0)
- , CI(cast<ConstantStruct>(GV->getInitializer()))
- {
- }
-
- // Accessors.
- bool isValid() const { return IsValid; }
-
- /// Apply - Set the value of each of the fields.
- ///
- virtual void Apply(int &Field) {
- Constant *C = CI->getOperand(I++);
- IsValid = IsValid && isa<ConstantInt>(C);
- }
- virtual void Apply(unsigned &Field) {
- Constant *C = CI->getOperand(I++);
- IsValid = IsValid && isa<ConstantInt>(C);
- }
- virtual void Apply(int64_t &Field) {
- Constant *C = CI->getOperand(I++);
- IsValid = IsValid && isa<ConstantInt>(C);
- }
- virtual void Apply(uint64_t &Field) {
- Constant *C = CI->getOperand(I++);
- IsValid = IsValid && isa<ConstantInt>(C);
- }
- virtual void Apply(bool &Field) {
- Constant *C = CI->getOperand(I++);
- IsValid = IsValid && isa<ConstantInt>(C) && C->getType() == Type::Int1Ty;
- }
- virtual void Apply(std::string &Field) {
- Constant *C = CI->getOperand(I++);
- IsValid = IsValid &&
- (!C || isStringValue(C) || C->isNullValue());
- }
- virtual void Apply(DebugInfoDesc *&Field) {
- // FIXME - Prepare the correct descriptor.
- Constant *C = CI->getOperand(I++);
- IsValid = IsValid && isGlobalVariable(C);
- }
- virtual void Apply(GlobalVariable *&Field) {
- Constant *C = CI->getOperand(I++);
- IsValid = IsValid && isGlobalVariable(C);
- }
- virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
- Constant *C = CI->getOperand(I++);
- IsValid = IsValid && isGlobalVariable(C);
- if (!IsValid) return;
-
- GlobalVariable *GV = getGlobalVariable(C);
- IsValid = IsValid && GV && GV->hasInitializer();
- if (!IsValid) return;
-
- ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer());
- IsValid = IsValid && CA;
- if (!IsValid) return;
-
- for (unsigned i = 0, N = CA->getNumOperands(); IsValid && i < N; ++i) {
- IsValid = IsValid && isGlobalVariable(CA->getOperand(i));
- if (!IsValid) return;
-
- GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i));
- VR.Verify(GVE);
- }
- }
-};
-
-}
-
-//===----------------------------------------------------------------------===//
-
-DebugInfoDesc *DIDeserializer::Deserialize(Value *V) {
- return Deserialize(getGlobalVariable(V));
-}
-DebugInfoDesc *DIDeserializer::Deserialize(GlobalVariable *GV) {
- // Handle NULL.
- if (!GV) return NULL;
-
- // Check to see if it has been already deserialized.
- DebugInfoDesc *&Slot = GlobalDescs[GV];
- if (Slot) return Slot;
-
- // Get the Tag from the global.
- unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
-
- // Create an empty instance of the correct sort.
- Slot = DebugInfoDesc::DescFactory(Tag);
-
- // If not a user defined descriptor.
- if (Slot) {
- // Deserialize the fields.
- DIDeserializeVisitor DRAM(*this, GV);
- DRAM.ApplyToFields(Slot);
- }
-
- return Slot;
-}
-
-//===----------------------------------------------------------------------===//
-
-/// getStrPtrType - Return a "sbyte *" type.
-///
-const PointerType *DISerializer::getStrPtrType() {
- // If not already defined.
- if (!StrPtrTy) {
- // Construct the pointer to signed bytes.
- StrPtrTy = PointerType::getUnqual(Type::Int8Ty);
- }
-
- return StrPtrTy;
-}
-
-/// getEmptyStructPtrType - Return a "{ }*" type.
-///
-const PointerType *DISerializer::getEmptyStructPtrType() {
- // If not already defined.
- if (EmptyStructPtrTy) return EmptyStructPtrTy;
-
- // Construct the pointer to empty structure type.
- const StructType *EmptyStructTy =
- StructType::get(std::vector<const Type*>());
-
- // Construct the pointer to empty structure type.
- EmptyStructPtrTy = PointerType::getUnqual(EmptyStructTy);
- return EmptyStructPtrTy;
-}
-
-/// getTagType - Return the type describing the specified descriptor (via tag.)
-///
-const StructType *DISerializer::getTagType(DebugInfoDesc *DD) {
- // Attempt to get the previously defined type.
- StructType *&Ty = TagTypes[DD->getTag()];
-
- // If not already defined.
- if (!Ty) {
- // Set up fields vector.
- std::vector<const Type*> Fields;
- // Get types of fields.
- DIGetTypesVisitor GTAM(*this, Fields);
- GTAM.ApplyToFields(DD);
-
- // Construct structured type.
- Ty = StructType::get(Fields);
-
- // Register type name with module.
- M->addTypeName(DD->getTypeString(), Ty);
- }
-
- return Ty;
-}
-
-/// getString - Construct the string as constant string global.
-///
-Constant *DISerializer::getString(const std::string &String) {
- // Check string cache for previous edition.
- Constant *&Slot = StringCache[String.c_str()];
-
- // Return Constant if previously defined.
- if (Slot) return Slot;
-
- // If empty string then use a sbyte* null instead.
- if (String.empty()) {
- Slot = ConstantPointerNull::get(getStrPtrType());
- } else {
- // Construct string as an llvm constant.
- Constant *ConstStr = ConstantArray::get(String);
-
- // Otherwise create and return a new string global.
- GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true,
- GlobalVariable::InternalLinkage,
- ConstStr, ".str", M);
- StrGV->setSection("llvm.metadata");
-
- // Convert to generic string pointer.
- Slot = ConstantExpr::getBitCast(StrGV, getStrPtrType());
- }
-
- return Slot;
-
-}
-
-/// Serialize - Recursively cast the specified descriptor into a GlobalVariable
-/// so that it can be serialized to a .bc or .ll file.
-GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) {
- // Check if the DebugInfoDesc is already in the map.
- GlobalVariable *&Slot = DescGlobals[DD];
-
- // See if DebugInfoDesc exists, if so return prior GlobalVariable.
- if (Slot) return Slot;
-
- // Get the type associated with the Tag.
- const StructType *Ty = getTagType(DD);
-
- // Create the GlobalVariable early to prevent infinite recursion.
- GlobalVariable *GV = new GlobalVariable(Ty, true, DD->getLinkage(),
- NULL, DD->getDescString(), M);
- GV->setSection("llvm.metadata");
-
- // Insert new GlobalVariable in DescGlobals map.
- Slot = GV;
-
- // Set up elements vector
- std::vector<Constant*> Elements;
- // Add fields.
- DISerializeVisitor SRAM(*this, Elements);
- SRAM.ApplyToFields(DD);
-
- // Set the globals initializer.
- GV->setInitializer(ConstantStruct::get(Ty, Elements));
-
- return GV;
-}
-
-/// addDescriptor - Directly connect DD with existing GV.
-void DISerializer::addDescriptor(DebugInfoDesc *DD,
- GlobalVariable *GV) {
- DescGlobals[DD] = GV;
-}
-
-//===----------------------------------------------------------------------===//
-
-/// Verify - Return true if the GlobalVariable appears to be a valid
-/// serialization of a DebugInfoDesc.
-bool DIVerifier::Verify(Value *V) {
- return !V || Verify(getGlobalVariable(V));
-}
-bool DIVerifier::Verify(GlobalVariable *GV) {
- // NULLs are valid.
- if (!GV) return true;
-
- // Check prior validity.
- unsigned &ValiditySlot = Validity[GV];
-
- // If visited before then use old state.
- if (ValiditySlot) return ValiditySlot == Valid;
-
- // Assume validity for the time being (recursion.)
- ValiditySlot = Valid;
-
- // Make sure the global is internal or link once (anchor.)
- if (GV->getLinkage() != GlobalValue::InternalLinkage &&
- GV->getLinkage() != GlobalValue::LinkOnceLinkage) {
- ValiditySlot = Invalid;
- return false;
- }
-
- // Get the Tag.
- unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
-
- // Check for user defined descriptors.
- if (Tag == DW_TAG_invalid) {
- ValiditySlot = Valid;
- return true;
- }
-
- // Get the Version.
- unsigned Version = DebugInfoDesc::VersionFromGlobal(GV);
-
- // Check for version mismatch.
- if (Version != LLVMDebugVersion) {
- ValiditySlot = Invalid;
- return false;
- }
-
- // Construct an empty DebugInfoDesc.
- DebugInfoDesc *DD = DebugInfoDesc::DescFactory(Tag);
-
- // Allow for user defined descriptors.
- if (!DD) return true;
-
- // Get the initializer constant.
- ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer());
-
- // Get the operand count.
- unsigned N = CI->getNumOperands();
-
- // Get the field count.
- unsigned &CountSlot = Counts[Tag];
- if (!CountSlot) {
- // Check the operand count to the field count
- DICountVisitor CTAM;
- CTAM.ApplyToFields(DD);
- CountSlot = CTAM.getCount();
- }
-
- // Field count must be at most equal operand count.
- if (CountSlot > N) {
- delete DD;
- ValiditySlot = Invalid;
- return false;
- }
-
- // Check each field for valid type.
- DIVerifyVisitor VRAM(*this, GV);
- VRAM.ApplyToFields(DD);
-
- // Release empty DebugInfoDesc.
- delete DD;
-
- // If fields are not valid.
- if (!VRAM.isValid()) {
- ValiditySlot = Invalid;
- return false;
- }
-
- return true;
-}
-
-/// isVerified - Return true if the specified GV has already been
-/// verified as a debug information descriptor.
-bool DIVerifier::isVerified(GlobalVariable *GV) {
- unsigned &ValiditySlot = Validity[GV];
- if (ValiditySlot) return ValiditySlot == Valid;
- return false;
-}
-
-//===----------------------------------------------------------------------===//
-
-DebugScope::~DebugScope() {
- for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i];
- for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j];
-}
-
-//===----------------------------------------------------------------------===//
-