[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