diff options
Diffstat (limited to 'clang/lib')
25 files changed, 725 insertions, 111 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 7353cbc..20836f6 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -2508,7 +2508,7 @@ bool Compiler<Emitter>::VisitAbstractConditionalOperator( }; if (std::optional<bool> BoolValue = getBoolValue(Condition)) { - if (BoolValue) + if (*BoolValue) return visitChildExpr(TrueExpr); return visitChildExpr(FalseExpr); } @@ -3235,7 +3235,8 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) { return this->visitInitializer(E->getArg(0)); // Zero initialization. - if (E->requiresZeroInitialization()) { + bool ZeroInit = E->requiresZeroInitialization(); + if (ZeroInit) { const Record *R = getRecord(E->getType()); if (!this->visitZeroRecordInitializer(R, E)) @@ -3246,6 +3247,19 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) { return true; } + // Avoid materializing a temporary for an elidable copy/move constructor. + if (!ZeroInit && E->isElidable()) { + const Expr *SrcObj = E->getArg(0); + assert(SrcObj->isTemporaryObject(Ctx.getASTContext(), Ctor->getParent())); + assert(Ctx.getASTContext().hasSameUnqualifiedType(E->getType(), + SrcObj->getType())); + if (const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj)) { + if (!this->emitCheckFunctionDecl(Ctor, E)) + return false; + return this->visitInitializer(ME->getSubExpr()); + } + } + const Function *Func = getFunction(Ctor); if (!Func) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index a2fb0fb..1f2ae92 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -919,33 +919,8 @@ bool CheckInit(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { return true; } -static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { - - if (F->isVirtual() && !S.getLangOpts().CPlusPlus20) { - const SourceLocation &Loc = S.Current->getLocation(OpPC); - S.CCEDiag(Loc, diag::note_constexpr_virtual_call); - return false; - } - - if (S.checkingPotentialConstantExpression() && S.Current->getDepth() != 0) - return false; - - if (F->isValid() && F->hasBody() && F->isConstexpr()) - return true; - - const FunctionDecl *DiagDecl = F->getDecl(); - const FunctionDecl *Definition = nullptr; - DiagDecl->getBody(Definition); - - if (!Definition && S.checkingPotentialConstantExpression() && - DiagDecl->isConstexpr()) { - return false; - } - - // Implicitly constexpr. - if (F->isLambdaStaticInvoker()) - return true; - +static bool diagnoseCallableDecl(InterpState &S, CodePtr OpPC, + const FunctionDecl *DiagDecl) { // Bail out if the function declaration itself is invalid. We will // have produced a relevant diagnostic while parsing it, so just // note the problematic sub-expression. @@ -953,11 +928,10 @@ static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { return Invalid(S, OpPC); // Diagnose failed assertions specially. - if (S.Current->getLocation(OpPC).isMacroID() && - F->getDecl()->getIdentifier()) { + if (S.Current->getLocation(OpPC).isMacroID() && DiagDecl->getIdentifier()) { // FIXME: Instead of checking for an implementation-defined function, // check and evaluate the assert() macro. - StringRef Name = F->getDecl()->getName(); + StringRef Name = DiagDecl->getName(); bool AssertFailed = Name == "__assert_rtn" || Name == "__assert_fail" || Name == "_wassert"; if (AssertFailed) { @@ -1004,7 +978,7 @@ static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { // for a constant expression. It might be defined at the point we're // actually calling it. bool IsExtern = DiagDecl->getStorageClass() == SC_Extern; - bool IsDefined = F->isDefined(); + bool IsDefined = DiagDecl->isDefined(); if (!IsDefined && !IsExtern && DiagDecl->isConstexpr() && S.checkingPotentialConstantExpression()) return false; @@ -1027,6 +1001,35 @@ static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { return false; } +static bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { + if (F->isVirtual() && !S.getLangOpts().CPlusPlus20) { + const SourceLocation &Loc = S.Current->getLocation(OpPC); + S.CCEDiag(Loc, diag::note_constexpr_virtual_call); + return false; + } + + if (S.checkingPotentialConstantExpression() && S.Current->getDepth() != 0) + return false; + + if (F->isValid() && F->hasBody() && F->isConstexpr()) + return true; + + const FunctionDecl *DiagDecl = F->getDecl(); + const FunctionDecl *Definition = nullptr; + DiagDecl->getBody(Definition); + + if (!Definition && S.checkingPotentialConstantExpression() && + DiagDecl->isConstexpr()) { + return false; + } + + // Implicitly constexpr. + if (F->isLambdaStaticInvoker()) + return true; + + return diagnoseCallableDecl(S, OpPC, DiagDecl); +} + static bool CheckCallDepth(InterpState &S, CodePtr OpPC) { if ((S.Current->getDepth() + 1) > S.getLangOpts().ConstexprCallDepth) { S.FFDiag(S.Current->getSource(OpPC), @@ -1500,6 +1503,21 @@ bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { return CheckActive(S, OpPC, Ptr, AK_Destroy); } +/// Opcode. Check if the function decl can be called at compile time. +bool CheckFunctionDecl(InterpState &S, CodePtr OpPC, const FunctionDecl *FD) { + if (S.checkingPotentialConstantExpression() && S.Current->getDepth() != 0) + return false; + + const FunctionDecl *Definition = nullptr; + const Stmt *Body = FD->getBody(Definition); + + if (Definition && Body && + (Definition->isConstexpr() || Definition->hasAttr<MSConstexprAttr>())) + return true; + + return diagnoseCallableDecl(S, OpPC, FD); +} + static void compileFunction(InterpState &S, const Function *Func) { const FunctionDecl *Definition = Func->getDecl()->getDefinition(); if (!Definition) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 6877b03..c16408c 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -117,6 +117,7 @@ bool CheckBitCast(InterpState &S, CodePtr OpPC, bool HasIndeterminateBits, bool TargetIsUCharOrByte); bool CheckBCPResult(InterpState &S, const Pointer &Ptr); bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr); +bool CheckFunctionDecl(InterpState &S, CodePtr OpPC, const FunctionDecl *FD); bool handleFixedPointOverflow(InterpState &S, CodePtr OpPC, const FixedPoint &FP); diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 1c17ad9e..a2eaa61 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -53,6 +53,7 @@ def ArgBool : ArgType { let Name = "bool"; } def ArgFixedPoint : ArgType { let Name = "FixedPoint"; let AsRef = true; } def ArgFunction : ArgType { let Name = "const Function *"; } +def ArgFunctionDecl : ArgType { let Name = "const FunctionDecl *"; } def ArgRecordDecl : ArgType { let Name = "const RecordDecl *"; } def ArgRecordField : ArgType { let Name = "const Record::Field *"; } def ArgFltSemantics : ArgType { let Name = "const llvm::fltSemantics *"; } @@ -422,6 +423,8 @@ def CheckLiteralType : Opcode { def CheckArraySize : Opcode { let Args = [ArgUint64]; } +def CheckFunctionDecl : Opcode { let Args = [ArgFunctionDecl]; } + // [] -> [Value] def GetGlobal : AccessOpcode; def GetGlobalUnchecked : AccessOpcode; diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 59d9459..0640fed 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -105,6 +105,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { return static_cast<const OMPFilterClause *>(C); case OMPC_ompx_dyn_cgroup_mem: return static_cast<const OMPXDynCGroupMemClause *>(C); + case OMPC_dyn_groupprivate: + return static_cast<const OMPDynGroupprivateClause *>(C); case OMPC_message: return static_cast<const OMPMessageClause *>(C); case OMPC_default: @@ -2857,6 +2859,24 @@ void OMPClausePrinter::VisitOMPXDynCGroupMemClause( OS << ")"; } +void OMPClausePrinter::VisitOMPDynGroupprivateClause( + OMPDynGroupprivateClause *Node) { + OS << "dyn_groupprivate("; + if (Node->getDynGroupprivateModifier() != OMPC_DYN_GROUPPRIVATE_unknown) { + OS << getOpenMPSimpleClauseTypeName(OMPC_dyn_groupprivate, + Node->getDynGroupprivateModifier()); + if (Node->getDynGroupprivateFallbackModifier() != + OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown) { + OS << ", "; + OS << getOpenMPSimpleClauseTypeName( + OMPC_dyn_groupprivate, Node->getDynGroupprivateFallbackModifier()); + } + OS << ": "; + } + Node->getSize()->printPretty(OS, nullptr, Policy, 0); + OS << ')'; +} + void OMPClausePrinter::VisitOMPDoacrossClause(OMPDoacrossClause *Node) { OS << "doacross("; OpenMPDoacrossClauseModifier DepType = Node->getDependenceType(); diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index c909e1b..4a8c638 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -968,6 +968,12 @@ void OMPClauseProfiler::VisitOMPXDynCGroupMemClause( if (Expr *Size = C->getSize()) Profiler->VisitStmt(Size); } +void OMPClauseProfiler::VisitOMPDynGroupprivateClause( + const OMPDynGroupprivateClause *C) { + VisitOMPClauseWithPreInit(C); + if (auto *Size = C->getSize()) + Profiler->VisitStmt(Size); +} void OMPClauseProfiler::VisitOMPDoacrossClause(const OMPDoacrossClause *C) { VisitOMPClauseList(C); } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 3d41f2d..8e60fc2 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -196,6 +196,16 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, return OMPC_GRAINSIZE_unknown; return Type; } + case OMPC_dyn_groupprivate: { + return llvm::StringSwitch<unsigned>(Str) +#define OPENMP_DYN_GROUPPRIVATE_MODIFIER(Name) \ + .Case(#Name, OMPC_DYN_GROUPPRIVATE_##Name) +#define OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER(Name) \ + .Case(#Name, OMPC_DYN_GROUPPRIVATE_FALLBACK_##Name) \ + .Case("fallback(" #Name ")", OMPC_DYN_GROUPPRIVATE_FALLBACK_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_DYN_GROUPPRIVATE_unknown); + } case OMPC_num_tasks: { unsigned Type = llvm::StringSwitch<unsigned>(Str) #define OPENMP_NUMTASKS_MODIFIER(Name) .Case(#Name, OMPC_NUMTASKS_##Name) @@ -544,6 +554,20 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier"); + case OMPC_dyn_groupprivate: + switch (Type) { + case OMPC_DYN_GROUPPRIVATE_unknown: + case OMPC_DYN_GROUPPRIVATE_FALLBACK_last: + return "unknown"; +#define OPENMP_DYN_GROUPPRIVATE_MODIFIER(Name) \ + case OMPC_DYN_GROUPPRIVATE_##Name: \ + return #Name; +#define OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER(Name) \ + case OMPC_DYN_GROUPPRIVATE_FALLBACK_##Name: \ + return "fallback(" #Name ")"; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'dyn_groupprivate' clause modifier"); case OMPC_num_tasks: switch (Type) { case OMPC_NUMTASKS_unknown: diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp index 1eb7199..7bb8c21 100644 --- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp @@ -66,7 +66,7 @@ static mlir::LogicalResult emitStmtWithResult(CIRGenFunction &cgf, mlir::LogicalResult CIRGenFunction::emitCompoundStmtWithoutScope( const CompoundStmt &s, Address *lastValue, AggValueSlot slot) { mlir::LogicalResult result = mlir::success(); - const Stmt *exprResult = s.getStmtExprResult(); + const Stmt *exprResult = s.body_back(); assert((!lastValue || (lastValue && exprResult)) && "If lastValue is not null then the CompoundStmt must have a " "StmtExprResult"); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0fea57b..98d59b7 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2368,9 +2368,8 @@ static QualType GeneralizeTransparentUnion(QualType Ty) { const RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf(); if (!UD->hasAttr<TransparentUnionAttr>()) return Ty; - for (const auto *it : UD->fields()) { - return it->getType(); - } + if (!UD->fields().empty()) + return UD->fields().begin()->getType(); return Ty; } diff --git a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp index 15fa78d..d4b0b81 100644 --- a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp @@ -590,6 +590,7 @@ struct ARMVectorIntrinsicInfo { Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \ TypeModifier } +// clang-format off static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = { NEONMAP1(__a32_vcvt_bf16_f32, arm_neon_vcvtfp2bf, 0), NEONMAP0(splat_lane_v), @@ -1217,35 +1218,55 @@ static const ARMVectorIntrinsicInfo AArch64SISDIntrinsicMap[] = { NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType), NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), + NEONMAP1(vcvtad_s32_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType), NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType), + NEONMAP1(vcvtad_u32_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType), NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType), NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType), + NEONMAP1(vcvtas_s64_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType), NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType), + NEONMAP1(vcvtas_u64_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType), NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), + NEONMAP1(vcvtd_s32_f64, aarch64_neon_fcvtzs, AddRetType | Add1ArgType), NEONMAP1(vcvtd_s64_f64, aarch64_neon_fcvtzs, AddRetType | Add1ArgType), + NEONMAP1(vcvtd_u32_f64, aarch64_neon_fcvtzu, AddRetType | Add1ArgType), NEONMAP1(vcvtd_u64_f64, aarch64_neon_fcvtzu, AddRetType | Add1ArgType), NEONMAP0(vcvth_bf16_f32), + NEONMAP1(vcvtmd_s32_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType), NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType), + NEONMAP1(vcvtmd_u32_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType), + NEONMAP1(vcvtms_s64_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType), NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), + NEONMAP1(vcvtms_u64_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), + NEONMAP1(vcvtnd_s32_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType), NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType), + NEONMAP1(vcvtnd_u32_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType), + NEONMAP1(vcvtns_s64_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType), NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), + NEONMAP1(vcvtns_u64_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), + NEONMAP1(vcvtpd_s32_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType), NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType), + NEONMAP1(vcvtpd_u32_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType), + NEONMAP1(vcvtps_s64_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType), NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), + NEONMAP1(vcvtps_u64_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), NEONMAP1(vcvts_s32_f32, aarch64_neon_fcvtzs, AddRetType | Add1ArgType), + NEONMAP1(vcvts_s64_f32, aarch64_neon_fcvtzs, AddRetType | Add1ArgType), NEONMAP1(vcvts_u32_f32, aarch64_neon_fcvtzu, AddRetType | Add1ArgType), + NEONMAP1(vcvts_u64_f32, aarch64_neon_fcvtzu, AddRetType | Add1ArgType), NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0), NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), @@ -1446,6 +1467,7 @@ static const ARMVectorIntrinsicInfo AArch64SISDIntrinsicMap[] = { NEONMAP1(vrsqrteh_f16, aarch64_neon_frsqrte, Add1ArgType), NEONMAP1(vrsqrtsh_f16, aarch64_neon_frsqrts, Add1ArgType), }; +// clang-format on // Some intrinsics are equivalent for codegen. static const std::pair<unsigned, unsigned> NEONEquivalentIntrinsicMap[] = { @@ -7624,6 +7646,16 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, Int = Intrinsic::aarch64_neon_vluti4q_laneq_x2; return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vluti4q_laneq_x2"); } + case NEON::BI__builtin_neon_vmmlaq_f16_mf8_fpm: + return EmitFP8NeonCall(Intrinsic::aarch64_neon_fmmla, + {llvm::FixedVectorType::get(HalfTy, 8), + llvm::FixedVectorType::get(Int8Ty, 16)}, + Ops, E, "fmmla"); + case NEON::BI__builtin_neon_vmmlaq_f32_mf8_fpm: + return EmitFP8NeonCall(Intrinsic::aarch64_neon_fmmla, + {llvm::FixedVectorType::get(FloatTy, 4), + llvm::FixedVectorType::get(Int8Ty, 16)}, + Ops, E, "fmmla"); case NEON::BI__builtin_neon_vcvt1_low_bf16_mf8_fpm: ExtractLow = true; [[fallthrough]]; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 30d3e52..e20963a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -8266,6 +8266,30 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, << "/kernel"; } + if (const Arg *A = Args.getLastArg(options::OPT__SLASH_vlen, + options::OPT__SLASH_vlen_EQ_256, + options::OPT__SLASH_vlen_EQ_512)) { + llvm::Triple::ArchType AT = getToolChain().getArch(); + StringRef Default = AT == llvm::Triple::x86 ? "IA32" : "SSE2"; + StringRef Arch = Args.getLastArgValue(options::OPT__SLASH_arch, Default); + + if (A->getOption().matches(options::OPT__SLASH_vlen_EQ_512)) { + if (Arch == "AVX512F" || Arch == "AVX512") + CmdArgs.push_back("-mprefer-vector-width=512"); + else + D.Diag(diag::warn_drv_argument_not_allowed_with) + << "/vlen=512" << std::string("/arch:").append(Arch); + } + + if (A->getOption().matches(options::OPT__SLASH_vlen_EQ_256)) { + if (Arch == "AVX512F" || Arch == "AVX512") + CmdArgs.push_back("-mprefer-vector-width=256"); + else if (Arch != "AVX" && Arch != "AVX2") + D.Diag(diag::warn_drv_argument_not_allowed_with) + << "/vlen=256" << std::string("/arch:").append(Arch); + } + } + Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg); Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb); if (MostGeneralArg && BestCaseArg) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index dd14fcd..9bbb33c 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -876,27 +876,28 @@ template <> struct MappingTraits<FormatStyle::TrailingCommentsAlignmentStyle> { FormatStyle::TrailingCommentsAlignmentStyle &Value) { IO.enumCase(Value, "Leave", FormatStyle::TrailingCommentsAlignmentStyle( - {FormatStyle::TCAS_Leave, 0})); + {FormatStyle::TCAS_Leave, 0, true})); IO.enumCase(Value, "Always", FormatStyle::TrailingCommentsAlignmentStyle( - {FormatStyle::TCAS_Always, 0})); + {FormatStyle::TCAS_Always, 0, true})); IO.enumCase(Value, "Never", FormatStyle::TrailingCommentsAlignmentStyle( - {FormatStyle::TCAS_Never, 0})); + {FormatStyle::TCAS_Never, 0, true})); // For backwards compatibility IO.enumCase(Value, "true", FormatStyle::TrailingCommentsAlignmentStyle( - {FormatStyle::TCAS_Always, 0})); + {FormatStyle::TCAS_Always, 0, true})); IO.enumCase(Value, "false", FormatStyle::TrailingCommentsAlignmentStyle( - {FormatStyle::TCAS_Never, 0})); + {FormatStyle::TCAS_Never, 0, true})); } static void mapping(IO &IO, FormatStyle::TrailingCommentsAlignmentStyle &Value) { + IO.mapOptional("AlignPPAndNotPP", Value.AlignPPAndNotPP); IO.mapOptional("Kind", Value.Kind); IO.mapOptional("OverEmptyLines", Value.OverEmptyLines); } @@ -1651,6 +1652,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.AlignTrailingComments = {}; LLVMStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Always; LLVMStyle.AlignTrailingComments.OverEmptyLines = 0; + LLVMStyle.AlignTrailingComments.AlignPPAndNotPP = true; LLVMStyle.AllowAllArgumentsOnNextLine = true; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; LLVMStyle.AllowBreakBeforeNoexceptSpecifier = FormatStyle::BBNSS_Never; diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 406c77c..fece384 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -1007,9 +1007,13 @@ void WhitespaceManager::alignTrailingComments() { return; const int Size = Changes.size(); + if (Size == 0) + return; + int MinColumn = 0; int StartOfSequence = 0; bool BreakBeforeNext = false; + bool IsInPP = Changes.front().Tok->Tok.is(tok::hash); int NewLineThreshold = 1; if (Style.AlignTrailingComments.Kind == FormatStyle::TCAS_Always) NewLineThreshold = Style.AlignTrailingComments.OverEmptyLines + 1; @@ -1018,7 +1022,19 @@ void WhitespaceManager::alignTrailingComments() { auto &C = Changes[I]; if (C.StartOfBlockComment) continue; - Newlines += C.NewlinesBefore; + if (C.NewlinesBefore != 0) { + Newlines += C.NewlinesBefore; + const bool WasInPP = std::exchange( + IsInPP, C.Tok->Tok.is(tok::hash) || (IsInPP && C.IsTrailingComment) || + C.ContinuesPPDirective); + if (IsInPP != WasInPP && !Style.AlignTrailingComments.AlignPPAndNotPP) { + alignTrailingComments(StartOfSequence, I, MinColumn); + MinColumn = 0; + MaxColumn = INT_MAX; + StartOfSequence = I; + Newlines = 0; + } + } if (!C.IsTrailingComment) continue; diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index d7d56b8..3595bbc 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -1233,20 +1233,6 @@ void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() { llvm::outs()); } -void GetDependenciesByModuleNameAction::ExecuteAction() { - CompilerInstance &CI = getCompilerInstance(); - Preprocessor &PP = CI.getPreprocessor(); - SourceManager &SM = PP.getSourceManager(); - FileID MainFileID = SM.getMainFileID(); - SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID); - SmallVector<IdentifierLoc, 2> Path; - IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName); - Path.emplace_back(FileStart, ModuleID); - auto ModResult = CI.loadModule(FileStart, Path, Module::Hidden, false); - PPCallbacks *CB = PP.getPPCallbacks(); - CB->moduleImport(SourceLocation(), Path, ModResult); -} - //===----------------------------------------------------------------------===// // HLSL Specific Actions //===----------------------------------------------------------------------===// diff --git a/clang/lib/Headers/llvm_libc_wrappers/stdlib.h b/clang/lib/Headers/llvm_libc_wrappers/stdlib.h index 1da22abd0..d79e7fa 100644 --- a/clang/lib/Headers/llvm_libc_wrappers/stdlib.h +++ b/clang/lib/Headers/llvm_libc_wrappers/stdlib.h @@ -34,13 +34,13 @@ _Static_assert(__builtin_offsetof(div_t, quot) == 0, "ABI mismatch!"); _Static_assert(__builtin_offsetof(ldiv_t, quot) == 0, "ABI mismatch!"); _Static_assert(__builtin_offsetof(lldiv_t, quot) == 0, "ABI mismatch!"); -#if defined(__GLIBC__) && __cplusplus >= 201703L +#if defined(__GLIBC__) && __cplusplus >= 201103L #define at_quick_exit atexit #endif #include <llvm-libc-decls/stdlib.h> -#if defined(__GLIBC__) && __cplusplus >= 201703L +#if defined(__GLIBC__) && __cplusplus >= 201103L #undef at_quick_exit #endif diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 31bc941..334438e 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -3178,6 +3178,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_align: case OMPC_message: case OMPC_ompx_dyn_cgroup_mem: + case OMPC_dyn_groupprivate: // OpenMP [2.5, Restrictions] // At most one num_threads clause can appear on the directive. // OpenMP [2.8.1, simd construct, Restrictions] @@ -3216,7 +3217,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, PP.LookAhead(/*N=*/0).isNot(tok::l_paren)) Clause = ParseOpenMPClause(CKind, WrongDirective); else if (CKind == OMPC_grainsize || CKind == OMPC_num_tasks || - CKind == OMPC_num_threads) + CKind == OMPC_num_threads || CKind == OMPC_dyn_groupprivate) Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective); else Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective); @@ -4009,6 +4010,83 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, Arg.push_back(OMPC_GRAINSIZE_unknown); KLoc.emplace_back(); } + } else if (Kind == OMPC_dyn_groupprivate) { + enum { SimpleModifier, ComplexModifier, NumberOfModifiers }; + Arg.resize(NumberOfModifiers); + KLoc.resize(NumberOfModifiers); + Arg[SimpleModifier] = OMPC_DYN_GROUPPRIVATE_unknown; + Arg[ComplexModifier] = OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown; + + auto ConsumeModifier = [&]() { + unsigned Type = NumberOfModifiers; + unsigned Modifier; + SourceLocation Loc; + if (!Tok.isAnnotation() && PP.getSpelling(Tok) == "fallback" && + NextToken().is(tok::l_paren)) { + ConsumeToken(); + BalancedDelimiterTracker ParenT(*this, tok::l_paren, tok::r_paren); + ParenT.consumeOpen(); + + Modifier = getOpenMPSimpleClauseType( + Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts()); + if (Modifier <= OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown || + Modifier >= OMPC_DYN_GROUPPRIVATE_FALLBACK_last) { + Diag(Tok.getLocation(), diag::err_expected) + << "'abort', 'null' or 'default_mem' in fallback modifier"; + SkipUntil(tok::r_paren); + return std::make_tuple(Type, Modifier, Loc); + } + Type = ComplexModifier; + Loc = Tok.getLocation(); + if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && + Tok.isNot(tok::annot_pragma_openmp_end)) + ConsumeAnyToken(); + ParenT.consumeClose(); + } else { + Modifier = getOpenMPSimpleClauseType( + Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts()); + if (Modifier < OMPC_DYN_GROUPPRIVATE_unknown) { + Type = SimpleModifier; + Loc = Tok.getLocation(); + if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && + Tok.isNot(tok::annot_pragma_openmp_end)) + ConsumeAnyToken(); + } + } + return std::make_tuple(Type, Modifier, Loc); + }; + + auto SaveModifier = [&](unsigned Type, unsigned Modifier, + SourceLocation Loc) { + assert(Type < NumberOfModifiers && "Unexpected modifier type"); + if (!KLoc[Type].isValid()) { + Arg[Type] = Modifier; + KLoc[Type] = Loc; + } else { + Diag(Loc, diag::err_omp_incompatible_dyn_groupprivate_modifier) + << getOpenMPSimpleClauseTypeName(OMPC_dyn_groupprivate, Modifier) + << getOpenMPSimpleClauseTypeName(OMPC_dyn_groupprivate, Arg[Type]); + } + }; + + // Parse 'modifier' + auto [Type1, Mod1, Loc1] = ConsumeModifier(); + if (Type1 < NumberOfModifiers) { + SaveModifier(Type1, Mod1, Loc1); + if (Tok.is(tok::comma)) { + // Parse ',' 'modifier' + ConsumeAnyToken(); + auto [Type2, Mod2, Loc2] = ConsumeModifier(); + if (Type2 < NumberOfModifiers) + SaveModifier(Type2, Mod2, Loc2); + } + // Parse ':' + if (Tok.is(tok::colon)) + ConsumeAnyToken(); + else + Diag(Tok, diag::warn_pragma_expected_colon) + << "dyn_groupprivate modifier"; + } } else if (Kind == OMPC_num_tasks) { // Parse optional <num_tasks modifier> ':' OpenMPNumTasksClauseModifier Modifier = @@ -4083,11 +4161,11 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, } } - bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) || - (Kind == OMPC_dist_schedule && DelimLoc.isValid()) || - Kind == OMPC_if || Kind == OMPC_device || - Kind == OMPC_grainsize || Kind == OMPC_num_tasks || - Kind == OMPC_num_threads; + bool NeedAnExpression = + (Kind == OMPC_schedule && DelimLoc.isValid()) || + (Kind == OMPC_dist_schedule && DelimLoc.isValid()) || Kind == OMPC_if || + Kind == OMPC_device || Kind == OMPC_grainsize || Kind == OMPC_num_tasks || + Kind == OMPC_num_threads || Kind == OMPC_dyn_groupprivate; if (NeedAnExpression) { SourceLocation ELoc = Tok.getLocation(); ExprResult LHS( diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 256f952..465dab2 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -16532,6 +16532,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, case OMPC_holds: Res = ActOnOpenMPHoldsClause(Expr, StartLoc, LParenLoc, EndLoc); break; + case OMPC_dyn_groupprivate: case OMPC_grainsize: case OMPC_num_tasks: case OMPC_num_threads: @@ -16658,6 +16659,8 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPC_num_teams: case OMPC_thread_limit: case OMPC_ompx_dyn_cgroup_mem: + case OMPC_dyn_groupprivate: + // TODO: This may need to consider teams too. if (Leafs[0] == OMPD_target) return OMPD_target; break; @@ -17705,7 +17708,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprWithArgClause( SourceLocation EndLoc) { OMPClause *Res = nullptr; switch (Kind) { - case OMPC_schedule: + case OMPC_schedule: { enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; assert(Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements); @@ -17716,6 +17719,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprWithArgClause( StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); break; + } case OMPC_if: assert(Argument.size() == 1 && ArgumentLoc.size() == 1); Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), @@ -17771,6 +17775,20 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprWithArgClause( static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr, StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); break; + case OMPC_dyn_groupprivate: { + enum { Modifier1, Modifier2, NumberOfElements }; + assert(Argument.size() == NumberOfElements && + ArgumentLoc.size() == NumberOfElements && + "Modifiers for dyn_groupprivate clause and their locations are " + "expected."); + Res = ActOnOpenMPDynGroupprivateClause( + static_cast<OpenMPDynGroupprivateClauseModifier>(Argument[Modifier1]), + static_cast<OpenMPDynGroupprivateClauseFallbackModifier>( + Argument[Modifier2]), + Expr, StartLoc, LParenLoc, ArgumentLoc[Modifier1], + ArgumentLoc[Modifier2], EndLoc); + break; + } case OMPC_num_threads: assert(Argument.size() == 1 && ArgumentLoc.size() == 1 && "Modifier for num_threads clause and its location are expected."); @@ -18127,6 +18145,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_affinity: case OMPC_when: case OMPC_ompx_dyn_cgroup_mem: + case OMPC_dyn_groupprivate: default: llvm_unreachable("Clause is not allowed."); } @@ -25246,6 +25265,49 @@ OMPClause *SemaOpenMP::ActOnOpenMPXDynCGroupMemClause(Expr *Size, ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); } +OMPClause *SemaOpenMP::ActOnOpenMPDynGroupprivateClause( + OpenMPDynGroupprivateClauseModifier M1, + OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, + SourceLocation M2Loc, SourceLocation EndLoc) { + + if ((M1Loc.isValid() && M1 == OMPC_DYN_GROUPPRIVATE_unknown) || + (M2Loc.isValid() && M2 == OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown)) { + std::string Values = getListOfPossibleValues( + OMPC_dyn_groupprivate, /*First=*/0, OMPC_DYN_GROUPPRIVATE_unknown); + Diag((M1Loc.isValid() && M1 == OMPC_DYN_GROUPPRIVATE_unknown) ? M1Loc + : M2Loc, + diag::err_omp_unexpected_clause_value) + << Values << getOpenMPClauseName(OMPC_dyn_groupprivate); + return nullptr; + } + + Expr *ValExpr = Size; + Stmt *HelperValStmt = nullptr; + + // OpenMP [2.5, Restrictions] + // The dyn_groupprivate expression must evaluate to a positive integer + // value. + if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_dyn_groupprivate, + /*StrictlyPositive=*/false)) + return nullptr; + + OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); + OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( + DKind, OMPC_dyn_groupprivate, getLangOpts().OpenMP); + if (CaptureRegion != OMPD_unknown && + !SemaRef.CurContext->isDependentContext()) { + ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); + llvm::MapVector<const Expr *, DeclRefExpr *> Captures; + ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); + HelperValStmt = buildPreInits(getASTContext(), Captures); + } + + return new (getASTContext()) OMPDynGroupprivateClause( + StartLoc, LParenLoc, EndLoc, ValExpr, HelperValStmt, CaptureRegion, M1, + M1Loc, M2, M2Loc); +} + OMPClause *SemaOpenMP::ActOnOpenMPDoacrossClause( OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 94105f1..c249148 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2463,6 +2463,19 @@ public: LParenLoc, EndLoc); } + /// Build a new OpenMP 'dyn_groupprivate' clause. + /// + /// By default, performs semantic analysis to build the new OpenMP clause. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPDynGroupprivateClause( + OpenMPDynGroupprivateClauseModifier M1, + OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, + SourceLocation M2Loc, SourceLocation EndLoc) { + return getSema().OpenMP().ActOnOpenMPDynGroupprivateClause( + M1, M2, Size, StartLoc, LParenLoc, M1Loc, M2Loc, EndLoc); + } + /// Build a new OpenMP 'ompx_attribute' clause. /// /// By default, performs semantic analysis to build the new OpenMP clause. @@ -11726,6 +11739,19 @@ OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause( } template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause( + OMPDynGroupprivateClause *C) { + ExprResult Size = getDerived().TransformExpr(C->getSize()); + if (Size.isInvalid()) + return nullptr; + return getDerived().RebuildOMPDynGroupprivateClause( + C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(), + Size.get(), C->getBeginLoc(), C->getLParenLoc(), + C->getDynGroupprivateModifierLoc(), + C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc()); +} + +template <typename Derived> OMPClause * TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) { llvm::SmallVector<Expr *, 16> Vars; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index d552821..a04041c 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11544,6 +11544,9 @@ OMPClause *OMPClauseReader::readClause() { case llvm::omp::OMPC_ompx_dyn_cgroup_mem: C = new (Context) OMPXDynCGroupMemClause(); break; + case llvm::omp::OMPC_dyn_groupprivate: + C = new (Context) OMPDynGroupprivateClause(); + break; case llvm::omp::OMPC_doacross: { unsigned NumVars = Record.readInt(); unsigned NumLoops = Record.readInt(); @@ -12736,6 +12739,19 @@ void OMPClauseReader::VisitOMPXDynCGroupMemClause(OMPXDynCGroupMemClause *C) { C->setLParenLoc(Record.readSourceLocation()); } +void OMPClauseReader::VisitOMPDynGroupprivateClause( + OMPDynGroupprivateClause *C) { + VisitOMPClauseWithPreInit(C); + C->setDynGroupprivateModifier( + Record.readEnum<OpenMPDynGroupprivateClauseModifier>()); + C->setDynGroupprivateFallbackModifier( + Record.readEnum<OpenMPDynGroupprivateClauseFallbackModifier>()); + C->setSize(Record.readSubExpr()); + C->setLParenLoc(Record.readSourceLocation()); + C->setDynGroupprivateModifierLoc(Record.readSourceLocation()); + C->setDynGroupprivateFallbackModifierLoc(Record.readSourceLocation()); +} + void OMPClauseReader::VisitOMPDoacrossClause(OMPDoacrossClause *C) { C->setLParenLoc(Record.readSourceLocation()); C->setDependenceType( diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index b1fd151..821e7df 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -8651,6 +8651,17 @@ void OMPClauseWriter::VisitOMPXDynCGroupMemClause(OMPXDynCGroupMemClause *C) { Record.AddSourceLocation(C->getLParenLoc()); } +void OMPClauseWriter::VisitOMPDynGroupprivateClause( + OMPDynGroupprivateClause *C) { + VisitOMPClauseWithPreInit(C); + Record.push_back(C->getDynGroupprivateModifier()); + Record.push_back(C->getDynGroupprivateFallbackModifier()); + Record.AddStmt(C->getSize()); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getDynGroupprivateModifierLoc()); + Record.AddSourceLocation(C->getDynGroupprivateFallbackModifierLoc()); +} + void OMPClauseWriter::VisitOMPDoacrossClause(OMPDoacrossClause *C) { Record.push_back(C->varlist_size()); Record.push_back(C->getNumLoops()); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp index eebecdb..4178d1f 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp @@ -1,4 +1,4 @@ -//===- DependencyScanner.cpp - Performs module dependency scanning --------===// +//===- DependencyScannerImpl.cpp - Implements module dependency scanning --===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -12,6 +12,7 @@ #include "clang/Driver/Driver.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/TargetParser/Host.h" using namespace clang; @@ -456,7 +457,8 @@ initVFSForTUBuferScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS, return std::make_pair(ModifiedFS, ModifiedCommandLine); } -std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>> +std::pair<IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>, + std::vector<std::string>> initVFSForByNameScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS, ArrayRef<std::string> CommandLine, StringRef WorkingDirectory, StringRef ModuleName) { @@ -588,7 +590,7 @@ computePrebuiltModulesASTMap(CompilerInstance &ScanInstance, } std::unique_ptr<DependencyOutputOptions> -takeDependencyOutputOptionsFrom(CompilerInstance &ScanInstance) { +takeAndUpdateDependencyOutputOptionsFrom(CompilerInstance &ScanInstance) { // This function moves the existing dependency output options from the // invocation to the collector. The options in the invocation are reset, // which ensures that the compiler won't create new dependency collectors, @@ -675,7 +677,7 @@ bool DependencyScanningAction::runInvocation( if (!MaybePrebuiltModulesASTMap) return false; - auto DepOutputOpts = takeDependencyOutputOptionsFrom(ScanInstance); + auto DepOutputOpts = takeAndUpdateDependencyOutputOptionsFrom(ScanInstance); MDC = initializeScanInstanceDependencyCollector( ScanInstance, std::move(DepOutputOpts), WorkingDirectory, Consumer, @@ -686,8 +688,6 @@ bool DependencyScanningAction::runInvocation( if (Service.getFormat() == ScanningOutputFormat::P1689) Action = std::make_unique<PreprocessOnlyAction>(); - else if (ModuleName) - Action = std::make_unique<GetDependenciesByModuleNameAction>(*ModuleName); else Action = std::make_unique<ReadPCHAndPreprocessAction>(); @@ -704,3 +704,175 @@ bool DependencyScanningAction::runInvocation( return Result; } + +bool CompilerInstanceWithContext::initialize(DiagnosticConsumer *DC) { + if (DC) { + DiagConsumer = DC; + } else { + DiagPrinterWithOS = + std::make_unique<TextDiagnosticsPrinterWithOutput>(CommandLine); + DiagConsumer = &DiagPrinterWithOS->DiagPrinter; + } + + std::tie(OverlayFS, CommandLine) = initVFSForByNameScanning( + Worker.BaseFS, CommandLine, CWD, "ScanningByName"); + + DiagEngineWithCmdAndOpts = std::make_unique<DignosticsEngineWithDiagOpts>( + CommandLine, OverlayFS, *DiagConsumer); + + std::tie(Driver, Compilation) = buildCompilation( + CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine, OverlayFS, Alloc); + + if (!Compilation) + return false; + + assert(Compilation->getJobs().size() && + "Must have a job list of non-zero size"); + const driver::Command &Command = *(Compilation->getJobs().begin()); + const auto &CommandArgs = Command.getArguments(); + assert(!CommandArgs.empty() && "Cannot have a command with 0 args"); + assert(StringRef(CommandArgs[0]) == "-cc1" && "Requires a cc1 job."); + OriginalInvocation = std::make_unique<CompilerInvocation>(); + + if (!CompilerInvocation::CreateFromArgs(*OriginalInvocation, CommandArgs, + *DiagEngineWithCmdAndOpts->DiagEngine, + Command.getExecutable())) { + DiagEngineWithCmdAndOpts->DiagEngine->Report( + diag::err_fe_expected_compiler_job) + << llvm::join(CommandLine, " "); + return false; + } + + if (any(Worker.Service.getOptimizeArgs() & ScanningOptimizations::Macros)) + canonicalizeDefines(OriginalInvocation->getPreprocessorOpts()); + + // Create the CompilerInstance. + IntrusiveRefCntPtr<ModuleCache> ModCache = + makeInProcessModuleCache(Worker.Service.getModuleCacheEntries()); + CIPtr = std::make_unique<CompilerInstance>( + std::make_shared<CompilerInvocation>(*OriginalInvocation), + Worker.PCHContainerOps, ModCache.get()); + auto &CI = *CIPtr; + + if (!initializeScanCompilerInstance( + CI, OverlayFS, DiagEngineWithCmdAndOpts->DiagEngine->getClient(), + Worker.Service, Worker.DepFS)) + return false; + + StableDirs = getInitialStableDirs(CI); + auto MaybePrebuiltModulesASTMap = + computePrebuiltModulesASTMap(CI, StableDirs); + if (!MaybePrebuiltModulesASTMap) + return false; + + PrebuiltModuleASTMap = std::move(*MaybePrebuiltModulesASTMap); + OutputOpts = takeAndUpdateDependencyOutputOptionsFrom(CI); + + // We do not create the target in initializeScanCompilerInstance because + // setting it here is unique for by-name lookups. We create the target only + // once here, and the information is reused for all computeDependencies calls. + // We do not need to call createTarget explicitly if we go through + // CompilerInstance::ExecuteAction to perform scanning. + CI.createTarget(); + + return true; +} + +bool CompilerInstanceWithContext::computeDependencies( + StringRef ModuleName, DependencyConsumer &Consumer, + DependencyActionController &Controller) { + assert(CIPtr && "CIPtr must be initialized before calling this method"); + auto &CI = *CIPtr; + + // We create this cleanup object because computeDependencies may exit + // early with errors. + auto CleanUp = llvm::make_scope_exit([&]() { + CI.clearDependencyCollectors(); + // The preprocessor may not be created at the entry of this method, + // but it must have been created when this method returns, whether + // there are errors during scanning or not. + CI.getPreprocessor().removePPCallbacks(); + }); + + auto MDC = initializeScanInstanceDependencyCollector( + CI, std::make_unique<DependencyOutputOptions>(*OutputOpts), CWD, Consumer, + Worker.Service, + /* The MDC's constructor makes a copy of the OriginalInvocation, so + we can pass it in without worrying that it might be changed across + invocations of computeDependencies. */ + *OriginalInvocation, Controller, PrebuiltModuleASTMap, StableDirs); + + if (!SrcLocOffset) { + // When SrcLocOffset is zero, we are at the beginning of the fake source + // file. In this case, we call BeginSourceFile to initialize. + std::unique_ptr<FrontendAction> Action = + std::make_unique<PreprocessOnlyAction>(); + auto InputFile = CI.getFrontendOpts().Inputs.begin(); + bool ActionBeginSucceeded = Action->BeginSourceFile(CI, *InputFile); + assert(ActionBeginSucceeded && "Action BeginSourceFile must succeed"); + (void)ActionBeginSucceeded; + } + + Preprocessor &PP = CI.getPreprocessor(); + SourceManager &SM = PP.getSourceManager(); + FileID MainFileID = SM.getMainFileID(); + SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID); + SourceLocation IDLocation = FileStart.getLocWithOffset(SrcLocOffset); + PPCallbacks *CB = nullptr; + if (!SrcLocOffset) { + // We need to call EnterSourceFile when SrcLocOffset is zero to initialize + // the preprocessor. + bool PPFailed = PP.EnterSourceFile(MainFileID, nullptr, SourceLocation()); + assert(!PPFailed && "Preprocess must be able to enter the main file."); + (void)PPFailed; + CB = MDC->getPPCallbacks(); + } else { + // When SrcLocOffset is non-zero, the preprocessor has already been + // initialized through a previous call of computeDependencies. We want to + // preserve the PP's state, hence we do not call EnterSourceFile again. + MDC->attachToPreprocessor(PP); + CB = MDC->getPPCallbacks(); + + FileID PrevFID; + SrcMgr::CharacteristicKind FileType = SM.getFileCharacteristic(IDLocation); + CB->LexedFileChanged(MainFileID, + PPChainedCallbacks::LexedFileChangeReason::EnterFile, + FileType, PrevFID, IDLocation); + } + + SrcLocOffset++; + SmallVector<IdentifierLoc, 2> Path; + IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName); + Path.emplace_back(IDLocation, ModuleID); + auto ModResult = CI.loadModule(IDLocation, Path, Module::Hidden, false); + + assert(CB && "Must have PPCallbacks after module loading"); + CB->moduleImport(SourceLocation(), Path, ModResult); + // Note that we are calling the CB's EndOfMainFile function, which + // forwards the results to the dependency consumer. + // It does not indicate the end of processing the fake file. + CB->EndOfMainFile(); + + if (!ModResult) + return false; + + CompilerInvocation ModuleInvocation(*OriginalInvocation); + MDC->applyDiscoveredDependencies(ModuleInvocation); + Consumer.handleBuildCommand( + {CommandLine[0], ModuleInvocation.getCC1CommandLine()}); + + return true; +} + +bool CompilerInstanceWithContext::finalize() { + DiagConsumer->finish(); + return true; +} + +llvm::Error CompilerInstanceWithContext::handleReturnStatus(bool Success) { + assert(DiagPrinterWithOS && "Must use the default DiagnosticConsumer."); + return Success ? llvm::Error::success() + : llvm::make_error<llvm::StringError>( + DiagPrinterWithOS->DiagnosticsOS.str(), + llvm::inconvertibleErrorCode()); +} diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.h b/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.h index 5657317..54166da 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.h +++ b/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.h @@ -1,4 +1,4 @@ -//===- DependencyScanner.h - Performs module dependency scanning *- C++ -*-===// +//===- DependencyScannerImpl.h - Implements dependency scanning *- C++ -*--===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,6 +23,8 @@ class DiagnosticConsumer; namespace tooling { namespace dependencies { class DependencyScanningService; +class DependencyScanningWorker; + class DependencyConsumer; class DependencyActionController; class DependencyScanningWorkerFilesystem; @@ -35,8 +37,7 @@ public: IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS, std::optional<StringRef> ModuleName = std::nullopt) : Service(Service), WorkingDirectory(WorkingDirectory), - Consumer(Consumer), Controller(Controller), DepFS(std::move(DepFS)), - ModuleName(ModuleName) {} + Consumer(Consumer), Controller(Controller), DepFS(std::move(DepFS)) {} bool runInvocation(std::unique_ptr<CompilerInvocation> Invocation, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, std::shared_ptr<PCHContainerOperations> PCHContainerOps, @@ -66,7 +67,6 @@ private: DependencyConsumer &Consumer; DependencyActionController &Controller; IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS; - std::optional<StringRef> ModuleName; std::optional<CompilerInstance> ScanInstanceStorage; std::shared_ptr<ModuleDepCollector> MDC; std::vector<std::string> LastCC1Arguments; @@ -118,7 +118,8 @@ initVFSForTUBuferScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS, StringRef WorkingDirectory, llvm::MemoryBufferRef TUBuffer); -std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>> +std::pair<IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>, + std::vector<std::string>> initVFSForByNameScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS, ArrayRef<std::string> CommandLine, StringRef WorkingDirectory, StringRef ModuleName); @@ -137,7 +138,7 @@ computePrebuiltModulesASTMap(CompilerInstance &ScanInstance, SmallVector<StringRef> &StableDirs); std::unique_ptr<DependencyOutputOptions> -takeDependencyOutputOptionsFrom(CompilerInstance &ScanInstance); +takeAndUpdateDependencyOutputOptionsFrom(CompilerInstance &ScanInstance); /// Create the dependency collector that will collect the produced /// dependencies. May return the created ModuleDepCollector depending @@ -150,6 +151,60 @@ std::shared_ptr<ModuleDepCollector> initializeScanInstanceDependencyCollector( DependencyActionController &Controller, PrebuiltModulesAttrsMap PrebuiltModulesASTMap, llvm::SmallVector<StringRef> &StableDirs); + +class CompilerInstanceWithContext { + // Context + DependencyScanningWorker &Worker; + llvm::StringRef CWD; + std::vector<std::string> CommandLine; + + // Context - file systems + llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS; + + // Context - Diagnostics engine. + std::unique_ptr<TextDiagnosticsPrinterWithOutput> DiagPrinterWithOS; + // DiagConsumer may points to DiagPrinterWithOS->DiagPrinter, or a custom + // DiagnosticConsumer passed in from initialize. + DiagnosticConsumer *DiagConsumer = nullptr; + std::unique_ptr<DignosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts; + + // Context - compiler invocation + // Compilation's command's arguments may be owned by Alloc when expanded from + // response files, so we need to keep Alloc alive in the context. + llvm::BumpPtrAllocator Alloc; + std::unique_ptr<clang::driver::Driver> Driver; + std::unique_ptr<clang::driver::Compilation> Compilation; + std::unique_ptr<CompilerInvocation> OriginalInvocation; + + // Context - output options + std::unique_ptr<DependencyOutputOptions> OutputOpts; + + // Context - stable directory handling + llvm::SmallVector<StringRef> StableDirs; + PrebuiltModulesAttrsMap PrebuiltModuleASTMap; + + // Compiler Instance + std::unique_ptr<CompilerInstance> CIPtr; + + // Source location offset. + int32_t SrcLocOffset = 0; + +public: + CompilerInstanceWithContext(DependencyScanningWorker &Worker, StringRef CWD, + const std::vector<std::string> &CMD) + : Worker(Worker), CWD(CWD), CommandLine(CMD) {}; + + // The three methods below returns false when they fail, with the detail + // accumulated in DiagConsumer. + bool initialize(DiagnosticConsumer *DC); + bool computeDependencies(StringRef ModuleName, DependencyConsumer &Consumer, + DependencyActionController &Controller); + bool finalize(); + + // The method below turns the return status from the above methods + // into an llvm::Error using a default DiagnosticConsumer. + llvm::Error handleReturnStatus(bool Success); +}; } // namespace dependencies } // namespace tooling } // namespace clang diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp index 27734ff..a1f2db7 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp @@ -162,13 +162,45 @@ DependencyScanningTool::getModuleDependencies( LookupModuleOutputCallback LookupModuleOutput) { FullDependencyConsumer Consumer(AlreadySeen); CallbackActionController Controller(LookupModuleOutput); - llvm::Error Result = Worker.computeDependencies(CWD, CommandLine, Consumer, - Controller, ModuleName); + if (auto Error = + Worker.initializeCompilerInstanceWithContextOrError(CWD, CommandLine)) + return std::move(Error); + + auto Result = Worker.computeDependenciesByNameWithContextOrError( + ModuleName, Consumer, Controller); + + if (auto Error = Worker.finalizeCompilerInstanceWithContextOrError()) + return std::move(Error); + if (Result) return std::move(Result); + return Consumer.takeTranslationUnitDeps(); } +llvm::Error DependencyScanningTool::initializeCompilerInstanceWithContext( + StringRef CWD, const std::vector<std::string> &CommandLine) { + return Worker.initializeCompilerInstanceWithContextOrError(CWD, CommandLine); +} + +llvm::Expected<TranslationUnitDeps> +DependencyScanningTool::computeDependenciesByNameWithContext( + StringRef ModuleName, const llvm::DenseSet<ModuleID> &AlreadySeen, + LookupModuleOutputCallback LookupModuleOutput) { + FullDependencyConsumer Consumer(AlreadySeen); + CallbackActionController Controller(LookupModuleOutput); + llvm::Error Result = Worker.computeDependenciesByNameWithContextOrError( + ModuleName, Consumer, Controller); + if (Result) + return std::move(Result); + + return Consumer.takeTranslationUnitDeps(); +} + +llvm::Error DependencyScanningTool::finalizeCompilerInstanceWithContext() { + return Worker.finalizeCompilerInstanceWithContextOrError(); +} + TranslationUnitDeps FullDependencyConsumer::takeTranslationUnitDeps() { TranslationUnitDeps TU; diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 0a1cf6b..dc408b1 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -43,6 +43,9 @@ DependencyScanningWorker::DependencyScanningWorker( } } +DependencyScanningWorker::~DependencyScanningWorker() = default; +DependencyActionController::~DependencyActionController() = default; + llvm::Error DependencyScanningWorker::computeDependencies( StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, DependencyConsumer &Consumer, DependencyActionController &Controller, @@ -58,21 +61,6 @@ llvm::Error DependencyScanningWorker::computeDependencies( DiagPrinterWithOS.DiagnosticsOS.str(), llvm::inconvertibleErrorCode()); } -llvm::Error DependencyScanningWorker::computeDependencies( - StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, - DependencyConsumer &Consumer, DependencyActionController &Controller, - StringRef ModuleName) { - // Capture the emitted diagnostics and report them to the client - // in the case of a failure. - TextDiagnosticsPrinterWithOutput DiagPrinterWithOS(CommandLine); - - if (computeDependencies(WorkingDirectory, CommandLine, Consumer, Controller, - DiagPrinterWithOS.DiagPrinter, ModuleName)) - return llvm::Error::success(); - return llvm::make_error<llvm::StringError>( - DiagPrinterWithOS.DiagnosticsOS.str(), llvm::inconvertibleErrorCode()); -} - static bool forEachDriverJob( ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, @@ -113,11 +101,11 @@ static bool createAndRunToolInvocation( bool DependencyScanningWorker::scanDependencies( StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, DependencyConsumer &Consumer, DependencyActionController &Controller, - DiagnosticConsumer &DC, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, - std::optional<StringRef> ModuleName) { + DiagnosticConsumer &DC, + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) { DignosticsEngineWithDiagOpts DiagEngineWithCmdAndOpts(CommandLine, FS, DC); DependencyScanningAction Action(Service, WorkingDirectory, Consumer, - Controller, DepFS, ModuleName); + Controller, DepFS); bool Success = false; if (CommandLine[1] == "-cc1") { @@ -172,24 +160,51 @@ bool DependencyScanningWorker::computeDependencies( auto [FinalFS, FinalCommandLine] = initVFSForTUBuferScanning( BaseFS, CommandLine, WorkingDirectory, *TUBuffer); return scanDependencies(WorkingDirectory, FinalCommandLine, Consumer, - Controller, DC, FinalFS, - /*ModuleName=*/std::nullopt); + Controller, DC, FinalFS); } else { BaseFS->setCurrentWorkingDirectory(WorkingDirectory); return scanDependencies(WorkingDirectory, CommandLine, Consumer, Controller, - DC, BaseFS, /*ModuleName=*/std::nullopt); + DC, BaseFS); } } -bool DependencyScanningWorker::computeDependencies( - StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, - DependencyConsumer &Consumer, DependencyActionController &Controller, - DiagnosticConsumer &DC, StringRef ModuleName) { - auto [OverlayFS, ModifiedCommandLine] = initVFSForByNameScanning( - BaseFS, CommandLine, WorkingDirectory, ModuleName); +llvm::Error +DependencyScanningWorker::initializeCompilerInstanceWithContextOrError( + StringRef CWD, const std::vector<std::string> &CommandLine) { + bool Success = initializeCompilerInstanceWithContext(CWD, CommandLine); + return CIWithContext->handleReturnStatus(Success); +} + +llvm::Error +DependencyScanningWorker::computeDependenciesByNameWithContextOrError( + StringRef ModuleName, DependencyConsumer &Consumer, + DependencyActionController &Controller) { + bool Success = + computeDependenciesByNameWithContext(ModuleName, Consumer, Controller); + return CIWithContext->handleReturnStatus(Success); +} + +llvm::Error +DependencyScanningWorker::finalizeCompilerInstanceWithContextOrError() { + bool Success = finalizeCompilerInstance(); + return CIWithContext->handleReturnStatus(Success); +} - return scanDependencies(WorkingDirectory, ModifiedCommandLine, Consumer, - Controller, DC, OverlayFS, ModuleName); +bool DependencyScanningWorker::initializeCompilerInstanceWithContext( + StringRef CWD, const std::vector<std::string> &CommandLine, + DiagnosticConsumer *DC) { + CIWithContext = + std::make_unique<CompilerInstanceWithContext>(*this, CWD, CommandLine); + return CIWithContext->initialize(DC); } -DependencyActionController::~DependencyActionController() {} +bool DependencyScanningWorker::computeDependenciesByNameWithContext( + StringRef ModuleName, DependencyConsumer &Consumer, + DependencyActionController &Controller) { + assert(CIWithContext && "CompilerInstance with context required!"); + return CIWithContext->computeDependencies(ModuleName, Consumer, Controller); +} + +bool DependencyScanningWorker::finalizeCompilerInstance() { + return CIWithContext->finalize(); +} diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index a117bec..e07a208 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -965,7 +965,9 @@ ModuleDepCollector::ModuleDepCollector( makeCommonInvocationForModuleBuild(std::move(OriginalCI))) {} void ModuleDepCollector::attachToPreprocessor(Preprocessor &PP) { - PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(*this)); + auto CollectorPP = std::make_unique<ModuleDepCollectorPP>(*this); + CollectorPPPtr = CollectorPP.get(); + PP.addPPCallbacks(std::move(CollectorPP)); } void ModuleDepCollector::attachToASTReader(ASTReader &R) {} |
