From a081b8bac734aec71c06839ca4d4d1568ad4402f Mon Sep 17 00:00:00 2001 From: boostmultifruit Date: Mon, 16 Dec 2019 05:52:48 +0000 Subject: [PATCH] Add Cyberway tables support #3 --- include/clang/AST/Decl.h | 5 +++++ include/clang/Basic/Attr.td | 20 ++++++++++++++++++-- include/clang/Basic/AttrDocs.td | 14 ++++++++++++++ include/clang/Basic/EosioAttrs.h | 17 +++++++++++++++++ lib/AST/Decl.cpp | 21 +++++++++++++++++++++ lib/Sema/SemaDeclAttr.cpp | 30 ++++++++++++++++++++++++++++++ 6 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 include/clang/Basic/EosioAttrs.h diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 908be8f1ea2e..adf72a261acb 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -32,6 +32,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/Visibility.h" +#include "clang/Basic/EosioAttrs.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" @@ -2960,6 +2961,10 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable { return K >= firstTypedefName && K <= lastTypedefName; } + bool hasEosioIndex() const; + EosioIndex getEosioIndex() const; + bool hasEosioTable() const; + EosioTable getEosioTable() const; private: bool isTransparentTagSlow() const; }; diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 37dbf69f2538..2f7593745ded 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -997,10 +997,26 @@ def EosioAction : InheritableAttr { let Documentation = [EosioActionDocs]; } +def EosioUnique : InheritableAttr { + let Spellings = [CXX11<"eosio", "unique">, GNU<"eosio_unique">]; + let Args = [StringArgument<"Orders", 1>]; + let Subjects = SubjectList<[TypedefName]>; + let MeaningfulToClassTemplateDefinition = 1; + let Documentation = [EosioUniqueDocs]; +} + +def EosioNonUnique : InheritableAttr { + let Spellings = [CXX11<"eosio", "non_unique">, GNU<"eosio_non_unique">]; + let Args = [StringArgument<"Orders", 1>]; + let Subjects = SubjectList<[TypedefName]>; + let MeaningfulToClassTemplateDefinition = 1; + let Documentation = [EosioNonUniqueDocs]; +} + def EosioTable : InheritableAttr { let Spellings = [CXX11<"eosio", "table">, GNU<"eosio_table">]; - let Args = [StringArgument<"name", 1>]; - let Subjects = SubjectList<[CXXRecord]>; + let Args = [StringArgument<"name", 1>]; // Cyberway: name is scope_type + let Subjects = SubjectList<[CXXRecord, TypedefName]>; let MeaningfulToClassTemplateDefinition = 1; let Documentation = [EosioTableDocs]; } diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index 05a07423daf8..8a9fba020f91 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -887,6 +887,20 @@ The ``eosio::action`` attribute marks a method as being an eosio action. }]; } +def EosioUniqueDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The ``eosio::unique`` attribute marks a type definition as being an unique index in eosio table. + }]; +} + +def EosioNonUniqueDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The ``eosio::non_unique`` attribute marks a type definition as being an non-unique index in eosio table. + }]; +} + def EosioTableDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/include/clang/Basic/EosioAttrs.h b/include/clang/Basic/EosioAttrs.h new file mode 100644 index 000000000000..23a764aa3689 --- /dev/null +++ b/include/clang/Basic/EosioAttrs.h @@ -0,0 +1,17 @@ +#ifndef LLVM_CLANG_BASIC_EOSIO_ATTRS_H +#define LLVM_CLANG_BASIC_EOSIO_ATTRS_H + +namespace clang { + +struct EosioIndex { + bool unique; + std::string orders; +}; + +struct EosioTable { + std::string scope_type; +}; + +} + +#endif // LLVM_CLANG_BASIC_EOSIO_ATTRS_H diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index e544be7cab25..6af03eb50a43 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -4425,6 +4425,27 @@ TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const { return nullptr; } +bool TypedefNameDecl::hasEosioIndex()const { return hasAttr() || hasAttr(); } +EosioIndex TypedefNameDecl::getEosioIndex()const { + EosioIndex ret; + const auto* idx = getAttr(); + ret.unique = (idx != nullptr); + if (idx) { + ret.orders = idx->getOrders(); + } else { + ret.orders = getAttr()->getOrders(); + } + return ret; +} + +bool TypedefNameDecl::hasEosioTable()const { return hasAttr(); } +EosioTable TypedefNameDecl::getEosioTable()const { + EosioTable ret; + const auto* idx = getAttr(); + ret.scope_type = idx->getName(); + return ret; +} + bool TypedefNameDecl::isTransparentTagSlow() const { auto determineIsTransparent = [&]() { if (auto *TT = getUnderlyingType()->getAs()) { diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 0269b861ca25..bf3444bc0a92 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -469,6 +469,30 @@ static void handleEosioActionAttribute(Sema &S, Decl *D, const AttributeList &AL AL.getAttributeSpellingListIndex())); } +static void handleEosioUniqueAttribute(Sema &S, Decl *D, const AttributeList &AL) { + // Handle the cases where the attribute has a text message. + StringRef Str, Replacement; + if (AL.isArgExpr(0) && AL.getArgAsExpr(0) && + !S.checkStringLiteralArgumentAttr(AL, 0, Str)) + return; + + D->addAttr(::new (S.Context) + EosioUniqueAttr(AL.getRange(), S.Context, Str, + AL.getAttributeSpellingListIndex())); +} + +static void handleEosioNonUniqueAttribute(Sema &S, Decl *D, const AttributeList &AL) { + // Handle the cases where the attribute has a text message. + StringRef Str, Replacement; + if (AL.isArgExpr(0) && AL.getArgAsExpr(0) && + !S.checkStringLiteralArgumentAttr(AL, 0, Str)) + return; + + D->addAttr(::new (S.Context) + EosioNonUniqueAttr(AL.getRange(), S.Context, Str, + AL.getAttributeSpellingListIndex())); +} + static void handleEosioTableAttribute(Sema &S, Decl *D, const AttributeList &AL) { // Handle the cases where the attribute has a text message. StringRef Str, Replacement; @@ -5940,6 +5964,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_EosioAction: handleEosioActionAttribute(S, D, AL); break; + case AttributeList::AT_EosioUnique: + handleEosioUniqueAttribute(S, D, AL); + break; + case AttributeList::AT_EosioNonUnique: + handleEosioNonUniqueAttribute(S, D, AL); + break; case AttributeList::AT_EosioTable: handleEosioTableAttribute(S, D, AL); break;