diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/StmtProfile.cpp')
| -rw-r--r-- | contrib/llvm-project/clang/lib/AST/StmtProfile.cpp | 522 |
1 files changed, 467 insertions, 55 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/StmtProfile.cpp b/contrib/llvm-project/clang/lib/AST/StmtProfile.cpp index de9de6ff463c..89d2a422509d 100644 --- a/contrib/llvm-project/clang/lib/AST/StmtProfile.cpp +++ b/contrib/llvm-project/clang/lib/AST/StmtProfile.cpp @@ -29,15 +29,21 @@ namespace { protected: llvm::FoldingSetNodeID &ID; bool Canonical; + bool ProfileLambdaExpr; public: - StmtProfiler(llvm::FoldingSetNodeID &ID, bool Canonical) - : ID(ID), Canonical(Canonical) {} + StmtProfiler(llvm::FoldingSetNodeID &ID, bool Canonical, + bool ProfileLambdaExpr) + : ID(ID), Canonical(Canonical), ProfileLambdaExpr(ProfileLambdaExpr) {} virtual ~StmtProfiler() {} void VisitStmt(const Stmt *S); + void VisitStmtNoChildren(const Stmt *S) { + HandleStmtClass(S->getStmtClass()); + } + virtual void HandleStmtClass(Stmt::StmtClass SC) = 0; #define STMT(Node, Base) void Visit##Node(const Node *S); @@ -55,7 +61,7 @@ namespace { virtual void VisitName(DeclarationName Name, bool TreatAsDecl = false) = 0; /// Visit identifiers that are not in Decl's or Type's. - virtual void VisitIdentifierInfo(IdentifierInfo *II) = 0; + virtual void VisitIdentifierInfo(const IdentifierInfo *II) = 0; /// Visit a nested-name-specifier that occurs within an expression /// or statement. @@ -79,8 +85,10 @@ namespace { public: StmtProfilerWithPointers(llvm::FoldingSetNodeID &ID, - const ASTContext &Context, bool Canonical) - : StmtProfiler(ID, Canonical), Context(Context) {} + const ASTContext &Context, bool Canonical, + bool ProfileLambdaExpr) + : StmtProfiler(ID, Canonical, ProfileLambdaExpr), Context(Context) {} + private: void HandleStmtClass(Stmt::StmtClass SC) override { ID.AddInteger(SC); @@ -95,7 +103,15 @@ namespace { ID.AddInteger(NTTP->getDepth()); ID.AddInteger(NTTP->getIndex()); ID.AddBoolean(NTTP->isParameterPack()); - VisitType(NTTP->getType()); + // C++20 [temp.over.link]p6: + // Two template-parameters are equivalent under the following + // conditions: [...] if they declare non-type template parameters, + // they have equivalent types ignoring the use of type-constraints + // for placeholder types + // + // TODO: Why do we need to include the type in the profile? It's not + // part of the mangling. + VisitType(Context.getUnconstrainedType(NTTP->getType())); return; } @@ -107,6 +123,9 @@ namespace { // definition of "equivalent" (per C++ [temp.over.link]) is at // least as strong as the definition of "equivalent" used for // name mangling. + // + // TODO: The Itanium C++ ABI only uses the top-level cv-qualifiers, + // not the entirety of the type. VisitType(Parm->getType()); ID.AddInteger(Parm->getFunctionScopeDepth()); ID.AddInteger(Parm->getFunctionScopeIndex()); @@ -144,7 +163,7 @@ namespace { ID.AddPointer(Name.getAsOpaquePtr()); } - void VisitIdentifierInfo(IdentifierInfo *II) override { + void VisitIdentifierInfo(const IdentifierInfo *II) override { ID.AddPointer(II); } @@ -166,7 +185,8 @@ namespace { ODRHash &Hash; public: StmtProfilerWithoutPointers(llvm::FoldingSetNodeID &ID, ODRHash &Hash) - : StmtProfiler(ID, false), Hash(Hash) {} + : StmtProfiler(ID, /*Canonical=*/false, /*ProfileLambdaExpr=*/false), + Hash(Hash) {} private: void HandleStmtClass(Stmt::StmtClass SC) override { @@ -191,7 +211,7 @@ namespace { } Hash.AddDeclarationName(Name, TreatAsDecl); } - void VisitIdentifierInfo(IdentifierInfo *II) override { + void VisitIdentifierInfo(const IdentifierInfo *II) override { ID.AddBoolean(II); if (II) { Hash.AddIdentifierInfo(II); @@ -218,7 +238,7 @@ namespace { void StmtProfiler::VisitStmt(const Stmt *S) { assert(S && "Requires non-null Stmt pointer"); - HandleStmtClass(S->getStmtClass()); + VisitStmtNoChildren(S); for (const Stmt *SubStmt : S->children()) { if (SubStmt) @@ -452,6 +472,11 @@ void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) { Profiler->VisitStmt(C->getNumThreads()); } +void OMPClauseProfiler::VisitOMPAlignClause(const OMPAlignClause *C) { + if (C->getAlignment()) + Profiler->VisitStmt(C->getAlignment()); +} + void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) { if (C->getSafelen()) Profiler->VisitStmt(C->getSafelen()); @@ -462,6 +487,19 @@ void OMPClauseProfiler::VisitOMPSimdlenClause(const OMPSimdlenClause *C) { Profiler->VisitStmt(C->getSimdlen()); } +void OMPClauseProfiler::VisitOMPSizesClause(const OMPSizesClause *C) { + for (auto *E : C->getSizesRefs()) + if (E) + Profiler->VisitExpr(E); +} + +void OMPClauseProfiler::VisitOMPFullClause(const OMPFullClause *C) {} + +void OMPClauseProfiler::VisitOMPPartialClause(const OMPPartialClause *C) { + if (const Expr *Factor = C->getFactor()) + Profiler->VisitExpr(Factor); +} + void OMPClauseProfiler::VisitOMPAllocatorClause(const OMPAllocatorClause *C) { if (C->getAllocator()) Profiler->VisitStmt(C->getAllocator()); @@ -477,6 +515,18 @@ void OMPClauseProfiler::VisitOMPDetachClause(const OMPDetachClause *C) { Profiler->VisitStmt(Evt); } +void OMPClauseProfiler::VisitOMPNovariantsClause(const OMPNovariantsClause *C) { + VistOMPClauseWithPreInit(C); + if (C->getCondition()) + Profiler->VisitStmt(C->getCondition()); +} + +void OMPClauseProfiler::VisitOMPNocontextClause(const OMPNocontextClause *C) { + VistOMPClauseWithPreInit(C); + if (C->getCondition()) + Profiler->VisitStmt(C->getCondition()); +} + void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { } void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { } @@ -496,6 +546,15 @@ void OMPClauseProfiler::VisitOMPDynamicAllocatorsClause( void OMPClauseProfiler::VisitOMPAtomicDefaultMemOrderClause( const OMPAtomicDefaultMemOrderClause *C) {} +void OMPClauseProfiler::VisitOMPAtClause(const OMPAtClause *C) {} + +void OMPClauseProfiler::VisitOMPSeverityClause(const OMPSeverityClause *C) {} + +void OMPClauseProfiler::VisitOMPMessageClause(const OMPMessageClause *C) { + if (C->getMessageString()) + Profiler->VisitStmt(C->getMessageString()); +} + void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) { VistOMPClauseWithPreInit(C); if (auto *S = C->getChunkSize()) @@ -521,6 +580,10 @@ void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {} void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {} +void OMPClauseProfiler::VisitOMPCompareClause(const OMPCompareClause *) {} + +void OMPClauseProfiler::VisitOMPFailClause(const OMPFailClause *) {} + void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {} void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {} @@ -531,13 +594,33 @@ void OMPClauseProfiler::VisitOMPReleaseClause(const OMPReleaseClause *) {} void OMPClauseProfiler::VisitOMPRelaxedClause(const OMPRelaxedClause *) {} +void OMPClauseProfiler::VisitOMPWeakClause(const OMPWeakClause *) {} + void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {} void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {} void OMPClauseProfiler::VisitOMPNogroupClause(const OMPNogroupClause *) {} -void OMPClauseProfiler::VisitOMPDestroyClause(const OMPDestroyClause *) {} +void OMPClauseProfiler::VisitOMPInitClause(const OMPInitClause *C) { + VisitOMPClauseList(C); +} + +void OMPClauseProfiler::VisitOMPUseClause(const OMPUseClause *C) { + if (C->getInteropVar()) + Profiler->VisitStmt(C->getInteropVar()); +} + +void OMPClauseProfiler::VisitOMPDestroyClause(const OMPDestroyClause *C) { + if (C->getInteropVar()) + Profiler->VisitStmt(C->getInteropVar()); +} + +void OMPClauseProfiler::VisitOMPFilterClause(const OMPFilterClause *C) { + VistOMPClauseWithPreInit(C); + if (C->getThreadID()) + Profiler->VisitStmt(C->getThreadID()); +} template<typename T> void OMPClauseProfiler::VisitOMPClauseList(T *Node) { @@ -807,6 +890,10 @@ void OMPClauseProfiler::VisitOMPIsDevicePtrClause( const OMPIsDevicePtrClause *C) { VisitOMPClauseList(C); } +void OMPClauseProfiler::VisitOMPHasDeviceAddrClause( + const OMPHasDeviceAddrClause *C) { + VisitOMPClauseList(C); +} void OMPClauseProfiler::VisitOMPNontemporalClause( const OMPNontemporalClause *C) { VisitOMPClauseList(C); @@ -835,6 +922,19 @@ void OMPClauseProfiler::VisitOMPAffinityClause(const OMPAffinityClause *C) { Profiler->VisitStmt(E); } void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {} +void OMPClauseProfiler::VisitOMPBindClause(const OMPBindClause *C) {} +void OMPClauseProfiler::VisitOMPXDynCGroupMemClause( + const OMPXDynCGroupMemClause *C) { + VistOMPClauseWithPreInit(C); + if (Expr *Size = C->getSize()) + Profiler->VisitStmt(Size); +} +void OMPClauseProfiler::VisitOMPDoacrossClause(const OMPDoacrossClause *C) { + VisitOMPClauseList(C); +} +void OMPClauseProfiler::VisitOMPXAttributeClause(const OMPXAttributeClause *C) { +} +void OMPClauseProfiler::VisitOMPXBareClause(const OMPXBareClause *C) {} } // namespace void @@ -848,7 +948,19 @@ StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) { P.Visit(*I); } +void StmtProfiler::VisitOMPCanonicalLoop(const OMPCanonicalLoop *L) { + VisitStmt(L); +} + +void StmtProfiler::VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitOMPLoopDirective(const OMPLoopDirective *S) { + VisitOMPLoopBasedDirective(S); +} + +void StmtProfiler::VisitOMPMetaDirective(const OMPMetaDirective *S) { VisitOMPExecutableDirective(S); } @@ -860,6 +972,28 @@ void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) { VisitOMPLoopDirective(S); } +void StmtProfiler::VisitOMPLoopTransformationDirective( + const OMPLoopTransformationDirective *S) { + VisitOMPLoopBasedDirective(S); +} + +void StmtProfiler::VisitOMPTileDirective(const OMPTileDirective *S) { + VisitOMPLoopTransformationDirective(S); +} + +void StmtProfiler::VisitOMPUnrollDirective(const OMPUnrollDirective *S) { + VisitOMPLoopTransformationDirective(S); +} + +void StmtProfiler::VisitOMPReverseDirective(const OMPReverseDirective *S) { + VisitOMPLoopTransformationDirective(S); +} + +void StmtProfiler::VisitOMPInterchangeDirective( + const OMPInterchangeDirective *S) { + VisitOMPLoopTransformationDirective(S); +} + void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) { VisitOMPLoopDirective(S); } @@ -876,6 +1010,10 @@ void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) { VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPScopeDirective(const OMPScopeDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) { VisitOMPExecutableDirective(S); } @@ -904,6 +1042,11 @@ void StmtProfiler::VisitOMPParallelMasterDirective( VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPParallelMaskedDirective( + const OMPParallelMaskedDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitOMPParallelSectionsDirective( const OMPParallelSectionsDirective *S) { VisitOMPExecutableDirective(S); @@ -925,6 +1068,9 @@ void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) { VisitOMPExecutableDirective(S); } +void StmtProfiler::VisitOMPErrorDirective(const OMPErrorDirective *S) { + VisitOMPExecutableDirective(S); +} void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) { VisitOMPExecutableDirective(S); if (const Expr *E = S->getReductionRef()) @@ -1006,21 +1152,41 @@ void StmtProfiler::VisitOMPMasterTaskLoopDirective( VisitOMPLoopDirective(S); } +void StmtProfiler::VisitOMPMaskedTaskLoopDirective( + const OMPMaskedTaskLoopDirective *S) { + VisitOMPLoopDirective(S); +} + void StmtProfiler::VisitOMPMasterTaskLoopSimdDirective( const OMPMasterTaskLoopSimdDirective *S) { VisitOMPLoopDirective(S); } +void StmtProfiler::VisitOMPMaskedTaskLoopSimdDirective( + const OMPMaskedTaskLoopSimdDirective *S) { + VisitOMPLoopDirective(S); +} + void StmtProfiler::VisitOMPParallelMasterTaskLoopDirective( const OMPParallelMasterTaskLoopDirective *S) { VisitOMPLoopDirective(S); } +void StmtProfiler::VisitOMPParallelMaskedTaskLoopDirective( + const OMPParallelMaskedTaskLoopDirective *S) { + VisitOMPLoopDirective(S); +} + void StmtProfiler::VisitOMPParallelMasterTaskLoopSimdDirective( const OMPParallelMasterTaskLoopSimdDirective *S) { VisitOMPLoopDirective(S); } +void StmtProfiler::VisitOMPParallelMaskedTaskLoopSimdDirective( + const OMPParallelMaskedTaskLoopSimdDirective *S) { + VisitOMPLoopDirective(S); +} + void StmtProfiler::VisitOMPDistributeDirective( const OMPDistributeDirective *S) { VisitOMPLoopDirective(S); @@ -1110,6 +1276,43 @@ void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective( VisitOMPLoopDirective(S); } +void StmtProfiler::VisitOMPInteropDirective(const OMPInteropDirective *S) { + VisitOMPExecutableDirective(S); +} + +void StmtProfiler::VisitOMPDispatchDirective(const OMPDispatchDirective *S) { + VisitOMPExecutableDirective(S); +} + +void StmtProfiler::VisitOMPMaskedDirective(const OMPMaskedDirective *S) { + VisitOMPExecutableDirective(S); +} + +void StmtProfiler::VisitOMPGenericLoopDirective( + const OMPGenericLoopDirective *S) { + VisitOMPLoopDirective(S); +} + +void StmtProfiler::VisitOMPTeamsGenericLoopDirective( + const OMPTeamsGenericLoopDirective *S) { + VisitOMPLoopDirective(S); +} + +void StmtProfiler::VisitOMPTargetTeamsGenericLoopDirective( + const OMPTargetTeamsGenericLoopDirective *S) { + VisitOMPLoopDirective(S); +} + +void StmtProfiler::VisitOMPParallelGenericLoopDirective( + const OMPParallelGenericLoopDirective *S) { + VisitOMPLoopDirective(S); +} + +void StmtProfiler::VisitOMPTargetParallelGenericLoopDirective( + const OMPTargetParallelGenericLoopDirective *S) { + VisitOMPLoopDirective(S); +} + void StmtProfiler::VisitExpr(const Expr *S) { VisitStmt(S); } @@ -1130,15 +1333,29 @@ void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) { } } +void StmtProfiler::VisitSYCLUniqueStableNameExpr( + const SYCLUniqueStableNameExpr *S) { + VisitExpr(S); + VisitType(S->getTypeSourceInfo()->getType()); +} + void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) { VisitExpr(S); - ID.AddInteger(S->getIdentKind()); + ID.AddInteger(llvm::to_underlying(S->getIdentKind())); } void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) { VisitExpr(S); S->getValue().Profile(ID); - ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind()); + + QualType T = S->getType(); + if (Canonical) + T = T.getCanonicalType(); + ID.AddInteger(T->getTypeClass()); + if (auto BitIntT = T->getAs<BitIntType>()) + BitIntT->Profile(ID); + else + ID.AddInteger(T->castAs<BuiltinType>()->getKind()); } void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral *S) { @@ -1149,7 +1366,7 @@ void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral *S) { void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) { VisitExpr(S); - ID.AddInteger(S->getKind()); + ID.AddInteger(llvm::to_underlying(S->getKind())); ID.AddInteger(S->getValue()); } @@ -1167,7 +1384,7 @@ void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) { void StmtProfiler::VisitStringLiteral(const StringLiteral *S) { VisitExpr(S); ID.AddString(S->getBytes()); - ID.AddInteger(S->getKind()); + ID.AddInteger(llvm::to_underlying(S->getKind())); } void StmtProfiler::VisitParenExpr(const ParenExpr *S) { @@ -1227,7 +1444,7 @@ void StmtProfiler::VisitMatrixSubscriptExpr(const MatrixSubscriptExpr *S) { VisitExpr(S); } -void StmtProfiler::VisitOMPArraySectionExpr(const OMPArraySectionExpr *S) { +void StmtProfiler::VisitArraySectionExpr(const ArraySectionExpr *S) { VisitExpr(S); } @@ -1349,7 +1566,7 @@ void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) { assert(D.isArrayRangeDesignator()); ID.AddInteger(2); } - ID.AddInteger(D.getFirstExprIndex()); + ID.AddInteger(D.getArrayIndex()); } } @@ -1458,8 +1675,8 @@ void StmtProfiler::VisitRequiresExpr(const RequiresExpr *S) { } else { ID.AddInteger(concepts::Requirement::RK_Nested); auto *NestedReq = cast<concepts::NestedRequirement>(Req); - ID.AddBoolean(NestedReq->isSubstitutionFailure()); - if (!NestedReq->isSubstitutionFailure()) + ID.AddBoolean(NestedReq->hasInvalidConstraint()); + if (!NestedReq->hasInvalidConstraint()) Visit(NestedReq->getConstraintExpr()); } } @@ -1467,7 +1684,8 @@ void StmtProfiler::VisitRequiresExpr(const RequiresExpr *S) { static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, UnaryOperatorKind &UnaryOp, - BinaryOperatorKind &BinaryOp) { + BinaryOperatorKind &BinaryOp, + unsigned &NumArgs) { switch (S->getOperator()) { case OO_None: case OO_New: @@ -1480,7 +1698,7 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, llvm_unreachable("Invalid operator call kind"); case OO_Plus: - if (S->getNumArgs() == 1) { + if (NumArgs == 1) { UnaryOp = UO_Plus; return Stmt::UnaryOperatorClass; } @@ -1489,7 +1707,7 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, return Stmt::BinaryOperatorClass; case OO_Minus: - if (S->getNumArgs() == 1) { + if (NumArgs == 1) { UnaryOp = UO_Minus; return Stmt::UnaryOperatorClass; } @@ -1498,7 +1716,7 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, return Stmt::BinaryOperatorClass; case OO_Star: - if (S->getNumArgs() == 1) { + if (NumArgs == 1) { UnaryOp = UO_Deref; return Stmt::UnaryOperatorClass; } @@ -1519,7 +1737,7 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, return Stmt::BinaryOperatorClass; case OO_Amp: - if (S->getNumArgs() == 1) { + if (NumArgs == 1) { UnaryOp = UO_AddrOf; return Stmt::UnaryOperatorClass; } @@ -1628,13 +1846,13 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, return Stmt::BinaryOperatorClass; case OO_PlusPlus: - UnaryOp = S->getNumArgs() == 1? UO_PreInc - : UO_PostInc; + UnaryOp = NumArgs == 1 ? UO_PreInc : UO_PostInc; + NumArgs = 1; return Stmt::UnaryOperatorClass; case OO_MinusMinus: - UnaryOp = S->getNumArgs() == 1? UO_PreDec - : UO_PostDec; + UnaryOp = NumArgs == 1 ? UO_PreDec : UO_PostDec; + NumArgs = 1; return Stmt::UnaryOperatorClass; case OO_Comma: @@ -1680,10 +1898,11 @@ void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) { UnaryOperatorKind UnaryOp = UO_Extension; BinaryOperatorKind BinaryOp = BO_Comma; - Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp); + unsigned NumArgs = S->getNumArgs(); + Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp, NumArgs); ID.AddInteger(SC); - for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I) + for (unsigned I = 0; I != NumArgs; ++I) Visit(S->getArg(I)); if (SC == Stmt::UnaryOperatorClass) ID.AddInteger(UnaryOp); @@ -1801,6 +2020,7 @@ void StmtProfiler::VisitMSPropertySubscriptExpr( void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) { VisitExpr(S); ID.AddBoolean(S->isImplicit()); + ID.AddBoolean(S->isCapturedByCopyInLambdaWithExplicitObjectParameter()); } void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) { @@ -1846,31 +2066,45 @@ StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) { void StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) { - VisitExpr(S); - for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(), - CEnd = S->explicit_capture_end(); - C != CEnd; ++C) { - if (C->capturesVLAType()) + if (!ProfileLambdaExpr) { + // Do not recursively visit the children of this expression. Profiling the + // body would result in unnecessary work, and is not safe to do during + // deserialization. + VisitStmtNoChildren(S); + + // C++20 [temp.over.link]p5: + // Two lambda-expressions are never considered equivalent. + VisitDecl(S->getLambdaClass()); + + return; + } + + CXXRecordDecl *Lambda = S->getLambdaClass(); + for (const auto &Capture : Lambda->captures()) { + ID.AddInteger(Capture.getCaptureKind()); + if (Capture.capturesVariable()) + VisitDecl(Capture.getCapturedVar()); + } + + // Profiling the body of the lambda may be dangerous during deserialization. + // So we'd like only to profile the signature here. + ODRHash Hasher; + // FIXME: We can't get the operator call easily by + // `CXXRecordDecl::getLambdaCallOperator()` if we're in deserialization. + // So we have to do something raw here. + for (auto *SubDecl : Lambda->decls()) { + FunctionDecl *Call = nullptr; + if (auto *FTD = dyn_cast<FunctionTemplateDecl>(SubDecl)) + Call = FTD->getTemplatedDecl(); + else if (auto *FD = dyn_cast<FunctionDecl>(SubDecl)) + Call = FD; + + if (!Call) continue; - ID.AddInteger(C->getCaptureKind()); - switch (C->getCaptureKind()) { - case LCK_StarThis: - case LCK_This: - break; - case LCK_ByRef: - case LCK_ByCopy: - VisitDecl(C->getCapturedVar()); - ID.AddBoolean(C->isPackExpansion()); - break; - case LCK_VLAType: - llvm_unreachable("VLA type in explicit captures."); - } + Hasher.AddFunctionDecl(Call, /*SkipBody=*/true); } - // Note: If we actually needed to be able to match lambda - // expressions, we would have to consider parameters and return type - // here, among other things. - VisitStmt(S->getBody()); + ID.AddInteger(Hasher.CalculateHash()); } void @@ -1894,7 +2128,7 @@ void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) { ID.AddInteger(S->getNumPlacementArgs()); ID.AddBoolean(S->isGlobalNew()); ID.AddBoolean(S->isParenTypeId()); - ID.AddInteger(S->getInitializationStyle()); + ID.AddInteger(llvm::to_underlying(S->getInitializationStyle())); } void @@ -2015,6 +2249,12 @@ void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) { } } +void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) { + VisitExpr(E); + VisitExpr(E->getPackIdExpression()); + VisitExpr(E->getIndexExpr()); +} + void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr( const SubstNonTypeTemplateParmPackExpr *S) { VisitExpr(S); @@ -2046,6 +2286,10 @@ void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) { ID.AddInteger(S->getOperator()); } +void StmtProfiler::VisitCXXParenListInitExpr(const CXXParenListInitExpr *S) { + VisitExpr(S); +} + void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) { VisitStmt(S); } @@ -2078,6 +2322,8 @@ void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) { VisitExpr(E); } +void StmtProfiler::VisitEmbedExpr(const EmbedExpr *E) { VisitExpr(E); } + void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr *E) { VisitExpr(E); } void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) { @@ -2208,6 +2454,12 @@ void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) { Arg.getAsIntegral().Profile(ID); break; + case TemplateArgument::StructuralValue: + VisitType(Arg.getStructuralValueType()); + // FIXME: Do we need to recursively decompose this ourselves? + Arg.getAsStructuralValue().Profile(ID); + break; + case TemplateArgument::Expression: Visit(Arg.getAsExpr()); break; @@ -2219,9 +2471,169 @@ void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) { } } +namespace { +class OpenACCClauseProfiler + : public OpenACCClauseVisitor<OpenACCClauseProfiler> { + StmtProfiler &Profiler; + +public: + OpenACCClauseProfiler(StmtProfiler &P) : Profiler(P) {} + + void VisitOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses) { + for (const OpenACCClause *Clause : Clauses) { + // TODO OpenACC: When we have clauses with expressions, we should + // profile them too. + Visit(Clause); + } + } + +#define VISIT_CLAUSE(CLAUSE_NAME) \ + void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause); + +#include "clang/Basic/OpenACCClauses.def" +}; + +/// Nothing to do here, there are no sub-statements. +void OpenACCClauseProfiler::VisitDefaultClause( + const OpenACCDefaultClause &Clause) {} + +void OpenACCClauseProfiler::VisitIfClause(const OpenACCIfClause &Clause) { + assert(Clause.hasConditionExpr() && + "if clause requires a valid condition expr"); + Profiler.VisitStmt(Clause.getConditionExpr()); +} + +void OpenACCClauseProfiler::VisitCopyClause(const OpenACCCopyClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} +void OpenACCClauseProfiler::VisitCopyInClause( + const OpenACCCopyInClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} + +void OpenACCClauseProfiler::VisitCopyOutClause( + const OpenACCCopyOutClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} + +void OpenACCClauseProfiler::VisitCreateClause( + const OpenACCCreateClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} + +void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) { + if (Clause.hasConditionExpr()) + Profiler.VisitStmt(Clause.getConditionExpr()); +} + +void OpenACCClauseProfiler::VisitNumGangsClause( + const OpenACCNumGangsClause &Clause) { + for (auto *E : Clause.getIntExprs()) + Profiler.VisitStmt(E); +} + +void OpenACCClauseProfiler::VisitNumWorkersClause( + const OpenACCNumWorkersClause &Clause) { + assert(Clause.hasIntExpr() && "num_workers clause requires a valid int expr"); + Profiler.VisitStmt(Clause.getIntExpr()); +} + +void OpenACCClauseProfiler::VisitPrivateClause( + const OpenACCPrivateClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} + +void OpenACCClauseProfiler::VisitFirstPrivateClause( + const OpenACCFirstPrivateClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} + +void OpenACCClauseProfiler::VisitAttachClause( + const OpenACCAttachClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} + +void OpenACCClauseProfiler::VisitDevicePtrClause( + const OpenACCDevicePtrClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} + +void OpenACCClauseProfiler::VisitNoCreateClause( + const OpenACCNoCreateClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} + +void OpenACCClauseProfiler::VisitPresentClause( + const OpenACCPresentClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} + +void OpenACCClauseProfiler::VisitVectorLengthClause( + const OpenACCVectorLengthClause &Clause) { + assert(Clause.hasIntExpr() && + "vector_length clause requires a valid int expr"); + Profiler.VisitStmt(Clause.getIntExpr()); +} + +void OpenACCClauseProfiler::VisitAsyncClause(const OpenACCAsyncClause &Clause) { + if (Clause.hasIntExpr()) + Profiler.VisitStmt(Clause.getIntExpr()); +} + +void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) { + if (Clause.hasDevNumExpr()) + Profiler.VisitStmt(Clause.getDevNumExpr()); + for (auto *E : Clause.getQueueIdExprs()) + Profiler.VisitStmt(E); +} +/// Nothing to do here, there are no sub-statements. +void OpenACCClauseProfiler::VisitDeviceTypeClause( + const OpenACCDeviceTypeClause &Clause) {} + +void OpenACCClauseProfiler::VisitAutoClause(const OpenACCAutoClause &Clause) {} + +void OpenACCClauseProfiler::VisitIndependentClause( + const OpenACCIndependentClause &Clause) {} + +void OpenACCClauseProfiler::VisitSeqClause(const OpenACCSeqClause &Clause) {} + +void OpenACCClauseProfiler::VisitReductionClause( + const OpenACCReductionClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} +} // namespace + +void StmtProfiler::VisitOpenACCComputeConstruct( + const OpenACCComputeConstruct *S) { + // VisitStmt handles children, so the AssociatedStmt is handled. + VisitStmt(S); + + OpenACCClauseProfiler P{*this}; + P.VisitOpenACCClauseList(S->clauses()); +} + +void StmtProfiler::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) { + // VisitStmt handles children, so the Loop is handled. + VisitStmt(S); + + OpenACCClauseProfiler P{*this}; + P.VisitOpenACCClauseList(S->clauses()); +} + void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, - bool Canonical) const { - StmtProfilerWithPointers Profiler(ID, Context, Canonical); + bool Canonical, bool ProfileLambdaExpr) const { + StmtProfilerWithPointers Profiler(ID, Context, Canonical, ProfileLambdaExpr); Profiler.Visit(this); } |
