slang_rs_export_element.cpp revision f8149d9e5a3795e9952717ee6346789a134c55c7
1#include "slang_rs_context.hpp" 2#include "slang_rs_export_type.hpp" 3#include "slang_rs_export_element.hpp" 4 5#include "clang/AST/Decl.h" /* for class clang::*Decl */ 6#include "clang/AST/Type.h" /* for class clang::*Type */ 7 8#include "clang/Basic/SourceLocation.h" /* for class clang::SourceLocation */ 9#include "clang/Basic/IdentifierTable.h" /* for class clang::IdentifierInfo */ 10 11namespace slang { 12 13bool RSExportElement::Initialized = false; 14RSExportElement::ElementInfoMapTy RSExportElement::ElementInfoMap; 15 16void RSExportElement::Init() { 17 if(!Initialized) { 18 /* Initialize ElementInfoMap */ 19#define USE_ELEMENT_DATA_TYPE 20#define USE_ELEMENT_DATA_KIND 21#define DEF_ELEMENT(_name, _dk, _dt, _norm, _vsize) \ 22 { \ 23 ElementInfo* EI = new ElementInfo; \ 24 EI->kind = GET_ELEMENT_DATA_KIND(_dk); \ 25 EI->type = GET_ELEMENT_DATA_TYPE(_dt); \ 26 EI->normalized = _norm; \ 27 EI->vsize = _vsize; \ 28 \ 29 llvm::StringRef Name(_name); \ 30 ElementInfoMap.insert( ElementInfoMapTy::value_type::Create(Name.begin(), \ 31 Name.end(), \ 32 ElementInfoMap.getAllocator(), \ 33 EI)); \ 34 } 35#include "slang_rs_export_element_support.inc" 36 37 Initialized = true; 38 } 39 return; 40} 41 42RSExportType* RSExportElement::Create(RSContext* Context, const Type* T, const ElementInfo* EI) { 43 /* Create RSExportType corresponded to the @T first and then verify */ 44 45 llvm::StringRef TypeName; 46 RSExportType* ET = NULL; 47 48 if(!Initialized) 49 Init(); 50 51 assert(EI != NULL && "Element info not found"); 52 53 if(!RSExportType::NormalizeType(T, TypeName)) 54 return NULL; 55 56 switch(T->getTypeClass()) { 57 case Type::Builtin: 58 case Type::Pointer: 59 { 60 assert(EI->vsize == 1 && "Element not a primitive class (please check your macro)"); 61 RSExportPrimitiveType* EPT = RSExportPrimitiveType::Create(Context, T, TypeName, EI->kind, EI->normalized); 62 /* verify */ 63 assert(EI->type == EPT->getType() && "Element has unexpected type"); 64 ET = EPT; 65 } 66 break; 67 68 case Type::ConstantArray: 69 { 70 //XXX 71 break; 72 } 73 74 case Type::ExtVector: 75 { 76 assert(EI->vsize > 1 && "Element not a vector class (please check your macro)"); 77 RSExportVectorType* EVT = RSExportVectorType::Create(Context, 78 static_cast<ExtVectorType*>(T->getCanonicalTypeInternal().getTypePtr()), 79 TypeName, 80 EI->kind, 81 EI->normalized); 82 /* verify */ 83 assert(EI->type == EVT->getType() && "Element has unexpected type"); 84 assert(EI->vsize == EVT->getNumElement() && "Element has unexpected size of vector"); 85 ET = EVT; 86 } 87 break; 88 89 case Type::Record: 90 { 91 /* Must be RS object type */ 92 93 if ( TypeName.equals(llvm::StringRef("rs_matrix2x2")) || 94 TypeName.equals(llvm::StringRef("rs_matrix3x3")) || 95 TypeName.equals(llvm::StringRef("rs_matrix4x4")) ) { 96 97 const clang::RecordType* RT = static_cast<const RecordType*> (T); 98 const RecordDecl* RD = RT->getDecl(); 99 RD = RD->getDefinition(); 100 //RSExportRecordType* ERT = new RSExportRecordType(Context, TypeName, RD->hasAttr<PackedAttr>()); 101 RecordDecl::field_iterator fit = RD->field_begin(); 102 FieldDecl* FD = *fit; 103 const Type* FT = RSExportType::GetTypeOfDecl(FD); 104 RSExportConstantArrayType* ECT = RSExportConstantArrayType::Create(Context, static_cast<const ConstantArrayType*> (FT), TypeName); 105 ET = ECT; 106 107 //RSExportType* FieldET = RSExportElement::CreateFromDecl(Context, FD); 108 //ERT->mFields.push_back( new Field(FieldET, FD->getName(), ERT, 0) ); 109 //const ASTRecordLayout &ASTRL = Context->getASTContext()->getASTRecordLayout(RD); 110 //ERT->AllocSize = (ASTRL.getSize() > ASTRL.getDataSize()) ? (ASTRL.getSize() >> 3) : (ASTRL.getDataSize() >> 3); 111 //ET = ERT; 112 113 } else { 114 RSExportPrimitiveType* EPT = RSExportPrimitiveType::Create(Context, T, TypeName, EI->kind, EI->normalized); 115 /* verify */ 116 assert(EI->type == EPT->getType() && "Element has unexpected type"); 117 ET = EPT; 118 } 119 } 120 break; 121 122 default: 123 /* TODO: warning: type is not exportable */ 124 printf("RSExportElement::Create : type '%s' is not exportable\n", T->getTypeClassName()); 125 break; 126 } 127 128 return ET; 129} 130 131RSExportType* RSExportElement::CreateFromDecl(RSContext* Context, const DeclaratorDecl* DD) { 132 const Type* T = RSExportType::GetTypeOfDecl(DD); 133 const Type* CT = GET_CANONICAL_TYPE(T); 134 const ElementInfo* EI = NULL; 135 136 /* For rs element that's NOT like those rs_color4f..., just call Create(Context, T) without finding EI */ 137 /* Note: Those rs_color4f kind of elements are either typed primitive or vector */ 138 if ((CT->getTypeClass() != Type::Builtin) && (CT->getTypeClass() != Type::ExtVector) && (CT->getTypeClass() != Type::Record)) { 139 return RSExportType::Create(Context, T); 140 } 141 142 /* Iterative query the name of type to see whether it's an element name like rs_color4f or its alias (via typedef) */ 143 while (T != CT) { 144 if (T->getTypeClass() != Type::Typedef) { 145 break; 146 } else { 147 const TypedefType* TT = static_cast<const TypedefType*>(T); 148 const TypedefDecl* TD = TT->getDecl(); 149 EI = GetElementInfo(TD->getName()); 150 if (EI != NULL) 151 break; 152 153 T = TD->getUnderlyingType().getTypePtr(); 154 } 155 } 156 157 if(EI == NULL) { 158 return RSExportType::Create(Context, T); 159 } else { 160 return RSExportElement::Create(Context, T, EI); 161 } 162} 163 164const RSExportElement::ElementInfo* RSExportElement::GetElementInfo(const llvm::StringRef& Name) { 165 if(!Initialized) 166 Init(); 167 168 ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name); 169 if(I == ElementInfoMap.end()) 170 return NULL; 171 else 172 return I->getValue(); 173} 174 175} /* namespace slang */ 176