diff options
author | Zonr Chang <zonr@google.com> | 2010-10-22 02:11:35 +0800 |
---|---|---|
committer | Shih-wei Liao <sliao@google.com> | 2010-10-21 11:53:02 -0700 |
commit | 3cd3dd327445fcfa49f0e96cb2de2055bce541e9 (patch) | |
tree | 594250f6d17161b11eb12f326c7857e9f541461e | |
parent | 7363d8430db732c42d392fcab47cf0e3f8eb4515 (diff) | |
download | android_frameworks_compile_slang-3cd3dd327445fcfa49f0e96cb2de2055bce541e9.tar.gz android_frameworks_compile_slang-3cd3dd327445fcfa49f0e96cb2de2055bce541e9.tar.bz2 android_frameworks_compile_slang-3cd3dd327445fcfa49f0e96cb2de2055bce541e9.zip |
Bug fix: support self-referential struct type.
-rw-r--r-- | slang_rs_export_type.cpp | 53 | ||||
-rw-r--r-- | slang_rs_export_type.h | 15 | ||||
-rw-r--r-- | slang_rs_exportable.cpp | 6 | ||||
-rw-r--r-- | slang_rs_exportable.h | 3 | ||||
-rw-r--r-- | slang_rs_spec_table.cpp | 5 |
5 files changed, 51 insertions, 31 deletions
diff --git a/slang_rs_export_type.cpp b/slang_rs_export_type.cpp index 1028eb6..6542c5d 100644 --- a/slang_rs_export_type.cpp +++ b/slang_rs_export_type.cpp @@ -86,7 +86,6 @@ llvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { return cname; \ break; #include "RSClangBuiltinEnums.inc" -#undef ENUM_SUPPORT_BUILTIN_TYPE default: { assert(false && "Unknown data type of the builtin"); break; @@ -165,7 +164,6 @@ const clang::Type *RSExportType::TypeExportable( #define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ case builtin_type: #include "RSClangBuiltinEnums.inc" -#undef ENUM_SUPPORT_BUILTIN_TYPE return T; default: { return NULL; @@ -403,11 +401,12 @@ RSExportType::RSExportType(RSContext *Context, return; } -void RSExportType::keep() { +bool RSExportType::keep() { + if (!RSExportable::keep()) + return false; // Invalidate converted LLVM type. mLLVMType = NULL; - RSExportable::keep(); - return; + return true; } bool RSExportType::equals(const RSExportable *E) const { @@ -437,7 +436,6 @@ RSExportPrimitiveType::GetRSObjectType(const llvm::StringRef &TypeName) { #define ENUM_RS_OBJECT_TYPE(type, cname) \ RSObjectTypeMap->GetOrCreateValue(cname, DataType ## type); #include "RSObjectTypeEnums.inc" -#undef ENUM_RS_OBJECT_TYPE } RSObjectTypeMapTy::const_iterator I = RSObjectTypeMap->find(TypeName); @@ -460,7 +458,6 @@ const size_t RSExportPrimitiveType::SizeOfDataTypeInBits[] = { #define ENUM_RS_DATA_TYPE(type, cname, bits) \ bits, #include "RSDataTypeEnums.inc" -#undef ENUM_RS_DATA_TYPE 0 // DataTypeMax }; @@ -485,7 +482,6 @@ RSExportPrimitiveType::GetDataType(const clang::Type *T) { return DataType ## type; \ } #include "RSClangBuiltinEnums.inc" -#undef ENUM_SUPPORT_BUILTIN_TYPE // The size of type WChar depend on platform so we abandon the support // to them. default: { @@ -637,9 +633,11 @@ const llvm::Type *RSExportPointerType::convertToLLVMType() const { return llvm::PointerType::getUnqual(PointeeType); } -void RSExportPointerType::keep() { +bool RSExportPointerType::keep() { + if (!RSExportType::keep()) + return false; const_cast<RSExportType*>(mPointeeType)->keep(); - RSExportType::keep(); + return true; } bool RSExportPointerType::equals(const RSExportable *E) const { @@ -672,7 +670,6 @@ RSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { break; \ } #include "RSClangBuiltinEnums.inc" -#undef ENUM_SUPPORT_BUILTIN_TYPE default: { return llvm::StringRef(); } @@ -819,10 +816,11 @@ const llvm::Type *RSExportConstantArrayType::convertToLLVMType() const { return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); } -void RSExportConstantArrayType::keep() { +bool RSExportConstantArrayType::keep() { + if (!RSExportType::keep()) + return false; const_cast<RSExportType*>(mElementType)->keep(); - RSExportType::keep(); - return; + return true; } bool RSExportConstantArrayType::equals(const RSExportable *E) const { @@ -903,10 +901,14 @@ RSExportRecordType *RSExportRecordType::Create(RSContext *Context, } const llvm::Type *RSExportRecordType::convertToLLVMType() const { + // Create an opaque type since struct may reference itself recursively. + llvm::PATypeHolder ResultHolder = + llvm::OpaqueType::get(getRSContext()->getLLVMContext()); + setAbstractLLVMType(ResultHolder.get()); + std::vector<const llvm::Type*> FieldTypes; - for (const_field_iterator FI = fields_begin(), - FE = fields_end(); + for (const_field_iterator FI = fields_begin(), FE = fields_end(); FI != FE; FI++) { const Field *F = *FI; @@ -915,20 +917,27 @@ const llvm::Type *RSExportRecordType::convertToLLVMType() const { FieldTypes.push_back(FET->getLLVMType()); } - return llvm::StructType::get(getRSContext()->getLLVMContext(), - FieldTypes, - mIsPacked); + llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), + FieldTypes, + mIsPacked); + if (ST != NULL) + static_cast<llvm::OpaqueType*>(ResultHolder.get()) + ->refineAbstractTypeTo(ST); + else + return NULL; + return ResultHolder.get(); } -void RSExportRecordType::keep() { +bool RSExportRecordType::keep() { + if (!RSExportType::keep()) + return false; for (std::list<const Field*>::iterator I = mFields.begin(), E = mFields.end(); I != E; I++) { const_cast<RSExportType*>((*I)->getType())->keep(); } - RSExportType::keep(); - return; + return true; } bool RSExportRecordType::equals(const RSExportable *E) const { diff --git a/slang_rs_export_type.h b/slang_rs_export_type.h index 60685cb..6dcaa44 100644 --- a/slang_rs_export_type.h +++ b/slang_rs_export_type.h @@ -110,6 +110,11 @@ class RSExportType : public RSExportable { // (all of these information are target dependent) without dealing with these // by ourselves. virtual const llvm::Type *convertToLLVMType() const = 0; + // Record type may recursively referece its type definition. We need a + // temporary type setup before the type construction gets done. + inline void setAbstractLLVMType(const llvm::Type *LLVMType) const { + mLLVMType = LLVMType; + } virtual ~RSExportType() {} public: @@ -138,7 +143,7 @@ class RSExportType : public RSExportable { inline const std::string &getName() const { return mName; } - virtual void keep(); + virtual bool keep(); virtual bool equals(const RSExportable *E) const; }; // RSExportType @@ -154,7 +159,6 @@ class RSExportPrimitiveType : public RSExportType { #define ENUM_RS_DATA_TYPE(type, cname, bits) \ DataType ## type, #include "RSDataTypeEnums.inc" -#undef ENUM_RS_DATA_TYPE DataTypeMax } DataType; @@ -165,7 +169,6 @@ class RSExportPrimitiveType : public RSExportType { #define ENUM_RS_DATA_KIND(kind) \ , DataKind ## kind #include "RSDataKindEnums.inc" -#undef ENUM_RS_DATA_KIND } DataKind; private: @@ -261,7 +264,7 @@ class RSExportPointerType : public RSExportType { public: static const clang::Type *IntegerType; - virtual void keep(); + virtual bool keep(); inline const RSExportType *getPointeeType() const { return mPointeeType; } @@ -367,7 +370,7 @@ class RSExportConstantArrayType : public RSExportType { inline unsigned getSize() const { return mSize; } inline const RSExportType *getElementType() const { return mElementType; } - virtual void keep(); + virtual bool keep(); virtual bool equals(const RSExportable *E) const; }; @@ -447,7 +450,7 @@ class RSExportRecordType : public RSExportType { inline bool isArtificial() const { return mIsArtificial; } inline size_t getAllocSize() const { return mAllocSize; } - virtual void keep(); + virtual bool keep(); virtual bool equals(const RSExportable *E) const; ~RSExportRecordType() { diff --git a/slang_rs_exportable.cpp b/slang_rs_exportable.cpp index 53ab33d..6e60582 100644 --- a/slang_rs_exportable.cpp +++ b/slang_rs_exportable.cpp @@ -18,10 +18,12 @@ using namespace slang; -void RSExportable::keep() { +bool RSExportable::keep() { + if (isKeep()) + return false; // Invalidate associated Context. mContext = NULL; - return; + return true; } bool RSExportable::equals(const RSExportable *E) const { diff --git a/slang_rs_exportable.h b/slang_rs_exportable.h index c3d0215..f336745 100644 --- a/slang_rs_exportable.h +++ b/slang_rs_exportable.h @@ -48,7 +48,8 @@ class RSExportable { // When keep() is invoked, mKeep will set to true and the associated RSContext // won't free this RSExportable object in its destructor. The deallcation // responsibility is then transferred to the object who invoked this function. - virtual void keep(); + // Return false if the exportable is kept or failed to keep. + virtual bool keep(); inline bool isKeep() const { return (mContext == NULL); } virtual bool equals(const RSExportable *E) const; diff --git a/slang_rs_spec_table.cpp b/slang_rs_spec_table.cpp index 6ef4e64..f08b28d 100644 --- a/slang_rs_spec_table.cpp +++ b/slang_rs_spec_table.cpp @@ -188,6 +188,7 @@ static int GenRSDataTypeEnums(const RSDataTypeSpec *const DataTypes[], DataTypes[i]->getTypeName(), DataTypes[i]->getTypePragmaName(), DataTypes[i]->getSizeInBit()); + printf("#undef ENUM_RS_DATA_TYPE"); return 0; } @@ -203,6 +204,7 @@ static int GenClangBuiltinEnum( ClangBuilitinsMap[i]->getBuiltinTypeKind(), ClangBuilitinsMap[i]->getDataType()->getTypeName(), ClangBuilitinsMap[i]->getDataType()->getTypePragmaName()); + printf("#undef ENUM_SUPPORT_BUILTIN_TYPE"); return 0; } @@ -217,6 +219,7 @@ static int GenRSObjectTypeEnums(const RSDataTypeSpec *const DataTypes[], printf("ENUM_RS_OBJECT_TYPE(%s, \"%s\")\n", DataTypes[i]->getTypeName(), DataTypes[i]->getTypePragmaName()); + printf("#undef ENUM_RS_OBJECT_TYPE"); return 0; } @@ -228,6 +231,7 @@ int GenRSDataKindEnums(const RSDataKindSpec *const DataKinds[], unsigned NumDataKinds) { for (unsigned i = 0; i < NumDataKinds; i++) printf("ENUM_RS_DATA_KIND(%s)\n", DataKinds[i]->getKindName()); + printf("#undef ENUM_RS_DATA_KIND"); return 0; } @@ -244,6 +248,7 @@ int GenRSDataElementEnums(const RSDataElementSpec *const DataElements[], DataElements[i]->getDataType()->getTypeName(), ((DataElements[i]->isNormal()) ? "true" : "false"), DataElements[i]->getVectorSize()); + printf("#undef ENUM_RS_DATA_ELEMENT"); return 0; } |