[llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y

Reid Spencer reid at x10sys.com
Tue Jan 2 13:53:59 PST 2007



Changes in directory llvm/lib/AsmParser:

llvmAsmParser.y updated: 1.295 -> 1.296
---
Log message:

Implement checking for unresolved types in the argument types and result 
type of function definitions. 
This fixes test/Regression/Assember/2007-01-02-Undefined-Arg-Type.ll


---
Diffs of the changes:  (+59 -0)

 llvmAsmParser.y |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 59 insertions(+)


Index: llvm/lib/AsmParser/llvmAsmParser.y
diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.295 llvm/lib/AsmParser/llvmAsmParser.y:1.296
--- llvm/lib/AsmParser/llvmAsmParser.y:1.295	Sun Dec 31 15:46:36 2006
+++ llvm/lib/AsmParser/llvmAsmParser.y	Tue Jan  2 15:53:43 2007
@@ -149,6 +149,58 @@
     }
     return Ret;
   }
+
+  bool TypeIsUnresolved(PATypeHolder* PATy) {
+    // If it isn't abstract, its resolved
+    const Type* Ty = PATy->get();
+    if (!Ty->isAbstract())
+      return false;
+    // Traverse the type looking for abstract types. If it isn't abstract then
+    // we don't need to traverse that leg of the type. 
+    std::vector<const Type*> WorkList, SeenList;
+    WorkList.push_back(Ty);
+    while (!WorkList.empty()) {
+      const Type* Ty = WorkList.back();
+      SeenList.push_back(Ty);
+      WorkList.pop_back();
+      if (const OpaqueType* OpTy = dyn_cast<OpaqueType>(Ty)) {
+        // Check to see if this is an unresolved type
+        std::map<ValID, PATypeHolder>::iterator I = LateResolveTypes.begin();
+        std::map<ValID, PATypeHolder>::iterator E = LateResolveTypes.end();
+        for ( ; I != E; ++I) {
+          if (I->second.get() == OpTy)
+            return true;
+        }
+      } else if (const SequentialType* SeqTy = dyn_cast<SequentialType>(Ty)) {
+        const Type* TheTy = SeqTy->getElementType();
+        if (TheTy->isAbstract() && TheTy != Ty) {
+          std::vector<const Type*>::iterator I = SeenList.begin(), 
+                                             E = SeenList.end();
+          for ( ; I != E; ++I)
+            if (*I == TheTy)
+              break;
+          if (I == E)
+            WorkList.push_back(TheTy);
+        }
+      } else if (const StructType* StrTy = dyn_cast<StructType>(Ty)) {
+        for (unsigned i = 0; i < StrTy->getNumElements(); ++i) {
+          const Type* TheTy = StrTy->getElementType(i);
+          if (TheTy->isAbstract() && TheTy != Ty) {
+            std::vector<const Type*>::iterator I = SeenList.begin(), 
+                                               E = SeenList.end();
+            for ( ; I != E; ++I)
+              if (*I == TheTy)
+                break;
+            if (I == E)
+              WorkList.push_back(TheTy);
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+
 } CurModule;
 
 static struct PerFunctionInfo {
@@ -1943,12 +1995,19 @@
   std::string FunctionName($3);
   free($3);  // Free strdup'd memory!
   
+  // Check the function result for abstractness if this is a define. We should
+  // have no abstract types at this point
+  if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($2.Ty))
+    GEN_ERROR("Reference to abstract result: "+ $2.Ty->get()->getDescription());
+
   std::vector<const Type*> ParamTypeList;
   std::vector<FunctionType::ParameterAttributes> ParamAttrs;
   ParamAttrs.push_back($2.Attrs);
   if ($5) {   // If there are arguments...
     for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I) {
       const Type* Ty = I->Ty->get();
+      if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty))
+        GEN_ERROR("Reference to abstract argument: " + Ty->getDescription());
       ParamTypeList.push_back(Ty);
       if (Ty != Type::VoidTy)
         ParamAttrs.push_back(I->Attrs);






More information about the llvm-commits mailing list