public void AddLabel (string name, LabeledStatement label)
{
if (labels == null)
labels = new Dictionary<string, object> ();
object value;
if (!labels.TryGetValue (name, out value)) {
labels.Add (name, label);
return;
}
LabeledStatement existing = value as LabeledStatement;
List<LabeledStatement> existing_list;
if (existing != null) {
existing_list = new List<LabeledStatement> ();
existing_list.Add (existing);
labels[name] = existing_list;
} else {
existing_list = (List<LabeledStatement>) value;
}
//
// A collision checking between labels
//
for (int i = 0; i < existing_list.Count; ++i) {
existing = existing_list[i];
Block b = existing.Block;
// Collision at same level
if (label.Block == b) {
Report.SymbolRelatedToPreviousError (existing.loc, name);
Report.Error (140, label.loc, "The label `{0}' is a duplicate", name);
break;
}
// Collision with parent
b = label.Block;
while ((b = b.Parent) != null) {
if (existing.Block == b) {
Report.Error (158, label.loc,
"The label `{0}' shadows another label by the same name in a contained scope", name);
i = existing_list.Count;
break;
}
}
// Collision with with children
b = existing.Block;
while ((b = b.Parent) != null) {
if (label.Block == b) {
Report.Error (158, label.loc,
"The label `{0}' shadows another label by the same name in a contained scope", name);
i = existing_list.Count;
break;
}
}
}
existing_list.Add (label);
}