summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Constant.h7
-rw-r--r--include/llvm/Constants.h16
-rw-r--r--lib/VMCore/Constants.cpp49
3 files changed, 56 insertions, 16 deletions
diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h
index 3ce8d2c243..f7d4dd2d32 100644
--- a/include/llvm/Constant.h
+++ b/include/llvm/Constant.h
@@ -97,6 +97,13 @@ public:
/// constant exprs and other cases we can't handle, we return an empty vector.
void getVectorElements(SmallVectorImpl<Constant*> &Elts) const;
+ /// getAggregateElement - For aggregates (struct/array/vector) return the
+ /// constant that corresponds to the specified element if possible, or null if
+ /// not. This can return null if the element index is a ConstantExpr, or if
+ /// 'this' is a constant expr.
+ Constant *getAggregateElement(unsigned Elt) const;
+ Constant *getAggregateElement(Constant *Elt) const;
+
/// destroyConstant - Called if some element of this constant is no longer
/// valid. At this point only other constants may be on the use_list for this
/// constant. Any constants on our Use list must also be destroy'd. The
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index 1823f1d49e..a685ccc31c 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -316,19 +316,19 @@ public:
/// getSequentialElement - If this CAZ has array or vector type, return a zero
/// with the right element type.
- Constant *getSequentialElement();
+ Constant *getSequentialElement() const;
/// getStructElement - If this CAZ has struct type, return a zero with the
/// right element type for the specified element.
- Constant *getStructElement(unsigned Elt);
+ Constant *getStructElement(unsigned Elt) const;
/// getElementValue - Return a zero of the right value for the specified GEP
/// index.
- Constant *getElementValue(Constant *C);
+ Constant *getElementValue(Constant *C) const;
/// getElementValue - Return a zero of the right value for the specified GEP
/// index.
- Constant *getElementValue(unsigned Idx);
+ Constant *getElementValue(unsigned Idx) const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
///
@@ -1157,19 +1157,19 @@ public:
/// getSequentialElement - If this Undef has array or vector type, return a
/// undef with the right element type.
- UndefValue *getSequentialElement();
+ UndefValue *getSequentialElement() const;
/// getStructElement - If this undef has struct type, return a undef with the
/// right element type for the specified element.
- UndefValue *getStructElement(unsigned Elt);
+ UndefValue *getStructElement(unsigned Elt) const;
/// getElementValue - Return an undef of the right value for the specified GEP
/// index.
- UndefValue *getElementValue(Constant *C);
+ UndefValue *getElementValue(Constant *C) const;
/// getElementValue - Return an undef of the right value for the specified GEP
/// index.
- UndefValue *getElementValue(unsigned Idx);
+ UndefValue *getElementValue(unsigned Idx) const;
virtual void destroyConstant();
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index dd13ace600..08b1818d75 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -150,6 +150,39 @@ Constant *Constant::getAllOnesValue(Type *Ty) {
getAllOnesValue(VTy->getElementType()));
}
+/// getAggregateElement - For aggregates (struct/array/vector) return the
+/// constant that corresponds to the specified element if possible, or null if
+/// not. This can return null if the element index is a ConstantExpr, or if
+/// 'this' is a constant expr.
+Constant *Constant::getAggregateElement(unsigned Elt) const {
+ if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(this))
+ return Elt < CS->getNumOperands() ? CS->getOperand(Elt) : 0;
+
+ if (const ConstantArray *CA = dyn_cast<ConstantArray>(this))
+ return Elt < CA->getNumOperands() ? CA->getOperand(Elt) : 0;
+
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
+ return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : 0;
+
+ if (const ConstantAggregateZero *CAZ =dyn_cast<ConstantAggregateZero>(this))
+ return CAZ->getElementValue(Elt);
+
+ if (const UndefValue *UV = dyn_cast<UndefValue>(this))
+ return UV->getElementValue(Elt);
+
+ if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(this))
+ return CDS->getElementAsConstant(Elt);
+ return 0;
+}
+
+Constant *Constant::getAggregateElement(Constant *Elt) const {
+ assert(isa<IntegerType>(Elt->getType()) && "Index must be an integer");
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Elt))
+ return getAggregateElement(CI->getZExtValue());
+ return 0;
+}
+
+
void Constant::destroyConstantImpl() {
// When a Constant is destroyed, there may be lingering
// references to the constant by other constants in the constant pool. These
@@ -594,21 +627,21 @@ bool ConstantFP::isExactlyValue(const APFloat &V) const {
/// getSequentialElement - If this CAZ has array or vector type, return a zero
/// with the right element type.
-Constant *ConstantAggregateZero::getSequentialElement() {
+Constant *ConstantAggregateZero::getSequentialElement() const {
return Constant::getNullValue(
cast<SequentialType>(getType())->getElementType());
}
/// getStructElement - If this CAZ has struct type, return a zero with the
/// right element type for the specified element.
-Constant *ConstantAggregateZero::getStructElement(unsigned Elt) {
+Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const {
return Constant::getNullValue(
cast<StructType>(getType())->getElementType(Elt));
}
/// getElementValue - Return a zero of the right value for the specified GEP
/// index if we can, otherwise return null (e.g. if C is a ConstantExpr).
-Constant *ConstantAggregateZero::getElementValue(Constant *C) {
+Constant *ConstantAggregateZero::getElementValue(Constant *C) const {
if (isa<SequentialType>(getType()))
return getSequentialElement();
return getStructElement(cast<ConstantInt>(C)->getZExtValue());
@@ -616,7 +649,7 @@ Constant *ConstantAggregateZero::getElementValue(Constant *C) {
/// getElementValue - Return a zero of the right value for the specified GEP
/// index.
-Constant *ConstantAggregateZero::getElementValue(unsigned Idx) {
+Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {
if (isa<SequentialType>(getType()))
return getSequentialElement();
return getStructElement(Idx);
@@ -629,19 +662,19 @@ Constant *ConstantAggregateZero::getElementValue(unsigned Idx) {
/// getSequentialElement - If this undef has array or vector type, return an
/// undef with the right element type.
-UndefValue *UndefValue::getSequentialElement() {
+UndefValue *UndefValue::getSequentialElement() const {
return UndefValue::get(cast<SequentialType>(getType())->getElementType());
}
/// getStructElement - If this undef has struct type, return a zero with the
/// right element type for the specified element.
-UndefValue *UndefValue::getStructElement(unsigned Elt) {
+UndefValue *UndefValue::getStructElement(unsigned Elt) const {
return UndefValue::get(cast<StructType>(getType())->getElementType(Elt));
}
/// getElementValue - Return an undef of the right value for the specified GEP
/// index if we can, otherwise return null (e.g. if C is a ConstantExpr).
-UndefValue *UndefValue::getElementValue(Constant *C) {
+UndefValue *UndefValue::getElementValue(Constant *C) const {
if (isa<SequentialType>(getType()))
return getSequentialElement();
return getStructElement(cast<ConstantInt>(C)->getZExtValue());
@@ -649,7 +682,7 @@ UndefValue *UndefValue::getElementValue(Constant *C) {
/// getElementValue - Return an undef of the right value for the specified GEP
/// index.
-UndefValue *UndefValue::getElementValue(unsigned Idx) {
+UndefValue *UndefValue::getElementValue(unsigned Idx) const {
if (isa<SequentialType>(getType()))
return getSequentialElement();
return getStructElement(Idx);