From 2a2b29e68a759042e0452db1f617abeff5c8b2c4 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 6 Oct 2024 14:51:04 +0900 Subject: [PATCH 01/26] Stash clueless hacks --- clang/include/clang/AST/APValue.h | 4 + clang/include/clang/AST/Reflection.h | 10 +- clang/include/clang/Sema/Sema.h | 148 ++++----- clang/lib/AST/ComputeDependence.cpp | 23 +- clang/lib/Parse/ParseReflect.cpp | 60 ++-- clang/lib/Sema/SemaReflect.cpp | 436 ++++++++++++++------------- 6 files changed, 339 insertions(+), 342 deletions(-) diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 21647ffa5ac5a4..27dd22a2d82ffb 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -489,6 +489,10 @@ class APValue { return isReflection() && getReflectionKind() == ReflectionKind::Annotation; } + bool isReflectedAttribute() const { + return isReflection() && getReflectionKind() == ReflectionKind::Attribute; + } + void dump() const; void dump(raw_ostream &OS, const ASTContext &Context) const; diff --git a/clang/include/clang/AST/Reflection.h b/clang/include/clang/AST/Reflection.h index 5838d310e00c5f..e31df466ddeeb2 100644 --- a/clang/include/clang/AST/Reflection.h +++ b/clang/include/clang/AST/Reflection.h @@ -48,7 +48,7 @@ enum class ReflectionKind { /// /// Corresponds to an APValue (plus a QualType). Object, - + /// \brief A reflection of a value (i.e., the result of a prvalue). /// /// Corresponds to an APValue (plus a QualType). @@ -102,8 +102,10 @@ enum class ReflectionKind { /// \brief A reflection of an annotation (P2996 ext). Annotation, -}; + /// \brief A reflection of a standard attribute (P3385). + Attribute, +}; /// \brief Representation of a hypothetical data member, which could be used to /// complete an incomplete class definition using the 'std::meta::define_class' @@ -116,8 +118,8 @@ struct TagDataMemberSpec { std::optional BitWidth; bool NoUniqueAddress; - bool operator==(TagDataMemberSpec const& Rhs) const; - bool operator!=(TagDataMemberSpec const& Rhs) const; + bool operator==(TagDataMemberSpec const &Rhs) const; + bool operator!=(TagDataMemberSpec const &Rhs) const; }; } // namespace clang diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 302caa65c0e2d1..828da165022cbf 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4888,12 +4888,9 @@ class Sema final : public SemaBase { SourceLocation AliasLoc, IdentifierInfo *Alias, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *Ident); - Decl *ActOnNamespaceAliasDef(Scope *CurScope, - SourceLocation NamespaceLoc, - SourceLocation AliasLoc, - IdentifierInfo *Alias, - CXXScopeSpec &SS, - SourceLocation IdentLoc, + Decl *ActOnNamespaceAliasDef(Scope *CurScope, SourceLocation NamespaceLoc, + SourceLocation AliasLoc, IdentifierInfo *Alias, + CXXScopeSpec &SS, SourceLocation IdentLoc, NamedDecl *ND); /// Remove decls we can't actually see from a lookup being used to declare @@ -8570,12 +8567,11 @@ class Sema final : public SemaBase { Scope *BodyScope); void ActOnFinishRequiresExpr(); concepts::Requirement *ActOnSimpleRequirement(Expr *E); - concepts::Requirement *ActOnTypeRequirement(SourceLocation TypenameKWLoc, - CXXScopeSpec &SS, - SourceLocation NameLoc, - const IdentifierInfo *TypeName, - TemplateIdAnnotation *TemplateId, - CXXSpliceSpecifierExpr *SpliceExpr); + concepts::Requirement * + ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS, + SourceLocation NameLoc, const IdentifierInfo *TypeName, + TemplateIdAnnotation *TemplateId, + CXXSpliceSpecifierExpr *SpliceExpr); concepts::Requirement *ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc); concepts::Requirement *ActOnCompoundRequirement( @@ -15164,15 +15160,16 @@ class Sema final : public SemaBase { bool suppressDiagnostics() const { return SuppressDiagnostics; } ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, - SourceLocation TemplateKWLoc, - CXXScopeSpec &SS, UnqualifiedId &Id); + SourceLocation TemplateKWLoc, CXXScopeSpec &SS, + UnqualifiedId &Id); ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, TypeResult T); - ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, - SourceLocation ArgLoc, Decl *D); + ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, SourceLocation ArgLoc, + Decl *D); ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, ParsedTemplateArgument Template); ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, CXXSpliceExpr *E); + ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, ParsedAttr *a); ExprResult ActOnCXXMetafunction(SourceLocation KwLoc, SourceLocation LParenLoc, @@ -15182,13 +15179,10 @@ class Sema final : public SemaBase { SourceLocation LSpliceLoc, Expr *Operand, SourceLocation RSpliceLoc); - TypeResult ActOnCXXSpliceExpectingType(SourceLocation LSplice, - Expr *Operand, - SourceLocation RSplice, - bool Complain); + TypeResult ActOnCXXSpliceExpectingType(SourceLocation LSplice, Expr *Operand, + SourceLocation RSplice, bool Complain); ExprResult ActOnCXXSpliceExpectingExpr(SourceLocation TemplateKWLoc, - SourceLocation LSplice, - Expr *Operand, + SourceLocation LSplice, Expr *Operand, SourceLocation RSplice, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, @@ -15204,14 +15198,13 @@ class Sema final : public SemaBase { ParsedTemplateArgument ActOnTemplateSpliceSpecifierArgument(CXXSpliceSpecifierExpr *Splice); - bool ActOnCXXNestedNameSpecifierReflectionSplice( - CXXScopeSpec &SS, CXXSpliceSpecifierExpr *Splice, - SourceLocation ColonColonLoc); + bool + ActOnCXXNestedNameSpecifierReflectionSplice(CXXScopeSpec &SS, + CXXSpliceSpecifierExpr *Splice, + SourceLocation ColonColonLoc); - ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - CXXSpliceExpr *RHS, + ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, + tok::TokenKind OpKind, CXXSpliceExpr *RHS, SourceLocation TemplateKWLoc); // Reflection of non-expression operands. @@ -15229,8 +15222,8 @@ class Sema final : public SemaBase { UnresolvedLookupExpr *E); ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, SubstNonTypeTemplateParmExpr *E); - ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, - CXXSpliceExpr *E); + ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, CXXSpliceExpr *E); + ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, ParsedAttr *A); ExprResult BuildCXXMetafunctionExpr(SourceLocation KwLoc, SourceLocation LParenLoc, @@ -15243,13 +15236,11 @@ class Sema final : public SemaBase { SourceLocation LSpliceLoc, Expr *Operand, SourceLocation RSpliceLoc); - QualType BuildReflectionSpliceType(SourceLocation LSplice, - Expr *Operand, - SourceLocation RSplice, - bool Complain); + QualType BuildReflectionSpliceType(SourceLocation LSplice, Expr *Operand, + SourceLocation RSplice, bool Complain); QualType BuildReflectionSpliceTypeLoc(TypeLocBuilder &TLB, - SourceLocation LSpliceLoc, - Expr *E, SourceLocation RSpliceLoc, + SourceLocation LSpliceLoc, Expr *E, + SourceLocation RSpliceLoc, bool Complain); ExprResult BuildReflectionSpliceExpr(SourceLocation TemplateKWLoc, SourceLocation LSplice, Expr *Operand, @@ -15266,8 +15257,7 @@ class Sema final : public SemaBase { ExprResult BuildMemberReferenceExpr(Scope *S, Expr *Base, SourceLocation OpLoc, - tok::TokenKind OpKind, - CXXSpliceExpr *RHS, + tok::TokenKind OpKind, CXXSpliceExpr *RHS, SourceLocation TemplateKWLoc); ExprResult BuildDependentMemberSpliceExpr(Expr *Base, SourceLocation OpLoc, bool IsArrow, CXXSpliceExpr *RHS); @@ -15280,10 +15270,10 @@ class Sema final : public SemaBase { // Lambdas having bound references to this Sema object, used to evaluate // metafunction (C++26, P2996) at constant evaluation time. llvm::SmallDenseMap> - MetafunctionImplCbs; + MetafunctionImplCbs; // Whether to elide access control when checking access to class members. - bool EllideAccessControl {false}; + bool EllideAccessControl{false}; // Used to check whether a template substitution is valid without producing // a diagnostic. @@ -15291,16 +15281,16 @@ class Sema final : public SemaBase { class AccessControlScopeGuard final { public: - AccessControlScopeGuard(const AccessControlScopeGuard&) = delete; - AccessControlScopeGuard(AccessControlScopeGuard&&) = delete; - AccessControlScopeGuard& operator=(const AccessControlScopeGuard&) = delete; - AccessControlScopeGuard& operator=(AccessControlScopeGuard&&) = delete; + AccessControlScopeGuard(const AccessControlScopeGuard &) = delete; + AccessControlScopeGuard(AccessControlScopeGuard &&) = delete; + AccessControlScopeGuard & + operator=(const AccessControlScopeGuard &) = delete; + AccessControlScopeGuard &operator=(AccessControlScopeGuard &&) = delete; // Sets EllideAccessControl to the new override value & keeps the // previous one, so we can revert when the scope guard exits explicit AccessControlScopeGuard(Sema &S, bool ellideAccessControlOverride) - : S_{S} - , previousEllideAccessControl_{S_.EllideAccessControl} { + : S_{S}, previousEllideAccessControl_{S_.EllideAccessControl} { S_.EllideAccessControl = ellideAccessControlOverride; } @@ -15310,7 +15300,7 @@ class Sema final : public SemaBase { private: Sema &S_; - bool previousEllideAccessControl_ {false}; + bool previousEllideAccessControl_{false}; }; ///@} @@ -15334,26 +15324,17 @@ class Sema final : public SemaBase { SourceLocation RParenLoc, BuildForRangeKind Kind); - StmtResult ActOnCXXInitListExpansionStmt(SourceLocation TemplateKWLoc, - SourceLocation ForLoc, - SourceLocation LParenLoc, Stmt *Init, - Stmt *ExpansionVarStmt, - SourceLocation ColonLoc, - CXXExpansionInitListExpr *Range, - SourceLocation RParenLoc, - Expr *TParmRef, - BuildForRangeKind Kind); - - StmtResult ActOnCXXDestructurableExpansionStmt(SourceLocation TemplateKWLoc, - SourceLocation ForLoc, - SourceLocation LParenLoc, - Stmt *Init, - Stmt *ExpansionVarStmt, - SourceLocation ColonLoc, - Expr *Range, - SourceLocation RParenLoc, - Expr *TParmRef, - BuildForRangeKind Kind); + StmtResult ActOnCXXInitListExpansionStmt( + SourceLocation TemplateKWLoc, SourceLocation ForLoc, + SourceLocation LParenLoc, Stmt *Init, Stmt *ExpansionVarStmt, + SourceLocation ColonLoc, CXXExpansionInitListExpr *Range, + SourceLocation RParenLoc, Expr *TParmRef, BuildForRangeKind Kind); + + StmtResult ActOnCXXDestructurableExpansionStmt( + SourceLocation TemplateKWLoc, SourceLocation ForLoc, + SourceLocation LParenLoc, Stmt *Init, Stmt *ExpansionVarStmt, + SourceLocation ColonLoc, Expr *Range, SourceLocation RParenLoc, + Expr *TParmRef, BuildForRangeKind Kind); bool ComputeDecompositionExpansionArity(Expr *Range, unsigned &Result); @@ -15369,26 +15350,17 @@ class Sema final : public SemaBase { ExprResult ActOnCXXDestructurableExpansionSelectExpr(Expr *Range, Expr *Idx, bool Constexpr); - StmtResult BuildCXXInitListExpansionStmt(SourceLocation TemplateKWLoc, - SourceLocation ForLoc, - SourceLocation LParenLoc, Stmt *Init, - Stmt *ExpansionVarStmt, - SourceLocation ColonLoc, - CXXExpansionInitListExpr *Range, - SourceLocation RParenLoc, - unsigned TemplateDepth, - BuildForRangeKind Kind); - - StmtResult BuildCXXDestructurableExpansionStmt(SourceLocation TemplateKWLoc, - SourceLocation ForLoc, - SourceLocation LParenLoc, - Stmt *Init, - Stmt *ExpansionVarStmt, - SourceLocation ColonLoc, - Expr *Range, - SourceLocation RParenLoc, - unsigned TemplateDepth, - BuildForRangeKind Kind); + StmtResult BuildCXXInitListExpansionStmt( + SourceLocation TemplateKWLoc, SourceLocation ForLoc, + SourceLocation LParenLoc, Stmt *Init, Stmt *ExpansionVarStmt, + SourceLocation ColonLoc, CXXExpansionInitListExpr *Range, + SourceLocation RParenLoc, unsigned TemplateDepth, BuildForRangeKind Kind); + + StmtResult BuildCXXDestructurableExpansionStmt( + SourceLocation TemplateKWLoc, SourceLocation ForLoc, + SourceLocation LParenLoc, Stmt *Init, Stmt *ExpansionVarStmt, + SourceLocation ColonLoc, Expr *Range, SourceLocation RParenLoc, + unsigned TemplateDepth, BuildForRangeKind Kind); ExprResult BuildCXXExpansionInitList(SourceLocation LBraceLoc, MultiExprArg SubExprs, diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index a2608a5d0dd2a9..e8f59fc272a69d 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -18,6 +18,7 @@ #include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExprOpenMP.h" +#include "clang/AST/Reflection.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "llvm/ADT/ArrayRef.h" @@ -470,7 +471,7 @@ ExprDependence clang::computeDependence(ArraySectionExpr *E) { ExprDependence clang::computeDependence(OMPArrayShapingExpr *E) { auto D = E->getBase()->getDependence(); - for (Expr *Dim: E->getDimensions()) + for (Expr *Dim : E->getDimensions()) if (Dim) D |= turnValueToTypeDependence(Dim->getDependence()); return D; @@ -935,7 +936,7 @@ ExprDependence clang::computeDependence(ConceptSpecializationExpr *E, ExprDependence D = ValueDependent ? ExprDependence::Value : ExprDependence::None; auto Res = D | toExprDependence(TA); - if(!ValueDependent && E->getSatisfaction().ContainsErrors) + if (!ValueDependent && E->getSatisfaction().ContainsErrors) Res |= ExprDependence::Error; return Res; } @@ -986,21 +987,21 @@ ExprDependence clang::computeDependence(CXXReflectExpr *E, case ReflectionKind::Namespace: case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: + case ReflectionKind::Attribute: return ExprDependence::None; } llvm_unreachable("unknown reflection kind while computing dependence"); } ExprDependence clang::computeDependence(CXXMetafunctionExpr *E) { - auto D = ExprDependence::None; - for (unsigned I = 0; I < E->getNumArgs(); ++I) { - Expr *Arg = E->getArg(I); - D |= Arg->getDependence(); - } - return D & ~ExprDependence::UnexpandedPack; + auto D = ExprDependence::None; + for (unsigned I = 0; I < E->getNumArgs(); ++I) { + Expr *Arg = E->getArg(I); + D |= Arg->getDependence(); + } + return D & ~ExprDependence::UnexpandedPack; } - ExprDependence clang::computeDependence(CXXSpliceSpecifierExpr *E) { return E->getOperand()->getDependence(); } @@ -1046,8 +1047,8 @@ ExprDependence clang::computeDependence(CXXExpansionInitListSelectExpr *E) { return D; } -ExprDependence clang::computeDependence( - CXXDestructurableExpansionSelectExpr *E) { +ExprDependence +clang::computeDependence(CXXDestructurableExpansionSelectExpr *E) { auto D = E->getRange()->getDependence() | E->getIdx()->getDependence(); if (D & ExprDependence::Value) D |= ExprDependence::Type; diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index f76bb6b1c7ee73..25413c424191a3 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -16,13 +16,15 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" +#include "clang/Sema/Ownership.h" +#include "clang/Sema/ParsedAttr.h" using namespace clang; ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { SourceLocation OperandLoc = Tok.getLocation(); EnterExpressionEvaluationContext EvalContext( - Actions, Sema::ExpressionEvaluationContext::ReflectionContext); + Actions, Sema::ExpressionEvaluationContext::ReflectionContext); // Parse a leading nested-name-specifier, e.g., // @@ -40,6 +42,24 @@ ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { // TentativeParsingAction TentativeAction(*this); + // Check for a standard attribute + { + assert(true && "P3385 - ParseCXXReflectExpression"); + ParsedAttributes attrs(AttrFactory); + if (MaybeParseAttributes(CXX11AttributeKind::CAK_AttributeSpecifier, + attrs)) { + if (attrs.size() > 1) { + assert(attrs.size() == 1 && "Attributes list are not supported"); + TentativeAction.Revert(); + return ExprError(); + } + + TentativeAction.Commit(); + return Actions.ActOnCXXReflectExpr(OpLoc, &attrs.front()); + } + TentativeAction.Revert(); + } + // Next, check for an unqualified-id. if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::kw_template, tok::tilde, tok::annot_template_id)) { @@ -79,9 +99,8 @@ ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { } TentativeAction.Revert(); - if (SS.isSet() && - TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, true, - ImplicitTypenameContext::No)) { + if (SS.isSet() && TryAnnotateTypeOrScopeTokenAfterScopeSpec( + SS, true, ImplicitTypenameContext::No)) { SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); return ExprError(); } @@ -168,8 +187,7 @@ bool Parser::ParseCXXSpliceSpecifier(SourceLocation TemplateKWLoc) { return false; } -TypeResult Parser::ParseCXXSpliceAsType(bool AllowDependent, - bool Complain) { +TypeResult Parser::ParseCXXSpliceAsType(bool AllowDependent, bool Complain) { assert(Tok.is(tok::annot_splice) && "expected annot_splice"); if (NextToken().is(tok::less)) { @@ -191,8 +209,7 @@ TypeResult Parser::ParseCXXSpliceAsType(bool AllowDependent, return TypeError(); TypeResult Result = Actions.ActOnCXXSpliceExpectingType( - Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc(), - Complain); + Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc(), Complain); if (!Result.isInvalid()) ConsumeAnnotationToken(); @@ -214,8 +231,8 @@ ExprResult Parser::ParseCXXSpliceAsExpr(bool AllowMemberReference) { SourceLocation LAngleLoc, RAngleLoc; if (TemplateKWLoc.isValid() && Tok.is(tok::less)) { TemplateArgList TArgs; - if (ParseTemplateIdAfterTemplateName(/*ConsumeLastToken=*/true, - LAngleLoc, TArgs, RAngleLoc, + if (ParseTemplateIdAfterTemplateName(/*ConsumeLastToken=*/true, LAngleLoc, + TArgs, RAngleLoc, /*Template=*/nullptr)) return ExprError(); @@ -237,7 +254,7 @@ DeclResult Parser::ParseCXXSpliceAsNamespace() { assert(!ER.isInvalid()); DeclResult Result = Actions.ActOnCXXSpliceExpectingNamespace( - Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc()); + Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc()); return Result; } @@ -251,9 +268,9 @@ Parser::TemplateTy Parser::ParseCXXSpliceAsTemplate() { ExprResult ER = getExprAnnotation(Splice); assert(!ER.isInvalid()); - return Actions.ActOnCXXSpliceExpectingTemplate( - Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc(), - /*Complain=*/true); + return Actions.ActOnCXXSpliceExpectingTemplate(Splice.getLocation(), ER.get(), + Splice.getAnnotationEndLoc(), + /*Complain=*/true); } static TemplateNameKind classifyTemplateDecl(TemplateName TName) { @@ -286,8 +303,7 @@ bool Parser::ParseTemplateAnnotationFromSplice(SourceLocation TemplateKWLoc, ConsumeAnnotationToken(); TemplateTy Template = Actions.ActOnCXXSpliceExpectingTemplate( - Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc(), - Complain); + Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc(), Complain); if (!Template) return true; bool IsDependent = Template.get().isDependent(); @@ -317,12 +333,12 @@ bool Parser::ParseTemplateAnnotationFromSplice(SourceLocation TemplateKWLoc, CXXScopeSpec SS; ASTTemplateArgsPtr TArgsPtr(TArgs); - TypeResult Type = ArgsInvalid - ? TypeError() - : Actions.ActOnTemplateIdType( - getCurScope(), SS, TemplateKWLoc, Template, - nullptr, TemplateNameLoc, LAngleLoc, TArgsPtr, - RAngleLoc); + TypeResult Type = + ArgsInvalid + ? TypeError() + : Actions.ActOnTemplateIdType(getCurScope(), SS, TemplateKWLoc, + Template, nullptr, TemplateNameLoc, + LAngleLoc, TArgsPtr, RAngleLoc); Tok.setKind(tok::annot_typename); setTypeAnnotation(Tok, Type); diff --git a/clang/lib/Sema/SemaReflect.cpp b/clang/lib/Sema/SemaReflect.cpp index 15ccf9cf6396fd..1a637a7bdfe1ab 100644 --- a/clang/lib/Sema/SemaReflect.cpp +++ b/clang/lib/Sema/SemaReflect.cpp @@ -18,9 +18,11 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/MetaActions.h" #include "clang/AST/Metafunction.h" +#include "clang/AST/Reflection.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" #include "clang/Sema/Lookup.h" +#include "clang/Sema/ParsedAttr.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Sema.h" #include "clang/Sema/Template.h" @@ -35,9 +37,8 @@ TemplateArgumentListInfo addLocToTemplateArgs(Sema &S, ArrayRef Args, SourceLocation ExprLoc) { auto convert = [&](const TemplateArgument &TA) -> TemplateArgumentLoc { - return S.getTrivialTemplateArgumentLoc(TA, - TA.getNonTypeTemplateArgumentType(), - ExprLoc); + return S.getTrivialTemplateArgumentLoc( + TA, TA.getNonTypeTemplateArgumentType(), ExprLoc); }; TemplateArgumentListInfo Result; @@ -51,8 +52,7 @@ TemplateArgumentListInfo addLocToTemplateArgs(Sema &S, return Result; } -Expr *CreateRefToDecl(Sema &S, ValueDecl *D, - SourceLocation ExprLoc) { +Expr *CreateRefToDecl(Sema &S, ValueDecl *D, SourceLocation ExprLoc) { NestedNameSpecifierLocBuilder NNSLocBuilder; if (const auto *RDC = dyn_cast(D->getDeclContext())) { QualType QT(RDC->getTypeForDecl(), 0); @@ -66,14 +66,13 @@ Expr *CreateRefToDecl(Sema &S, ValueDecl *D, VTSD && VTSD->getTemplateSpecializationKind() == TSK_Undeclared) { const TemplateArgumentList &TAList = VTSD->getTemplateArgs(); TemplateArgumentListInfo TAListInfo( - addLocToTemplateArgs(S, TAList.asArray(), ExprLoc)); + addLocToTemplateArgs(S, TAList.asArray(), ExprLoc)); CXXScopeSpec SS; DeclarationNameInfo DNI(VTSD->getDeclName(), ExprLoc); - ExprResult ER = S.CheckVarTemplateId(SS, DNI, - VTSD->getSpecializedTemplate(), - VTSD->getSpecializedTemplate(), - ExprLoc, &TAListInfo); + ExprResult ER = S.CheckVarTemplateId( + SS, DNI, VTSD->getSpecializedTemplate(), VTSD->getSpecializedTemplate(), + ExprLoc, &TAListInfo); return ER.get(); } else { QualType QT(D->getType()); @@ -99,18 +98,14 @@ class MetaActionsImpl : public MetaActions { ArrayRef TArgs, SourceLocation InstantiateLoc) { for (const TemplateArgument &Arg : TArgs) - TAListInfo.addArgument( - S.getTrivialTemplateArgumentLoc(Arg, - Arg.getNonTypeTemplateArgumentType(), - InstantiateLoc)); + TAListInfo.addArgument(S.getTrivialTemplateArgumentLoc( + Arg, Arg.getNonTypeTemplateArgumentType(), InstantiateLoc)); } public: - MetaActionsImpl(Sema &S) : MetaActions(), S(S) { } + MetaActionsImpl(Sema &S) : MetaActions(), S(S) {} - Decl *CurrentCtx() const override { - return cast(S.CurContext); - } + Decl *CurrentCtx() const override { return cast(S.CurContext); } bool IsAccessible(NamedDecl *Target, DeclContext *Ctx) override { bool Result = false; @@ -134,8 +129,8 @@ class MetaActionsImpl : public MetaActions { } bool IsAccessibleBase(QualType BaseTy, QualType DerivedTy, - const CXXBasePath &Path, - DeclContext *Ctx, SourceLocation AccessLoc) override { + const CXXBasePath &Path, DeclContext *Ctx, + SourceLocation AccessLoc) override { Sema::AccessResult Result; DeclContext *PreviousDC = S.CurContext; @@ -151,7 +146,7 @@ class MetaActionsImpl : public MetaActions { bool EnsureInstantiated(Decl *D, SourceRange Range) override { auto validateConstraints = [&](TemplateDecl *TDecl, - ArrayRef TArgs) { + ArrayRef TArgs) { MultiLevelTemplateArgumentList MLTAL(TDecl, TArgs, false); if (S.EnsureTemplateArgumentListConstraints(TDecl, MLTAL, Range)) return false; @@ -170,13 +165,14 @@ class MetaActionsImpl : public MetaActions { return true; if (S.InstantiateClassTemplateSpecialization( - Range.getBegin(), CTSD, TSK_ExplicitInstantiationDefinition, false)) + Range.getBegin(), CTSD, TSK_ExplicitInstantiationDefinition, + false)) return false; S.InstantiateClassTemplateSpecializationMembers( - Range.getBegin(), CTSD, TSK_ExplicitInstantiationDefinition); + Range.getBegin(), CTSD, TSK_ExplicitInstantiationDefinition); } else if (auto *VTSD = dyn_cast(D); - VTSD && !VTSD->isCompleteDefinition()) { + VTSD && !VTSD->isCompleteDefinition()) { if (!validateConstraints(VTSD->getSpecializedTemplate(), VTSD->getTemplateArgs().asArray())) return true; @@ -185,9 +181,10 @@ class MetaActionsImpl : public MetaActions { } else if (auto *FD = dyn_cast(D); FD && FD->isTemplateInstantiation()) { if (FD->getTemplateSpecializationArgs()) - if (!validateConstraints(FD->getPrimaryTemplate(), - FD->getTemplateSpecializationArgs()->asArray())) - return true; + if (!validateConstraints( + FD->getPrimaryTemplate(), + FD->getTemplateSpecializationArgs()->asArray())) + return true; S.InstantiateFunctionDefinition(Range.getBegin(), FD, true, true); } @@ -284,8 +281,8 @@ class MetaActionsImpl : public MetaActions { TemplateArgumentListInfo TAListInfo; populateTemplateArgumentListInfo(TAListInfo, TArgs, InstantiateLoc); - DeclResult Result = S.CheckVarTemplateId(TD, InstantiateLoc, - InstantiateLoc, TAListInfo); + DeclResult Result = + S.CheckVarTemplateId(TD, InstantiateLoc, InstantiateLoc, TAListInfo); if (Result.isInvalid()) return nullptr; Spec = cast(Result.get()); @@ -304,15 +301,14 @@ class MetaActionsImpl : public MetaActions { CXXScopeSpec SS; DeclarationNameInfo DNI(TD->getDeclName(), InstantiateLoc); - ExprResult Result = S.CheckConceptTemplateId(SS, InstantiateLoc, DNI, TD, - TD, &TAListInfo); + ExprResult Result = + S.CheckConceptTemplateId(SS, InstantiateLoc, DNI, TD, TD, &TAListInfo); return Result.get(); } - Expr * - SynthesizeDirectMemberAccess(Expr *Obj, DeclRefExpr *Mem, - ArrayRef TArgs, - SourceLocation PlaceholderLoc) override { + Expr *SynthesizeDirectMemberAccess(Expr *Obj, DeclRefExpr *Mem, + ArrayRef TArgs, + SourceLocation PlaceholderLoc) override { TemplateArgumentListInfo TAListInfo; populateTemplateArgumentListInfo(TAListInfo, TArgs, PlaceholderLoc); @@ -320,11 +316,11 @@ class MetaActionsImpl : public MetaActions { PlaceholderLoc, PlaceholderLoc, Mem, PlaceholderLoc, &TAListInfo, false); - tok::TokenKind TK = Obj->getType()->isPointerType() ? tok::arrow : - tok::period; - ExprResult Result = S.ActOnMemberAccessExpr(S.getCurScope(), Obj, - Obj->getExprLoc(), TK, Splice, - Splice->getExprLoc()); + tok::TokenKind TK = + Obj->getType()->isPointerType() ? tok::arrow : tok::period; + ExprResult Result = + S.ActOnMemberAccessExpr(S.getCurScope(), Obj, Obj->getExprLoc(), TK, + Splice, Splice->getExprLoc()); return Result.get(); } @@ -340,8 +336,8 @@ class MetaActionsImpl : public MetaActions { FunctionDecl *Spec; TemplateDeductionResult Result = S.DeduceTemplateArguments( - TD, &TAListInfo, Args, Spec, DeductionInfo, false, true, QualType{}, - Expr::Classification(), [](ArrayRef) { return false; }); + TD, &TAListInfo, Args, Spec, DeductionInfo, false, true, QualType{}, + Expr::Classification(), [](ArrayRef) { return false; }); if (Result != TemplateDeductionResult::Success) return nullptr; @@ -352,15 +348,15 @@ class MetaActionsImpl : public MetaActions { EnterExpressionEvaluationContext Ctx( S, Sema::ExpressionEvaluationContext::ConstantEvaluated); - SourceRange Range(Fn->getExprLoc(), - Args.size() > 0 ? Args.back()->getEndLoc() : - Fn->getEndLoc()); + SourceRange Range(Fn->getExprLoc(), Args.size() > 0 + ? Args.back()->getEndLoc() + : Fn->getEndLoc()); if (auto *DRE = dyn_cast(Fn)) if (auto *Ctor = dyn_cast(DRE->getDecl())) { QualType ClsTy(Ctor->getParent()->getTypeForDecl(), 0); ExprResult Result = S.BuildCXXConstructExpr( - Fn->getExprLoc(), ClsTy, Ctor, false, Args, false, false, false, - false, CXXConstructionKind::Complete, Range); + Fn->getExprLoc(), ClsTy, Ctor, false, Args, false, false, false, + false, CXXConstructionKind::Complete, Range); return Result.get(); } @@ -376,6 +372,7 @@ class MetaActionsImpl : public MetaActions { class RestoreDeclContextTy { Sema &S; DeclContext *DC; + public: RestoreDeclContextTy(Sema &S) : S(S), DC(S.CurContext) {} ~RestoreDeclContextTy() { S.CurContext = DC; } @@ -395,8 +392,8 @@ class MetaActionsImpl : public MetaActions { else if (IncompleteDecl->getTagKind() == TagTypeKind::Union) TypeSpec = TST_union; - if (auto *CTSD = dyn_cast( - IncompleteDecl)) { + if (auto *CTSD = + dyn_cast(IncompleteDecl)) { TemplateName TName(CTSD->getSpecializedTemplate()); ParsedTemplateTy ParsedTemplate = ParsedTemplateTy::make(TName); @@ -416,16 +413,15 @@ class MetaActionsImpl : public MetaActions { switch (TArg.getKind()) { case TemplateArgument::Type: ParsedTArgs.emplace_back(ParsedTemplateArgument::Type, - TArg.getAsType().getAsOpaquePtr(), - SourceLocation()); + TArg.getAsType().getAsOpaquePtr(), + SourceLocation()); break; case TemplateArgument::Integral: { - IntegerLiteral *IL = IntegerLiteral::Create(S.Context, - TArg.getAsIntegral(), - TArg.getIntegralType(), - DefinitionLoc); + IntegerLiteral *IL = + IntegerLiteral::Create(S.Context, TArg.getAsIntegral(), + TArg.getIntegralType(), DefinitionLoc); ParsedTArgs.emplace_back(ParsedTemplateArgument::NonType, IL, - SourceLocation()); + SourceLocation()); break; } case TemplateArgument::Template: { @@ -442,21 +438,18 @@ class MetaActionsImpl : public MetaActions { SmallVector CleanupList; TemplateIdAnnotation *TAnnot = TemplateIdAnnotation::Create( - SourceLocation{}, SourceLocation{}, - IncompleteDecl->getIdentifier(), OO_None, ParsedTemplate, - TNK_Type_template, SourceLocation{}, SourceLocation{}, - ParsedTArgs, false, CleanupList); + SourceLocation{}, SourceLocation{}, IncompleteDecl->getIdentifier(), + OO_None, ParsedTemplate, TNK_Type_template, SourceLocation{}, + SourceLocation{}, ParsedTArgs, false, CleanupList); - MTP.push_back( - S.ActOnTemplateParameterList(0, SourceLocation{}, - SourceLocation{}, SourceLocation{}, - std::nullopt, SourceLocation{}, - nullptr)); + MTP.push_back(S.ActOnTemplateParameterList( + 0, SourceLocation{}, SourceLocation{}, SourceLocation{}, + std::nullopt, SourceLocation{}, nullptr)); NewDeclResult = S.ActOnClassTemplateSpecialization( - &ClsScope, TypeSpec, TagUseKind::Definition, DefinitionLoc, - SourceLocation{}, SS, *TAnnot, ParsedAttributesView::none(), - MTP, nullptr); + &ClsScope, TypeSpec, TagUseKind::Definition, DefinitionLoc, + SourceLocation{}, SS, *TAnnot, ParsedAttributesView::none(), MTP, + nullptr); MTP.clear(); for (auto *TAnnot : CleanupList) @@ -485,12 +478,11 @@ class MetaActionsImpl : public MetaActions { bool OwnedDecl = true, IsDependent = false; NewDeclResult = S.ActOnTag( - S.getCurScope(), TypeSpec, TagUseKind::Definition, - DefinitionLoc, SS, IncompleteDecl->getIdentifier(), - IncompleteDecl->getBeginLoc(), ParsedAttributesView::none(), - AS_none, SourceLocation{}, MTP, OwnedDecl, IsDependent, - SourceLocation{}, false, TR, false, false, Sema::OOK_Outside, - nullptr); + S.getCurScope(), TypeSpec, TagUseKind::Definition, DefinitionLoc, + SS, IncompleteDecl->getIdentifier(), IncompleteDecl->getBeginLoc(), + ParsedAttributesView::none(), AS_none, SourceLocation{}, MTP, + OwnedDecl, IsDependent, SourceLocation{}, false, TR, false, false, + Sema::OOK_Outside, nullptr); // The new tag -should- declare the same entity as the original tag. assert((NewDeclResult.isInvalid() || @@ -502,16 +494,16 @@ class MetaActionsImpl : public MetaActions { if (NewDeclResult.isInvalid()) return nullptr; CXXRecordDecl *NewDecl = cast(NewDeclResult.get()); - + // Start the new definition. S.ActOnTagStartDefinition(&ClsScope, NewDecl); S.ActOnStartCXXMemberDeclarations(&ClsScope, NewDecl, SourceLocation{}, false, false, SourceLocation{}); // Derive member visibility. - AccessSpecifier MemberAS = (IncompleteDecl->isClass() ? AS_private : - AS_public); - + AccessSpecifier MemberAS = + (IncompleteDecl->isClass() ? AS_private : AS_public); + AttributeFactory AttrFactory; AttributePool AttrPool(AttrFactory); @@ -521,7 +513,7 @@ class MetaActionsImpl : public MetaActions { // Build the member declaration. unsigned DiagID; const char *PrevSpec; - + DeclSpec DS(AttrFactory); DS.SetStorageClassSpec(S, DeclSpec::SCS_unspecified, DefinitionLoc, PrevSpec, DiagID, S.Context.getPrintingPolicy()); @@ -535,17 +527,15 @@ class MetaActionsImpl : public MetaActions { if (MemberSpec->Alignment) { IdentifierInfo &II = S.Context.Idents.get("alignas"); IntegerLiteral *IL = IntegerLiteral::Create( - S.Context, - llvm::APSInt::getUnsigned(MemberSpec->Alignment.value()), - S.Context.getSizeType(), DefinitionLoc); + S.Context, llvm::APSInt::getUnsigned(MemberSpec->Alignment.value()), + S.Context.getSizeType(), DefinitionLoc); ArgsUnion Args(IL); ParsedAttr::Form Form(tok::kw_alignas); SourceRange Range(DefinitionLoc, DefinitionLoc); - MemberAttrs.addAtEnd(AttrPool.create(&II, Range, nullptr, - SourceLocation{}, nullptr, 0, - Form)); + MemberAttrs.addAtEnd(AttrPool.create( + &II, Range, nullptr, SourceLocation{}, nullptr, 0, Form)); } if (MemberSpec->NoUniqueAddress) { IdentifierInfo &II = S.Context.Idents.get("no_unique_address"); @@ -558,11 +548,11 @@ class MetaActionsImpl : public MetaActions { // Create declarator for the member. Declarator MemberDeclarator(DS, MemberAttrs, DeclaratorContext::Member); - + // Set the identifier, unless this is a zero-width bit-field. if (!MemberSpec->BitWidth || *MemberSpec->BitWidth > 0) { std::string MemberName = MemberSpec->Name.value_or( - "__" + llvm::toString(llvm::APSInt::get(AnonMemCtr++), 10)); + "__" + llvm::toString(llvm::APSInt::get(AnonMemCtr++), 10)); IdentifierInfo &II = S.Context.Idents.get(MemberName); MemberDeclarator.SetIdentifier(&II, DefinitionLoc); @@ -572,8 +562,8 @@ class MetaActionsImpl : public MetaActions { Expr *BitWidthCE = nullptr; if (MemberSpec->BitWidth) { BitWidthCE = IntegerLiteral::Create( - S.Context, llvm::APSInt::getUnsigned(*MemberSpec->BitWidth), - S.Context.getSizeType(), DefinitionLoc); + S.Context, llvm::APSInt::getUnsigned(*MemberSpec->BitWidth), + S.Context.getSizeType(), DefinitionLoc); } VirtSpecifiers VS; @@ -582,10 +572,9 @@ class MetaActionsImpl : public MetaActions { } // Finish the member-specification and the class definition. - S.ActOnFinishCXXMemberSpecification(&ClsScope, NewDecl->getBeginLoc(), - NewDecl, SourceLocation{}, - SourceLocation{}, - ParsedAttributesView::none()); + S.ActOnFinishCXXMemberSpecification( + &ClsScope, NewDecl->getBeginLoc(), NewDecl, SourceLocation{}, + SourceLocation{}, ParsedAttributesView::none()); S.ActOnTagFinishDefinition(&ClsScope, NewDecl, DefinitionLoc); S.ActOnPopScope(DefinitionLoc, &ClsScope); @@ -603,7 +592,7 @@ class MetaActionsImpl : public MetaActions { ParsedAttr::Form::Annotation()); } }; -} // anonymous namespace +} // anonymous namespace ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, SourceLocation TemplateKWLoc, @@ -621,16 +610,18 @@ ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, Found.addDecl(Id.TemplateId->Template.get().getAsTemplateDecl()); } else if (Id.getKind() == UnqualifiedIdKind::IK_TemplateId && Id.TemplateId->Template.get().getKind() == - TemplateName::DependentTemplate && - Id.TemplateId->Template.get().getAsDependentTemplateName() - ->isSpliceSpecifier()) { - auto *Splice = const_cast( - Id.TemplateId->Template.get().getAsDependentTemplateName() - ->getSpliceSpecifier()); + TemplateName::DependentTemplate && + Id.TemplateId->Template.get() + .getAsDependentTemplateName() + ->isSpliceSpecifier()) { + auto *Splice = + const_cast(Id.TemplateId->Template.get() + .getAsDependentTemplateName() + ->getSpliceSpecifier()); ExprResult Result = BuildReflectionSpliceExpr( - TemplateKWLoc, Splice->getLSpliceLoc(), Splice, - Splice->getRSpliceLoc(), TArgs, false); - assert(!Result.isInvalid()); // Should never fail for dependent operands. + TemplateKWLoc, Splice->getLSpliceLoc(), Splice, Splice->getRSpliceLoc(), + TArgs, false); + assert(!Result.isInvalid()); // Should never fail for dependent operands. return BuildCXXReflectExpr(OpLoc, Result.get()); } else if (TemplateKWLoc.isValid() && !TArgs) { @@ -645,8 +636,8 @@ ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, return BuildCXXReflectExpr(OpLoc, TemplateKWLoc, Template.get()); } else if (SS.isSet() && SS.getScopeRep()->isDependent()) { - ExprResult Result = BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, - TArgs); + ExprResult Result = + BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TArgs); // This should only fail if 'SS' is invalid, but that should already have // been diagnosed. assert(!Result.isInvalid()); @@ -705,8 +696,7 @@ ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, } if (auto *TD = dyn_cast(ND)) { - return BuildCXXReflectExpr(OpLoc, NameInfo.getBeginLoc(), - TemplateName(TD)); + return BuildCXXReflectExpr(OpLoc, NameInfo.getBeginLoc(), TemplateName(TD)); } llvm_unreachable("unknown reflection operand!"); @@ -741,6 +731,11 @@ ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OperatorLoc, return BuildCXXReflectExpr(OperatorLoc, E); } +ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OperatorLoc, + ParsedAttr *A) { + return BuildCXXReflectExpr(OperatorLoc, A); +} + /// Returns an expression representing the result of a metafunction operating /// on a reflection. ExprResult Sema::ActOnCXXMetafunction(SourceLocation KwLoc, @@ -795,8 +790,7 @@ ExprResult Sema::ActOnCXXMetafunction(SourceLocation KwLoc, if (Args.size() < Metafn->getMinArgs() + 1 || Args.size() > Metafn->getMaxArgs() + 1) { Diag(KwLoc, diag::err_metafunction_arity) - << (Metafn->getMinArgs() + 1) - << (Metafn->getMaxArgs() + 1) + << (Metafn->getMinArgs() + 1) << (Metafn->getMaxArgs() + 1) << Args.size(); return ExprError(); } @@ -807,8 +801,8 @@ ExprResult Sema::ActOnCXXMetafunction(SourceLocation KwLoc, const auto &ImplIt = getMetafunctionCb(FnID); // Return the CXXMetafunctionExpr representation. - return BuildCXXMetafunctionExpr(KwLoc, LParenLoc, RParenLoc, - FnID, ImplIt, Args); + return BuildCXXMetafunctionExpr(KwLoc, LParenLoc, RParenLoc, FnID, ImplIt, + Args); } const CXXMetafunctionExpr::ImplFn &Sema::getMetafunctionCb(unsigned FnID) { @@ -818,13 +812,12 @@ const CXXMetafunctionExpr::ImplFn &Sema::getMetafunctionCb(unsigned FnID) { Metafunction::Lookup(FnID, Metafn); assert(Metafn); - auto MetafnImpl = std::make_unique( - std::function( - [this, Metafn](APValue &Result, - CXXMetafunctionExpr::EvaluateFn EvalFn, - CXXMetafunctionExpr::DiagnoseFn DiagFn, - QualType ResultTy, SourceRange Range, - ArrayRef Args) -> bool { + auto MetafnImpl = + std::make_unique(std::function( + [this, + Metafn](APValue &Result, CXXMetafunctionExpr::EvaluateFn EvalFn, + CXXMetafunctionExpr::DiagnoseFn DiagFn, QualType ResultTy, + SourceRange Range, ArrayRef Args) -> bool { MetaActionsImpl Actions(*this); return Metafn->evaluate(Result, Context, Actions, EvalFn, DiagFn, ResultTy, Range, Args); @@ -856,10 +849,10 @@ TypeResult Sema::ActOnCXXSpliceExpectingType(SourceLocation LSpliceLoc, } ExprResult Sema::ActOnCXXSpliceExpectingExpr( - SourceLocation TemplateKWLoc, SourceLocation LSpliceLoc, Expr *Operand, - SourceLocation RSpliceLoc, SourceLocation LAngleLoc, - ASTTemplateArgsPtr TArgsIn, SourceLocation RAngleLoc, - bool AllowMemberReference) { + SourceLocation TemplateKWLoc, SourceLocation LSpliceLoc, Expr *Operand, + SourceLocation RSpliceLoc, SourceLocation LAngleLoc, + ASTTemplateArgsPtr TArgsIn, SourceLocation RAngleLoc, + bool AllowMemberReference) { TemplateArgumentListInfo TArgs; if (TArgsIn.size() > 0) { TArgs.setLAngleLoc(LAngleLoc); @@ -877,15 +870,16 @@ DeclResult Sema::ActOnCXXSpliceExpectingNamespace(SourceLocation LSpliceLoc, return BuildReflectionSpliceNamespace(LSpliceLoc, Operand, RSpliceLoc); } -Sema::TemplateTy Sema::ActOnCXXSpliceExpectingTemplate( - SourceLocation LSpliceLoc, Expr *Operand, SourceLocation RSpliceLoc, - bool Complain) { +Sema::TemplateTy +Sema::ActOnCXXSpliceExpectingTemplate(SourceLocation LSpliceLoc, Expr *Operand, + SourceLocation RSpliceLoc, + bool Complain) { return BuildReflectionSpliceTemplate(LSpliceLoc, Operand, RSpliceLoc, Complain); } -ParsedTemplateArgument Sema::ActOnTemplateSpliceSpecifierArgument( - CXXSpliceSpecifierExpr *Splice) { +ParsedTemplateArgument +Sema::ActOnTemplateSpliceSpecifierArgument(CXXSpliceSpecifierExpr *Splice) { if (Splice->isValueDependent()) { return ParsedTemplateArgument(ParsedTemplateArgument::SpliceSpecifier, Splice, Splice->getExprLoc()); @@ -901,28 +895,29 @@ ParsedTemplateArgument Sema::ActOnTemplateSpliceSpecifierArgument( if (Splice->getTemplateKWLoc().isValid() && !ER.Val.isReflectedTemplate()) { Diag(Splice->getOperand()->getExprLoc(), - diag::err_unexpected_reflection_kind_in_splice) << 3; + diag::err_unexpected_reflection_kind_in_splice) + << 3; return ParsedTemplateArgument(); } switch (ER.Val.getReflectionKind()) { case ReflectionKind::Type: - return ParsedTemplateArgument(ParsedTemplateArgument::Type, - const_cast( - ER.Val.getOpaqueReflectionData()), - Splice->getExprLoc()); + return ParsedTemplateArgument( + ParsedTemplateArgument::Type, + const_cast(ER.Val.getOpaqueReflectionData()), + Splice->getExprLoc()); case ReflectionKind::Object: { QualType ResultTy = ER.Val.getTypeOfReflectedResult(Context); - Expr *OVE = new (Context) OpaqueValueExpr(Splice->getExprLoc(), ResultTy, - VK_LValue); + Expr *OVE = new (Context) + OpaqueValueExpr(Splice->getExprLoc(), ResultTy, VK_LValue); Expr *CE = ConstantExpr::Create(Context, OVE, ER.Val.getReflectedObject()); return ParsedTemplateArgument(ParsedTemplateArgument::NonType, CE, Splice->getExprLoc()); } case ReflectionKind::Value: { QualType ResultTy = ER.Val.getTypeOfReflectedResult(Context); - Expr *OVE = new (Context) OpaqueValueExpr(Splice->getExprLoc(), ResultTy, - VK_PRValue); + Expr *OVE = new (Context) + OpaqueValueExpr(Splice->getExprLoc(), ResultTy, VK_PRValue); Expr *CE = ConstantExpr::Create(Context, OVE, ER.Val.getReflectedValue()); return ParsedTemplateArgument(ParsedTemplateArgument::NonType, CE, Splice->getExprLoc()); @@ -941,19 +936,19 @@ ParsedTemplateArgument Sema::ActOnTemplateSpliceSpecifierArgument( } case ReflectionKind::Null: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) - << "null reflections" << 0 << 0; + << "null reflections" << 0 << 0; break; case ReflectionKind::Namespace: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) - << "namespaces" << 0 << 0; + << "namespaces" << 0 << 0; break; case ReflectionKind::BaseSpecifier: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) - << "base specifiers" << 0 << 0; + << "base specifiers" << 0 << 0; break; case ReflectionKind::DataMemberSpec: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) - << "data member specs" << 0 << 0; + << "data member specs" << 0 << 0; break; } return ParsedTemplateArgument(); @@ -980,11 +975,11 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, // TODO(P2996): Capture whole SourceRange of declaration naming. ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, SourceLocation OperandLoc, Decl *D) { - bool IsNamespace = isa(D); + bool IsNamespace = + isa(D); - APValue RV(IsNamespace ? ReflectionKind::Namespace : - ReflectionKind::Declaration, D); + APValue RV( + IsNamespace ? ReflectionKind::Namespace : ReflectionKind::Declaration, D); return CXXReflectExpr::Create(Context, OperatorLoc, SourceRange(OperandLoc, OperandLoc), RV); } @@ -1042,9 +1037,9 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, // variable which would be initialized by the operand 'ULE'. QualType ConstAutoTy = Context.getAutoDeductType().withConst(); TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(ConstAutoTy, 0); - auto *InventedVD = VarDecl::Create(Context, nullptr, SourceLocation(), - E->getExprLoc(), nullptr, ConstAutoTy, - TSI, SC_Auto); + auto *InventedVD = + VarDecl::Create(Context, nullptr, SourceLocation(), E->getExprLoc(), + nullptr, ConstAutoTy, TSI, SC_Auto); // Use the 'auto' deduction machinery to infer the operand type. if (DeduceVariableDeclarationType(InventedVD, true, ULE)) { @@ -1057,10 +1052,8 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, // refer to; raise an error in the presence of any ambiguity. bool HadMultipleCandidates; DeclAccessPair FoundOverload; - FunctionDecl *FoundDecl = - ResolveAddressOfOverloadedFunction(ULE, InventedVD->getType(), true, - FoundOverload, - &HadMultipleCandidates); + FunctionDecl *FoundDecl = ResolveAddressOfOverloadedFunction( + ULE, InventedVD->getType(), true, FoundOverload, &HadMultipleCandidates); if (!FoundDecl) { Diag(E->getExprLoc(), diag::err_reflect_overload_set); return ExprError(); @@ -1127,10 +1120,21 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, ER.Val); } -ExprResult Sema::BuildCXXMetafunctionExpr( - SourceLocation KwLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, - unsigned MetaFnID, const CXXMetafunctionExpr::ImplFn &Impl, - SmallVectorImpl &Args) { +ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, + ParsedAttr *A) { + assert(true && "P3385 - BuildCXXReflectExpr"); + assert(true && A->getAttrName()->getName()); + + return CXXReflectExpr::Create( + Context, OperatorLoc, A->getRange(), + APValue{ReflectionKind::Attribute, static_cast(A)}); +} + +ExprResult +Sema::BuildCXXMetafunctionExpr(SourceLocation KwLoc, SourceLocation LParenLoc, + SourceLocation RParenLoc, unsigned MetaFnID, + const CXXMetafunctionExpr::ImplFn &Impl, + SmallVectorImpl &Args) { // Look up the corresponding Metafunction object. const Metafunction *MetaFn; if (Metafunction::Lookup(MetaFnID, MetaFn)) { @@ -1154,7 +1158,7 @@ ExprResult Sema::BuildCXXMetafunctionExpr( RecordDecl *SourceLocDecl = lookupStdSourceLocationImpl(KwLoc); if (SourceLocDecl) Result = Context.getPointerType( - Context.getRecordType(SourceLocDecl).withConst()); + Context.getRecordType(SourceLocDecl).withConst()); return SourceLocDecl == nullptr; } case Metafunction::MFRK_spliceFromArg: { @@ -1221,8 +1225,7 @@ ExprResult Sema::BuildCXXSpliceSpecifierExpr(SourceLocation TemplateKWLoc, return Operand; } -QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, - Expr *Operand, +QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice, bool Complain) { if (Operand->isTypeDependent() || Operand->isValueDependent()) { @@ -1247,11 +1250,12 @@ QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, if (ER.Val.isReflectedTemplate()) { return Context.getDeducedTemplateSpecializationType( - ER.Val.getReflectedTemplate(), QualType(), false); + ER.Val.getReflectedTemplate(), QualType(), false); } else if (!ER.Val.isReflectedType()) { if (Complain) Diag(Operand->getExprLoc(), - diag::err_unexpected_reflection_kind_in_splice) << 0; + diag::err_unexpected_reflection_kind_in_splice) + << 0; return QualType(); } @@ -1263,14 +1267,12 @@ QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, CTD && CTD->getSpecializationKind() == TSK_Undeclared) { TemplateName TName(CTD->getSpecializedTemplate()); - const TemplateArgumentList &TAList = - CTD->getTemplateInstantiationArgs(); + const TemplateArgumentList &TAList = CTD->getTemplateInstantiationArgs(); TemplateArgumentListInfo TAListInfo( - addLocToTemplateArgs(*this, TAList.asArray(), - Operand->getExprLoc())); + addLocToTemplateArgs(*this, TAList.asArray(), Operand->getExprLoc())); - ReflectedTy = CheckTemplateIdType(TName, Operand->getExprLoc(), - TAListInfo); + ReflectedTy = + CheckTemplateIdType(TName, Operand->getExprLoc(), TAListInfo); if (ReflectedTy.isNull()) return QualType(); } @@ -1279,12 +1281,11 @@ QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, } QualType Sema::BuildReflectionSpliceTypeLoc(TypeLocBuilder &TLB, - SourceLocation LSpliceLoc, - Expr *E, + SourceLocation LSpliceLoc, Expr *E, SourceLocation RSpliceLoc, bool Complain) { - QualType SpliceTy = BuildReflectionSpliceType(LSpliceLoc, E, RSpliceLoc, - Complain); + QualType SpliceTy = + BuildReflectionSpliceType(LSpliceLoc, E, RSpliceLoc, Complain); if (SpliceTy.isNull()) return QualType(); else if (isa(SpliceTy)) { @@ -1305,11 +1306,11 @@ QualType Sema::BuildReflectionSpliceTypeLoc(TypeLocBuilder &TLB, } ExprResult Sema::BuildReflectionSpliceExpr( - SourceLocation TemplateKWLoc, SourceLocation LSplice, Expr *Operand, - SourceLocation RSplice, const TemplateArgumentListInfo *TArgs, - bool AllowMemberReference) { - if (isa(Operand) && - !Operand->isTypeDependent() && !Operand->isValueDependent()) { + SourceLocation TemplateKWLoc, SourceLocation LSplice, Expr *Operand, + SourceLocation RSplice, const TemplateArgumentListInfo *TArgs, + bool AllowMemberReference) { + if (isa(Operand) && !Operand->isTypeDependent() && + !Operand->isValueDependent()) { auto *SpliceOp = cast(Operand); SmallVector Diags; @@ -1327,11 +1328,12 @@ ExprResult Sema::BuildReflectionSpliceExpr( Diag(Operand->getExprLoc(), diag::err_splice_operand_not_reflection); return ExprError(); } - bool RequireTemplate = TemplateKWLoc.isValid() || - TArgs->getLAngleLoc().isValid(); + bool RequireTemplate = + TemplateKWLoc.isValid() || TArgs->getLAngleLoc().isValid(); if (RequireTemplate && !ER.Val.isReflectedTemplate()) { Diag(Operand->getExprLoc(), - diag::err_unexpected_reflection_kind_in_splice) << 3; + diag::err_unexpected_reflection_kind_in_splice) + << 3; return ExprError(); } @@ -1346,7 +1348,7 @@ ExprResult Sema::BuildReflectionSpliceExpr( dyn_cast(TheDecl)->isInstance()))) { Diag(Operand->getExprLoc(), diag::err_dependent_splice_implicit_member_reference) - << Operand->getSourceRange(); + << Operand->getSourceRange(); Diag(Operand->getExprLoc(), diag::note_dependent_splice_explicit_this_may_fix); return ExprError(); @@ -1371,32 +1373,32 @@ ExprResult Sema::BuildReflectionSpliceExpr( } case ReflectionKind::Object: { QualType QT = ER.Val.getTypeOfReflectedResult(Context); - Expr *OVE = new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), QT, - VK_LValue); - Expr *CE = ConstantExpr::Create(Context, OVE, - ER.Val.getReflectedObject()); - - Operand = CXXSpliceExpr::Create(Context, VK_LValue, TemplateKWLoc, - LSplice, CE, RSplice, TArgs, - AllowMemberReference); + Expr *OVE = + new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), QT, VK_LValue); + Expr *CE = + ConstantExpr::Create(Context, OVE, ER.Val.getReflectedObject()); + + Operand = + CXXSpliceExpr::Create(Context, VK_LValue, TemplateKWLoc, LSplice, CE, + RSplice, TArgs, AllowMemberReference); break; } case ReflectionKind::Value: { QualType QT = ER.Val.getTypeOfReflectedResult(Context); - Expr *OVE = new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), QT, - VK_PRValue); + Expr *OVE = + new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), QT, VK_PRValue); Expr *CE = ConstantExpr::Create(Context, OVE, ER.Val.getReflectedValue()); - Operand = CXXSpliceExpr::Create(Context, VK_PRValue, TemplateKWLoc, - LSplice, CE, RSplice, TArgs, - AllowMemberReference); + Operand = + CXXSpliceExpr::Create(Context, VK_PRValue, TemplateKWLoc, LSplice, CE, + RSplice, TArgs, AllowMemberReference); break; } case ReflectionKind::Template: { if (SpliceOp->getTemplateKWLoc().isInvalid()) { Diag(SpliceOp->getOperand()->getExprLoc(), diag::err_unexpected_reflection_kind_in_splice) - << 1 << SpliceOp->getOperand()->getSourceRange(); + << 1 << SpliceOp->getOperand()->getSourceRange(); return ExprError(); } @@ -1410,7 +1412,7 @@ ExprResult Sema::BuildReflectionSpliceExpr( CXXScopeSpec SS; if (auto *RD = dyn_cast(TDecl->getDeclContext())) { TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo( - QualType(RD->getTypeForDecl(), 0), Operand->getExprLoc()); + QualType(RD->getTypeForDecl(), 0), Operand->getExprLoc()); SS.Extend(Context, SourceLocation(), TSI->getTypeLoc(), Operand->getExprLoc()); } @@ -1449,7 +1451,8 @@ ExprResult Sema::BuildReflectionSpliceExpr( } else if (isa(TDecl) || isa(TDecl)) { Diag(Operand->getExprLoc(), - diag::err_unexpected_reflection_template_kind) << 1; + diag::err_unexpected_reflection_template_kind) + << 1; return ExprError(); } @@ -1457,22 +1460,21 @@ ExprResult Sema::BuildReflectionSpliceExpr( NestedNameSpecifierLocBuilder NNSLocBuilder; if (auto *RD = dyn_cast(TDecl->getDeclContext())) { TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo( - QualType(RD->getTypeForDecl(), 0), Operand->getExprLoc()); - NNSLocBuilder.Extend(Context, SourceLocation(), - TSI->getTypeLoc(), Operand->getExprLoc()); + QualType(RD->getTypeForDecl(), 0), Operand->getExprLoc()); + NNSLocBuilder.Extend(Context, SourceLocation(), TSI->getTypeLoc(), + Operand->getExprLoc()); } UnresolvedSet<1> DeclSet; DeclSet.addDecl(TDecl); - Operand = UnresolvedLookupExpr::Create(Context, NamingCls, - SS.getWithLocInContext(Context), - SourceLocation(), DeclNameInfo, - false, TArgs, DeclSet.begin(), - DeclSet.end(), false, false); - - Operand = CXXSpliceExpr::Create(Context, VK_LValue, TemplateKWLoc, - LSplice, Operand, RSplice, TArgs, - AllowMemberReference); + Operand = UnresolvedLookupExpr::Create( + Context, NamingCls, SS.getWithLocInContext(Context), SourceLocation(), + DeclNameInfo, false, TArgs, DeclSet.begin(), DeclSet.end(), false, + false); + + Operand = + CXXSpliceExpr::Create(Context, VK_LValue, TemplateKWLoc, LSplice, + Operand, RSplice, TArgs, AllowMemberReference); break; } case ReflectionKind::Null: @@ -1488,9 +1490,9 @@ ExprResult Sema::BuildReflectionSpliceExpr( } return Operand; } - return CXXSpliceExpr::Create(Context, Operand->getValueKind(), - TemplateKWLoc, LSplice, Operand, RSplice, - TArgs, AllowMemberReference); + return CXXSpliceExpr::Create(Context, Operand->getValueKind(), TemplateKWLoc, + LSplice, Operand, RSplice, TArgs, + AllowMemberReference); } DeclResult Sema::BuildReflectionSpliceNamespace(SourceLocation LSplice, @@ -1521,8 +1523,7 @@ DeclResult Sema::BuildReflectionSpliceNamespace(SourceLocation LSplice, Diag(Operand->getExprLoc(), diag::err_unexpected_reflection_kind) << 2; return DeclError(); } else if (isa(ER.Val.getReflectedNamespace())) { - Diag(Operand->getExprLoc(), - diag::err_splice_global_scope_as_namespace); + Diag(Operand->getExprLoc(), diag::err_splice_global_scope_as_namespace); return DeclError(); } @@ -1537,9 +1538,8 @@ Sema::TemplateTy Sema::BuildReflectionSpliceTemplate(SourceLocation LSplice, auto *SpliceOp = cast(Operand); if (Operand->isValueDependent()) - return TemplateTy::make( - Context.getDependentTemplateName( - cast(Operand))); + return TemplateTy::make(Context.getDependentTemplateName( + cast(Operand))); SmallVector Diags; Expr::EvalResult ER; @@ -1547,7 +1547,8 @@ Sema::TemplateTy Sema::BuildReflectionSpliceTemplate(SourceLocation LSplice, if (!Operand->EvaluateAsRValue(ER, Context, true)) { Diag(SpliceOp->getOperand()->getExprLoc(), - diag::err_splice_operand_not_constexpr) << SpliceOp->getOperand(); + diag::err_splice_operand_not_constexpr) + << SpliceOp->getOperand(); for (PartialDiagnosticAt PD : Diags) Diag(PD.first, PD.second); return TemplateTy(); @@ -1555,7 +1556,8 @@ Sema::TemplateTy Sema::BuildReflectionSpliceTemplate(SourceLocation LSplice, if (!ER.Val.isReflection()) { Diag(SpliceOp->getOperand()->getExprLoc(), - diag::err_splice_operand_not_reflection) << SpliceOp->getSourceRange(); + diag::err_splice_operand_not_reflection) + << SpliceOp->getSourceRange(); return TemplateTy(); } From 4a28ad2a017d380458db2f8a561755a52f6d4548 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 6 Oct 2024 16:33:34 +0900 Subject: [PATCH 02/26] Stash --- clang/include/clang/AST/APValue.h | 2 ++ clang/include/clang/AST/RecursiveASTVisitor.h | 1 + clang/lib/AST/APValue.cpp | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 27dd22a2d82ffb..f3ff6f3ff21709 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -40,6 +40,7 @@ template class BasicReaderBase; class Expr; class FieldDecl; class NamespaceDecl; + class ParsedAttr; struct PrintingPolicy; class Type; class ValueDecl; @@ -682,6 +683,7 @@ class APValue { CXXBaseSpecifier *getReflectedBaseSpecifier() const; TagDataMemberSpec *getReflectedDataMemberSpec() const; CXX26AnnotationAttr *getReflectedAnnotation() const; + ParsedAttr *getReflectedAttribute() const; void setInt(APSInt I) { assert(isInt() && "Invalid accessor"); diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 9dd8528c04f470..d89134e044cd39 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2991,6 +2991,7 @@ DEF_TRAVERSE_STMT(CXXReflectExpr, { case ReflectionKind::Namespace: case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: + case ReflectionKind::Attribute: break; } } diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 3c65393d7e09a4..e3337863ec3711 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -547,6 +547,7 @@ static void profileReflection(llvm::FoldingSetNodeID &ID, APValue V) { case ReflectionKind::Namespace: case ReflectionKind::BaseSpecifier: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: ID.AddPointer(V.getOpaqueReflectionData()); return; case ReflectionKind::DataMemberSpec: { @@ -942,6 +943,13 @@ CXX26AnnotationAttr *APValue::getReflectedAnnotation() const { const_cast(getOpaqueReflectionData())); } +ParsedAttr *APValue::getReflectedAttribute() const { + assert(getReflectionKind() == ReflectionKind::Attribute && + "not a reflection of an attribute"); + return reinterpret_cast( + const_cast(getOpaqueReflectionData())); +} + static double GetApproxValue(const llvm::APFloat &F) { llvm::APFloat V = F; bool ignored; From a2f0785c8867441f6354ef659c12e11a13d0ee1a Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 6 Oct 2024 16:36:55 +0900 Subject: [PATCH 03/26] Stash --- clang/lib/Parse/ParseReflect.cpp | 42 +++++++++++++++++--------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index 25413c424191a3..bef389d078c1ab 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -16,15 +16,13 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" -#include "clang/Sema/Ownership.h" -#include "clang/Sema/ParsedAttr.h" using namespace clang; ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { SourceLocation OperandLoc = Tok.getLocation(); EnterExpressionEvaluationContext EvalContext( - Actions, Sema::ExpressionEvaluationContext::ReflectionContext); + Actions, Sema::ExpressionEvaluationContext::ReflectionContext); // Parse a leading nested-name-specifier, e.g., // @@ -99,8 +97,9 @@ ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { } TentativeAction.Revert(); - if (SS.isSet() && TryAnnotateTypeOrScopeTokenAfterScopeSpec( - SS, true, ImplicitTypenameContext::No)) { + if (SS.isSet() && + TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, true, + ImplicitTypenameContext::No)) { SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); return ExprError(); } @@ -187,7 +186,8 @@ bool Parser::ParseCXXSpliceSpecifier(SourceLocation TemplateKWLoc) { return false; } -TypeResult Parser::ParseCXXSpliceAsType(bool AllowDependent, bool Complain) { +TypeResult Parser::ParseCXXSpliceAsType(bool AllowDependent, + bool Complain) { assert(Tok.is(tok::annot_splice) && "expected annot_splice"); if (NextToken().is(tok::less)) { @@ -209,7 +209,8 @@ TypeResult Parser::ParseCXXSpliceAsType(bool AllowDependent, bool Complain) { return TypeError(); TypeResult Result = Actions.ActOnCXXSpliceExpectingType( - Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc(), Complain); + Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc(), + Complain); if (!Result.isInvalid()) ConsumeAnnotationToken(); @@ -231,8 +232,8 @@ ExprResult Parser::ParseCXXSpliceAsExpr(bool AllowMemberReference) { SourceLocation LAngleLoc, RAngleLoc; if (TemplateKWLoc.isValid() && Tok.is(tok::less)) { TemplateArgList TArgs; - if (ParseTemplateIdAfterTemplateName(/*ConsumeLastToken=*/true, LAngleLoc, - TArgs, RAngleLoc, + if (ParseTemplateIdAfterTemplateName(/*ConsumeLastToken=*/true, + LAngleLoc, TArgs, RAngleLoc, /*Template=*/nullptr)) return ExprError(); @@ -254,7 +255,7 @@ DeclResult Parser::ParseCXXSpliceAsNamespace() { assert(!ER.isInvalid()); DeclResult Result = Actions.ActOnCXXSpliceExpectingNamespace( - Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc()); + Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc()); return Result; } @@ -268,9 +269,9 @@ Parser::TemplateTy Parser::ParseCXXSpliceAsTemplate() { ExprResult ER = getExprAnnotation(Splice); assert(!ER.isInvalid()); - return Actions.ActOnCXXSpliceExpectingTemplate(Splice.getLocation(), ER.get(), - Splice.getAnnotationEndLoc(), - /*Complain=*/true); + return Actions.ActOnCXXSpliceExpectingTemplate( + Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc(), + /*Complain=*/true); } static TemplateNameKind classifyTemplateDecl(TemplateName TName) { @@ -303,7 +304,8 @@ bool Parser::ParseTemplateAnnotationFromSplice(SourceLocation TemplateKWLoc, ConsumeAnnotationToken(); TemplateTy Template = Actions.ActOnCXXSpliceExpectingTemplate( - Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc(), Complain); + Splice.getLocation(), ER.get(), Splice.getAnnotationEndLoc(), + Complain); if (!Template) return true; bool IsDependent = Template.get().isDependent(); @@ -333,12 +335,12 @@ bool Parser::ParseTemplateAnnotationFromSplice(SourceLocation TemplateKWLoc, CXXScopeSpec SS; ASTTemplateArgsPtr TArgsPtr(TArgs); - TypeResult Type = - ArgsInvalid - ? TypeError() - : Actions.ActOnTemplateIdType(getCurScope(), SS, TemplateKWLoc, - Template, nullptr, TemplateNameLoc, - LAngleLoc, TArgsPtr, RAngleLoc); + TypeResult Type = ArgsInvalid + ? TypeError() + : Actions.ActOnTemplateIdType( + getCurScope(), SS, TemplateKWLoc, Template, + nullptr, TemplateNameLoc, LAngleLoc, TArgsPtr, + RAngleLoc); Tok.setKind(tok::annot_typename); setTypeAnnotation(Tok, Type); From 56fc53e4b073dedcf406595433d24c06b99988f1 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 6 Oct 2024 16:39:22 +0900 Subject: [PATCH 04/26] Stash Stash Stash Stash --- clang/include/clang/AST/Reflection.h | 4 +- clang/include/clang/Sema/Sema.h | 148 ++++++++++++++++----------- clang/lib/AST/ComputeDependence.cpp | 22 ++-- 3 files changed, 102 insertions(+), 72 deletions(-) diff --git a/clang/include/clang/AST/Reflection.h b/clang/include/clang/AST/Reflection.h index e31df466ddeeb2..fde146b47d4240 100644 --- a/clang/include/clang/AST/Reflection.h +++ b/clang/include/clang/AST/Reflection.h @@ -118,8 +118,8 @@ struct TagDataMemberSpec { std::optional BitWidth; bool NoUniqueAddress; - bool operator==(TagDataMemberSpec const &Rhs) const; - bool operator!=(TagDataMemberSpec const &Rhs) const; + bool operator==(TagDataMemberSpec const& Rhs) const; + bool operator!=(TagDataMemberSpec const& Rhs) const; }; } // namespace clang diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 828da165022cbf..79124386f7fd33 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4888,9 +4888,12 @@ class Sema final : public SemaBase { SourceLocation AliasLoc, IdentifierInfo *Alias, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *Ident); - Decl *ActOnNamespaceAliasDef(Scope *CurScope, SourceLocation NamespaceLoc, - SourceLocation AliasLoc, IdentifierInfo *Alias, - CXXScopeSpec &SS, SourceLocation IdentLoc, + Decl *ActOnNamespaceAliasDef(Scope *CurScope, + SourceLocation NamespaceLoc, + SourceLocation AliasLoc, + IdentifierInfo *Alias, + CXXScopeSpec &SS, + SourceLocation IdentLoc, NamedDecl *ND); /// Remove decls we can't actually see from a lookup being used to declare @@ -8567,11 +8570,12 @@ class Sema final : public SemaBase { Scope *BodyScope); void ActOnFinishRequiresExpr(); concepts::Requirement *ActOnSimpleRequirement(Expr *E); - concepts::Requirement * - ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS, - SourceLocation NameLoc, const IdentifierInfo *TypeName, - TemplateIdAnnotation *TemplateId, - CXXSpliceSpecifierExpr *SpliceExpr); + concepts::Requirement *ActOnTypeRequirement(SourceLocation TypenameKWLoc, + CXXScopeSpec &SS, + SourceLocation NameLoc, + const IdentifierInfo *TypeName, + TemplateIdAnnotation *TemplateId, + CXXSpliceSpecifierExpr *SpliceExpr); concepts::Requirement *ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc); concepts::Requirement *ActOnCompoundRequirement( @@ -15160,12 +15164,12 @@ class Sema final : public SemaBase { bool suppressDiagnostics() const { return SuppressDiagnostics; } ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, - SourceLocation TemplateKWLoc, CXXScopeSpec &SS, - UnqualifiedId &Id); + SourceLocation TemplateKWLoc, + CXXScopeSpec &SS, UnqualifiedId &Id); ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, TypeResult T); - ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, SourceLocation ArgLoc, - Decl *D); + ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, + SourceLocation ArgLoc, Decl *D); ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, ParsedTemplateArgument Template); ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, CXXSpliceExpr *E); @@ -15179,10 +15183,13 @@ class Sema final : public SemaBase { SourceLocation LSpliceLoc, Expr *Operand, SourceLocation RSpliceLoc); - TypeResult ActOnCXXSpliceExpectingType(SourceLocation LSplice, Expr *Operand, - SourceLocation RSplice, bool Complain); + TypeResult ActOnCXXSpliceExpectingType(SourceLocation LSplice, + Expr *Operand, + SourceLocation RSplice, + bool Complain); ExprResult ActOnCXXSpliceExpectingExpr(SourceLocation TemplateKWLoc, - SourceLocation LSplice, Expr *Operand, + SourceLocation LSplice, + Expr *Operand, SourceLocation RSplice, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, @@ -15198,13 +15205,14 @@ class Sema final : public SemaBase { ParsedTemplateArgument ActOnTemplateSpliceSpecifierArgument(CXXSpliceSpecifierExpr *Splice); - bool - ActOnCXXNestedNameSpecifierReflectionSplice(CXXScopeSpec &SS, - CXXSpliceSpecifierExpr *Splice, - SourceLocation ColonColonLoc); + bool ActOnCXXNestedNameSpecifierReflectionSplice( + CXXScopeSpec &SS, CXXSpliceSpecifierExpr *Splice, + SourceLocation ColonColonLoc); - ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, - tok::TokenKind OpKind, CXXSpliceExpr *RHS, + ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, + SourceLocation OpLoc, + tok::TokenKind OpKind, + CXXSpliceExpr *RHS, SourceLocation TemplateKWLoc); // Reflection of non-expression operands. @@ -15215,6 +15223,7 @@ class Sema final : public SemaBase { ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, SourceLocation OperandLoc, TemplateName Template); + ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, ParsedAttr *A); // Reflection of expression operands. ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, Expr *E); @@ -15222,8 +15231,8 @@ class Sema final : public SemaBase { UnresolvedLookupExpr *E); ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, SubstNonTypeTemplateParmExpr *E); - ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, CXXSpliceExpr *E); - ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, ParsedAttr *A); + ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, + CXXSpliceExpr *E); ExprResult BuildCXXMetafunctionExpr(SourceLocation KwLoc, SourceLocation LParenLoc, @@ -15236,11 +15245,13 @@ class Sema final : public SemaBase { SourceLocation LSpliceLoc, Expr *Operand, SourceLocation RSpliceLoc); - QualType BuildReflectionSpliceType(SourceLocation LSplice, Expr *Operand, - SourceLocation RSplice, bool Complain); + QualType BuildReflectionSpliceType(SourceLocation LSplice, + Expr *Operand, + SourceLocation RSplice, + bool Complain); QualType BuildReflectionSpliceTypeLoc(TypeLocBuilder &TLB, - SourceLocation LSpliceLoc, Expr *E, - SourceLocation RSpliceLoc, + SourceLocation LSpliceLoc, + Expr *E, SourceLocation RSpliceLoc, bool Complain); ExprResult BuildReflectionSpliceExpr(SourceLocation TemplateKWLoc, SourceLocation LSplice, Expr *Operand, @@ -15257,7 +15268,8 @@ class Sema final : public SemaBase { ExprResult BuildMemberReferenceExpr(Scope *S, Expr *Base, SourceLocation OpLoc, - tok::TokenKind OpKind, CXXSpliceExpr *RHS, + tok::TokenKind OpKind, + CXXSpliceExpr *RHS, SourceLocation TemplateKWLoc); ExprResult BuildDependentMemberSpliceExpr(Expr *Base, SourceLocation OpLoc, bool IsArrow, CXXSpliceExpr *RHS); @@ -15270,10 +15282,10 @@ class Sema final : public SemaBase { // Lambdas having bound references to this Sema object, used to evaluate // metafunction (C++26, P2996) at constant evaluation time. llvm::SmallDenseMap> - MetafunctionImplCbs; + MetafunctionImplCbs; // Whether to elide access control when checking access to class members. - bool EllideAccessControl{false}; + bool EllideAccessControl {false}; // Used to check whether a template substitution is valid without producing // a diagnostic. @@ -15281,16 +15293,16 @@ class Sema final : public SemaBase { class AccessControlScopeGuard final { public: - AccessControlScopeGuard(const AccessControlScopeGuard &) = delete; - AccessControlScopeGuard(AccessControlScopeGuard &&) = delete; - AccessControlScopeGuard & - operator=(const AccessControlScopeGuard &) = delete; - AccessControlScopeGuard &operator=(AccessControlScopeGuard &&) = delete; + AccessControlScopeGuard(const AccessControlScopeGuard&) = delete; + AccessControlScopeGuard(AccessControlScopeGuard&&) = delete; + AccessControlScopeGuard& operator=(const AccessControlScopeGuard&) = delete; + AccessControlScopeGuard& operator=(AccessControlScopeGuard&&) = delete; // Sets EllideAccessControl to the new override value & keeps the // previous one, so we can revert when the scope guard exits explicit AccessControlScopeGuard(Sema &S, bool ellideAccessControlOverride) - : S_{S}, previousEllideAccessControl_{S_.EllideAccessControl} { + : S_{S} + , previousEllideAccessControl_{S_.EllideAccessControl} { S_.EllideAccessControl = ellideAccessControlOverride; } @@ -15300,7 +15312,7 @@ class Sema final : public SemaBase { private: Sema &S_; - bool previousEllideAccessControl_{false}; + bool previousEllideAccessControl_ {false}; }; ///@} @@ -15324,17 +15336,26 @@ class Sema final : public SemaBase { SourceLocation RParenLoc, BuildForRangeKind Kind); - StmtResult ActOnCXXInitListExpansionStmt( - SourceLocation TemplateKWLoc, SourceLocation ForLoc, - SourceLocation LParenLoc, Stmt *Init, Stmt *ExpansionVarStmt, - SourceLocation ColonLoc, CXXExpansionInitListExpr *Range, - SourceLocation RParenLoc, Expr *TParmRef, BuildForRangeKind Kind); - - StmtResult ActOnCXXDestructurableExpansionStmt( - SourceLocation TemplateKWLoc, SourceLocation ForLoc, - SourceLocation LParenLoc, Stmt *Init, Stmt *ExpansionVarStmt, - SourceLocation ColonLoc, Expr *Range, SourceLocation RParenLoc, - Expr *TParmRef, BuildForRangeKind Kind); + StmtResult ActOnCXXInitListExpansionStmt(SourceLocation TemplateKWLoc, + SourceLocation ForLoc, + SourceLocation LParenLoc, Stmt *Init, + Stmt *ExpansionVarStmt, + SourceLocation ColonLoc, + CXXExpansionInitListExpr *Range, + SourceLocation RParenLoc, + Expr *TParmRef, + BuildForRangeKind Kind); + + StmtResult ActOnCXXDestructurableExpansionStmt(SourceLocation TemplateKWLoc, + SourceLocation ForLoc, + SourceLocation LParenLoc, + Stmt *Init, + Stmt *ExpansionVarStmt, + SourceLocation ColonLoc, + Expr *Range, + SourceLocation RParenLoc, + Expr *TParmRef, + BuildForRangeKind Kind); bool ComputeDecompositionExpansionArity(Expr *Range, unsigned &Result); @@ -15350,17 +15371,26 @@ class Sema final : public SemaBase { ExprResult ActOnCXXDestructurableExpansionSelectExpr(Expr *Range, Expr *Idx, bool Constexpr); - StmtResult BuildCXXInitListExpansionStmt( - SourceLocation TemplateKWLoc, SourceLocation ForLoc, - SourceLocation LParenLoc, Stmt *Init, Stmt *ExpansionVarStmt, - SourceLocation ColonLoc, CXXExpansionInitListExpr *Range, - SourceLocation RParenLoc, unsigned TemplateDepth, BuildForRangeKind Kind); - - StmtResult BuildCXXDestructurableExpansionStmt( - SourceLocation TemplateKWLoc, SourceLocation ForLoc, - SourceLocation LParenLoc, Stmt *Init, Stmt *ExpansionVarStmt, - SourceLocation ColonLoc, Expr *Range, SourceLocation RParenLoc, - unsigned TemplateDepth, BuildForRangeKind Kind); + StmtResult BuildCXXInitListExpansionStmt(SourceLocation TemplateKWLoc, + SourceLocation ForLoc, + SourceLocation LParenLoc, Stmt *Init, + Stmt *ExpansionVarStmt, + SourceLocation ColonLoc, + CXXExpansionInitListExpr *Range, + SourceLocation RParenLoc, + unsigned TemplateDepth, + BuildForRangeKind Kind); + + StmtResult BuildCXXDestructurableExpansionStmt(SourceLocation TemplateKWLoc, + SourceLocation ForLoc, + SourceLocation LParenLoc, + Stmt *Init, + Stmt *ExpansionVarStmt, + SourceLocation ColonLoc, + Expr *Range, + SourceLocation RParenLoc, + unsigned TemplateDepth, + BuildForRangeKind Kind); ExprResult BuildCXXExpansionInitList(SourceLocation LBraceLoc, MultiExprArg SubExprs, diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index e8f59fc272a69d..73327c39b6e741 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -18,7 +18,6 @@ #include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExprOpenMP.h" -#include "clang/AST/Reflection.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "llvm/ADT/ArrayRef.h" @@ -471,7 +470,7 @@ ExprDependence clang::computeDependence(ArraySectionExpr *E) { ExprDependence clang::computeDependence(OMPArrayShapingExpr *E) { auto D = E->getBase()->getDependence(); - for (Expr *Dim : E->getDimensions()) + for (Expr *Dim: E->getDimensions()) if (Dim) D |= turnValueToTypeDependence(Dim->getDependence()); return D; @@ -936,7 +935,7 @@ ExprDependence clang::computeDependence(ConceptSpecializationExpr *E, ExprDependence D = ValueDependent ? ExprDependence::Value : ExprDependence::None; auto Res = D | toExprDependence(TA); - if (!ValueDependent && E->getSatisfaction().ContainsErrors) + if(!ValueDependent && E->getSatisfaction().ContainsErrors) Res |= ExprDependence::Error; return Res; } @@ -994,14 +993,15 @@ ExprDependence clang::computeDependence(CXXReflectExpr *E, } ExprDependence clang::computeDependence(CXXMetafunctionExpr *E) { - auto D = ExprDependence::None; - for (unsigned I = 0; I < E->getNumArgs(); ++I) { - Expr *Arg = E->getArg(I); - D |= Arg->getDependence(); - } - return D & ~ExprDependence::UnexpandedPack; + auto D = ExprDependence::None; + for (unsigned I = 0; I < E->getNumArgs(); ++I) { + Expr *Arg = E->getArg(I); + D |= Arg->getDependence(); + } + return D & ~ExprDependence::UnexpandedPack; } + ExprDependence clang::computeDependence(CXXSpliceSpecifierExpr *E) { return E->getOperand()->getDependence(); } @@ -1047,8 +1047,8 @@ ExprDependence clang::computeDependence(CXXExpansionInitListSelectExpr *E) { return D; } -ExprDependence -clang::computeDependence(CXXDestructurableExpansionSelectExpr *E) { +ExprDependence clang::computeDependence( + CXXDestructurableExpansionSelectExpr *E) { auto D = E->getRange()->getDependence() | E->getIdx()->getDependence(); if (D & ExprDependence::Value) D |= ExprDependence::Type; From 4b439c0352d0da6af1e3b815a99df3aae846ecc6 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 6 Oct 2024 16:49:03 +0900 Subject: [PATCH 05/26] Stash --- clang/lib/Sema/SemaReflect.cpp | 421 +++++++++++++++++---------------- 1 file changed, 217 insertions(+), 204 deletions(-) diff --git a/clang/lib/Sema/SemaReflect.cpp b/clang/lib/Sema/SemaReflect.cpp index 1a637a7bdfe1ab..1a89deadd3ffe3 100644 --- a/clang/lib/Sema/SemaReflect.cpp +++ b/clang/lib/Sema/SemaReflect.cpp @@ -18,11 +18,9 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/MetaActions.h" #include "clang/AST/Metafunction.h" -#include "clang/AST/Reflection.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" #include "clang/Sema/Lookup.h" -#include "clang/Sema/ParsedAttr.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Sema.h" #include "clang/Sema/Template.h" @@ -37,8 +35,9 @@ TemplateArgumentListInfo addLocToTemplateArgs(Sema &S, ArrayRef Args, SourceLocation ExprLoc) { auto convert = [&](const TemplateArgument &TA) -> TemplateArgumentLoc { - return S.getTrivialTemplateArgumentLoc( - TA, TA.getNonTypeTemplateArgumentType(), ExprLoc); + return S.getTrivialTemplateArgumentLoc(TA, + TA.getNonTypeTemplateArgumentType(), + ExprLoc); }; TemplateArgumentListInfo Result; @@ -52,7 +51,8 @@ TemplateArgumentListInfo addLocToTemplateArgs(Sema &S, return Result; } -Expr *CreateRefToDecl(Sema &S, ValueDecl *D, SourceLocation ExprLoc) { +Expr *CreateRefToDecl(Sema &S, ValueDecl *D, + SourceLocation ExprLoc) { NestedNameSpecifierLocBuilder NNSLocBuilder; if (const auto *RDC = dyn_cast(D->getDeclContext())) { QualType QT(RDC->getTypeForDecl(), 0); @@ -66,13 +66,14 @@ Expr *CreateRefToDecl(Sema &S, ValueDecl *D, SourceLocation ExprLoc) { VTSD && VTSD->getTemplateSpecializationKind() == TSK_Undeclared) { const TemplateArgumentList &TAList = VTSD->getTemplateArgs(); TemplateArgumentListInfo TAListInfo( - addLocToTemplateArgs(S, TAList.asArray(), ExprLoc)); + addLocToTemplateArgs(S, TAList.asArray(), ExprLoc)); CXXScopeSpec SS; DeclarationNameInfo DNI(VTSD->getDeclName(), ExprLoc); - ExprResult ER = S.CheckVarTemplateId( - SS, DNI, VTSD->getSpecializedTemplate(), VTSD->getSpecializedTemplate(), - ExprLoc, &TAListInfo); + ExprResult ER = S.CheckVarTemplateId(SS, DNI, + VTSD->getSpecializedTemplate(), + VTSD->getSpecializedTemplate(), + ExprLoc, &TAListInfo); return ER.get(); } else { QualType QT(D->getType()); @@ -98,14 +99,18 @@ class MetaActionsImpl : public MetaActions { ArrayRef TArgs, SourceLocation InstantiateLoc) { for (const TemplateArgument &Arg : TArgs) - TAListInfo.addArgument(S.getTrivialTemplateArgumentLoc( - Arg, Arg.getNonTypeTemplateArgumentType(), InstantiateLoc)); + TAListInfo.addArgument( + S.getTrivialTemplateArgumentLoc(Arg, + Arg.getNonTypeTemplateArgumentType(), + InstantiateLoc)); } public: - MetaActionsImpl(Sema &S) : MetaActions(), S(S) {} + MetaActionsImpl(Sema &S) : MetaActions(), S(S) { } - Decl *CurrentCtx() const override { return cast(S.CurContext); } + Decl *CurrentCtx() const override { + return cast(S.CurContext); + } bool IsAccessible(NamedDecl *Target, DeclContext *Ctx) override { bool Result = false; @@ -129,8 +134,8 @@ class MetaActionsImpl : public MetaActions { } bool IsAccessibleBase(QualType BaseTy, QualType DerivedTy, - const CXXBasePath &Path, DeclContext *Ctx, - SourceLocation AccessLoc) override { + const CXXBasePath &Path, + DeclContext *Ctx, SourceLocation AccessLoc) override { Sema::AccessResult Result; DeclContext *PreviousDC = S.CurContext; @@ -146,7 +151,7 @@ class MetaActionsImpl : public MetaActions { bool EnsureInstantiated(Decl *D, SourceRange Range) override { auto validateConstraints = [&](TemplateDecl *TDecl, - ArrayRef TArgs) { + ArrayRef TArgs) { MultiLevelTemplateArgumentList MLTAL(TDecl, TArgs, false); if (S.EnsureTemplateArgumentListConstraints(TDecl, MLTAL, Range)) return false; @@ -165,14 +170,13 @@ class MetaActionsImpl : public MetaActions { return true; if (S.InstantiateClassTemplateSpecialization( - Range.getBegin(), CTSD, TSK_ExplicitInstantiationDefinition, - false)) + Range.getBegin(), CTSD, TSK_ExplicitInstantiationDefinition, false)) return false; S.InstantiateClassTemplateSpecializationMembers( - Range.getBegin(), CTSD, TSK_ExplicitInstantiationDefinition); + Range.getBegin(), CTSD, TSK_ExplicitInstantiationDefinition); } else if (auto *VTSD = dyn_cast(D); - VTSD && !VTSD->isCompleteDefinition()) { + VTSD && !VTSD->isCompleteDefinition()) { if (!validateConstraints(VTSD->getSpecializedTemplate(), VTSD->getTemplateArgs().asArray())) return true; @@ -181,10 +185,9 @@ class MetaActionsImpl : public MetaActions { } else if (auto *FD = dyn_cast(D); FD && FD->isTemplateInstantiation()) { if (FD->getTemplateSpecializationArgs()) - if (!validateConstraints( - FD->getPrimaryTemplate(), - FD->getTemplateSpecializationArgs()->asArray())) - return true; + if (!validateConstraints(FD->getPrimaryTemplate(), + FD->getTemplateSpecializationArgs()->asArray())) + return true; S.InstantiateFunctionDefinition(Range.getBegin(), FD, true, true); } @@ -281,8 +284,8 @@ class MetaActionsImpl : public MetaActions { TemplateArgumentListInfo TAListInfo; populateTemplateArgumentListInfo(TAListInfo, TArgs, InstantiateLoc); - DeclResult Result = - S.CheckVarTemplateId(TD, InstantiateLoc, InstantiateLoc, TAListInfo); + DeclResult Result = S.CheckVarTemplateId(TD, InstantiateLoc, + InstantiateLoc, TAListInfo); if (Result.isInvalid()) return nullptr; Spec = cast(Result.get()); @@ -301,14 +304,15 @@ class MetaActionsImpl : public MetaActions { CXXScopeSpec SS; DeclarationNameInfo DNI(TD->getDeclName(), InstantiateLoc); - ExprResult Result = - S.CheckConceptTemplateId(SS, InstantiateLoc, DNI, TD, TD, &TAListInfo); + ExprResult Result = S.CheckConceptTemplateId(SS, InstantiateLoc, DNI, TD, + TD, &TAListInfo); return Result.get(); } - Expr *SynthesizeDirectMemberAccess(Expr *Obj, DeclRefExpr *Mem, - ArrayRef TArgs, - SourceLocation PlaceholderLoc) override { + Expr * + SynthesizeDirectMemberAccess(Expr *Obj, DeclRefExpr *Mem, + ArrayRef TArgs, + SourceLocation PlaceholderLoc) override { TemplateArgumentListInfo TAListInfo; populateTemplateArgumentListInfo(TAListInfo, TArgs, PlaceholderLoc); @@ -316,11 +320,11 @@ class MetaActionsImpl : public MetaActions { PlaceholderLoc, PlaceholderLoc, Mem, PlaceholderLoc, &TAListInfo, false); - tok::TokenKind TK = - Obj->getType()->isPointerType() ? tok::arrow : tok::period; - ExprResult Result = - S.ActOnMemberAccessExpr(S.getCurScope(), Obj, Obj->getExprLoc(), TK, - Splice, Splice->getExprLoc()); + tok::TokenKind TK = Obj->getType()->isPointerType() ? tok::arrow : + tok::period; + ExprResult Result = S.ActOnMemberAccessExpr(S.getCurScope(), Obj, + Obj->getExprLoc(), TK, Splice, + Splice->getExprLoc()); return Result.get(); } @@ -336,8 +340,8 @@ class MetaActionsImpl : public MetaActions { FunctionDecl *Spec; TemplateDeductionResult Result = S.DeduceTemplateArguments( - TD, &TAListInfo, Args, Spec, DeductionInfo, false, true, QualType{}, - Expr::Classification(), [](ArrayRef) { return false; }); + TD, &TAListInfo, Args, Spec, DeductionInfo, false, true, QualType{}, + Expr::Classification(), [](ArrayRef) { return false; }); if (Result != TemplateDeductionResult::Success) return nullptr; @@ -348,15 +352,15 @@ class MetaActionsImpl : public MetaActions { EnterExpressionEvaluationContext Ctx( S, Sema::ExpressionEvaluationContext::ConstantEvaluated); - SourceRange Range(Fn->getExprLoc(), Args.size() > 0 - ? Args.back()->getEndLoc() - : Fn->getEndLoc()); + SourceRange Range(Fn->getExprLoc(), + Args.size() > 0 ? Args.back()->getEndLoc() : + Fn->getEndLoc()); if (auto *DRE = dyn_cast(Fn)) if (auto *Ctor = dyn_cast(DRE->getDecl())) { QualType ClsTy(Ctor->getParent()->getTypeForDecl(), 0); ExprResult Result = S.BuildCXXConstructExpr( - Fn->getExprLoc(), ClsTy, Ctor, false, Args, false, false, false, - false, CXXConstructionKind::Complete, Range); + Fn->getExprLoc(), ClsTy, Ctor, false, Args, false, false, false, + false, CXXConstructionKind::Complete, Range); return Result.get(); } @@ -372,7 +376,6 @@ class MetaActionsImpl : public MetaActions { class RestoreDeclContextTy { Sema &S; DeclContext *DC; - public: RestoreDeclContextTy(Sema &S) : S(S), DC(S.CurContext) {} ~RestoreDeclContextTy() { S.CurContext = DC; } @@ -392,8 +395,8 @@ class MetaActionsImpl : public MetaActions { else if (IncompleteDecl->getTagKind() == TagTypeKind::Union) TypeSpec = TST_union; - if (auto *CTSD = - dyn_cast(IncompleteDecl)) { + if (auto *CTSD = dyn_cast( + IncompleteDecl)) { TemplateName TName(CTSD->getSpecializedTemplate()); ParsedTemplateTy ParsedTemplate = ParsedTemplateTy::make(TName); @@ -413,15 +416,16 @@ class MetaActionsImpl : public MetaActions { switch (TArg.getKind()) { case TemplateArgument::Type: ParsedTArgs.emplace_back(ParsedTemplateArgument::Type, - TArg.getAsType().getAsOpaquePtr(), - SourceLocation()); + TArg.getAsType().getAsOpaquePtr(), + SourceLocation()); break; case TemplateArgument::Integral: { - IntegerLiteral *IL = - IntegerLiteral::Create(S.Context, TArg.getAsIntegral(), - TArg.getIntegralType(), DefinitionLoc); + IntegerLiteral *IL = IntegerLiteral::Create(S.Context, + TArg.getAsIntegral(), + TArg.getIntegralType(), + DefinitionLoc); ParsedTArgs.emplace_back(ParsedTemplateArgument::NonType, IL, - SourceLocation()); + SourceLocation()); break; } case TemplateArgument::Template: { @@ -438,18 +442,21 @@ class MetaActionsImpl : public MetaActions { SmallVector CleanupList; TemplateIdAnnotation *TAnnot = TemplateIdAnnotation::Create( - SourceLocation{}, SourceLocation{}, IncompleteDecl->getIdentifier(), - OO_None, ParsedTemplate, TNK_Type_template, SourceLocation{}, - SourceLocation{}, ParsedTArgs, false, CleanupList); + SourceLocation{}, SourceLocation{}, + IncompleteDecl->getIdentifier(), OO_None, ParsedTemplate, + TNK_Type_template, SourceLocation{}, SourceLocation{}, + ParsedTArgs, false, CleanupList); - MTP.push_back(S.ActOnTemplateParameterList( - 0, SourceLocation{}, SourceLocation{}, SourceLocation{}, - std::nullopt, SourceLocation{}, nullptr)); + MTP.push_back( + S.ActOnTemplateParameterList(0, SourceLocation{}, + SourceLocation{}, SourceLocation{}, + std::nullopt, SourceLocation{}, + nullptr)); NewDeclResult = S.ActOnClassTemplateSpecialization( - &ClsScope, TypeSpec, TagUseKind::Definition, DefinitionLoc, - SourceLocation{}, SS, *TAnnot, ParsedAttributesView::none(), MTP, - nullptr); + &ClsScope, TypeSpec, TagUseKind::Definition, DefinitionLoc, + SourceLocation{}, SS, *TAnnot, ParsedAttributesView::none(), + MTP, nullptr); MTP.clear(); for (auto *TAnnot : CleanupList) @@ -478,11 +485,12 @@ class MetaActionsImpl : public MetaActions { bool OwnedDecl = true, IsDependent = false; NewDeclResult = S.ActOnTag( - S.getCurScope(), TypeSpec, TagUseKind::Definition, DefinitionLoc, - SS, IncompleteDecl->getIdentifier(), IncompleteDecl->getBeginLoc(), - ParsedAttributesView::none(), AS_none, SourceLocation{}, MTP, - OwnedDecl, IsDependent, SourceLocation{}, false, TR, false, false, - Sema::OOK_Outside, nullptr); + S.getCurScope(), TypeSpec, TagUseKind::Definition, + DefinitionLoc, SS, IncompleteDecl->getIdentifier(), + IncompleteDecl->getBeginLoc(), ParsedAttributesView::none(), + AS_none, SourceLocation{}, MTP, OwnedDecl, IsDependent, + SourceLocation{}, false, TR, false, false, Sema::OOK_Outside, + nullptr); // The new tag -should- declare the same entity as the original tag. assert((NewDeclResult.isInvalid() || @@ -494,16 +502,16 @@ class MetaActionsImpl : public MetaActions { if (NewDeclResult.isInvalid()) return nullptr; CXXRecordDecl *NewDecl = cast(NewDeclResult.get()); - + // Start the new definition. S.ActOnTagStartDefinition(&ClsScope, NewDecl); S.ActOnStartCXXMemberDeclarations(&ClsScope, NewDecl, SourceLocation{}, false, false, SourceLocation{}); // Derive member visibility. - AccessSpecifier MemberAS = - (IncompleteDecl->isClass() ? AS_private : AS_public); - + AccessSpecifier MemberAS = (IncompleteDecl->isClass() ? AS_private : + AS_public); + AttributeFactory AttrFactory; AttributePool AttrPool(AttrFactory); @@ -513,7 +521,7 @@ class MetaActionsImpl : public MetaActions { // Build the member declaration. unsigned DiagID; const char *PrevSpec; - + DeclSpec DS(AttrFactory); DS.SetStorageClassSpec(S, DeclSpec::SCS_unspecified, DefinitionLoc, PrevSpec, DiagID, S.Context.getPrintingPolicy()); @@ -527,15 +535,17 @@ class MetaActionsImpl : public MetaActions { if (MemberSpec->Alignment) { IdentifierInfo &II = S.Context.Idents.get("alignas"); IntegerLiteral *IL = IntegerLiteral::Create( - S.Context, llvm::APSInt::getUnsigned(MemberSpec->Alignment.value()), - S.Context.getSizeType(), DefinitionLoc); + S.Context, + llvm::APSInt::getUnsigned(MemberSpec->Alignment.value()), + S.Context.getSizeType(), DefinitionLoc); ArgsUnion Args(IL); ParsedAttr::Form Form(tok::kw_alignas); SourceRange Range(DefinitionLoc, DefinitionLoc); - MemberAttrs.addAtEnd(AttrPool.create( - &II, Range, nullptr, SourceLocation{}, nullptr, 0, Form)); + MemberAttrs.addAtEnd(AttrPool.create(&II, Range, nullptr, + SourceLocation{}, nullptr, 0, + Form)); } if (MemberSpec->NoUniqueAddress) { IdentifierInfo &II = S.Context.Idents.get("no_unique_address"); @@ -548,11 +558,11 @@ class MetaActionsImpl : public MetaActions { // Create declarator for the member. Declarator MemberDeclarator(DS, MemberAttrs, DeclaratorContext::Member); - + // Set the identifier, unless this is a zero-width bit-field. if (!MemberSpec->BitWidth || *MemberSpec->BitWidth > 0) { std::string MemberName = MemberSpec->Name.value_or( - "__" + llvm::toString(llvm::APSInt::get(AnonMemCtr++), 10)); + "__" + llvm::toString(llvm::APSInt::get(AnonMemCtr++), 10)); IdentifierInfo &II = S.Context.Idents.get(MemberName); MemberDeclarator.SetIdentifier(&II, DefinitionLoc); @@ -562,8 +572,8 @@ class MetaActionsImpl : public MetaActions { Expr *BitWidthCE = nullptr; if (MemberSpec->BitWidth) { BitWidthCE = IntegerLiteral::Create( - S.Context, llvm::APSInt::getUnsigned(*MemberSpec->BitWidth), - S.Context.getSizeType(), DefinitionLoc); + S.Context, llvm::APSInt::getUnsigned(*MemberSpec->BitWidth), + S.Context.getSizeType(), DefinitionLoc); } VirtSpecifiers VS; @@ -572,9 +582,10 @@ class MetaActionsImpl : public MetaActions { } // Finish the member-specification and the class definition. - S.ActOnFinishCXXMemberSpecification( - &ClsScope, NewDecl->getBeginLoc(), NewDecl, SourceLocation{}, - SourceLocation{}, ParsedAttributesView::none()); + S.ActOnFinishCXXMemberSpecification(&ClsScope, NewDecl->getBeginLoc(), + NewDecl, SourceLocation{}, + SourceLocation{}, + ParsedAttributesView::none()); S.ActOnTagFinishDefinition(&ClsScope, NewDecl, DefinitionLoc); S.ActOnPopScope(DefinitionLoc, &ClsScope); @@ -592,7 +603,7 @@ class MetaActionsImpl : public MetaActions { ParsedAttr::Form::Annotation()); } }; -} // anonymous namespace +} // anonymous namespace ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, SourceLocation TemplateKWLoc, @@ -610,18 +621,16 @@ ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, Found.addDecl(Id.TemplateId->Template.get().getAsTemplateDecl()); } else if (Id.getKind() == UnqualifiedIdKind::IK_TemplateId && Id.TemplateId->Template.get().getKind() == - TemplateName::DependentTemplate && - Id.TemplateId->Template.get() - .getAsDependentTemplateName() - ->isSpliceSpecifier()) { - auto *Splice = - const_cast(Id.TemplateId->Template.get() - .getAsDependentTemplateName() - ->getSpliceSpecifier()); + TemplateName::DependentTemplate && + Id.TemplateId->Template.get().getAsDependentTemplateName() + ->isSpliceSpecifier()) { + auto *Splice = const_cast( + Id.TemplateId->Template.get().getAsDependentTemplateName() + ->getSpliceSpecifier()); ExprResult Result = BuildReflectionSpliceExpr( - TemplateKWLoc, Splice->getLSpliceLoc(), Splice, Splice->getRSpliceLoc(), - TArgs, false); - assert(!Result.isInvalid()); // Should never fail for dependent operands. + TemplateKWLoc, Splice->getLSpliceLoc(), Splice, + Splice->getRSpliceLoc(), TArgs, false); + assert(!Result.isInvalid()); // Should never fail for dependent operands. return BuildCXXReflectExpr(OpLoc, Result.get()); } else if (TemplateKWLoc.isValid() && !TArgs) { @@ -636,8 +645,8 @@ ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, return BuildCXXReflectExpr(OpLoc, TemplateKWLoc, Template.get()); } else if (SS.isSet() && SS.getScopeRep()->isDependent()) { - ExprResult Result = - BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TArgs); + ExprResult Result = BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, + TArgs); // This should only fail if 'SS' is invalid, but that should already have // been diagnosed. assert(!Result.isInvalid()); @@ -696,7 +705,8 @@ ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, } if (auto *TD = dyn_cast(ND)) { - return BuildCXXReflectExpr(OpLoc, NameInfo.getBeginLoc(), TemplateName(TD)); + return BuildCXXReflectExpr(OpLoc, NameInfo.getBeginLoc(), + TemplateName(TD)); } llvm_unreachable("unknown reflection operand!"); @@ -790,7 +800,8 @@ ExprResult Sema::ActOnCXXMetafunction(SourceLocation KwLoc, if (Args.size() < Metafn->getMinArgs() + 1 || Args.size() > Metafn->getMaxArgs() + 1) { Diag(KwLoc, diag::err_metafunction_arity) - << (Metafn->getMinArgs() + 1) << (Metafn->getMaxArgs() + 1) + << (Metafn->getMinArgs() + 1) + << (Metafn->getMaxArgs() + 1) << Args.size(); return ExprError(); } @@ -801,8 +812,8 @@ ExprResult Sema::ActOnCXXMetafunction(SourceLocation KwLoc, const auto &ImplIt = getMetafunctionCb(FnID); // Return the CXXMetafunctionExpr representation. - return BuildCXXMetafunctionExpr(KwLoc, LParenLoc, RParenLoc, FnID, ImplIt, - Args); + return BuildCXXMetafunctionExpr(KwLoc, LParenLoc, RParenLoc, + FnID, ImplIt, Args); } const CXXMetafunctionExpr::ImplFn &Sema::getMetafunctionCb(unsigned FnID) { @@ -812,12 +823,13 @@ const CXXMetafunctionExpr::ImplFn &Sema::getMetafunctionCb(unsigned FnID) { Metafunction::Lookup(FnID, Metafn); assert(Metafn); - auto MetafnImpl = - std::make_unique(std::function( - [this, - Metafn](APValue &Result, CXXMetafunctionExpr::EvaluateFn EvalFn, - CXXMetafunctionExpr::DiagnoseFn DiagFn, QualType ResultTy, - SourceRange Range, ArrayRef Args) -> bool { + auto MetafnImpl = std::make_unique( + std::function( + [this, Metafn](APValue &Result, + CXXMetafunctionExpr::EvaluateFn EvalFn, + CXXMetafunctionExpr::DiagnoseFn DiagFn, + QualType ResultTy, SourceRange Range, + ArrayRef Args) -> bool { MetaActionsImpl Actions(*this); return Metafn->evaluate(Result, Context, Actions, EvalFn, DiagFn, ResultTy, Range, Args); @@ -849,10 +861,10 @@ TypeResult Sema::ActOnCXXSpliceExpectingType(SourceLocation LSpliceLoc, } ExprResult Sema::ActOnCXXSpliceExpectingExpr( - SourceLocation TemplateKWLoc, SourceLocation LSpliceLoc, Expr *Operand, - SourceLocation RSpliceLoc, SourceLocation LAngleLoc, - ASTTemplateArgsPtr TArgsIn, SourceLocation RAngleLoc, - bool AllowMemberReference) { + SourceLocation TemplateKWLoc, SourceLocation LSpliceLoc, Expr *Operand, + SourceLocation RSpliceLoc, SourceLocation LAngleLoc, + ASTTemplateArgsPtr TArgsIn, SourceLocation RAngleLoc, + bool AllowMemberReference) { TemplateArgumentListInfo TArgs; if (TArgsIn.size() > 0) { TArgs.setLAngleLoc(LAngleLoc); @@ -870,16 +882,15 @@ DeclResult Sema::ActOnCXXSpliceExpectingNamespace(SourceLocation LSpliceLoc, return BuildReflectionSpliceNamespace(LSpliceLoc, Operand, RSpliceLoc); } -Sema::TemplateTy -Sema::ActOnCXXSpliceExpectingTemplate(SourceLocation LSpliceLoc, Expr *Operand, - SourceLocation RSpliceLoc, - bool Complain) { +Sema::TemplateTy Sema::ActOnCXXSpliceExpectingTemplate( + SourceLocation LSpliceLoc, Expr *Operand, SourceLocation RSpliceLoc, + bool Complain) { return BuildReflectionSpliceTemplate(LSpliceLoc, Operand, RSpliceLoc, Complain); } -ParsedTemplateArgument -Sema::ActOnTemplateSpliceSpecifierArgument(CXXSpliceSpecifierExpr *Splice) { +ParsedTemplateArgument Sema::ActOnTemplateSpliceSpecifierArgument( + CXXSpliceSpecifierExpr *Splice) { if (Splice->isValueDependent()) { return ParsedTemplateArgument(ParsedTemplateArgument::SpliceSpecifier, Splice, Splice->getExprLoc()); @@ -895,29 +906,28 @@ Sema::ActOnTemplateSpliceSpecifierArgument(CXXSpliceSpecifierExpr *Splice) { if (Splice->getTemplateKWLoc().isValid() && !ER.Val.isReflectedTemplate()) { Diag(Splice->getOperand()->getExprLoc(), - diag::err_unexpected_reflection_kind_in_splice) - << 3; + diag::err_unexpected_reflection_kind_in_splice) << 3; return ParsedTemplateArgument(); } switch (ER.Val.getReflectionKind()) { case ReflectionKind::Type: - return ParsedTemplateArgument( - ParsedTemplateArgument::Type, - const_cast(ER.Val.getOpaqueReflectionData()), - Splice->getExprLoc()); + return ParsedTemplateArgument(ParsedTemplateArgument::Type, + const_cast( + ER.Val.getOpaqueReflectionData()), + Splice->getExprLoc()); case ReflectionKind::Object: { QualType ResultTy = ER.Val.getTypeOfReflectedResult(Context); - Expr *OVE = new (Context) - OpaqueValueExpr(Splice->getExprLoc(), ResultTy, VK_LValue); + Expr *OVE = new (Context) OpaqueValueExpr(Splice->getExprLoc(), ResultTy, + VK_LValue); Expr *CE = ConstantExpr::Create(Context, OVE, ER.Val.getReflectedObject()); return ParsedTemplateArgument(ParsedTemplateArgument::NonType, CE, Splice->getExprLoc()); } case ReflectionKind::Value: { QualType ResultTy = ER.Val.getTypeOfReflectedResult(Context); - Expr *OVE = new (Context) - OpaqueValueExpr(Splice->getExprLoc(), ResultTy, VK_PRValue); + Expr *OVE = new (Context) OpaqueValueExpr(Splice->getExprLoc(), ResultTy, + VK_PRValue); Expr *CE = ConstantExpr::Create(Context, OVE, ER.Val.getReflectedValue()); return ParsedTemplateArgument(ParsedTemplateArgument::NonType, CE, Splice->getExprLoc()); @@ -936,19 +946,19 @@ Sema::ActOnTemplateSpliceSpecifierArgument(CXXSpliceSpecifierExpr *Splice) { } case ReflectionKind::Null: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) - << "null reflections" << 0 << 0; + << "null reflections" << 0 << 0; break; case ReflectionKind::Namespace: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) - << "namespaces" << 0 << 0; + << "namespaces" << 0 << 0; break; case ReflectionKind::BaseSpecifier: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) - << "base specifiers" << 0 << 0; + << "base specifiers" << 0 << 0; break; case ReflectionKind::DataMemberSpec: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) - << "data member specs" << 0 << 0; + << "data member specs" << 0 << 0; break; } return ParsedTemplateArgument(); @@ -975,11 +985,11 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, // TODO(P2996): Capture whole SourceRange of declaration naming. ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, SourceLocation OperandLoc, Decl *D) { - bool IsNamespace = - isa(D); + bool IsNamespace = isa(D); - APValue RV( - IsNamespace ? ReflectionKind::Namespace : ReflectionKind::Declaration, D); + APValue RV(IsNamespace ? ReflectionKind::Namespace : + ReflectionKind::Declaration, D); return CXXReflectExpr::Create(Context, OperatorLoc, SourceRange(OperandLoc, OperandLoc), RV); } @@ -1037,9 +1047,9 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, // variable which would be initialized by the operand 'ULE'. QualType ConstAutoTy = Context.getAutoDeductType().withConst(); TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(ConstAutoTy, 0); - auto *InventedVD = - VarDecl::Create(Context, nullptr, SourceLocation(), E->getExprLoc(), - nullptr, ConstAutoTy, TSI, SC_Auto); + auto *InventedVD = VarDecl::Create(Context, nullptr, SourceLocation(), + E->getExprLoc(), nullptr, ConstAutoTy, + TSI, SC_Auto); // Use the 'auto' deduction machinery to infer the operand type. if (DeduceVariableDeclarationType(InventedVD, true, ULE)) { @@ -1052,8 +1062,10 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, // refer to; raise an error in the presence of any ambiguity. bool HadMultipleCandidates; DeclAccessPair FoundOverload; - FunctionDecl *FoundDecl = ResolveAddressOfOverloadedFunction( - ULE, InventedVD->getType(), true, FoundOverload, &HadMultipleCandidates); + FunctionDecl *FoundDecl = + ResolveAddressOfOverloadedFunction(ULE, InventedVD->getType(), true, + FoundOverload, + &HadMultipleCandidates); if (!FoundDecl) { Diag(E->getExprLoc(), diag::err_reflect_overload_set); return ExprError(); @@ -1130,11 +1142,10 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, APValue{ReflectionKind::Attribute, static_cast(A)}); } -ExprResult -Sema::BuildCXXMetafunctionExpr(SourceLocation KwLoc, SourceLocation LParenLoc, - SourceLocation RParenLoc, unsigned MetaFnID, - const CXXMetafunctionExpr::ImplFn &Impl, - SmallVectorImpl &Args) { +ExprResult Sema::BuildCXXMetafunctionExpr( + SourceLocation KwLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, + unsigned MetaFnID, const CXXMetafunctionExpr::ImplFn &Impl, + SmallVectorImpl &Args) { // Look up the corresponding Metafunction object. const Metafunction *MetaFn; if (Metafunction::Lookup(MetaFnID, MetaFn)) { @@ -1158,7 +1169,7 @@ Sema::BuildCXXMetafunctionExpr(SourceLocation KwLoc, SourceLocation LParenLoc, RecordDecl *SourceLocDecl = lookupStdSourceLocationImpl(KwLoc); if (SourceLocDecl) Result = Context.getPointerType( - Context.getRecordType(SourceLocDecl).withConst()); + Context.getRecordType(SourceLocDecl).withConst()); return SourceLocDecl == nullptr; } case Metafunction::MFRK_spliceFromArg: { @@ -1225,7 +1236,8 @@ ExprResult Sema::BuildCXXSpliceSpecifierExpr(SourceLocation TemplateKWLoc, return Operand; } -QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, Expr *Operand, +QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, + Expr *Operand, SourceLocation RSplice, bool Complain) { if (Operand->isTypeDependent() || Operand->isValueDependent()) { @@ -1250,12 +1262,11 @@ QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, Expr *Operand, if (ER.Val.isReflectedTemplate()) { return Context.getDeducedTemplateSpecializationType( - ER.Val.getReflectedTemplate(), QualType(), false); + ER.Val.getReflectedTemplate(), QualType(), false); } else if (!ER.Val.isReflectedType()) { if (Complain) Diag(Operand->getExprLoc(), - diag::err_unexpected_reflection_kind_in_splice) - << 0; + diag::err_unexpected_reflection_kind_in_splice) << 0; return QualType(); } @@ -1267,12 +1278,14 @@ QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, Expr *Operand, CTD && CTD->getSpecializationKind() == TSK_Undeclared) { TemplateName TName(CTD->getSpecializedTemplate()); - const TemplateArgumentList &TAList = CTD->getTemplateInstantiationArgs(); + const TemplateArgumentList &TAList = + CTD->getTemplateInstantiationArgs(); TemplateArgumentListInfo TAListInfo( - addLocToTemplateArgs(*this, TAList.asArray(), Operand->getExprLoc())); + addLocToTemplateArgs(*this, TAList.asArray(), + Operand->getExprLoc())); - ReflectedTy = - CheckTemplateIdType(TName, Operand->getExprLoc(), TAListInfo); + ReflectedTy = CheckTemplateIdType(TName, Operand->getExprLoc(), + TAListInfo); if (ReflectedTy.isNull()) return QualType(); } @@ -1281,11 +1294,12 @@ QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, Expr *Operand, } QualType Sema::BuildReflectionSpliceTypeLoc(TypeLocBuilder &TLB, - SourceLocation LSpliceLoc, Expr *E, + SourceLocation LSpliceLoc, + Expr *E, SourceLocation RSpliceLoc, bool Complain) { - QualType SpliceTy = - BuildReflectionSpliceType(LSpliceLoc, E, RSpliceLoc, Complain); + QualType SpliceTy = BuildReflectionSpliceType(LSpliceLoc, E, RSpliceLoc, + Complain); if (SpliceTy.isNull()) return QualType(); else if (isa(SpliceTy)) { @@ -1306,11 +1320,11 @@ QualType Sema::BuildReflectionSpliceTypeLoc(TypeLocBuilder &TLB, } ExprResult Sema::BuildReflectionSpliceExpr( - SourceLocation TemplateKWLoc, SourceLocation LSplice, Expr *Operand, - SourceLocation RSplice, const TemplateArgumentListInfo *TArgs, - bool AllowMemberReference) { - if (isa(Operand) && !Operand->isTypeDependent() && - !Operand->isValueDependent()) { + SourceLocation TemplateKWLoc, SourceLocation LSplice, Expr *Operand, + SourceLocation RSplice, const TemplateArgumentListInfo *TArgs, + bool AllowMemberReference) { + if (isa(Operand) && + !Operand->isTypeDependent() && !Operand->isValueDependent()) { auto *SpliceOp = cast(Operand); SmallVector Diags; @@ -1328,12 +1342,11 @@ ExprResult Sema::BuildReflectionSpliceExpr( Diag(Operand->getExprLoc(), diag::err_splice_operand_not_reflection); return ExprError(); } - bool RequireTemplate = - TemplateKWLoc.isValid() || TArgs->getLAngleLoc().isValid(); + bool RequireTemplate = TemplateKWLoc.isValid() || + TArgs->getLAngleLoc().isValid(); if (RequireTemplate && !ER.Val.isReflectedTemplate()) { Diag(Operand->getExprLoc(), - diag::err_unexpected_reflection_kind_in_splice) - << 3; + diag::err_unexpected_reflection_kind_in_splice) << 3; return ExprError(); } @@ -1348,7 +1361,7 @@ ExprResult Sema::BuildReflectionSpliceExpr( dyn_cast(TheDecl)->isInstance()))) { Diag(Operand->getExprLoc(), diag::err_dependent_splice_implicit_member_reference) - << Operand->getSourceRange(); + << Operand->getSourceRange(); Diag(Operand->getExprLoc(), diag::note_dependent_splice_explicit_this_may_fix); return ExprError(); @@ -1373,32 +1386,32 @@ ExprResult Sema::BuildReflectionSpliceExpr( } case ReflectionKind::Object: { QualType QT = ER.Val.getTypeOfReflectedResult(Context); - Expr *OVE = - new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), QT, VK_LValue); - Expr *CE = - ConstantExpr::Create(Context, OVE, ER.Val.getReflectedObject()); - - Operand = - CXXSpliceExpr::Create(Context, VK_LValue, TemplateKWLoc, LSplice, CE, - RSplice, TArgs, AllowMemberReference); + Expr *OVE = new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), QT, + VK_LValue); + Expr *CE = ConstantExpr::Create(Context, OVE, + ER.Val.getReflectedObject()); + + Operand = CXXSpliceExpr::Create(Context, VK_LValue, TemplateKWLoc, + LSplice, CE, RSplice, TArgs, + AllowMemberReference); break; } case ReflectionKind::Value: { QualType QT = ER.Val.getTypeOfReflectedResult(Context); - Expr *OVE = - new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), QT, VK_PRValue); + Expr *OVE = new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), QT, + VK_PRValue); Expr *CE = ConstantExpr::Create(Context, OVE, ER.Val.getReflectedValue()); - Operand = - CXXSpliceExpr::Create(Context, VK_PRValue, TemplateKWLoc, LSplice, CE, - RSplice, TArgs, AllowMemberReference); + Operand = CXXSpliceExpr::Create(Context, VK_PRValue, TemplateKWLoc, + LSplice, CE, RSplice, TArgs, + AllowMemberReference); break; } case ReflectionKind::Template: { if (SpliceOp->getTemplateKWLoc().isInvalid()) { Diag(SpliceOp->getOperand()->getExprLoc(), diag::err_unexpected_reflection_kind_in_splice) - << 1 << SpliceOp->getOperand()->getSourceRange(); + << 1 << SpliceOp->getOperand()->getSourceRange(); return ExprError(); } @@ -1412,7 +1425,7 @@ ExprResult Sema::BuildReflectionSpliceExpr( CXXScopeSpec SS; if (auto *RD = dyn_cast(TDecl->getDeclContext())) { TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo( - QualType(RD->getTypeForDecl(), 0), Operand->getExprLoc()); + QualType(RD->getTypeForDecl(), 0), Operand->getExprLoc()); SS.Extend(Context, SourceLocation(), TSI->getTypeLoc(), Operand->getExprLoc()); } @@ -1451,8 +1464,7 @@ ExprResult Sema::BuildReflectionSpliceExpr( } else if (isa(TDecl) || isa(TDecl)) { Diag(Operand->getExprLoc(), - diag::err_unexpected_reflection_template_kind) - << 1; + diag::err_unexpected_reflection_template_kind) << 1; return ExprError(); } @@ -1460,21 +1472,22 @@ ExprResult Sema::BuildReflectionSpliceExpr( NestedNameSpecifierLocBuilder NNSLocBuilder; if (auto *RD = dyn_cast(TDecl->getDeclContext())) { TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo( - QualType(RD->getTypeForDecl(), 0), Operand->getExprLoc()); - NNSLocBuilder.Extend(Context, SourceLocation(), TSI->getTypeLoc(), - Operand->getExprLoc()); + QualType(RD->getTypeForDecl(), 0), Operand->getExprLoc()); + NNSLocBuilder.Extend(Context, SourceLocation(), + TSI->getTypeLoc(), Operand->getExprLoc()); } UnresolvedSet<1> DeclSet; DeclSet.addDecl(TDecl); - Operand = UnresolvedLookupExpr::Create( - Context, NamingCls, SS.getWithLocInContext(Context), SourceLocation(), - DeclNameInfo, false, TArgs, DeclSet.begin(), DeclSet.end(), false, - false); - - Operand = - CXXSpliceExpr::Create(Context, VK_LValue, TemplateKWLoc, LSplice, - Operand, RSplice, TArgs, AllowMemberReference); + Operand = UnresolvedLookupExpr::Create(Context, NamingCls, + SS.getWithLocInContext(Context), + SourceLocation(), DeclNameInfo, + false, TArgs, DeclSet.begin(), + DeclSet.end(), false, false); + + Operand = CXXSpliceExpr::Create(Context, VK_LValue, TemplateKWLoc, + LSplice, Operand, RSplice, TArgs, + AllowMemberReference); break; } case ReflectionKind::Null: @@ -1490,9 +1503,9 @@ ExprResult Sema::BuildReflectionSpliceExpr( } return Operand; } - return CXXSpliceExpr::Create(Context, Operand->getValueKind(), TemplateKWLoc, - LSplice, Operand, RSplice, TArgs, - AllowMemberReference); + return CXXSpliceExpr::Create(Context, Operand->getValueKind(), + TemplateKWLoc, LSplice, Operand, RSplice, + TArgs, AllowMemberReference); } DeclResult Sema::BuildReflectionSpliceNamespace(SourceLocation LSplice, @@ -1523,7 +1536,8 @@ DeclResult Sema::BuildReflectionSpliceNamespace(SourceLocation LSplice, Diag(Operand->getExprLoc(), diag::err_unexpected_reflection_kind) << 2; return DeclError(); } else if (isa(ER.Val.getReflectedNamespace())) { - Diag(Operand->getExprLoc(), diag::err_splice_global_scope_as_namespace); + Diag(Operand->getExprLoc(), + diag::err_splice_global_scope_as_namespace); return DeclError(); } @@ -1538,8 +1552,9 @@ Sema::TemplateTy Sema::BuildReflectionSpliceTemplate(SourceLocation LSplice, auto *SpliceOp = cast(Operand); if (Operand->isValueDependent()) - return TemplateTy::make(Context.getDependentTemplateName( - cast(Operand))); + return TemplateTy::make( + Context.getDependentTemplateName( + cast(Operand))); SmallVector Diags; Expr::EvalResult ER; @@ -1547,8 +1562,7 @@ Sema::TemplateTy Sema::BuildReflectionSpliceTemplate(SourceLocation LSplice, if (!Operand->EvaluateAsRValue(ER, Context, true)) { Diag(SpliceOp->getOperand()->getExprLoc(), - diag::err_splice_operand_not_constexpr) - << SpliceOp->getOperand(); + diag::err_splice_operand_not_constexpr) << SpliceOp->getOperand(); for (PartialDiagnosticAt PD : Diags) Diag(PD.first, PD.second); return TemplateTy(); @@ -1556,8 +1570,7 @@ Sema::TemplateTy Sema::BuildReflectionSpliceTemplate(SourceLocation LSplice, if (!ER.Val.isReflection()) { Diag(SpliceOp->getOperand()->getExprLoc(), - diag::err_splice_operand_not_reflection) - << SpliceOp->getSourceRange(); + diag::err_splice_operand_not_reflection) << SpliceOp->getSourceRange(); return TemplateTy(); } From edef0d251bda8c38828a40b4e02a2cab174bf101 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 6 Oct 2024 21:04:31 +0900 Subject: [PATCH 06/26] Stash diagnostic to trace compilation --- .../clang/Basic/DiagnosticParseKinds.td | 9 +++++ .../clang/Basic/DiagnosticSemaKinds.td | 3 ++ clang/lib/Parse/ParseReflect.cpp | 38 ++++++++++--------- clang/lib/Sema/SemaReflect.cpp | 4 +- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index f7a9a698911b2a..4883b498fa877c 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1746,6 +1746,15 @@ def err_annotation_with_using : Error< "annotations are not permitted following an attribute-using-prefix">; } +let CategoryName = "P3385" in { + +def p3385_trace_attribute_parsed : Warning< + "found attribute to parse following caret operator">; +def p3385_err_attributes_list : Error< + "reflection of attribute list is not supported, found %0 attributes">; + +} + let CategoryName = "Generics Issue" in { def err_objc_expected_type_parameter : Error< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5db541f3a87eb7..5c37168bba951d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3173,6 +3173,9 @@ def note_dependent_splice_explicit_this_may_fix : Note< def err_cannot_expand_over_type : Error< "cannot expand over an expression of type %0">; +def p3385_trace_building_attribute_reflection : Warning< + "building a CXX reflection on attribute %0">; + // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< "'%0' type specifier is incompatible with C++98">, diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index bef389d078c1ab..e1bafd46ea9835 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -40,24 +40,6 @@ ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { // TentativeParsingAction TentativeAction(*this); - // Check for a standard attribute - { - assert(true && "P3385 - ParseCXXReflectExpression"); - ParsedAttributes attrs(AttrFactory); - if (MaybeParseAttributes(CXX11AttributeKind::CAK_AttributeSpecifier, - attrs)) { - if (attrs.size() > 1) { - assert(attrs.size() == 1 && "Attributes list are not supported"); - TentativeAction.Revert(); - return ExprError(); - } - - TentativeAction.Commit(); - return Actions.ActOnCXXReflectExpr(OpLoc, &attrs.front()); - } - TentativeAction.Revert(); - } - // Next, check for an unqualified-id. if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::kw_template, tok::tilde, tok::annot_template_id)) { @@ -97,6 +79,26 @@ ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { } TentativeAction.Revert(); + + // Check for a standard attribute + { + ParsedAttributes attrs(AttrFactory); + if (MaybeParseAttributes(CXX11AttributeKind::CAK_AttributeSpecifier, + attrs)) { + Diag(OperandLoc, diag::p3385_trace_attribute_parsed); + // FIXME handle empty [[]] + if (attrs.size() != 1) { + Diag(OperandLoc, diag::p3385_err_attributes_list) << attrs.size(); + TentativeAction.Revert(); + return ExprError(); + } + + TentativeAction.Commit(); + return Actions.ActOnCXXReflectExpr(OpLoc, &attrs.front()); + } + TentativeAction.Revert(); + } + if (SS.isSet() && TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, true, ImplicitTypenameContext::No)) { diff --git a/clang/lib/Sema/SemaReflect.cpp b/clang/lib/Sema/SemaReflect.cpp index 1a89deadd3ffe3..2d3ca061838d3d 100644 --- a/clang/lib/Sema/SemaReflect.cpp +++ b/clang/lib/Sema/SemaReflect.cpp @@ -1134,8 +1134,8 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, ParsedAttr *A) { - assert(true && "P3385 - BuildCXXReflectExpr"); - assert(true && A->getAttrName()->getName()); + Diag(A->getLoc(), diag::p3385_trace_building_attribute_reflection) + << A->getAttrName()->getName(); return CXXReflectExpr::Create( Context, OperatorLoc, A->getRange(), From 0c32b986f86ae8d20f3ce7471938f3e684911121 Mon Sep 17 00:00:00 2001 From: zebullon Date: Mon, 7 Oct 2024 17:33:37 +0900 Subject: [PATCH 07/26] Remove misplaced revert on attribute parse --- clang/include/clang/Basic/DiagnosticParseKinds.td | 4 ++-- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Parse/ParseReflect.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 4883b498fa877c..2461506bd82f80 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1749,9 +1749,9 @@ def err_annotation_with_using : Error< let CategoryName = "P3385" in { def p3385_trace_attribute_parsed : Warning< - "found attribute to parse following caret operator">; + "(p3385) found attribute to parse following caret operator">; def p3385_err_attributes_list : Error< - "reflection of attribute list is not supported, found %0 attributes">; + "(p3385) reflection of attribute list is not supported, found %0 attributes">; } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5c37168bba951d..716df4fbcafcc5 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3174,7 +3174,7 @@ def err_cannot_expand_over_type : Error< "cannot expand over an expression of type %0">; def p3385_trace_building_attribute_reflection : Warning< - "building a CXX reflection on attribute %0">; + "(p3385) building a CXX reflection on attribute %0">; // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index e1bafd46ea9835..3b2aa6f1b75774 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/AST/Attr.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" @@ -89,7 +90,6 @@ ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { // FIXME handle empty [[]] if (attrs.size() != 1) { Diag(OperandLoc, diag::p3385_err_attributes_list) << attrs.size(); - TentativeAction.Revert(); return ExprError(); } From 9dd6baea853270f01994347d529c70dcb889fc1e Mon Sep 17 00:00:00 2001 From: zebullon Date: Mon, 7 Oct 2024 20:22:40 +0900 Subject: [PATCH 08/26] Add dumb trace for the boys Actually parse the reflection on assume --- clang/include/clang/Basic/DiagnosticParseKinds.td | 4 ++++ clang/lib/Parse/ParseDeclCXX.cpp | 12 ++++++++++-- clang/lib/Parse/ParseReflect.cpp | 15 ++++++++------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 2461506bd82f80..a32642778b1ce1 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1750,6 +1750,10 @@ let CategoryName = "P3385" in { def p3385_trace_attribute_parsed : Warning< "(p3385) found attribute to parse following caret operator">; +def p3385_trace_empty_attributes_list : Warning< + "(p3385) reflection of an empty attribute list">; +def p3385_trace_ParseCXX11AttributeSpecifierInternal : Warning< + "(p3385) ParseCXX11AttributeSpecifierInternal %0">; def p3385_err_attributes_list : Error< "(p3385) reflection of attribute list is not supported, found %0 attributes">; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index fe46d6a86da5a4..31c6afa3fe46af 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -5080,6 +5080,7 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, } if (Tok.isRegularKeywordAttribute()) { + Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "0"; SourceLocation Loc = Tok.getLocation(); IdentifierInfo *AttrName = Tok.getIdentifierInfo(); ParsedAttr::Form Form = ParsedAttr::Form(Tok.getKind()); @@ -5134,7 +5135,9 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, bool AttrParsed = false; while (!Tok.isOneOf(tok::r_square, tok::semi, tok::eof, tok::r_splice)) { + Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "1"; if (AttrParsed) { + Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "1.1"; // If we parsed an attribute, a comma is required before parsing any // additional attributes. if (ExpectAndConsume(tok::comma)) { @@ -5165,9 +5168,11 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, AttrName = TryParseCXX11AttributeIdentifier( AttrLoc, SemaCodeCompletion::AttributeCompletion::Attribute, CommonScopeName); - if (!AttrName) + if (!AttrName) { + Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "2"; // Break out to the "expected ']'" diagnostic. break; + } // scoped attribute if (TryConsumeToken(tok::coloncolon)) { @@ -5195,11 +5200,14 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, } // Parse attribute arguments - if (Tok.is(tok::l_paren)) + if (Tok.is(tok::l_paren)){ + Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "3"; AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc, ScopeName, ScopeLoc, OpenMPTokens); + } if (!AttrParsed) { + Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "4"; Attrs.addNew( AttrName, SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc), diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index 3b2aa6f1b75774..fbd8c0c9af471e 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -80,23 +80,24 @@ ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { } TentativeAction.Revert(); - // Check for a standard attribute { ParsedAttributes attrs(AttrFactory); - if (MaybeParseAttributes(CXX11AttributeKind::CAK_AttributeSpecifier, - attrs)) { + if (MaybeParseCXX11Attributes(attrs)) { Diag(OperandLoc, diag::p3385_trace_attribute_parsed); - // FIXME handle empty [[]] - if (attrs.size() != 1) { + + // FIXME handle empty [[]] gracefully + if (attrs.empty()) { + Diag(OperandLoc, diag::p3385_trace_empty_attributes_list); + return ExprError(); + } + if (attrs.size() > 1) { Diag(OperandLoc, diag::p3385_err_attributes_list) << attrs.size(); return ExprError(); } - TentativeAction.Commit(); return Actions.ActOnCXXReflectExpr(OpLoc, &attrs.front()); } - TentativeAction.Revert(); } if (SS.isSet() && From fe573e42d8976e11891956200db2b5a0efadcd50 Mon Sep 17 00:00:00 2001 From: zebullon Date: Mon, 7 Oct 2024 20:28:32 +0900 Subject: [PATCH 09/26] Clean up brkpoint traces --- clang/include/clang/Basic/DiagnosticParseKinds.td | 4 ++-- clang/lib/Parse/ParseDeclCXX.cpp | 9 +-------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index a32642778b1ce1..35c710c215ecd1 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1752,8 +1752,8 @@ def p3385_trace_attribute_parsed : Warning< "(p3385) found attribute to parse following caret operator">; def p3385_trace_empty_attributes_list : Warning< "(p3385) reflection of an empty attribute list">; -def p3385_trace_ParseCXX11AttributeSpecifierInternal : Warning< - "(p3385) ParseCXX11AttributeSpecifierInternal %0">; +def p3385_trace_execution_checkpoint : Warning< + "(p3385) trace_execution_checkpoint %0">; def p3385_err_attributes_list : Error< "(p3385) reflection of attribute list is not supported, found %0 attributes">; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 31c6afa3fe46af..407183aace5c4c 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -5080,7 +5080,6 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, } if (Tok.isRegularKeywordAttribute()) { - Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "0"; SourceLocation Loc = Tok.getLocation(); IdentifierInfo *AttrName = Tok.getIdentifierInfo(); ParsedAttr::Form Form = ParsedAttr::Form(Tok.getKind()); @@ -5135,9 +5134,7 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, bool AttrParsed = false; while (!Tok.isOneOf(tok::r_square, tok::semi, tok::eof, tok::r_splice)) { - Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "1"; if (AttrParsed) { - Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "1.1"; // If we parsed an attribute, a comma is required before parsing any // additional attributes. if (ExpectAndConsume(tok::comma)) { @@ -5168,11 +5165,9 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, AttrName = TryParseCXX11AttributeIdentifier( AttrLoc, SemaCodeCompletion::AttributeCompletion::Attribute, CommonScopeName); - if (!AttrName) { - Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "2"; + if (!AttrName) // Break out to the "expected ']'" diagnostic. break; - } // scoped attribute if (TryConsumeToken(tok::coloncolon)) { @@ -5201,13 +5196,11 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, // Parse attribute arguments if (Tok.is(tok::l_paren)){ - Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "3"; AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc, ScopeName, ScopeLoc, OpenMPTokens); } if (!AttrParsed) { - Diag(Tok.getLocation(), diag::p3385_trace_ParseCXX11AttributeSpecifierInternal) << "4"; Attrs.addNew( AttrName, SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc), From b0d1f58c36789a1e9d0aa45d89955e2adbd567d1 Mon Sep 17 00:00:00 2001 From: zebullon Date: Tue, 8 Oct 2024 21:18:43 +0900 Subject: [PATCH 10/26] Stash non working meta functions --- clang/include/clang/AST/ExprCXX.h | 3 ++- clang/lib/AST/ExprConstantMeta.cpp | 24 ++++++++++++++++++++++++ libcxx/include/experimental/meta | 7 +++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index ea12345ea49f55..137cb75e8b9d6d 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -5321,7 +5321,8 @@ class BuiltinBitCastExpr final }; /// Represents a C++2c reflect expression (P2996). The operand of the expression -/// is either a type, an expression, a template-name, or a namespace. +/// is either a type, an expression, a template-name, an attribute or a +/// namespace. class CXXReflectExpr : public Expr { enum class OperandKind { Unset, diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index aa1a14ac9ca746..c2b94871740534 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -26,6 +26,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Sema/ParsedAttr.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" @@ -291,6 +292,10 @@ static bool is_namespace(APValue &Result, ASTContext &C, MetaActions &Meta, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, SourceRange Range, ArrayRef Args); +static bool is_attribute(APValue &Result, ASTContext &C, MetaActions &Meta, + EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, + SourceRange Range, ArrayRef Args); + static bool is_function(APValue &Result, ASTContext &C, MetaActions &Meta, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, SourceRange Range, ArrayRef Args); @@ -627,6 +632,7 @@ static constexpr Metafunction Metafunctions[] = { { Metafunction::MFRK_bool, 1, 1, is_base }, { Metafunction::MFRK_bool, 1, 1, is_data_member_spec }, { Metafunction::MFRK_bool, 1, 1, is_namespace }, + { Metafunction::MFRK_bool, 1, 1, is_attribute }, { Metafunction::MFRK_bool, 1, 1, is_function }, { Metafunction::MFRK_bool, 1, 1, is_variable }, { Metafunction::MFRK_bool, 1, 1, is_type }, @@ -1871,6 +1877,11 @@ bool identifier_of(APValue &Result, ASTContext &C, MetaActions &Meta, getDeclName(Name, C, RV.getReflectedNamespace()); break; } + case clang::ReflectionKind::Attribute: { + ParsedAttr* attr = RV.getReflectedAttribute(); + Name = attr->getAttrName()->getName(); + break; + } case ReflectionKind::DataMemberSpec: { TagDataMemberSpec *TDMS = RV.getReflectedDataMemberSpec(); if (TDMS->Name) @@ -3851,6 +3862,19 @@ bool is_namespace(APValue &Result, ASTContext &C, MetaActions &Meta, return SetAndSucceed(Result, makeBool(C, RV.isReflectedNamespace())); } +bool is_attribute(APValue &Result, ASTContext &C, MetaActions &Meta, + EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, + SourceRange Range, ArrayRef Args) { + assert(Args[0]->getType()->isReflectionType()); + assert(ResultTy == C.BoolTy); + + APValue RV; + if (!Evaluator(RV, Args[0], true)) + return true; + + return SetAndSucceed(Result, makeBool(C, RV.isReflectedAttribute())); +} + bool is_function(APValue &Result, ASTContext &C, MetaActions &Meta, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, SourceRange Range, ArrayRef Args) { diff --git a/libcxx/include/experimental/meta b/libcxx/include/experimental/meta index 1a1b322cc88d24..a7b6c9d297d021 100644 --- a/libcxx/include/experimental/meta +++ b/libcxx/include/experimental/meta @@ -153,6 +153,7 @@ consteval auto is_static_member(info) -> bool; consteval auto is_base(info) -> bool; consteval auto is_data_member_spec(info) -> bool; consteval auto is_namespace(info) -> bool; +consteval auto is_attribute(info) -> bool; consteval auto is_function(info) -> bool; consteval auto is_variable(info) -> bool; consteval auto is_type(info) -> bool; @@ -479,6 +480,7 @@ enum : unsigned { __metafn_is_base, __metafn_is_data_member_spec, __metafn_is_namespace, + __metafn_is_attribute, __metafn_is_function, __metafn_is_variable, __metafn_is_type, @@ -886,6 +888,11 @@ consteval auto is_namespace(info r) -> bool { return __metafunction(detail::__metafn_is_namespace, r); } +// Returns whether the reflected entity is an attribute. +consteval auto is_attribute(info r) -> bool { + return __metafunction(detail::__metafn_is_attribute, r); +} + consteval auto bases_of(info r) -> vector { if (is_namespace(r)) throw "Namespaces cannot have base classes"; From 7d12469a23090af6173edfb38e78ee45cf41dd51 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sat, 12 Oct 2024 12:42:48 +0900 Subject: [PATCH 11/26] Support is_attribute --- clang/include/clang/AST/RecursiveASTVisitor.h | 2 +- .../clang/Basic/DiagnosticMetafnKinds.td | 4 ++- clang/lib/AST/APValue.cpp | 4 +++ clang/lib/AST/ExprConstantMeta.cpp | 29 +++++++++++++++++-- clang/lib/AST/ItaniumMangle.cpp | 5 ++++ clang/lib/Parse/ParseDeclCXX.cpp | 3 +- clang/lib/Sema/SemaReflect.cpp | 6 ++++ clang/lib/Sema/TreeTransform.h | 1 + 8 files changed, 47 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index d89134e044cd39..268c8bafdb6c88 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2991,7 +2991,7 @@ DEF_TRAVERSE_STMT(CXXReflectExpr, { case ReflectionKind::Namespace: case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: - case ReflectionKind::Attribute: + case ReflectionKind::Attribute: // TODO P3385 ? break; } } diff --git a/clang/include/clang/Basic/DiagnosticMetafnKinds.td b/clang/include/clang/Basic/DiagnosticMetafnKinds.td index 3bd7a0019a666d..3cc79bbbfabe9c 100644 --- a/clang/include/clang/Basic/DiagnosticMetafnKinds.td +++ b/clang/include/clang/Basic/DiagnosticMetafnKinds.td @@ -18,7 +18,7 @@ def metafn_no_associated_property : Note< "%0 has no %select{type|parent}1">; def metafn_cannot_query_property : Note<"cannot query the " "%select{type|object|value|size|alignment|parameters|return type|" - "annotations}0 of %1">; + "annotations|attributes}0 of %1">; // Ranges of entities. def metafn_cannot_introspect_type : Note< @@ -88,6 +88,8 @@ def metafn_value_not_structural_type : Note< "values of non-structural type %0 cannot be represented as reflections">; def metafn_result_not_representable : Note< "provided %select{value|object}0 cannot be represented by a reflection">; +def metafn_p3385_trace_execution_checkpoint : Note< + "(p3385-metafn) trace_execution_checkpoint %0">; // Class definition. def metafn_name_invalid_identifier : Note< diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index e3337863ec3711..6a68b888c6d509 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -1303,6 +1303,9 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy, case ReflectionKind::Annotation: Repr = "annotation"; break; + case ReflectionKind::Attribute: + Repr = "attribute"; + break; } Out << "^^(" << Repr << ")"; return; @@ -1643,6 +1646,7 @@ void APValue::setReflection(ReflectionKind RK, const void *Ptr) { case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: SelfData.Kind = RK; SelfData.Data = Ptr; return; diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index c2b94871740534..af393d56cfb98f 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -1877,7 +1877,7 @@ bool identifier_of(APValue &Result, ASTContext &C, MetaActions &Meta, getDeclName(Name, C, RV.getReflectedNamespace()); break; } - case clang::ReflectionKind::Attribute: { + case ReflectionKind::Attribute: { ParsedAttr* attr = RV.getReflectedAttribute(); Name = attr->getAttrName()->getName(); break; @@ -1973,6 +1973,7 @@ bool has_identifier(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Object: case ReflectionKind::Value: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: break; } @@ -3037,6 +3038,7 @@ bool is_access_specified(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Namespace: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); } llvm_unreachable("invalid reflection type"); @@ -3145,6 +3147,7 @@ bool is_accessible(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Namespace: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return DiagnoseReflectionKind(Diagnoser, Range, "a class member", DescriptionOf(RV)); } @@ -3180,7 +3183,8 @@ bool is_virtual(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Namespace: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: - return SetAndSucceed(Result, makeBool(C, IsVirtual)); + case ReflectionKind::Attribute: + return SetAndSucceed(Result, makeBool(C, false)); } llvm_unreachable("invalid reflection type"); } @@ -3205,6 +3209,7 @@ bool is_pure_virtual(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Declaration: { bool IsPureVirtual = false; @@ -3238,6 +3243,7 @@ bool is_override(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Declaration: { if (const auto *MD = dyn_cast(RV.getReflectedDecl())) @@ -3268,6 +3274,7 @@ bool is_deleted(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Declaration: { bool IsDeleted = false; @@ -3299,6 +3306,7 @@ bool is_defaulted(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Declaration: { bool IsDefaulted = false; @@ -3330,6 +3338,7 @@ bool is_explicit(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: case ReflectionKind::Template: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Declaration: { @@ -3867,7 +3876,6 @@ bool is_attribute(APValue &Result, ASTContext &C, MetaActions &Meta, SourceRange Range, ArrayRef Args) { assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == C.BoolTy); - APValue RV; if (!Evaluator(RV, Args[0], true)) return true; @@ -4286,6 +4294,7 @@ bool has_template_arguments(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); } llvm_unreachable("unknown reflection kind"); @@ -4385,6 +4394,7 @@ bool is_constructor(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Declaration: { bool result = isa(RV.getReflectedDecl()); @@ -4523,6 +4533,7 @@ bool is_destructor(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Declaration: { bool result = isa(RV.getReflectedDecl()); @@ -4552,6 +4563,7 @@ bool is_special_member_function(APValue &Result, ASTContext &C, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Declaration: { bool IsSpecial = false; @@ -5170,6 +5182,7 @@ bool offset_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return DiagnoseReflectionKind(Diagnoser, Range, "a non-static data member", DescriptionOf(RV)); case ReflectionKind::Declaration: { @@ -5226,6 +5239,7 @@ bool size_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Namespace: case ReflectionKind::BaseSpecifier: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) << 3 << DescriptionOf(RV); } @@ -5252,6 +5266,7 @@ bool bit_offset_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return DiagnoseReflectionKind(Diagnoser, Range, "a non-static data member", DescriptionOf(RV)); case ReflectionKind::Declaration: { @@ -5314,6 +5329,7 @@ bool bit_size_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Namespace: case ReflectionKind::BaseSpecifier: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) << 3 << DescriptionOf(RV); } @@ -5377,6 +5393,7 @@ bool alignment_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Namespace: case ReflectionKind::BaseSpecifier: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) << 4 << DescriptionOf(RV) << Range; } @@ -5565,6 +5582,7 @@ bool get_ith_parameter_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return true; } return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) @@ -5600,6 +5618,7 @@ bool has_consistent_identifier(APValue &Result, ASTContext &C, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return has_identifier(Result, C, Meta, Evaluator, Diagnoser, ResultTy, Range, Args); } @@ -5626,6 +5645,7 @@ bool has_ellipsis_parameter(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) << 5 << DescriptionOf(RV) << Range; case ReflectionKind::Type: @@ -5672,6 +5692,7 @@ bool has_default_argument(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return DiagnoseReflectionKind(Diagnoser, Range, "a function parameter", DescriptionOf(RV)); } @@ -5746,6 +5767,7 @@ bool return_type_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) << 6 << DescriptionOf(RV) << Range; } @@ -5818,6 +5840,7 @@ bool get_ith_annotation_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) << 7 << DescriptionOf(RV) << Range; } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index d9cbd4762331bd..1eba6ed0c8b8b0 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -29,6 +29,7 @@ #include "clang/AST/ExprObjC.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/Mangle.h" +#include "clang/Sema/ParsedAttr.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/ABI.h" #include "clang/Basic/DiagnosticAST.h" @@ -4799,6 +4800,10 @@ void CXXNameMangler::mangleReflection(const APValue &R) { Out << 'B' << (*TDMS->BitWidth); break; } + case ReflectionKind::Attribute: { + Out << "Atr" << (R.getReflectedAttribute())->getAttrName()->getName(); + break; + } case ReflectionKind::Annotation: { Out << 'a'; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 407183aace5c4c..fe46d6a86da5a4 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -5195,10 +5195,9 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, } // Parse attribute arguments - if (Tok.is(tok::l_paren)){ + if (Tok.is(tok::l_paren)) AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc, ScopeName, ScopeLoc, OpenMPTokens); - } if (!AttrParsed) { Attrs.addNew( diff --git a/clang/lib/Sema/SemaReflect.cpp b/clang/lib/Sema/SemaReflect.cpp index 2d3ca061838d3d..5e36291a423ac8 100644 --- a/clang/lib/Sema/SemaReflect.cpp +++ b/clang/lib/Sema/SemaReflect.cpp @@ -960,6 +960,10 @@ ParsedTemplateArgument Sema::ActOnTemplateSpliceSpecifierArgument( Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) << "data member specs" << 0 << 0; break; + case ReflectionKind::Attribute: + Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) + << "attribute" << 0 << 0; + break; } return ParsedTemplateArgument(); } @@ -1496,6 +1500,7 @@ ExprResult Sema::BuildReflectionSpliceExpr( case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: Diag(SpliceOp->getOperand()->getExprLoc(), diag::err_unexpected_reflection_kind_in_splice) << 1 << SpliceOp->getOperand()->getSourceRange(); @@ -1624,6 +1629,7 @@ DeclContext *Sema::TryFindDeclContextOf(const Expr *E) { case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: Diag(E->getExprLoc(), diag::err_expected_class_or_namespace) << "spliced entity" << getLangOpts().CPlusPlus; return nullptr; diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 6c38df3143e7dd..5be1edf0490651 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -8968,6 +8968,7 @@ TreeTransform::TransformCXXReflectExpr(CXXReflectExpr *E) { case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: llvm_unreachable("reflect expression should not have this reflection kind"); } llvm_unreachable("invalid reflection"); From e2f916b0f53d4185c5ac421a5d225bbcd763ccb6 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sat, 12 Oct 2024 21:15:38 +0900 Subject: [PATCH 12/26] Cleanup --- clang/lib/AST/ExprConstantMeta.cpp | 61 +++++++++++++++++++++++++++--- clang/lib/AST/ItaniumMangle.cpp | 4 -- clang/lib/Parse/ParseExpr.cpp | 1 + libcxx/include/experimental/meta | 29 ++++++++++---- 4 files changed, 79 insertions(+), 16 deletions(-) diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index af393d56cfb98f..ec29fa7c00b430 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -292,10 +292,6 @@ static bool is_namespace(APValue &Result, ASTContext &C, MetaActions &Meta, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, SourceRange Range, ArrayRef Args); -static bool is_attribute(APValue &Result, ASTContext &C, MetaActions &Meta, - EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, - SourceRange Range, ArrayRef Args); - static bool is_function(APValue &Result, ASTContext &C, MetaActions &Meta, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, SourceRange Range, ArrayRef Args); @@ -563,6 +559,26 @@ static bool annotate(APValue &Result, ASTContext &C, MetaActions &Meta, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, SourceRange Range, ArrayRef Args); +// ----------------------------------------------------------------------------- +// P3385 Metafunction declarations +// ----------------------------------------------------------------------------- + + +static bool get_begin_attributes_of(APValue &Result, ASTContext &C, + MetaActions &Meta, EvalFn Evaluator, + DiagFn Diagnoser, QualType ResultTy, + SourceRange Range, + ArrayRef Args); + +static bool get_next_attributes_of(APValue &Result, ASTContext &C, + MetaActions &Meta, EvalFn Evaluator, + DiagFn Diagnoser, QualType ResultTy, + SourceRange Range, + ArrayRef Args); + +static bool is_attribute(APValue &Result, ASTContext &C, MetaActions &Meta, + EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, + SourceRange Range, ArrayRef Args); // ----------------------------------------------------------------------------- // Metafunction table @@ -632,7 +648,6 @@ static constexpr Metafunction Metafunctions[] = { { Metafunction::MFRK_bool, 1, 1, is_base }, { Metafunction::MFRK_bool, 1, 1, is_data_member_spec }, { Metafunction::MFRK_bool, 1, 1, is_namespace }, - { Metafunction::MFRK_bool, 1, 1, is_attribute }, { Metafunction::MFRK_bool, 1, 1, is_function }, { Metafunction::MFRK_bool, 1, 1, is_variable }, { Metafunction::MFRK_bool, 1, 1, is_type }, @@ -692,6 +707,12 @@ static constexpr Metafunction Metafunctions[] = { { Metafunction::MFRK_metaInfo, 3, 3, get_ith_annotation_of }, { Metafunction::MFRK_bool, 1, 1, is_annotation }, { Metafunction::MFRK_metaInfo, 2, 2, annotate }, + + // P3385 attributes reflection + { Metafunction::MFRK_metaInfo, 2, 2, get_begin_attributes_of }, + { Metafunction::MFRK_metaInfo, 2, 2, get_next_attributes_of }, + { Metafunction::MFRK_bool, 1, 1, is_attribute }, + }; constexpr const unsigned NumMetafunctions = sizeof(Metafunctions) / sizeof(Metafunction); @@ -1422,6 +1443,22 @@ bool DiagnoseReflectionKind(DiagFn Diagnoser, SourceRange Range, // Metafunction implementations // ----------------------------------------------------------------------------- +bool get_begin_attributes_of(APValue &Result, ASTContext &C, + MetaActions &Meta, EvalFn Evaluator, + DiagFn Diagnoser, QualType ResultTy, + SourceRange Range, ArrayRef Args) { + // TODO P3385 + return false; +} + +bool get_next_attributes_of(APValue &Result, ASTContext &C, + MetaActions &Meta, EvalFn Evaluator, + DiagFn Diagnoser, QualType ResultTy, + SourceRange Range, ArrayRef Args) { + // TODO P3385 + return false; +} + bool get_begin_enumerator_decl_of(APValue &Result, ASTContext &C, MetaActions &Meta, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, @@ -1459,6 +1496,7 @@ bool get_begin_enumerator_decl_of(APValue &Result, ASTContext &C, case ReflectionKind::Namespace: case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: + case ReflectionKind::Attribute: case ReflectionKind::Annotation: { return DiagnoseReflectionKind(Diagnoser, Range, "an enum type", DescriptionOf(RV)); @@ -1499,6 +1537,7 @@ bool get_next_enumerator_decl_of(APValue &Result, ASTContext &C, case ReflectionKind::Namespace: case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: + case ReflectionKind::Attribute: case ReflectionKind::Annotation: { llvm_unreachable("should have failed in 'get_begin_enumerator_decl_of'"); } @@ -1556,6 +1595,7 @@ bool get_ith_base_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return DiagnoseReflectionKind(Diagnoser, Range, "a class type", DescriptionOf(RV)); } @@ -1610,6 +1650,7 @@ bool get_ith_template_argument_of(APValue &Result, ASTContext &C, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return DiagnoseReflectionKind(Diagnoser, Range, "a template specialization", DescriptionOf(RV)); } @@ -1699,6 +1740,7 @@ bool get_begin_member_decl_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return true; } llvm_unreachable("unknown reflection kind"); @@ -2082,6 +2124,7 @@ bool type_of(APValue &Result, ASTContext &C, MetaActions &Meta, switch (RV.getReflectionKind()) { case ReflectionKind::Null: case ReflectionKind::Type: + case ReflectionKind::Attribute: case ReflectionKind::Template: case ReflectionKind::Namespace: return Diagnoser(Range.getBegin(), diag::metafn_no_associated_property) @@ -2157,6 +2200,7 @@ bool parent_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: if (Diagnoser) return Diagnoser(Range.getBegin(), diag::metafn_no_associated_property) << DescriptionOf(RV) << 1 << Range; @@ -2210,6 +2254,7 @@ bool dealias(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, RV); case ReflectionKind::Type: { QualType QT = RV.getReflectedType(); @@ -2271,6 +2316,7 @@ bool object_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) << 1 << DescriptionOf(RV) << Range; } @@ -2360,6 +2406,7 @@ bool value_of(APValue &Result, ASTContext &C, MetaActions &Meta, /*DropCV=*/true, /*DropRefs=*/false); return SetAndSucceed(Result, A->getValue().Lift(Ty)); } + case ReflectionKind::Attribute: // TODO P3385 anything to do ? case ReflectionKind::Null: case ReflectionKind::Type: case ReflectionKind::Template: @@ -2407,6 +2454,7 @@ bool template_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return DiagnoseReflectionKind(Diagnoser, Range, "a template specialization", DescriptionOf(RV)); return true; @@ -2429,6 +2477,7 @@ static bool CanActAsTemplateArg(const APValue &RV) { case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: case ReflectionKind::Null: return false; } @@ -2896,6 +2945,7 @@ bool is_public(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: case ReflectionKind::Namespace: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); } llvm_unreachable("invalid reflection type"); @@ -5915,6 +5965,7 @@ bool annotate(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return Diagnoser(Range.getBegin(), diag::metafn_cannot_annotate) << DescriptionOf(Appertainee) << Range; } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 1eba6ed0c8b8b0..f92c4e99fc1198 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4800,10 +4800,6 @@ void CXXNameMangler::mangleReflection(const APValue &R) { Out << 'B' << (*TDMS->BitWidth); break; } - case ReflectionKind::Attribute: { - Out << "Atr" << (R.getReflectedAttribute())->getAttrName()->getName(); - break; - } case ReflectionKind::Annotation: { Out << 'a'; diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index e6b79f53b38139..a15af31714e416 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -26,6 +26,7 @@ #include "clang/AST/Availability.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/LocInfoType.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Parse/Parser.h" diff --git a/libcxx/include/experimental/meta b/libcxx/include/experimental/meta index a7b6c9d297d021..6f6d4d8c42c50e 100644 --- a/libcxx/include/experimental/meta +++ b/libcxx/include/experimental/meta @@ -153,7 +153,6 @@ consteval auto is_static_member(info) -> bool; consteval auto is_base(info) -> bool; consteval auto is_data_member_spec(info) -> bool; consteval auto is_namespace(info) -> bool; -consteval auto is_attribute(info) -> bool; consteval auto is_function(info) -> bool; consteval auto is_variable(info) -> bool; consteval auto is_type(info) -> bool; @@ -382,6 +381,10 @@ template consteval auto is_annotation(info) -> bool; consteval auto annotate(info) -> info; +// Attributes reflection (P3385) +consteval auto is_attribute(info) -> bool; +consteval auto attributes_of(info r) -> vector; + } // namespace reflection_v2 } // namespace meta } // namespace std @@ -480,7 +483,6 @@ enum : unsigned { __metafn_is_base, __metafn_is_data_member_spec, __metafn_is_namespace, - __metafn_is_attribute, __metafn_is_function, __metafn_is_variable, __metafn_is_type, @@ -540,6 +542,11 @@ enum : unsigned { __metafn_get_ith_annotation_of, __metafn_is_annotation, __metafn_annotate, + + // P3385 attributes reflection + __metafn_get_begin_attributes_of, + __metafn_get_get_next_attributes_of, + __metafn_is_attribute, }; consteval auto __workaround_expand_compiler_builtins(info type) -> info; @@ -888,11 +895,6 @@ consteval auto is_namespace(info r) -> bool { return __metafunction(detail::__metafn_is_namespace, r); } -// Returns whether the reflected entity is an attribute. -consteval auto is_attribute(info r) -> bool { - return __metafunction(detail::__metafn_is_attribute, r); -} - consteval auto bases_of(info r) -> vector { if (is_namespace(r)) throw "Namespaces cannot have base classes"; @@ -2181,6 +2183,19 @@ consteval auto annotate(info entity, info val) -> info { #endif // __has_feature(annotation_attributes) +// #ifdef TODO Feature flag for P3385 + +// Returns whether the reflected entity is an attribute. +consteval auto is_attribute(info r) -> bool { + return __metafunction(detail::__metafn_is_attribute, r); +} + +consteval auto attributes_of(info r) -> vector { + // TODO P3385 + throw("P3385 - unimplemented"); +} + +// #endif TODO Feature flag for P3385 template [[deprecated("separated into 'reflect_value', 'reflect_result', and " From a824da23ac3c1a1120d6eb7a8f69d7274eb5ebd2 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sat, 12 Oct 2024 21:19:27 +0900 Subject: [PATCH 13/26] Cleanup --- clang/lib/AST/ItaniumMangle.cpp | 1 - clang/lib/Parse/ParseExpr.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index f92c4e99fc1198..d9cbd4762331bd 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -29,7 +29,6 @@ #include "clang/AST/ExprObjC.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/Mangle.h" -#include "clang/Sema/ParsedAttr.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/ABI.h" #include "clang/Basic/DiagnosticAST.h" diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index a15af31714e416..e6b79f53b38139 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -26,7 +26,6 @@ #include "clang/AST/Availability.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/LocInfoType.h" -#include "clang/Basic/DiagnosticParse.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Parse/Parser.h" From 2fe287d4f8ee7e94fc553e7f290dd441a6ec0d02 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 13 Oct 2024 17:18:31 +0900 Subject: [PATCH 14/26] Stash early ith attributes of Stash early ith attributes of --- clang/include/clang/AST/ExprCXX.h | 4 +- clang/lib/AST/ExprConstantMeta.cpp | 127 +++++++++++++++++++++++------ libcxx/include/experimental/meta | 31 ++++++- 3 files changed, 130 insertions(+), 32 deletions(-) diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 137cb75e8b9d6d..134c7e49081b3f 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -5409,12 +5409,12 @@ class CXXReflectExpr : public Expr { /// reflections (P2996). Arguments vary by function. class CXXMetafunctionExpr : public Expr { public: - // Type of callback provided to executing metafunctinons to help evaluate an + // Type of callback provided to executing metafunctions to help evaluate an // expression in the current constant evaluation context. using EvaluateFn = std::function; - // Type of callback provided to report a diagnistc to the evaluation context. + // Type of callback provided to report a diagnostic to the evaluation context. using DiagnoseFn = std::function; diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index ec29fa7c00b430..dc48a2feacb15b 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -22,7 +22,9 @@ #include "clang/AST/Metafunction.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/Reflection.h" +#include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/DiagnosticMetafn.h" +#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" @@ -563,18 +565,11 @@ static bool annotate(APValue &Result, ASTContext &C, MetaActions &Meta, // P3385 Metafunction declarations // ----------------------------------------------------------------------------- - -static bool get_begin_attributes_of(APValue &Result, ASTContext &C, - MetaActions &Meta, EvalFn Evaluator, - DiagFn Diagnoser, QualType ResultTy, - SourceRange Range, - ArrayRef Args); - -static bool get_next_attributes_of(APValue &Result, ASTContext &C, - MetaActions &Meta, EvalFn Evaluator, - DiagFn Diagnoser, QualType ResultTy, - SourceRange Range, - ArrayRef Args); +static bool get_ith_attribute_of(APValue &Result, ASTContext &C, + MetaActions &Meta, EvalFn Evaluator, + DiagFn Diagnoser, QualType ResultTy, + SourceRange Range, + ArrayRef Args); static bool is_attribute(APValue &Result, ASTContext &C, MetaActions &Meta, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, @@ -709,8 +704,7 @@ static constexpr Metafunction Metafunctions[] = { { Metafunction::MFRK_metaInfo, 2, 2, annotate }, // P3385 attributes reflection - { Metafunction::MFRK_metaInfo, 2, 2, get_begin_attributes_of }, - { Metafunction::MFRK_metaInfo, 2, 2, get_next_attributes_of }, + { Metafunction::MFRK_metaInfo, 3, 3, get_ith_attribute_of }, { Metafunction::MFRK_bool, 1, 1, is_attribute }, }; @@ -775,6 +769,10 @@ static APValue makeReflection(CXX26AnnotationAttr *A) { return APValue(ReflectionKind::Annotation, A); } +static APValue makeReflection(ParsedAttr *Attr) { + return APValue(ReflectionKind::Attribute, Attr); +} + static Expr *makeStrLiteral(StringRef Str, ASTContext &C, bool Utf8) { QualType ConstCharTy = (Utf8 ? C.Char8Ty : C.CharTy).withConst(); @@ -1423,6 +1421,9 @@ StringRef DescriptionOf(APValue RV, bool Granular = true) { case ReflectionKind::Annotation: { return "an annotation"; } + case ReflectionKind::Attribute: { + return "an attribute"; + } } } @@ -1443,19 +1444,93 @@ bool DiagnoseReflectionKind(DiagFn Diagnoser, SourceRange Range, // Metafunction implementations // ----------------------------------------------------------------------------- -bool get_begin_attributes_of(APValue &Result, ASTContext &C, - MetaActions &Meta, EvalFn Evaluator, - DiagFn Diagnoser, QualType ResultTy, - SourceRange Range, ArrayRef Args) { - // TODO P3385 - return false; -} +// FIXME Reconciliate Attr and Attribute by just storing AttributeCommonInfo +struct AttributeScratchpad { + AttributeFactory factory; + ParsedAttributes attributes; + AttributeScratchpad() : factory(), attributes(factory) {} +}; -bool get_next_attributes_of(APValue &Result, ASTContext &C, - MetaActions &Meta, EvalFn Evaluator, - DiagFn Diagnoser, QualType ResultTy, - SourceRange Range, ArrayRef Args) { - // TODO P3385 +bool get_ith_attribute_of(APValue &Result, ASTContext &C, + MetaActions &Meta, EvalFn Evaluator, + DiagFn Diagnoser, QualType ResultTy, + SourceRange Range, ArrayRef Args) { + assert(Args[0]->getType()->isReflectionType()); + assert(ResultTy == C.MetaInfoTy); + Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of"; + + APValue RV; + if (!Evaluator(RV, Args[0], true)) + return true; + + APValue Sentinel; + if (!Evaluator(Sentinel, Args[1], true)) + return true; + assert(Sentinel.isReflectedType()); + + APValue Idx; + if (!Evaluator(Idx, Args[2], true)) + return true; + size_t idx = Idx.getInt().getExtValue(); + + switch (RV.getReflectionKind()) { + case ReflectionKind::Attribute: { + Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case attribute"; + // We don't allow ^^[[ attribute, attribute]], so when reflected type is + // attribute idx must be 0 + if (idx == 0) { + Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case attribute idx = 0"; + ParsedAttr *Attr = RV.getReflectedAttribute(); + return SetAndSucceed(Result, makeReflection(Attr)); + } + Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case attribute idx > 0"; + return SetAndSucceed(Result, Sentinel); + } + case ReflectionKind::Declaration: { + Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration"; + Decl *D = RV.getReflectedDecl(); + auto attrs = C.getDeclAttrs(D); + if (attrs.empty()) { + Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration, empty "; + return SetAndSucceed(Result, Sentinel); + } + if (idx == attrs.size()) { + Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration, finished "; + return SetAndSucceed(Result, Sentinel); + } + Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration, ith "; + + Attr* attr = attrs[idx]; + static AttributeScratchpad scratchpad; + + if (attr->getForm().getSyntax() != AttributeCommonInfo::Syntax::AS_CXX11) { + // FIXME Filter them instead of erroring + return DiagnoseReflectionKind(Diagnoser, Range, "a standard CXX11 attribute", + DescriptionOf(RV)); + } + scratchpad.attributes.addNew( + const_cast(attr->getAttrName()), // FIXME... + attr->getRange(), + nullptr, + attr->getLocation(), + nullptr, nullptr, nullptr, + attr->getForm()); + + return SetAndSucceed(Result, makeReflection(&scratchpad.attributes[0])); + } + case ReflectionKind::Type: + case ReflectionKind::Null: + case ReflectionKind::Template: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: + case ReflectionKind::Annotation: + return DiagnoseReflectionKind(Diagnoser, Range, "declaration or attribute", + DescriptionOf(RV)); + } + llvm_unreachable("unknown reflection kind"); return false; } diff --git a/libcxx/include/experimental/meta b/libcxx/include/experimental/meta index 6f6d4d8c42c50e..a4c5f78ff37991 100644 --- a/libcxx/include/experimental/meta +++ b/libcxx/include/experimental/meta @@ -544,8 +544,7 @@ enum : unsigned { __metafn_annotate, // P3385 attributes reflection - __metafn_get_begin_attributes_of, - __metafn_get_get_next_attributes_of, + __metafn_get_ith_attribute_of, __metafn_is_attribute, }; @@ -757,6 +756,25 @@ struct front_annotation_of { } }; +// TODO #ifdef P3385 feature flag + +struct front_attribute_of { + consteval info operator()(info reflectedEntity) const { + return __metafunction(detail::__metafn_get_ith_attribute_of, + reflectedEntity, LIFT(sentinel), 0); + } +}; + +struct next_attribute_of { + consteval info operator()(auto /*currItrInfo */, info reflectedEntity, + size_t idx) const { + return __metafunction(detail::__metafn_get_ith_attribute_of, + reflectedEntity, LIFT(sentinel), idx); + } +}; + +// TODO #endif P3385 feature flag + } // namespace __range_of_infos // ----------------------------------------------------------------------------- @@ -2191,8 +2209,13 @@ consteval auto is_attribute(info r) -> bool { } consteval auto attributes_of(info r) -> vector { - // TODO P3385 - throw("P3385 - unimplemented"); + using iterator = + __range_of_infos::iterator<__range_of_infos::front_attribute_of, + __range_of_infos::next_attribute_of, + __range_of_infos::map_identity_fn>; + using range = __range_of_infos::range; + auto rng = range{r}; + return vector{rng.begin(), rng.end()}; } // #endif TODO Feature flag for P3385 From 0a1288ae24167553f9e08f04cc479f3f578d6286 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 13 Oct 2024 19:45:09 +0900 Subject: [PATCH 15/26] Stash --- clang/lib/AST/ExprConstantMeta.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index dc48a2feacb15b..2032233d2edc4e 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -1457,6 +1457,7 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, SourceRange Range, ArrayRef Args) { assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == C.MetaInfoTy); + Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of"; APValue RV; @@ -1515,7 +1516,7 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, attr->getLocation(), nullptr, nullptr, nullptr, attr->getForm()); - + return SetAndSucceed(Result, makeReflection(&scratchpad.attributes[0])); } case ReflectionKind::Type: From c6b54ddc3e0ecb6e3069405c50415119dae99e19 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 13 Oct 2024 20:09:35 +0900 Subject: [PATCH 16/26] Stash attributesOf --- clang/lib/AST/ExprConstantMeta.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index 2032233d2edc4e..079e12618a15a2 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -1458,8 +1458,6 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == C.MetaInfoTy); - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of"; - APValue RV; if (!Evaluator(RV, Args[0], true)) return true; @@ -1476,36 +1474,30 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, switch (RV.getReflectionKind()) { case ReflectionKind::Attribute: { - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case attribute"; // We don't allow ^^[[ attribute, attribute]], so when reflected type is // attribute idx must be 0 if (idx == 0) { - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case attribute idx = 0"; ParsedAttr *Attr = RV.getReflectedAttribute(); return SetAndSucceed(Result, makeReflection(Attr)); } - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case attribute idx > 0"; return SetAndSucceed(Result, Sentinel); } case ReflectionKind::Declaration: { - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration"; Decl *D = RV.getReflectedDecl(); auto attrs = C.getDeclAttrs(D); if (attrs.empty()) { - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration, empty "; return SetAndSucceed(Result, Sentinel); } if (idx == attrs.size()) { - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration, finished "; return SetAndSucceed(Result, Sentinel); } - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration, ith "; Attr* attr = attrs[idx]; static AttributeScratchpad scratchpad; if (attr->getForm().getSyntax() != AttributeCommonInfo::Syntax::AS_CXX11) { - // FIXME Filter them instead of erroring + // FIXME Filter them instead of erroring... + // or we can filter with "| std::filter" on arrival return DiagnoseReflectionKind(Diagnoser, Range, "a standard CXX11 attribute", DescriptionOf(RV)); } From 75be9e4685c686c6c32ea7d310f84e62190caab1 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 13 Oct 2024 20:09:35 +0900 Subject: [PATCH 17/26] Stash attributesOf Stash attributesOf --- clang/include/clang/AST/APValue.h | 4 +- .../clang/Basic/DiagnosticMetafnKinds.td | 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/AST/APValue.cpp | 5 +- clang/lib/AST/ExprConstantMeta.cpp | 49 +++++-------------- 5 files changed, 20 insertions(+), 41 deletions(-) diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index f3ff6f3ff21709..892a7f165a5fc7 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -32,6 +32,7 @@ template class BasicReaderBase; class AddrLabelExpr; class ASTContext; + class AttributeCommonInfo; class CharUnits; class CXX26AnnotationAttr; class CXXRecordDecl; @@ -40,7 +41,6 @@ template class BasicReaderBase; class Expr; class FieldDecl; class NamespaceDecl; - class ParsedAttr; struct PrintingPolicy; class Type; class ValueDecl; @@ -683,7 +683,7 @@ class APValue { CXXBaseSpecifier *getReflectedBaseSpecifier() const; TagDataMemberSpec *getReflectedDataMemberSpec() const; CXX26AnnotationAttr *getReflectedAnnotation() const; - ParsedAttr *getReflectedAttribute() const; + AttributeCommonInfo *getReflectedAttribute() const; void setInt(APSInt I) { assert(isInt() && "Invalid accessor"); diff --git a/clang/include/clang/Basic/DiagnosticMetafnKinds.td b/clang/include/clang/Basic/DiagnosticMetafnKinds.td index 3cc79bbbfabe9c..2c13309857b3ef 100644 --- a/clang/include/clang/Basic/DiagnosticMetafnKinds.td +++ b/clang/include/clang/Basic/DiagnosticMetafnKinds.td @@ -90,6 +90,8 @@ def metafn_result_not_representable : Note< "provided %select{value|object}0 cannot be represented by a reflection">; def metafn_p3385_trace_execution_checkpoint : Note< "(p3385-metafn) trace_execution_checkpoint %0">; +def metafn_p3385_non_standard_attribute : Warning< + "(p3385-metafn) Non standard attribute discovered %0">; // Class definition. def metafn_name_invalid_identifier : Note< diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 79124386f7fd33..e6de857724d7b0 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -35,6 +35,7 @@ #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/AttrSubjectMatchRules.h" +#include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/CapturedStmt.h" #include "clang/Basic/Cuda.h" diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 6a68b888c6d509..decb53c9f03caa 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -22,6 +22,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/Type.h" +#include "clang/Basic/AttributeCommonInfo.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -943,10 +944,10 @@ CXX26AnnotationAttr *APValue::getReflectedAnnotation() const { const_cast(getOpaqueReflectionData())); } -ParsedAttr *APValue::getReflectedAttribute() const { +AttributeCommonInfo *APValue::getReflectedAttribute() const { assert(getReflectionKind() == ReflectionKind::Attribute && "not a reflection of an attribute"); - return reinterpret_cast( + return reinterpret_cast( const_cast(getOpaqueReflectionData())); } diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index 2032233d2edc4e..84252f8a41735f 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -28,7 +28,6 @@ #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Sema/ParsedAttr.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" @@ -769,7 +768,7 @@ static APValue makeReflection(CXX26AnnotationAttr *A) { return APValue(ReflectionKind::Annotation, A); } -static APValue makeReflection(ParsedAttr *Attr) { +static APValue makeReflection(AttributeCommonInfo *Attr) { return APValue(ReflectionKind::Attribute, Attr); } @@ -1444,13 +1443,6 @@ bool DiagnoseReflectionKind(DiagFn Diagnoser, SourceRange Range, // Metafunction implementations // ----------------------------------------------------------------------------- -// FIXME Reconciliate Attr and Attribute by just storing AttributeCommonInfo -struct AttributeScratchpad { - AttributeFactory factory; - ParsedAttributes attributes; - AttributeScratchpad() : factory(), attributes(factory) {} -}; - bool get_ith_attribute_of(APValue &Result, ASTContext &C, MetaActions &Meta, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, @@ -1458,8 +1450,6 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == C.MetaInfoTy); - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of"; - APValue RV; if (!Evaluator(RV, Args[0], true)) return true; @@ -1476,48 +1466,33 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, switch (RV.getReflectionKind()) { case ReflectionKind::Attribute: { - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case attribute"; // We don't allow ^^[[ attribute, attribute]], so when reflected type is // attribute idx must be 0 if (idx == 0) { - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case attribute idx = 0"; - ParsedAttr *Attr = RV.getReflectedAttribute(); - return SetAndSucceed(Result, makeReflection(Attr)); + AttributeCommonInfo *attr = RV.getReflectedAttribute(); + if (attr->getForm().getSyntax() == AttributeCommonInfo::Syntax::AS_CXX11) { + return SetAndSucceed(Result, makeReflection(attr)); + } + Diagnoser(Range.getBegin(), diag::metafn_p3385_non_standard_attribute) << attr->getAttrName(); } - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case attribute idx > 0"; return SetAndSucceed(Result, Sentinel); } case ReflectionKind::Declaration: { - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration"; Decl *D = RV.getReflectedDecl(); auto attrs = C.getDeclAttrs(D); if (attrs.empty()) { - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration, empty "; return SetAndSucceed(Result, Sentinel); } if (idx == attrs.size()) { - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration, finished "; return SetAndSucceed(Result, Sentinel); } - Diagnoser(Range.getBegin(), diag::metafn_p3385_trace_execution_checkpoint) << "get_ith_attribute_of : case declaration, ith "; Attr* attr = attrs[idx]; - static AttributeScratchpad scratchpad; - - if (attr->getForm().getSyntax() != AttributeCommonInfo::Syntax::AS_CXX11) { - // FIXME Filter them instead of erroring - return DiagnoseReflectionKind(Diagnoser, Range, "a standard CXX11 attribute", - DescriptionOf(RV)); - } - scratchpad.attributes.addNew( - const_cast(attr->getAttrName()), // FIXME... - attr->getRange(), - nullptr, - attr->getLocation(), - nullptr, nullptr, nullptr, - attr->getForm()); - - return SetAndSucceed(Result, makeReflection(&scratchpad.attributes[0])); + if (attr->getForm().getSyntax() == AttributeCommonInfo::Syntax::AS_CXX11) { + return SetAndSucceed(Result, makeReflection(attr)); + } + Diagnoser(Range.getBegin(), diag::metafn_p3385_non_standard_attribute) << attr->getAttrName(); + return SetAndSucceed(Result, Sentinel); } case ReflectionKind::Type: case ReflectionKind::Null: @@ -1996,7 +1971,7 @@ bool identifier_of(APValue &Result, ASTContext &C, MetaActions &Meta, break; } case ReflectionKind::Attribute: { - ParsedAttr* attr = RV.getReflectedAttribute(); + AttributeCommonInfo* attr = RV.getReflectedAttribute(); Name = attr->getAttrName()->getName(); break; } From 424e82823921a985f070930998e2ee796f39dcce Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 20 Oct 2024 10:00:49 +0900 Subject: [PATCH 18/26] Stash to check regression --- clang/lib/AST/ExprConstantMeta.cpp | 72 ++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index 84252f8a41735f..d35daa8b6f7e99 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -22,6 +22,7 @@ #include "clang/AST/Metafunction.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/Reflection.h" +#include "clang/AST/Type.h" #include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/DiagnosticMetafn.h" #include "clang/Basic/IdentifierTable.h" @@ -32,7 +33,6 @@ #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" - namespace clang { using EvalFn = Metafunction::EvaluateFn; @@ -768,7 +768,7 @@ static APValue makeReflection(CXX26AnnotationAttr *A) { return APValue(ReflectionKind::Annotation, A); } -static APValue makeReflection(AttributeCommonInfo *Attr) { +static APValue makeReflection(const AttributeCommonInfo * Attr) { return APValue(ReflectionKind::Attribute, Attr); } @@ -1473,28 +1473,64 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, if (attr->getForm().getSyntax() == AttributeCommonInfo::Syntax::AS_CXX11) { return SetAndSucceed(Result, makeReflection(attr)); } - Diagnoser(Range.getBegin(), diag::metafn_p3385_non_standard_attribute) << attr->getAttrName(); + return Diagnoser(Range.getBegin(), diag::metafn_p3385_non_standard_attribute) << attr->getAttrName(); } + // TODO diagnostic ? return SetAndSucceed(Result, Sentinel); } - case ReflectionKind::Declaration: { - Decl *D = RV.getReflectedDecl(); - auto attrs = C.getDeclAttrs(D); - if (attrs.empty()) { - return SetAndSucceed(Result, Sentinel); + // Weirdly enough I thought it would be needed... then again what do I know... + // + // case ReflectionKind::Declaration: { + // Decl *D = RV.getReflectedDecl(); + // + // auto attrs = C.getDeclAttrs(D); + // if (attrs.empty()) { + // return SetAndSucceed(Result, Sentinel); + // } + // if (idx == attrs.size()) { + // return SetAndSucceed(Result, Sentinel); + // } + // + // Attr* attr = attrs[idx]; + // if (attr->getForm().getSyntax() == AttributeCommonInfo::Syntax::AS_CXX11) { + // return SetAndSucceed(Result, makeReflection(attr)); + // } + // Diagnoser(Range.getBegin(), diag::metafn_p3385_non_standard_attribute) << attr->getAttrName(); + // return SetAndSucceed(Result, Sentinel); + // } + case ReflectionKind::Type: { + QualType qType = RV.getReflectedType(); + Decl *D = findTypeDecl(qType); + if (!D) { + return DiagnoseReflectionKind(Diagnoser, Range, "attribute or type", + DescriptionOf(RV)); } - if (idx == attrs.size()) { - return SetAndSucceed(Result, Sentinel); + TypeSourceInfo* typeInfo = C.getTrivialTypeSourceInfo(qType, Range.getBegin()); + + VarDecl *var = VarDecl::Create( + C, + D->getDeclContext(), + Range.getBegin(), + Range.getBegin(), + nullptr, + qType, + typeInfo, + SC_None); + auto attrs = var->attrs(); + // FIXME cache this... + if (auto* attr = attrs.begin(); attr != attrs.end()) { + while(idx != 0) { + ++attr; + --idx; + if (attr == attrs.end()) { + return SetAndSucceed(Result, Sentinel); + } + } + return SetAndSucceed(Result, makeReflection(*attr)); } - - Attr* attr = attrs[idx]; - if (attr->getForm().getSyntax() == AttributeCommonInfo::Syntax::AS_CXX11) { - return SetAndSucceed(Result, makeReflection(attr)); - } - Diagnoser(Range.getBegin(), diag::metafn_p3385_non_standard_attribute) << attr->getAttrName(); - return SetAndSucceed(Result, Sentinel); + return SetAndSucceed(Result, Sentinel); } - case ReflectionKind::Type: + case ReflectionKind::Declaration: case ReflectionKind::Null: case ReflectionKind::Template: case ReflectionKind::Object: From ef2ff0fba393b4518c9b7e313e1a6e04aac9497e Mon Sep 17 00:00:00 2001 From: zebullon Date: Mon, 21 Oct 2024 21:45:19 +0900 Subject: [PATCH 19/26] Stash to check regression --- .../clang/Basic/DiagnosticMetafnKinds.td | 3 +- clang/lib/AST/ExprConstantMeta.cpp | 72 +++++++++++++------ 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticMetafnKinds.td b/clang/include/clang/Basic/DiagnosticMetafnKinds.td index 2c13309857b3ef..39150bd411d5ef 100644 --- a/clang/include/clang/Basic/DiagnosticMetafnKinds.td +++ b/clang/include/clang/Basic/DiagnosticMetafnKinds.td @@ -88,7 +88,8 @@ def metafn_value_not_structural_type : Note< "values of non-structural type %0 cannot be represented as reflections">; def metafn_result_not_representable : Note< "provided %select{value|object}0 cannot be represented by a reflection">; -def metafn_p3385_trace_execution_checkpoint : Note< + +def metafn_p3385_trace_execution_checkpoint : Warning< "(p3385-metafn) trace_execution_checkpoint %0">; def metafn_p3385_non_standard_attribute : Warning< "(p3385-metafn) Non standard attribute discovered %0">; diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index d35daa8b6f7e99..9b45e93c3f2081 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -962,6 +962,15 @@ static bool findAnnotLoc(APValue &Result, ASTContext &C, EvalFn Evaluator, return !Evaluator(Result, SLE, true); } +static bool findAttrLoc(APValue &Result, ASTContext &C, EvalFn Evaluator, + QualType ResultTy, AttributeCommonInfo *A) { + SourceLocExpr *SLE = + new (C) SourceLocExpr(C, SourceLocIdentKind::SourceLocStruct, + ResultTy, A->getLoc(), SourceLocation(), + nullptr); + return !Evaluator(Result, SLE, true); +} + static QualType desugarType(QualType QT, bool UnwrapAliases, bool DropCV, bool DropRefs) { bool IsConst = QT.isConstQualified(); @@ -1466,17 +1475,15 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, switch (RV.getReflectionKind()) { case ReflectionKind::Attribute: { - // We don't allow ^^[[ attribute, attribute]], so when reflected type is - // attribute idx must be 0 - if (idx == 0) { - AttributeCommonInfo *attr = RV.getReflectedAttribute(); - if (attr->getForm().getSyntax() == AttributeCommonInfo::Syntax::AS_CXX11) { - return SetAndSucceed(Result, makeReflection(attr)); - } - return Diagnoser(Range.getBegin(), diag::metafn_p3385_non_standard_attribute) << attr->getAttrName(); - } - // TODO diagnostic ? + if (idx != 0) { return SetAndSucceed(Result, Sentinel); + } + AttributeCommonInfo *attr = RV.getReflectedAttribute(); + if (attr->getForm().getSyntax() == AttributeCommonInfo::Syntax::AS_CXX11) { + return SetAndSucceed(Result, makeReflection(attr)); + } + // Non standard + return Diagnoser(Range.getBegin(), diag::metafn_p3385_non_standard_attribute) << attr->getAttrName(); } // Weirdly enough I thought it would be needed... then again what do I know... // @@ -1502,21 +1509,27 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, QualType qType = RV.getReflectedType(); Decl *D = findTypeDecl(qType); if (!D) { + // FIXME how would we end up here ? return DiagnoseReflectionKind(Diagnoser, Range, "attribute or type", DescriptionOf(RV)); } - TypeSourceInfo* typeInfo = C.getTrivialTypeSourceInfo(qType, Range.getBegin()); - - VarDecl *var = VarDecl::Create( - C, - D->getDeclContext(), - Range.getBegin(), - Range.getBegin(), - nullptr, - qType, - typeInfo, - SC_None); - auto attrs = var->attrs(); + // TypeSourceInfo* typeInfo = C.getTrivialTypeSourceInfo(qType, Range.getBegin()); + + // VarDecl *var = VarDecl::Create( + // C, + // D->getDeclContext(), + // Range.getBegin(), + // Range.getBegin(), + // nullptr, + // qType, + // typeInfo, + // SC_None); + // auto attrs = var->attrs(); + auto attrs = D->attrs(); + + if (attrs.empty()) { + return SetAndSucceed(Result, Sentinel); + } // FIXME cache this... if (auto* attr = attrs.begin(); attr != attrs.end()) { while(idx != 0) { @@ -2190,6 +2203,9 @@ bool source_location_of(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Annotation: return findAnnotLoc(Result, C, Evaluator, ResultTy, RV.getReflectedAnnotation()); + case ReflectionKind::Attribute: + return findAttrLoc(Result, C, Evaluator, ResultTy, + RV.getReflectedAttribute()); case ReflectionKind::Object: case ReflectionKind::Value: case ReflectionKind::Null: @@ -2985,6 +3001,7 @@ bool extract(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Type: case ReflectionKind::Template: case ReflectionKind::Namespace: + case ReflectionKind::Attribute: case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: return Diagnoser(Range.getBegin(), diag::metafn_cannot_extract) @@ -3076,6 +3093,7 @@ bool is_protected(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Value: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: case ReflectionKind::Namespace: return SetAndSucceed(Result, makeBool(C, false)); } @@ -3121,6 +3139,7 @@ bool is_private(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::Namespace: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); } llvm_unreachable("invalid reflection type"); @@ -3511,6 +3530,7 @@ bool is_noexcept(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Type: { const QualType QT = RV.getReflectedType(); @@ -3582,6 +3602,7 @@ bool is_const(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Type: { bool result = isConstQualifiedType(RV.getReflectedType()); @@ -3622,6 +3643,7 @@ bool is_volatile(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); case ReflectionKind::Type: { bool result = isVolatileQualifiedType(RV.getReflectedType()); @@ -3964,7 +3986,8 @@ bool is_static_member(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: - return SetAndSucceed(Result, makeBool(C, result)); + case ReflectionKind::Attribute: + return SetAndSucceed(Result, makeBool(C, false)); } llvm_unreachable("unknown reflection kind"); } @@ -4096,6 +4119,7 @@ bool is_alias(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return SetAndSucceed(Result, makeBool(C, false)); } llvm_unreachable("unknown reflection kind"); @@ -4157,6 +4181,7 @@ bool has_complete_definition(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: break; } @@ -4956,6 +4981,7 @@ bool reflect_invoke(APValue &Result, ASTContext &C, MetaActions &Meta, case ReflectionKind::BaseSpecifier: case ReflectionKind::DataMemberSpec: case ReflectionKind::Annotation: + case ReflectionKind::Attribute: return Diagnoser(Range.getBegin(), diag::metafn_cannot_invoke) << DescriptionOf(FnRefl) << Range; case ReflectionKind::Object: { From 13be7da6be87be1f190f5492872e5c1d4675ac8b Mon Sep 17 00:00:00 2001 From: zebullon Date: Mon, 21 Oct 2024 22:11:02 +0900 Subject: [PATCH 20/26] Pass easy test on attribute_of type --- clang/lib/AST/ExprConstantMeta.cpp | 33 +----------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index 9b45e93c3f2081..77a2998e8decab 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -1485,26 +1485,6 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, // Non standard return Diagnoser(Range.getBegin(), diag::metafn_p3385_non_standard_attribute) << attr->getAttrName(); } - // Weirdly enough I thought it would be needed... then again what do I know... - // - // case ReflectionKind::Declaration: { - // Decl *D = RV.getReflectedDecl(); - // - // auto attrs = C.getDeclAttrs(D); - // if (attrs.empty()) { - // return SetAndSucceed(Result, Sentinel); - // } - // if (idx == attrs.size()) { - // return SetAndSucceed(Result, Sentinel); - // } - // - // Attr* attr = attrs[idx]; - // if (attr->getForm().getSyntax() == AttributeCommonInfo::Syntax::AS_CXX11) { - // return SetAndSucceed(Result, makeReflection(attr)); - // } - // Diagnoser(Range.getBegin(), diag::metafn_p3385_non_standard_attribute) << attr->getAttrName(); - // return SetAndSucceed(Result, Sentinel); - // } case ReflectionKind::Type: { QualType qType = RV.getReflectedType(); Decl *D = findTypeDecl(qType); @@ -1513,23 +1493,12 @@ bool get_ith_attribute_of(APValue &Result, ASTContext &C, return DiagnoseReflectionKind(Diagnoser, Range, "attribute or type", DescriptionOf(RV)); } - // TypeSourceInfo* typeInfo = C.getTrivialTypeSourceInfo(qType, Range.getBegin()); - - // VarDecl *var = VarDecl::Create( - // C, - // D->getDeclContext(), - // Range.getBegin(), - // Range.getBegin(), - // nullptr, - // qType, - // typeInfo, - // SC_None); - // auto attrs = var->attrs(); auto attrs = D->attrs(); if (attrs.empty()) { return SetAndSucceed(Result, Sentinel); } + // FIXME cache this... if (auto* attr = attrs.begin(); attr != attrs.end()) { while(idx != 0) { From a3cbe57cd3fff5b3fed2546c77d8aca3cf9d71bb Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 27 Oct 2024 12:05:18 +0900 Subject: [PATCH 21/26] Stash interim splice --- .../clang/Basic/DiagnosticParseKinds.td | 3 +- clang/include/clang/Parse/Parser.h | 7 ++ clang/include/clang/Sema/Sema.h | 6 ++ clang/lib/Parse/ParseDeclCXX.cpp | 92 +++++++++++++++++++ clang/lib/Parse/ParseReflect.cpp | 8 ++ clang/lib/Sema/SemaReflect.cpp | 16 ++++ 6 files changed, 131 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 35c710c215ecd1..28ba5a17b349e6 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1756,7 +1756,8 @@ def p3385_trace_execution_checkpoint : Warning< "(p3385) trace_execution_checkpoint %0">; def p3385_err_attributes_list : Error< "(p3385) reflection of attribute list is not supported, found %0 attributes">; - +def p3385_err_attribute_splicing_error : Error< + "(p3385) splicing of attributes error: %0">; } let CategoryName = "Generics Issue" in { diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index f26e95fcd56b01..781ac2a3c98705 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -19,6 +19,7 @@ #include "clang/Basic/OperatorPrecedence.h" #include "clang/Lex/CodeCompletionHandler.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Sema/Ownership.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaCodeCompletion.h" #include "clang/Sema/SemaObjC.h" @@ -3047,6 +3048,11 @@ class Parser : public CodeCompletionHandler { ParseCXX11AttributeSpecifierInternal(Attrs, OpenMPTokens, EndLoc); ReplayOpenMPAttributeTokens(OpenMPTokens); } + + bool tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, + SourceLocation *EndLoc = nullptr); + /// Try parsing a splice expression when inside an attribute specifier + void ParseCXX11Attributes(ParsedAttributes &attrs); /// Parses a C++11 (or C23)-style attribute argument list. Returns true /// if this results in adding an attribute to the ParsedAttributes list. @@ -3966,6 +3972,7 @@ class Parser : public CodeCompletionHandler { bool ParseCXXSpliceSpecifier(SourceLocation TemplateKWLoc = {}); TypeResult ParseCXXSpliceAsType(bool AllowDependent, bool Complain); + DeclResult ParseCXXSpliceAsAttributes(); ExprResult ParseCXXSpliceAsExpr(bool AllowMemberReference); DeclResult ParseCXXSpliceAsNamespace(); TemplateTy ParseCXXSpliceAsTemplate(); // TODO(P2996): Do we use this? diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e6de857724d7b0..4aa60c47cf5f22 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -15199,6 +15199,9 @@ class Sema final : public SemaBase { DeclResult ActOnCXXSpliceExpectingNamespace(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice); + DeclResult ActOnCXXSpliceExpectingAttributes(SourceLocation LSplice, + Expr *Operand, + SourceLocation RSplice); TemplateTy ActOnCXXSpliceExpectingTemplate(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice, @@ -15262,6 +15265,9 @@ class Sema final : public SemaBase { DeclResult BuildReflectionSpliceNamespace(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice); + DeclResult BuildReflectionSpliceAttributes(SourceLocation LSplice, + Expr *Operand, + SourceLocation RSplice); TemplateTy BuildReflectionSpliceTemplate(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice, diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index fe46d6a86da5a4..89a619dc8f9cb2 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -13,11 +13,13 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" +#include "clang/AST/Attrs.inc" #include "clang/AST/DeclTemplate.h" #include "clang/AST/PrettyDeclStackTrace.h" #include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/Attributes.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TokenKinds.h" @@ -5041,11 +5043,56 @@ bool Parser::ParseCXX11AttributeArgs( return true; } +bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, + SourceLocation *EndLoc) +{ + // Try parsing a [: meta-info :] immediately following '[' '[' + if (!Tok.is(tok::l_splice)) { + return true; + } + if (ParseCXXSpliceSpecifier()) { + // FIXME diagnostic is terrible... + Diag(Tok.getLocation(), diag::p3385_err_attribute_splicing_error) + << "invalid expression in attribute splicing"; + return true; // yea...Dont know what kind of convention that is + } + if (Tok.is(tok::annot_splice)) { + ExprResult Result = getExprAnnotation(Tok); + ConsumeAnnotationToken(); + + + CXXSpliceSpecifierExpr *SpliceExpr = + dyn_cast(Result.get()); + Diag(SpliceExpr->getExprLoc(), diag::p3385_trace_execution_checkpoint) + << "parsed splice expression in attribute"; + + // Finish with consuming close ']' ']' + SourceLocation CloseLoc = Tok.getLocation(); + if (ExpectAndConsume(tok::r_square)) + SkipUntil(tok::r_square); + else if (Tok.is(tok::r_square)) + checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd); + if (EndLoc) + *EndLoc = Tok.getLocation(); + if (ExpectAndConsume(tok::r_square)) + SkipUntil(tok::r_square); + + return false; + // if (Actions.ActOnCXXNestedNameSpecifierReflectionSplice(SS, SpliceExpr, + // CCLoc)) { + // SS.SetInvalid(SourceRange(SpliceExpr->getExprLoc(), CCLoc)); + // return true; + // } + } + return true; +} + /// Parse a C++11 or C23 attribute-specifier. /// /// [C++11] attribute-specifier: /// '[' '[' attribute-list ']' ']' /// alignment-specifier +/// '[' '[' splice-name-qualifier ']' ']' /// /// [C++11] attribute-list: /// attribute[opt] @@ -5079,6 +5126,8 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, return; } + Diag(Tok.getLocation(), diag::p3385_trace_execution_checkpoint) << "1"; + if (Tok.isRegularKeywordAttribute()) { SourceLocation Loc = Tok.getLocation(); IdentifierInfo *AttrName = Tok.getIdentifierInfo(); @@ -5151,6 +5200,49 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, SourceLocation ScopeLoc, AttrLoc; IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr; + if (!tryParseSpliceAttrSpecifier(Attrs, EndLoc)) { + return; + } + // // TODO externalize this into a dedicated function + // // Try parsing a [: meta-info :] immediately following '[' '[' + // if (Tok.is(tok::l_splice)) { + // if (ParseCXXSpliceSpecifier()) { + // // FIXME diagnostic is terrible... + // Diag(Tok.getLocation(), diag::p3385_err_attribute_splicing_error) + // << "invalid expression in attribute splicing"; + // return; + // } + // if (Tok.is(tok::annot_splice)) { + // ExprResult Result = getExprAnnotation(Tok); + // ConsumeAnnotationToken(); + + + // CXXSpliceSpecifierExpr *SpliceExpr = + // dyn_cast(Result.get()); + // Diag(SpliceExpr->getExprLoc(), diag::p3385_trace_execution_checkpoint) + // << "parsed splice expression in attribute"; + + // // Finish with consuming close ']' ']' + // SourceLocation CloseLoc = Tok.getLocation(); + // if (ExpectAndConsume(tok::r_square)) + // SkipUntil(tok::r_square); + // else if (Tok.is(tok::r_square)) + // checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd); + // if (EndLoc) + // *EndLoc = Tok.getLocation(); + // if (ExpectAndConsume(tok::r_square)) + // SkipUntil(tok::r_square); + + // return; + // // if (Actions.ActOnCXXNestedNameSpecifierReflectionSplice(SS, SpliceExpr, + // // CCLoc)) { + // // SS.SetInvalid(SourceRange(SpliceExpr->getExprLoc(), CCLoc)); + // // return true; + // // } + // } + // return; + // } + if (Tok.is(tok::equal) && getLangOpts().AnnotationAttributes) { // This is a C++2c annotation. if (CommonScopeName) { diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index fbd8c0c9af471e..ae1509d81d08e3 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -17,6 +17,7 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" +#include "clang/Sema/Ownership.h" using namespace clang; ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { @@ -263,6 +264,13 @@ DeclResult Parser::ParseCXXSpliceAsNamespace() { return Result; } + +DeclResult Parser::ParseCXXSpliceAsAttributes() +{ + assert(Tok.is(tok::l_splice()) && "expected splice"); + return DeclResult{}; +} + Parser::TemplateTy Parser::ParseCXXSpliceAsTemplate() { assert(Tok.is(tok::annot_splice) && "expected annot_splice"); diff --git a/clang/lib/Sema/SemaReflect.cpp b/clang/lib/Sema/SemaReflect.cpp index 5e36291a423ac8..311646046e57db 100644 --- a/clang/lib/Sema/SemaReflect.cpp +++ b/clang/lib/Sema/SemaReflect.cpp @@ -21,6 +21,7 @@ #include "clang/Basic/DiagnosticSema.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" #include "clang/Sema/Lookup.h" +#include "clang/Sema/Ownership.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Sema.h" #include "clang/Sema/Template.h" @@ -882,6 +883,13 @@ DeclResult Sema::ActOnCXXSpliceExpectingNamespace(SourceLocation LSpliceLoc, return BuildReflectionSpliceNamespace(LSpliceLoc, Operand, RSpliceLoc); } +DeclResult Sema::ActOnCXXSpliceExpectingAttributes(SourceLocation LSpliceLoc, + Expr *Operand, + SourceLocation RSpliceLoc) { + // TODO P3385 : build here + return DeclResult{}; +} + Sema::TemplateTy Sema::ActOnCXXSpliceExpectingTemplate( SourceLocation LSpliceLoc, Expr *Operand, SourceLocation RSpliceLoc, bool Complain) { @@ -1513,6 +1521,14 @@ ExprResult Sema::BuildReflectionSpliceExpr( TArgs, AllowMemberReference); } +DeclResult Sema::BuildReflectionSpliceAttributes(SourceLocation LSplice, + Expr *Operand, + SourceLocation RSplice) +{ + // TODO P3385 + return DeclResult{}; +} + DeclResult Sema::BuildReflectionSpliceNamespace(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice) { From 9c0c9046e303533d13581fd7faba00eabff32e4d Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 27 Oct 2024 12:17:55 +0900 Subject: [PATCH 22/26] Stash interim splice --- clang/include/clang/Parse/Parser.h | 2 -- clang/include/clang/Sema/Sema.h | 6 ---- clang/lib/Parse/ParseDeclCXX.cpp | 52 ++++-------------------------- clang/lib/Parse/ParseReflect.cpp | 7 ---- clang/lib/Sema/SemaReflect.cpp | 15 --------- 5 files changed, 6 insertions(+), 76 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 781ac2a3c98705..6f72000f195dab 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -19,7 +19,6 @@ #include "clang/Basic/OperatorPrecedence.h" #include "clang/Lex/CodeCompletionHandler.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Sema/Ownership.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaCodeCompletion.h" #include "clang/Sema/SemaObjC.h" @@ -3972,7 +3971,6 @@ class Parser : public CodeCompletionHandler { bool ParseCXXSpliceSpecifier(SourceLocation TemplateKWLoc = {}); TypeResult ParseCXXSpliceAsType(bool AllowDependent, bool Complain); - DeclResult ParseCXXSpliceAsAttributes(); ExprResult ParseCXXSpliceAsExpr(bool AllowMemberReference); DeclResult ParseCXXSpliceAsNamespace(); TemplateTy ParseCXXSpliceAsTemplate(); // TODO(P2996): Do we use this? diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4aa60c47cf5f22..e6de857724d7b0 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -15199,9 +15199,6 @@ class Sema final : public SemaBase { DeclResult ActOnCXXSpliceExpectingNamespace(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice); - DeclResult ActOnCXXSpliceExpectingAttributes(SourceLocation LSplice, - Expr *Operand, - SourceLocation RSplice); TemplateTy ActOnCXXSpliceExpectingTemplate(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice, @@ -15265,9 +15262,6 @@ class Sema final : public SemaBase { DeclResult BuildReflectionSpliceNamespace(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice); - DeclResult BuildReflectionSpliceAttributes(SourceLocation LSplice, - Expr *Operand, - SourceLocation RSplice); TemplateTy BuildReflectionSpliceTemplate(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice, diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 89a619dc8f9cb2..6c4f9d5ccedb5c 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -13,13 +13,11 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" -#include "clang/AST/Attrs.inc" #include "clang/AST/DeclTemplate.h" #include "clang/AST/PrettyDeclStackTrace.h" #include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/Attributes.h" #include "clang/Basic/CharInfo.h" -#include "clang/Basic/DiagnosticParse.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TokenKinds.h" @@ -5064,8 +5062,8 @@ bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, CXXSpliceSpecifierExpr *SpliceExpr = dyn_cast(Result.get()); Diag(SpliceExpr->getExprLoc(), diag::p3385_trace_execution_checkpoint) - << "parsed splice expression in attribute"; - + << "successfully parsed splice expression in attribute"; + // Finish with consuming close ']' ']' SourceLocation CloseLoc = Tok.getLocation(); if (ExpectAndConsume(tok::r_square)) @@ -5085,7 +5083,7 @@ bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, // } } return true; -} +} /// Parse a C++11 or C23 attribute-specifier. /// @@ -5126,8 +5124,6 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, return; } - Diag(Tok.getLocation(), diag::p3385_trace_execution_checkpoint) << "1"; - if (Tok.isRegularKeywordAttribute()) { SourceLocation Loc = Tok.getLocation(); IdentifierInfo *AttrName = Tok.getIdentifierInfo(); @@ -5200,48 +5196,12 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, SourceLocation ScopeLoc, AttrLoc; IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr; + // Try parsing a `[: :]` expression if (!tryParseSpliceAttrSpecifier(Attrs, EndLoc)) { + // I'll forget in 10 minutes but... in clang convention, we end up here + // when we actually did succeed... so we quit parsing attributes here. return; } - // // TODO externalize this into a dedicated function - // // Try parsing a [: meta-info :] immediately following '[' '[' - // if (Tok.is(tok::l_splice)) { - // if (ParseCXXSpliceSpecifier()) { - // // FIXME diagnostic is terrible... - // Diag(Tok.getLocation(), diag::p3385_err_attribute_splicing_error) - // << "invalid expression in attribute splicing"; - // return; - // } - // if (Tok.is(tok::annot_splice)) { - // ExprResult Result = getExprAnnotation(Tok); - // ConsumeAnnotationToken(); - - - // CXXSpliceSpecifierExpr *SpliceExpr = - // dyn_cast(Result.get()); - // Diag(SpliceExpr->getExprLoc(), diag::p3385_trace_execution_checkpoint) - // << "parsed splice expression in attribute"; - - // // Finish with consuming close ']' ']' - // SourceLocation CloseLoc = Tok.getLocation(); - // if (ExpectAndConsume(tok::r_square)) - // SkipUntil(tok::r_square); - // else if (Tok.is(tok::r_square)) - // checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd); - // if (EndLoc) - // *EndLoc = Tok.getLocation(); - // if (ExpectAndConsume(tok::r_square)) - // SkipUntil(tok::r_square); - - // return; - // // if (Actions.ActOnCXXNestedNameSpecifierReflectionSplice(SS, SpliceExpr, - // // CCLoc)) { - // // SS.SetInvalid(SourceRange(SpliceExpr->getExprLoc(), CCLoc)); - // // return true; - // // } - // } - // return; - // } if (Tok.is(tok::equal) && getLangOpts().AnnotationAttributes) { // This is a C++2c annotation. diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index ae1509d81d08e3..4de77b1682b9bc 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -264,13 +264,6 @@ DeclResult Parser::ParseCXXSpliceAsNamespace() { return Result; } - -DeclResult Parser::ParseCXXSpliceAsAttributes() -{ - assert(Tok.is(tok::l_splice()) && "expected splice"); - return DeclResult{}; -} - Parser::TemplateTy Parser::ParseCXXSpliceAsTemplate() { assert(Tok.is(tok::annot_splice) && "expected annot_splice"); diff --git a/clang/lib/Sema/SemaReflect.cpp b/clang/lib/Sema/SemaReflect.cpp index 311646046e57db..2cd76dc0a8d57f 100644 --- a/clang/lib/Sema/SemaReflect.cpp +++ b/clang/lib/Sema/SemaReflect.cpp @@ -883,13 +883,6 @@ DeclResult Sema::ActOnCXXSpliceExpectingNamespace(SourceLocation LSpliceLoc, return BuildReflectionSpliceNamespace(LSpliceLoc, Operand, RSpliceLoc); } -DeclResult Sema::ActOnCXXSpliceExpectingAttributes(SourceLocation LSpliceLoc, - Expr *Operand, - SourceLocation RSpliceLoc) { - // TODO P3385 : build here - return DeclResult{}; -} - Sema::TemplateTy Sema::ActOnCXXSpliceExpectingTemplate( SourceLocation LSpliceLoc, Expr *Operand, SourceLocation RSpliceLoc, bool Complain) { @@ -1521,14 +1514,6 @@ ExprResult Sema::BuildReflectionSpliceExpr( TArgs, AllowMemberReference); } -DeclResult Sema::BuildReflectionSpliceAttributes(SourceLocation LSplice, - Expr *Operand, - SourceLocation RSplice) -{ - // TODO P3385 - return DeclResult{}; -} - DeclResult Sema::BuildReflectionSpliceNamespace(SourceLocation LSplice, Expr *Operand, SourceLocation RSplice) { From 83ff0f3d24c9176d3b583371a9bb74cd2995f69a Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 27 Oct 2024 15:36:40 +0900 Subject: [PATCH 23/26] Stash interim splice --- clang/lib/Parse/ParseDeclCXX.cpp | 63 +++++++++++++++++++------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 6c4f9d5ccedb5c..cb43d2781f0127 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -14,10 +14,12 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/PrettyDeclStackTrace.h" #include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/Attributes.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TokenKinds.h" @@ -5054,35 +5056,44 @@ bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, << "invalid expression in attribute splicing"; return true; // yea...Dont know what kind of convention that is } - if (Tok.is(tok::annot_splice)) { - ExprResult Result = getExprAnnotation(Tok); - ConsumeAnnotationToken(); - - - CXXSpliceSpecifierExpr *SpliceExpr = - dyn_cast(Result.get()); - Diag(SpliceExpr->getExprLoc(), diag::p3385_trace_execution_checkpoint) - << "successfully parsed splice expression in attribute"; - - // Finish with consuming close ']' ']' - SourceLocation CloseLoc = Tok.getLocation(); - if (ExpectAndConsume(tok::r_square)) - SkipUntil(tok::r_square); - else if (Tok.is(tok::r_square)) - checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd); - if (EndLoc) - *EndLoc = Tok.getLocation(); - if (ExpectAndConsume(tok::r_square)) - SkipUntil(tok::r_square); + if (!Tok.is(tok::annot_splice)) { + return true; + } + ExprResult Result = getExprAnnotation(Tok); + ConsumeAnnotationToken(); + // TODO should be an ActOnBlablabla() + // + auto *SpliceExpr = cast(Result.get()); + Expr::EvalResult ER; + if (!SpliceExpr->EvaluateAsRValue(ER, Actions.getASTContext(), true)) { return false; - // if (Actions.ActOnCXXNestedNameSpecifierReflectionSplice(SS, SpliceExpr, - // CCLoc)) { - // SS.SetInvalid(SourceRange(SpliceExpr->getExprLoc(), CCLoc)); - // return true; - // } } - return true; + assert(ER.Val.getKind() == APValue::Reflection); + switch (ER.Val.getReflectionKind()) { + case ReflectionKind::Attribute: { + auto * attr = ER.Val.getReflectedAttribute(); + Diag(Tok.getLocation(), diag::p3385_trace_execution_checkpoint) + << attr->getAttrName(); + break; + } + default: + Diag(Tok.getLocation(), diag::p3385_err_attribute_splicing_error) + << "unsupported kind in attribute splicing"; + } + + // Finish with consuming close ']' ']' + SourceLocation CloseLoc = Tok.getLocation(); + if (ExpectAndConsume(tok::r_square)) + SkipUntil(tok::r_square); + else if (Tok.is(tok::r_square)) + checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd); + if (EndLoc) + *EndLoc = Tok.getLocation(); + if (ExpectAndConsume(tok::r_square)) + SkipUntil(tok::r_square); + + return false; } /// Parse a C++11 or C23 attribute-specifier. From 59135b3f2a1b4ad6eff42549c5d3db1c5eb0d970 Mon Sep 17 00:00:00 2001 From: zebullon Date: Sun, 27 Oct 2024 16:03:33 +0900 Subject: [PATCH 24/26] Support some splice, note that attributes_of(^^[[ is buggy from this commit on Stash interim splice Stash interim splice --- clang/lib/Parse/ParseDeclCXX.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index cb43d2781f0127..acdeaf20b8523d 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -5059,10 +5059,14 @@ bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, if (!Tok.is(tok::annot_splice)) { return true; } + Diag(Tok.getLocation(), diag::p3385_trace_execution_checkpoint) + << "Found splice in attribute expression"; + SourceLocation loc = (Tok.getLocation()); + SourceRange range(loc); ExprResult Result = getExprAnnotation(Tok); ConsumeAnnotationToken(); - // TODO should be an ActOnBlablabla() + // TODO export to ActOnBlablabla() is the `iDiOmAtIc WaY` // auto *SpliceExpr = cast(Result.get()); Expr::EvalResult ER; @@ -5073,8 +5077,12 @@ bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, switch (ER.Val.getReflectionKind()) { case ReflectionKind::Attribute: { auto * attr = ER.Val.getReflectedAttribute(); - Diag(Tok.getLocation(), diag::p3385_trace_execution_checkpoint) - << attr->getAttrName(); + + Attrs.addNew( + const_cast(attr->getAttrName()), // (C) Trust me bro + range, + nullptr, loc, nullptr, 0, + ParsedAttr::Form::CXX11()); break; } default: @@ -5082,7 +5090,8 @@ bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, << "unsupported kind in attribute splicing"; } - // Finish with consuming close ']' ']' + // FIXME this shouldnt be here... but we early quit ParseCXX11AttributeSpecifierInternal + // Finish with consuming close ']' '] SourceLocation CloseLoc = Tok.getLocation(); if (ExpectAndConsume(tok::r_square)) SkipUntil(tok::r_square); From a7539bc2d57d4484634eda94029376fe8a0a5de9 Mon Sep 17 00:00:00 2001 From: zebullon Date: Wed, 13 Nov 2024 20:23:49 +0900 Subject: [PATCH 25/26] Shame stash the parsedAttrs with Parser to deal with lifetime... --- clang/include/clang/Parse/Parser.h | 2 ++ clang/lib/Parse/ParseReflect.cpp | 13 +++++++------ clang/lib/Parse/Parser.cpp | 3 ++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 6f72000f195dab..4039604838f427 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -316,6 +316,8 @@ class Parser : public CodeCompletionHandler { /// Factory object for creating ParsedAttr objects. AttributeFactory AttrFactory; + /// FIXNE P3385 + ParsedAttributes Attrs; /// Gathers and cleans up TemplateIdAnnotations when parsing of a /// top-level declaration is finished. diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index 4de77b1682b9bc..9b0de2401b5cd1 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -83,21 +83,22 @@ ExprResult Parser::ParseCXXReflectExpression(SourceLocation OpLoc) { // Check for a standard attribute { - ParsedAttributes attrs(AttrFactory); - if (MaybeParseCXX11Attributes(attrs)) { + size_t last = Attrs.size(); + if (MaybeParseCXX11Attributes(Attrs)) { + size_t newLast = Attrs.size(); Diag(OperandLoc, diag::p3385_trace_attribute_parsed); // FIXME handle empty [[]] gracefully - if (attrs.empty()) { + if (last == newLast) { Diag(OperandLoc, diag::p3385_trace_empty_attributes_list); return ExprError(); } - if (attrs.size() > 1) { - Diag(OperandLoc, diag::p3385_err_attributes_list) << attrs.size(); + if (newLast - last > 1) { + Diag(OperandLoc, diag::p3385_err_attributes_list) << (newLast - last); return ExprError(); } - return Actions.ActOnCXXReflectExpr(OpLoc, &attrs.front()); + return Actions.ActOnCXXReflectExpr(OpLoc, &Attrs.back()); } } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 7f7851cc451536..4e1bd266bd24f2 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -21,6 +21,7 @@ #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/DeclSpec.h" +#include "clang/Sema/ParsedAttr.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaCodeCompletion.h" @@ -57,7 +58,7 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies) : PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions), Diags(PP.getDiagnostics()), GreaterThanIsOperator(true), ColonIsSacred(false), InMessageExpression(false), - TemplateParameterDepth(0), ParsingInObjCContainer(false) { + TemplateParameterDepth(0), Attrs(AttrFactory), ParsingInObjCContainer(false) { SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies; Tok.startToken(); Tok.setKind(tok::eof); From d7d903f084f7a5522da4fb5dffcd3bfc8ee875de Mon Sep 17 00:00:00 2001 From: zebullon Date: Mon, 25 Nov 2024 09:51:28 +0900 Subject: [PATCH 26/26] Stash splicing type reflection --- clang/lib/Parse/ParseDeclCXX.cpp | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index acdeaf20b8523d..96bba3244a03d0 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -16,6 +16,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/PrettyDeclStackTrace.h" +#include "clang/AST/Reflection.h" #include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/Attributes.h" #include "clang/Basic/CharInfo.h" @@ -5043,6 +5044,43 @@ bool Parser::ParseCXX11AttributeArgs( return true; } +// FIXME I'm copypasting this straight from ExprConstantMeta +// +static NamedDecl *findTypeDecl(QualType QT) { + // If it's an ElaboratedType, get the underlying NamedType. + if (const ElaboratedType *ET = dyn_cast(QT)) + QT = ET->getNamedType(); + + // Get the type's declaration. + NamedDecl *D = nullptr; + if (auto *TDT = dyn_cast(QT)) + D = TDT->getDecl(); + else if (auto *UT = dyn_cast(QT)) + D = UT->getFoundDecl(); + else if (auto *TD = QT->getAsTagDecl()) + return TD; + else if (auto *TT = dyn_cast(QT)) + D = TT->getDecl(); + else if (auto *UUTD = dyn_cast(QT)) + D = UUTD->getDecl(); + else if (auto *TS = dyn_cast(QT)) { + if (auto *CTD = dyn_cast( + TS->getTemplateName().getAsTemplateDecl())) { + void *InsertPos; + D = CTD->findSpecialization(TS->template_arguments(), InsertPos); + } + } else if (auto *STTP = dyn_cast(QT)) + D = findTypeDecl(STTP->getReplacementType()); + else if (auto *ICNT = dyn_cast(QT)) + D = ICNT->getDecl(); + else if (auto *DTT = dyn_cast(QT)) + D = findTypeDecl(DTT->getUnderlyingType()); + + return D; +} + +// FIXME this is get_attributes, repeated here +// bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, SourceLocation *EndLoc) { @@ -5063,6 +5101,8 @@ bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, << "Found splice in attribute expression"; SourceLocation loc = (Tok.getLocation()); SourceRange range(loc); + + // FIXME What's this doing ? ExprResult Result = getExprAnnotation(Tok); ConsumeAnnotationToken(); @@ -5073,6 +5113,7 @@ bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, if (!SpliceExpr->EvaluateAsRValue(ER, Actions.getASTContext(), true)) { return false; } + assert(ER.Val.getKind() == APValue::Reflection); switch (ER.Val.getReflectionKind()) { case ReflectionKind::Attribute: { @@ -5085,6 +5126,23 @@ bool Parser::tryParseSpliceAttrSpecifier(ParsedAttributes &Attrs, ParsedAttr::Form::CXX11()); break; } + case ReflectionKind::Type: { + QualType qType = ER.Val.getReflectedType(); + Decl *D = findTypeDecl(qType); + if (!D) { + // FIXME how would we end up here ? + Diag(Tok.getLocation(), diag::p3385_err_attribute_splicing_error) + << "Error while splicing type attributes inside a [[ ]]"; + } + for (auto *const attr : D->attrs()) { + Attrs.addNew( + const_cast(attr->getAttrName()), // (C) Trust me bro 2 + range, + nullptr, loc, nullptr, 0, + ParsedAttr::Form::CXX11()); + } + break; + } default: Diag(Tok.getLocation(), diag::p3385_err_attribute_splicing_error) << "unsupported kind in attribute splicing";