llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Nhat Nguyen (changkhothuychung) <details> <summary>Changes</summary> First step in adding support for reflection, will add reflection operator parsing for the remaining cases in upcoming subsequent PRs. --- Patch is 22.24 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/164685.diff 27 Files Affected: - (modified) clang/include/clang/AST/ExprCXX.h (+50) - (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+4) - (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+5) - (modified) clang/include/clang/Basic/Features.def (+2) - (modified) clang/include/clang/Basic/LangOptions.def (+1) - (modified) clang/include/clang/Basic/StmtNodes.td (+3) - (modified) clang/include/clang/Basic/TokenKinds.def (+1) - (modified) clang/include/clang/Driver/Options.td (+6-1) - (modified) clang/include/clang/Parse/Parser.h (+6) - (modified) clang/include/clang/Sema/Sema.h (+11) - (modified) clang/include/clang/Serialization/ASTBitCodes.h (+3) - (modified) clang/lib/AST/ExprCXX.cpp (+34) - (modified) clang/lib/AST/ExprClassification.cpp (+1) - (modified) clang/lib/AST/ExprConstant.cpp (+1) - (modified) clang/lib/AST/StmtPrinter.cpp (+6) - (modified) clang/lib/AST/StmtProfile.cpp (+5) - (modified) clang/lib/Lex/Lexer.cpp (+3) - (modified) clang/lib/Parse/CMakeLists.txt (+1) - (modified) clang/lib/Parse/ParseExpr.cpp (+10) - (added) clang/lib/Parse/ParseReflect.cpp (+54) - (modified) clang/lib/Parse/ParseTentative.cpp (+3) - (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+1) - (modified) clang/lib/Sema/SemaExpr.cpp (+19) - (modified) clang/lib/Sema/TreeTransform.h (+6) - (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+9) - (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+6) - (added) clang/test/Reflection/parsing-reflection.pass.cpp (+21) ``````````diff diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 5f16bac94d5e6..5c8b2209d5364 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -5493,6 +5493,56 @@ class BuiltinBitCastExpr final } }; +/// Represents a C++2c reflect expression (P2996). +class CXXReflectExpr : public Expr { + + // Source locations. + SourceLocation OperatorLoc; + SourceRange OperandRange; + + CXXReflectExpr(const ASTContext &C, QualType T, QualType Ty); + CXXReflectExpr(const ASTContext &C, QualType T, Decl *Arg, bool IsNamespace); + CXXReflectExpr(EmptyShell Empty); + +public: + + static CXXReflectExpr *Create(ASTContext &C, SourceLocation OperatorLoc, + SourceLocation ArgLoc, QualType Operand); + + static CXXReflectExpr *Create(ASTContext &C, SourceLocation OperatorLoc, + SourceLocation OperandLoc, Decl *Operand); + + static CXXReflectExpr *CreateEmpty(ASTContext& C); + + SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { + return OperandRange.getEnd(); + } + SourceRange getSourceRange() const { + return SourceRange(getBeginLoc(), getEndLoc()); + } + + /// Returns location of the '^^'-operator. + SourceLocation getOperatorLoc() const { return OperatorLoc; } + SourceRange getOperandRange() const { return OperandRange; } + + /// Sets the location of the '^^'-operator. + void setOperatorLoc(SourceLocation L) { OperatorLoc = L; } + void setOperandRange(SourceRange R) { OperandRange = R; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXReflectExprClass; + } +}; + } // namespace clang #endif // LLVM_CLANG_AST_EXPRCXX_H diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 7a2881f6124f3..7b8a678ffb861 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2883,6 +2883,10 @@ DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); }) +DEF_TRAVERSE_STMT(CXXReflectExpr, { + // TODO +}) + // These expressions all might take explicit template arguments. // We traverse those if so. FIXME: implement these. DEF_TRAVERSE_STMT(CXXConstructExpr, {}) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index c724136a7fdaf..ea81a2332cd50 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1848,6 +1848,11 @@ def err_placeholder_expected_auto_or_decltype_auto : Error< "expected 'auto' or 'decltype(auto)' after concept name">; } +let CategoryName = "Reflection Issue" in { +def err_cannot_reflect_operand : Error< + "cannot reflect the provided operand">; +} + def warn_max_tokens : Warning< "the number of preprocessor source tokens (%0) exceeds this token limit (%1)">, InGroup<MaxTokens>, DefaultIgnore; diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 0e91b42a132c1..c9d24430326ff 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -380,6 +380,8 @@ FEATURE(cxx_abi_relative_vtable, LangOpts.CPlusPlus && LangOpts.RelativeCXXABIVT FEATURE(clang_atomic_attributes, true) +FEATURE(reflection, LangOpts.Reflection) + // CUDA/HIP Features FEATURE(cuda_noinline_keyword, LangOpts.CUDA) EXTENSION(cuda_implicit_host_device_templates, LangOpts.CUDA && LangOpts.OffloadImplicitHostDeviceTemplates) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 84f5ab3443a59..b2051fb536432 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -498,6 +498,7 @@ LANGOPT(BoundsSafety, 1, 0, NotCompatible, "Bounds safety extension for C") LANGOPT(EnableLifetimeSafety, 1, 0, NotCompatible, "Experimental lifetime safety analysis for C++") LANGOPT(PreserveVec3Type, 1, 0, NotCompatible, "Preserve 3-component vector type") +LANGOPT(Reflection , 1, 0, NotCompatible, "C++26 Reflection") #undef LANGOPT #undef ENUM_LANGOPT diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index bf3686bb372d5..987e1d1408e06 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -177,6 +177,9 @@ def CoyieldExpr : StmtNode<CoroutineSuspendExpr>; def ConceptSpecializationExpr : StmtNode<Expr>; def RequiresExpr : StmtNode<Expr>; +// c++ 26 reflection +def CXXReflectExpr : StmtNode<Expr>; + // Obj-C Expressions. def ObjCStringLiteral : StmtNode<Expr>; def ObjCBoxedExpr : StmtNode<Expr>; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 564d6010181cc..b7fef8b2de739 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -233,6 +233,7 @@ PUNCTUATOR(greatergreater, ">>") PUNCTUATOR(greaterequal, ">=") PUNCTUATOR(greatergreaterequal, ">>=") PUNCTUATOR(caret, "^") +PUNCTUATOR(caretcaret, "^^") PUNCTUATOR(caretequal, "^=") PUNCTUATOR(pipe, "|") PUNCTUATOR(pipepipe, "||") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 6245cf33a0719..1880459fab52f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3663,6 +3663,11 @@ defm application_extension : BoolFOption<"application-extension", PosFlag<SetTrue, [], [ClangOption, CC1Option], "Restrict code to those available for App Extensions">, NegFlag<SetFalse>>; +defm reflection : BoolFOption<"reflection", + LangOpts<"Reflection">, DefaultFalse, + PosFlag<SetTrue, [], [ClangOption, CC1Option], + "Enable C++26 reflection">, + NegFlag<SetFalse>>; defm sized_deallocation : BoolFOption<"sized-deallocation", LangOpts<"SizedDeallocation">, Default<cpp14.KeyPath>, PosFlag<SetTrue, [], [], "Enable C++14 sized global deallocation functions">, @@ -7153,7 +7158,7 @@ defm android_pad_segment : BooleanFFlag<"android-pad-segment">, Group<f_Group>; def shared_libflangrt : Flag<["-"], "shared-libflangrt">, HelpText<"Link the flang-rt shared library">, Group<Link_Group>, Visibility<[FlangOption]>, Flags<[NoArgumentUnused]>; -def static_libflangrt : Flag<["-"], "static-libflangrt">, +def static_libflangrt : Flag<["-"], "static-libflangrt">, HelpText<"Link the flang-rt static library">, Group<Link_Group>, Visibility<[FlangOption]>, Flags<[NoArgumentUnused]>; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index e301cf1080977..9b8d8f7633f4d 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -150,6 +150,7 @@ enum class TentativeCXXTypeIdContext { AsTemplateArgument, InTrailingReturnType, AsGenericSelectionArgument, + AsReflectionOperand }; /// The kind of attribute specifier we have found. @@ -5167,6 +5168,11 @@ class Parser : public CodeCompletionHandler { /// Implementations are in ParseHLSL.cpp ///@{ + + //===--------------------------------------------------------------------===// + // C++2c: Reflection [P2996] + ExprResult ParseCXXReflectExpression(SourceLocation OpLoc); + private: bool MaybeParseHLSLAnnotations(Declarator &D, SourceLocation *EndLoc = nullptr, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index f53aafdeb4f36..d07c1160023b3 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14663,6 +14663,17 @@ class Sema final : public SemaBase { /// Implementations are in SemaConcept.cpp ///@{ +public: + + ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, TypeSourceInfo* T); + ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, + SourceLocation ArgLoc, Decl *D); + + ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, + SourceLocation OperandLoc, QualType T); + ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, + SourceLocation OperandLoc, Decl *D); + public: void PushSatisfactionStackEntry(const NamedDecl *D, const llvm::FoldingSetNodeID &ID) { diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 5d09d5536e5ab..b950c444d9aa2 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1925,6 +1925,9 @@ enum StmtCode { EXPR_CONCEPT_SPECIALIZATION, // ConceptSpecializationExpr EXPR_REQUIRES, // RequiresExpr + // Reflection + EXPR_REFLECT, + // CUDA EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 95de6a82a5270..b4758465f669a 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1939,6 +1939,40 @@ TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const ASTContext &C, return new (Mem) TypeTraitExpr(EmptyShell(), IsStoredAsBool); } +CXXReflectExpr::CXXReflectExpr(const ASTContext &C, QualType T, QualType Ty) +: Expr(CXXReflectExprClass, T, VK_PRValue, OK_Ordinary) {} + +CXXReflectExpr::CXXReflectExpr(const ASTContext &C, QualType T, Decl *Arg, bool IsNamespace) +: Expr(CXXReflectExprClass, T, VK_PRValue, OK_Ordinary) {} + +CXXReflectExpr::CXXReflectExpr(EmptyShell Empty) +: Expr(CXXReflectExprClass, Empty) {} + +CXXReflectExpr *CXXReflectExpr::Create(ASTContext &C, SourceLocation OperatorLoc, + SourceLocation OperandLoc, QualType Operand) { + CXXReflectExpr *E = new (C) CXXReflectExpr(C, C.DependentTy, Operand); + E->setOperatorLoc(OperatorLoc); + E->setOperandRange(OperandLoc); + return E; +} + +CXXReflectExpr *CXXReflectExpr::Create(ASTContext &C, + SourceLocation OperatorLoc, + SourceLocation OperandLoc, + Decl *Operand) { + bool IsNamespace = isa<TranslationUnitDecl>(Operand); + + CXXReflectExpr *E = new (C) CXXReflectExpr(C, C.DependentTy, Operand, + IsNamespace); + E->setOperatorLoc(OperatorLoc); + E->setOperandRange(OperandLoc); + return E; +} + +CXXReflectExpr *CXXReflectExpr::CreateEmpty(ASTContext &C) { + return new (C) CXXReflectExpr(EmptyShell()); +} + CUDAKernelCallExpr::CUDAKernelCallExpr(Expr *Fn, CallExpr *Config, ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK, SourceLocation RP, diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index aeacd0dc765ef..4c53c316e989a 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -216,6 +216,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::SourceLocExprClass: case Expr::ConceptSpecializationExprClass: case Expr::RequiresExprClass: + case Expr::CXXReflectExprClass: return Cl::CL_PRValue; case Expr::EmbedExprClass: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index b706b14945b6d..0f14aa3c7258f 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -18295,6 +18295,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::ArrayTypeTraitExprClass: case Expr::ExpressionTraitExprClass: case Expr::CXXNoexceptExprClass: + case Expr::CXXReflectExprClass: return NoDiag(); case Expr::CallExprClass: case Expr::CXXOperatorCallExprClass: { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 586c3000f105c..8e5bab721e8e4 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -2566,6 +2566,12 @@ void StmtPrinter::VisitCXXUnresolvedConstructExpr( OS << ')'; } + +void StmtPrinter::VisitCXXReflectExpr(CXXReflectExpr *S) { + // TODO: Make this better. + OS << "^(...)"; +} + void StmtPrinter::VisitCXXDependentScopeMemberExpr( CXXDependentScopeMemberExpr *Node) { if (!Node->isImplicitAccess()) { diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 589a156a2b6ea..ad37b5e71472e 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2164,6 +2164,11 @@ StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) { ID.AddInteger(Hasher.CalculateHash()); } +void StmtProfiler::VisitCXXReflectExpr(const CXXReflectExpr *E) { + VisitExpr(E); + // TODO: +} + void StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) { VisitExpr(S); diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index b282a600c0e56..5df36d041d0c1 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -4348,6 +4348,9 @@ bool Lexer::LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine) { if (Char == '=') { CurPtr = ConsumeChar(CurPtr, SizeTmp, Result); Kind = tok::caretequal; + } else if (LangOpts.Reflection && Char == '^') { + CurPtr = ConsumeChar(CurPtr, SizeTmp, Result); + Kind = tok::caretcaret; } else { if (LangOpts.OpenCL && Char == '^') Diag(CurPtr, diag::err_opencl_logical_exclusive_or); diff --git a/clang/lib/Parse/CMakeLists.txt b/clang/lib/Parse/CMakeLists.txt index e6cbf3b868b7d..8dd120f529b13 100644 --- a/clang/lib/Parse/CMakeLists.txt +++ b/clang/lib/Parse/CMakeLists.txt @@ -26,6 +26,7 @@ add_clang_library(clangParse ParseTentative.cpp Parser.cpp ParseOpenACC.cpp + ParseReflect.cpp LINK_LIBS clangAST diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 3515343202de1..22963d985b01b 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1208,6 +1208,13 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, AllowSuffix = false; Res = ParseUnaryExprOrTypeTraitExpression(); break; + case tok::caretcaret: { + if (getLangOpts().Reflection) { + SourceLocation FirstCaret = ConsumeToken(); // eat first '^' + Res = ParseCXXReflectExpression(/*OpLoc=*/FirstCaret); + } + break; + } case tok::ampamp: { // unary-expression: '&&' identifier if (NotPrimaryExpression) *NotPrimaryExpression = true; @@ -2249,6 +2256,9 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { else if (getLangOpts().C2y && OpTok.is(tok::kw__Countof)) Diag(OpTok, diag::warn_c2y_compat_keyword) << OpTok.getName(); + if (OpTok.is(tok::caretcaret)) + return ParseCXXReflectExpression(OpTok.getLocation()); + EnterExpressionEvaluationContext Unevaluated( Actions, Sema::ExpressionEvaluationContext::Unevaluated, Sema::ReuseLambdaContextDecl); diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp new file mode 100644 index 0000000000000..817c885ab2804 --- /dev/null +++ b/clang/lib/Parse/ParseReflect.cpp @@ -0,0 +1,54 @@ + + + + +#include "clang/AST/LocInfoType.h" +#include "clang/Basic/DiagnosticParse.h" +#include "clang/Parse/Parser.h" +#include "clang/Parse/RAIIObjectsForParser.h" +#include "clang/Sema/EnterExpressionEvaluationContext.h" +using namespace clang; + +ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { + assert(Tok.is(tok::caretcaret) && "expected '^^'"); + EnterExpressionEvaluationContext Unevaluated( + Actions, Sema::ExpressionEvaluationContext::Unevaluated); + + SourceLocation OperandLoc = Tok.getLocation(); + + // Parse a leading nested-name-specifier + CXXScopeSpec SS; + if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, + /*ObjectHasErrors=*/false, + /*EnteringContext=*/false)) { + SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); + return ExprError(); + } + + { + TentativeParsingAction TPA(*this); + + if (SS.isValid() && + SS.getScopeRep().getKind() == NestedNameSpecifier::Kind::Global) { + // Check for global namespace '^^::' + TPA.Commit(); + Decl *TUDecl = Actions.getASTContext().getTranslationUnitDecl(); + return Actions.ActOnCXXReflectExpr(OpLoc, SourceLocation(), TUDecl); + } + TPA.Revert(); + } + + if (isCXXTypeId(TentativeCXXTypeIdContext::AsReflectionOperand)) { + TypeResult TR = ParseTypeName(/*TypeOf=*/nullptr); + if (TR.isInvalid()) + return ExprError(); + + TypeSourceInfo *TSI = nullptr; + QualType QT = Actions.GetTypeFromParser(TR.get(), &TSI); + + return Actions.ActOnCXXReflectExpr(OpLoc, TSI); + } + + Diag(OperandLoc, diag::err_cannot_reflect_operand); + return ExprError(); +} diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index 82f2294ff5bb7..8a3ae2232767e 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -574,6 +574,9 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { } else if (Context == TentativeCXXTypeIdContext::InTrailingReturnType) { TPR = TPResult::True; isAmbiguous = true; + } else if (Context == TentativeCXXTypeIdContext::AsReflectionOperand) { + TPR = TPResult::True; + isAmbiguous = true; } else TPR = TPResult::False; } diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index a0483c3027199..ff8d2139289a3 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1379,6 +1379,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Expr::CXXNoexceptExprClass: case Expr::CXXNullPtrLiteralExprClass: case Expr::CXXPseudoDestructorExprClass: + case Expr::CXXReflectExprClass: case Expr::CXXScalarValueInitExprClass: case Expr::CXXThisExprClass: case Expr::CXXUuidofExprClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 06b2529011c74..95bc91ab29f90 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -17760,6 +17760,25 @@ void Sema::PushExpressionEvaluationContextForFunction( } } +ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, TypeSourceInfo* TSI) { + return BuildCXXReflectExpr(OpLoc, TSI->getTypeLoc().getBeginLoc(), TSI->getType()); +} + +ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, + SourceLocation ArgLoc, Decl *D) { + return BuildCXXReflectExpr(OpLoc, ArgLoc, D); +} + +ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, + SourceLocation OperandLoc, QualType T) { + return CXXReflectExpr::Create(Context, OperatorLoc, OperandLoc, T); +} + +ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, + SourceLocation OperandLoc, Decl *D) { + return CXXReflectExpr::Create(Context, OperatorLoc, OperandLoc, D); +} + namespace { const DeclRefExpr *CheckPossibleDeref(Sema &S, const Expr *PossibleDeref) { diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 6967301483361..6620c422331e4 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -12873,6 +12873,12 @@ ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr( E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT); } +template <typename Derived> +ExprResult TreeTransform<Derived>::TransformCXXReflectExpr(CXXReflectExpr *E) { + // No subexpressions to recurse over in PR1. + return E; +} + template<typename Derived> ExprResult TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExp... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/164685 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
