https://github.com/changkhothuychung updated https://github.com/llvm/llvm-project/pull/164692
>From 482e25e9ba7994194f564d3c5f34e57bc818ebf0 Mon Sep 17 00:00:00 2001 From: changkhothuychung <[email protected]> Date: Wed, 22 Oct 2025 14:34:06 -0400 Subject: [PATCH 1/9] parsing global namespace and primitive types --- clang/include/clang/AST/ExprCXX.h | 50 +++++++++++++++++ clang/include/clang/AST/RecursiveASTVisitor.h | 4 ++ .../clang/Basic/DiagnosticParseKinds.td | 5 ++ clang/include/clang/Basic/Features.def | 2 + clang/include/clang/Basic/LangOptions.def | 1 + clang/include/clang/Basic/StmtNodes.td | 3 ++ clang/include/clang/Basic/TokenKinds.def | 1 + clang/include/clang/Driver/Options.td | 9 +++- clang/include/clang/Parse/Parser.h | 14 ++++- clang/include/clang/Sema/DeclSpec.h | 2 +- clang/include/clang/Sema/Sema.h | 11 ++++ .../include/clang/Serialization/ASTBitCodes.h | 3 ++ clang/lib/AST/ExprCXX.cpp | 34 ++++++++++++ clang/lib/AST/ExprClassification.cpp | 1 + clang/lib/AST/ExprConstant.cpp | 1 + clang/lib/AST/StmtPrinter.cpp | 6 +++ clang/lib/AST/StmtProfile.cpp | 5 ++ clang/lib/Lex/Lexer.cpp | 3 ++ clang/lib/Parse/CMakeLists.txt | 1 + clang/lib/Parse/ParseExpr.cpp | 10 ++++ clang/lib/Parse/ParseReflect.cpp | 54 +++++++++++++++++++ clang/lib/Parse/ParseTentative.cpp | 3 ++ clang/lib/Sema/SemaExceptionSpec.cpp | 1 + clang/lib/Sema/SemaExpr.cpp | 19 +++++++ clang/lib/Sema/TreeTransform.h | 6 +++ clang/lib/Serialization/ASTReaderStmt.cpp | 9 ++++ clang/lib/Serialization/ASTWriterStmt.cpp | 6 +++ .../Reflection/parsing-reflection.pass.cpp | 21 ++++++++ 28 files changed, 281 insertions(+), 4 deletions(-) create mode 100644 clang/lib/Parse/ParseReflect.cpp create mode 100644 clang/test/Reflection/parsing-reflection.pass.cpp 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..b3d4936354e5e 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, "Experimental 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..b3d6dbfb241d5 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">, @@ -4346,7 +4351,7 @@ def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>, HelpText<"Do not process trigraph sequences">, Visibility<[ClangOption, CC1Option]>; def funique_source_file_names: Flag<["-"], "funique-source-file-names">, Group<f_Group>, - HelpText<"Allow the compiler to assume that each translation unit has a unique " + HelpText<"Allow the compiler to assume that each translation unit has a unique " "source file identifier (see -funique-source-file-identifier) at link time">; def fno_unique_source_file_names: Flag<["-"], "fno-unique-source-file-names">; def unique_source_file_identifier_EQ: Joined<["-"], "funique-source-file-identifier=">, Group<f_Group>, @@ -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..a494c734a074e 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. @@ -1548,6 +1549,7 @@ class Parser : public CodeCompletionHandler { DSC_condition, // condition declaration context DSC_association, // A _Generic selection expression's type association DSC_new, // C++ new expression + DSC_reflect_operator }; /// Is this a context in which we are parsing just a type-specifier (or @@ -1561,6 +1563,7 @@ class Parser : public CodeCompletionHandler { case DeclSpecContext::DSC_top_level: case DeclSpecContext::DSC_objc_method_result: case DeclSpecContext::DSC_condition: + case DeclSpecContext::DSC_reflect_operator: return false; case DeclSpecContext::DSC_template_type_arg: @@ -1619,6 +1622,7 @@ class Parser : public CodeCompletionHandler { case DeclSpecContext::DSC_conv_operator: case DeclSpecContext::DSC_template_arg: case DeclSpecContext::DSC_new: + case DeclSpecContext::DSC_reflect_operator: return AllowDefiningTypeSpec::No; } llvm_unreachable("Missing DeclSpecContext case"); @@ -1643,6 +1647,7 @@ class Parser : public CodeCompletionHandler { case DeclSpecContext::DSC_conv_operator: case DeclSpecContext::DSC_template_arg: case DeclSpecContext::DSC_new: + case DeclSpecContext::DSC_reflect_operator: return false; } @@ -1663,6 +1668,7 @@ class Parser : public CodeCompletionHandler { case DeclSpecContext::DSC_association: case DeclSpecContext::DSC_conv_operator: case DeclSpecContext::DSC_new: + case DeclSpecContext::DSC_reflect_operator: return true; case DeclSpecContext::DSC_objc_method_result: @@ -1694,6 +1700,7 @@ class Parser : public CodeCompletionHandler { case DeclSpecContext::DSC_template_arg: case DeclSpecContext::DSC_conv_operator: case DeclSpecContext::DSC_association: + case DeclSpecContext::DSC_reflect_operator: return ImplicitTypenameContext::No; } llvm_unreachable("Missing DeclSpecContext case"); @@ -5167,6 +5174,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, @@ -7677,7 +7689,7 @@ class Parser : public CodeCompletionHandler { /// [GNU] asm-clobbers: /// asm-string-literal /// asm-clobbers ',' asm-string-literal - /// \endverbatim + /// \endverbatim /// StmtResult ParseAsmStatement(bool &msAsm); diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index c1a99a1fddc80..0e7171f950ee7 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -1849,7 +1849,7 @@ enum class DeclaratorContext { AliasDecl, // C++11 alias-declaration. AliasTemplate, // C++11 alias-declaration template. RequiresExpr, // C++2a requires-expression. - Association // C11 _Generic selection expression association. + Association // C11 _Generic selection expression association. }; // Describes whether the current context is a context where an implicit 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(PredefinedExpr *E) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 70b898a53fcbd..df65909292863 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -529,6 +529,11 @@ void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) { } } + +void ASTStmtReader::VisitCXXReflectExpr(CXXReflectExpr *E) { + llvm_unreachable("unimplemented"); +} + void ASTStmtReader::VisitSYCLKernelCallStmt(SYCLKernelCallStmt *S) { VisitStmt(S); S->setOriginalStmt(cast<CompoundStmt>(Record.readSubStmt())); @@ -4520,6 +4525,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case EXPR_HLSL_OUT_ARG: S = HLSLOutArgExpr::CreateEmpty(Context); break; + case EXPR_REFLECT: { + S = CXXReflectExpr::CreateEmpty(Context); + break; + } } // We hit a STMT_STOP, so we're done with this expression. diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index ebda91e3819c3..1c0ac710cdc98 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -466,6 +466,12 @@ void ASTStmtWriter::VisitCoyieldExpr(CoyieldExpr *E) { Code = serialization::EXPR_COYIELD; } +void ASTStmtWriter::VisitCXXReflectExpr(CXXReflectExpr *E) { + VisitExpr(E); + Record.AddSourceLocation(E->getOperatorLoc()); + Code = serialization::EXPR_REFLECT; +} + void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) { VisitExpr(E); Record.AddSourceLocation(E->getKeywordLoc()); diff --git a/clang/test/Reflection/parsing-reflection.pass.cpp b/clang/test/Reflection/parsing-reflection.pass.cpp new file mode 100644 index 0000000000000..22101970bd2bd --- /dev/null +++ b/clang/test/Reflection/parsing-reflection.pass.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 %s -std=c++23 -freflection + + +int main() +{ + (void)(^^::); + (void)(^^void); + (void)(^^bool); + (void)(^^char); + (void)(^^signed char); + (void)(^^unsigned char); + (void)(^^short); + (void)(^^unsigned short); + (void)(^^int); + (void)(^^unsigned int); + (void)(^^long); + (void)(^^unsigned long); + (void)(^^long long); + (void)(^^float); + (void)(^^double); +} >From c2d6d7ee7c8be9e4800f7e7716a437ad04973604 Mon Sep 17 00:00:00 2001 From: changkhothuychung <[email protected]> Date: Wed, 22 Oct 2025 14:41:01 -0400 Subject: [PATCH 2/9] cleanup --- clang/include/clang/Parse/Parser.h | 8 +------- clang/include/clang/Sema/DeclSpec.h | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index a494c734a074e..b9dfd440c7313 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1548,8 +1548,7 @@ class Parser : public CodeCompletionHandler { // 'instancetype' DSC_condition, // condition declaration context DSC_association, // A _Generic selection expression's type association - DSC_new, // C++ new expression - DSC_reflect_operator + DSC_new // C++ new expression }; /// Is this a context in which we are parsing just a type-specifier (or @@ -1563,7 +1562,6 @@ class Parser : public CodeCompletionHandler { case DeclSpecContext::DSC_top_level: case DeclSpecContext::DSC_objc_method_result: case DeclSpecContext::DSC_condition: - case DeclSpecContext::DSC_reflect_operator: return false; case DeclSpecContext::DSC_template_type_arg: @@ -1622,7 +1620,6 @@ class Parser : public CodeCompletionHandler { case DeclSpecContext::DSC_conv_operator: case DeclSpecContext::DSC_template_arg: case DeclSpecContext::DSC_new: - case DeclSpecContext::DSC_reflect_operator: return AllowDefiningTypeSpec::No; } llvm_unreachable("Missing DeclSpecContext case"); @@ -1647,7 +1644,6 @@ class Parser : public CodeCompletionHandler { case DeclSpecContext::DSC_conv_operator: case DeclSpecContext::DSC_template_arg: case DeclSpecContext::DSC_new: - case DeclSpecContext::DSC_reflect_operator: return false; } @@ -1668,7 +1664,6 @@ class Parser : public CodeCompletionHandler { case DeclSpecContext::DSC_association: case DeclSpecContext::DSC_conv_operator: case DeclSpecContext::DSC_new: - case DeclSpecContext::DSC_reflect_operator: return true; case DeclSpecContext::DSC_objc_method_result: @@ -1700,7 +1695,6 @@ class Parser : public CodeCompletionHandler { case DeclSpecContext::DSC_template_arg: case DeclSpecContext::DSC_conv_operator: case DeclSpecContext::DSC_association: - case DeclSpecContext::DSC_reflect_operator: return ImplicitTypenameContext::No; } llvm_unreachable("Missing DeclSpecContext case"); diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index 0e7171f950ee7..c1a99a1fddc80 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -1849,7 +1849,7 @@ enum class DeclaratorContext { AliasDecl, // C++11 alias-declaration. AliasTemplate, // C++11 alias-declaration template. RequiresExpr, // C++2a requires-expression. - Association // C11 _Generic selection expression association. + Association // C11 _Generic selection expression association. }; // Describes whether the current context is a context where an implicit >From 7c7ac796acd4359e367599a057ae67e72f7f0622 Mon Sep 17 00:00:00 2001 From: changkhothuychung <[email protected]> Date: Wed, 22 Oct 2025 14:50:35 -0400 Subject: [PATCH 3/9] cleanup --- clang/include/clang/Basic/LangOptions.def | 2 +- clang/include/clang/Driver/Options.td | 2 +- clang/include/clang/Parse/Parser.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index b3d4936354e5e..b2051fb536432 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -498,7 +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, "Experimental C++26 Reflection") +LANGOPT(Reflection , 1, 0, NotCompatible, "C++26 Reflection") #undef LANGOPT #undef ENUM_LANGOPT diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index b3d6dbfb241d5..1880459fab52f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4351,7 +4351,7 @@ def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>, HelpText<"Do not process trigraph sequences">, Visibility<[ClangOption, CC1Option]>; def funique_source_file_names: Flag<["-"], "funique-source-file-names">, Group<f_Group>, - HelpText<"Allow the compiler to assume that each translation unit has a unique " + HelpText<"Allow the compiler to assume that each translation unit has a unique " "source file identifier (see -funique-source-file-identifier) at link time">; def fno_unique_source_file_names: Flag<["-"], "fno-unique-source-file-names">; def unique_source_file_identifier_EQ: Joined<["-"], "funique-source-file-identifier=">, Group<f_Group>, diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index b9dfd440c7313..9b8d8f7633f4d 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1548,7 +1548,7 @@ class Parser : public CodeCompletionHandler { // 'instancetype' DSC_condition, // condition declaration context DSC_association, // A _Generic selection expression's type association - DSC_new // C++ new expression + DSC_new, // C++ new expression }; /// Is this a context in which we are parsing just a type-specifier (or @@ -7683,7 +7683,7 @@ class Parser : public CodeCompletionHandler { /// [GNU] asm-clobbers: /// asm-string-literal /// asm-clobbers ',' asm-string-literal - /// \endverbatim + /// \endverbatim /// StmtResult ParseAsmStatement(bool &msAsm); >From 61c7f94abc617fd39ae49ab0a2614a7ad45c6acb Mon Sep 17 00:00:00 2001 From: changkhothuychung <[email protected]> Date: Wed, 22 Oct 2025 14:51:44 -0400 Subject: [PATCH 4/9] cleanup --- clang/include/clang/Driver/Options.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 1880459fab52f..2218a767f0c7a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4351,7 +4351,7 @@ def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>, HelpText<"Do not process trigraph sequences">, Visibility<[ClangOption, CC1Option]>; def funique_source_file_names: Flag<["-"], "funique-source-file-names">, Group<f_Group>, - HelpText<"Allow the compiler to assume that each translation unit has a unique " + HelpText<"Allow the compiler to assume that each translation unit has a unique " "source file identifier (see -funique-source-file-identifier) at link time">; def fno_unique_source_file_names: Flag<["-"], "fno-unique-source-file-names">; def unique_source_file_identifier_EQ: Joined<["-"], "funique-source-file-identifier=">, Group<f_Group>, @@ -7158,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]>; >From 78fe7c41cd8ddee55ac7c9366a673db88b561d2d Mon Sep 17 00:00:00 2001 From: changkhothuychung <[email protected]> Date: Wed, 22 Oct 2025 14:52:49 -0400 Subject: [PATCH 5/9] cleanup --- clang/include/clang/Driver/Options.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 2218a767f0c7a..1880459fab52f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4351,7 +4351,7 @@ def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>, HelpText<"Do not process trigraph sequences">, Visibility<[ClangOption, CC1Option]>; def funique_source_file_names: Flag<["-"], "funique-source-file-names">, Group<f_Group>, - HelpText<"Allow the compiler to assume that each translation unit has a unique " + HelpText<"Allow the compiler to assume that each translation unit has a unique " "source file identifier (see -funique-source-file-identifier) at link time">; def fno_unique_source_file_names: Flag<["-"], "fno-unique-source-file-names">; def unique_source_file_identifier_EQ: Joined<["-"], "funique-source-file-identifier=">, Group<f_Group>, @@ -7158,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]>; >From 5ae087341d1f4a397edea5a1c24917e86f6cbca0 Mon Sep 17 00:00:00 2001 From: changkhothuychung <[email protected]> Date: Wed, 22 Oct 2025 15:22:39 -0400 Subject: [PATCH 6/9] add dummy mangling --- clang/lib/AST/ItaniumMangle.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 2173aed5b45af..18bd38c66b5e9 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4945,6 +4945,12 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, E = cast<ConstantExpr>(E)->getSubExpr(); goto recurse; + case Expr::CXXReflectExprClass: { + // TODO: implement this after introducing std::meta::info + // and add info in APValue + break; + } + // FIXME: invent manglings for all these. case Expr::BlockExprClass: case Expr::ChooseExprClass: >From 4503b11a2036e0f66ab5e789296bf6bc98a4d867 Mon Sep 17 00:00:00 2001 From: changkhothuychung <[email protected]> Date: Wed, 22 Oct 2025 15:22:49 -0400 Subject: [PATCH 7/9] add file description --- clang/lib/Parse/ParseReflect.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index 817c885ab2804..8c974d949d87f 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -1,11 +1,18 @@ - - - +//===--- ParseReflect.cpp - C++2c Reflection Parsing ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements parsing for reflection facilities. +// +//===----------------------------------------------------------------------===// #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; >From 4852569077792a3432c3f1954749b647dd9430a7 Mon Sep 17 00:00:00 2001 From: changkhothuychung <[email protected]> Date: Wed, 22 Oct 2025 15:44:44 -0400 Subject: [PATCH 8/9] clang format --- clang/include/clang/AST/ExprCXX.h | 3 +-- clang/include/clang/AST/RecursiveASTVisitor.h | 4 +--- clang/include/clang/Parse/Parser.h | 8 ++++---- clang/include/clang/Sema/Sema.h | 16 +++++++-------- clang/lib/AST/ExprCXX.cpp | 20 +++++++++++-------- clang/lib/AST/StmtPrinter.cpp | 1 - clang/lib/AST/StmtProfile.cpp | 2 +- clang/lib/Parse/ParseReflect.cpp | 2 +- clang/lib/Sema/SemaExpr.cpp | 6 ++++-- clang/lib/Serialization/ASTReaderStmt.cpp | 1 - 10 files changed, 32 insertions(+), 31 deletions(-) diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 5c8b2209d5364..be2e5ef8644ee 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -5505,14 +5505,13 @@ class CXXReflectExpr : public Expr { 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); + static CXXReflectExpr *CreateEmpty(ASTContext &C); SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; } SourceLocation getEndLoc() const LLVM_READONLY { diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 7b8a678ffb861..827b38a030409 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2883,9 +2883,7 @@ DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); }) -DEF_TRAVERSE_STMT(CXXReflectExpr, { - // TODO -}) +DEF_TRAVERSE_STMT(CXXReflectExpr, {/*TODO*/}) // These expressions all might take explicit template arguments. // We traverse those if so. FIXME: implement these. diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 9b8d8f7633f4d..c819f18675f5d 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -5169,9 +5169,9 @@ class Parser : public CodeCompletionHandler { ///@{ - //===--------------------------------------------------------------------===// - // C++2c: Reflection [P2996] - ExprResult ParseCXXReflectExpression(SourceLocation OpLoc); + //===--------------------------------------------------------------------===// + // C++2c: Reflection [P2996] + ExprResult ParseCXXReflectExpression(SourceLocation OpLoc); private: bool MaybeParseHLSLAnnotations(Declarator &D, @@ -7683,7 +7683,7 @@ class Parser : public CodeCompletionHandler { /// [GNU] asm-clobbers: /// asm-string-literal /// asm-clobbers ',' asm-string-literal - /// \endverbatim + /// \endverbatim /// StmtResult ParseAsmStatement(bool &msAsm); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d07c1160023b3..dd1c577f7b45d 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14665,14 +14665,14 @@ class Sema final : public SemaBase { 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); + 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, diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index b4758465f669a..f3cf5620ed52d 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1940,16 +1940,19 @@ TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const ASTContext &C, } CXXReflectExpr::CXXReflectExpr(const ASTContext &C, QualType T, QualType Ty) -: Expr(CXXReflectExprClass, T, VK_PRValue, OK_Ordinary) {} + : 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(const ASTContext &C, QualType T, Decl *Arg, + bool IsNamespace) + : Expr(CXXReflectExprClass, T, VK_PRValue, OK_Ordinary) {} CXXReflectExpr::CXXReflectExpr(EmptyShell Empty) -: Expr(CXXReflectExprClass, Empty) {} + : Expr(CXXReflectExprClass, Empty) {} -CXXReflectExpr *CXXReflectExpr::Create(ASTContext &C, SourceLocation OperatorLoc, - SourceLocation OperandLoc, QualType Operand) { +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); @@ -1962,8 +1965,9 @@ CXXReflectExpr *CXXReflectExpr::Create(ASTContext &C, Decl *Operand) { bool IsNamespace = isa<TranslationUnitDecl>(Operand); - CXXReflectExpr *E = new (C) CXXReflectExpr(C, C.DependentTy, Operand, - IsNamespace); + CXXReflectExpr *E = + new (C) CXXReflectExpr(C, C.DependentTy, Operand, IsNamespace); + E->setOperatorLoc(OperatorLoc); E->setOperandRange(OperandLoc); return E; diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 8e5bab721e8e4..e3073da1eec9d 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -2566,7 +2566,6 @@ void StmtPrinter::VisitCXXUnresolvedConstructExpr( OS << ')'; } - void StmtPrinter::VisitCXXReflectExpr(CXXReflectExpr *S) { // TODO: Make this better. OS << "^(...)"; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index ad37b5e71472e..56bbffdebb276 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2166,7 +2166,7 @@ StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) { void StmtProfiler::VisitCXXReflectExpr(const CXXReflectExpr *E) { VisitExpr(E); - // TODO: + // TODO: } void diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index 8c974d949d87f..541cbd90261ea 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -36,7 +36,7 @@ ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { TentativeParsingAction TPA(*this); if (SS.isValid() && - SS.getScopeRep().getKind() == NestedNameSpecifier::Kind::Global) { + SS.getScopeRep().getKind() == NestedNameSpecifier::Kind::Global) { // Check for global namespace '^^::' TPA.Commit(); Decl *TUDecl = Actions.getASTContext().getTranslationUnitDecl(); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 95bc91ab29f90..239e3382c1ff6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -17760,8 +17760,10 @@ void Sema::PushExpressionEvaluationContextForFunction( } } -ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, TypeSourceInfo* TSI) { - return BuildCXXReflectExpr(OpLoc, TSI->getTypeLoc().getBeginLoc(), TSI->getType()); +ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, + TypeSourceInfo *TSI) { + return BuildCXXReflectExpr(OpLoc, TSI->getTypeLoc().getBeginLoc(), + TSI->getType()); } ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index df65909292863..c127ceac245d0 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -529,7 +529,6 @@ void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) { } } - void ASTStmtReader::VisitCXXReflectExpr(CXXReflectExpr *E) { llvm_unreachable("unimplemented"); } >From d3f0f70c9128dbb549e0d056c41777c4c05b90e7 Mon Sep 17 00:00:00 2001 From: changkhothuychung <[email protected]> Date: Wed, 22 Oct 2025 15:48:01 -0400 Subject: [PATCH 9/9] clang format --- clang/include/clang/Parse/Parser.h | 1 - clang/include/clang/Sema/Sema.h | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index c819f18675f5d..6fab68c1a1689 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -5168,7 +5168,6 @@ class Parser : public CodeCompletionHandler { /// Implementations are in ParseHLSL.cpp ///@{ - //===--------------------------------------------------------------------===// // C++2c: Reflection [P2996] ExprResult ParseCXXReflectExpression(SourceLocation OpLoc); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index dd1c577f7b45d..12ee9e348ef01 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14665,14 +14665,14 @@ class Sema final : public SemaBase { public: - ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, TypeSourceInfo* T); + ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, TypeSourceInfo *T); ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, SourceLocation ArgLoc, Decl *D); ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, - SourceLocation OperandLoc, QualType T); + SourceLocation OperandLoc, QualType T); ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, - SourceLocation OperandLoc, Decl *D); + SourceLocation OperandLoc, Decl *D); public: void PushSatisfactionStackEntry(const NamedDecl *D, _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
