}
+static void setValueNameInternal(Value *V, const std::string &Name,
+ SymbolTable &ST) {
+ if (V->getType() == Type::VoidTy)
+ ThrowException("Can't assign name '" + Name + "' to value with void type!");
+
+ // Set the name
+ V->setName(Name, &ST);
+
+ // If we're in function scope
+ if (inFunctionScope()) {
+ // Look up the symbol in the Function's local symboltable
+ Value *Existing = CurFun.LocalSymtab.lookup(V->getType(),Name);
+
+ // If it already exists, bail out. We have to recheck this, because there
+ // may be entries inserted into the current basic block (which has not yet
+ // been inserted into the function) which collide.
+ if (Existing) {
+ ThrowException("Redefinition of value named '" + Name + "' in the '" +
+ V->getType()->getDescription() + "' type plane!");
+ } else {
+ // otherwise, since it doesn't exist, insert it.
+ CurFun.LocalSymtab.insert(V);
+ }
+ }
+}
+
// setValueName - Set the specified value to the name given. The name may be
// null potentially, in which case this is a noop. The string passed in is
-// assumed to be a malloc'd string buffer, and is freed by this function.
+// assumed to be a malloc'd string buffer, and is free'd by this function.
+//
+static void setValueName(Value *V, char *NameStr) {
+ if (NameStr) {
+ std::string Name(NameStr); // Copy string
+ free(NameStr); // Free old string
+
+ assert(inFunctionScope() && "Must be in function scope!");
+ SymbolTable &ST = CurFun.CurrentFunction->getSymbolTable();
+ if (ST.lookup(V->getType(), Name))
+ ThrowException("Redefinition of value named '" + Name + "' in the '" +
+ V->getType()->getDescription() + "' type plane!");
+
+ setValueNameInternal(V, Name, ST);
+ }
+}
+
+// setValueNameMergingDuplicates - Set the specified value to the name given.
+// The name may be null potentially, in which case this is a noop. The string
+// passed in is assumed to be a malloc'd string buffer, and is free'd by this
+// function.
//
// This function returns true if the value has already been defined, but is
// allowed to be redefined in the specified context. If the name is a new name
// for the typeplane, false is returned.
//
-static bool setValueName(Value *V, char *NameStr) {
+static bool setValueNameMergingDuplicates(Value *V, char *NameStr) {
if (NameStr == 0) return false;
-
+
std::string Name(NameStr); // Copy string
free(NameStr); // Free old string
- if (V->getType() == Type::VoidTy)
- ThrowException("Can't assign name '" + Name +
- "' to a null valued instruction!");
-
+ // FIXME: If we eliminated the function constant pool (which we should), this
+ // would just unconditionally look at the module symtab.
SymbolTable &ST = inFunctionScope() ?
CurFun.CurrentFunction->getSymbolTable() :
CurModule.CurrentModule->getSymbolTable();
Value *Existing = ST.lookup(V->getType(), Name);
-
if (Existing) { // Inserting a name that is already defined???
- // We are a simple redefinition of a value, check to see if it
- // is defined the same as the old one...
- if (const Constant *C = dyn_cast<Constant>(Existing)) {
- if (C == V) return true; // Constants are equal to themselves
- } else if (GlobalVariable *EGV = dyn_cast<GlobalVariable>(Existing)) {
+ // We are a simple redefinition of a value, check to see if it is defined
+ // the same as the old one...
+ if (GlobalVariable *EGV = dyn_cast<GlobalVariable>(Existing)) {
// We are allowed to redefine a global variable in two circumstances:
// 1. If at least one of the globals is uninitialized or
// 2. If both initializers have the same value.
return true; // They are equivalent!
}
}
+ } else if (const Constant *C = dyn_cast<Constant>(Existing)) {
+ if (C == V) return true; // Constants are equal to themselves
}
ThrowException("Redefinition of value named '" + Name + "' in the '" +
V->getType()->getDescription() + "' type plane!");
}
-
- // Set the name
- V->setName(Name, &ST);
-
- // If we're in function scope
- if (inFunctionScope()) {
- // Look up the symbol in the function's local symboltable
- Existing = CurFun.LocalSymtab.lookup(V->getType(),Name);
-
- // If it already exists
- if (Existing) {
- // Bail
- ThrowException("Redefinition of value named '" + Name + "' in the '" +
- V->getType()->getDescription() + "' type plane!");
-
- // otherwise, since it doesn't exist
- } else {
- // Insert it.
- CurFun.LocalSymtab.insert(V);
- }
- }
+
+ setValueNameInternal(V, Name, ST);
return false;
}
+
+
// setTypeName - Set the specified type to the name given. The name may be
// null potentially, in which case this is a noop. The string passed in is
// assumed to be a malloc'd string buffer, and is freed by this function.
// ConstPool - Constants with optional names assigned to them.
ConstPool : ConstPool OptAssign CONST ConstVal {
- if (!setValueName($4, $2))
+ // FIXME: THIS SHOULD REALLY BE ELIMINATED. It is totally unneeded.
+ if (!setValueNameMergingDuplicates($4, $2))
InsertValue($4);
}
| ConstPool OptAssign TYPE TypesV { // Types can be defined in the const pool
ThrowException("Global value initializer is not a constant!");
GlobalVariable *GV = new GlobalVariable(Ty, $4, $3, Initializer);
- if (!setValueName(GV, $2)) { // If not redefining...
+ if (!setValueNameMergingDuplicates(GV, $2)) { // If not redefining...
CurModule.CurrentModule->getGlobalList().push_back(GV);
int Slot = InsertValue(GV, CurModule.Values);
const Type *Ty = *$5;
// Global declarations appear in Constant Pool
GlobalVariable *GV = new GlobalVariable(Ty,$4,GlobalValue::ExternalLinkage);
- if (!setValueName(GV, $2)) { // If not redefining...
+ if (!setValueNameMergingDuplicates(GV, $2)) { // If not redefining...
CurModule.CurrentModule->getGlobalList().push_back(GV);
int Slot = InsertValue(GV, CurModule.Values);
I != $4->end(); ++I, ++ArgIt) {
delete I->first; // Delete the typeholder...
- if (setValueName(ArgIt, I->second)) // Insert arg into symtab...
- assert(0 && "No arg redef allowed!");
-
+ setValueName(ArgIt, I->second); // Insert arg into symtab...
InsertValue(ArgIt);
}
};
BasicBlockList : BasicBlockList BasicBlock {
- ($$ = $1)->getBasicBlockList().push_back($2);
+ $$ = $1;
}
| FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks
- ($$ = $1)->getBasicBlockList().push_back($2);
+ $$ = $1;
};
// br, br/cc, switch, ret
//
BasicBlock : InstructionList OptAssign BBTerminatorInst {
- if (setValueName($3, $2)) { assert(0 && "No redefn allowed!"); }
+ setValueName($3, $2);
InsertValue($3);
$1->getInstList().push_back($3);
$$ = $1;
}
| LABELSTR InstructionList OptAssign BBTerminatorInst {
- if (setValueName($4, $3)) { assert(0 && "No redefn allowed!"); }
+ setValueName($4, $3);
InsertValue($4);
$2->getInstList().push_back($4);
- if (setValueName($2, $1)) { assert(0 && "No label redef allowed!"); }
+ setValueName($2, $1);
InsertValue($2);
$$ = $2;
$$ = $1;
}
| /* empty */ {
- $$ = CurBB = new BasicBlock();
+ $$ = CurBB = new BasicBlock("", CurFun.CurrentFunction);
};
BBTerminatorInst : RET ResolvedVal { // Return with a result...
Inst : OptAssign InstVal {
// Is this definition named?? if so, assign the name...
- if (setValueName($2, $1)) { assert(0 && "No redefin allowed!"); }
+ setValueName($2, $1);
InsertValue($2);
$$ = $2;
};