diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 1f3d524691ed61dea0f6d999515e71e7e84f66ff..61f2ea94af36c9ca37c3e8cd116647d118803425 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -6462,6 +6462,69 @@ private: friend class ASTStmtWriter; }; +/// Represents a call to the builtin function __builtin_hm_type_signature. +class HMTypeSigExpr final : public Expr { + SourceLocation OpLoc, RParenLoc; + QualType DataType; + public: + enum FieldType { PADDING = 0, POINTER = 1, DATA = 2 }; + + UnaryExprOrTypeTrait ExprKind; + + /// Build an empty call expression. + explicit HMTypeSigExpr(EmptyShell Empty) : Expr(HMTypeSigExprClass, Empty) {} + HMTypeSigExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo, + QualType resultType, SourceLocation op, + SourceLocation rp); + + FieldType getFieldTypeEnum(QualType FieldTy) const; + UnaryExprOrTypeTrait getKind() const {return ExprKind;} + std::string getFieldTypeStr(FieldType FieldEnum) const {return std::to_string(FieldEnum);} + APValue EvaluateTypeSig(const ASTContext &Ctx) const; + APValue MakeStringLiteral(StringRef Tmp, const ASTContext &Ctx) const; + void divideGranules(QualType CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const; + void divideGranules(const FieldDecl *Field, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const; + bool divideGranulesBase(FieldType CurType, uint64_t fieldSize, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const; + void divideGranulesArray(const ArrayType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const; + void divideGranulesVector(const VectorType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const; + void divideGranulesRecord(const RecordType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const; + void divideGranulesUnion(const RecordType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const; + + /// Return a string representing the name of the specific builtin function. + StringRef getBuiltinStr() const; + APValue getBuiltinResuilt(const ASTContext &Ctx, std::string signature, unsigned short summary) const; + QualType getTypeOfArgument() const { + return DataType; + } + + SourceLocation getOperatorLoc() const { return OpLoc; } + void setOperatorLoc(SourceLocation L) { OpLoc = L; } + + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + + SourceLocation getBeginLoc() const LLVM_READONLY { return OpLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(child_iterator(), child_iterator()); + } + + private: + friend class ASTStmtReader; + const uint64_t GranulesSize = 64; +}; + } // end namespace clang #endif // LLVM_CLANG_AST_EXPR_H diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 6c6d5402d5d12742cdbc69d91f8a34db0dc396ad..08c30d5955958ff04a765dc40a9345443422b9f8 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3158,6 +3158,9 @@ DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective, DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(HMTypeSigExpr, {}) + // OpenMP clauses. template bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index ebbd8db313428549fc3350ee5405c8dc842ea118..292c295e5c0b89a5bee952ddc0ff4eafba7f1b44 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -202,6 +202,7 @@ def OpaqueValueExpr : StmtNode; def TypoExpr : StmtNode; def RecoveryExpr : StmtNode; def BuiltinBitCastExpr : StmtNode; +def HMTypeSigExpr : StmtNode; // Microsoft Extensions. def MSPropertyRefExpr : StmtNode; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 47e4c2754dd05865e4a055a17d892090cf839325..21e2b09cfefb610c22d609b6a843a271af2a6768 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -435,6 +435,8 @@ KEYWORD(__builtin_COLUMN , KEYALL) KEYWORD(__builtin_source_location , KEYCXX) UNARY_EXPR_OR_TYPE_TRAIT(__builtin_get_modifier_bytype, PacModifierByType, KEYALL) // OHOS_LOCAL +UNARY_EXPR_OR_TYPE_TRAIT(__builtin_hm_type_summary, HMTypeSummary, KEYALL) +UNARY_EXPR_OR_TYPE_TRAIT(__builtin_hm_type_signature, HMTypeSignature, KEYALL) // __builtin_types_compatible_p is a GNU C extension that we handle like a C++ // type trait. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 8f2800d6f2eaf18096157593406d5a9eb7bb91af..f6c04c9871dddcc5556f8aeb7f7c41e3fb390287 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -5854,6 +5854,11 @@ public: bool CheckCaseExpression(Expr *E); + // __builtin_hm_type_signature(type) + ExprResult ActOnHMTypeSig(SourceLocation OpLoc, + UnaryExprOrTypeTrait ExprKind, + ParsedType ParsedTy, SourceRange ArgRange); + /// Describes the result of an "if-exists" condition check. enum IfExistsResult { /// The symbol exists. diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 58f456486f6def43655bd09aefca2e060968e660..e2d96c3419a64dfd76855c7a363e1ad2e3877304 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1888,6 +1888,7 @@ enum StmtCode { EXPR_CXX_FOLD, // CXXFoldExpr EXPR_CONCEPT_SPECIALIZATION, // ConceptSpecializationExpr EXPR_REQUIRES, // RequiresExpr + EXPR_HM_TYPE_SIG, // A HMTypeSigExpr record. // CUDA EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index ca477e6500c5ec6ab3239d8ca5368a82b23dba33..f9d3be2ceb1b58ee915ad2961bb3da8aba6b2e5c 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3483,6 +3483,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case ConceptSpecializationExprClass: case RequiresExprClass: case SYCLUniqueStableNameExprClass: + case HMTypeSigExprClass: // These never have a side-effect. return false; @@ -4852,6 +4853,226 @@ RecoveryExpr *RecoveryExpr::CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs) { return new (Mem) RecoveryExpr(EmptyShell(), NumSubExprs); } +// __builtin_hm_type_signature +HMTypeSigExpr::HMTypeSigExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo, + QualType resultTy, SourceLocation op, + SourceLocation rp) + : Expr(HMTypeSigExprClass, resultTy, VK_PRValue, OK_Ordinary), + OpLoc(op), RParenLoc(rp) { + this->DataType = TInfo->getType(); + this->ExprKind = ExprKind; +} + +HMTypeSigExpr::FieldType HMTypeSigExpr::getFieldTypeEnum(QualType FieldTy) const { + if (FieldTy->isPointerType()) { + return HMTypeSigExpr::POINTER; + } else { + return HMTypeSigExpr::DATA; + } +} + +StringRef HMTypeSigExpr::getBuiltinStr() const { + if (getKind() == UETT_HMTypeSummary) + return "__builtin_hm_type_summary"; + else + return "__builtin_hm_type_signature"; +} + +APValue HMTypeSigExpr::getBuiltinResuilt(const ASTContext &Ctx, std::string signature, unsigned short summary) const { + auto MakeStringLiteral = [&](StringRef Tmp) { + using LValuePathEntry = APValue::LValuePathEntry; + StringLiteral *Res = Ctx.getPredefinedStringLiteralFromCache(Tmp); + // Decay the string to a pointer to the first character. + LValuePathEntry Path[1] = {LValuePathEntry::ArrayIndex(0)}; + return APValue(Res, CharUnits::Zero(), Path, /*OnePastTheEnd=*/false); + }; + if (getKind() == UETT_HMTypeSignature) + return MakeStringLiteral(signature); + else + return APValue(llvm::APSInt(llvm::APInt(Ctx.getIntWidth(Ctx.UnsignedShortTy), summary, false))); +} + +APValue HMTypeSigExpr::MakeStringLiteral(StringRef Tmp, const ASTContext &Ctx) const { + using LValuePathEntry = APValue::LValuePathEntry; + StringLiteral *Res = Ctx.getPredefinedStringLiteralFromCache(Tmp); + // Decay the string to a pointer to the first character. + LValuePathEntry Path[1] = {LValuePathEntry::ArrayIndex(0)}; + return APValue(Res, CharUnits::Zero(), Path, /*OnePastTheEnd=*/false); + } + +APValue HMTypeSigExpr::EvaluateTypeSig(const ASTContext &Ctx) const { + if (!DataType->isRecordType()) { + return getBuiltinResuilt(Ctx, getFieldTypeStr(getFieldTypeEnum(DataType)), getFieldTypeEnum(DataType)); + } + RecordDecl *RD = DataType->castAs()->getDecl(); + if (!RD->getDefinition()) { + llvm::errs() << "not defination cannot get signature.\n"; + return getBuiltinResuilt(Ctx, getFieldTypeStr(getFieldTypeEnum(DataType)), getFieldTypeEnum(DataType)); + } + uint64_t GranulesPos = 0; + std::vector> GranulesVec; + std::vector vec; + GranulesVec.push_back(vec); + divideGranules(DataType, Ctx, GranulesPos, GranulesVec); + std::string signature; + unsigned summary = 0; + for (auto tmpVec : GranulesVec) { + unsigned GranulesValue = 0; + if (tmpVec.empty()) { + continue; + } + for (auto type : tmpVec) { + GranulesValue = GranulesValue | type; // 计算单个颗粒的value + } + signature += std::to_string(GranulesValue); + summary |= (1 << GranulesValue); + } + return getBuiltinResuilt(Ctx, signature, summary); +} + +void HMTypeSigExpr::divideGranules(QualType CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + if (CurType->isRecordType()) { + divideGranulesRecord(CurType->castAs(), Ctx, GranulesPos, vec); + } else if (CurType->isArrayType()){ + divideGranulesArray(Ctx.getAsArrayType(CurType), Ctx, GranulesPos, vec); + } else if (CurType->isVectorType()){ + divideGranulesVector(CurType->castAs(), Ctx, GranulesPos, vec); + } else { + uint64_t fieldSize = Ctx.getTypeSize(CurType); + divideGranulesBase(getFieldTypeEnum(CurType), fieldSize, Ctx, GranulesPos, vec); + } +} + +void HMTypeSigExpr::divideGranules(const FieldDecl *Field, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + auto CurType = Field->getType(); + if (Field->isBitField()) { + uint64_t fieldSize = Field->getBitWidthValue(Ctx); + divideGranulesBase(getFieldTypeEnum(CurType), fieldSize, Ctx, GranulesPos, vec); + return; + } + divideGranules(CurType, Ctx, GranulesPos, vec); +} + +bool HMTypeSigExpr::divideGranulesBase(FieldType CurType, uint64_t fieldSize, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + if ((GranulesPos + fieldSize) <= GranulesSize) { + vec.back().push_back(CurType); + GranulesPos += fieldSize; + } else { + uint64_t tmpSize = GranulesSize - GranulesPos; + // 也有128位的整形,分成两部分分别添加 + divideGranulesBase(CurType, tmpSize, Ctx, GranulesPos, vec); + fieldSize = fieldSize - tmpSize; + divideGranulesBase(CurType, fieldSize, Ctx, GranulesPos, vec); + return true; + } + if (GranulesPos == GranulesSize) { + std::vector subVec; + vec.push_back(subVec); + GranulesPos = 0; + } + return true; +} + +void HMTypeSigExpr::divideGranulesArray(const ArrayType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + if (!CurType) { + return; + } + uint64_t fieldSize = Ctx.getTypeSize(CurType); + auto elemType = CurType->getElementType(); + uint64_t elemSize = Ctx.getTypeSize(elemType); + for (uint64_t elemPos = 0; elemPos < fieldSize; elemPos += elemSize) { + divideGranules(elemType, Ctx, GranulesPos, vec); + } +} + +void HMTypeSigExpr::divideGranulesVector(const VectorType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + if (!CurType) { + return; + } + unsigned elemNum = CurType->getNumElements();; + auto elemType = CurType->getElementType(); + for (unsigned i = 0; i < elemNum; i++) { + divideGranules(elemType, Ctx, GranulesPos, vec); + } +} + +void HMTypeSigExpr::divideGranulesUnion(const RecordType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + RecordDecl *RD = CurType->getDecl(); + uint64_t UnionSize = Ctx.getTypeSize(CurType); + std::vector> GranulesResult; + uint64_t TmpPos = GranulesPos; + for (auto *Field : RD->fields()) { + std::vector> GranulesVec; + std::vector TmpVec; + GranulesVec.push_back(TmpVec); + TmpPos = GranulesPos; + uint64_t FieldSz = Field->isBitField() ? Field->getBitWidthValue(Ctx) : Ctx.getTypeSize(Field->getType()); + divideGranules(Field, Ctx, TmpPos, GranulesVec); + if (UnionSize > FieldSz) { + uint64_t FieldSize = UnionSize - FieldSz; + divideGranulesBase(PADDING, FieldSize, Ctx, TmpPos, GranulesVec); + } + unsigned i = 0; + unsigned vecSize = GranulesResult.size(); + for (auto tmpVec : GranulesVec) { + if (i < vecSize) { + GranulesResult[i].insert(GranulesResult[i].end(), tmpVec.begin(), tmpVec.end()); + } else { + GranulesResult.push_back(tmpVec); + } + i++; + } + } + for (unsigned i = 0; i < GranulesResult.size(); i++) { + if (i == 0) { + for (auto type : GranulesResult[i]) { + vec.back().push_back(type); + } + } else { + vec.push_back(GranulesResult[i]); + } + } + GranulesPos = TmpPos; +} + +void HMTypeSigExpr::divideGranulesRecord(const RecordType *CurType, const ASTContext &Ctx, uint64_t &GranulesPos, + std::vector> &vec) const { + if (!CurType) { + return; + } + RecordDecl *RD = CurType->getDecl(); + if (!RD->getDefinition()) { + llvm::errs() << RD->getNameAsString() << "not defination cannot get signature.\n"; + return; + } + if (RD->isUnion()) { + return divideGranulesUnion(CurType, Ctx, GranulesPos, vec); + } + uint64_t preFieldEnd = 0, curFieldStart = 0; + const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); + for (auto *Field : RD->fields()) { + curFieldStart = Layout.getFieldOffset(Field->getFieldIndex()); + if (curFieldStart > preFieldEnd) { + uint64_t fieldSize = curFieldStart - preFieldEnd; + divideGranulesBase(PADDING, fieldSize, Ctx, GranulesPos, vec); + } + divideGranules(Field, Ctx, GranulesPos, vec); + uint64_t FieldSz = Field->isBitField() ? Field->getBitWidthValue(Ctx) : Ctx.getTypeSize(Field->getType()); + preFieldEnd = curFieldStart + FieldSz; + } + curFieldStart = Ctx.getTypeSize(CurType); + if (curFieldStart > preFieldEnd) { + uint64_t fieldSize = curFieldStart - preFieldEnd; + divideGranulesBase(PADDING, fieldSize, Ctx, GranulesPos, vec); + } +} + void OMPArrayShapingExpr::setDimensions(ArrayRef Dims) { assert( NumDims == Dims.size() && diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 6c122cac2c60b75122da0b904be26e281569a3f8..b5bdca86cf77f784ce68774f0efed783d6cf123b 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -203,6 +203,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::SourceLocExprClass: case Expr::ConceptSpecializationExprClass: case Expr::RequiresExprClass: + case Expr::HMTypeSigExprClass: return Cl::CL_PRValue; case Expr::ConstantExprClass: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d22135079fa636dde8244b034b16b13de0c87d72..6b1c4d67fc47d089e7228060e38829456bd103e3 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2026,6 +2026,8 @@ static bool IsGlobalLValue(APValue::LValueBase B) { // constructor can produce a constant expression. We must assume that such // an expression might be a global lvalue. return true; + case Expr::HMTypeSigExprClass: + return true; } } @@ -8795,6 +8797,14 @@ public: return true; } + bool VisitHMTypeSigExpr(const HMTypeSigExpr *E) { + if (E->getKind() != UETT_HMTypeSignature) + return false; + APValue LValResult = E->EvaluateTypeSig(Info.Ctx); + Result.setFrom(Info.Ctx, LValResult); + return true; + } + // FIXME: Missing: @protocol, @selector }; } // end anonymous namespace @@ -10985,6 +10995,7 @@ public: bool VisitCastExpr(const CastExpr* E); bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E); + bool VisitHMTypeSigExpr(const HMTypeSigExpr *E); bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { return Success(E->getValue(), E); @@ -13288,6 +13299,10 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr( } return Success(0, E); } + case UETT_HMTypeSummary: + case UETT_HMTypeSignature: { + return false; + } // OHOS_LOCAL End case UETT_OpenMPRequiredSimdAlign: assert(E->isArgumentType()); @@ -13300,6 +13315,14 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr( llvm_unreachable("unknown expr/type trait"); } + +bool IntExprEvaluator::VisitHMTypeSigExpr(const HMTypeSigExpr *E) { + if (E->getKind() != UETT_HMTypeSummary) { + return false; + } + APValue LValResult = E->EvaluateTypeSig(Info.Ctx); + return Success(LValResult, E); +} bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) { CharUnits Result; @@ -15475,6 +15498,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::ArrayTypeTraitExprClass: case Expr::ExpressionTraitExprClass: case Expr::CXXNoexceptExprClass: + case Expr::HMTypeSigExprClass: return NoDiag(); case Expr::CallExprClass: case Expr::CXXOperatorCallExprClass: { diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index b1091945d85f076b841a6bea73e8193344fe6ed9..2341e2c7a36d907b4e8e55eaff751b81592f52da 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4289,6 +4289,7 @@ recurse: case Expr::AtomicExprClass: case Expr::SourceLocExprClass: case Expr::BuiltinBitCastExprClass: + case Expr::HMTypeSigExprClass: { NotPrimaryExpr(); if (!NullOut) { @@ -4692,6 +4693,8 @@ recurse: return; } // OHOS_LOCAL Begin + case UETT_HMTypeSummary: + case UETT_HMTypeSignature: case UETT_PacModifierByType: { return; } diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 625048c69a86427ea4771fb59b8720c68c798d3e..a891ec4fe92861faf08fffdf9e45c6cb6acbf46c 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -2716,6 +2716,10 @@ void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) { OS << ")"; } +void StmtPrinter::VisitHMTypeSigExpr(HMTypeSigExpr *Node) { + OS << Node->getBuiltinStr() << "()"; +} + //===----------------------------------------------------------------------===// // Stmt method implementations //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 92a8b18cf68a30bae0ef4ecce839137bf1a50786..35e289bd2da384ce7860d2a6fa21da57bfa7a028 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2215,6 +2215,10 @@ void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) { void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr *E) { VisitExpr(E); } +void StmtProfiler::VisitHMTypeSigExpr(const HMTypeSigExpr *E) { + VisitExpr(E); +} + void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) { VisitExpr(S); } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 747bb00dee299edb487a428b75bcb97186adb84f..4456e66bcd1421cfbacab8b655f0a5c5455be973 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -646,7 +646,12 @@ public: return ConstantEmitter(CGF).emitAbstract(SLE->getLocation(), Evaluated, SLE->getType()); } - + Value *VisitHMTypeSigExpr(HMTypeSigExpr *SLE) { + auto &Ctx = CGF.getContext(); + APValue Evaluated = SLE->EvaluateTypeSig(Ctx); + return ConstantEmitter(CGF).emitAbstract(SLE->getBeginLoc(), Evaluated, + SLE->getType()); + } Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE); return Visit(DAE->getExpr()); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 2b506786df770a095f44bc7f26c75b4d4c8925c0..e716a4797df3db7588508769cd4b1e62c6177427 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1423,6 +1423,8 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, // unary-expression: '__builtin_omp_required_simd_align' '(' type-name ')' case tok::kw___builtin_omp_required_simd_align: case tok::kw___builtin_get_modifier_bytype: // OHOS_LOCAL + case tok::kw___builtin_hm_type_summary: + case tok::kw___builtin_hm_type_signature: if (NotPrimaryExpression) *NotPrimaryExpression = true; AllowSuffix = false; @@ -2283,12 +2285,11 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, ParsedType &CastTy, SourceRange &CastRange) { - assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_sizeof, tok::kw___alignof, - tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, - tok::kw___builtin_omp_required_simd_align, - tok::kw___builtin_get_modifier_bytype // OHOS_LOCAL - ) && - "Not a typeof/sizeof/alignof/vec_step expression!"); +assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_sizeof, tok::kw___alignof, + tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, + tok::kw___builtin_omp_required_simd_align, tok::kw___builtin_get_modifier_bytype, + tok::kw___builtin_hm_type_summary, tok::kw___builtin_hm_type_signature) && + "Not a typeof/sizeof/alignof/vec_step expression!"); ExprResult Operand; @@ -2297,9 +2298,8 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, // If construct allows a form without parenthesis, user may forget to put // pathenthesis around type name. if (OpTok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, - tok::kw__Alignof, - tok::kw___builtin_get_modifier_bytype // OHOS_LOCAL - )) { + tok::kw__Alignof, tok::kw___builtin_get_modifier_bytype, + tok::kw___builtin_hm_type_summary, tok::kw___builtin_hm_type_signature)) { if (isTypeIdUnambiguously()) { DeclSpec DS(AttrFactory); ParseSpecifierQualifierList(DS); @@ -2408,8 +2408,8 @@ ExprResult Parser::ParseSYCLUniqueStableNameExpression() { ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___alignof, tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, - tok::kw___builtin_omp_required_simd_align, - tok::kw___builtin_get_modifier_bytype) && // OHOS_LOCAL + tok::kw___builtin_omp_required_simd_align, tok::kw___builtin_get_modifier_bytype, + tok::kw___builtin_hm_type_summary, tok::kw___builtin_hm_type_signature) && "Not a sizeof/alignof/vec_step/get_modifier_bytype expression!"); Token OpTok = Tok; ConsumeToken(); @@ -2489,6 +2489,16 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { else if (OpTok.is(tok::kw___builtin_get_modifier_bytype)) ExprKind = UETT_PacModifierByType; // OHOS_LOCAL End + else if (OpTok.is(tok::kw___builtin_hm_type_summary)) + ExprKind = UETT_HMTypeSummary; + else if (OpTok.is(tok::kw___builtin_hm_type_signature)) + ExprKind = UETT_HMTypeSignature; + + if (isCastExpr && + (OpTok.is(tok::kw___builtin_hm_type_summary) || + OpTok.is(tok::kw___builtin_hm_type_signature))) { + return Actions.ActOnHMTypeSig(OpTok.getLocation(), ExprKind, CastTy, CastRange); + } if (isCastExpr) return Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(), ExprKind, diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index d8344cfd01f951365f63efb7b5b3557299e445ca..2c048a1369bf121924104c6f151a6bd66791499f 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1404,6 +1404,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Expr::SourceLocExprClass: case Expr::ConceptSpecializationExprClass: case Expr::RequiresExprClass: + case Expr::HMTypeSigExprClass: // These expressions can never throw. return CT_Cannot; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 83081bbf0aa0c34e9cc1304c90110d44d89cc565..47146e5aaf6f38e0e7cc235c2430f17899e750d5 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -20813,3 +20813,20 @@ ExprResult Sema::CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, return RecoveryExpr::Create(Context, T, Begin, End, SubExprs); } + +// __builtin_hm_type_signature +ExprResult Sema::ActOnHMTypeSig(SourceLocation OpLoc, + UnaryExprOrTypeTrait ExprKind, + ParsedType ParsedTy, SourceRange ArgRange) { + QualType resultTy; + TypeSourceInfo *TInfo; + GetTypeFromParser(ParsedTy, &TInfo); + if (ExprKind == UETT_HMTypeSummary) + resultTy = Context.UnsignedShortTy; + else { // UETT_HMTypeSignature) + QualType ArrTy = Context.getStringLiteralArrayType(Context.CharTy, 0); + resultTy = Context.getPointerType(ArrTy->getAsArrayTypeUnsafe()->getElementType()); + } + return new (Context) + HMTypeSigExpr(ExprKind, TInfo, resultTy, OpLoc, ArgRange.getEnd()); +} diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index a8589191fc919b503a0c76a5804a6706d2471491..2344ac2aeb6d27ba10bf4a117a8750c9c32f29f4 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -11770,6 +11770,11 @@ ExprResult TreeTransform::TransformSourceLocExpr(SourceLocExpr *E) { getSema().CurContext); } +template +ExprResult TreeTransform::TransformHMTypeSigExpr(HMTypeSigExpr *E) { + return E; +} + template ExprResult TreeTransform::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index e0ae019bf803e01a92a83e1591fdf9845b6ae455..e792641c9feae54ef24f7cc915b5fc43925c2bb9 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2191,6 +2191,12 @@ void ASTStmtReader::VisitRecoveryExpr(RecoveryExpr *E) { Child = Record.readSubStmt(); } +void ASTStmtReader::VisitHMTypeSigExpr(HMTypeSigExpr *E) { + VisitExpr(E); + E->setOperatorLoc(readSourceLocation()); + E->setRParenLoc(readSourceLocation()); +} + //===----------------------------------------------------------------------===// // Microsoft Expressions and Statements //===----------------------------------------------------------------------===// @@ -4004,13 +4010,17 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; } - case EXPR_REQUIRES: + case EXPR_REQUIRES: { unsigned numLocalParameters = Record[ASTStmtReader::NumExprFields]; unsigned numRequirement = Record[ASTStmtReader::NumExprFields + 1]; S = RequiresExpr::Create(Context, Empty, numLocalParameters, numRequirement); break; } + case EXPR_HM_TYPE_SIG: + S = new (Context) HMTypeSigExpr(Empty); + break; + } // We hit a STMT_STOP, so we're done with this expression. if (Finished) diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 5e5a86ee01a2baeea224ab5a05c8db1277e83f6a..02542490830f8aca6f4978acd3515bbab3669571 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1273,6 +1273,13 @@ void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) { Code = serialization::EXPR_ATOMIC; } +void ASTStmtWriter::VisitHMTypeSigExpr(HMTypeSigExpr *E) { + VisitExpr(E); + Record.AddSourceLocation(E->getOperatorLoc()); + Record.AddSourceLocation(E->getRParenLoc()); + Code = serialization::EXPR_HM_TYPE_SIG; +} + //===----------------------------------------------------------------------===// // Objective-C Expressions and Statements. //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 19149d0798229a5f4c7e9be6bbbf9ca74d1d15f4..56bd1735b3e0b4255a82d2dde72e07473d9670e6 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1606,6 +1606,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPArrayShapingExprClass: case Stmt::OMPIteratorExprClass: case Stmt::SYCLUniqueStableNameExprClass: + case Stmt::HMTypeSigExprClass: case Stmt::TypeTraitExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet preVisit; diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 15294dac0977dfc0449ee492d593555173c03e70..d28ff01796be840702a47b3f19c76a4f70aef9d1 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -335,6 +335,7 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, case Stmt::ObjCSubscriptRefExprClass: case Stmt::RecoveryExprClass: case Stmt::SYCLUniqueStableNameExprClass: + case Stmt::HMTypeSigExprClass: K = CXCursor_UnexposedExpr; break; diff --git a/llvm/include/llvm/PARTS/Parts.h b/llvm/include/llvm/PARTS/Parts.h index 4c23975f134350c455f4d92abdb7ceb7f119c55f..ad62b5c6358d9ba40afcf35ce44afd023625655c 100644 --- a/llvm/include/llvm/PARTS/Parts.h +++ b/llvm/include/llvm/PARTS/Parts.h @@ -38,6 +38,7 @@ bool useDataFieldTag(); bool useDataFieldProtection(); PartsBeCfiType getBeCfiType(); uint16_t getTypeIdFor(const Type *T); +std::string getLLVMRevision(); } } #endif \ No newline at end of file diff --git a/llvm/lib/PARTS/Parts.cpp b/llvm/lib/PARTS/Parts.cpp index a49b889829a688664d2a74c88d4898a355b8466f..a013a62a926113304d2d4da3a38acda84e253505 100644 --- a/llvm/lib/PARTS/Parts.cpp +++ b/llvm/lib/PARTS/Parts.cpp @@ -136,4 +136,13 @@ uint16_t llvm::PARTS::getTypeIdFor(const Type *T) uint16_t TheTypeId = getTypeId(Buf); TypeIdCache.emplace(T, TheTypeId); return TheTypeId; +} + +std::string llvm::PARTS::getLLVMRevision() +{ +#ifdef LLVM_REVISION + return LLVM_REVISION; +#else + return ""; +#endif } \ No newline at end of file