Provide the correct patch for bug 345. The solution is to add a setTypeName
authorReid Spencer <rspencer@reidspencer.com>
Wed, 26 May 2004 21:48:31 +0000 (21:48 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Wed, 26 May 2004 21:48:31 +0000 (21:48 +0000)
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

include/llvm/Type.h
lib/AsmParser/llvmAsmParser.y

index 140b56445fbd6555bcade2f0fcbf625f00e3ac83..f35506b319d875f85f588b562c34005a5ed18313 100644 (file)
@@ -96,10 +96,6 @@ protected:
   Type(const std::string &Name, PrimitiveID id);
   virtual ~Type() {}
 
-  /// setName - Associate the name with this type in the symbol table, but don't
-  /// set the local name to be equal specified name.
-  ///
-  virtual void setName(const std::string &Name, SymbolTable *ST = 0);
 
   /// Types can become nonabstract later, if they are refined.
   ///
@@ -131,6 +127,11 @@ public:
   /// @brief Debugging support: print to stderr
   virtual void dump() const;
 
+  /// setName - Associate the name with this type in the symbol table, but don't
+  /// set the local name to be equal specified name.
+  ///
+  virtual void setName(const std::string &Name, SymbolTable *ST = 0);
+
   //===--------------------------------------------------------------------===//
   // Property accessors for dealing with types... Some of these virtual methods
   // are defined in private classes defined in Type.cpp for primitive types.
index a5a844b1d8e3691b733af4e407ecc03be850ccec..dfdb398f44ae56376655a81953aa3672eaaed4ef 100644 (file)
@@ -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(),