The Mother-of-All code review:
1. Fix AllowRSPrefix bug
2. Remove member mRS*Pragma in class RSContext
3. No longer only support 2x2, 3x3, 4x4 arrays
4. Fix Export All code for victorhsieh
5. Improve readability and maintainability
6. size_t -> int in calculating padding
Change-Id: I772aebd1440af66a89e2d2e688b193e500f38d69
diff --git a/slang_rs_export_element.cpp b/slang_rs_export_element.cpp
index 718f84e..aecadcf 100644
--- a/slang_rs_export_element.cpp
+++ b/slang_rs_export_element.cpp
@@ -2,174 +2,195 @@
#include "slang_rs_export_type.hpp"
#include "slang_rs_export_element.hpp"
-#include "clang/AST/Decl.h" /* for class clang::*Decl */
-#include "clang/AST/Type.h" /* for class clang::*Type */
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceLocation.h" /* for class clang::SourceLocation */
-#include "clang/Basic/IdentifierTable.h" /* for class clang::IdentifierInfo */
+#include "clang/AST/Decl.h"
+#include "clang/AST/Type.h"
-namespace slang {
+using namespace slang;
bool RSExportElement::Initialized = false;
RSExportElement::ElementInfoMapTy RSExportElement::ElementInfoMap;
void RSExportElement::Init() {
- if(!Initialized) {
- /* Initialize ElementInfoMap */
+ if (!Initialized) {
+ // Initialize ElementInfoMap
#define USE_ELEMENT_DATA_TYPE
#define USE_ELEMENT_DATA_KIND
-#define DEF_ELEMENT(_name, _dk, _dt, _norm, _vsize) \
- { \
- ElementInfo* EI = new ElementInfo; \
- EI->kind = GET_ELEMENT_DATA_KIND(_dk); \
- EI->type = GET_ELEMENT_DATA_TYPE(_dt); \
- EI->normalized = _norm; \
- EI->vsize = _vsize; \
- \
- llvm::StringRef Name(_name); \
- ElementInfoMap.insert( ElementInfoMapTy::value_type::Create(Name.begin(), \
- Name.end(), \
- ElementInfoMap.getAllocator(), \
- EI)); \
- }
+#define DEF_ELEMENT(_name, _dk, _dt, _norm, _vsize) \
+ { \
+ ElementInfo *EI = new ElementInfo; \
+ EI->kind = GET_ELEMENT_DATA_KIND(_dk); \
+ EI->type = GET_ELEMENT_DATA_TYPE(_dt); \
+ EI->normalized = _norm; \
+ EI->vsize = _vsize; \
+ \
+ llvm::StringRef Name(_name); \
+ ElementInfoMap.insert( \
+ ElementInfoMapTy::value_type::Create( \
+ Name.begin(), \
+ Name.end(), \
+ ElementInfoMap.getAllocator(), \
+ EI \
+ )); \
+ }
#include "slang_rs_export_element_support.inc"
- Initialized = true;
- }
- return;
+ Initialized = true;
+ }
+ return;
}
-RSExportType* RSExportElement::Create(RSContext* Context, const Type* T, const ElementInfo* EI) {
- /* Create RSExportType corresponded to the @T first and then verify */
+RSExportType *RSExportElement::Create(RSContext *Context,
+ const clang::Type *T,
+ const ElementInfo *EI) {
+ // Create RSExportType corresponded to the @T first and then verify
- llvm::StringRef TypeName;
- RSExportType* ET = NULL;
+ llvm::StringRef TypeName;
+ RSExportType *ET = NULL;
- if(!Initialized)
- Init();
+ if (!Initialized)
+ Init();
- assert(EI != NULL && "Element info not found");
+ assert(EI != NULL && "Element info not found");
- if(!RSExportType::NormalizeType(T, TypeName))
- return NULL;
+ if (!RSExportType::NormalizeType(T, TypeName))
+ return NULL;
- switch(T->getTypeClass()) {
- case Type::Builtin:
- case Type::Pointer:
- {
- assert(EI->vsize == 1 && "Element not a primitive class (please check your macro)");
- RSExportPrimitiveType* EPT = RSExportPrimitiveType::Create(Context, T, TypeName, EI->kind, EI->normalized);
- /* verify */
- assert(EI->type == EPT->getType() && "Element has unexpected type");
- ET = EPT;
- }
- break;
-
- case Type::ConstantArray:
- {
- //XXX
- break;
- }
-
- case Type::ExtVector:
- {
- assert(EI->vsize > 1 && "Element not a vector class (please check your macro)");
- RSExportVectorType* EVT = RSExportVectorType::Create(Context,
- static_cast<ExtVectorType*>(T->getCanonicalTypeInternal().getTypePtr()),
- TypeName,
- EI->kind,
- EI->normalized);
- /* verify */
- assert(EI->type == EVT->getType() && "Element has unexpected type");
- assert(EI->vsize == EVT->getNumElement() && "Element has unexpected size of vector");
- ET = EVT;
- }
- break;
-
- case Type::Record:
- {
- /* Must be RS object type */
-
- if ( TypeName.equals(llvm::StringRef("rs_matrix2x2")) ||
- TypeName.equals(llvm::StringRef("rs_matrix3x3")) ||
- TypeName.equals(llvm::StringRef("rs_matrix4x4")) ) {
-
- const clang::RecordType* RT = static_cast<const RecordType*> (T);
- const RecordDecl* RD = RT->getDecl();
- RD = RD->getDefinition();
- //RSExportRecordType* ERT = new RSExportRecordType(Context, TypeName, RD->hasAttr<PackedAttr>());
- RecordDecl::field_iterator fit = RD->field_begin();
- FieldDecl* FD = *fit;
- const Type* FT = RSExportType::GetTypeOfDecl(FD);
- RSExportConstantArrayType* ECT = RSExportConstantArrayType::Create(Context, static_cast<const ConstantArrayType*> (FT), TypeName);
- ET = ECT;
-
- //RSExportType* FieldET = RSExportElement::CreateFromDecl(Context, FD);
- //ERT->mFields.push_back( new Field(FieldET, FD->getName(), ERT, 0) );
- //const ASTRecordLayout &ASTRL = Context->getASTContext()->getASTRecordLayout(RD);
- //ERT->AllocSize = (ASTRL.getSize() > ASTRL.getDataSize()) ? (ASTRL.getSize() >> 3) : (ASTRL.getDataSize() >> 3);
- //ET = ERT;
-
- } else {
- RSExportPrimitiveType* EPT = RSExportPrimitiveType::Create(Context, T, TypeName, EI->kind, EI->normalized);
- /* verify */
- assert(EI->type == EPT->getType() && "Element has unexpected type");
- ET = EPT;
- }
- }
- break;
-
- default:
- /* TODO: warning: type is not exportable */
- printf("RSExportElement::Create : type '%s' is not exportable\n", T->getTypeClassName());
- break;
+ switch(T->getTypeClass()) {
+ case clang::Type::Builtin:
+ case clang::Type::Pointer: {
+ assert(EI->vsize == 1 && "Element not a primitive class (please check "
+ "your macro)");
+ RSExportPrimitiveType *EPT =
+ RSExportPrimitiveType::Create(Context,
+ T,
+ TypeName,
+ EI->kind,
+ EI->normalized);
+ // Verify
+ assert(EI->type == EPT->getType() && "Element has unexpected type");
+ ET = EPT;
+ break;
}
- return ET;
+ case clang::Type::ConstantArray: {
+ //XXX
+ break;
+ }
+
+ case clang::Type::ExtVector: {
+ assert(EI->vsize > 1 && "Element not a vector class (please check your "
+ "macro)");
+ RSExportVectorType *EVT =
+ RSExportVectorType::Create(Context,
+ static_cast<clang::ExtVectorType*>(
+ T->getCanonicalTypeInternal()
+ .getTypePtr()),
+ TypeName,
+ EI->kind,
+ EI->normalized);
+ // Verify
+ assert(EI->type == EVT->getType() && "Element has unexpected type");
+ assert(EI->vsize == EVT->getNumElement() && "Element has unexpected size "
+ "of vector");
+ ET = EVT;
+ break;
+ }
+
+ case clang::Type::Record: {
+ // Must be RS object type
+
+ if ( TypeName.equals(llvm::StringRef("rs_matrix2x2")) ||
+ TypeName.equals(llvm::StringRef("rs_matrix3x3")) ||
+ TypeName.equals(llvm::StringRef("rs_matrix4x4")) ) {
+
+ const clang::RecordType *RT = static_cast<const clang::RecordType*> (T);
+ const clang::RecordDecl *RD = RT->getDecl();
+ RD = RD->getDefinition();
+ clang::RecordDecl::field_iterator fit = RD->field_begin();
+ clang::FieldDecl *FD = *fit;
+ const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
+ RSExportConstantArrayType *ECT =
+ RSExportConstantArrayType::Create(
+ Context,
+ static_cast<const clang::ConstantArrayType*> (FT),
+ TypeName
+ );
+ ET = ECT;
+ } else {
+ RSExportPrimitiveType* EPT =
+ RSExportPrimitiveType::Create(Context,
+ T,
+ TypeName,
+ EI->kind,
+ EI->normalized);
+ // Verify
+ assert(EI->type == EPT->getType() && "Element has unexpected type");
+ ET = EPT;
+ }
+ break;
+ }
+
+ default: {
+ // TODO: warning: type is not exportable
+ fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n",
+ T->getTypeClassName());
+ break;
+ }
+ }
+
+ return ET;
}
-RSExportType* RSExportElement::CreateFromDecl(RSContext* Context, const DeclaratorDecl* DD) {
- const Type* T = RSExportType::GetTypeOfDecl(DD);
- const Type* CT = GET_CANONICAL_TYPE(T);
- const ElementInfo* EI = NULL;
+RSExportType *RSExportElement::CreateFromDecl(RSContext *Context,
+ const clang::DeclaratorDecl *DD) {
+ const clang::Type* T = RSExportType::GetTypeOfDecl(DD);
+ const clang::Type* CT = GET_CANONICAL_TYPE(T);
+ const ElementInfo* EI = NULL;
- /* For rs element that's NOT like those rs_color4f..., just call Create(Context, T) without finding EI */
- /* Note: Those rs_color4f kind of elements are either typed primitive or vector */
- if ((CT->getTypeClass() != Type::Builtin) && (CT->getTypeClass() != Type::ExtVector) && (CT->getTypeClass() != Type::Record)) {
- return RSExportType::Create(Context, T);
- }
+ // For rs element that's NOT like those rs_color4f..., just call
+ // Create(Context, T) without finding EI.
+ // Note: Those rs_color4f kind of elements are either typed primitive or
+ // vector
+ if ((CT->getTypeClass() != clang::Type::Builtin) &&
+ (CT->getTypeClass() != clang::Type::ExtVector) &&
+ (CT->getTypeClass() != clang::Type::Record)) {
+ return RSExportType::Create(Context, T);
+ }
- /* Iterative query the name of type to see whether it's an element name like rs_color4f or its alias (via typedef) */
- while (T != CT) {
- if (T->getTypeClass() != Type::Typedef) {
- break;
- } else {
- const TypedefType* TT = static_cast<const TypedefType*>(T);
- const TypedefDecl* TD = TT->getDecl();
- EI = GetElementInfo(TD->getName());
- if (EI != NULL)
- break;
-
- T = TD->getUnderlyingType().getTypePtr();
- }
- }
-
- if(EI == NULL) {
- return RSExportType::Create(Context, T);
+ // Iterative query the name of type to see whether it's an element name
+ // like rs_color4f or its alias (via typedef).
+ while (T != CT) {
+ if (T->getTypeClass() != clang::Type::Typedef) {
+ break;
} else {
- return RSExportElement::Create(Context, T, EI);
+ const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T);
+ const clang::TypedefDecl *TD = TT->getDecl();
+ EI = GetElementInfo(TD->getName());
+ if (EI != NULL)
+ break;
+
+ T = TD->getUnderlyingType().getTypePtr();
}
+ }
+
+ if (EI == NULL) {
+ return RSExportType::Create(Context, T);
+ } else {
+ return RSExportElement::Create(Context, T, EI);
+ }
}
-const RSExportElement::ElementInfo* RSExportElement::GetElementInfo(const llvm::StringRef& Name) {
- if(!Initialized)
- Init();
+const RSExportElement::ElementInfo *
+RSExportElement::GetElementInfo(const llvm::StringRef& Name) {
+ if (!Initialized)
+ Init();
- ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name);
- if(I == ElementInfoMap.end())
- return NULL;
- else
- return I->getValue();
+ ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name);
+ if (I == ElementInfoMap.end())
+ return NULL;
+ else
+ return I->getValue();
}
-
-} /* namespace slang */