aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2004-05-26 21:48:31 +0000
committerReid Spencer <rspencer@reidspencer.com>2004-05-26 21:48:31 +0000
commit75719bf239dcb122f5bfa049e3103ea703e8262a (patch)
tree9e203cc3747650719a383c510673a2fcdd2efd3a /lib
parent9b41dcfa60b9fe436ee68bcd5a9e401f58aac872 (diff)
downloadexternal_llvm-75719bf239dcb122f5bfa049e3103ea703e8262a.zip
external_llvm-75719bf239dcb122f5bfa049e3103ea703e8262a.tar.gz
external_llvm-75719bf239dcb122f5bfa049e3103ea703e8262a.tar.bz2
Provide the correct patch for bug 345. The solution is to add a setTypeName
function to llvmAsmParser.y and then use it in the one place in the grammar that needs it. Also had to make Type::setName public because setTypeName needs it in order to retain compatibility with setValueName. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13795 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AsmParser/llvmAsmParser.y75
1 files changed, 68 insertions, 7 deletions
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index a5a844b..dfdb398 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -502,6 +502,7 @@ static void ResolveTypes(std::map<ValID, PATypeHolder> &LateResolveTypes) {
// for the typeplane, false is returned.
//
static bool setValueName(Value *V, char *NameStr) {
+ assert(!isa<Type>(V) && "Can't set name of a Type with setValueName");
if (NameStr == 0) return false;
std::string Name(NameStr); // Copy string
@@ -515,12 +516,7 @@ static bool setValueName(Value *V, char *NameStr) {
CurFun.CurrentFunction->getSymbolTable() :
CurModule.CurrentModule->getSymbolTable();
- Value *Existing;
- // FIXME: this is really gross
- if (V->getType() != Type::TypeTy)
- Existing = ST.lookup(V->getType(), Name);
- else
- Existing = ST.lookupType(Name);
+ Value *Existing = ST.lookup(V->getType(), Name);
if (Existing) { // Inserting a name that is already defined???
// There is only one case where this is allowed: when we are refining an
@@ -591,6 +587,71 @@ static bool setValueName(Value *V, char *NameStr) {
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.
+//
+// This function returns true if the type has already been defined, but is
+// allowed to be redefined in the specified context. If the name is a new name
+// for the type plane, it is inserted and false is returned.
+static bool setTypeName(Type *T, char *NameStr) {
+ if (NameStr == 0) return false;
+
+ std::string Name(NameStr); // Copy string
+ free(NameStr); // Free old string
+
+ // We don't allow assigning names to void type
+ if (T == Type::VoidTy)
+ ThrowException("Can't assign name '" + Name + "' to the null type!");
+
+ SymbolTable &ST = inFunctionScope() ?
+ CurFun.CurrentFunction->getSymbolTable() :
+ CurModule.CurrentModule->getSymbolTable();
+
+ Type *Existing = ST.lookupType(Name);
+
+ if (Existing) { // Inserting a name that is already defined???
+ // There is only one case where this is allowed: when we are refining an
+ // opaque type. In this case, Existing will be an opaque type.
+ if (const OpaqueType *OpTy = dyn_cast<OpaqueType>(Existing)) {
+ // We ARE replacing an opaque type!
+ ((OpaqueType*)OpTy)->refineAbstractTypeTo(T);
+ return true;
+ }
+
+ // Otherwise, this is an attempt to redefine a type. That's okay if
+ // the redefinition is identical to the original. This will be so if
+ // Existing and T point to the same Type object. In this one case we
+ // allow the equivalent redefinition.
+ if (Existing == T) return true; // Yes, it's equal.
+
+ // Any other kind of (non-equivalent) redefinition is an error.
+ ThrowException("Redefinition of type named '" + Name + "' in the '" +
+ T->getDescription() + "' type plane!");
+ }
+
+ // Okay, its a newly named type. Set its name.
+ T->setName(Name,&ST);
+
+ // If we're in function scope
+ if (inFunctionScope()) {
+ // Look up the symbol in the function's local symboltable
+ Existing = CurFun.LocalSymtab.lookupType(Name);
+
+ // If it already exists
+ if (Existing) {
+ // Bail
+ ThrowException("Redefinition of type named '" + Name + "' in the '" +
+ T->getDescription() + "' type plane in function scope!");
+
+ // otherwise, since it doesn't exist
+ } else {
+ // Insert it.
+ CurFun.LocalSymtab.insert(Name,T);
+ }
+ }
+ return false;
+}
//===----------------------------------------------------------------------===//
// Code for handling upreferences in type names...
@@ -1352,7 +1413,7 @@ ConstPool : ConstPool OptAssign CONST ConstVal {
ResolveTypeTo($2, $4->get());
// TODO: FIXME when Type are not const
- if (!setValueName(const_cast<Type*>($4->get()), $2)) {
+ if (!setTypeName(const_cast<Type*>($4->get()), $2)) {
// If this is not a redefinition of a type...
if (!$2) {
InsertType($4->get(),