[llvm-branch-commits] [cfe-branch] r134788 - in /cfe/branches/type-system-rewrite/lib/CodeGen: CodeGenTypes.cpp CodeGenTypes.h

Chris Lattner sabre at nondot.org
Fri Jul 8 21:46:25 PDT 2011


Author: lattner
Date: Fri Jul  8 23:46:25 2011
New Revision: 134788

URL: http://llvm.org/viewvc/llvm-project?rev=134788&view=rev
Log:
don't infinitely recurse converting structure types.

Modified:
    cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenTypes.cpp
    cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenTypes.h

Modified: cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenTypes.cpp?rev=134788&r1=134787&r2=134788&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenTypes.cpp Fri Jul  8 23:46:25 2011
@@ -239,6 +239,7 @@
   }
   case Type::LValueReference:
   case Type::RValueReference: {
+    RecursionStatePointerRAII X(RecursionState);
     const ReferenceType &RTy = cast<ReferenceType>(Ty);
     QualType ETy = RTy.getPointeeType();
     llvm::Type *PointeeType = ConvertTypeForMem(ETy);
@@ -246,6 +247,7 @@
     return llvm::PointerType::get(PointeeType, AS);
   }
   case Type::Pointer: {
+    RecursionStatePointerRAII X(RecursionState);
     const PointerType &PTy = cast<PointerType>(Ty);
     QualType ETy = PTy.getPointeeType();
     llvm::Type *PointeeType = ConvertTypeForMem(ETy);
@@ -323,6 +325,7 @@
   }
 
   case Type::ObjCObjectPointer: {
+    RecursionStatePointerRAII X(RecursionState);
     // Protocol qualifications do not influence the LLVM type, we just return a
     // pointer to the underlying interface type. We don't need to worry about
     // recursive conversion.
@@ -343,6 +346,7 @@
   }
 
   case Type::BlockPointer: {
+    RecursionStatePointerRAII X(RecursionState);
     const QualType FTy = cast<BlockPointerType>(Ty).getPointeeType();
     llvm::Type *PointeeType = ConvertTypeForMem(FTy);
     unsigned AS = Context.getTargetAddressSpace(FTy);
@@ -359,30 +363,35 @@
 }
 
 /// ConvertRecordDeclType - Lay out a tagged decl type like struct or union.
-llvm::Type *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) {
-  
+llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) {
   // TagDecl's are not necessarily unique, instead use the (clang)
   // type connected to the decl.
-  QualType T = Context.getTagDeclType(RD);
-  const Type *Key = T.getTypePtr();
+  const Type *Key = Context.getTagDeclType(RD).getTypePtr();
 
-#if 0 
-  abort();
-#endif
-  
-  //std::string Name =
-  //std::string(RD->getKindName()) + "." + RD->getQualifiedNameAsString();
-  //llvm::StructType::createNamed(getLLVMContext(), Name);
+  llvm::StructType *&Entry = RecordDeclTypes[Key];
 
-  // Get the opaque LLVM type.
-  llvm::StructType *Ty = cast<llvm::StructType>(ConvertType(T));
+  // If we don't have a StructType at all yet, create the forward declaration.
+  if (Entry == 0)
+    Entry = llvm::StructType::createNamed(getLLVMContext(), 
+                                          std::string(RD->getKindName()) + "." +
+                                          RD->getQualifiedNameAsString());
+  llvm::StructType *Ty = Entry;
 
   // If this is still a forward declaration, or the LLVM type is already
   // complete, there's nothing more to do.
   if (!RD->isDefinition() || !Ty->isOpaque())
     return Ty;
+  
+  // If we're recursively nested inside the conversion of a pointer inside the
+  // struct, defer conversion.
+  if (RecursionState == RS_StructPointer) {
+    DeferredRecords.push_back(RD);
+    return Ty;
+  }
 
   // Okay, this is a definition of a type.  Compile the implementation now.
+  RecursionStateTy SavedRecursionState = RecursionState;
+  RecursionState = RS_Struct;
 
   // Force conversion of non-virtual base classes recursively.
   if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
@@ -400,6 +409,14 @@
   CGRecordLayout *Layout = ComputeRecordLayout(RD, Ty);
   CGRecordLayouts[Key] = Layout;
 
+  
+  // Restore our recursion state.  If we're done converting the outer-most
+  // record, then convert any deferred structs as well.
+  RecursionState = SavedRecursionState;
+  if (RecursionState == RS_Normal)
+    while (!DeferredRecords.empty())
+      ConvertRecordDeclType(DeferredRecords.pop_back_val());
+
   return Ty;
 }
 

Modified: cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenTypes.h?rev=134788&r1=134787&r2=134788&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenTypes.h (original)
+++ cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenTypes.h Fri Jul  8 23:46:25 2011
@@ -58,9 +58,9 @@
 class CodeGenTypes {
   ASTContext &Context;
   const TargetInfo &Target;
-  llvm::Module& TheModule;
-  const llvm::TargetData& TheTargetData;
-  const ABIInfo& TheABIInfo;
+  llvm::Module &TheModule;
+  const llvm::TargetData &TheTargetData;
+  const ABIInfo &TheABIInfo;
   CGCXXABI &TheCXXABI;
   const CodeGenOptions &CodeGenOpts;
 
@@ -74,9 +74,35 @@
   /// record layout info.
   llvm::DenseMap<const Type*, CGRecordLayout *> CGRecordLayouts;
 
+  /// RecordDeclTypes - This contains the LLVM IR type for any converted
+  /// RecordDecl.
+  llvm::DenseMap<const Type*, llvm::StructType *> RecordDeclTypes;
+  
   /// FunctionInfos - Hold memoized CGFunctionInfo results.
   llvm::FoldingSet<CGFunctionInfo> FunctionInfos;
 
+  enum RecursionStateTy {
+    RS_Normal,        // Normal type conversion.
+    RS_Struct,        // Recursively inside a struct conversion.
+    RS_StructPointer  // Recursively inside a pointer in a struct.
+  } RecursionState;
+  
+  llvm::SmallVector<const RecordDecl *, 8> DeferredRecords;
+  
+  struct RecursionStatePointerRAII {
+    RecursionStateTy &Val;
+    RecursionStateTy Saved;
+    
+    RecursionStatePointerRAII(RecursionStateTy &V) : Val(V), Saved(V) {
+      if (Val == RS_Struct)
+        Val = RS_StructPointer;
+    }
+    
+    ~RecursionStatePointerRAII() {
+      Val = Saved;
+    }
+  };
+  
 private:
   /// TypeCache - This map keeps cache of llvm::Types
   /// and maps llvm::Types to corresponding clang::Type.
@@ -196,7 +222,7 @@
 
 public:  // These are internal details of CGT that shouldn't be used externally.
   /// ConvertRecordDeclType - Lay out a tagged decl type like struct or union.
-  llvm::Type *ConvertRecordDeclType(const RecordDecl *TD);
+  llvm::StructType *ConvertRecordDeclType(const RecordDecl *TD);
 
   /// GetExpandedTypes - Expand the type \arg Ty into the LLVM
   /// argument types it would be passed as on the provided vector \arg





More information about the llvm-branch-commits mailing list