aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/APValue.cpp2
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp12
-rw-r--r--clang/lib/AST/Decl.cpp47
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp2
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp9
-rw-r--r--clang/lib/AST/StmtProfile.cpp8
-rw-r--r--clang/lib/AST/TextNodeDumper.cpp3
-rw-r--r--clang/lib/AST/TypePrinter.cpp3
-rw-r--r--clang/lib/Analysis/CFG.cpp7
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp36
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenDecl.cpp22
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp3
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp64
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp6
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.cpp2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.h28
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp37
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp168
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h28
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp23
-rw-r--r--clang/lib/CIR/Dialect/IR/CIRDialect.cpp11
-rw-r--r--clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp9
-rw-r--r--clang/lib/CodeGen/CGAtomic.cpp2
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp56
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp2
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp2
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp2
-rw-r--r--clang/lib/CodeGen/CGRecordLayoutBuilder.cpp12
-rw-r--r--clang/lib/CodeGen/Targets/SPIR.cpp6
-rw-r--r--clang/lib/CodeGen/Targets/X86.cpp5
-rw-r--r--clang/lib/Driver/ToolChains/Flang.cpp3
-rw-r--r--clang/lib/Driver/ToolChains/HLSL.cpp2
-rw-r--r--clang/lib/ExtractAPI/ExtractAPIConsumer.cpp3
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp50
-rw-r--r--clang/lib/Format/Format.cpp2
-rw-r--r--clang/lib/Format/FormatToken.cpp4
-rw-r--r--clang/lib/Format/FormatToken.h5
-rw-r--r--clang/lib/Format/FormatTokenLexer.cpp4
-rw-r--r--clang/lib/Format/MacroExpander.cpp2
-rw-r--r--clang/lib/Format/NamespaceEndCommentsFixer.cpp4
-rw-r--r--clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp2
-rw-r--r--clang/lib/Format/QualifierAlignmentFixer.cpp2
-rw-r--r--clang/lib/Format/SortJavaScriptImports.cpp4
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp106
-rw-r--r--clang/lib/Format/UnwrappedLineFormatter.cpp6
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp42
-rw-r--r--clang/lib/Format/WhitespaceManager.cpp2
-rw-r--r--clang/lib/Frontend/ChainedIncludesSource.cpp2
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp13
-rw-r--r--clang/lib/Frontend/FrontendAction.cpp11
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp4
-rw-r--r--clang/lib/Parse/ParseDecl.cpp3
-rw-r--r--clang/lib/Parse/ParseHLSLRootSignature.cpp61
-rw-r--r--clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp110
-rw-r--r--clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h16
-rw-r--r--clang/lib/Sema/HLSLExternalSemaSource.cpp26
-rw-r--r--clang/lib/Sema/SemaChecking.cpp25
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--clang/lib/Sema/SemaExpr.cpp7
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp4
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp11
-rw-r--r--clang/lib/Sema/SemaOpenACC.cpp30
-rw-r--r--clang/lib/Sema/SemaTemplateDeductionGuide.cpp9
-rw-r--r--clang/lib/Serialization/ASTReader.cpp15
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp9
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Core/CallEvent.cpp31
-rw-r--r--clang/lib/StaticAnalyzer/Core/RegionStore.cpp10
-rw-r--r--clang/lib/StaticAnalyzer/Core/Store.cpp2
-rw-r--r--clang/lib/Testing/TestAST.cpp2
-rw-r--r--clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp13
-rw-r--r--clang/lib/Tooling/Tooling.cpp2
73 files changed, 788 insertions, 496 deletions
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index 7173c2a..2e1c8eb 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -784,7 +784,7 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,
if (!O.isZero()) {
if (IsReference)
Out << "*(";
- if (S.isZero() || O % S) {
+ if (S.isZero() || !O.isMultipleOf(S)) {
Out << "(char*)";
S = CharUnits::One();
}
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 0b7b6cd..c71fd22 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -540,7 +540,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
if (const auto *IL = dyn_cast<IntegerLiteral>(SubExpr)) {
if (ToT != PT_IntAP && ToT != PT_IntAPS && FromT != PT_IntAP &&
FromT != PT_IntAPS && !CE->getType()->isEnumeralType())
- return this->emitConst(IL->getValue(), CE);
+ return this->emitConst(APSInt(IL->getValue(), !isSignedType(*FromT)),
+ CE);
if (!this->emitConst(IL->getValue(), SubExpr))
return false;
} else {
@@ -4541,7 +4542,14 @@ bool Compiler<Emitter>::emitConst(T Value, const Expr *E) {
template <class Emitter>
bool Compiler<Emitter>::emitConst(const APSInt &Value, PrimType Ty,
const Expr *E) {
- return this->emitConst(static_cast<const APInt &>(Value), Ty, E);
+ if (Ty == PT_IntAPS)
+ return this->emitConstIntAPS(Value, E);
+ if (Ty == PT_IntAP)
+ return this->emitConstIntAP(Value, E);
+
+ if (Value.isSigned())
+ return this->emitConst(Value.getSExtValue(), Ty, E);
+ return this->emitConst(Value.getZExtValue(), Ty, E);
}
template <class Emitter>
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index cd8e495..c734155 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3552,6 +3552,53 @@ void FunctionDecl::setIsTypeAwareOperatorNewOrDelete(bool IsTypeAware) {
getASTContext().setIsTypeAwareOperatorNewOrDelete(this, IsTypeAware);
}
+UsualDeleteParams FunctionDecl::getUsualDeleteParams() const {
+ UsualDeleteParams Params;
+
+ // This function should only be called for operator delete declarations.
+ assert(getDeclName().isAnyOperatorDelete());
+ if (!getDeclName().isAnyOperatorDelete())
+ return Params;
+
+ const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
+ auto AI = FPT->param_type_begin(), AE = FPT->param_type_end();
+
+ if (isTypeAwareOperatorNewOrDelete()) {
+ Params.TypeAwareDelete = TypeAwareAllocationMode::Yes;
+ assert(AI != AE);
+ ++AI;
+ }
+
+ // The first argument after the type-identity parameter (if any) is
+ // always a void* (or C* for a destroying operator delete for class
+ // type C).
+ ++AI;
+
+ // The next parameter may be a std::destroying_delete_t.
+ if (isDestroyingOperatorDelete()) {
+ assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
+ Params.DestroyingDelete = true;
+ assert(AI != AE);
+ ++AI;
+ }
+
+ // Figure out what other parameters we should be implicitly passing.
+ if (AI != AE && (*AI)->isIntegerType()) {
+ Params.Size = true;
+ ++AI;
+ } else
+ assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
+
+ if (AI != AE && (*AI)->isAlignValT()) {
+ Params.Alignment = AlignedAllocationMode::Yes;
+ ++AI;
+ } else
+ assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
+
+ assert(AI == AE && "unexpected usual deallocation function parameter");
+ return Params;
+}
+
LanguageLinkage FunctionDecl::getLanguageLinkage() const {
return getDeclLanguageLinkage(*this);
}
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 2173aed..844db79 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4624,6 +4624,8 @@ void CXXNameMangler::mangleType(const HLSLAttributedResourceType *T) {
Str += "_ROV";
if (Attrs.RawBuffer)
Str += "_Raw";
+ if (Attrs.IsCounter)
+ Str += "_Counter";
if (T->hasContainedType())
Str += "_CT";
mangleVendorQualifier(Str);
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 43f4e07..00b938b 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2087,9 +2087,8 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
if (InsertExtraPadding) {
CharUnits ASanAlignment = CharUnits::fromQuantity(8);
CharUnits ExtraSizeForAsan = ASanAlignment;
- if (FieldSize % ASanAlignment)
- ExtraSizeForAsan +=
- ASanAlignment - CharUnits::fromQuantity(FieldSize % ASanAlignment);
+ if (!FieldSize.isMultipleOf(ASanAlignment))
+ ExtraSizeForAsan += ASanAlignment - (FieldSize % ASanAlignment);
EffectiveFieldSize = FieldSize = FieldSize + ExtraSizeForAsan;
}
@@ -2119,10 +2118,10 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
if (RD->hasAttr<PackedAttr>() || !MaxFieldAlignment.isZero())
if (FieldAlign < OriginalFieldAlign)
if (D->getType()->isRecordType()) {
- // If the offset is a multiple of the alignment of
+ // If the offset is not a multiple of the alignment of
// the type, raise the warning.
// TODO: Takes no account the alignment of the outer struct
- if (FieldOffset % OriginalFieldAlign != 0)
+ if (!FieldOffset.isMultipleOf(OriginalFieldAlign))
Diag(D->getLocation(), diag::warn_unaligned_access)
<< Context.getCanonicalTagType(RD) << D->getName()
<< D->getType();
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 589a156..f3b5478 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2655,8 +2655,6 @@ void OpenACCClauseProfiler::VisitPrivateClause(
for (auto &Recipe : Clause.getInitRecipes()) {
Profiler.VisitDecl(Recipe.AllocaDecl);
- if (Recipe.InitExpr)
- Profiler.VisitExpr(Recipe.InitExpr);
}
}
@@ -2666,8 +2664,6 @@ void OpenACCClauseProfiler::VisitFirstPrivateClause(
for (auto &Recipe : Clause.getInitRecipes()) {
Profiler.VisitDecl(Recipe.AllocaDecl);
- if (Recipe.InitExpr)
- Profiler.VisitExpr(Recipe.InitExpr);
Profiler.VisitDecl(Recipe.InitFromTemporary);
}
}
@@ -2773,12 +2769,10 @@ void OpenACCClauseProfiler::VisitReductionClause(
for (auto &Recipe : Clause.getRecipes()) {
Profiler.VisitDecl(Recipe.AllocaDecl);
- if (Recipe.InitExpr)
- Profiler.VisitExpr(Recipe.InitExpr);
// TODO: OpenACC: Make sure we remember to update this when we figure out
// what we're adding for the operation recipe, in the meantime, a static
// assert will make sure we don't add something.
- static_assert(sizeof(OpenACCReductionRecipe) == 2 * sizeof(int *));
+ static_assert(sizeof(OpenACCReductionRecipe) == sizeof(int *));
}
}
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 8f7fe3b..cf5e914 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -3095,6 +3095,9 @@ void TextNodeDumper::VisitHLSLRootSignatureDecl(
case llvm::dxbc::RootSignatureVersion::V1_1:
OS << "1.1";
break;
+ case llvm::dxbc::RootSignatureVersion::V1_2:
+ OS << "1.2";
+ break;
}
OS << ", ";
llvm::hlsl::rootsig::dumpRootElements(OS, D->getRootElements());
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index f3448af..66a1b68 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2062,6 +2062,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case attr::HLSLROV:
case attr::HLSLRawBuffer:
case attr::HLSLContainedType:
+ case attr::HLSLIsCounter:
llvm_unreachable("HLSL resource type attributes handled separately");
case attr::OpenCLPrivateAddressSpace:
@@ -2210,6 +2211,8 @@ void TypePrinter::printHLSLAttributedResourceAfter(
OS << " [[hlsl::is_rov]]";
if (Attrs.RawBuffer)
OS << " [[hlsl::raw_buffer]]";
+ if (Attrs.IsCounter)
+ OS << " [[hlsl::is_counter]]";
QualType ContainedTy = T->getContainedType();
if (!ContainedTy.isNull()) {
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 60a2d11..cdde849 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -4516,10 +4516,13 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) {
//
// Note: We add a successor to a switch that is considered covered yet has no
// case statements if the enumeration has no enumerators.
+ // We also consider this successor reachable if
+ // BuildOpts.SwitchReqDefaultCoveredEnum is true.
bool SwitchAlwaysHasSuccessor = false;
SwitchAlwaysHasSuccessor |= switchExclusivelyCovered;
- SwitchAlwaysHasSuccessor |= Terminator->isAllEnumCasesCovered() &&
- Terminator->getSwitchCaseList();
+ SwitchAlwaysHasSuccessor |=
+ !BuildOpts.AssumeReachableDefaultInSwitchStatements &&
+ Terminator->isAllEnumCasesCovered() && Terminator->getSwitchCaseList();
addSuccessor(SwitchTerminatedBlock, DefaultCaseBlock,
!SwitchAlwaysHasSuccessor);
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index d19f86a..a56fdb1 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -419,22 +419,28 @@ public:
// The expression for this variable, OR
const Expr *Exp = nullptr;
- // Reference to another VarDefinition
- unsigned Ref = 0;
+ // Direct reference to another VarDefinition
+ unsigned DirectRef = 0;
+
+ // Reference to underlying canonical non-reference VarDefinition.
+ unsigned CanonicalRef = 0;
// The map with which Exp should be interpreted.
Context Ctx;
bool isReference() const { return !Exp; }
+ void invalidateRef() { DirectRef = CanonicalRef = 0; }
+
private:
// Create ordinary variable definition
VarDefinition(const NamedDecl *D, const Expr *E, Context C)
: Dec(D), Exp(E), Ctx(C) {}
// Create reference to previous definition
- VarDefinition(const NamedDecl *D, unsigned R, Context C)
- : Dec(D), Ref(R), Ctx(C) {}
+ VarDefinition(const NamedDecl *D, unsigned DirectRef, unsigned CanonicalRef,
+ Context C)
+ : Dec(D), DirectRef(DirectRef), CanonicalRef(CanonicalRef), Ctx(C) {}
};
private:
@@ -445,7 +451,7 @@ private:
public:
LocalVariableMap() {
// index 0 is a placeholder for undefined variables (aka phi-nodes).
- VarDefinitions.push_back(VarDefinition(nullptr, 0u, getEmptyContext()));
+ VarDefinitions.push_back(VarDefinition(nullptr, 0, 0, getEmptyContext()));
}
/// Look up a definition, within the given context.
@@ -471,7 +477,7 @@ public:
Ctx = VarDefinitions[i].Ctx;
return VarDefinitions[i].Exp;
}
- i = VarDefinitions[i].Ref;
+ i = VarDefinitions[i].DirectRef;
}
return nullptr;
}
@@ -508,7 +514,7 @@ public:
void dump() {
for (unsigned i = 1, e = VarDefinitions.size(); i < e; ++i) {
const Expr *Exp = VarDefinitions[i].Exp;
- unsigned Ref = VarDefinitions[i].Ref;
+ unsigned Ref = VarDefinitions[i].DirectRef;
dumpVarDefinitionName(i);
llvm::errs() << " = ";
@@ -539,9 +545,9 @@ protected:
friend class VarMapBuilder;
// Resolve any definition ID down to its non-reference base ID.
- unsigned getCanonicalDefinitionID(unsigned ID) {
+ unsigned getCanonicalDefinitionID(unsigned ID) const {
while (ID > 0 && VarDefinitions[ID].isReference())
- ID = VarDefinitions[ID].Ref;
+ ID = VarDefinitions[ID].CanonicalRef;
return ID;
}
@@ -564,10 +570,11 @@ protected:
}
// Add a new reference to an existing definition.
- Context addReference(const NamedDecl *D, unsigned i, Context Ctx) {
+ Context addReference(const NamedDecl *D, unsigned Ref, Context Ctx) {
unsigned newID = VarDefinitions.size();
Context NewCtx = ContextFactory.add(Ctx, D, newID);
- VarDefinitions.push_back(VarDefinition(D, i, Ctx));
+ VarDefinitions.push_back(
+ VarDefinition(D, Ref, getCanonicalDefinitionID(Ref), Ctx));
return NewCtx;
}
@@ -769,15 +776,14 @@ void LocalVariableMap::intersectBackEdge(Context C1, Context C2) {
const unsigned *I2 = C2.lookup(P.first);
if (!I2) {
// Variable does not exist at the end of the loop, invalidate.
- VDef->Ref = 0;
+ VDef->invalidateRef();
continue;
}
// Compare the canonical IDs. This correctly handles chains of references
// and determines if the variable is truly loop-invariant.
- if (getCanonicalDefinitionID(VDef->Ref) != getCanonicalDefinitionID(*I2)) {
- VDef->Ref = 0; // Mark this variable as undefined
- }
+ if (VDef->CanonicalRef != getCanonicalDefinitionID(*I2))
+ VDef->invalidateRef(); // Mark this variable as undefined
}
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index 10b8255..563a753 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -35,8 +35,8 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d,
getContext().getLangOpts().ElideConstructors && d.isNRVOVariable();
CIRGenFunction::AutoVarEmission emission(d);
- emission.IsEscapingByRef = d.isEscapingByref();
- if (emission.IsEscapingByRef)
+ emission.isEscapingByRef = d.isEscapingByref();
+ if (emission.isEscapingByRef)
cgm.errorNYI(d.getSourceRange(),
"emitAutoVarDecl: decl escaping by reference");
@@ -78,7 +78,7 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d,
alignment);
}
- emission.Addr = address;
+ emission.addr = address;
setAddrOfLocalVar(&d, address);
return emission;
@@ -101,13 +101,13 @@ bool CIRGenFunction::isTrivialInitializer(const Expr *init) {
void CIRGenFunction::emitAutoVarInit(
const CIRGenFunction::AutoVarEmission &emission) {
- assert(emission.Variable && "emission was not valid!");
+ assert(emission.variable && "emission was not valid!");
// If this was emitted as a global constant, we're done.
if (emission.wasEmittedAsGlobal())
return;
- const VarDecl &d = *emission.Variable;
+ const VarDecl &d = *emission.variable;
QualType type = d.getType();
@@ -124,7 +124,7 @@ void CIRGenFunction::emitAutoVarInit(
return;
}
- const Address addr = emission.Addr;
+ const Address addr = emission.addr;
// Check whether this is a byref variable that's potentially
// captured and moved by its own initializer. If so, we'll need to
@@ -153,7 +153,7 @@ void CIRGenFunction::emitAutoVarInit(
}
mlir::Attribute constant;
- if (emission.IsConstantAggregate ||
+ if (emission.isConstantAggregate ||
d.mightBeUsableInConstantExpressions(getContext())) {
// FIXME: Differently from LLVM we try not to emit / lower too much
// here for CIR since we are interested in seeing the ctor in some
@@ -196,7 +196,7 @@ void CIRGenFunction::emitAutoVarInit(
// FIXME(cir): migrate most of this file to use mlir::TypedAttr directly.
auto typedConstant = mlir::dyn_cast<mlir::TypedAttr>(constant);
assert(typedConstant && "expected typed attribute");
- if (!emission.IsConstantAggregate) {
+ if (!emission.isConstantAggregate) {
// For simple scalar/complex initialization, store the value directly.
LValue lv = makeAddrLValue(addr, type);
assert(init && "expected initializer");
@@ -209,7 +209,7 @@ void CIRGenFunction::emitAutoVarInit(
void CIRGenFunction::emitAutoVarCleanups(
const CIRGenFunction::AutoVarEmission &emission) {
- const VarDecl &d = *emission.Variable;
+ const VarDecl &d = *emission.variable;
// Check the type for a cleanup.
if (QualType::DestructionKind dtorKind = d.needsDestruction(getContext()))
@@ -821,7 +821,7 @@ void CIRGenFunction::emitAutoVarTypeCleanup(
// original stack object, not the possibly forwarded object.
Address addr = emission.getObjectAddress(*this);
- const VarDecl *var = emission.Variable;
+ const VarDecl *var = emission.variable;
QualType type = var->getType();
CleanupKind cleanupKind = NormalAndEHCleanup;
@@ -834,7 +834,7 @@ void CIRGenFunction::emitAutoVarTypeCleanup(
case QualType::DK_cxx_destructor:
// If there's an NRVO flag on the emission, we need a different
// cleanup.
- if (emission.NRVOFlag) {
+ if (emission.nrvoFlag) {
cgm.errorNYI(var->getSourceRange(), "emitAutoVarTypeCleanup: NRVO");
return;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index af42d1d..1e987f3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -133,8 +133,7 @@ public:
}
void VisitParenExpr(ParenExpr *pe) { Visit(pe->getSubExpr()); }
void VisitGenericSelectionExpr(GenericSelectionExpr *ge) {
- cgf.cgm.errorNYI(ge->getSourceRange(),
- "AggExprEmitter: VisitGenericSelectionExpr");
+ Visit(ge->getResultExpr());
}
void VisitCoawaitExpr(CoawaitExpr *e) {
cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCoawaitExpr");
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
index 83208bf..7989ad2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -210,60 +210,6 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorCall(
return emitCall(fnInfo, callee, returnValue, args, nullptr, loc);
}
-namespace {
-/// The parameters to pass to a usual operator delete.
-struct UsualDeleteParams {
- TypeAwareAllocationMode typeAwareDelete = TypeAwareAllocationMode::No;
- bool destroyingDelete = false;
- bool size = false;
- AlignedAllocationMode alignment = AlignedAllocationMode::No;
-};
-} // namespace
-
-// FIXME(cir): this should be shared with LLVM codegen
-static UsualDeleteParams getUsualDeleteParams(const FunctionDecl *fd) {
- UsualDeleteParams params;
-
- const FunctionProtoType *fpt = fd->getType()->castAs<FunctionProtoType>();
- auto ai = fpt->param_type_begin(), ae = fpt->param_type_end();
-
- if (fd->isTypeAwareOperatorNewOrDelete()) {
- params.typeAwareDelete = TypeAwareAllocationMode::Yes;
- assert(ai != ae);
- ++ai;
- }
-
- // The first argument after the type-identity parameter (if any) is
- // always a void* (or C* for a destroying operator delete for class
- // type C).
- ++ai;
-
- // The next parameter may be a std::destroying_delete_t.
- if (fd->isDestroyingOperatorDelete()) {
- params.destroyingDelete = true;
- assert(ai != ae);
- ++ai;
- }
-
- // Figure out what other parameters we should be implicitly passing.
- if (ai != ae && (*ai)->isIntegerType()) {
- params.size = true;
- ++ai;
- } else {
- assert(!isTypeAwareAllocation(params.typeAwareDelete));
- }
-
- if (ai != ae && (*ai)->isAlignValT()) {
- params.alignment = AlignedAllocationMode::Yes;
- ++ai;
- } else {
- assert(!isTypeAwareAllocation(params.typeAwareDelete));
- }
-
- assert(ai == ae && "unexpected usual deallocation function parameter");
- return params;
-}
-
static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e,
unsigned minElements,
mlir::Value &numElements,
@@ -616,11 +562,11 @@ void CIRGenFunction::emitDeleteCall(const FunctionDecl *deleteFD,
const auto *deleteFTy = deleteFD->getType()->castAs<FunctionProtoType>();
CallArgList deleteArgs;
- UsualDeleteParams params = getUsualDeleteParams(deleteFD);
+ UsualDeleteParams params = deleteFD->getUsualDeleteParams();
auto paramTypeIt = deleteFTy->param_type_begin();
// Pass std::type_identity tag if present
- if (isTypeAwareAllocation(params.typeAwareDelete))
+ if (isTypeAwareAllocation(params.TypeAwareDelete))
cgm.errorNYI(deleteFD->getSourceRange(),
"emitDeleteCall: type aware delete");
@@ -631,12 +577,12 @@ void CIRGenFunction::emitDeleteCall(const FunctionDecl *deleteFD,
deleteArgs.add(RValue::get(deletePtr), argTy);
// Pass the std::destroying_delete tag if present.
- if (params.destroyingDelete)
+ if (params.DestroyingDelete)
cgm.errorNYI(deleteFD->getSourceRange(),
"emitDeleteCall: destroying delete");
// Pass the size if the delete function has a size_t parameter.
- if (params.size) {
+ if (params.Size) {
QualType sizeType = *paramTypeIt++;
CharUnits deleteTypeSize = getContext().getTypeSizeInChars(deleteTy);
assert(mlir::isa<cir::IntType>(convertType(sizeType)) &&
@@ -648,7 +594,7 @@ void CIRGenFunction::emitDeleteCall(const FunctionDecl *deleteFD,
}
// Pass the alignment if the delete function has an align_val_t parameter.
- if (isAlignedAllocation(params.alignment))
+ if (isAlignedAllocation(params.Alignment))
cgm.errorNYI(deleteFD->getSourceRange(),
"emitDeleteCall: aligned allocation");
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index f4bbced..500007f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2151,8 +2151,10 @@ mlir::Value ScalarExprEmitter::VisitRealImag(const UnaryOperator *e,
}
if (e->getOpcode() == UO_Real) {
- return promotionTy.isNull() ? Visit(op)
- : cgf.emitPromotedScalarExpr(op, promotionTy);
+ mlir::Value operand = promotionTy.isNull()
+ ? Visit(op)
+ : cgf.emitPromotedScalarExpr(op, promotionTy);
+ return builder.createComplexReal(loc, operand);
}
// __imag on a scalar returns zero. Emit the subexpr to ensure side
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index a404c0c..b26b4f2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -836,6 +836,8 @@ LValue CIRGenFunction::emitLValue(const Expr *e) {
return emitCallExprLValue(cast<CallExpr>(e));
case Expr::ParenExprClass:
return emitLValue(cast<ParenExpr>(e)->getSubExpr());
+ case Expr::GenericSelectionExprClass:
+ return emitLValue(cast<GenericSelectionExpr>(e)->getResultExpr());
case Expr::DeclRefExprClass:
return emitDeclRefLValue(cast<DeclRefExpr>(e));
case Expr::CStyleCastExprClass:
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index c0ed8b4..cb7cf98 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -479,55 +479,55 @@ public:
ConstantEmission tryEmitAsConstant(const MemberExpr *me);
struct AutoVarEmission {
- const clang::VarDecl *Variable;
+ const clang::VarDecl *variable;
/// The address of the alloca for languages with explicit address space
/// (e.g. OpenCL) or alloca casted to generic pointer for address space
/// agnostic languages (e.g. C++). Invalid if the variable was emitted
/// as a global constant.
- Address Addr;
+ Address addr;
/// True if the variable is of aggregate type and has a constant
/// initializer.
- bool IsConstantAggregate = false;
+ bool isConstantAggregate = false;
/// True if the variable is a __block variable that is captured by an
/// escaping block.
- bool IsEscapingByRef = false;
+ bool isEscapingByRef = false;
/// True if the variable was emitted as an offload recipe, and thus doesn't
/// have the same sort of alloca initialization.
- bool EmittedAsOffload = false;
+ bool emittedAsOffload = false;
- mlir::Value NRVOFlag{};
+ mlir::Value nrvoFlag{};
struct Invalid {};
- AutoVarEmission(Invalid) : Variable(nullptr), Addr(Address::invalid()) {}
+ AutoVarEmission(Invalid) : variable(nullptr), addr(Address::invalid()) {}
AutoVarEmission(const clang::VarDecl &variable)
- : Variable(&variable), Addr(Address::invalid()) {}
+ : variable(&variable), addr(Address::invalid()) {}
static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); }
- bool wasEmittedAsGlobal() const { return !Addr.isValid(); }
+ bool wasEmittedAsGlobal() const { return !addr.isValid(); }
- bool wasEmittedAsOffloadClause() const { return EmittedAsOffload; }
+ bool wasEmittedAsOffloadClause() const { return emittedAsOffload; }
/// Returns the raw, allocated address, which is not necessarily
/// the address of the object itself. It is casted to default
/// address space for address space agnostic languages.
- Address getAllocatedAddress() const { return Addr; }
+ Address getAllocatedAddress() const { return addr; }
// Changes the stored address for the emission. This function should only
// be used in extreme cases, and isn't required to model normal AST
// initialization/variables.
- void setAllocatedAddress(Address A) { Addr = A; }
+ void setAllocatedAddress(Address a) { addr = a; }
/// Returns the address of the object within this declaration.
/// Note that this does not chase the forwarding pointer for
/// __block decls.
Address getObjectAddress(CIRGenFunction &cgf) const {
- if (!IsEscapingByRef)
- return Addr;
+ if (!isEscapingByRef)
+ return addr;
assert(!cir::MissingFeatures::opAllocaEscapeByReference());
return Address::invalid();
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
index 7f9350a..a9af753 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
@@ -62,7 +62,7 @@ mlir::Value CIRGenFunction::createOpenACCConstantInt(mlir::Location loc,
auto constOp = builder.create<mlir::arith::ConstantOp>(
loc, builder.getIntegerAttr(ty, value));
- return constOp.getResult();
+ return constOp;
}
CIRGenFunction::OpenACCDataOperandInfo
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
index 3cf0534..3d86f71 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
@@ -110,7 +110,7 @@ class OpenACCClauseCIREmitter final
auto constOp = builder.create<mlir::arith::ConstantOp>(
loc, builder.getIntegerAttr(ty, value));
- return constOp.getResult();
+ return constOp;
}
mlir::Value createConstantInt(SourceLocation loc, unsigned width,
@@ -230,13 +230,13 @@ class OpenACCClauseCIREmitter final
std::is_same_v<AfterOpTy, mlir::acc::DetachOp>) {
// Detach/Delete ops don't have the variable reference here, so they
// take 1 fewer argument to their build function.
- afterOp = builder.create<AfterOpTy>(
- opInfo.beginLoc, beforeOp.getResult(), structured, implicit,
- opInfo.name, opInfo.bounds);
+ afterOp =
+ builder.create<AfterOpTy>(opInfo.beginLoc, beforeOp, structured,
+ implicit, opInfo.name, opInfo.bounds);
} else {
afterOp = builder.create<AfterOpTy>(
- opInfo.beginLoc, beforeOp.getResult(), opInfo.varValue, structured,
- implicit, opInfo.name, opInfo.bounds);
+ opInfo.beginLoc, beforeOp, opInfo.varValue, structured, implicit,
+ opInfo.name, opInfo.bounds);
}
}
@@ -1001,11 +1001,11 @@ public:
OpenACCRecipeBuilder<mlir::acc::PrivateRecipeOp>(cgf, builder)
.getOrCreateRecipe(
cgf.getContext(), recipeInsertLocation, varExpr,
- varRecipe.AllocaDecl, varRecipe.InitExpr,
+ varRecipe.AllocaDecl,
/*temporary=*/nullptr, OpenACCReductionOperator::Invalid,
Decl::castToDeclContext(cgf.curFuncDecl), opInfo.origType,
opInfo.bounds.size(), opInfo.boundTypes, opInfo.baseType,
- privateOp.getResult());
+ privateOp);
// TODO: OpenACC: The dialect is going to change in the near future to
// have these be on a different operation, so when that changes, we
// probably need to change these here.
@@ -1036,24 +1036,17 @@ public:
{
mlir::OpBuilder::InsertionGuard guardCase(builder);
- // TODO: OpenACC: At the moment this is a bit of a hacky way of doing
- // this, and won't work when we get to bounds/etc. Do this for now to
- // limit the scope of this refactor.
- VarDecl *allocaDecl = varRecipe.AllocaDecl;
- allocaDecl->setInit(varRecipe.InitExpr);
- allocaDecl->setInitStyle(VarDecl::CallInit);
auto recipe =
OpenACCRecipeBuilder<mlir::acc::FirstprivateRecipeOp>(cgf,
builder)
.getOrCreateRecipe(
cgf.getContext(), recipeInsertLocation, varExpr,
- varRecipe.AllocaDecl, varRecipe.InitExpr,
- varRecipe.InitFromTemporary,
+ varRecipe.AllocaDecl, varRecipe.InitFromTemporary,
OpenACCReductionOperator::Invalid,
Decl::castToDeclContext(cgf.curFuncDecl), opInfo.origType,
opInfo.bounds.size(), opInfo.boundTypes, opInfo.baseType,
- firstPrivateOp.getResult());
+ firstPrivateOp);
// TODO: OpenACC: The dialect is going to change in the near future to
// have these be on a different operation, so when that changes, we
@@ -1086,22 +1079,16 @@ public:
{
mlir::OpBuilder::InsertionGuard guardCase(builder);
- // TODO: OpenACC: At the moment this is a bit of a hacky way of doing
- // this, and won't work when we get to bounds/etc. Do this for now to
- // limit the scope of this refactor.
- VarDecl *allocaDecl = varRecipe.AllocaDecl;
- allocaDecl->setInit(varRecipe.InitExpr);
- allocaDecl->setInitStyle(VarDecl::CallInit);
auto recipe =
OpenACCRecipeBuilder<mlir::acc::ReductionRecipeOp>(cgf, builder)
.getOrCreateRecipe(
cgf.getContext(), recipeInsertLocation, varExpr,
- varRecipe.AllocaDecl, varRecipe.InitExpr,
+ varRecipe.AllocaDecl,
/*temporary=*/nullptr, clause.getReductionOp(),
Decl::castToDeclContext(cgf.curFuncDecl), opInfo.origType,
opInfo.bounds.size(), opInfo.boundTypes, opInfo.baseType,
- reductionOp.getResult());
+ reductionOp);
operation.addReduction(builder.getContext(), reductionOp, recipe);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp
index fc28ac5..ea6ea2c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp
@@ -36,6 +36,75 @@ mlir::Block *OpenACCRecipeBuilderBase::createRecipeBlock(mlir::Region &region,
llvm::SmallVector<mlir::Location> locs{types.size(), loc};
return builder.createBlock(&region, region.end(), types, locs);
}
+void OpenACCRecipeBuilderBase::makeAllocaCopy(mlir::Location loc,
+ mlir::Type copyType,
+ mlir::Value numEltsToCopy,
+ mlir::Value offsetPerSubarray,
+ mlir::Value destAlloca,
+ mlir::Value srcAlloca) {
+ mlir::OpBuilder::InsertionGuard guardCase(builder);
+
+ mlir::Type itrTy = cgf.cgm.convertType(cgf.getContext().UnsignedLongLongTy);
+ auto itrPtrTy = cir::PointerType::get(itrTy);
+ mlir::IntegerAttr itrAlign =
+ cgf.cgm.getSize(cgf.getContext().getTypeAlignInChars(
+ cgf.getContext().UnsignedLongLongTy));
+
+ auto loopBuilder = [&]() {
+ auto itr =
+ cir::AllocaOp::create(builder, loc, itrPtrTy, itrTy, "itr", itrAlign);
+ cir::ConstantOp constZero = builder.getConstInt(loc, itrTy, 0);
+ builder.CIRBaseBuilderTy::createStore(loc, constZero, itr);
+ builder.createFor(
+ loc,
+ /*condBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ // itr < numEltsToCopy
+ // Enforce a trip count of 1 if there wasn't any element count, this
+ // way we can just use this loop with a constant bounds instead of a
+ // separate code path.
+ if (!numEltsToCopy)
+ numEltsToCopy = builder.getConstInt(loc, itrTy, 1);
+
+ auto loadCur = cir::LoadOp::create(builder, loc, {itr});
+ auto cmp = builder.createCompare(loc, cir::CmpOpKind::lt, loadCur,
+ numEltsToCopy);
+ builder.createCondition(cmp);
+ },
+ /*bodyBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ // destAlloca[itr] = srcAlloca[offsetPerSubArray * itr];
+ auto loadCur = cir::LoadOp::create(builder, loc, {itr});
+ auto srcOffset = builder.createMul(loc, offsetPerSubarray, loadCur);
+
+ auto ptrToOffsetIntoSrc = cir::PtrStrideOp::create(
+ builder, loc, copyType, srcAlloca, srcOffset);
+
+ auto offsetIntoDecayDest = cir::PtrStrideOp::create(
+ builder, loc, builder.getPointerTo(copyType), destAlloca,
+ loadCur);
+
+ builder.CIRBaseBuilderTy::createStore(loc, ptrToOffsetIntoSrc,
+ offsetIntoDecayDest);
+ builder.createYield(loc);
+ },
+ /*stepBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ // Simple increment of the iterator.
+ auto load = cir::LoadOp::create(builder, loc, {itr});
+ auto inc = cir::UnaryOp::create(builder, loc, load.getType(),
+ cir::UnaryOpKind::Inc, load);
+ builder.CIRBaseBuilderTy::createStore(loc, inc, itr);
+ builder.createYield(loc);
+ });
+ };
+
+ cir::ScopeOp::create(builder, loc,
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ loopBuilder();
+ builder.createYield(loc);
+ });
+}
mlir::Value OpenACCRecipeBuilderBase::makeBoundsAlloca(
mlir::Block *block, SourceRange exprRange, mlir::Location loc,
@@ -78,6 +147,10 @@ mlir::Value OpenACCRecipeBuilderBase::makeBoundsAlloca(
bool lastBoundWasArray = isArrayTy(boundTypes.back());
+ // Make sure we track a moving version of this so we can get our
+ // 'copying' back to correct.
+ mlir::Value lastAlloca = initialAlloca;
+
// Since we're iterating the types in reverse, this sets up for each index
// corresponding to the boundsRange to be the 'after application of the
// bounds.
@@ -125,14 +198,21 @@ mlir::Value OpenACCRecipeBuilderBase::makeBoundsAlloca(
mlir::Type eltTy = cgf.convertType(resultType);
cir::PointerType ptrTy = builder.getPointerTo(eltTy);
- builder.createAlloca(loc, ptrTy, eltTy, "openacc.init.bounds",
- cgf.getContext().getTypeAlignInChars(resultType),
- curSize);
-
- // TODO: OpenACC : At this point we should be copying the addresses of
- // each element of this to the last allocation. At the moment, that is
- // not yet implemented.
- cgf.cgm.errorNYI(exprRange, "OpenACC recipe alloca copying");
+ mlir::Value curAlloca = builder.createAlloca(
+ loc, ptrTy, eltTy, "openacc.init.bounds",
+ cgf.getContext().getTypeAlignInChars(resultType), curSize);
+
+ makeAllocaCopy(loc, ptrTy, cumulativeElts, eltsPerSubArray, lastAlloca,
+ curAlloca);
+ lastAlloca = curAlloca;
+ } else {
+ // In the case of an array, we just need to decay the pointer, so just do
+ // a zero-offset stride on the last alloca to decay it down an array
+ // level.
+ cir::ConstantOp constZero = builder.getConstInt(loc, itrTy, 0);
+ lastAlloca = builder.getArrayElement(loc, loc, lastAlloca,
+ cgf.convertType(resultType),
+ constZero, /*shouldDecay=*/true);
}
cumulativeElts = eltsToAlloca;
@@ -160,7 +240,7 @@ OpenACCRecipeBuilderBase::createBoundsLoop(mlir::Value subscriptedValue,
if (auto arrayTy = dyn_cast<cir::ArrayType>(eltTy))
return builder.getArrayElement(loc, loc, subVal, arrayTy.getElementType(),
- idxLoad.getResult(),
+ idxLoad,
/*shouldDecay=*/true);
assert(isa<cir::PointerType>(eltTy));
@@ -168,8 +248,8 @@ OpenACCRecipeBuilderBase::createBoundsLoop(mlir::Value subscriptedValue,
auto eltLoad = cir::LoadOp::create(builder, loc, {subVal});
return cir::PtrStrideOp::create(builder, loc, eltLoad.getType(), eltLoad,
- idxLoad.getResult())
- .getResult();
+ idxLoad);
+
};
auto forStmtBuilder = [&]() {
@@ -191,12 +271,11 @@ OpenACCRecipeBuilderBase::createBoundsLoop(mlir::Value subscriptedValue,
if (inverse) {
cir::ConstantOp constOne = builder.getConstInt(loc, itrTy, 1);
- auto sub =
- cir::BinOp::create(builder, loc, itrTy, cir::BinOpKind::Sub,
- ubConversion.getResult(0), constOne.getResult());
+ auto sub = cir::BinOp::create(builder, loc, itrTy, cir::BinOpKind::Sub,
+ ubConversion.getResult(0), constOne);
// Upperbound is exclusive, so subtract 1.
- builder.CIRBaseBuilderTy::createStore(loc, sub.getResult(), itr);
+ builder.CIRBaseBuilderTy::createStore(loc, sub, itr);
} else {
// Lowerbound is inclusive, so we can include it.
builder.CIRBaseBuilderTy::createStore(loc, lbConversion.getResult(0),
@@ -214,8 +293,8 @@ OpenACCRecipeBuilderBase::createBoundsLoop(mlir::Value subscriptedValue,
auto loadCur = cir::LoadOp::create(builder, loc, {itr});
// Use 'not equal' since we are just doing an increment/decrement.
auto cmp = builder.createCompare(
- loc, inverse ? cir::CmpOpKind::ge : cir::CmpOpKind::lt,
- loadCur.getResult(), endItr.getResult(0));
+ loc, inverse ? cir::CmpOpKind::ge : cir::CmpOpKind::lt, loadCur,
+ endItr.getResult(0));
builder.createCondition(cmp);
},
/*bodyBuilder=*/
@@ -229,11 +308,10 @@ OpenACCRecipeBuilderBase::createBoundsLoop(mlir::Value subscriptedValue,
/*stepBuilder=*/
[&](mlir::OpBuilder &b, mlir::Location loc) {
auto load = cir::LoadOp::create(builder, loc, {itr});
- auto unary = cir::UnaryOp::create(builder, loc, load.getType(),
- inverse ? cir::UnaryOpKind::Dec
- : cir::UnaryOpKind::Inc,
- load.getResult());
- builder.CIRBaseBuilderTy::createStore(loc, unary.getResult(), itr);
+ auto unary = cir::UnaryOp::create(
+ builder, loc, load.getType(),
+ inverse ? cir::UnaryOpKind::Dec : cir::UnaryOpKind::Inc, load);
+ builder.CIRBaseBuilderTy::createStore(loc, unary, itr);
builder.createYield(loc);
});
};
@@ -322,6 +400,32 @@ void OpenACCRecipeBuilderBase::createRecipeDestroySection(
mlir::acc::YieldOp::create(builder, locEnd);
}
+void OpenACCRecipeBuilderBase::makeBoundsInit(
+ mlir::Value alloca, mlir::Location loc, mlir::Block *block,
+ const VarDecl *allocaDecl, QualType origType, bool isInitSection) {
+ mlir::OpBuilder::InsertionGuard guardCase(builder);
+ builder.setInsertionPointToEnd(block);
+ CIRGenFunction::LexicalScope ls(cgf, loc, block);
+
+ CIRGenFunction::AutoVarEmission tempDeclEmission{*allocaDecl};
+ tempDeclEmission.emittedAsOffload = true;
+
+ // The init section is the only one of the handful that only has a single
+ // argument for the 'type', so we have to drop 1 for init, and future calls
+ // to this will need to drop 2.
+ llvm::MutableArrayRef<mlir::BlockArgument> boundsRange =
+ block->getArguments().drop_front(isInitSection ? 1 : 2);
+
+ mlir::Value subscriptedValue = alloca;
+ for (mlir::BlockArgument boundArg : llvm::reverse(boundsRange))
+ subscriptedValue = createBoundsLoop(subscriptedValue, boundArg, loc,
+ /*inverse=*/false);
+
+ tempDeclEmission.setAllocatedAddress(
+ Address{subscriptedValue, cgf.convertType(origType),
+ cgf.getContext().getDeclAlign(allocaDecl)});
+ cgf.emitAutoVarInit(tempDeclEmission);
+}
// TODO: OpenACC: When we get this implemented for the reduction/firstprivate,
// this might end up re-merging with createRecipeInitCopy. For now, keep it
@@ -331,7 +435,7 @@ void OpenACCRecipeBuilderBase::createPrivateInitRecipe(
mlir::Location loc, mlir::Location locEnd, SourceRange exprRange,
mlir::Value mainOp, mlir::acc::PrivateRecipeOp recipe, size_t numBounds,
llvm::ArrayRef<QualType> boundTypes, const VarDecl *allocaDecl,
- QualType origType, const Expr *initExpr) {
+ QualType origType) {
assert(allocaDecl && "Required recipe variable not set?");
CIRGenFunction::DeclMapRevertingRAII declMapRAII{cgf, allocaDecl};
@@ -364,11 +468,17 @@ void OpenACCRecipeBuilderBase::createPrivateInitRecipe(
cgf.emitAutoVarAlloca(*allocaDecl, builder.saveInsertionPoint());
cgf.emitAutoVarInit(tempDeclEmission);
} else {
- makeBoundsAlloca(block, exprRange, loc, "openacc.private.init", numBounds,
- boundTypes);
-
- if (initExpr)
- cgf.cgm.errorNYI(exprRange, "private-init with bounds initialization");
+ mlir::Value alloca = makeBoundsAlloca(
+ block, exprRange, loc, "openacc.private.init", numBounds, boundTypes);
+
+ // If the initializer is trivial, there is nothing to do here, so save
+ // ourselves some effort.
+ if (allocaDecl->getInit() &&
+ (!cgf.isTrivialInitializer(allocaDecl->getInit()) ||
+ cgf.getContext().getLangOpts().getTrivialAutoVarInit() !=
+ LangOptions::TrivialAutoVarInitKind::Uninitialized))
+ makeBoundsInit(alloca, loc, block, allocaDecl, origType,
+ /*isInitSection=*/true);
}
mlir::acc::YieldOp::create(builder, locEnd);
@@ -395,7 +505,7 @@ void OpenACCRecipeBuilderBase::createFirstprivateRecipeCopy(
// that instead of the variable in the other block.
tempDeclEmission.setAllocatedAddress(
Address{toArg, elementTy, cgf.getContext().getDeclAlign(varRecipe)});
- tempDeclEmission.EmittedAsOffload = true;
+ tempDeclEmission.emittedAsOffload = true;
CIRGenFunction::DeclMapRevertingRAII declMapRAII{cgf, temporary};
cgf.setAddrOfLocalVar(
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h
index acd187b..a05b0bd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.h
@@ -24,6 +24,10 @@
namespace clang::CIRGen {
class OpenACCRecipeBuilderBase {
+ // makes the copy of the addresses of an alloca to the previous allocation.
+ void makeAllocaCopy(mlir::Location loc, mlir::Type copyType,
+ mlir::Value numEltsToCopy, mlir::Value offsetPerSubarray,
+ mlir::Value destAlloca, mlir::Value srcAlloca);
// This function generates the required alloca, similar to
// 'emitAutoVarAlloca', except for the OpenACC array/pointer types.
mlir::Value makeBoundsAlloca(mlir::Block *block, SourceRange exprRange,
@@ -31,6 +35,10 @@ class OpenACCRecipeBuilderBase {
size_t numBounds,
llvm::ArrayRef<QualType> boundTypes);
+ void makeBoundsInit(mlir::Value alloca, mlir::Location loc,
+ mlir::Block *block, const VarDecl *allocaDecl,
+ QualType origType, bool isInitSection);
+
protected:
CIRGen::CIRGenFunction &cgf;
CIRGen::CIRGenBuilderTy &builder;
@@ -62,8 +70,7 @@ protected:
mlir::acc::PrivateRecipeOp recipe,
size_t numBounds,
llvm::ArrayRef<QualType> boundTypes,
- const VarDecl *allocaDecl, QualType origType,
- const Expr *initExpr);
+ const VarDecl *allocaDecl, QualType origType);
void createRecipeDestroySection(mlir::Location loc, mlir::Location locEnd,
mlir::Value mainOp, CharUnits alignment,
@@ -204,15 +211,12 @@ public:
OpenACCRecipeBuilder(CIRGen::CIRGenFunction &cgf,
CIRGen::CIRGenBuilderTy &builder)
: OpenACCRecipeBuilderBase(cgf, builder) {}
- RecipeTy getOrCreateRecipe(ASTContext &astCtx,
- mlir::OpBuilder::InsertPoint &insertLocation,
- const Expr *varRef, const VarDecl *varRecipe,
- const Expr *initExpr, const VarDecl *temporary,
- OpenACCReductionOperator reductionOp,
- DeclContext *dc, QualType origType,
- size_t numBounds,
- llvm::ArrayRef<QualType> boundTypes,
- QualType baseType, mlir::Value mainOp) {
+ RecipeTy getOrCreateRecipe(
+ ASTContext &astCtx, mlir::OpBuilder::InsertPoint &insertLocation,
+ const Expr *varRef, const VarDecl *varRecipe, const VarDecl *temporary,
+ OpenACCReductionOperator reductionOp, DeclContext *dc, QualType origType,
+ size_t numBounds, llvm::ArrayRef<QualType> boundTypes, QualType baseType,
+ mlir::Value mainOp) {
assert(!varRecipe->getType()->isSpecificBuiltinType(
BuiltinType::ArraySection) &&
"array section shouldn't make it to recipe creation");
@@ -258,7 +262,7 @@ public:
if constexpr (std::is_same_v<RecipeTy, mlir::acc::PrivateRecipeOp>) {
createPrivateInitRecipe(loc, locEnd, varRef->getSourceRange(), mainOp,
recipe, numBounds, boundTypes, varRecipe,
- origType, initExpr);
+ origType);
} else {
createRecipeInitCopy(loc, locEnd, varRef->getSourceRange(), mainOp,
recipe, varRecipe, temporary);
diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
index a762881..87f2340 100644
--- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
@@ -296,9 +296,8 @@ void CIRRecordLowering::lower(bool nonVirtualBaseType) {
}
llvm::stable_sort(members);
- // TODO: implement clipTailPadding once bitfields are implemented
- assert(!cir::MissingFeatures::bitfields());
- assert(!cir::MissingFeatures::recordZeroInit());
+ // TODO: Verify bitfield clipping
+ assert(!cir::MissingFeatures::checkBitfieldClipping());
members.push_back(makeStorageInfo(size, getUIntNType(8)));
determinePacked(nonVirtualBaseType);
@@ -319,9 +318,11 @@ void CIRRecordLowering::fillOutputFields() {
fieldIdxMap[member.fieldDecl->getCanonicalDecl()] =
fieldTypes.size() - 1;
// A field without storage must be a bitfield.
- assert(!cir::MissingFeatures::bitfields());
- if (!member.data)
+ if (!member.data) {
+ assert(member.fieldDecl &&
+ "member.data is a nullptr so member.fieldDecl should not be");
setBitFieldInfo(member.fieldDecl, member.offset, fieldTypes.back());
+ }
} else if (member.kind == MemberInfo::InfoKind::Base) {
nonVirtualBases[member.cxxRecordDecl] = fieldTypes.size() - 1;
} else if (member.kind == MemberInfo::InfoKind::VBase) {
@@ -615,7 +616,7 @@ void CIRRecordLowering::determinePacked(bool nvBaseType) {
continue;
// If any member falls at an offset that it not a multiple of its alignment,
// then the entire record must be packed.
- if (member.offset % getAlignment(member.data))
+ if (!member.offset.isMultipleOf(getAlignment(member.data)))
packed = true;
if (member.offset < nvSize)
nvAlignment = std::max(nvAlignment, getAlignment(member.data));
@@ -623,12 +624,12 @@ void CIRRecordLowering::determinePacked(bool nvBaseType) {
}
// If the size of the record (the capstone's offset) is not a multiple of the
// record's alignment, it must be packed.
- if (members.back().offset % alignment)
+ if (!members.back().offset.isMultipleOf(alignment))
packed = true;
// If the non-virtual sub-object is not a multiple of the non-virtual
// sub-object's alignment, it must be packed. We cannot have a packed
// non-virtual sub-object and an unpacked complete object or vise versa.
- if (nvSize % nvAlignment)
+ if (!nvSize.isMultipleOf(nvAlignment))
packed = true;
// Update the alignment of the sentinel.
if (!packed)
@@ -697,13 +698,9 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *rd, cir::RecordType *ty) {
ty ? *ty : cir::RecordType{}, baseTy ? baseTy : cir::RecordType{},
(bool)lowering.zeroInitializable, (bool)lowering.zeroInitializableAsBase);
- assert(!cir::MissingFeatures::recordZeroInit());
-
rl->nonVirtualBases.swap(lowering.nonVirtualBases);
rl->completeObjectVirtualBases.swap(lowering.virtualBases);
- assert(!cir::MissingFeatures::bitfields());
-
// Add all the field numbers.
rl->fieldIdxMap.swap(lowering.fieldIdxMap);
@@ -824,7 +821,7 @@ void CIRRecordLowering::lowerUnion() {
appendPaddingBytes(layoutSize - getSize(storageType));
// Set packed if we need it.
- if (layoutSize % getAlignment(storageType))
+ if (!layoutSize.isMultipleOf(getAlignment(storageType)))
packed = true;
}
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index fb87036..6b5cc80 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2388,14 +2388,23 @@ OpFoldResult cir::ComplexCreateOp::fold(FoldAdaptor adaptor) {
//===----------------------------------------------------------------------===//
LogicalResult cir::ComplexRealOp::verify() {
- if (getType() != getOperand().getType().getElementType()) {
+ mlir::Type operandTy = getOperand().getType();
+ if (auto complexOperandTy = mlir::dyn_cast<cir::ComplexType>(operandTy)) {
+ operandTy = complexOperandTy.getElementType();
+ }
+
+ if (getType() != operandTy) {
emitOpError() << ": result type does not match operand type";
return failure();
}
+
return success();
}
OpFoldResult cir::ComplexRealOp::fold(FoldAdaptor adaptor) {
+ if (!mlir::isa<cir::ComplexType>(getOperand().getType()))
+ return nullptr;
+
if (auto complexCreateOp = getOperand().getDefiningOp<cir::ComplexCreateOp>())
return complexCreateOp.getOperand(0);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 22f069d..4bc7783 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2999,8 +2999,13 @@ mlir::LogicalResult CIRToLLVMComplexRealOpLowering::matchAndRewrite(
cir::ComplexRealOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
mlir::Type resultLLVMTy = getTypeConverter()->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::ExtractValueOp>(
- op, resultLLVMTy, adaptor.getOperand(), llvm::ArrayRef<std::int64_t>{0});
+ mlir::Value operand = adaptor.getOperand();
+ if (mlir::isa<cir::ComplexType>(op.getOperand().getType())) {
+ operand = mlir::LLVM::ExtractValueOp::create(
+ rewriter, op.getLoc(), resultLLVMTy, operand,
+ llvm::ArrayRef<std::int64_t>{0});
+ }
+ rewriter.replaceOp(op, operand);
return mlir::success();
}
diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index eeb0fd6..4a3446a 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -880,7 +880,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
CharUnits MaxInlineWidth =
getContext().toCharUnitsFromBits(MaxInlineWidthInBits);
DiagnosticsEngine &Diags = CGM.getDiags();
- bool Misaligned = (Ptr.getAlignment() % TInfo.Width) != 0;
+ bool Misaligned = !Ptr.getAlignment().isMultipleOf(TInfo.Width);
bool Oversized = getContext().toBits(TInfo.Width) > MaxInlineWidthInBits;
if (Misaligned) {
Diags.Report(E->getBeginLoc(), diag::warn_atomic_op_misaligned)
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index a092b71..c52526c 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -1377,58 +1377,6 @@ RValue CodeGenFunction::EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
}
namespace {
-/// The parameters to pass to a usual operator delete.
-struct UsualDeleteParams {
- TypeAwareAllocationMode TypeAwareDelete = TypeAwareAllocationMode::No;
- bool DestroyingDelete = false;
- bool Size = false;
- AlignedAllocationMode Alignment = AlignedAllocationMode::No;
-};
-}
-
-static UsualDeleteParams getUsualDeleteParams(const FunctionDecl *FD) {
- UsualDeleteParams Params;
-
- const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>();
- auto AI = FPT->param_type_begin(), AE = FPT->param_type_end();
-
- if (FD->isTypeAwareOperatorNewOrDelete()) {
- Params.TypeAwareDelete = TypeAwareAllocationMode::Yes;
- assert(AI != AE);
- ++AI;
- }
-
- // The first argument after the type-identity parameter (if any) is
- // always a void* (or C* for a destroying operator delete for class
- // type C).
- ++AI;
-
- // The next parameter may be a std::destroying_delete_t.
- if (FD->isDestroyingOperatorDelete()) {
- assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
- Params.DestroyingDelete = true;
- assert(AI != AE);
- ++AI;
- }
-
- // Figure out what other parameters we should be implicitly passing.
- if (AI != AE && (*AI)->isIntegerType()) {
- Params.Size = true;
- ++AI;
- } else
- assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
-
- if (AI != AE && (*AI)->isAlignValT()) {
- Params.Alignment = AlignedAllocationMode::Yes;
- ++AI;
- } else
- assert(!isTypeAwareAllocation(Params.TypeAwareDelete));
-
- assert(AI == AE && "unexpected usual deallocation function parameter");
- return Params;
-}
-
-namespace {
/// A cleanup to call the given 'operator delete' function upon abnormal
/// exit from a new expression. Templated on a traits type that deals with
/// ensuring that the arguments dominate the cleanup if necessary.
@@ -1505,7 +1453,7 @@ namespace {
} else {
// For a non-placement new-expression, 'operator delete' can take a
// size and/or an alignment if it has the right parameters.
- Params = getUsualDeleteParams(OperatorDelete);
+ Params = OperatorDelete->getUsualDeleteParams();
}
assert(!Params.DestroyingDelete &&
@@ -1838,7 +1786,7 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,
const auto *DeleteFTy = DeleteFD->getType()->castAs<FunctionProtoType>();
CallArgList DeleteArgs;
- auto Params = getUsualDeleteParams(DeleteFD);
+ auto Params = DeleteFD->getUsualDeleteParams();
auto ParamTypeIt = DeleteFTy->param_type_begin();
std::optional<llvm::AllocaInst *> TagAlloca;
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index b44dd9e..6407afc 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -433,7 +433,7 @@ llvm::Constant *ConstantAggregateBuilder::buildFrom(
// All remaining elements must be the same type.
if (Elems[I]->getType() != CommonType ||
- Offset(I) % ElemSize != 0) {
+ !Offset(I).isMultipleOf(ElemSize)) {
CanEmitArray = false;
break;
}
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 60f30a1..dbcce9b 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -5367,7 +5367,7 @@ IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
// Ignore scan requests that don't start at an even multiple of the
// word size. We can't encode them.
- if ((beginOfScan % WordSize) != 0)
+ if (!beginOfScan.isMultipleOf(WordSize))
continue;
// Ignore scan requests that start before the instance start.
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 75bde3f..8cda583 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1542,7 +1542,7 @@ static llvm::TargetRegionEntryInfo getEntryInfoFromPresumedLoc(
SourceManager &SM = CGM.getContext().getSourceManager();
PresumedLoc PLoc = SM.getPresumedLoc(BeginLoc);
- if (CGM.getFileSystem()->exists(PLoc.getFilename()))
+ if (!CGM.getFileSystem()->exists(PLoc.getFilename()))
PLoc = SM.getPresumedLoc(BeginLoc, /*UseLineDirectives=*/false);
return std::pair<std::string, uint64_t>(PLoc.getFilename(), PLoc.getLine());
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 5f6136c..e9205c6 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -369,11 +369,11 @@ void CGRecordLowering::lowerUnion(bool isNonVirtualBaseType) {
appendPaddingBytes(LayoutSize - getSize(StorageType));
// Set packed if we need it.
const auto StorageAlignment = getAlignment(StorageType);
- assert((Layout.getSize() % StorageAlignment == 0 ||
- Layout.getDataSize() % StorageAlignment) &&
+ assert((Layout.getSize().isMultipleOf(StorageAlignment) ||
+ !Layout.getDataSize().isMultipleOf(StorageAlignment)) &&
"Union's standard layout and no_unique_address layout must agree on "
"packedness");
- if (Layout.getDataSize() % StorageAlignment)
+ if (!Layout.getDataSize().isMultipleOf(StorageAlignment))
Packed = true;
}
@@ -977,7 +977,7 @@ void CGRecordLowering::determinePacked(bool NVBaseType) {
continue;
// If any member falls at an offset that it not a multiple of its alignment,
// then the entire record must be packed.
- if (Member.Offset % getAlignment(Member.Data))
+ if (!Member.Offset.isMultipleOf(getAlignment(Member.Data)))
Packed = true;
if (Member.Offset < NVSize)
NVAlignment = std::max(NVAlignment, getAlignment(Member.Data));
@@ -985,12 +985,12 @@ void CGRecordLowering::determinePacked(bool NVBaseType) {
}
// If the size of the record (the capstone's offset) is not a multiple of the
// record's alignment, it must be packed.
- if (Members.back().Offset % Alignment)
+ if (!Members.back().Offset.isMultipleOf(Alignment))
Packed = true;
// If the non-virtual sub-object is not a multiple of the non-virtual
// sub-object's alignment, it must be packed. We cannot have a packed
// non-virtual sub-object and an unpacked complete object or vise versa.
- if (NVSize % NVAlignment)
+ if (!NVSize.isMultipleOf(NVAlignment))
Packed = true;
// Update the alignment of the sentinel.
if (!Packed)
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp
index 2e3fc53..4aa6314 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -486,6 +486,12 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType(
return getSPIRVImageTypeFromHLSLResource(ResAttrs, ContainedTy, CGM);
}
+ if (ResAttrs.IsCounter) {
+ llvm::Type *ElemType = llvm::Type::getInt32Ty(Ctx);
+ uint32_t StorageClass = /* StorageBuffer storage class */ 12;
+ return llvm::TargetExtType::get(Ctx, "spirv.VulkanBuffer", {ElemType},
+ {StorageClass, true});
+ }
llvm::Type *ElemType = CGM.getTypes().ConvertTypeForMem(ContainedTy);
llvm::ArrayType *RuntimeArrayType = llvm::ArrayType::get(ElemType, 0);
uint32_t StorageClass = /* StorageBuffer storage class */ 12;
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index c03ba94..fb78948 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -1343,9 +1343,10 @@ class X86_64ABIInfo : public ABIInfo {
}
bool returnCXXRecordGreaterThan128InMem() const {
- // Clang <= 20.0 did not do this.
+ // Clang <= 20.0 did not do this, and PlayStation does not do this.
if (getContext().getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver20)
+ LangOptions::ClangABI::Ver20 ||
+ getTarget().getTriple().isPS())
return false;
return true;
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 426bc52..a56fa41 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -822,6 +822,9 @@ static void addFloatingPointOptions(const Driver &D, const ArgList &Args,
complexRangeKindToStr(Range)));
}
+ if (Args.hasArg(options::OPT_fno_fast_real_mod))
+ CmdArgs.push_back("-fno-fast-real-mod");
+
if (!HonorINFs && !HonorNaNs && AssociativeMath && ReciprocalMath &&
ApproxFunc && !SignedZeros &&
(FPContract == "fast" || FPContract.empty())) {
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp
index f4858e4..2869549 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -64,7 +64,7 @@ bool isLegalShaderModel(Triple &T) {
} break;
case Triple::EnvironmentType::RootSignature:
VersionTuple MinVer(1, 0);
- VersionTuple MaxVer(1, 1);
+ VersionTuple MaxVer(1, 2);
return MinVer <= Version && Version <= MaxVer;
}
return false;
diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index 1087eb3..6966d40 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -444,8 +444,7 @@ bool ExtractAPIAction::PrepareToExecuteAction(CompilerInstance &CI) {
return true;
if (!CI.hasFileManager())
- if (!CI.createFileManager())
- return false;
+ CI.createFileManager();
auto Kind = Inputs[0].getKind();
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 9413c13..cd4c1aa 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -368,7 +368,7 @@ bool ContinuationIndenter::canBreak(const LineState &State) {
// If binary operators are moved to the next line (including commas for some
// styles of constructor initializers), that's always ok.
- if (!Current.isOneOf(TT_BinaryOperator, tok::comma) &&
+ if (Current.isNoneOf(TT_BinaryOperator, tok::comma) &&
// Allow breaking opening brace of lambdas (when passed as function
// arguments) to a new line when BeforeLambdaBody brace wrapping is
// enabled.
@@ -445,7 +445,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
(!Style.BreakBeforeTernaryOperators &&
Previous.is(TT_ConditionalExpr))) &&
CurrentState.BreakBeforeParameter && !Current.isTrailingComment() &&
- !Current.isOneOf(tok::r_paren, tok::r_brace)) {
+ Current.isNoneOf(tok::r_paren, tok::r_brace)) {
return true;
}
if (CurrentState.IsChainedConditional &&
@@ -523,9 +523,9 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
if (Style.AlwaysBreakBeforeMultilineStrings &&
(NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
Previous.is(tok::comma) || Current.NestingLevel < 2) &&
- !Previous.isOneOf(tok::kw_return, tok::lessless, tok::at,
+ Previous.isNoneOf(tok::kw_return, tok::lessless, tok::at,
Keywords.kw_dollar) &&
- !Previous.isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
+ Previous.isNoneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
nextIsMultilineString(State)) {
return true;
}
@@ -648,7 +648,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
// into the ColumnLimit, they are checked here in the ContinuationIndenter.
if (Style.ColumnLimit != 0 && Previous.is(BK_Block) &&
Previous.is(tok::l_brace) &&
- !Current.isOneOf(tok::r_brace, tok::comment)) {
+ Current.isNoneOf(tok::r_brace, tok::comment)) {
return true;
}
@@ -752,7 +752,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
return false;
const auto *Next = Comma->getNextNonComment();
- return Next && !Next->isOneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
+ return Next && Next->isNoneOf(TT_LambdaLSquare, tok::l_brace, tok::caret);
};
if (DisallowLineBreaks())
@@ -835,7 +835,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
return Tok.is(tok::l_brace) && Tok.isNot(BK_Block) &&
Style.Cpp11BracedListStyle;
};
- if (!Tok.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
+ if (Tok.isNoneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) &&
!IsStartOfBracedList()) {
return false;
}
@@ -843,7 +843,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
return true;
if (Tok.Previous->isIf())
return Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak;
- return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
+ return Tok.Previous->isNoneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
tok::kw_switch) &&
!(Style.isJavaScript() && Tok.Previous->is(Keywords.kw_await));
};
@@ -882,8 +882,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
Tok.isOneOf(tok::ellipsis, Keywords.kw_await))) {
return true;
}
- const auto *Previous = Tok.Previous;
- if (!Previous || (!Previous->isOneOf(TT_FunctionDeclarationLParen,
+ if (const auto *Previous = Tok.Previous;
+ !Previous || (Previous->isNoneOf(TT_FunctionDeclarationLParen,
TT_LambdaDefinitionLParen) &&
!IsFunctionCallParen(*Previous))) {
return true;
@@ -920,9 +920,9 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
// align the commas with the opening paren.
if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign &&
!CurrentState.IsCSharpGenericTypeConstraint && Previous.opensScope() &&
- Previous.isNot(TT_ObjCMethodExpr) && Previous.isNot(TT_RequiresClause) &&
- Previous.isNot(TT_TableGenDAGArgOpener) &&
- Previous.isNot(TT_TableGenDAGArgOpenerToBreak) &&
+ Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
+ TT_TableGenDAGArgOpener,
+ TT_TableGenDAGArgOpenerToBreak) &&
!(Current.MacroParent && Previous.MacroParent) &&
(Current.isNot(TT_LineComment) ||
Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen)) &&
@@ -962,7 +962,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
if (Current.isNot(tok::comment) && P &&
(P->isOneOf(TT_BinaryOperator, tok::comma) ||
(P->is(TT_ConditionalExpr) && P->is(tok::colon))) &&
- !P->isOneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
+ P->isNoneOf(TT_OverloadedOperator, TT_CtorInitializerComma) &&
P->getPrecedence() != prec::Assignment &&
P->getPrecedence() != prec::Relational &&
P->getPrecedence() != prec::Spaceship) {
@@ -992,7 +992,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
// parameter, i.e. let nested calls have a continuation indent.
CurrentState.LastSpace = State.Column;
CurrentState.NestedBlockIndent = State.Column;
- } else if (!Current.isOneOf(tok::comment, tok::caret) &&
+ } else if (Current.isNoneOf(tok::comment, tok::caret) &&
((Previous.is(tok::comma) &&
Previous.isNot(TT_OverloadedOperator)) ||
(Previous.is(tok::colon) && Previous.is(TT_ObjCMethodExpr)))) {
@@ -1099,7 +1099,7 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
if (Current.isNot(TT_LambdaArrow) &&
(!Style.isJavaScript() || Current.NestingLevel != 0 ||
!PreviousNonComment || PreviousNonComment->isNot(tok::equal) ||
- !Current.isOneOf(Keywords.kw_async, Keywords.kw_function))) {
+ Current.isNoneOf(Keywords.kw_async, Keywords.kw_function))) {
CurrentState.NestedBlockIndent = State.Column;
}
@@ -1239,11 +1239,11 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
}
if (PreviousNonComment &&
- !PreviousNonComment->isOneOf(tok::comma, tok::colon, tok::semi) &&
+ PreviousNonComment->isNoneOf(tok::comma, tok::colon, tok::semi) &&
((PreviousNonComment->isNot(TT_TemplateCloser) &&
!PreviousNonComment->ClosesRequiresClause) ||
Current.NestingLevel != 0) &&
- !PreviousNonComment->isOneOf(
+ PreviousNonComment->isNoneOf(
TT_BinaryOperator, TT_FunctionAnnotationRParen, TT_JavaAnnotation,
TT_LeadingJavaAnnotation) &&
Current.isNot(TT_BinaryOperator) && !PreviousNonComment->opensScope() &&
@@ -1281,8 +1281,8 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
bool AllowAllConstructorInitializersOnNextLine =
Style.PackConstructorInitializers == FormatStyle::PCIS_NextLine ||
Style.PackConstructorInitializers == FormatStyle::PCIS_NextLineOnly;
- if (!(Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
- PreviousIsBreakingCtorInitializerColon) ||
+ if ((Previous.isNoneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) &&
+ !PreviousIsBreakingCtorInitializerColon) ||
(!Style.AllowAllParametersOfDeclarationOnNextLine &&
State.Line->MustBeDeclaration) ||
(!Style.AllowAllArgumentsOnNextLine &&
@@ -1576,7 +1576,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
if (Previous.is(tok::r_paren) &&
Previous.isNot(TT_TableGenDAGArgOperatorToBreak) &&
!Current.isBinaryOperator() &&
- !Current.isOneOf(tok::colon, tok::comment)) {
+ Current.isNoneOf(tok::colon, tok::comment)) {
return ContinuationIndent;
}
if (Current.is(TT_ProtoExtensionLSquare))
@@ -1591,7 +1591,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
NextNonComment->SpacesRequiredBefore;
}
if (CurrentState.Indent == State.FirstIndent && PreviousNonComment &&
- !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma)) {
+ PreviousNonComment->isNoneOf(tok::r_brace, TT_CtorInitializerComma)) {
// Ensure that we fall back to the continuation indent width instead of
// just flushing continuations left.
return CurrentState.Indent + Style.ContinuationIndentWidth;
@@ -1734,7 +1734,7 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
}
if (Previous && (Previous->isOneOf(TT_BinaryOperator, TT_ConditionalExpr) ||
(Previous->isOneOf(tok::l_paren, tok::comma, tok::colon) &&
- !Previous->isOneOf(TT_DictLiteral, TT_ObjCMethodExpr,
+ Previous->isNoneOf(TT_DictLiteral, TT_ObjCMethodExpr,
TT_CtorInitializerColon)))) {
CurrentState.NestedBlockInlined =
!Newline && hasNestedBlockInlined(Previous, Current, Style);
@@ -1758,7 +1758,7 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
State.StartOfStringLiteral = State.Column + 1;
} else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
State.StartOfStringLiteral = State.Column;
- } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
+ } else if (Current.isNoneOf(tok::comment, tok::identifier, tok::hash) &&
!Current.isStringLiteral()) {
State.StartOfStringLiteral = 0;
}
@@ -2057,7 +2057,7 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
// array literals as these follow different indentation rules.
bool NoLineBreak =
Current.Children.empty() &&
- !Current.isOneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
+ Current.isNoneOf(TT_DictLiteral, TT_ArrayInitializerLSquare) &&
(CurrentState.NoLineBreak || CurrentState.NoLineBreakInOperand ||
(Current.is(TT_TemplateOpener) &&
CurrentState.ContainsUnwrappedBuilder));
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 835071d..2bf6244 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -2435,7 +2435,7 @@ private:
const auto *NextLine = I + 1 == End ? nullptr : I[1];
for (const auto *Token = Line->First; Token && !Token->Finalized;
Token = Token->Next) {
- if (!Token->Optional || !Token->isOneOf(tok::l_brace, tok::r_brace))
+ if (!Token->Optional || Token->isNoneOf(tok::l_brace, tok::r_brace))
continue;
auto *Next = Token->Next;
assert(Next || Token == Line->Last);
diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp
index c60ae8f..c2956a1 100644
--- a/clang/lib/Format/FormatToken.cpp
+++ b/clang/lib/Format/FormatToken.cpp
@@ -108,7 +108,7 @@ unsigned CommaSeparatedList::formatAfterToken(LineState &State,
// Ensure that we start on the opening brace.
const FormatToken *LBrace =
State.NextToken->Previous->getPreviousNonComment();
- if (!LBrace || !LBrace->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
+ if (!LBrace || LBrace->isNoneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
LBrace->is(BK_Block) || LBrace->is(TT_DictLiteral) ||
LBrace->Next->is(TT_DesignatedInitializerPeriod)) {
return 0;
@@ -177,7 +177,7 @@ static unsigned CodePointsBetween(const FormatToken *Begin,
void CommaSeparatedList::precomputeFormattingInfos(const FormatToken *Token) {
// FIXME: At some point we might want to do this for other lists, too.
if (!Token->MatchingParen ||
- !Token->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)) {
+ Token->isNoneOf(tok::l_brace, TT_ArrayInitializerLSquare)) {
return;
}
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index a28446a..e4ddd61 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -645,6 +645,9 @@ public:
return is(K1) || isOneOf(K2, Ks...);
}
template <typename T> bool isNot(T Kind) const { return !is(Kind); }
+ template <typename... Ts> bool isNoneOf(Ts... Ks) const {
+ return !isOneOf(Ks...);
+ }
bool isIf(bool AllowConstexprMacro = true) const {
return is(tok::kw_if) || endsSequence(tok::kw_constexpr, tok::kw_if) ||
@@ -748,7 +751,7 @@ public:
/// Returns \c true if this is a "." or "->" accessing a member.
bool isMemberAccess() const {
return isOneOf(tok::arrow, tok::period, tok::arrowstar) &&
- !isOneOf(TT_DesignatedInitializerPeriod, TT_TrailingReturnArrow,
+ isNoneOf(TT_DesignatedInitializerPeriod, TT_TrailingReturnArrow,
TT_LambdaArrow, TT_LeadingJavaAnnotation);
}
diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp
index 3f4aa52..86a5185 100644
--- a/clang/lib/Format/FormatTokenLexer.cpp
+++ b/clang/lib/Format/FormatTokenLexer.cpp
@@ -733,7 +733,7 @@ void FormatTokenLexer::tryParseJavaTextBlock() {
// its text if successful.
void FormatTokenLexer::tryParseJSRegexLiteral() {
FormatToken *RegexToken = Tokens.back();
- if (!RegexToken->isOneOf(tok::slash, tok::slashequal))
+ if (RegexToken->isNoneOf(tok::slash, tok::slashequal))
return;
FormatToken *Prev = nullptr;
@@ -1041,7 +1041,7 @@ void FormatTokenLexer::handleTemplateStrings() {
void FormatTokenLexer::tryParsePythonComment() {
FormatToken *HashToken = Tokens.back();
- if (!HashToken->isOneOf(tok::hash, tok::hashhash))
+ if (HashToken->isNoneOf(tok::hash, tok::hashhash))
return;
// Turn the remainder of this line into a comment.
const char *CommentBegin =
diff --git a/clang/lib/Format/MacroExpander.cpp b/clang/lib/Format/MacroExpander.cpp
index 85a53c9..445e173 100644
--- a/clang/lib/Format/MacroExpander.cpp
+++ b/clang/lib/Format/MacroExpander.cpp
@@ -86,7 +86,7 @@ private:
}
bool parseExpansion() {
- if (!Current->isOneOf(tok::equal, tok::eof))
+ if (Current->isNoneOf(tok::equal, tok::eof))
return false;
if (Current->is(tok::equal))
nextToken();
diff --git a/clang/lib/Format/NamespaceEndCommentsFixer.cpp b/clang/lib/Format/NamespaceEndCommentsFixer.cpp
index 08f8d68..95ccfac 100644
--- a/clang/lib/Format/NamespaceEndCommentsFixer.cpp
+++ b/clang/lib/Format/NamespaceEndCommentsFixer.cpp
@@ -70,7 +70,7 @@ std::string computeName(const FormatToken *NamespaceTok) {
// and closing parenthesis or comma.
assert(Tok && Tok->is(tok::l_paren) && "expected an opening parenthesis");
Tok = Tok->getNextNonComment();
- while (Tok && !Tok->isOneOf(tok::r_paren, tok::comma)) {
+ while (Tok && Tok->isNoneOf(tok::r_paren, tok::comma)) {
name += Tok->TokenText;
Tok = Tok->getNextNonComment();
}
@@ -85,7 +85,7 @@ std::string computeName(const FormatToken *NamespaceTok) {
// one token before that up until the '{'. A '(' might be a macro with
// arguments.
const FormatToken *FirstNSTok = nullptr;
- while (Tok && !Tok->isOneOf(tok::l_brace, tok::coloncolon, tok::l_paren)) {
+ while (Tok && Tok->isNoneOf(tok::l_brace, tok::coloncolon, tok::l_paren)) {
if (FirstNSTok)
FirstNSName += FirstNSTok->TokenText;
FirstNSTok = Tok;
diff --git a/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp b/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp
index b885942..b12b370 100644
--- a/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp
+++ b/clang/lib/Format/ObjCPropertyAttributeOrderFixer.cpp
@@ -61,7 +61,7 @@ void ObjCPropertyAttributeOrderFixer::sortPropertyAttributes(
}
// Most attributes look like identifiers, but `class` is a keyword.
- if (!Tok->isOneOf(tok::identifier, tok::kw_class)) {
+ if (Tok->isNoneOf(tok::identifier, tok::kw_class)) {
// If we hit any other kind of token, just bail.
return;
}
diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp
index 043d957..e3e30ca 100644
--- a/clang/lib/Format/QualifierAlignmentFixer.cpp
+++ b/clang/lib/Format/QualifierAlignmentFixer.cpp
@@ -508,7 +508,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft(
// Don't change declarations such as
// `foo(struct Foo const a);` -> `foo(struct Foo const a);`
- if (!Previous || !Previous->isOneOf(tok::kw_struct, tok::kw_class)) {
+ if (!Previous || Previous->isNoneOf(tok::kw_struct, tok::kw_class)) {
insertQualifierBefore(SourceMgr, Fixes, TypeToken, Qualifier);
removeToken(SourceMgr, Fixes, Tok);
}
diff --git a/clang/lib/Format/SortJavaScriptImports.cpp b/clang/lib/Format/SortJavaScriptImports.cpp
index ace3dff..a403a4f 100644
--- a/clang/lib/Format/SortJavaScriptImports.cpp
+++ b/clang/lib/Format/SortJavaScriptImports.cpp
@@ -439,7 +439,7 @@ private:
// for grammar EBNF (production ModuleItem).
bool parseModuleReference(const AdditionalKeywords &Keywords,
JsModuleReference &Reference) {
- if (!Current || !Current->isOneOf(Keywords.kw_import, tok::kw_export))
+ if (!Current || Current->isNoneOf(Keywords.kw_import, tok::kw_export))
return false;
Reference.IsExport = Current->is(tok::kw_export);
@@ -570,7 +570,7 @@ private:
Symbol.Range.setEnd(Current->Tok.getLocation());
Reference.Symbols.push_back(Symbol);
- if (!Current->isOneOf(tok::r_brace, tok::comma))
+ if (Current->isNoneOf(tok::r_brace, tok::comma))
return false;
}
Reference.SymbolsEnd = Current->Tok.getLocation();
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 0c9c88a..59f81b3 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -203,7 +203,7 @@ private:
return false;
}
if (InExpr && SeenTernaryOperator &&
- (!Next || !Next->isOneOf(tok::l_paren, tok::l_brace))) {
+ (!Next || Next->isNoneOf(tok::l_paren, tok::l_brace))) {
return false;
}
if (!MaybeAngles)
@@ -577,7 +577,7 @@ private:
if (IsIf && CurrentToken->is(tok::semi)) {
for (auto *Tok = OpeningParen.Next;
Tok != CurrentToken &&
- !Tok->isOneOf(tok::equal, tok::l_paren, tok::l_brace);
+ Tok->isNoneOf(tok::equal, tok::l_paren, tok::l_brace);
Tok = Tok->Next) {
if (Tok->isPointerOrReference())
Tok->setFinalizedType(TT_PointerOrReference);
@@ -704,7 +704,7 @@ private:
!IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&
IsCpp && !IsCpp11AttributeSpecifier && !IsCSharpAttributeSpecifier &&
Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
- !CurrentToken->isOneOf(tok::l_brace, tok::r_square) &&
+ CurrentToken->isNoneOf(tok::l_brace, tok::r_square) &&
(!Parent ||
Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
tok::kw_return, tok::kw_throw) ||
@@ -1334,7 +1334,7 @@ private:
if (Style.isJavaScript()) {
if (Contexts.back().ColonIsForRangeExpr || // colon in for loop
(Contexts.size() == 1 && // switch/case labels
- !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) ||
+ Line.First->isNoneOf(tok::kw_enum, tok::kw_case)) ||
Contexts.back().ContextKind == tok::l_paren || // function params
Contexts.back().ContextKind == tok::l_square || // array type
(!Contexts.back().IsExpression &&
@@ -1411,7 +1411,7 @@ private:
} else if (Contexts.back().ColonIsForRangeExpr) {
Tok->setType(TT_RangeBasedForLoopColon);
for (auto *Token = Prev;
- Token && !Token->isOneOf(tok::semi, tok::l_paren);
+ Token && Token->isNoneOf(tok::semi, tok::l_paren);
Token = Token->Previous) {
if (Token->isPointerOrReference())
Token->setFinalizedType(TT_PointerOrReference);
@@ -1425,7 +1425,7 @@ private:
Scopes.back() == ST_Class)) {
Tok->setType(TT_BitFieldColon);
} else if (Contexts.size() == 1 &&
- !Line.getFirstNonComment()->isOneOf(tok::kw_enum, tok::kw_case,
+ Line.getFirstNonComment()->isNoneOf(tok::kw_enum, tok::kw_case,
tok::kw_default) &&
!Line.startsWith(tok::kw_typedef, tok::kw_enum)) {
if (Prev->isOneOf(tok::r_paren, tok::kw_noexcept) ||
@@ -1562,10 +1562,10 @@ private:
if (Line.MustBeDeclaration && Contexts.size() == 1 &&
!Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
!Line.startsWith(tok::l_paren) &&
- !Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen)) {
+ Tok->isNoneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen)) {
if (!Prev ||
(!Prev->isAttribute() &&
- !Prev->isOneOf(TT_RequiresClause, TT_LeadingJavaAnnotation,
+ Prev->isNoneOf(TT_RequiresClause, TT_LeadingJavaAnnotation,
TT_BinaryOperator))) {
Line.MightBeFunctionDecl = true;
Tok->MightBeFunctionDeclParen = true;
@@ -1664,7 +1664,7 @@ private:
}
}
while (CurrentToken &&
- !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
+ CurrentToken->isNoneOf(tok::l_paren, tok::semi, tok::r_paren)) {
if (CurrentToken->isOneOf(tok::star, tok::amp))
CurrentToken->setType(TT_PointerOrReference);
auto Next = CurrentToken->getNextNonComment();
@@ -1728,8 +1728,8 @@ private:
// cond ? id : "B";
// cond ? cond2 ? "A" : "B" : "C";
if (!Contexts.back().IsExpression && Line.MustBeDeclaration &&
- (!Next || !Next->isOneOf(tok::identifier, tok::string_literal) ||
- !Next->Next || !Next->Next->isOneOf(tok::colon, tok::question))) {
+ (!Next || Next->isNoneOf(tok::identifier, tok::string_literal) ||
+ !Next->Next || Next->Next->isNoneOf(tok::colon, tok::question))) {
Tok->setType(TT_CSharpNullable);
break;
}
@@ -1796,7 +1796,7 @@ private:
if (!parseTableGenValue())
return false;
} else if (Tok->isOneOf(Keywords.kw_def, Keywords.kw_defm) &&
- (!Next || !Next->isOneOf(tok::colon, tok::l_brace))) {
+ (!Next || Next->isNoneOf(tok::colon, tok::l_brace))) {
// The case NameValue appears.
if (!parseTableGenValue(true))
return false;
@@ -2094,7 +2094,7 @@ private:
// Reset token type in case we have already looked at it and then
// recovered from an error (e.g. failure to find the matching >).
if (!CurrentToken->isTypeFinalized() &&
- !CurrentToken->isOneOf(
+ CurrentToken->isNoneOf(
TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,
TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,
TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,
@@ -2230,7 +2230,7 @@ private:
// type or non-type.
if (Contexts.back().ContextKind == tok::less) {
assert(Current.Previous->Previous);
- return !Current.Previous->Previous->isOneOf(tok::kw_typename,
+ return Current.Previous->Previous->isNoneOf(tok::kw_typename,
tok::kw_class);
}
@@ -2266,7 +2266,7 @@ private:
if (!Line.startsWith(TT_UnaryOperator)) {
for (FormatToken *Previous = Current.Previous;
Previous && Previous->Previous &&
- !Previous->Previous->isOneOf(tok::comma, tok::semi);
+ Previous->Previous->isNoneOf(tok::comma, tok::semi);
Previous = Previous->Previous) {
if (Previous->isOneOf(tok::r_square, tok::r_paren, tok::greater)) {
Previous = Previous->MatchingParen;
@@ -2430,7 +2430,7 @@ private:
Current.setType(TT_BinaryOperator);
} else if (Current.is(tok::arrow) && AutoFound &&
Line.MightBeFunctionDecl && Current.NestingLevel == 0 &&
- !Current.Previous->isOneOf(tok::kw_operator, tok::identifier)) {
+ Current.Previous->isNoneOf(tok::kw_operator, tok::identifier)) {
// not auto operator->() -> xxx;
Current.setType(TT_TrailingReturnArrow);
} else if (Current.is(tok::arrow) && Current.Previous &&
@@ -2511,7 +2511,7 @@ private:
Current.setType(TT_CastRParen);
if (Current.MatchingParen && Current.Next &&
!Current.Next->isBinaryOperator() &&
- !Current.Next->isOneOf(
+ Current.Next->isNoneOf(
tok::semi, tok::colon, tok::l_brace, tok::l_paren, tok::comma,
tok::period, tok::arrow, tok::coloncolon, tok::kw_noexcept)) {
if (FormatToken *AfterParen = Current.MatchingParen->Next;
@@ -2569,7 +2569,7 @@ private:
} else if (Current.isOneOf(tok::identifier, tok::kw_const, tok::kw_noexcept,
tok::kw_requires) &&
Current.Previous &&
- !Current.Previous->isOneOf(tok::equal, tok::at,
+ Current.Previous->isNoneOf(tok::equal, tok::at,
TT_CtorInitializerComma,
TT_CtorInitializerColon) &&
Line.MightBeFunctionDecl && Contexts.size() == 1) {
@@ -2658,7 +2658,7 @@ private:
if (PreviousNotConst->is(TT_TemplateCloser)) {
return PreviousNotConst && PreviousNotConst->MatchingParen &&
PreviousNotConst->MatchingParen->Previous &&
- !PreviousNotConst->MatchingParen->Previous->isOneOf(
+ PreviousNotConst->MatchingParen->Previous->isNoneOf(
tok::period, tok::kw_template);
}
@@ -2780,7 +2780,7 @@ private:
// If there is an identifier (or with a few exceptions a keyword) right
// before the parentheses, this is unlikely to be a cast.
if (LeftOfParens->Tok.getIdentifierInfo() &&
- !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
+ LeftOfParens->isNoneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
tok::kw_delete, tok::kw_throw)) {
return false;
}
@@ -2918,7 +2918,7 @@ private:
const bool NextIsAmpOrStar = AfterRParen->isOneOf(tok::amp, tok::star);
if (!(AfterRParen->isUnaryOperator() || NextIsAmpOrStar) ||
AfterRParen->is(tok::plus) ||
- !AfterRParen->Next->isOneOf(tok::identifier, tok::numeric_constant)) {
+ AfterRParen->Next->isNoneOf(tok::identifier, tok::numeric_constant)) {
return false;
}
@@ -2948,7 +2948,7 @@ private:
// Search for unexpected tokens.
for (Prev = BeforeRParen; Prev != LParen; Prev = Prev->Previous)
- if (!Prev->isOneOf(tok::kw_const, tok::identifier, tok::coloncolon))
+ if (Prev->isNoneOf(tok::kw_const, tok::identifier, tok::coloncolon))
return false;
return true;
@@ -3740,7 +3740,7 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) {
const bool InRequiresExpression = Line.Type == LT_RequiresExpression;
for (auto &Child : Line.Children) {
if (InRequiresExpression &&
- !Child->First->isOneOf(tok::kw_typename, tok::kw_requires,
+ Child->First->isNoneOf(tok::kw_typename, tok::kw_requires,
TT_CompoundRequirementLBrace)) {
Child->Type = LT_SimpleRequirement;
}
@@ -3857,7 +3857,7 @@ static bool isFunctionDeclarationName(const LangOptions &LangOpts,
// Find parentheses of parameter list.
if (Current.is(tok::kw_operator)) {
if (Previous.Tok.getIdentifierInfo() &&
- !Previous.isOneOf(tok::kw_return, tok::kw_co_return)) {
+ Previous.isNoneOf(tok::kw_return, tok::kw_co_return)) {
return true;
}
if (Previous.is(tok::r_paren) && Previous.is(TT_TypeDeclarationParen)) {
@@ -4328,7 +4328,7 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
// Slightly prefer formatting local lambda definitions like functions.
if (Right.is(TT_LambdaLSquare) && Left.is(tok::equal))
return 35;
- if (!Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
+ if (Right.isNoneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
TT_ArrayInitializerLSquare,
TT_DesignatedInitializerLSquare, TT_AttributeSquare)) {
return 500;
@@ -4519,7 +4519,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
const FormatToken &Left,
const FormatToken &Right) const {
if (Left.is(tok::kw_return) &&
- !Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) {
+ Right.isNoneOf(tok::semi, tok::r_paren, tok::hashhash)) {
return true;
}
if (Left.is(tok::kw_throw) && Right.is(tok::l_paren) && Right.MatchingParen &&
@@ -4579,7 +4579,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
}
// co_await (x), co_yield (x), co_return (x)
if (Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) &&
- !Right.isOneOf(tok::semi, tok::r_paren)) {
+ Right.isNoneOf(tok::semi, tok::r_paren)) {
return true;
}
@@ -4656,7 +4656,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
return getTokenPointerOrReferenceAlignment(Right) !=
FormatStyle::PAS_Left;
}
- return !Left.isOneOf(TT_PointerOrReference, tok::l_paren) &&
+ return Left.isNoneOf(TT_PointerOrReference, tok::l_paren) &&
(getTokenPointerOrReferenceAlignment(Right) !=
FormatStyle::PAS_Left ||
(Line.IsMultiVariableDeclStmt &&
@@ -4729,7 +4729,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
const auto *LParen = Right.Next->MatchingParen;
return !LParen || LParen->isNot(TT_FunctionTypeLParen);
}
- return !BeforeLeft->isOneOf(tok::l_paren, tok::l_square);
+ return BeforeLeft->isNoneOf(tok::l_paren, tok::l_square);
}
// Ensure right pointer alignment with ellipsis e.g. int *...P
if (Left.is(tok::ellipsis) && BeforeLeft &&
@@ -4808,10 +4808,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
TT_LambdaLSquare)));
}
if (Right.is(tok::l_square) &&
- !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
+ Right.isNoneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
TT_DesignatedInitializerLSquare,
TT_StructuredBindingLSquare, TT_AttributeSquare) &&
- !Left.isOneOf(tok::numeric_constant, TT_DictLiteral) &&
+ Left.isNoneOf(tok::numeric_constant, TT_DictLiteral) &&
!(Left.isNot(tok::r_square) && Style.SpaceBeforeSquareBrackets &&
Right.is(TT_ArraySubscriptLSquare))) {
return false;
@@ -4894,7 +4894,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
return Style.SpaceBeforeParensOptions.AfterFunctionDefinitionName ||
spaceRequiredBeforeParens(Right);
}
- if (!BeforeLeft || !BeforeLeft->isOneOf(tok::period, tok::arrow)) {
+ if (!BeforeLeft || BeforeLeft->isNoneOf(tok::period, tok::arrow)) {
if (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch)) {
return Style.SpaceBeforeParensOptions.AfterControlStatements ||
spaceRequiredBeforeParens(Right);
@@ -4917,7 +4917,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if (Left.is(tok::at) && Right.isNot(tok::objc_not_keyword))
return false;
if (Right.is(TT_UnaryOperator)) {
- return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
+ return Left.isNoneOf(tok::l_paren, tok::l_square, tok::at) &&
(Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
}
// No space between the variable name and the initializer list.
@@ -5260,7 +5260,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
if (Left.is(tok::ellipsis))
return false;
if (Left.is(TT_TemplateCloser) &&
- !Right.isOneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
+ Right.isNoneOf(tok::equal, tok::l_brace, tok::comma, tok::l_square,
Keywords.kw_implements, Keywords.kw_extends)) {
// Type assertions ('<type>expr') are not followed by whitespace. Other
// locations that should have whitespace following are identified by the
@@ -5299,7 +5299,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
// Add space between things in a primitive's state table unless in a
// transition like `(0?)`.
if ((Left.is(TT_VerilogTableItem) &&
- !Right.isOneOf(tok::r_paren, tok::semi)) ||
+ Right.isNoneOf(tok::r_paren, tok::semi)) ||
(Right.is(TT_VerilogTableItem) && Left.isNot(tok::l_paren))) {
const FormatToken *Next = Right.getNextNonComment();
return !(Next && Next->is(tok::r_paren));
@@ -5348,8 +5348,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
// previous rule.
if ((Right.is(Keywords.kw_apostrophe) ||
(Right.is(BK_BracedInit) && Right.is(tok::l_brace))) &&
- !(Left.isOneOf(Keywords.kw_assign, Keywords.kw_unique) ||
- Keywords.isVerilogWordOperator(Left)) &&
+ Left.isNoneOf(Keywords.kw_assign, Keywords.kw_unique) &&
+ !Keywords.isVerilogWordOperator(Left) &&
(Left.isOneOf(tok::r_square, tok::r_paren, tok::r_brace,
tok::numeric_constant) ||
Keywords.isWordLike(Left))) {
@@ -5549,14 +5549,14 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
return Right.hasWhitespaceBefore();
}
if (Right.is(tok::coloncolon) &&
- !Left.isOneOf(tok::l_brace, tok::comment, tok::l_paren)) {
+ Left.isNoneOf(tok::l_brace, tok::comment, tok::l_paren)) {
// Put a space between < and :: in vector< ::std::string >
return (Left.is(TT_TemplateOpener) &&
((Style.Standard < FormatStyle::LS_Cpp11) ||
ShouldAddSpacesInAngles())) ||
- !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
- tok::kw___super, TT_TemplateOpener,
- TT_TemplateCloser)) ||
+ Left.isNoneOf(tok::l_paren, tok::r_paren, tok::l_square,
+ tok::kw___super, TT_TemplateOpener,
+ TT_TemplateCloser) ||
(Left.is(tok::l_paren) && Style.SpacesInParensOptions.Other);
}
if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
@@ -5567,7 +5567,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
}
// Space before TT_StructuredBindingLSquare.
if (Right.is(TT_StructuredBindingLSquare)) {
- return !Left.isOneOf(tok::amp, tok::ampamp) ||
+ return Left.isNoneOf(tok::amp, tok::ampamp) ||
getTokenReferenceAlignment(Left) != FormatStyle::PAS_Right;
}
// Space before & or && following a TT_StructuredBindingLSquare.
@@ -5599,7 +5599,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
// Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
static bool isAllmanBrace(const FormatToken &Tok) {
return Tok.is(tok::l_brace) && Tok.is(BK_Block) &&
- !Tok.isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
+ Tok.isNoneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
}
// Returns 'true' if 'Tok' is a function argument.
@@ -5617,7 +5617,7 @@ isEmptyLambdaAllowed(const FormatToken &Tok,
static bool isAllmanLambdaBrace(const FormatToken &Tok) {
return Tok.is(tok::l_brace) && Tok.is(BK_Block) &&
- !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
+ Tok.isNoneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
}
bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
@@ -5686,7 +5686,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
tok::kw_const) &&
// kw_var/kw_let are pseudo-tokens that are tok::identifier, so match
// above.
- !Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let)) {
+ Line.First->isNoneOf(Keywords.kw_var, Keywords.kw_let)) {
// Object literals on the top level of a file are treated as "enum-style".
// Each key/value pair is put on a separate line, instead of bin-packing.
return true;
@@ -5831,7 +5831,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
}
if (Right.is(tok::comment)) {
- return !Left.isOneOf(BK_BracedInit, TT_CtorInitializerColon) &&
+ return Left.isNoneOf(BK_BracedInit, TT_CtorInitializerColon) &&
Right.NewlinesBefore > 0 && Right.HasUnescapedNewline;
}
if (Left.isTrailingComment())
@@ -5873,7 +5873,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
case FormatStyle::RCPS_WithPreceding:
return Right.isNot(tok::semi);
case FormatStyle::RCPS_OwnLineWithBrace:
- return !Right.isOneOf(tok::semi, tok::l_brace);
+ return Right.isNoneOf(tok::semi, tok::l_brace);
default:
break;
}
@@ -6000,7 +6000,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// Put multiple Java annotation on a new line.
if ((Style.isJava() || Style.isJavaScript()) &&
Left.is(TT_LeadingJavaAnnotation) &&
- !Right.isOneOf(TT_LeadingJavaAnnotation, tok::l_paren) &&
+ Right.isNoneOf(TT_LeadingJavaAnnotation, tok::l_paren) &&
(Line.Last->is(tok::l_brace) || Style.BreakAfterJavaFieldAnnotations)) {
return true;
}
@@ -6206,7 +6206,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
return false;
// Avoid to break after '(' in the cases that is in bang operators.
if (Right.is(tok::l_paren)) {
- return !Left.isOneOf(TT_TableGenBangOperator, TT_TableGenCondOperator,
+ return Left.isNoneOf(TT_TableGenBangOperator, TT_TableGenCondOperator,
TT_TemplateCloser);
}
// Avoid to break between the value and its suffix part.
@@ -6294,7 +6294,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
}
if (Right.is(tok::colon) &&
- !Right.isOneOf(TT_CtorInitializerColon, TT_InlineASMColon,
+ Right.isNoneOf(TT_CtorInitializerColon, TT_InlineASMColon,
TT_BitFieldColon)) {
return false;
}
@@ -6378,7 +6378,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
}
if (Left.isOneOf(TT_TemplateCloser, TT_UnaryOperator, tok::kw_operator))
return false;
- if (Left.is(tok::equal) && !Right.isOneOf(tok::kw_default, tok::kw_delete) &&
+ if (Left.is(tok::equal) && Right.isNoneOf(tok::kw_default, tok::kw_delete) &&
Line.Type == LT_VirtualFunctionDecl && Left.NestingLevel == 0) {
return false;
}
@@ -6405,7 +6405,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
// Allow breaking after a trailing annotation, e.g. after a method
// declaration.
if (Left.is(TT_TrailingAnnotation)) {
- return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
+ return Right.isNoneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
tok::less, tok::coloncolon);
}
@@ -6448,7 +6448,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
return true;
if ((Left.isBinaryOperator() || Left.is(TT_BinaryOperator)) &&
- !Left.isOneOf(tok::arrowstar, tok::lessless) &&
+ Left.isNoneOf(tok::arrowstar, tok::lessless) &&
Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&
(Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||
Left.getPrecedence() == prec::Assignment)) {
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index ac9d147..ac9c81d 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -506,7 +506,7 @@ private:
(NextLine.First->is(tok::r_brace) &&
!Style.BraceWrapping.SplitEmptyRecord);
} else if (TheLine->InPPDirective ||
- !TheLine->First->isOneOf(tok::kw_class, tok::kw_enum,
+ TheLine->First->isNoneOf(tok::kw_class, tok::kw_enum,
tok::kw_struct)) {
// Try to merge a block with left brace unwrapped that wasn't yet
// covered.
@@ -686,8 +686,8 @@ private:
}
Limit = limitConsideringMacros(I + 1, E, Limit);
AnnotatedLine &Line = **I;
- if (Line.First->isNot(tok::kw_do) && Line.First->isNot(tok::kw_else) &&
- Line.Last->isNot(tok::kw_else) && Line.Last->isNot(tok::r_paren)) {
+ if (Line.First->isNoneOf(tok::kw_do, tok::kw_else) &&
+ Line.Last->isNoneOf(tok::kw_else, tok::r_paren)) {
return 0;
}
// Only merge `do while` if `do` is the only statement on the line.
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 6948b3d..2879743 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -405,7 +405,7 @@ bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
case tok::r_brace:
if (OpeningBrace) {
if (!Style.RemoveBracesLLVM || Line->InPPDirective ||
- !OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
+ OpeningBrace->isNoneOf(TT_ControlStatementLBrace, TT_ElseLBrace)) {
return false;
}
if (FormatTok->isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
@@ -427,7 +427,7 @@ bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
unsigned StoredPosition = Tokens->getPosition();
auto *Next = Tokens->getNextNonComment();
FormatTok = Tokens->setPosition(StoredPosition);
- if (!Next->isOneOf(tok::colon, tok::arrow)) {
+ if (Next->isNoneOf(tok::colon, tok::arrow)) {
// default not followed by `:` or `->` is not a case label; treat it
// like an identifier.
parseStructuralElement();
@@ -584,7 +584,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
ProbablyBracedList =
ProbablyBracedList ||
(NextTok->is(tok::identifier) &&
- !PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace));
+ PrevTok->isNoneOf(tok::semi, tok::r_brace, tok::l_brace));
ProbablyBracedList = ProbablyBracedList ||
(NextTok->is(tok::semi) &&
@@ -607,7 +607,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
// A statement can end with only `;` (simple statement), a block
// closing brace (compound statement), or `:` (label statement).
// If PrevTok is a block opening brace, Tok ends an empty block.
- !PrevTok->isOneOf(tok::semi, BK_Block, tok::colon)) {
+ PrevTok->isNoneOf(tok::semi, BK_Block, tok::colon)) {
ProbablyBracedList = true;
}
}
@@ -1157,7 +1157,7 @@ void UnwrappedLineParser::parsePPDefine() {
IncludeGuard = IG_Defined;
IncludeGuardToken = nullptr;
for (auto &Line : Lines) {
- if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
+ if (Line.Tokens.front().Tok->isNoneOf(tok::comment, tok::hash)) {
IncludeGuard = IG_Rejected;
break;
}
@@ -1233,7 +1233,7 @@ void UnwrappedLineParser::parsePPUnknown() {
static bool tokenCanStartNewLine(const FormatToken &Tok) {
// Semicolon can be a null-statement, l_square can be a start of a macro or
// a C++11 attribute, but this doesn't seem to be common.
- return !Tok.isOneOf(tok::semi, tok::l_brace,
+ return Tok.isNoneOf(tok::semi, tok::l_brace,
// Tokens that can only be used as binary operators and a
// part of overloaded operator names.
tok::period, tok::periodstar, tok::arrow, tok::arrowstar,
@@ -1256,7 +1256,7 @@ static bool mustBeJSIdent(const AdditionalKeywords &Keywords,
// FIXME: This returns true for C/C++ keywords like 'struct'.
return FormatTok->is(tok::identifier) &&
(!FormatTok->Tok.getIdentifierInfo() ||
- !FormatTok->isOneOf(
+ FormatTok->isNoneOf(
Keywords.kw_in, Keywords.kw_of, Keywords.kw_as, Keywords.kw_async,
Keywords.kw_await, Keywords.kw_yield, Keywords.kw_finally,
Keywords.kw_function, Keywords.kw_import, Keywords.kw_is,
@@ -1322,7 +1322,7 @@ static bool isC78ParameterDecl(const FormatToken *Tok, const FormatToken *Next,
return false;
if (!isC78Type(*Tok) &&
- !Tok->isOneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
+ Tok->isNoneOf(tok::kw_register, tok::kw_struct, tok::kw_union)) {
return false;
}
@@ -1345,7 +1345,7 @@ bool UnwrappedLineParser::parseModuleImport() {
if (auto Token = Tokens->peekNextToken(/*SkipComment=*/true);
!Token->Tok.getIdentifierInfo() &&
- !Token->isOneOf(tok::colon, tok::less, tok::string_literal)) {
+ Token->isNoneOf(tok::colon, tok::less, tok::string_literal)) {
return false;
}
@@ -1357,7 +1357,7 @@ bool UnwrappedLineParser::parseModuleImport() {
// Handle import <foo/bar.h> as we would an include statement.
else if (FormatTok->is(tok::less)) {
nextToken();
- while (!FormatTok->isOneOf(tok::semi, tok::greater) && !eof()) {
+ while (FormatTok->isNoneOf(tok::semi, tok::greater) && !eof()) {
// Mark tokens up to the trailing line comments as implicit string
// literals.
if (FormatTok->isNot(tok::comment) &&
@@ -2394,13 +2394,13 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
const auto *BeforeRParen = Previous->getPreviousNonComment();
// Lambdas can be cast to function types only, e.g. `std::function<int()>`
// and `int (*)()`.
- if (!BeforeRParen || !BeforeRParen->isOneOf(tok::greater, tok::r_paren))
+ if (!BeforeRParen || BeforeRParen->isNoneOf(tok::greater, tok::r_paren))
return false;
} else if (Previous->is(tok::star)) {
Previous = Previous->getPreviousNonComment();
}
if (Previous && Previous->Tok.getIdentifierInfo() &&
- !Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
+ Previous->isNoneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
tok::kw_co_return)) {
return false;
}
@@ -2450,7 +2450,7 @@ void UnwrappedLineParser::tryToParseJSFunction() {
if (FormatTok->is(tok::l_brace))
tryToParseBracedList();
else
- while (!FormatTok->isOneOf(tok::l_brace, tok::semi) && !eof())
+ while (FormatTok->isNoneOf(tok::l_brace, tok::semi) && !eof())
nextToken();
}
@@ -3108,11 +3108,11 @@ void UnwrappedLineParser::parseTryCatch() {
for (bool SeenCatch = false;;) {
if (FormatTok->is(tok::at))
nextToken();
- if (!(FormatTok->isOneOf(tok::kw_catch, Keywords.kw___except,
- tok::kw___finally, tok::objc_catch,
- tok::objc_finally) ||
- ((Style.isJava() || Style.isJavaScript()) &&
- FormatTok->is(Keywords.kw_finally)))) {
+ if (FormatTok->isNoneOf(tok::kw_catch, Keywords.kw___except,
+ tok::kw___finally, tok::objc_catch,
+ tok::objc_finally) &&
+ !((Style.isJava() || Style.isJavaScript()) &&
+ FormatTok->is(Keywords.kw_finally))) {
break;
}
if (FormatTok->is(tok::kw_catch))
@@ -3290,7 +3290,7 @@ void UnwrappedLineParser::parseForOrWhileLoop(bool HasParens) {
Keywords.kw_repeat))) &&
"'for', 'while' or foreach macro expected");
const bool KeepBraces = !Style.RemoveBracesLLVM ||
- !FormatTok->isOneOf(tok::kw_for, tok::kw_while);
+ FormatTok->isNoneOf(tok::kw_for, tok::kw_while);
nextToken();
// JS' for await ( ...
@@ -4339,7 +4339,7 @@ void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
// to the terminating `;`. For everything else, just return and continue
// parsing the structural element, i.e. the declaration or expression for
// `export default`.
- if (!IsImport && !FormatTok->isOneOf(tok::l_brace, tok::star) &&
+ if (!IsImport && FormatTok->isNoneOf(tok::l_brace, tok::star) &&
!FormatTok->isStringLiteral() &&
!(FormatTok->is(Keywords.kw_type) &&
Tokens->peekNextToken()->isOneOf(tok::l_brace, tok::star))) {
@@ -4886,7 +4886,7 @@ void UnwrappedLineParser::readToken(int LevelDifference) {
const auto *Next = Tokens->peekNextToken();
if ((Style.isVerilog() && !Keywords.isVerilogPPDirective(*Next)) ||
(Style.isTableGen() &&
- !Next->isOneOf(tok::kw_else, tok::pp_define, tok::pp_ifdef,
+ Next->isNoneOf(tok::kw_else, tok::pp_define, tok::pp_ifdef,
tok::pp_ifndef, tok::pp_endif))) {
break;
}
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 30c06bb..54f366f 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -462,7 +462,7 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
if ((Style.PointerAlignment == FormatStyle::PAS_Right ||
Style.ReferenceAlignment == FormatStyle::RAS_Right) &&
CurrentChange.Spaces != 0 &&
- !CurrentChange.Tok->isOneOf(tok::equal, tok::r_paren,
+ CurrentChange.Tok->isNoneOf(tok::equal, tok::r_paren,
TT_TemplateCloser)) {
const bool ReferenceNotRightAligned =
Style.ReferenceAlignment != FormatStyle::RAS_Right &&
diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp
index 82249f8..049277c 100644
--- a/clang/lib/Frontend/ChainedIncludesSource.cpp
+++ b/clang/lib/Frontend/ChainedIncludesSource.cpp
@@ -129,7 +129,7 @@ clang::createChainedIncludesSource(CompilerInstance &CI,
Clang->setTarget(TargetInfo::CreateTargetInfo(
Clang->getDiagnostics(), Clang->getInvocation().getTargetOpts()));
Clang->createFileManager();
- Clang->createSourceManager(Clang->getFileManager());
+ Clang->createSourceManager();
Clang->createPreprocessor(TU_Prefix);
Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),
&Clang->getPreprocessor());
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index b1fb905..5844366 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -382,17 +382,18 @@ IntrusiveRefCntPtr<DiagnosticsEngine> CompilerInstance::createDiagnostics(
// File Manager
-FileManager *CompilerInstance::createFileManager() {
+void CompilerInstance::createFileManager() {
assert(VFS && "CompilerInstance needs a VFS for creating FileManager");
FileMgr = llvm::makeIntrusiveRefCnt<FileManager>(getFileSystemOpts(), VFS);
- return FileMgr.get();
}
// Source Manager
-void CompilerInstance::createSourceManager(FileManager &FileMgr) {
- SourceMgr =
- llvm::makeIntrusiveRefCnt<SourceManager>(getDiagnostics(), FileMgr);
+void CompilerInstance::createSourceManager() {
+ assert(Diagnostics && "DiagnosticsEngine needed for creating SourceManager");
+ assert(FileMgr && "FileManager needed for creating SourceManager");
+ SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(getDiagnostics(),
+ getFileManager());
}
// Initialize the remapping of files to alternative contents, e.g.,
@@ -1186,7 +1187,7 @@ std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl(
if (llvm::is_contained(DiagOpts.SystemHeaderWarningsModules, ModuleName))
Instance.getDiagnostics().setSuppressSystemWarnings(false);
- Instance.createSourceManager(Instance.getFileManager());
+ Instance.createSourceManager();
SourceManager &SourceMgr = Instance.getSourceManager();
if (ThreadSafeConfig) {
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 6cc3b65..1b63c40 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -879,7 +879,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
// file, otherwise the CompilerInstance will happily destroy them.
CI.setVirtualFileSystem(AST->getFileManager().getVirtualFileSystemPtr());
CI.setFileManager(AST->getFileManagerPtr());
- CI.createSourceManager(CI.getFileManager());
+ CI.createSourceManager();
CI.getSourceManager().initializeForReplay(AST->getSourceManager());
// Preload all the module files loaded transitively by the AST unit. Also
@@ -971,13 +971,10 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
// Set up the file system, file and source managers, if needed.
if (!CI.hasVirtualFileSystem())
CI.createVirtualFileSystem();
- if (!CI.hasFileManager()) {
- if (!CI.createFileManager()) {
- return false;
- }
- }
+ if (!CI.hasFileManager())
+ CI.createFileManager();
if (!CI.hasSourceManager()) {
- CI.createSourceManager(CI.getFileManager());
+ CI.createSourceManager();
if (CI.getDiagnosticOpts().getFormat() == DiagnosticOptions::SARIF) {
static_cast<SARIFDiagnosticPrinter *>(&CI.getDiagnosticClient())
->setSarifWriter(
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index ae09f70..238c5e2 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -2077,7 +2077,7 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
llvm::SmallString<32> FilePath = File;
if (!WorkingDir.empty() && !path::is_absolute(FilePath))
- fs::make_absolute(WorkingDir, FilePath);
+ path::make_absolute(WorkingDir, FilePath);
// remove_dots switches to backslashes on windows as a side-effect!
// We always want to suggest forward slashes for includes.
// (not remove_dots(..., posix) as that misparses windows paths).
@@ -2091,7 +2091,7 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
// `BestPrefixLength` accordingly.
auto CheckDir = [&](llvm::SmallString<32> Dir) -> bool {
if (!WorkingDir.empty() && !path::is_absolute(Dir))
- fs::make_absolute(WorkingDir, Dir);
+ path::make_absolute(WorkingDir, Dir);
path::remove_dots(Dir, /*remove_dot_dot=*/true);
for (auto NI = path::begin(File), NE = path::end(File),
DI = path::begin(Dir), DE = path::end(Dir);
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 22c01c4..d6cd7eb 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2083,6 +2083,9 @@ void Parser::SkipMalformedDecl() {
return;
break;
+ case tok::kw_extern:
+ // 'extern' at the start of a line is almost certainly a good
+ // place to pick back up parsing
case tok::kw_namespace:
// 'namespace' at the start of a line is almost certainly a good
// place to pick back up parsing, except in an Objective-C
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 3b16efb..7be6eec 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -485,6 +485,9 @@ std::optional<StaticSampler> RootSignatureParser::parseStaticSampler() {
if (Params->Visibility.has_value())
Sampler.Visibility = Params->Visibility.value();
+ if (Params->Flags.has_value())
+ Sampler.Flags = Params->Flags.value();
+
return Sampler;
}
@@ -926,6 +929,20 @@ RootSignatureParser::parseStaticSamplerParams() {
if (!Visibility.has_value())
return std::nullopt;
Params.Visibility = Visibility;
+ } else if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
+ // `flags` `=` STATIC_SAMPLE_FLAGS
+ if (Params.Flags.has_value()) {
+ reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
+ return std::nullopt;
+ }
+
+ if (consumeExpectedToken(TokenKind::pu_equal))
+ return std::nullopt;
+
+ auto Flags = parseStaticSamplerFlags(TokenKind::kw_flags);
+ if (!Flags.has_value())
+ return std::nullopt;
+ Params.Flags = Flags;
} else {
consumeNextToken(); // let diagnostic be at the start of invalid token
reportDiag(diag::err_hlsl_invalid_token)
@@ -1255,6 +1272,50 @@ RootSignatureParser::parseDescriptorRangeFlags(TokenKind Context) {
return Flags;
}
+std::optional<llvm::dxbc::StaticSamplerFlags>
+RootSignatureParser::parseStaticSamplerFlags(TokenKind Context) {
+ assert(CurToken.TokKind == TokenKind::pu_equal &&
+ "Expects to only be invoked starting at given keyword");
+
+ // Handle the edge-case of '0' to specify no flags set
+ if (tryConsumeExpectedToken(TokenKind::int_literal)) {
+ if (!verifyZeroFlag()) {
+ reportDiag(diag::err_hlsl_rootsig_non_zero_flag);
+ return std::nullopt;
+ }
+ return llvm::dxbc::StaticSamplerFlags::None;
+ }
+
+ TokenKind Expected[] = {
+#define STATIC_SAMPLER_FLAG_ENUM(NAME, LIT) TokenKind::en_##NAME,
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+ };
+
+ std::optional<llvm::dxbc::StaticSamplerFlags> Flags;
+
+ do {
+ if (tryConsumeExpectedToken(Expected)) {
+ switch (CurToken.TokKind) {
+#define STATIC_SAMPLER_FLAG_ENUM(NAME, LIT) \
+ case TokenKind::en_##NAME: \
+ Flags = maybeOrFlag<llvm::dxbc::StaticSamplerFlags>( \
+ Flags, llvm::dxbc::StaticSamplerFlags::NAME); \
+ break;
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+ default:
+ llvm_unreachable("Switch for consumed enum token was not provided");
+ }
+ } else {
+ consumeNextToken(); // consume token to point at invalid token
+ reportDiag(diag::err_hlsl_invalid_token)
+ << /*value=*/1 << /*value of*/ Context;
+ return std::nullopt;
+ }
+ } while (tryConsumeExpectedToken(TokenKind::pu_or));
+
+ return Flags;
+}
+
std::optional<uint32_t> RootSignatureParser::handleUIntLiteral() {
// Parse the numeric value and do semantic checks on its specification
clang::NumericLiteralParser Literal(
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 97a6a7f..3c20ccd 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -138,7 +138,16 @@ private:
// LastStmt - refers to the last statement in the method body; referencing
// LastStmt will remove the statement from the method body since
// it will be linked from the new expression being constructed.
- enum class PlaceHolder { _0, _1, _2, _3, _4, Handle = 128, LastStmt };
+ enum class PlaceHolder {
+ _0,
+ _1,
+ _2,
+ _3,
+ _4,
+ Handle = 128,
+ CounterHandle,
+ LastStmt
+ };
Expr *convertPlaceholder(PlaceHolder PH);
Expr *convertPlaceholder(LocalVar &Var);
@@ -178,10 +187,14 @@ public:
template <typename ResourceT, typename ValueT>
BuiltinTypeMethodBuilder &setHandleFieldOnResource(ResourceT ResourceRecord,
ValueT HandleValue);
+ template <typename T>
+ BuiltinTypeMethodBuilder &
+ accessCounterHandleFieldOnResource(T ResourceRecord);
template <typename T> BuiltinTypeMethodBuilder &returnValue(T ReturnValue);
BuiltinTypeMethodBuilder &returnThis();
BuiltinTypeDeclBuilder &finalize();
Expr *getResourceHandleExpr();
+ Expr *getResourceCounterHandleExpr();
private:
void createDecl();
@@ -346,6 +359,8 @@ TemplateParameterListBuilder::finalizeTemplateArgs(ConceptDecl *CD) {
Expr *BuiltinTypeMethodBuilder::convertPlaceholder(PlaceHolder PH) {
if (PH == PlaceHolder::Handle)
return getResourceHandleExpr();
+ if (PH == PlaceHolder::CounterHandle)
+ return getResourceCounterHandleExpr();
if (PH == PlaceHolder::LastStmt) {
assert(!StmtsList.empty() && "no statements in the list");
@@ -467,6 +482,18 @@ Expr *BuiltinTypeMethodBuilder::getResourceHandleExpr() {
OK_Ordinary);
}
+Expr *BuiltinTypeMethodBuilder::getResourceCounterHandleExpr() {
+ ensureCompleteDecl();
+
+ ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
+ CXXThisExpr *This = CXXThisExpr::Create(
+ AST, SourceLocation(), Method->getFunctionObjectParameterType(), true);
+ FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
+ return MemberExpr::CreateImplicit(AST, This, false, HandleField,
+ HandleField->getType(), VK_LValue,
+ OK_Ordinary);
+}
+
BuiltinTypeMethodBuilder &
BuiltinTypeMethodBuilder::declareLocalVar(LocalVar &Var) {
ensureCompleteDecl();
@@ -584,6 +611,22 @@ BuiltinTypeMethodBuilder::setHandleFieldOnResource(ResourceT ResourceRecord,
}
template <typename T>
+BuiltinTypeMethodBuilder &
+BuiltinTypeMethodBuilder::accessCounterHandleFieldOnResource(T ResourceRecord) {
+ ensureCompleteDecl();
+
+ Expr *ResourceExpr = convertPlaceholder(ResourceRecord);
+
+ ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
+ FieldDecl *HandleField = DeclBuilder.getResourceCounterHandleField();
+ MemberExpr *HandleExpr = MemberExpr::CreateImplicit(
+ AST, ResourceExpr, false, HandleField, HandleField->getType(), VK_LValue,
+ OK_Ordinary);
+ StmtsList.push_back(HandleExpr);
+ return *this;
+}
+
+template <typename T>
BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnValue(T ReturnValue) {
ensureCompleteDecl();
@@ -722,8 +765,31 @@ BuiltinTypeDeclBuilder::addMemberVariable(StringRef Name, QualType Type,
return *this;
}
+BuiltinTypeDeclBuilder &
+BuiltinTypeDeclBuilder::addBufferHandles(ResourceClass RC, bool IsROV,
+ bool RawBuffer, bool HasCounter,
+ AccessSpecifier Access) {
+ addHandleMember(RC, IsROV, RawBuffer, Access);
+ if (HasCounter)
+ addCounterHandleMember(RC, IsROV, RawBuffer, Access);
+ return *this;
+}
+
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
+ return addResourceMember("__handle", RC, IsROV, RawBuffer,
+ /*IsCounter=*/false, Access);
+}
+
+BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCounterHandleMember(
+ ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
+ return addResourceMember("__counter_handle", RC, IsROV, RawBuffer,
+ /*IsCounter=*/true, Access);
+}
+
+BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addResourceMember(
+ StringRef MemberName, ResourceClass RC, bool IsROV, bool RawBuffer,
+ bool IsCounter, AccessSpecifier Access) {
assert(!Record->isCompleteDefinition() && "record is already complete");
ASTContext &Ctx = SemaRef.getASTContext();
@@ -739,9 +805,12 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
ElementTypeInfo
? HLSLContainedTypeAttr::CreateImplicit(Ctx, ElementTypeInfo)
: nullptr};
+ if (IsCounter)
+ Attrs.push_back(HLSLIsCounterAttr::CreateImplicit(Ctx));
+
if (CreateHLSLAttributedResourceType(SemaRef, Ctx.HLSLResourceTy, Attrs,
AttributedResTy))
- addMemberVariable("__handle", AttributedResTy, {}, Access);
+ addMemberVariable(MemberName, AttributedResTy, {}, Access);
return *this;
}
@@ -844,12 +913,17 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyConstructor() {
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
- return BuiltinTypeMethodBuilder(*this, /*Name=*/"", AST.VoidTy,
- /*IsConst=*/false, /*IsCtor=*/true)
- .addParam("other", ConstRecordRefType)
+ BuiltinTypeMethodBuilder MMB(*this, /*Name=*/"", AST.VoidTy,
+ /*IsConst=*/false, /*IsCtor=*/true);
+ MMB.addParam("other", ConstRecordRefType)
.accessHandleFieldOnResource(PH::_0)
- .assign(PH::Handle, PH::LastStmt)
- .finalize();
+ .assign(PH::Handle, PH::LastStmt);
+
+ if (getResourceCounterHandleField())
+ MMB.accessCounterHandleFieldOnResource(PH::_0).assign(PH::CounterHandle,
+ PH::LastStmt);
+
+ return MMB.finalize();
}
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyAssignmentOperator() {
@@ -863,12 +937,16 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCopyAssignmentOperator() {
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
DeclarationName Name = AST.DeclarationNames.getCXXOperatorName(OO_Equal);
- return BuiltinTypeMethodBuilder(*this, Name, RecordRefType)
- .addParam("other", ConstRecordRefType)
+ BuiltinTypeMethodBuilder MMB(*this, Name, RecordRefType);
+ MMB.addParam("other", ConstRecordRefType)
.accessHandleFieldOnResource(PH::_0)
- .assign(PH::Handle, PH::LastStmt)
- .returnThis()
- .finalize();
+ .assign(PH::Handle, PH::LastStmt);
+
+ if (getResourceCounterHandleField())
+ MMB.accessCounterHandleFieldOnResource(PH::_0).assign(PH::CounterHandle,
+ PH::LastStmt);
+
+ return MMB.returnThis().finalize();
}
BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators() {
@@ -903,6 +981,14 @@ FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() const {
return I->second;
}
+FieldDecl *BuiltinTypeDeclBuilder::getResourceCounterHandleField() const {
+ auto I = Fields.find("__counter_handle");
+ if (I == Fields.end() ||
+ !I->second->getType()->isHLSLAttributedResourceType())
+ return nullptr;
+ return I->second;
+}
+
QualType BuiltinTypeDeclBuilder::getFirstTemplateTypeParam() {
assert(Template && "record it not a template");
if (const auto *TTD = dyn_cast<TemplateTypeParmDecl>(
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index 9448af1..a981602 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -72,8 +72,9 @@ public:
AccessSpecifier Access = AccessSpecifier::AS_private);
BuiltinTypeDeclBuilder &
- addHandleMember(ResourceClass RC, bool IsROV, bool RawBuffer,
- AccessSpecifier Access = AccessSpecifier::AS_private);
+ addBufferHandles(ResourceClass RC, bool IsROV, bool RawBuffer,
+ bool HasCounter,
+ AccessSpecifier Access = AccessSpecifier::AS_private);
BuiltinTypeDeclBuilder &addArraySubscriptOperators();
// Builtin types constructors
@@ -95,7 +96,18 @@ public:
BuiltinTypeDeclBuilder &addConsumeMethod();
private:
+ BuiltinTypeDeclBuilder &addResourceMember(StringRef MemberName,
+ ResourceClass RC, bool IsROV,
+ bool RawBuffer, bool IsCounter,
+ AccessSpecifier Access);
+ BuiltinTypeDeclBuilder &
+ addHandleMember(ResourceClass RC, bool IsROV, bool RawBuffer,
+ AccessSpecifier Access = AccessSpecifier::AS_private);
+ BuiltinTypeDeclBuilder &
+ addCounterHandleMember(ResourceClass RC, bool IsROV, bool RawBuffer,
+ AccessSpecifier Access = AccessSpecifier::AS_private);
FieldDecl *getResourceHandleField() const;
+ FieldDecl *getResourceCounterHandleField() const;
QualType getFirstTemplateTypeParam();
QualType getHandleElementType();
Expr *getConstantIntExpr(int value);
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 464922b..cc43e94 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -230,9 +230,9 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
/// Set up common members and attributes for buffer types
static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
ResourceClass RC, bool IsROV,
- bool RawBuffer) {
+ bool RawBuffer, bool HasCounter) {
return BuiltinTypeDeclBuilder(S, Decl)
- .addHandleMember(RC, IsROV, RawBuffer)
+ .addBufferHandles(RC, IsROV, RawBuffer, HasCounter)
.addDefaultHandleConstructor()
.addCopyConstructor()
.addCopyAssignmentOperator()
@@ -377,7 +377,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
- /*RawBuffer=*/false)
+ /*RawBuffer=*/false, /*HasCounter=*/false)
.addArraySubscriptOperators()
.addLoadMethods()
.completeDefinition();
@@ -389,7 +389,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
- /*RawBuffer=*/false)
+ /*RawBuffer=*/false, /*HasCounter=*/false)
.addArraySubscriptOperators()
.addLoadMethods()
.completeDefinition();
@@ -401,7 +401,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
- /*RawBuffer=*/false)
+ /*RawBuffer=*/false, /*HasCounter=*/false)
.addArraySubscriptOperators()
.addLoadMethods()
.completeDefinition();
@@ -412,7 +412,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
- /*RawBuffer=*/true)
+ /*RawBuffer=*/true, /*HasCounter=*/false)
.addArraySubscriptOperators()
.addLoadMethods()
.completeDefinition();
@@ -423,7 +423,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
- /*RawBuffer=*/true)
+ /*RawBuffer=*/true, /*HasCounter=*/true)
.addArraySubscriptOperators()
.addLoadMethods()
.addIncrementCounterMethod()
@@ -437,7 +437,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
- /*RawBuffer=*/true)
+ /*RawBuffer=*/true, /*HasCounter=*/true)
.addAppendMethod()
.completeDefinition();
});
@@ -448,7 +448,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
- /*RawBuffer=*/true)
+ /*RawBuffer=*/true, /*HasCounter=*/true)
.addConsumeMethod()
.completeDefinition();
});
@@ -459,7 +459,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
- /*RawBuffer=*/true)
+ /*RawBuffer=*/true, /*HasCounter=*/true)
.addArraySubscriptOperators()
.addLoadMethods()
.addIncrementCounterMethod()
@@ -471,14 +471,14 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
- /*RawBuffer=*/true)
+ /*RawBuffer=*/true, /*HasCounter=*/false)
.completeDefinition();
});
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWByteAddressBuffer")
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
- /*RawBuffer=*/true)
+ /*RawBuffer=*/true, /*HasCounter=*/false)
.completeDefinition();
});
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
@@ -486,7 +486,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
- /*RawBuffer=*/true)
+ /*RawBuffer=*/true, /*HasCounter=*/false)
.completeDefinition();
});
}
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 39c3aa2..7ce3513 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -14881,13 +14881,11 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
// Diag message shows element size in bits and in "bytes" (platform-
// dependent CharUnits)
DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
- PDiag(DiagID)
- << toString(index, 10, true) << AddrBits
- << (unsigned)ASTC.toBits(*ElemCharUnits)
- << toString(ElemBytes, 10, false)
- << toString(MaxElems, 10, false)
- << (unsigned)MaxElems.getLimitedValue(~0U)
- << IndexExpr->getSourceRange());
+ PDiag(DiagID) << index << AddrBits
+ << (unsigned)ASTC.toBits(*ElemCharUnits)
+ << ElemBytes << MaxElems
+ << MaxElems.getZExtValue()
+ << IndexExpr->getSourceRange());
const NamedDecl *ND = nullptr;
// Try harder to find a NamedDecl to point at in the note.
@@ -14970,10 +14968,10 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
QualType CastMsgTy = ASE ? ASE->getLHS()->getType() : QualType();
- DiagRuntimeBehavior(
- BaseExpr->getBeginLoc(), BaseExpr,
- PDiag(DiagID) << toString(index, 10, true) << ArrayTy->desugar()
- << CastMsg << CastMsgTy << IndexExpr->getSourceRange());
+ DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
+ PDiag(DiagID)
+ << index << ArrayTy->desugar() << CastMsg
+ << CastMsgTy << IndexExpr->getSourceRange());
} else {
unsigned DiagID = diag::warn_array_index_precedes_bounds;
if (!ASE) {
@@ -14982,8 +14980,7 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
}
DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
- PDiag(DiagID) << toString(index, 10, true)
- << IndexExpr->getSourceRange());
+ PDiag(DiagID) << index << IndexExpr->getSourceRange());
}
const NamedDecl *ND = nullptr;
@@ -15946,7 +15943,7 @@ void Sema::RefersToMemberWithReducedAlignment(
}
// Check if the synthesized offset fulfills the alignment.
- if (Offset % ExpectedAlignment != 0 ||
+ if (!Offset.isMultipleOf(ExpectedAlignment) ||
// It may fulfill the offset it but the effective alignment may still be
// lower than the expected expression alignment.
CompleteObjectAlignment < ExpectedAlignment) {
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1131e1f..16d42d2 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -13660,7 +13660,7 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc, bool HasTypename,
if (Cxx20Enumerator) {
Diag(NameLoc, diag::warn_cxx17_compat_using_decl_non_member_enumerator)
- << SS.getRange();
+ << SS.getScopeRep() << SS.getRange();
return false;
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 06b2529..4d3c7d6 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -20107,9 +20107,10 @@ static void DoMarkVarDeclReferenced(
bool NeededForConstantEvaluation =
isPotentiallyConstantEvaluatedContext(SemaRef) && UsableInConstantExpr;
- bool NeedDefinition = OdrUse == OdrUseContext::Used ||
- NeededForConstantEvaluation ||
- Var->getType()->isUndeducedType();
+ bool NeedDefinition =
+ OdrUse == OdrUseContext::Used || NeededForConstantEvaluation ||
+ (TSK != clang::TSK_Undeclared && !UsableInConstantExpr &&
+ Var->getType()->isUndeducedType());
assert(!isa<VarTemplatePartialSpecializationDecl>(Var) &&
"Can't instantiate a partial template specialization.");
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 779ccf5..576eb32 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1251,6 +1251,10 @@ Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S,
else
Record = cast<CXXRecordDecl>(ContextDecl);
+ // 'this' never refers to the lambda class itself.
+ if (Record->isLambda())
+ return;
+
QualType T = S.Context.getCanonicalTagType(Record);
T = S.getASTContext().getQualifiedType(T, CXXThisTypeQuals);
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 129b03c..fa30c66b 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -1810,6 +1810,13 @@ bool clang::CreateHLSLAttributedResourceType(
}
ResAttrs.RawBuffer = true;
break;
+ case attr::HLSLIsCounter:
+ if (ResAttrs.IsCounter) {
+ S.Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A;
+ return false;
+ }
+ ResAttrs.IsCounter = true;
+ break;
case attr::HLSLContainedType: {
const HLSLContainedTypeAttr *CTAttr = cast<HLSLContainedTypeAttr>(A);
QualType Ty = CTAttr->getType();
@@ -1902,6 +1909,10 @@ bool SemaHLSL::handleResourceTypeAttr(QualType T, const ParsedAttr &AL) {
A = HLSLRawBufferAttr::Create(getASTContext(), ACI);
break;
+ case ParsedAttr::AT_HLSLIsCounter:
+ A = HLSLIsCounterAttr::Create(getASTContext(), ACI);
+ break;
+
case ParsedAttr::AT_HLSLContainedType: {
if (AL.getNumArgs() != 1 && !AL.hasParsedType()) {
Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index a64f207..9aaf7f4 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -2789,7 +2789,7 @@ OpenACCPrivateRecipe SemaOpenACC::CreatePrivateInitRecipe(const Expr *VarExpr) {
AllocaDecl->setInitStyle(VarDecl::CallInit);
}
- return OpenACCPrivateRecipe(AllocaDecl, Init.get());
+ return OpenACCPrivateRecipe(AllocaDecl);
}
OpenACCFirstPrivateRecipe
@@ -2828,7 +2828,14 @@ SemaOpenACC::CreateFirstPrivateInitRecipe(const Expr *VarExpr) {
if (!ArrTy) {
ExprResult Init = FinishValueInit(
SemaRef.SemaRef, Entity, VarExpr->getBeginLoc(), VarTy, TemporaryDRE);
- return OpenACCFirstPrivateRecipe(AllocaDecl, Init.get(), Temporary);
+
+ // For 'no bounds' version, we can use this as a shortcut, so set the init
+ // anyway.
+ if (Init.isUsable()) {
+ AllocaDecl->setInit(Init.get());
+ AllocaDecl->setInitStyle(VarDecl::CallInit);
+ }
+ return OpenACCFirstPrivateRecipe(AllocaDecl, Temporary);
}
// Arrays need to have each individual element initialized as there
@@ -2875,8 +2882,16 @@ SemaOpenACC::CreateFirstPrivateInitRecipe(const Expr *VarExpr) {
ExprResult Init = FinishValueInit(SemaRef.SemaRef, Entity,
VarExpr->getBeginLoc(), VarTy, InitExpr);
- return OpenACCFirstPrivateRecipe(AllocaDecl, Init.get(), Temporary);
+ // For 'no bounds' version, we can use this as a shortcut, so set the init
+ // anyway.
+ if (Init.isUsable()) {
+ AllocaDecl->setInit(Init.get());
+ AllocaDecl->setInitStyle(VarDecl::CallInit);
+ }
+
+ return OpenACCFirstPrivateRecipe(AllocaDecl, Temporary);
}
+
OpenACCReductionRecipe SemaOpenACC::CreateReductionInitRecipe(
OpenACCReductionOperator ReductionOperator, const Expr *VarExpr) {
// TODO: OpenACC: This shouldn't be necessary, see PrivateInitRecipe
@@ -2932,5 +2947,12 @@ OpenACCReductionRecipe SemaOpenACC::CreateReductionInitRecipe(
ExprResult Init = FinishValueInit(SemaRef.SemaRef, Entity,
VarExpr->getBeginLoc(), VarTy, InitExpr);
- return OpenACCReductionRecipe(AllocaDecl, Init.get());
+
+ // For 'no bounds' version, we can use this as a shortcut, so set the init
+ // anyway.
+ if (Init.isUsable()) {
+ AllocaDecl->setInit(Init.get());
+ AllocaDecl->setInitStyle(VarDecl::CallInit);
+ }
+ return OpenACCReductionRecipe(AllocaDecl);
}
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 3d54d1e..fe673ea 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -1428,10 +1428,13 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
DeclareImplicitDeductionGuidesForTypeAlias(*this, AliasTemplate, Loc);
return;
}
- if (CXXRecordDecl *DefRecord =
- cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
+ CXXRecordDecl *DefRecord =
+ dyn_cast_or_null<CXXRecordDecl>(Template->getTemplatedDecl());
+ if (!DefRecord)
+ return;
+ if (const CXXRecordDecl *Definition = DefRecord->getDefinition()) {
if (TemplateDecl *DescribedTemplate =
- DefRecord->getDescribedClassTemplate())
+ Definition->getDescribedClassTemplate())
Template = DescribedTemplate;
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index c05e428..6acf79a 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -12860,10 +12860,9 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
llvm::SmallVector<OpenACCPrivateRecipe> RecipeList;
for (unsigned I = 0; I < VarList.size(); ++I) {
- static_assert(sizeof(OpenACCPrivateRecipe) == 2 * sizeof(int *));
+ static_assert(sizeof(OpenACCPrivateRecipe) == 1 * sizeof(int *));
VarDecl *Alloca = readDeclAs<VarDecl>();
- Expr *InitExpr = readSubExpr();
- RecipeList.push_back({Alloca, InitExpr});
+ RecipeList.push_back({Alloca});
}
return OpenACCPrivateClause::Create(getContext(), BeginLoc, LParenLoc,
@@ -12886,11 +12885,10 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
llvm::SmallVector<OpenACCFirstPrivateRecipe> RecipeList;
for (unsigned I = 0; I < VarList.size(); ++I) {
- static_assert(sizeof(OpenACCFirstPrivateRecipe) == 3 * sizeof(int *));
+ static_assert(sizeof(OpenACCFirstPrivateRecipe) == 2 * sizeof(int *));
VarDecl *Recipe = readDeclAs<VarDecl>();
- Expr *InitExpr = readSubExpr();
VarDecl *RecipeTemp = readDeclAs<VarDecl>();
- RecipeList.push_back({Recipe, InitExpr, RecipeTemp});
+ RecipeList.push_back({Recipe, RecipeTemp});
}
return OpenACCFirstPrivateClause::Create(getContext(), BeginLoc, LParenLoc,
@@ -13011,10 +13009,9 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
llvm::SmallVector<OpenACCReductionRecipe> RecipeList;
for (unsigned I = 0; I < VarList.size(); ++I) {
- static_assert(sizeof(OpenACCReductionRecipe) == 2 * sizeof(int *));
+ static_assert(sizeof(OpenACCReductionRecipe) == sizeof(int *));
VarDecl *Recipe = readDeclAs<VarDecl>();
- Expr *InitExpr = readSubExpr();
- RecipeList.push_back({Recipe, InitExpr});
+ RecipeList.push_back({Recipe});
}
return OpenACCReductionClause::Create(getContext(), BeginLoc, LParenLoc, Op,
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index cdf95ba..09b1e58 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -8779,9 +8779,8 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
writeOpenACCVarList(PC);
for (const OpenACCPrivateRecipe &R : PC->getInitRecipes()) {
- static_assert(sizeof(R) == 2 * sizeof(int *));
+ static_assert(sizeof(R) == 1 * sizeof(int *));
AddDeclRef(R.AllocaDecl);
- AddStmt(const_cast<Expr *>(R.InitExpr));
}
return;
}
@@ -8803,9 +8802,8 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
writeOpenACCVarList(FPC);
for (const OpenACCFirstPrivateRecipe &R : FPC->getInitRecipes()) {
- static_assert(sizeof(R) == 3 * sizeof(int *));
+ static_assert(sizeof(R) == 2 * sizeof(int *));
AddDeclRef(R.AllocaDecl);
- AddStmt(const_cast<Expr *>(R.InitExpr));
AddDeclRef(R.InitFromTemporary);
}
return;
@@ -8927,9 +8925,8 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
writeOpenACCVarList(RC);
for (const OpenACCReductionRecipe &R : RC->getRecipes()) {
- static_assert(sizeof(OpenACCReductionRecipe) == 2 * sizeof(int *));
+ static_assert(sizeof(OpenACCReductionRecipe) == 1 * sizeof(int *));
AddDeclRef(R.AllocaDecl);
- AddStmt(const_cast<Expr *>(R.InitExpr));
}
return;
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
index e1f9a77..955b8d1 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp
@@ -385,6 +385,10 @@ public:
if (RTC.isUnretained(RetValue->getType()))
return;
}
+ if (retainsRet && *retainsRet) {
+ CreateOrCopyFnCall.insert(RetValue);
+ return;
+ }
if (auto *CE = dyn_cast<CallExpr>(RetValue)) {
auto *Callee = CE->getDirectCallee();
if (!Callee || !isCreateOrCopyFunction(Callee))
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index 180056c..06ba015 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -1254,6 +1254,15 @@ template <> struct DenseMapInfo<PrivateMethodKey> {
};
} // end namespace llvm
+// NOTE: This cache is a "global" variable, and it is cleared by
+// CallEventManager's constructor so we do not keep old entries when
+// loading/unloading ASTs. If we are worried about concurrency, we may need to
+// revisit this someday. In terms of memory, this table stays around until clang
+// quits, which also may be bad if we need to release memory.
+using PrivateMethodCacheTy =
+ llvm::DenseMap<PrivateMethodKey, std::optional<const ObjCMethodDecl *>>;
+static PrivateMethodCacheTy PrivateMethodCache;
+
static const ObjCMethodDecl *
lookupRuntimeDefinition(const ObjCInterfaceDecl *Interface,
Selector LookupSelector, bool InstanceMethod) {
@@ -1262,21 +1271,8 @@ lookupRuntimeDefinition(const ObjCInterfaceDecl *Interface,
// that repeated queries on the same ObjCIntefaceDecl and Selector
// don't incur the same cost. On some test cases, we can see the
// same query being issued thousands of times.
- //
- // NOTE: This cache is essentially a "global" variable, but it
- // only gets lazily created when we get here. The value of the
- // cache probably comes from it being global across ExprEngines,
- // where the same queries may get issued. If we are worried about
- // concurrency, or possibly loading/unloading ASTs, etc., we may
- // need to revisit this someday. In terms of memory, this table
- // stays around until clang quits, which also may be bad if we
- // need to release memory.
- using PrivateMethodCache =
- llvm::DenseMap<PrivateMethodKey, std::optional<const ObjCMethodDecl *>>;
-
- static PrivateMethodCache PMC;
std::optional<const ObjCMethodDecl *> &Val =
- PMC[{Interface, LookupSelector, InstanceMethod}];
+ PrivateMethodCache[{Interface, LookupSelector, InstanceMethod}];
// Query lookupPrivateMethod() if the cache does not hit.
if (!Val) {
@@ -1422,6 +1418,13 @@ void ObjCMethodCall::getInitialStackFrameContents(
}
}
+CallEventManager::CallEventManager(llvm::BumpPtrAllocator &alloc)
+ : Alloc(alloc) {
+ // Clear the method cache to avoid hits when multiple AST are loaded/unloaded
+ // within a single process. This can happen with unit tests, for instance.
+ PrivateMethodCache.clear();
+}
+
CallEventRef<>
CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State,
const LocationContext *LCtx,
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index 8e9d6fe..af0ef52 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -2658,14 +2658,20 @@ RegionStoreManager::bindArray(LimitedRegionBindingsConstRef B,
return bindAggregate(B, R, V);
}
- // Handle lazy compound values.
+ // FIXME Single value constant should have been handled before this call to
+ // bindArray. This is only a hotfix to not crash.
+ if (Init.isConstant())
+ return bindAggregate(B, R, Init);
+
if (std::optional LCV = Init.getAs<nonloc::LazyCompoundVal>()) {
if (std::optional NewB = tryBindSmallArray(B, R, AT, *LCV))
return *NewB;
-
return bindAggregate(B, R, Init);
}
+ if (isa<nonloc::SymbolVal>(Init))
+ return bindAggregate(B, R, Init);
+
if (Init.isUnknown())
return bindAggregate(B, R, UnknownVal());
diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp
index 971e6bc..b609f36 100644
--- a/clang/lib/StaticAnalyzer/Core/Store.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Store.cpp
@@ -210,7 +210,7 @@ std::optional<const MemRegion *> StoreManager::castRegion(const MemRegion *R,
// Is the offset a multiple of the size? If so, we can layer the
// ElementRegion (with elementType == PointeeTy) directly on top of
// the base region.
- if (off % pointeeTySize == 0) {
+ if (off.isMultipleOf(pointeeTySize)) {
newIndex = off / pointeeTySize;
newSuperR = baseR;
}
diff --git a/clang/lib/Testing/TestAST.cpp b/clang/lib/Testing/TestAST.cpp
index 9ad0de9..d333895 100644
--- a/clang/lib/Testing/TestAST.cpp
+++ b/clang/lib/Testing/TestAST.cpp
@@ -61,7 +61,7 @@ void createMissingComponents(CompilerInstance &Clang) {
if (!Clang.hasFileManager())
Clang.createFileManager();
if (!Clang.hasSourceManager())
- Clang.createSourceManager(Clang.getFileManager());
+ Clang.createSourceManager();
if (!Clang.hasTarget())
Clang.createTarget();
if (!Clang.hasPreprocessor())
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp
index d370bfd..010380d 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp
@@ -31,7 +31,7 @@ public:
for (const auto &File : getDependencies()) {
CanonPath = File;
llvm::sys::path::remove_dots(CanonPath, /*remove_dot_dot=*/true);
- llvm::sys::fs::make_absolute(WorkingDirectory, CanonPath);
+ llvm::sys::path::make_absolute(WorkingDirectory, CanonPath);
C.handleFileDependency(CanonPath);
}
}
@@ -415,7 +415,7 @@ bool DependencyScanningAction::runInvocation(
any(Service.getOptimizeArgs() & ScanningOptimizations::VFS);
// Create a new FileManager to match the invocation's FileSystemOptions.
- auto *FileMgr = ScanInstance.createFileManager();
+ ScanInstance.createFileManager();
// Use the dependency scanning optimized file system if requested to do so.
if (DepFS) {
@@ -423,16 +423,17 @@ bool DependencyScanningAction::runInvocation(
if (!ScanInstance.getHeaderSearchOpts().ModuleCachePath.empty()) {
SmallString<256> ModulesCachePath;
normalizeModuleCachePath(
- *FileMgr, ScanInstance.getHeaderSearchOpts().ModuleCachePath,
- ModulesCachePath);
+ ScanInstance.getFileManager(),
+ ScanInstance.getHeaderSearchOpts().ModuleCachePath, ModulesCachePath);
DepFS->setBypassedPathPrefix(ModulesCachePath);
}
ScanInstance.setDependencyDirectivesGetter(
- std::make_unique<ScanningDependencyDirectivesGetter>(*FileMgr));
+ std::make_unique<ScanningDependencyDirectivesGetter>(
+ ScanInstance.getFileManager()));
}
- ScanInstance.createSourceManager(*FileMgr);
+ ScanInstance.createSourceManager();
// Create a collection of stable directories derived from the ScanInstance
// for determining whether module dependencies would fully resolve from
diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp
index 2d4790b..ea5a372 100644
--- a/clang/lib/Tooling/Tooling.cpp
+++ b/clang/lib/Tooling/Tooling.cpp
@@ -458,7 +458,7 @@ bool FrontendActionFactory::runInvocation(
if (!Compiler.hasDiagnostics())
return false;
- Compiler.createSourceManager(*Files);
+ Compiler.createSourceManager();
const bool Success = Compiler.ExecuteAction(*ScopedToolAction);