aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp18
-rw-r--r--clang/lib/AST/ByteCode/Interp.cpp80
-rw-r--r--clang/lib/AST/ByteCode/Interp.h1
-rw-r--r--clang/lib/AST/ByteCode/Opcodes.td3
-rw-r--r--clang/lib/AST/OpenMPClause.cpp20
-rw-r--r--clang/lib/AST/StmtProfile.cpp6
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp24
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenStmt.cpp2
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp5
-rw-r--r--clang/lib/CodeGen/TargetBuiltins/ARM.cpp32
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp24
-rw-r--r--clang/lib/Format/Format.cpp12
-rw-r--r--clang/lib/Format/WhitespaceManager.cpp18
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp14
-rw-r--r--clang/lib/Headers/llvm_libc_wrappers/stdlib.h4
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp90
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp64
-rw-r--r--clang/lib/Sema/TreeTransform.h26
-rw-r--r--clang/lib/Serialization/ASTReader.cpp16
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp11
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp184
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.h67
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp36
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp75
-rw-r--r--clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp4
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) {}