diff options
Diffstat (limited to 'lib/CodeGen/CodeGenTypes.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 151 |
1 files changed, 82 insertions, 69 deletions
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index a4a8654..fcda053 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -31,7 +31,6 @@ using namespace CodeGen; CodeGenTypes::CodeGenTypes(CodeGenModule &cgm) : CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()), - TheDataLayout(cgm.getDataLayout()), Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()), TheABIInfo(cgm.getTargetCodeGenInfo().getABIInfo()) { SkippedLayout = false; @@ -295,6 +294,76 @@ static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext, llvm_unreachable("Unknown float format!"); } +llvm::Type *CodeGenTypes::ConvertFunctionType(QualType QFT, + const FunctionDecl *FD) { + assert(QFT.isCanonical()); + const Type *Ty = QFT.getTypePtr(); + const FunctionType *FT = cast<FunctionType>(QFT.getTypePtr()); + // First, check whether we can build the full function type. If the + // function type depends on an incomplete type (e.g. a struct or enum), we + // cannot lower the function type. + if (!isFuncTypeConvertible(FT)) { + // This function's type depends on an incomplete tag type. + + // Force conversion of all the relevant record types, to make sure + // we re-convert the FunctionType when appropriate. + if (const RecordType *RT = FT->getReturnType()->getAs<RecordType>()) + ConvertRecordDeclType(RT->getDecl()); + if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) + for (unsigned i = 0, e = FPT->getNumParams(); i != e; i++) + if (const RecordType *RT = FPT->getParamType(i)->getAs<RecordType>()) + ConvertRecordDeclType(RT->getDecl()); + + SkippedLayout = true; + + // Return a placeholder type. + return llvm::StructType::get(getLLVMContext()); + } + + // While we're converting the parameter types for a function, we don't want + // to recursively convert any pointed-to structs. Converting directly-used + // structs is ok though. + if (!RecordsBeingLaidOut.insert(Ty).second) { + SkippedLayout = true; + return llvm::StructType::get(getLLVMContext()); + } + + // The function type can be built; call the appropriate routines to + // build it. + const CGFunctionInfo *FI; + if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) { + FI = &arrangeFreeFunctionType( + CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT, 0)), FD); + } else { + const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(FT); + FI = &arrangeFreeFunctionType( + CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(FNPT, 0))); + } + + llvm::Type *ResultType = nullptr; + // If there is something higher level prodding our CGFunctionInfo, then + // don't recurse into it again. + if (FunctionsBeingProcessed.count(FI)) { + + ResultType = llvm::StructType::get(getLLVMContext()); + SkippedLayout = true; + } else { + + // Otherwise, we're good to go, go ahead and convert it. + ResultType = GetFunctionType(*FI); + } + + RecordsBeingLaidOut.erase(Ty); + + if (SkippedLayout) + TypeCache.clear(); + + if (RecordsBeingLaidOut.empty()) + while (!DeferredRecords.empty()) + ConvertRecordDeclType(DeferredRecords.pop_back_val()); + return ResultType; +} + /// ConvertType - Convert the specified type to its LLVM form. llvm::Type *CodeGenTypes::ConvertType(QualType T) { T = Context.getCanonicalType(T); @@ -389,9 +458,19 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { case BuiltinType::OCLImage1dBuffer: case BuiltinType::OCLImage2d: case BuiltinType::OCLImage2dArray: + case BuiltinType::OCLImage2dDepth: + case BuiltinType::OCLImage2dArrayDepth: + case BuiltinType::OCLImage2dMSAA: + case BuiltinType::OCLImage2dArrayMSAA: + case BuiltinType::OCLImage2dMSAADepth: + case BuiltinType::OCLImage2dArrayMSAADepth: case BuiltinType::OCLImage3d: case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: + case BuiltinType::OCLClkEvent: + case BuiltinType::OCLQueue: + case BuiltinType::OCLNDRange: + case BuiltinType::OCLReserveID: ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty); break; @@ -476,75 +555,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { break; } case Type::FunctionNoProto: - case Type::FunctionProto: { - const FunctionType *FT = cast<FunctionType>(Ty); - // First, check whether we can build the full function type. If the - // function type depends on an incomplete type (e.g. a struct or enum), we - // cannot lower the function type. - if (!isFuncTypeConvertible(FT)) { - // This function's type depends on an incomplete tag type. - - // Force conversion of all the relevant record types, to make sure - // we re-convert the FunctionType when appropriate. - if (const RecordType *RT = FT->getReturnType()->getAs<RecordType>()) - ConvertRecordDeclType(RT->getDecl()); - if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) - for (unsigned i = 0, e = FPT->getNumParams(); i != e; i++) - if (const RecordType *RT = FPT->getParamType(i)->getAs<RecordType>()) - ConvertRecordDeclType(RT->getDecl()); - - // Return a placeholder type. - ResultType = llvm::StructType::get(getLLVMContext()); - - SkippedLayout = true; - break; - } - - // While we're converting the parameter types for a function, we don't want - // to recursively convert any pointed-to structs. Converting directly-used - // structs is ok though. - if (!RecordsBeingLaidOut.insert(Ty).second) { - ResultType = llvm::StructType::get(getLLVMContext()); - - SkippedLayout = true; - break; - } - - // The function type can be built; call the appropriate routines to - // build it. - const CGFunctionInfo *FI; - if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) { - FI = &arrangeFreeFunctionType( - CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT, 0))); - } else { - const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(FT); - FI = &arrangeFreeFunctionType( - CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(FNPT, 0))); - } - - // If there is something higher level prodding our CGFunctionInfo, then - // don't recurse into it again. - if (FunctionsBeingProcessed.count(FI)) { - - ResultType = llvm::StructType::get(getLLVMContext()); - SkippedLayout = true; - } else { - - // Otherwise, we're good to go, go ahead and convert it. - ResultType = GetFunctionType(*FI); - } - - RecordsBeingLaidOut.erase(Ty); - - if (SkippedLayout) - TypeCache.clear(); - - if (RecordsBeingLaidOut.empty()) - while (!DeferredRecords.empty()) - ConvertRecordDeclType(DeferredRecords.pop_back_val()); + case Type::FunctionProto: + ResultType = ConvertFunctionType(T); break; - } - case Type::ObjCObject: ResultType = ConvertType(cast<ObjCObjectType>(Ty)->getBaseType()); break; |