#include "llvm/Module.h"
#include "llvm/Analysis/SlotCalculator.h"
#include <algorithm>
-#include <hash_map>
-#include <strstream.h>
#include <assert.h>
ConstPoolBool *ConstPoolBool::True = new ConstPoolBool(true);
string ConstPoolArray::getStrValue() const {
string Result;
- strstream makeString;
// As a special case, print the array as a string if it is an array of
// ubytes or an array of sbytes with positive values.
//
- const Type* elType = cast<ArrayType>(this->getType())->getElementType();
- bool isString = (elType == Type::SByteTy || elType == Type::UByteTy)
- && Operands.size() > 0;
+ const Type *ETy = cast<ArrayType>(getType())->getElementType();
+ bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy);
+ for (unsigned i = 0; i < Operands.size(); i++)
+ if (ETy == Type::SByteTy &&
+ cast<ConstPoolSInt>(Operands[i])->getValue() < 0) {
+ isString = false;
+ break;
+ }
+
if (isString) {
+ Result = "c\"";
for (unsigned i = 0; i < Operands.size(); i++) {
- if (elType == Type::SByteTy && cast<ConstPoolSInt>(Operands[i]) < 0)
- {
- isString = false;
- break;
- }
- // else it is a legal char and is safe to cast to an unsigned int
- uint64_t c = ((elType == Type::SByteTy)
- ? (uint64_t) cast<ConstPoolSInt>(Operands[i])->getValue()
- : cast<ConstPoolUInt>(Operands[i])->getValue());
- makeString << (char) c;
+ unsigned char C = (ETy == Type::SByteTy) ?
+ (unsigned char)cast<ConstPoolSInt>(Operands[i])->getValue() :
+ (unsigned char)cast<ConstPoolUInt>(Operands[i])->getValue();
+
+ if (isprint(C)) {
+ Result += C;
+ } else {
+ Result += '\\';
+ Result += (C/16)+'0';
+ Result += (C&15)+'0';
+ }
}
- }
-
- if (isString) {
- makeString << ends;
- Result = "c\"";
- Result += makeString.str();
Result += "\"";
- free(makeString.str());
+
} else {
Result = "[";
if (Operands.size()) {
//---- ConstPoolArray::get() implementation...
//
static ValueMap<vector<ConstPoolVal*>, ConstPoolArray> ArrayConstants;
-static hash_map<const char*, ConstPoolArray*> StringConstants;
ConstPoolArray *ConstPoolArray::get(const ArrayType *Ty,
const vector<ConstPoolVal*> &V) {
return Result;
}
-ConstPoolArray *ConstPoolArray::get(const string& stringConstant) {
- ConstPoolArray *Result = StringConstants[stringConstant.c_str()];
- if (Result == NULL) {
- ArrayType *aty = ArrayType::get(Type::UByteTy/*,stringConstant.length()*/);
- vector<ConstPoolVal*> charVals;
- for (const char *c = stringConstant.c_str(); *c; ++c) {
- if (isprint(*c))
- charVals.push_back(ConstPoolUInt::get(Type::UByteTy, *c));
- else {
- char charString[3];
- sprintf(charString, "\\%02X", *c);
- charVals.push_back(ConstPoolUInt::get(Type::UByteTy, charString[0]));
- charVals.push_back(ConstPoolUInt::get(Type::UByteTy, charString[1]));
- charVals.push_back(ConstPoolUInt::get(Type::UByteTy, charString[2]));
- }
- }
-
- // Append "\00" which is the null character in LLVM
- charVals.push_back(ConstPoolUInt::get(Type::UByteTy, '\\'));
- charVals.push_back(ConstPoolUInt::get(Type::UByteTy, '0'));
- charVals.push_back(ConstPoolUInt::get(Type::UByteTy, '0'));
-
- Result = ConstPoolArray::get(aty, charVals);
- StringConstants[stringConstant.c_str()] = Result;
- }
- return Result;
+// ConstPoolArray::get(const string&) - Return an array that is initialized to
+// contain the specified string. A null terminator is added to the specified
+// string so that it may be used in a natural way...
+//
+ConstPoolArray *ConstPoolArray::get(const string &Str) {
+ vector<ConstPoolVal*> ElementVals;
+
+ for (unsigned i = 0; i < Str.length(); ++i)
+ ElementVals.push_back(ConstPoolUInt::get(Type::UByteTy, Str[i]));
+
+ // Add a null terminator to the string...
+ ElementVals.push_back(ConstPoolUInt::get(Type::UByteTy, 0));
+
+ ArrayType *ATy = ArrayType::get(Type::UByteTy/*,stringConstant.length()*/);
+ return ConstPoolArray::get(ATy, ElementVals);
}