aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib')
-rw-r--r--contrib/llvm-project/clang/lib/APINotes/APINotesManager.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/AST/ASTImporter.cpp48
-rw-r--r--contrib/llvm-project/clang/lib/AST/ASTStructuralEquivalence.cpp12
-rw-r--r--contrib/llvm-project/clang/lib/AST/Decl.cpp41
-rw-r--r--contrib/llvm-project/clang/lib/AST/DeclBase.cpp74
-rw-r--r--contrib/llvm-project/clang/lib/AST/Expr.cpp83
-rw-r--r--contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp90
-rw-r--r--contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp31
-rw-r--r--contrib/llvm-project/clang/lib/Analysis/FlowSensitive/RecordOps.cpp33
-rw-r--r--contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp25
-rw-r--r--contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp1
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp1
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp4
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h1
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Version.cpp18
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Warnings.cpp3
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp7
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp209
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp129
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp26
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.cpp63
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.h2
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp148
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h16
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/Targets/AArch64.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp6
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp4
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp15
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp59
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp127
-rw-r--r--contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp20
-rw-r--r--contrib/llvm-project/clang/lib/Format/Format.cpp8
-rw-r--r--contrib/llvm-project/clang/lib/Format/MatchFilePath.cpp122
-rw-r--r--contrib/llvm-project/clang/lib/Format/MatchFilePath.h22
-rw-r--r--contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp3
-rw-r--r--contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp6
-rw-r--r--contrib/llvm-project/clang/lib/Headers/adcintrin.h160
-rw-r--r--contrib/llvm-project/clang/lib/Headers/adxintrin.h143
-rw-r--r--contrib/llvm-project/clang/lib/Headers/immintrin.h8
-rw-r--r--contrib/llvm-project/clang/lib/Headers/riscv_bitmanip.h24
-rw-r--r--contrib/llvm-project/clang/lib/Interpreter/CodeCompletion.cpp223
-rw-r--r--contrib/llvm-project/clang/lib/Interpreter/Interpreter.cpp4
-rw-r--r--contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp22
-rw-r--r--contrib/llvm-project/clang/lib/Parse/ParseOpenACC.cpp92
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp77
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp45
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp90
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp16
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp28
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp4
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaInit.cpp214
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp13
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaRISCVVectorLookup.cpp19
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp7
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp28
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp52
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp405
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp15
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp574
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp241
-rw-r--r--contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp86
-rw-r--r--contrib/llvm-project/clang/lib/Support/RISCVVIntrinsicUtils.cpp2
64 files changed, 2510 insertions, 1555 deletions
diff --git a/contrib/llvm-project/clang/lib/APINotes/APINotesManager.cpp b/contrib/llvm-project/clang/lib/APINotes/APINotesManager.cpp
index a921c8b9fce3..d3aef09dac91 100644
--- a/contrib/llvm-project/clang/lib/APINotes/APINotesManager.cpp
+++ b/contrib/llvm-project/clang/lib/APINotes/APINotesManager.cpp
@@ -125,7 +125,7 @@ APINotesManager::loadAPINotes(StringRef Buffer) {
bool APINotesManager::loadAPINotes(const DirectoryEntry *HeaderDir,
FileEntryRef APINotesFile) {
- assert(Readers.find(HeaderDir) == Readers.end());
+ assert(!Readers.contains(HeaderDir));
if (auto Reader = loadAPINotes(APINotesFile)) {
Readers[HeaderDir] = Reader.release();
return false;
diff --git a/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp b/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp
index f1f335118f37..b61180c4f349 100644
--- a/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp
+++ b/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp
@@ -2771,9 +2771,11 @@ ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (auto *FoundAlias = dyn_cast<TypeAliasTemplateDecl>(FoundDecl))
- return Importer.MapImported(D, FoundAlias);
- ConflictingDecls.push_back(FoundDecl);
+ if (auto *FoundAlias = dyn_cast<TypeAliasTemplateDecl>(FoundDecl)) {
+ if (IsStructuralMatch(D, FoundAlias))
+ return Importer.MapImported(D, FoundAlias);
+ ConflictingDecls.push_back(FoundDecl);
+ }
}
if (!ConflictingDecls.empty()) {
@@ -3418,10 +3420,16 @@ static bool isAncestorDeclContextOf(const DeclContext *DC, const Stmt *S) {
while (!ToProcess.empty()) {
const Stmt *CurrentS = ToProcess.pop_back_val();
ToProcess.append(CurrentS->child_begin(), CurrentS->child_end());
- if (const auto *DeclRef = dyn_cast<DeclRefExpr>(CurrentS))
+ if (const auto *DeclRef = dyn_cast<DeclRefExpr>(CurrentS)) {
if (const Decl *D = DeclRef->getDecl())
if (isAncestorDeclContextOf(DC, D))
return true;
+ } else if (const auto *E =
+ dyn_cast_or_null<SubstNonTypeTemplateParmExpr>(CurrentS)) {
+ if (const Decl *D = E->getAssociatedDecl())
+ if (isAncestorDeclContextOf(DC, D))
+ return true;
+ }
}
return false;
}
@@ -7820,6 +7828,18 @@ ExpectedStmt ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
*ToLParenLocOrErr, OCE->getBridgeKind(), E->getCastKind(),
*ToBridgeKeywordLocOrErr, ToTypeInfoAsWritten, ToSubExpr);
}
+ case Stmt::BuiltinBitCastExprClass: {
+ auto *BBC = cast<BuiltinBitCastExpr>(E);
+ ExpectedSLoc ToKWLocOrErr = import(BBC->getBeginLoc());
+ if (!ToKWLocOrErr)
+ return ToKWLocOrErr.takeError();
+ ExpectedSLoc ToRParenLocOrErr = import(BBC->getEndLoc());
+ if (!ToRParenLocOrErr)
+ return ToRParenLocOrErr.takeError();
+ return new (Importer.getToContext()) BuiltinBitCastExpr(
+ ToType, E->getValueKind(), E->getCastKind(), ToSubExpr,
+ ToTypeInfoAsWritten, *ToKWLocOrErr, *ToRParenLocOrErr);
+ }
default:
llvm_unreachable("Cast expression of unsupported type!");
return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
@@ -9003,10 +9023,6 @@ class AttrImporter {
public:
AttrImporter(ASTImporter &I) : Importer(I), NImporter(I) {}
- // Useful for accessing the imported attribute.
- template <typename T> T *castAttrAs() { return cast<T>(ToAttr); }
- template <typename T> const T *castAttrAs() const { return cast<T>(ToAttr); }
-
// Create an "importer" for an attribute parameter.
// Result of the 'value()' of that object is to be passed to the function
// 'importAttr', in the order that is expected by the attribute class.
@@ -9101,6 +9117,12 @@ Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
break;
}
+ case attr::AlignValue: {
+ auto *From = cast<AlignValueAttr>(FromAttr);
+ AI.importAttr(From, AI.importArg(From->getAlignment()).value());
+ break;
+ }
+
case attr::Format: {
const auto *From = cast<FormatAttr>(FromAttr);
AI.importAttr(From, Import(From->getType()), From->getFormatIdx(),
@@ -9214,15 +9236,6 @@ Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
From->args_size());
break;
}
- case attr::CountedBy: {
- AI.cloneAttr(FromAttr);
- const auto *CBA = cast<CountedByAttr>(FromAttr);
- Expected<SourceRange> SR = Import(CBA->getCountedByFieldLoc()).get();
- if (!SR)
- return SR.takeError();
- AI.castAttrAs<CountedByAttr>()->setCountedByFieldLoc(SR.get());
- break;
- }
default: {
// The default branch works for attributes that have no arguments to import.
@@ -9391,7 +9404,6 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) {
setImportDeclError(FromD, *Error);
return make_error<ASTImportError>(*Error);
}
-
// Make sure that ImportImpl registered the imported decl.
assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?");
if (auto Error = ImportAttrs(ToD, FromD))
diff --git a/contrib/llvm-project/clang/lib/AST/ASTStructuralEquivalence.cpp b/contrib/llvm-project/clang/lib/AST/ASTStructuralEquivalence.cpp
index 6bb4bf14b873..1f492b051e03 100644
--- a/contrib/llvm-project/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/contrib/llvm-project/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1978,6 +1978,18 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ TypeAliasTemplateDecl *D1,
+ TypeAliasTemplateDecl *D2) {
+ // Check template parameters.
+ if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
+ return false;
+
+ // Check the templated declaration.
+ return IsStructurallyEquivalent(Context, D1->getTemplatedDecl(),
+ D2->getTemplatedDecl());
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
ConceptDecl *D1,
ConceptDecl *D2) {
// Check template parameters.
diff --git a/contrib/llvm-project/clang/lib/AST/Decl.cpp b/contrib/llvm-project/clang/lib/AST/Decl.cpp
index 527ea6042daa..12e0a6faa4c3 100644
--- a/contrib/llvm-project/clang/lib/AST/Decl.cpp
+++ b/contrib/llvm-project/clang/lib/AST/Decl.cpp
@@ -1088,11 +1088,11 @@ bool NamedDecl::isPlaceholderVar(const LangOptions &LangOpts) const {
return false;
if (isa<FieldDecl>(this))
return true;
- if (auto *IFD = dyn_cast<IndirectFieldDecl>(this)) {
+ if (const auto *IFD = dyn_cast<IndirectFieldDecl>(this)) {
if (!getDeclContext()->isFunctionOrMethod() &&
!getDeclContext()->isRecord())
return false;
- VarDecl *VD = IFD->getVarDecl();
+ const VarDecl *VD = IFD->getVarDecl();
return !VD || VD->getStorageDuration() == SD_Automatic;
}
// and it declares a variable with automatic storage duration
@@ -1105,7 +1105,7 @@ bool NamedDecl::isPlaceholderVar(const LangOptions &LangOpts) const {
}
if (const auto *BD = dyn_cast<BindingDecl>(this);
BD && getDeclContext()->isFunctionOrMethod()) {
- VarDecl *VD = BD->getHoldingVar();
+ const VarDecl *VD = BD->getHoldingVar();
return !VD || VD->getStorageDuration() == StorageDuration::SD_Automatic;
}
return false;
@@ -1843,7 +1843,8 @@ static bool isRedeclarable(Decl::Kind K) {
llvm_unreachable("unknown decl kind");
}
-bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
+bool NamedDecl::declarationReplaces(const NamedDecl *OldD,
+ bool IsKnownNewer) const {
assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch");
// Never replace one imported declaration with another; we need both results
@@ -1873,13 +1874,13 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
// Using declarations can be replaced if they import the same name from the
// same context.
- if (auto *UD = dyn_cast<UsingDecl>(this)) {
+ if (const auto *UD = dyn_cast<UsingDecl>(this)) {
ASTContext &Context = getASTContext();
return Context.getCanonicalNestedNameSpecifier(UD->getQualifier()) ==
Context.getCanonicalNestedNameSpecifier(
cast<UsingDecl>(OldD)->getQualifier());
}
- if (auto *UUVD = dyn_cast<UnresolvedUsingValueDecl>(this)) {
+ if (const auto *UUVD = dyn_cast<UnresolvedUsingValueDecl>(this)) {
ASTContext &Context = getASTContext();
return Context.getCanonicalNestedNameSpecifier(UUVD->getQualifier()) ==
Context.getCanonicalNestedNameSpecifier(
@@ -1896,7 +1897,7 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
// Check whether this is actually newer than OldD. We want to keep the
// newer declaration. This loop will usually only iterate once, because
// OldD is usually the previous declaration.
- for (auto *D : redecls()) {
+ for (const auto *D : redecls()) {
if (D == OldD)
break;
@@ -2199,8 +2200,7 @@ static LanguageLinkage getDeclLanguageLinkage(const T &D) {
// Language linkage is a C++ concept, but saying that everything else in C has
// C language linkage fits the implementation nicely.
- ASTContext &Context = D.getASTContext();
- if (!Context.getLangOpts().CPlusPlus)
+ if (!D.getASTContext().getLangOpts().CPlusPlus)
return CLanguageLinkage;
// C++ [dcl.link]p4: A C language linkage is ignored in determining the
@@ -2943,7 +2943,7 @@ bool ParmVarDecl::isDestroyedInCallee() const {
// FIXME: isParamDestroyedInCallee() should probably imply
// isDestructedType()
- auto *RT = getType()->getAs<RecordType>();
+ const auto *RT = getType()->getAs<RecordType>();
if (RT && RT->getDecl()->isParamDestroyedInCallee() &&
getType().isDestructedType())
return true;
@@ -3105,7 +3105,7 @@ FunctionDecl::getDefaultedFunctionInfo() const {
}
bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
- for (auto *I : redecls()) {
+ for (const auto *I : redecls()) {
if (I->doesThisDeclarationHaveABody()) {
Definition = I;
return true;
@@ -3116,7 +3116,7 @@ bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
}
bool FunctionDecl::hasTrivialBody() const {
- Stmt *S = getBody();
+ const Stmt *S = getBody();
if (!S) {
// Since we don't have a body for this function, we don't know if it's
// trivial or not.
@@ -3212,7 +3212,7 @@ void FunctionDecl::setPure(bool P) {
template<std::size_t Len>
static bool isNamed(const NamedDecl *ND, const char (&Str)[Len]) {
- IdentifierInfo *II = ND->getIdentifier();
+ const IdentifierInfo *II = ND->getIdentifier();
return II && II->isStr(Str);
}
@@ -3305,9 +3305,9 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const {
if (proto->getNumParams() != 2 || proto->isVariadic())
return false;
- ASTContext &Context =
- cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext())
- ->getASTContext();
+ const ASTContext &Context =
+ cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext())
+ ->getASTContext();
// The result type and first argument type are constant across all
// these operators. The second argument must be exactly void*.
@@ -3342,7 +3342,7 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(
unsigned Params = 1;
QualType Ty = FPT->getParamType(Params);
- ASTContext &Ctx = getASTContext();
+ const ASTContext &Ctx = getASTContext();
auto Consume = [&] {
++Params;
@@ -3388,7 +3388,8 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(
QualType T = Ty;
while (const auto *TD = T->getAs<TypedefType>())
T = TD->getDecl()->getUnderlyingType();
- IdentifierInfo *II = T->castAs<EnumType>()->getDecl()->getIdentifier();
+ const IdentifierInfo *II =
+ T->castAs<EnumType>()->getDecl()->getIdentifier();
if (II && II->isStr("__hot_cold_t"))
Consume();
}
@@ -3586,7 +3587,7 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
(!hasAttr<ArmBuiltinAliasAttr>() && !hasAttr<BuiltinAliasAttr>()))
return 0;
- ASTContext &Context = getASTContext();
+ const ASTContext &Context = getASTContext();
if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
return BuiltinID;
@@ -3745,7 +3746,7 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
assert(!doesThisDeclarationHaveABody() &&
"Must have a declaration without a body.");
- ASTContext &Context = getASTContext();
+ const ASTContext &Context = getASTContext();
if (Context.getLangOpts().MSVCCompat) {
const FunctionDecl *Definition;
diff --git a/contrib/llvm-project/clang/lib/AST/DeclBase.cpp b/contrib/llvm-project/clang/lib/AST/DeclBase.cpp
index e4d7169752bc..5e03f0223d31 100644
--- a/contrib/llvm-project/clang/lib/AST/DeclBase.cpp
+++ b/contrib/llvm-project/clang/lib/AST/DeclBase.cpp
@@ -29,6 +29,7 @@
#include "clang/AST/Type.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/PartialDiagnostic.h"
@@ -410,79 +411,6 @@ bool Decl::isFileContextDecl() const {
return DC && DC->isFileContext();
}
-bool Decl::isFlexibleArrayMemberLike(
- ASTContext &Ctx, const Decl *D, QualType Ty,
- LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
- bool IgnoreTemplateOrMacroSubstitution) {
- // For compatibility with existing code, we treat arrays of length 0 or
- // 1 as flexible array members.
- const auto *CAT = Ctx.getAsConstantArrayType(Ty);
- if (CAT) {
- using FAMKind = LangOptions::StrictFlexArraysLevelKind;
-
- llvm::APInt Size = CAT->getSize();
- if (StrictFlexArraysLevel == FAMKind::IncompleteOnly)
- return false;
-
- // GCC extension, only allowed to represent a FAM.
- if (Size.isZero())
- return true;
-
- if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1))
- return false;
-
- if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2))
- return false;
- } else if (!Ctx.getAsIncompleteArrayType(Ty)) {
- return false;
- }
-
- if (const auto *OID = dyn_cast_if_present<ObjCIvarDecl>(D))
- return OID->getNextIvar() == nullptr;
-
- const auto *FD = dyn_cast_if_present<FieldDecl>(D);
- if (!FD)
- return false;
-
- if (CAT) {
- // GCC treats an array memeber of a union as an FAM if the size is one or
- // zero.
- llvm::APInt Size = CAT->getSize();
- if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne()))
- return true;
- }
-
- // Don't consider sizes resulting from macro expansions or template argument
- // substitution to form C89 tail-padded arrays.
- if (IgnoreTemplateOrMacroSubstitution) {
- TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
- while (TInfo) {
- TypeLoc TL = TInfo->getTypeLoc();
-
- // Look through typedefs.
- if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) {
- const TypedefNameDecl *TDL = TTL.getTypedefNameDecl();
- TInfo = TDL->getTypeSourceInfo();
- continue;
- }
-
- if (auto CTL = TL.getAs<ConstantArrayTypeLoc>()) {
- if (const Expr *SizeExpr =
- dyn_cast_if_present<IntegerLiteral>(CTL.getSizeExpr());
- !SizeExpr || SizeExpr->getExprLoc().isMacroID())
- return false;
- }
-
- break;
- }
- }
-
- // Test that the field is the last in the structure.
- RecordDecl::field_iterator FI(
- DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
- return ++FI == FD->getParent()->field_end();
-}
-
TranslationUnitDecl *Decl::getTranslationUnitDecl() {
if (auto *TUD = dyn_cast<TranslationUnitDecl>(this))
return TUD;
diff --git a/contrib/llvm-project/clang/lib/AST/Expr.cpp b/contrib/llvm-project/clang/lib/AST/Expr.cpp
index b125fc676da8..a90f92d07f86 100644
--- a/contrib/llvm-project/clang/lib/AST/Expr.cpp
+++ b/contrib/llvm-project/clang/lib/AST/Expr.cpp
@@ -205,22 +205,85 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const {
}
bool Expr::isFlexibleArrayMemberLike(
- ASTContext &Ctx,
+ ASTContext &Context,
LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
bool IgnoreTemplateOrMacroSubstitution) const {
+
+ // For compatibility with existing code, we treat arrays of length 0 or
+ // 1 as flexible array members.
+ const auto *CAT = Context.getAsConstantArrayType(getType());
+ if (CAT) {
+ llvm::APInt Size = CAT->getSize();
+
+ using FAMKind = LangOptions::StrictFlexArraysLevelKind;
+
+ if (StrictFlexArraysLevel == FAMKind::IncompleteOnly)
+ return false;
+
+ // GCC extension, only allowed to represent a FAM.
+ if (Size == 0)
+ return true;
+
+ if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1))
+ return false;
+
+ if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2))
+ return false;
+ } else if (!Context.getAsIncompleteArrayType(getType()))
+ return false;
+
const Expr *E = IgnoreParens();
- const Decl *D = nullptr;
- if (const auto *ME = dyn_cast<MemberExpr>(E))
- D = ME->getMemberDecl();
- else if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
- D = DRE->getDecl();
+ const NamedDecl *ND = nullptr;
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
+ ND = DRE->getDecl();
+ else if (const auto *ME = dyn_cast<MemberExpr>(E))
+ ND = ME->getMemberDecl();
else if (const auto *IRE = dyn_cast<ObjCIvarRefExpr>(E))
- D = IRE->getDecl();
+ return IRE->getDecl()->getNextIvar() == nullptr;
+
+ if (!ND)
+ return false;
- return Decl::isFlexibleArrayMemberLike(Ctx, D, E->getType(),
- StrictFlexArraysLevel,
- IgnoreTemplateOrMacroSubstitution);
+ // A flexible array member must be the last member in the class.
+ // FIXME: If the base type of the member expr is not FD->getParent(),
+ // this should not be treated as a flexible array member access.
+ if (const auto *FD = dyn_cast<FieldDecl>(ND)) {
+ // GCC treats an array memeber of a union as an FAM if the size is one or
+ // zero.
+ if (CAT) {
+ llvm::APInt Size = CAT->getSize();
+ if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne()))
+ return true;
+ }
+
+ // Don't consider sizes resulting from macro expansions or template argument
+ // substitution to form C89 tail-padded arrays.
+ if (IgnoreTemplateOrMacroSubstitution) {
+ TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
+ while (TInfo) {
+ TypeLoc TL = TInfo->getTypeLoc();
+ // Look through typedefs.
+ if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) {
+ const TypedefNameDecl *TDL = TTL.getTypedefNameDecl();
+ TInfo = TDL->getTypeSourceInfo();
+ continue;
+ }
+ if (ConstantArrayTypeLoc CTL = TL.getAs<ConstantArrayTypeLoc>()) {
+ const Expr *SizeExpr = dyn_cast<IntegerLiteral>(CTL.getSizeExpr());
+ if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
+ return false;
+ }
+ break;
+ }
+ }
+
+ RecordDecl::field_iterator FI(
+ DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
+ return ++FI == FD->getParent()->field_end();
+ }
+
+ return false;
}
const ValueDecl *
diff --git a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index b98037b73645..96fe6df88dbb 100644
--- a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -726,27 +726,70 @@ void Environment::setStorageLocation(const Expr &E, StorageLocation &Loc) {
// so allow these as an exception.
assert(E.isGLValue() ||
E.getType()->isSpecificBuiltinType(BuiltinType::BuiltinFn));
- setStorageLocationInternal(E, Loc);
+ const Expr &CanonE = ignoreCFGOmittedNodes(E);
+ assert(!ExprToLoc.contains(&CanonE));
+ ExprToLoc[&CanonE] = &Loc;
}
StorageLocation *Environment::getStorageLocation(const Expr &E) const {
// See comment in `setStorageLocation()`.
assert(E.isGLValue() ||
E.getType()->isSpecificBuiltinType(BuiltinType::BuiltinFn));
- return getStorageLocationInternal(E);
+ auto It = ExprToLoc.find(&ignoreCFGOmittedNodes(E));
+ return It == ExprToLoc.end() ? nullptr : &*It->second;
+}
+
+// Returns whether a prvalue of record type is the one that originally
+// constructs the object (i.e. it doesn't propagate it from one of its
+// children).
+static bool isOriginalRecordConstructor(const Expr &RecordPRValue) {
+ if (auto *Init = dyn_cast<InitListExpr>(&RecordPRValue))
+ return !Init->isSemanticForm() || !Init->isTransparent();
+ return isa<CXXConstructExpr>(RecordPRValue) || isa<CallExpr>(RecordPRValue) ||
+ isa<LambdaExpr>(RecordPRValue) ||
+ // The framework currently does not propagate the objects created in
+ // the two branches of a `ConditionalOperator` because there is no way
+ // to reconcile their storage locations, which are different. We
+ // therefore claim that the `ConditionalOperator` is the expression
+ // that originally constructs the object.
+ // Ultimately, this will be fixed by propagating locations down from
+ // the result object, rather than up from the original constructor as
+ // we do now (see also the FIXME in the documentation for
+ // `getResultObjectLocation()`).
+ isa<ConditionalOperator>(RecordPRValue);
}
RecordStorageLocation &
-Environment::getResultObjectLocation(const Expr &RecordPRValue) {
+Environment::getResultObjectLocation(const Expr &RecordPRValue) const {
assert(RecordPRValue.getType()->isRecordType());
assert(RecordPRValue.isPRValue());
- if (StorageLocation *ExistingLoc = getStorageLocationInternal(RecordPRValue))
- return *cast<RecordStorageLocation>(ExistingLoc);
- auto &Loc = cast<RecordStorageLocation>(
- DACtx->getStableStorageLocation(RecordPRValue));
- setStorageLocationInternal(RecordPRValue, Loc);
- return Loc;
+ // Returns a storage location that we can use if assertions fail.
+ auto FallbackForAssertFailure =
+ [this, &RecordPRValue]() -> RecordStorageLocation & {
+ return cast<RecordStorageLocation>(
+ DACtx->getStableStorageLocation(RecordPRValue));
+ };
+
+ if (isOriginalRecordConstructor(RecordPRValue)) {
+ auto *Val = cast_or_null<RecordValue>(getValue(RecordPRValue));
+ // The builtin transfer function should have created a `RecordValue` for all
+ // original record constructors.
+ assert(Val);
+ if (!Val)
+ return FallbackForAssertFailure();
+ return Val->getLoc();
+ }
+
+ // Expression nodes that propagate a record prvalue should have exactly one
+ // child.
+ llvm::SmallVector<const Stmt *> children(RecordPRValue.child_begin(),
+ RecordPRValue.child_end());
+ assert(children.size() == 1);
+ if (children.empty())
+ return FallbackForAssertFailure();
+
+ return getResultObjectLocation(*cast<Expr>(children[0]));
}
PointerValue &Environment::getOrCreateNullPointerValue(QualType PointeeType) {
@@ -760,6 +803,11 @@ void Environment::setValue(const StorageLocation &Loc, Value &Val) {
}
void Environment::setValue(const Expr &E, Value &Val) {
+ if (auto *RecordVal = dyn_cast<RecordValue>(&Val)) {
+ assert(isOriginalRecordConstructor(E) ||
+ &RecordVal->getLoc() == &getResultObjectLocation(E));
+ }
+
assert(E.isPRValue());
ExprToVal[&E] = &Val;
}
@@ -799,18 +847,6 @@ Value *Environment::createValue(QualType Type) {
return Val;
}
-void Environment::setStorageLocationInternal(const Expr &E,
- StorageLocation &Loc) {
- const Expr &CanonE = ignoreCFGOmittedNodes(E);
- assert(!ExprToLoc.contains(&CanonE));
- ExprToLoc[&CanonE] = &Loc;
-}
-
-StorageLocation *Environment::getStorageLocationInternal(const Expr &E) const {
- auto It = ExprToLoc.find(&ignoreCFGOmittedNodes(E));
- return It == ExprToLoc.end() ? nullptr : &*It->second;
-}
-
Value *Environment::createValueUnlessSelfReferential(
QualType Type, llvm::DenseSet<QualType> &Visited, int Depth,
int &CreatedValuesCount) {
@@ -998,7 +1034,7 @@ RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE,
if (ImplicitObject == nullptr)
return nullptr;
if (ImplicitObject->getType()->isPointerType()) {
- if (auto *Val = cast_or_null<PointerValue>(Env.getValue(*ImplicitObject)))
+ if (auto *Val = Env.get<PointerValue>(*ImplicitObject))
return &cast<RecordStorageLocation>(Val->getPointeeLoc());
return nullptr;
}
@@ -1012,11 +1048,11 @@ RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
if (Base == nullptr)
return nullptr;
if (ME.isArrow()) {
- if (auto *Val = cast_or_null<PointerValue>(Env.getValue(*Base)))
+ if (auto *Val = Env.get<PointerValue>(*Base))
return &cast<RecordStorageLocation>(Val->getPointeeLoc());
return nullptr;
}
- return cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*Base));
+ return Env.get<RecordStorageLocation>(*Base);
}
std::vector<FieldDecl *> getFieldsForInitListExpr(const RecordDecl *RD) {
@@ -1041,9 +1077,10 @@ RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env) {
assert(Expr.getType()->isRecordType());
if (Expr.isPRValue()) {
- if (auto *ExistingVal = cast_or_null<RecordValue>(Env.getValue(Expr))) {
+ if (auto *ExistingVal = Env.get<RecordValue>(Expr)) {
auto &NewVal = Env.create<RecordValue>(ExistingVal->getLoc());
Env.setValue(Expr, NewVal);
+ Env.setValue(NewVal.getLoc(), NewVal);
return NewVal;
}
@@ -1052,8 +1089,7 @@ RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env) {
return NewVal;
}
- if (auto *Loc =
- cast_or_null<RecordStorageLocation>(Env.getStorageLocation(Expr))) {
+ if (auto *Loc = Env.get<RecordStorageLocation>(Expr)) {
auto &NewVal = Env.create<RecordValue>(*Loc);
Env.setValue(*Loc, NewVal);
return NewVal;
diff --git a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
index 69ac2c2b82cf..1d31b22b6d25 100644
--- a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
+++ b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
@@ -226,7 +226,7 @@ auto isComparisonOperatorCall(L lhs_arg_matcher, R rhs_arg_matcher) {
/// Ensures that `Expr` is mapped to a `BoolValue` and returns its formula.
const Formula &forceBoolValue(Environment &Env, const Expr &Expr) {
- auto *Value = cast_or_null<BoolValue>(Env.getValue(Expr));
+ auto *Value = Env.get<BoolValue>(Expr);
if (Value != nullptr)
return Value->formula();
@@ -267,7 +267,7 @@ BoolValue *getHasValue(Environment &Env, RecordStorageLocation *OptionalLoc) {
if (OptionalLoc == nullptr)
return nullptr;
StorageLocation &HasValueLoc = locForHasValue(*OptionalLoc);
- auto *HasValueVal = cast_or_null<BoolValue>(Env.getValue(HasValueLoc));
+ auto *HasValueVal = Env.get<BoolValue>(HasValueLoc);
if (HasValueVal == nullptr) {
HasValueVal = &Env.makeAtomicBoolValue();
Env.setValue(HasValueLoc, *HasValueVal);
@@ -406,7 +406,7 @@ void transferCallReturningOptional(const CallExpr *E,
if (E->isPRValue()) {
Loc = &State.Env.getResultObjectLocation(*E);
} else {
- Loc = cast_or_null<RecordStorageLocation>(State.Env.getStorageLocation(*E));
+ Loc = State.Env.get<RecordStorageLocation>(*E);
if (Loc == nullptr) {
Loc = &cast<RecordStorageLocation>(State.Env.createStorageLocation(*E));
State.Env.setStorageLocation(*E, *Loc);
@@ -449,8 +449,7 @@ BoolValue &valueOrConversionHasValue(const FunctionDecl &F, const Expr &E,
// This is a constructor/assignment call for `optional<T>` with argument of
// type `optional<U>` such that `T` is constructible from `U`.
- auto *Loc =
- cast_or_null<RecordStorageLocation>(State.Env.getStorageLocation(E));
+ auto *Loc = State.Env.get<RecordStorageLocation>(E);
if (auto *HasValueVal = getHasValue(State.Env, Loc))
return *HasValueVal;
return State.Env.makeAtomicBoolValue();
@@ -471,8 +470,7 @@ void transferAssignment(const CXXOperatorCallExpr *E, BoolValue &HasValueVal,
LatticeTransferState &State) {
assert(E->getNumArgs() > 0);
- if (auto *Loc = cast_or_null<RecordStorageLocation>(
- State.Env.getStorageLocation(*E->getArg(0)))) {
+ if (auto *Loc = State.Env.get<RecordStorageLocation>(*E->getArg(0))) {
createOptionalValue(*Loc, HasValueVal, State.Env);
// Assign a storage location for the whole expression.
@@ -534,18 +532,15 @@ void transferSwapCall(const CXXMemberCallExpr *E,
const MatchFinder::MatchResult &,
LatticeTransferState &State) {
assert(E->getNumArgs() == 1);
- auto *OtherLoc = cast_or_null<RecordStorageLocation>(
- State.Env.getStorageLocation(*E->getArg(0)));
+ auto *OtherLoc = State.Env.get<RecordStorageLocation>(*E->getArg(0));
transferSwap(getImplicitObjectLocation(*E, State.Env), OtherLoc, State.Env);
}
void transferStdSwapCall(const CallExpr *E, const MatchFinder::MatchResult &,
LatticeTransferState &State) {
assert(E->getNumArgs() == 2);
- auto *Arg0Loc = cast_or_null<RecordStorageLocation>(
- State.Env.getStorageLocation(*E->getArg(0)));
- auto *Arg1Loc = cast_or_null<RecordStorageLocation>(
- State.Env.getStorageLocation(*E->getArg(1)));
+ auto *Arg0Loc = State.Env.get<RecordStorageLocation>(*E->getArg(0));
+ auto *Arg1Loc = State.Env.get<RecordStorageLocation>(*E->getArg(1));
transferSwap(Arg0Loc, Arg1Loc, State.Env);
}
@@ -585,11 +580,9 @@ void transferOptionalAndOptionalCmp(const clang::CXXOperatorCallExpr *CmpExpr,
Environment &Env = State.Env;
auto &A = Env.arena();
auto *CmpValue = &forceBoolValue(Env, *CmpExpr);
- auto *Arg0Loc = cast_or_null<RecordStorageLocation>(
- Env.getStorageLocation(*CmpExpr->getArg(0)));
+ auto *Arg0Loc = Env.get<RecordStorageLocation>(*CmpExpr->getArg(0));
if (auto *LHasVal = getHasValue(Env, Arg0Loc)) {
- auto *Arg1Loc = cast_or_null<RecordStorageLocation>(
- Env.getStorageLocation(*CmpExpr->getArg(1)));
+ auto *Arg1Loc = Env.get<RecordStorageLocation>(*CmpExpr->getArg(1));
if (auto *RHasVal = getHasValue(Env, Arg1Loc)) {
if (CmpExpr->getOperator() == clang::OO_ExclaimEqual)
CmpValue = &A.makeNot(*CmpValue);
@@ -603,7 +596,7 @@ void transferOptionalAndValueCmp(const clang::CXXOperatorCallExpr *CmpExpr,
const clang::Expr *E, Environment &Env) {
auto &A = Env.arena();
auto *CmpValue = &forceBoolValue(Env, *CmpExpr);
- auto *Loc = cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*E));
+ auto *Loc = Env.get<RecordStorageLocation>(*E);
if (auto *HasVal = getHasValue(Env, Loc)) {
if (CmpExpr->getOperator() == clang::OO_ExclaimEqual)
CmpValue = &A.makeNot(*CmpValue);
@@ -616,7 +609,7 @@ void transferOptionalAndNulloptCmp(const clang::CXXOperatorCallExpr *CmpExpr,
const clang::Expr *E, Environment &Env) {
auto &A = Env.arena();
auto *CmpValue = &forceBoolValue(Env, *CmpExpr);
- auto *Loc = cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*E));
+ auto *Loc = Env.get<RecordStorageLocation>(*E);
if (auto *HasVal = getHasValue(Env, Loc)) {
if (CmpExpr->getOperator() == clang::OO_ExclaimEqual)
CmpValue = &A.makeNot(*CmpValue);
diff --git a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/RecordOps.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/RecordOps.cpp
index caaf443382b0..da4dd6dc0785 100644
--- a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/RecordOps.cpp
+++ b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/RecordOps.cpp
@@ -66,19 +66,8 @@ void clang::dataflow::copyRecord(RecordStorageLocation &Src,
}
}
- RecordValue *SrcVal = cast_or_null<RecordValue>(Env.getValue(Src));
- RecordValue *DstVal = cast_or_null<RecordValue>(Env.getValue(Dst));
-
- DstVal = &Env.create<RecordValue>(Dst);
+ RecordValue *DstVal = &Env.create<RecordValue>(Dst);
Env.setValue(Dst, *DstVal);
-
- if (SrcVal == nullptr)
- return;
-
- for (const auto &[Name, Value] : SrcVal->properties()) {
- if (Value != nullptr)
- DstVal->setProperty(Name, *Value);
- }
}
bool clang::dataflow::recordsEqual(const RecordStorageLocation &Loc1,
@@ -125,25 +114,5 @@ bool clang::dataflow::recordsEqual(const RecordStorageLocation &Loc1,
}
}
- llvm::StringMap<Value *> Props1, Props2;
-
- if (RecordValue *Val1 = cast_or_null<RecordValue>(Env1.getValue(Loc1)))
- for (const auto &[Name, Value] : Val1->properties())
- Props1[Name] = Value;
- if (RecordValue *Val2 = cast_or_null<RecordValue>(Env2.getValue(Loc2)))
- for (const auto &[Name, Value] : Val2->properties())
- Props2[Name] = Value;
-
- if (Props1.size() != Props2.size())
- return false;
-
- for (const auto &[Name, Value] : Props1) {
- auto It = Props2.find(Name);
- if (It == Props2.end())
- return false;
- if (Value != It->second)
- return false;
- }
-
return true;
}
diff --git a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index bbf5f12359bc..55093c2e2cda 100644
--- a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -339,8 +339,7 @@ public:
switch (S->getOpcode()) {
case UO_Deref: {
- const auto *SubExprVal =
- cast_or_null<PointerValue>(Env.getValue(*SubExpr));
+ const auto *SubExprVal = Env.get<PointerValue>(*SubExpr);
if (SubExprVal == nullptr)
break;
@@ -467,8 +466,7 @@ public:
const Expr *Arg = S->getArg(0);
assert(Arg != nullptr);
- auto *ArgLoc =
- cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*Arg));
+ auto *ArgLoc = Env.get<RecordStorageLocation>(*Arg);
if (ArgLoc == nullptr)
return;
@@ -489,7 +487,6 @@ public:
if (S->getType()->isRecordType()) {
auto &InitialVal = *cast<RecordValue>(Env.createValue(S->getType()));
Env.setValue(*S, InitialVal);
- copyRecord(InitialVal.getLoc(), Env.getResultObjectLocation(*S), Env);
}
transferInlineCall(S, ConstructorDecl);
@@ -516,14 +513,12 @@ public:
RecordStorageLocation *LocSrc = nullptr;
if (Arg1->isPRValue()) {
- if (auto *Val = cast_or_null<RecordValue>(Env.getValue(*Arg1)))
+ if (auto *Val = Env.get<RecordValue>(*Arg1))
LocSrc = &Val->getLoc();
} else {
- LocSrc =
- cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*Arg1));
+ LocSrc = Env.get<RecordStorageLocation>(*Arg1);
}
- auto *LocDst =
- cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*Arg0));
+ auto *LocDst = Env.get<RecordStorageLocation>(*Arg0);
if (LocSrc == nullptr || LocDst == nullptr)
return;
@@ -582,6 +577,14 @@ public:
Env.setValue(*S, *ArgVal);
} else if (const FunctionDecl *F = S->getDirectCallee()) {
transferInlineCall(S, F);
+
+ // If this call produces a prvalue of record type, make sure that we have
+ // a `RecordValue` for it. This is required so that
+ // `Environment::getResultObjectLocation()` is able to return a location
+ // for this `CallExpr`.
+ if (S->getType()->isRecordType() && S->isPRValue())
+ if (Env.getValue(*S) == nullptr)
+ refreshRecordValue(*S, Env);
}
}
@@ -669,7 +672,7 @@ public:
auto Init = Inits[InitIdx++];
assert(Base.getType().getCanonicalType() ==
Init->getType().getCanonicalType());
- auto* BaseVal = cast_or_null<RecordValue>(Env.getValue(*Init));
+ auto *BaseVal = Env.get<RecordValue>(*Init);
if (!BaseVal)
BaseVal = cast<RecordValue>(Env.createValue(Init->getType()));
// Take ownership of the fields of the `RecordValue` for the base class
diff --git a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
index 8c9360235da7..faf83a8920d4 100644
--- a/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -130,7 +130,7 @@ private:
if (Env.getValue(Cond) == nullptr)
transfer(StmtToEnv, Cond, Env);
- auto *Val = cast_or_null<BoolValue>(Env.getValue(Cond));
+ auto *Val = Env.get<BoolValue>(Cond);
// Value merging depends on flow conditions from different environments
// being mutually exclusive -- that is, they cannot both be true in their
// entirety (even if they may share some clauses). So, we need *some* value
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
index def16c032c86..3ee39133fcee 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
@@ -225,6 +225,7 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;
BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
+ BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
return true;
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
index ce7e4d4639ce..6e1842fc64e5 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
@@ -419,6 +419,7 @@ bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
+ BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
return true;
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
index 60a4e0ed69c3..685462961ee3 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
@@ -350,6 +350,7 @@ bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
.Case("riscv64", Is64Bit)
.Case("32bit", !Is64Bit)
.Case("64bit", Is64Bit)
+ .Case("experimental", HasExperimental)
.Default(std::nullopt);
if (Result)
return *Result;
@@ -382,6 +383,9 @@ bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
FastUnalignedAccess = llvm::is_contained(Features, "+fast-unaligned-access");
+ if (llvm::is_contained(Features, "+experimental"))
+ HasExperimental = true;
+
return true;
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
index a893cae914ce..f98c88cd45f8 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
@@ -31,6 +31,7 @@ protected:
private:
bool FastUnalignedAccess;
+ bool HasExperimental = false;
public:
RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
diff --git a/contrib/llvm-project/clang/lib/Basic/Version.cpp b/contrib/llvm-project/clang/lib/Basic/Version.cpp
index e205da7adec1..4823f566bd77 100644
--- a/contrib/llvm-project/clang/lib/Basic/Version.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Version.cpp
@@ -57,6 +57,14 @@ std::string getLLVMRevision() {
#endif
}
+std::string getClangVendor() {
+#ifdef CLANG_VENDOR
+ return CLANG_VENDOR;
+#else
+ return "";
+#endif
+}
+
std::string getClangFullRepositoryVersion() {
std::string buf;
llvm::raw_string_ostream OS(buf);
@@ -92,10 +100,7 @@ std::string getClangFullVersion() {
std::string getClangToolFullVersion(StringRef ToolName) {
std::string buf;
llvm::raw_string_ostream OS(buf);
-#ifdef CLANG_VENDOR
- OS << CLANG_VENDOR;
-#endif
- OS << ToolName << " version " CLANG_VERSION_STRING;
+ OS << getClangVendor() << ToolName << " version " CLANG_VERSION_STRING;
std::string repo = getClangFullRepositoryVersion();
if (!repo.empty()) {
@@ -110,10 +115,7 @@ std::string getClangFullCPPVersion() {
// the one we report on the command line.
std::string buf;
llvm::raw_string_ostream OS(buf);
-#ifdef CLANG_VENDOR
- OS << CLANG_VENDOR;
-#endif
- OS << "Clang " CLANG_VERSION_STRING;
+ OS << getClangVendor() << "Clang " CLANG_VERSION_STRING;
std::string repo = getClangFullRepositoryVersion();
if (!repo.empty()) {
diff --git a/contrib/llvm-project/clang/lib/Basic/Warnings.cpp b/contrib/llvm-project/clang/lib/Basic/Warnings.cpp
index cb23d844ef8f..bab1af4f03b6 100644
--- a/contrib/llvm-project/clang/lib/Basic/Warnings.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Warnings.cpp
@@ -198,8 +198,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
}
}
- for (unsigned i = 0, e = Opts.Remarks.size(); i != e; ++i) {
- StringRef Opt = Opts.Remarks[i];
+ for (StringRef Opt : Opts.Remarks) {
const auto Flavor = diag::Flavor::Remark;
// Check to see if this warning starts with "no-", if so, this is a
diff --git a/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp b/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp
index 7d16de33763a..a6142d99f3b6 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp
@@ -881,7 +881,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
<< PluginFN << toString(PassPlugin.takeError());
}
}
- for (auto PassCallback : CodeGenOpts.PassBuilderCallbacks)
+ for (const auto &PassCallback : CodeGenOpts.PassBuilderCallbacks)
PassCallback(PB);
#define HANDLE_EXTENSION(Ext) \
get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
@@ -1068,11 +1068,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
}
}
if (CodeGenOpts.FatLTO) {
- // Set module flags, like EnableSplitLTOUnit and UnifiedLTO, since FatLTO
+ // Set the EnableSplitLTOUnit and UnifiedLTO module flags, since FatLTO
// uses a different action than Backend_EmitBC or Backend_EmitLL.
- if (!TheModule->getModuleFlag("ThinLTO"))
- TheModule->addModuleFlag(llvm::Module::Error, "ThinLTO",
- uint32_t(CodeGenOpts.PrepareForThinLTO));
if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
uint32_t(CodeGenOpts.EnableSplitLTOUnit));
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp
index 3327866d2b96..5081062da286 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp
@@ -25,7 +25,6 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/OSLog.h"
-#include "clang/AST/OperationKinds.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
@@ -232,19 +231,19 @@ static Value *MakeBinaryAtomicValue(
static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) {
Value *Val = CGF.EmitScalarExpr(E->getArg(0));
- Value *Address = CGF.EmitScalarExpr(E->getArg(1));
+ Address Addr = CGF.EmitPointerWithAlignment(E->getArg(1));
Val = CGF.EmitToMemory(Val, E->getArg(0)->getType());
- LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getArg(0)->getType());
+ LValue LV = CGF.MakeAddrLValue(Addr, E->getArg(0)->getType());
LV.setNontemporal(true);
CGF.EmitStoreOfScalar(Val, LV, false);
return nullptr;
}
static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) {
- Value *Address = CGF.EmitScalarExpr(E->getArg(0));
+ Address Addr = CGF.EmitPointerWithAlignment(E->getArg(0));
- LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getType());
+ LValue LV = CGF.MakeAddrLValue(Addr, E->getType());
LV.setNontemporal(true);
return CGF.EmitLoadOfScalar(LV, E->getExprLoc());
}
@@ -819,165 +818,6 @@ CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true);
}
-llvm::Value *
-CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
- llvm::IntegerType *ResType) {
- // The code generated here calculates the size of a struct with a flexible
- // array member that uses the counted_by attribute. There are two instances
- // we handle:
- //
- // struct s {
- // unsigned long flags;
- // int count;
- // int array[] __attribute__((counted_by(count)));
- // }
- //
- // 1) bdos of the flexible array itself:
- //
- // __builtin_dynamic_object_size(p->array, 1) ==
- // p->count * sizeof(*p->array)
- //
- // 2) bdos of a pointer into the flexible array:
- //
- // __builtin_dynamic_object_size(&p->array[42], 1) ==
- // (p->count - 42) * sizeof(*p->array)
- //
- // 2) bdos of the whole struct, including the flexible array:
- //
- // __builtin_dynamic_object_size(p, 1) ==
- // max(sizeof(struct s),
- // offsetof(struct s, array) + p->count * sizeof(*p->array))
- //
- ASTContext &Ctx = getContext();
- const Expr *Base = E->IgnoreParenImpCasts();
- const Expr *Idx = nullptr;
-
- if (const auto *UO = dyn_cast<UnaryOperator>(Base);
- UO && UO->getOpcode() == UO_AddrOf) {
- Expr *SubExpr = UO->getSubExpr()->IgnoreParenImpCasts();
- if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(SubExpr)) {
- Base = ASE->getBase()->IgnoreParenImpCasts();
- Idx = ASE->getIdx()->IgnoreParenImpCasts();
-
- if (const auto *IL = dyn_cast<IntegerLiteral>(Idx)) {
- int64_t Val = IL->getValue().getSExtValue();
- if (Val < 0)
- // __bdos returns 0 for negative indexes into an array in a struct.
- return getDefaultBuiltinObjectSizeResult(Type, ResType);
-
- if (Val == 0)
- // The index is 0, so we don't need to take it into account.
- Idx = nullptr;
- }
- } else {
- // Potential pointer to another element in the struct.
- Base = SubExpr;
- }
- }
-
- // Get the flexible array member Decl.
- const ValueDecl *FAMDecl = nullptr;
- if (const auto *ME = dyn_cast<MemberExpr>(Base)) {
- // Check if \p Base is referencing the FAM itself.
- if (const ValueDecl *MD = ME->getMemberDecl()) {
- const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
- getLangOpts().getStrictFlexArraysLevel();
- if (!Decl::isFlexibleArrayMemberLike(
- Ctx, MD, MD->getType(), StrictFlexArraysLevel,
- /*IgnoreTemplateOrMacroSubstitution=*/true))
- return nullptr;
-
- FAMDecl = MD;
- }
- } else if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) {
- // Check if we're pointing to the whole struct.
- QualType Ty = DRE->getDecl()->getType();
- if (Ty->isPointerType())
- Ty = Ty->getPointeeType();
-
- if (const auto *RD = Ty->getAsRecordDecl())
- // Don't use the outer lexical record because the FAM might be in a
- // different RecordDecl.
- FAMDecl = FindFlexibleArrayMemberField(Ctx, RD);
- }
-
- if (!FAMDecl || !FAMDecl->hasAttr<CountedByAttr>())
- // No flexible array member found or it doesn't have the "counted_by"
- // attribute.
- return nullptr;
-
- const ValueDecl *CountedByFD = FindCountedByField(Base);
- if (!CountedByFD)
- // Can't find the field referenced by the "counted_by" attribute.
- return nullptr;
-
- // Build a load of the counted_by field.
- bool IsSigned = CountedByFD->getType()->isSignedIntegerType();
- const Expr *CountedByExpr = BuildCountedByFieldExpr(Base, CountedByFD);
- Value *CountedByInst = EmitAnyExprToTemp(CountedByExpr).getScalarVal();
- llvm::Type *CountedByTy = CountedByInst->getType();
-
- // Build a load of the index and subtract it from the count.
- Value *IdxInst = nullptr;
- if (Idx) {
- bool IdxSigned = Idx->getType()->isSignedIntegerType();
- IdxInst = EmitAnyExprToTemp(Idx).getScalarVal();
- IdxInst = IdxSigned ? Builder.CreateSExtOrTrunc(IdxInst, CountedByTy)
- : Builder.CreateZExtOrTrunc(IdxInst, CountedByTy);
-
- // We go ahead with the calculation here. If the index turns out to be
- // negative, we'll catch it at the end.
- CountedByInst =
- Builder.CreateSub(CountedByInst, IdxInst, "", !IsSigned, IsSigned);
- }
-
- // Calculate how large the flexible array member is in bytes.
- const ArrayType *ArrayTy = Ctx.getAsArrayType(FAMDecl->getType());
- CharUnits Size = Ctx.getTypeSizeInChars(ArrayTy->getElementType());
- llvm::Constant *ElemSize =
- llvm::ConstantInt::get(CountedByTy, Size.getQuantity(), IsSigned);
- Value *FAMSize =
- Builder.CreateMul(CountedByInst, ElemSize, "", !IsSigned, IsSigned);
- FAMSize = IsSigned ? Builder.CreateSExtOrTrunc(FAMSize, ResType)
- : Builder.CreateZExtOrTrunc(FAMSize, ResType);
- Value *Res = FAMSize;
-
- if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) {
- // The whole struct is specificed in the __bdos.
- const RecordDecl *OuterRD =
- CountedByFD->getDeclContext()->getOuterLexicalRecordContext();
- const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(OuterRD);
-
- // Get the offset of the FAM.
- CharUnits Offset = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(FAMDecl));
- llvm::Constant *FAMOffset =
- ConstantInt::get(ResType, Offset.getQuantity(), IsSigned);
- Value *OffsetAndFAMSize =
- Builder.CreateAdd(FAMOffset, Res, "", !IsSigned, IsSigned);
-
- // Get the full size of the struct.
- llvm::Constant *SizeofStruct =
- ConstantInt::get(ResType, Layout.getSize().getQuantity(), IsSigned);
-
- // max(sizeof(struct s),
- // offsetof(struct s, array) + p->count * sizeof(*p->array))
- Res = IsSigned
- ? Builder.CreateBinaryIntrinsic(llvm::Intrinsic::smax,
- OffsetAndFAMSize, SizeofStruct)
- : Builder.CreateBinaryIntrinsic(llvm::Intrinsic::umax,
- OffsetAndFAMSize, SizeofStruct);
- }
-
- // A negative \p IdxInst or \p CountedByInst means that the index lands
- // outside of the flexible array member. If that's the case, we want to
- // return 0.
- Value *Cmp = Builder.CreateIsNotNeg(CountedByInst);
- if (IdxInst)
- Cmp = Builder.CreateAnd(Builder.CreateIsNotNeg(IdxInst), Cmp);
-
- return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, IsSigned));
-}
-
/// Returns a Value corresponding to the size of the given expression.
/// This Value may be either of the following:
/// - A llvm::Argument (if E is a param with the pass_object_size attribute on
@@ -1010,13 +850,6 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
}
}
- if (IsDynamic) {
- // Emit special code for a flexible array member with the "counted_by"
- // attribute.
- if (Value *V = emitFlexibleArrayMemberSize(E, Type, ResType))
- return V;
- }
-
// LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't
// evaluate E for side-effects. In either case, we shouldn't lower to
// @llvm.objectsize.
@@ -3214,7 +3047,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *AlignmentValue = EmitScalarExpr(E->getArg(1));
ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);
if (AlignmentCI->getValue().ugt(llvm::Value::MaximumAlignment))
- AlignmentCI = ConstantInt::get(AlignmentCI->getType(),
+ AlignmentCI = ConstantInt::get(AlignmentCI->getIntegerType(),
llvm::Value::MaximumAlignment);
emitAlignmentAssumption(PtrValue, Ptr,
@@ -10485,6 +10318,30 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
return nullptr;
}
+static void swapCommutativeSMEOperands(unsigned BuiltinID,
+ SmallVectorImpl<Value *> &Ops) {
+ unsigned MultiVec;
+ switch (BuiltinID) {
+ default:
+ return;
+ case SME::BI__builtin_sme_svsumla_za32_s8_vg4x1:
+ MultiVec = 1;
+ break;
+ case SME::BI__builtin_sme_svsumla_za32_s8_vg4x2:
+ case SME::BI__builtin_sme_svsudot_za32_s8_vg1x2:
+ MultiVec = 2;
+ break;
+ case SME::BI__builtin_sme_svsudot_za32_s8_vg1x4:
+ case SME::BI__builtin_sme_svsumla_za32_s8_vg4x4:
+ MultiVec = 4;
+ break;
+ }
+
+ if (MultiVec > 0)
+ for (unsigned I = 0; I < MultiVec; ++I)
+ std::swap(Ops[I + 1], Ops[I + 1 + MultiVec]);
+}
+
Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
auto *Builtin = findARMVectorIntrinsicInMap(AArch64SMEIntrinsicMap, BuiltinID,
@@ -10507,6 +10364,9 @@ Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID,
BuiltinID == SME::BI__builtin_sme_svstr_za)
return EmitSMELdrStr(TypeFlags, Ops, Builtin->LLVMIntrinsic);
+ // Handle builtins which require their multi-vector operands to be swapped
+ swapCommutativeSMEOperands(BuiltinID, Ops);
+
// Should not happen!
if (Builtin->LLVMIntrinsic == 0)
return nullptr;
@@ -17034,7 +16894,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
Value *Op1 = EmitScalarExpr(E->getArg(1));
ConstantInt *AlignmentCI = cast<ConstantInt>(Op0);
if (AlignmentCI->getValue().ugt(llvm::Value::MaximumAlignment))
- AlignmentCI = ConstantInt::get(AlignmentCI->getType(),
+ AlignmentCI = ConstantInt::get(AlignmentCI->getIntegerType(),
llvm::Value::MaximumAlignment);
emitAlignmentAssumption(Op1, E->getArg(1),
@@ -17272,7 +17132,8 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
Op0, llvm::FixedVectorType::get(ConvertType(E->getType()), 2));
if (getTarget().isLittleEndian())
- Index = ConstantInt::get(Index->getType(), 1 - Index->getZExtValue());
+ Index =
+ ConstantInt::get(Index->getIntegerType(), 1 - Index->getZExtValue());
return Builder.CreateExtractElement(Unpacked, Index);
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp
index ed9aaa28c257..3f277725d9e7 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGExpr.cpp
@@ -30,7 +30,6 @@
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Intrinsics.h"
@@ -926,27 +925,16 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
if (CE->getCastKind() == CK_ArrayToPointerDecay &&
!CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.getContext(),
StrictFlexArraysLevel)) {
- CodeGenFunction::SanitizerScope SanScope(&CGF);
-
IndexedType = CE->getSubExpr()->getType();
const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe();
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
return CGF.Builder.getInt(CAT->getSize());
-
- if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
+ else if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
return CGF.getVLASize(VAT).NumElts;
// Ignore pass_object_size here. It's not applicable on decayed pointers.
}
-
- if (const ValueDecl *VD = CGF.FindCountedByField(Base)) {
- IndexedType = Base->getType();
- const Expr *E = CGF.BuildCountedByFieldExpr(Base, VD);
- return CGF.EmitAnyExprToTemp(E).getScalarVal();
- }
}
- CodeGenFunction::SanitizerScope SanScope(&CGF);
-
QualType EltTy{Base->getType()->getPointeeOrArrayElementType(), 0};
if (llvm::Value *POS = CGF.LoadPassedObjectSize(Base, EltTy)) {
IndexedType = Base->getType();
@@ -956,122 +944,13 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
return nullptr;
}
-const Expr *
-CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
- const ValueDecl *CountedByVD) {
- // Find the outer struct expr (i.e. p in p->a.b.c.d).
- Expr *CountedByExpr = const_cast<Expr *>(Base)->IgnoreParenImpCasts();
-
- // Work our way up the expression until we reach the DeclRefExpr.
- while (!isa<DeclRefExpr>(CountedByExpr))
- if (const auto *ME = dyn_cast<MemberExpr>(CountedByExpr))
- CountedByExpr = ME->getBase()->IgnoreParenImpCasts();
-
- // Add back an implicit cast to create the required pr-value.
- CountedByExpr = ImplicitCastExpr::Create(
- getContext(), CountedByExpr->getType(), CK_LValueToRValue, CountedByExpr,
- nullptr, VK_PRValue, FPOptionsOverride());
-
- if (const auto *IFD = dyn_cast<IndirectFieldDecl>(CountedByVD)) {
- // The counted_by field is inside an anonymous struct / union. The
- // IndirectFieldDecl has the correct order of FieldDecls to build this
- // easily. (Yay!)
- for (NamedDecl *ND : IFD->chain()) {
- auto *VD = cast<ValueDecl>(ND);
- CountedByExpr =
- MemberExpr::CreateImplicit(getContext(), CountedByExpr,
- CountedByExpr->getType()->isPointerType(),
- VD, VD->getType(), VK_LValue, OK_Ordinary);
- }
- } else {
- CountedByExpr = MemberExpr::CreateImplicit(
- getContext(), const_cast<Expr *>(CountedByExpr),
- CountedByExpr->getType()->isPointerType(),
- const_cast<ValueDecl *>(CountedByVD), CountedByVD->getType(), VK_LValue,
- OK_Ordinary);
- }
-
- return CountedByExpr;
-}
-
-const ValueDecl *
-CodeGenFunction::FindFlexibleArrayMemberField(ASTContext &Ctx,
- const RecordDecl *RD) {
- const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
- getLangOpts().getStrictFlexArraysLevel();
-
- for (const Decl *D : RD->decls()) {
- if (const auto *VD = dyn_cast<ValueDecl>(D);
- VD && Decl::isFlexibleArrayMemberLike(
- Ctx, VD, VD->getType(), StrictFlexArraysLevel,
- /*IgnoreTemplateOrMacroSubstitution=*/true))
- return VD;
-
- if (const auto *Record = dyn_cast<RecordDecl>(D))
- if (const ValueDecl *VD = FindFlexibleArrayMemberField(Ctx, Record))
- return VD;
- }
-
- return nullptr;
-}
-
-const ValueDecl *CodeGenFunction::FindCountedByField(const Expr *Base) {
- ASTContext &Ctx = getContext();
- const RecordDecl *OuterRD = nullptr;
- const FieldDecl *FD = nullptr;
-
- Base = Base->IgnoreParenImpCasts();
-
- // Get the outer-most lexical RecordDecl.
- if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) {
- QualType Ty = DRE->getDecl()->getType();
- if (Ty->isPointerType())
- Ty = Ty->getPointeeType();
-
- if (const auto *RD = Ty->getAsRecordDecl())
- OuterRD = RD->getOuterLexicalRecordContext();
- } else if (const auto *ME = dyn_cast<MemberExpr>(Base)) {
- if (const ValueDecl *MD = ME->getMemberDecl()) {
- OuterRD = MD->getDeclContext()->getOuterLexicalRecordContext();
-
- const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
- getLangOpts().getStrictFlexArraysLevel();
- if (Decl::isFlexibleArrayMemberLike(
- Ctx, MD, MD->getType(), StrictFlexArraysLevel,
- /*IgnoreTemplateOrMacroSubstitution=*/true))
- // Base is referencing the FAM itself.
- FD = dyn_cast<FieldDecl>(MD);
- }
- }
-
- if (!OuterRD)
- return nullptr;
-
- if (!FD) {
- const ValueDecl *VD = FindFlexibleArrayMemberField(Ctx, OuterRD);
- FD = dyn_cast_if_present<FieldDecl>(VD);
- if (!FD)
- return nullptr;
- }
-
- const auto *CBA = FD->getAttr<CountedByAttr>();
- if (!CBA)
- return nullptr;
-
- DeclarationName DName(CBA->getCountedByField());
- DeclContext::lookup_result Lookup = OuterRD->lookup(DName);
-
- if (Lookup.empty())
- return nullptr;
-
- return dyn_cast<ValueDecl>(Lookup.front());
-}
-
void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
llvm::Value *Index, QualType IndexType,
bool Accessed) {
assert(SanOpts.has(SanitizerKind::ArrayBounds) &&
"should not be called unless adding bounds checks");
+ SanitizerScope SanScope(this);
+
const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
@@ -1081,8 +960,6 @@ void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
if (!Bound)
return;
- SanitizerScope SanScope(this);
-
bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType();
llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned);
llvm::Value *BoundVal = Builder.CreateIntCast(Bound, SizeTy, false);
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp
index 41ad2ddac30d..6adf99531e30 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1894,8 +1894,8 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
// initializer, since LLVM optimizers generally do not want to touch
// shuffles.
unsigned CurIdx = 0;
- bool VIsUndefShuffle = false;
- llvm::Value *V = llvm::UndefValue::get(VType);
+ bool VIsPoisonShuffle = false;
+ llvm::Value *V = llvm::PoisonValue::get(VType);
for (unsigned i = 0; i != NumInitElements; ++i) {
Expr *IE = E->getInit(i);
Value *Init = Visit(IE);
@@ -1915,16 +1915,16 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
Value *LHS = nullptr, *RHS = nullptr;
if (CurIdx == 0) {
- // insert into undef -> shuffle (src, undef)
+ // insert into poison -> shuffle (src, poison)
// shufflemask must use an i32
Args.push_back(getAsInt32(C, CGF.Int32Ty));
Args.resize(ResElts, -1);
LHS = EI->getVectorOperand();
RHS = V;
- VIsUndefShuffle = true;
- } else if (VIsUndefShuffle) {
- // insert into undefshuffle && size match -> shuffle (v, src)
+ VIsPoisonShuffle = true;
+ } else if (VIsPoisonShuffle) {
+ // insert into poison shuffle && size match -> shuffle (v, src)
llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V);
for (unsigned j = 0; j != CurIdx; ++j)
Args.push_back(getMaskElt(SVV, j, 0));
@@ -1933,7 +1933,7 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
RHS = EI->getVectorOperand();
- VIsUndefShuffle = false;
+ VIsPoisonShuffle = false;
}
if (!Args.empty()) {
V = Builder.CreateShuffleVector(LHS, RHS, Args);
@@ -1944,7 +1944,7 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
}
V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
"vecinit");
- VIsUndefShuffle = false;
+ VIsPoisonShuffle = false;
++CurIdx;
continue;
}
@@ -1962,9 +1962,9 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
if (OpTy->getNumElements() == ResElts) {
for (unsigned j = 0; j != CurIdx; ++j) {
- // If the current vector initializer is a shuffle with undef, merge
+ // If the current vector initializer is a shuffle with poison, merge
// this shuffle directly into it.
- if (VIsUndefShuffle) {
+ if (VIsPoisonShuffle) {
Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0));
} else {
Args.push_back(j);
@@ -1974,7 +1974,7 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
Args.push_back(getMaskElt(SVI, j, Offset));
Args.resize(ResElts, -1);
- if (VIsUndefShuffle)
+ if (VIsPoisonShuffle)
V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
Init = SVOp;
@@ -1997,12 +1997,12 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
Args.resize(ResElts, -1);
}
- // If V is undef, make sure it ends up on the RHS of the shuffle to aid
+ // If V is poison, make sure it ends up on the RHS of the shuffle to aid
// merging subsequent shuffles into this one.
if (CurIdx == 0)
std::swap(V, Init);
V = Builder.CreateShuffleVector(V, Init, Args, "vecinit");
- VIsUndefShuffle = isa<llvm::UndefValue>(Init);
+ VIsPoisonShuffle = isa<llvm::PoisonValue>(Init);
CurIdx += InitElts;
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 3e8a40e7540b..e887d35198b3 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -182,10 +182,8 @@ void CGHLSLRuntime::finishCodeGen() {
llvm::hlsl::ResourceKind RK = Buf.IsCBuffer
? llvm::hlsl::ResourceKind::CBuffer
: llvm::hlsl::ResourceKind::TBuffer;
- std::string TyName =
- Buf.Name.str() + (Buf.IsCBuffer ? ".cb." : ".tb.") + "ty";
- addBufferResourceAnnotation(GV, TyName, RC, RK, /*IsROV=*/false,
- Buf.Binding);
+ addBufferResourceAnnotation(GV, RC, RK, /*IsROV=*/false,
+ llvm::hlsl::ElementType::Invalid, Buf.Binding);
}
}
@@ -194,10 +192,10 @@ CGHLSLRuntime::Buffer::Buffer(const HLSLBufferDecl *D)
Binding(D->getAttr<HLSLResourceBindingAttr>()) {}
void CGHLSLRuntime::addBufferResourceAnnotation(llvm::GlobalVariable *GV,
- llvm::StringRef TyName,
llvm::hlsl::ResourceClass RC,
llvm::hlsl::ResourceKind RK,
bool IsROV,
+ llvm::hlsl::ElementType ET,
BufferResBinding &Binding) {
llvm::Module &M = CGM.getModule();
@@ -216,15 +214,62 @@ void CGHLSLRuntime::addBufferResourceAnnotation(llvm::GlobalVariable *GV,
assert(false && "Unsupported buffer type!");
return;
}
-
assert(ResourceMD != nullptr &&
"ResourceMD must have been set by the switch above.");
llvm::hlsl::FrontendResource Res(
- GV, TyName, RK, IsROV, Binding.Reg.value_or(UINT_MAX), Binding.Space);
+ GV, RK, ET, IsROV, Binding.Reg.value_or(UINT_MAX), Binding.Space);
ResourceMD->addOperand(Res.getMetadata());
}
+static llvm::hlsl::ElementType
+calculateElementType(const ASTContext &Context, const clang::Type *ResourceTy) {
+ using llvm::hlsl::ElementType;
+
+ // TODO: We may need to update this when we add things like ByteAddressBuffer
+ // that don't have a template parameter (or, indeed, an element type).
+ const auto *TST = ResourceTy->getAs<TemplateSpecializationType>();
+ assert(TST && "Resource types must be template specializations");
+ ArrayRef<TemplateArgument> Args = TST->template_arguments();
+ assert(!Args.empty() && "Resource has no element type");
+
+ // At this point we have a resource with an element type, so we can assume
+ // that it's valid or we would have diagnosed the error earlier.
+ QualType ElTy = Args[0].getAsType();
+
+ // We should either have a basic type or a vector of a basic type.
+ if (const auto *VecTy = ElTy->getAs<clang::VectorType>())
+ ElTy = VecTy->getElementType();
+
+ if (ElTy->isSignedIntegerType()) {
+ switch (Context.getTypeSize(ElTy)) {
+ case 16:
+ return ElementType::I16;
+ case 32:
+ return ElementType::I32;
+ case 64:
+ return ElementType::I64;
+ }
+ } else if (ElTy->isUnsignedIntegerType()) {
+ switch (Context.getTypeSize(ElTy)) {
+ case 16:
+ return ElementType::U16;
+ case 32:
+ return ElementType::U32;
+ case 64:
+ return ElementType::U64;
+ }
+ } else if (ElTy->isSpecificBuiltinType(BuiltinType::Half))
+ return ElementType::F16;
+ else if (ElTy->isSpecificBuiltinType(BuiltinType::Float))
+ return ElementType::F32;
+ else if (ElTy->isSpecificBuiltinType(BuiltinType::Double))
+ return ElementType::F64;
+
+ // TODO: We need to handle unorm/snorm float types here once we support them
+ llvm_unreachable("Invalid element type for resource");
+}
+
void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) {
const Type *Ty = D->getType()->getPointeeOrArrayElementType();
if (!Ty)
@@ -239,10 +284,10 @@ void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) {
llvm::hlsl::ResourceClass RC = Attr->getResourceClass();
llvm::hlsl::ResourceKind RK = Attr->getResourceKind();
bool IsROV = Attr->getIsROV();
+ llvm::hlsl::ElementType ET = calculateElementType(CGM.getContext(), Ty);
- QualType QT(Ty, 0);
BufferResBinding Binding(D->getAttr<HLSLResourceBindingAttr>());
- addBufferResourceAnnotation(GV, QT.getAsString(), RC, RK, IsROV, Binding);
+ addBufferResourceAnnotation(GV, RC, RK, IsROV, ET, Binding);
}
CGHLSLRuntime::BufferResBinding::BufferResBinding(
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.h b/contrib/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.h
index bb500cb5c979..bffefb66740a 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -90,9 +90,9 @@ public:
private:
void addBufferResourceAnnotation(llvm::GlobalVariable *GV,
- llvm::StringRef TyName,
llvm::hlsl::ResourceClass RC,
llvm::hlsl::ResourceKind RK, bool IsROV,
+ llvm::hlsl::ElementType ET,
BufferResBinding &Binding);
void addConstant(VarDecl *D, Buffer &CB);
void addBufferDecls(const DeclContext *DC, Buffer &CB);
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 7f7e6f530666..ea6645a39e83 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -6811,8 +6811,10 @@ private:
OpenMPMapClauseKind MapType, ArrayRef<OpenMPMapModifierKind> MapModifiers,
ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
- MapCombinedInfoTy &CombinedInfo, StructRangeInfoTy &PartialStruct,
- bool IsFirstComponentList, bool IsImplicit,
+ MapCombinedInfoTy &CombinedInfo,
+ MapCombinedInfoTy &StructBaseCombinedInfo,
+ StructRangeInfoTy &PartialStruct, bool IsFirstComponentList,
+ bool IsImplicit, bool GenerateAllInfoForClauses,
const ValueDecl *Mapper = nullptr, bool ForDeviceAddr = false,
const ValueDecl *BaseDecl = nullptr, const Expr *MapExpr = nullptr,
ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
@@ -7098,6 +7100,25 @@ private:
bool IsNonContiguous = CombinedInfo.NonContigInfo.IsNonContiguous;
bool IsPrevMemberReference = false;
+ // We need to check if we will be encountering any MEs. If we do not
+ // encounter any ME expression it means we will be mapping the whole struct.
+ // In that case we need to skip adding an entry for the struct to the
+ // CombinedInfo list and instead add an entry to the StructBaseCombinedInfo
+ // list only when generating all info for clauses.
+ bool IsMappingWholeStruct = true;
+ if (!GenerateAllInfoForClauses) {
+ IsMappingWholeStruct = false;
+ } else {
+ for (auto TempI = I; TempI != CE; ++TempI) {
+ const MemberExpr *PossibleME =
+ dyn_cast<MemberExpr>(TempI->getAssociatedExpression());
+ if (PossibleME) {
+ IsMappingWholeStruct = false;
+ break;
+ }
+ }
+ }
+
for (; I != CE; ++I) {
// If the current component is member of a struct (parent struct) mark it.
if (!EncounteredME) {
@@ -7317,21 +7338,41 @@ private:
break;
}
llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
+ // Skip adding an entry in the CurInfo of this combined entry if the
+ // whole struct is currently being mapped. The struct needs to be added
+ // in the first position before any data internal to the struct is being
+ // mapped.
if (!IsMemberPointerOrAddr ||
(Next == CE && MapType != OMPC_MAP_unknown)) {
- CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
- CombinedInfo.BasePointers.push_back(BP.getPointer());
- CombinedInfo.DevicePtrDecls.push_back(nullptr);
- CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None);
- CombinedInfo.Pointers.push_back(LB.getPointer());
- CombinedInfo.Sizes.push_back(
- CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true));
- CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize
- : 1);
+ if (!IsMappingWholeStruct) {
+ CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
+ CombinedInfo.BasePointers.push_back(BP.getPointer());
+ CombinedInfo.DevicePtrDecls.push_back(nullptr);
+ CombinedInfo.DevicePointers.push_back(DeviceInfoTy::None);
+ CombinedInfo.Pointers.push_back(LB.getPointer());
+ CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
+ Size, CGF.Int64Ty, /*isSigned=*/true));
+ CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize
+ : 1);
+ } else {
+ StructBaseCombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
+ StructBaseCombinedInfo.BasePointers.push_back(BP.getPointer());
+ StructBaseCombinedInfo.DevicePtrDecls.push_back(nullptr);
+ StructBaseCombinedInfo.DevicePointers.push_back(DeviceInfoTy::None);
+ StructBaseCombinedInfo.Pointers.push_back(LB.getPointer());
+ StructBaseCombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
+ Size, CGF.Int64Ty, /*isSigned=*/true));
+ StructBaseCombinedInfo.NonContigInfo.Dims.push_back(
+ IsNonContiguous ? DimSize : 1);
+ }
// If Mapper is valid, the last component inherits the mapper.
bool HasMapper = Mapper && Next == CE;
- CombinedInfo.Mappers.push_back(HasMapper ? Mapper : nullptr);
+ if (!IsMappingWholeStruct)
+ CombinedInfo.Mappers.push_back(HasMapper ? Mapper : nullptr);
+ else
+ StructBaseCombinedInfo.Mappers.push_back(HasMapper ? Mapper
+ : nullptr);
// We need to add a pointer flag for each map that comes from the
// same expression except for the first one. We also need to signal
@@ -7363,7 +7404,10 @@ private:
}
}
- CombinedInfo.Types.push_back(Flags);
+ if (!IsMappingWholeStruct)
+ CombinedInfo.Types.push_back(Flags);
+ else
+ StructBaseCombinedInfo.Types.push_back(Flags);
}
// If we have encountered a member expression so far, keep track of the
@@ -7954,8 +7998,10 @@ private:
for (const auto &Data : Info) {
StructRangeInfoTy PartialStruct;
- // Temporary generated information.
+ // Current struct information:
MapCombinedInfoTy CurInfo;
+ // Current struct base information:
+ MapCombinedInfoTy StructBaseCurInfo;
const Decl *D = Data.first;
const ValueDecl *VD = cast_or_null<ValueDecl>(D);
for (const auto &M : Data.second) {
@@ -7965,29 +8011,55 @@ private:
// Remember the current base pointer index.
unsigned CurrentBasePointersIdx = CurInfo.BasePointers.size();
+ unsigned StructBasePointersIdx =
+ StructBaseCurInfo.BasePointers.size();
CurInfo.NonContigInfo.IsNonContiguous =
L.Components.back().isNonContiguous();
generateInfoForComponentList(
L.MapType, L.MapModifiers, L.MotionModifiers, L.Components,
- CurInfo, PartialStruct, /*IsFirstComponentList=*/false,
- L.IsImplicit, L.Mapper, L.ForDeviceAddr, VD, L.VarRef);
+ CurInfo, StructBaseCurInfo, PartialStruct,
+ /*IsFirstComponentList=*/false, L.IsImplicit,
+ /*GenerateAllInfoForClauses*/ true, L.Mapper, L.ForDeviceAddr, VD,
+ L.VarRef);
- // If this entry relates with a device pointer, set the relevant
+ // If this entry relates to a device pointer, set the relevant
// declaration and add the 'return pointer' flag.
if (L.ReturnDevicePointer) {
- assert(CurInfo.BasePointers.size() > CurrentBasePointersIdx &&
+ // Check whether a value was added to either CurInfo or
+ // StructBaseCurInfo and error if no value was added to either of
+ // them:
+ assert((CurrentBasePointersIdx < CurInfo.BasePointers.size() ||
+ StructBasePointersIdx <
+ StructBaseCurInfo.BasePointers.size()) &&
"Unexpected number of mapped base pointers.");
+ // Choose a base pointer index which is always valid:
const ValueDecl *RelevantVD =
L.Components.back().getAssociatedDeclaration();
assert(RelevantVD &&
"No relevant declaration related with device pointer??");
- CurInfo.DevicePtrDecls[CurrentBasePointersIdx] = RelevantVD;
- CurInfo.DevicePointers[CurrentBasePointersIdx] =
- L.ForDeviceAddr ? DeviceInfoTy::Address : DeviceInfoTy::Pointer;
- CurInfo.Types[CurrentBasePointersIdx] |=
- OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM;
+ // If StructBaseCurInfo has been updated this iteration then work on
+ // the first new entry added to it i.e. make sure that when multiple
+ // values are added to any of the lists, the first value added is
+ // being modified by the assignments below (not the last value
+ // added).
+ if (StructBasePointersIdx < StructBaseCurInfo.BasePointers.size()) {
+ StructBaseCurInfo.DevicePtrDecls[StructBasePointersIdx] =
+ RelevantVD;
+ StructBaseCurInfo.DevicePointers[StructBasePointersIdx] =
+ L.ForDeviceAddr ? DeviceInfoTy::Address
+ : DeviceInfoTy::Pointer;
+ StructBaseCurInfo.Types[StructBasePointersIdx] |=
+ OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM;
+ } else {
+ CurInfo.DevicePtrDecls[CurrentBasePointersIdx] = RelevantVD;
+ CurInfo.DevicePointers[CurrentBasePointersIdx] =
+ L.ForDeviceAddr ? DeviceInfoTy::Address
+ : DeviceInfoTy::Pointer;
+ CurInfo.Types[CurrentBasePointersIdx] |=
+ OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM;
+ }
}
}
}
@@ -8034,17 +8106,24 @@ private:
CurInfo.Mappers.push_back(nullptr);
}
}
+
+ // Unify entries in one list making sure the struct mapping precedes the
+ // individual fields:
+ MapCombinedInfoTy UnionCurInfo;
+ UnionCurInfo.append(StructBaseCurInfo);
+ UnionCurInfo.append(CurInfo);
+
// If there is an entry in PartialStruct it means we have a struct with
// individual members mapped. Emit an extra combined entry.
if (PartialStruct.Base.isValid()) {
- CurInfo.NonContigInfo.Dims.push_back(0);
- emitCombinedEntry(CombinedInfo, CurInfo.Types, PartialStruct,
+ UnionCurInfo.NonContigInfo.Dims.push_back(0);
+ // Emit a combined entry:
+ emitCombinedEntry(CombinedInfo, UnionCurInfo.Types, PartialStruct,
/*IsMapThis*/ !VD, OMPBuilder, VD);
}
- // We need to append the results of this capture to what we already
- // have.
- CombinedInfo.append(CurInfo);
+ // We need to append the results of this capture to what we already have.
+ CombinedInfo.append(UnionCurInfo);
}
// Append data for use_device_ptr clauses.
CombinedInfo.append(UseDeviceDataCombinedInfo);
@@ -8554,6 +8633,7 @@ public:
// Associated with a capture, because the mapping flags depend on it.
// Go through all of the elements with the overlapped elements.
bool IsFirstComponentList = true;
+ MapCombinedInfoTy StructBaseCombinedInfo;
for (const auto &Pair : OverlappedData) {
const MapData &L = *Pair.getFirst();
OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
@@ -8568,7 +8648,8 @@ public:
OverlappedComponents = Pair.getSecond();
generateInfoForComponentList(
MapType, MapModifiers, std::nullopt, Components, CombinedInfo,
- PartialStruct, IsFirstComponentList, IsImplicit, Mapper,
+ StructBaseCombinedInfo, PartialStruct, IsFirstComponentList,
+ IsImplicit, /*GenerateAllInfoForClauses*/ false, Mapper,
/*ForDeviceAddr=*/false, VD, VarRef, OverlappedComponents);
IsFirstComponentList = false;
}
@@ -8584,10 +8665,11 @@ public:
L;
auto It = OverlappedData.find(&L);
if (It == OverlappedData.end())
- generateInfoForComponentList(MapType, MapModifiers, std::nullopt,
- Components, CombinedInfo, PartialStruct,
- IsFirstComponentList, IsImplicit, Mapper,
- /*ForDeviceAddr=*/false, VD, VarRef);
+ generateInfoForComponentList(
+ MapType, MapModifiers, std::nullopt, Components, CombinedInfo,
+ StructBaseCombinedInfo, PartialStruct, IsFirstComponentList,
+ IsImplicit, /*GenerateAllInfoForClauses*/ false, Mapper,
+ /*ForDeviceAddr=*/false, VD, VarRef);
IsFirstComponentList = false;
}
}
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h
index 618e78809db4..751d8110b13d 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h
@@ -3022,19 +3022,6 @@ public:
void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index,
QualType IndexType, bool Accessed);
- // Find a struct's flexible array member. It may be embedded inside multiple
- // sub-structs, but must still be the last field.
- const ValueDecl *FindFlexibleArrayMemberField(ASTContext &Ctx,
- const RecordDecl *RD);
-
- /// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns
- /// \p nullptr if either the attribute or the field doesn't exist.
- const ValueDecl *FindCountedByField(const Expr *Base);
-
- /// Build an expression accessing the "counted_by" field.
- const Expr *BuildCountedByFieldExpr(const Expr *Base,
- const ValueDecl *CountedByVD);
-
llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
bool isInc, bool isPre);
ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
@@ -4830,9 +4817,6 @@ private:
llvm::Value *EmittedE,
bool IsDynamic);
- llvm::Value *emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
- llvm::IntegerType *ResType);
-
void emitZeroOrPatternForAutoVarInit(QualType type, const VarDecl &D,
Address Loc);
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
index 7ad26ace328a..d78f2594a237 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
@@ -995,12 +995,7 @@ void CodeGenModule::Release() {
uint32_t(CLANG_VERSION_MINOR));
getModule().addModuleFlag(llvm::Module::Warning, "zos_product_patchlevel",
uint32_t(CLANG_VERSION_PATCHLEVEL));
- std::string ProductId;
-#ifdef CLANG_VENDOR
- ProductId = #CLANG_VENDOR;
-#else
- ProductId = "clang";
-#endif
+ std::string ProductId = getClangVendor() + "clang";
getModule().addModuleFlag(llvm::Module::Error, "zos_product_id",
llvm::MDString::get(VMContext, ProductId));
@@ -1111,6 +1106,9 @@ void CodeGenModule::Release() {
if (LangOpts.BranchTargetEnforcement)
getModule().addModuleFlag(llvm::Module::Min, "branch-target-enforcement",
1);
+ if (LangOpts.BranchProtectionPAuthLR)
+ getModule().addModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr",
+ 1);
if (LangOpts.hasSignReturnAddress())
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 1);
if (LangOpts.isSignReturnAddressScopeAll())
diff --git a/contrib/llvm-project/clang/lib/CodeGen/Targets/AArch64.cpp b/contrib/llvm-project/clang/lib/CodeGen/Targets/AArch64.cpp
index be5145daa00b..7102d190fe00 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -136,6 +136,8 @@ public:
Fn->addFnAttr("branch-target-enforcement",
BPI.BranchTargetEnforcement ? "true" : "false");
+ Fn->addFnAttr("branch-protection-pauth-lr",
+ BPI.BranchProtectionPAuthLR ? "true" : "false");
}
bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF,
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp
index f9670ea6f251..e6126ff62db3 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp
@@ -328,6 +328,12 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
}
+ if (D.IsFlangMode()) {
+ addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
+ addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
+ CmdArgs.push_back("-lm");
+ CmdArgs.push_back("-lpthread");
+ }
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
Exec, CmdArgs, Inputs, Output));
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 2e39fc29a931..80c0f88105d1 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -45,6 +45,10 @@ static bool getArchFeatures(const Driver &D, StringRef Arch,
(*ISAInfo)->toFeatures(
Features, [&Args](const Twine &Str) { return Args.MakeArgString(Str); },
/*AddAllExtensions=*/true);
+
+ if (EnableExperimentalExtensions)
+ Features.push_back(Args.MakeArgString("+experimental"));
+
return true;
}
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
index de9fd5eaa1e0..70dc7e54aca1 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1497,7 +1497,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
<< Triple.getArchName();
StringRef Scope, Key;
- bool IndirectBranches;
+ bool IndirectBranches, BranchProtectionPAuthLR;
if (A->getOption().matches(options::OPT_msign_return_address_EQ)) {
Scope = A->getValue();
@@ -1506,6 +1506,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
<< A->getSpelling() << Scope;
Key = "a_key";
IndirectBranches = false;
+ BranchProtectionPAuthLR = false;
} else {
StringRef DiagMsg;
llvm::ARM::ParsedBranchProtection PBP;
@@ -1517,6 +1518,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
<< "b-key" << A->getAsString(Args);
Scope = PBP.Scope;
Key = PBP.Key;
+ BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
IndirectBranches = PBP.BranchTargetEnforcement;
}
@@ -1525,6 +1527,9 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
if (!Scope.equals("none"))
CmdArgs.push_back(
Args.MakeArgString(Twine("-msign-return-address-key=") + Key));
+ if (BranchProtectionPAuthLR)
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-mbranch-protection-pauth-lr")));
if (IndirectBranches)
CmdArgs.push_back("-mbranch-target-enforce");
}
@@ -3198,13 +3203,13 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
options::OPT_fstrict_float_cast_overflow, false))
CmdArgs.push_back("-fno-strict-float-cast-overflow");
- if (const Arg *A = Args.getLastArg(options::OPT_fcx_limited_range))
+ if (Args.hasArg(options::OPT_fcx_limited_range))
CmdArgs.push_back("-fcx-limited-range");
- if (const Arg *A = Args.getLastArg(options::OPT_fcx_fortran_rules))
+ if (Args.hasArg(options::OPT_fcx_fortran_rules))
CmdArgs.push_back("-fcx-fortran-rules");
- if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_limited_range))
+ if (Args.hasArg(options::OPT_fno_cx_limited_range))
CmdArgs.push_back("-fno-cx-limited-range");
- if (const Arg *A = Args.getLastArg(options::OPT_fno_cx_fortran_rules))
+ if (Args.hasArg(options::OPT_fno_cx_fortran_rules))
CmdArgs.push_back("-fno-cx-fortran-rules");
}
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 45901ee7157f..6eb0ed8f3fed 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1174,8 +1174,9 @@ static void addFortranMain(const ToolChain &TC, const ArgList &Args,
// The --whole-archive option needs to be part of the link line to make
// sure that the main() function from Fortran_main.a is pulled in by the
// linker. However, it shouldn't be used if it's already active.
- // TODO: Find an equivalent of `--whole-archive` for Darwin.
- if (!isWholeArchivePresent(Args) && !TC.getTriple().isMacOSX()) {
+ // TODO: Find an equivalent of `--whole-archive` for Darwin and AIX.
+ if (!isWholeArchivePresent(Args) && !TC.getTriple().isMacOSX() &&
+ !TC.getTriple().isOSAIX()) {
CmdArgs.push_back("--whole-archive");
CmdArgs.push_back("-lFortran_main");
CmdArgs.push_back("--no-whole-archive");
@@ -1317,28 +1318,28 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args);
// Collect shared runtimes.
if (SanArgs.needsSharedRt()) {
- if (SanArgs.needsAsanRt() && SanArgs.linkRuntimes()) {
+ if (SanArgs.needsAsanRt()) {
SharedRuntimes.push_back("asan");
if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
HelperStaticRuntimes.push_back("asan-preinit");
}
- if (SanArgs.needsMemProfRt() && SanArgs.linkRuntimes()) {
+ if (SanArgs.needsMemProfRt()) {
SharedRuntimes.push_back("memprof");
if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
HelperStaticRuntimes.push_back("memprof-preinit");
}
- if (SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) {
+ if (SanArgs.needsUbsanRt()) {
if (SanArgs.requiresMinimalRuntime())
SharedRuntimes.push_back("ubsan_minimal");
else
SharedRuntimes.push_back("ubsan_standalone");
}
- if (SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) {
+ if (SanArgs.needsScudoRt()) {
SharedRuntimes.push_back("scudo_standalone");
}
- if (SanArgs.needsTsanRt() && SanArgs.linkRuntimes())
+ if (SanArgs.needsTsanRt())
SharedRuntimes.push_back("tsan");
- if (SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) {
+ if (SanArgs.needsHwasanRt()) {
if (SanArgs.needsHwasanAliasesRt())
SharedRuntimes.push_back("hwasan_aliases");
else
@@ -1349,7 +1350,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
}
// The stats_client library is also statically linked into DSOs.
- if (SanArgs.needsStatsRt() && SanArgs.linkRuntimes())
+ if (SanArgs.needsStatsRt())
StaticRuntimes.push_back("stats_client");
// Always link the static runtime regardless of DSO or executable.
@@ -1365,20 +1366,19 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
// Each static runtime that has a DSO counterpart above is excluded below,
// but runtimes that exist only as static are not affected by needsSharedRt.
- if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt() && SanArgs.linkRuntimes()) {
+ if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt()) {
StaticRuntimes.push_back("asan");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("asan_cxx");
}
- if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt() &&
- SanArgs.linkRuntimes()) {
+ if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) {
StaticRuntimes.push_back("memprof");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("memprof_cxx");
}
- if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) {
+ if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt()) {
if (SanArgs.needsHwasanAliasesRt()) {
StaticRuntimes.push_back("hwasan_aliases");
if (SanArgs.linkCXXRuntimes())
@@ -1389,22 +1389,21 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
StaticRuntimes.push_back("hwasan_cxx");
}
}
- if (SanArgs.needsDfsanRt() && SanArgs.linkRuntimes())
+ if (SanArgs.needsDfsanRt())
StaticRuntimes.push_back("dfsan");
- if (SanArgs.needsLsanRt() && SanArgs.linkRuntimes())
+ if (SanArgs.needsLsanRt())
StaticRuntimes.push_back("lsan");
- if (SanArgs.needsMsanRt() && SanArgs.linkRuntimes()) {
+ if (SanArgs.needsMsanRt()) {
StaticRuntimes.push_back("msan");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("msan_cxx");
}
- if (!SanArgs.needsSharedRt() && SanArgs.needsTsanRt() &&
- SanArgs.linkRuntimes()) {
+ if (!SanArgs.needsSharedRt() && SanArgs.needsTsanRt()) {
StaticRuntimes.push_back("tsan");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("tsan_cxx");
}
- if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) {
+ if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt()) {
if (SanArgs.requiresMinimalRuntime()) {
StaticRuntimes.push_back("ubsan_minimal");
} else {
@@ -1413,24 +1412,24 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
StaticRuntimes.push_back("ubsan_standalone_cxx");
}
}
- if (SanArgs.needsSafeStackRt() && SanArgs.linkRuntimes()) {
+ if (SanArgs.needsSafeStackRt()) {
NonWholeStaticRuntimes.push_back("safestack");
RequiredSymbols.push_back("__safestack_init");
}
- if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes())) {
- if (SanArgs.needsCfiRt() && SanArgs.linkRuntimes())
+ if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt())) {
+ if (SanArgs.needsCfiRt())
StaticRuntimes.push_back("cfi");
- if (SanArgs.needsCfiDiagRt() && SanArgs.linkRuntimes()) {
+ if (SanArgs.needsCfiDiagRt()) {
StaticRuntimes.push_back("cfi_diag");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("ubsan_standalone_cxx");
}
}
- if (SanArgs.needsStatsRt() && SanArgs.linkRuntimes()) {
+ if (SanArgs.needsStatsRt()) {
NonWholeStaticRuntimes.push_back("stats");
RequiredSymbols.push_back("__sanitizer_stats_register");
}
- if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) {
+ if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt()) {
StaticRuntimes.push_back("scudo_standalone");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("scudo_standalone_cxx");
@@ -1441,13 +1440,15 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
// C runtime, etc). Returns true if sanitizer system deps need to be linked in.
bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
+ const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args);
SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes,
NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols;
- collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
- NonWholeStaticRuntimes, HelperStaticRuntimes,
- RequiredSymbols);
+ if (SanArgs.linkRuntimes()) {
+ collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
+ NonWholeStaticRuntimes, HelperStaticRuntimes,
+ RequiredSymbols);
+ }
- const SanitizerArgs &SanArgs = TC.getSanitizerArgs(Args);
// Inject libfuzzer dependencies.
if (SanArgs.needsFuzzer() && SanArgs.linkRuntimes() &&
!Args.hasArg(options::OPT_shared)) {
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp
index 835215a83c40..38361d6889a1 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -30,6 +30,7 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/RISCVISAInfo.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/TargetParser.h"
#include <system_error>
@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
Result.Multilibs = CSKYMultilibs;
}
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This function will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+/// - ABI must be the same.
+/// - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+/// - march that contains atomic extension can't reuse multi-lib that
+/// doesn't have atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+selectRISCVMultilib(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+ const Multilib::flags_list &Flags,
+ llvm::SmallVectorImpl<Multilib> &SelectedMultilibs) {
+ // Try to find the perfect matching multi-lib first.
+ if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
+ return true;
+
+ Multilib::flags_list NewFlags;
+ std::vector<MultilibBuilder> NewMultilibs;
+
+ llvm::Expected<std::unique_ptr<llvm::RISCVISAInfo>> ParseResult =
+ llvm::RISCVISAInfo::parseArchString(
+ Arch, /*EnableExperimentalExtension=*/true,
+ /*ExperimentalExtensionVersionCheck=*/false);
+ if (!ParseResult) {
+ // Ignore any error here, we assume it will be handled in another place.
+ consumeError(ParseResult.takeError());
+ return false;
+ }
+
+ auto &ISAInfo = *ParseResult;
+
+ addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);
+ addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);
+
+ // Collect all flags except march=*
+ for (StringRef Flag : Flags) {
+ if (Flag.starts_with("!march=") || Flag.starts_with("-march="))
+ continue;
+
+ NewFlags.push_back(Flag.str());
+ }
+
+ llvm::StringSet<> AllArchExts;
+ // Reconstruct multi-lib list, and break march option into separated
+ // extension. e.g. march=rv32im -> +i +m
+ for (const auto &M : RISCVMultilibSet) {
+ bool Skip = false;
+
+ MultilibBuilder NewMultilib =
+ MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());
+ for (StringRef Flag : M.flags()) {
+ // Add back all flags except -march.
+ if (!Flag.consume_front("-march=")) {
+ NewMultilib.flag(Flag);
+ continue;
+ }
+
+ // Break down -march into individual extension.
+ llvm::Expected<std::unique_ptr<llvm::RISCVISAInfo>> MLConfigParseResult =
+ llvm::RISCVISAInfo::parseArchString(
+ Flag, /*EnableExperimentalExtension=*/true,
+ /*ExperimentalExtensionVersionCheck=*/false);
+ if (!MLConfigParseResult) {
+ // Ignore any error here, we assume it will handled in another place.
+ llvm::consumeError(MLConfigParseResult.takeError());
+
+ // We might get a parsing error if rv32e in the list, we could just skip
+ // that and process the rest of multi-lib configs.
+ Skip = true;
+ continue;
+ }
+ auto &MLConfigISAInfo = *MLConfigParseResult;
+
+ const llvm::RISCVISAInfo::OrderedExtensionMap &MLConfigArchExts =
+ MLConfigISAInfo->getExtensions();
+ for (auto MLConfigArchExt : MLConfigArchExts) {
+ auto ExtName = MLConfigArchExt.first;
+ NewMultilib.flag(Twine("-", ExtName).str());
+
+ if (AllArchExts.insert(ExtName).second) {
+ addMultilibFlag(ISAInfo->hasExtension(ExtName),
+ Twine("-", ExtName).str(), NewFlags);
+ }
+ }
+
+ // Check the XLEN explicitly.
+ if (MLConfigISAInfo->getXLen() == 32) {
+ NewMultilib.flag("-m32");
+ NewMultilib.flag("-m64", /*Disallow*/ true);
+ } else {
+ NewMultilib.flag("-m32", /*Disallow*/ true);
+ NewMultilib.flag("-m64");
+ }
+
+ // Atomic extension must be explicitly checked, soft and hard atomic
+ // operation never co-work correctly.
+ if (!MLConfigISAInfo->hasExtension("a"))
+ NewMultilib.flag("-a", /*Disallow*/ true);
+ }
+
+ if (Skip)
+ continue;
+
+ NewMultilibs.emplace_back(NewMultilib);
+ }
+
+ // Build an internal used only multi-lib list, used for checking any
+ // compatible multi-lib.
+ MultilibSet NewRISCVMultilibs =
+ MultilibSetBuilder().Either(NewMultilibs).makeMultilibSet();
+
+ if (NewRISCVMultilibs.select(NewFlags, SelectedMultilibs))
+ for (const Multilib &NewSelectedM : SelectedMultilibs)
+ for (const auto &M : RISCVMultilibSet)
+ // Look up the corresponding multi-lib entry in original multi-lib set.
+ if (M.gccSuffix() == NewSelectedM.gccSuffix())
+ return true;
+
+ return false;
+}
+
static void findRISCVBareMetalMultilibs(const Driver &D,
const llvm::Triple &TargetTriple,
StringRef Path, const ArgList &Args,
@@ -1766,7 +1890,8 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
}
}
- if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs))
+ if (selectRISCVMultilib(RISCVMultilibs, MArch, Flags,
+ Result.SelectedMultilibs))
Result.Multilibs = RISCVMultilibs;
}
diff --git a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp b/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp
index bd319f21b05f..8489a30dd34a 100644
--- a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp
+++ b/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp
@@ -583,17 +583,15 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
return true;
}
- // If the return type spans multiple lines, wrap before the function name.
- if (((Current.is(TT_FunctionDeclarationName) &&
- !State.Line->ReturnTypeWrapped &&
- // Don't break before a C# function when no break after return type.
- (!Style.isCSharp() ||
- Style.AlwaysBreakAfterReturnType != FormatStyle::RTBS_None) &&
- // Don't always break between a JavaScript `function` and the function
- // name.
- !Style.isJavaScript()) ||
- (Current.is(tok::kw_operator) && Previous.isNot(tok::coloncolon))) &&
- Previous.isNot(tok::kw_template) && CurrentState.BreakBeforeParameter) {
+ if (Current.is(TT_FunctionDeclarationName) &&
+ !State.Line->ReturnTypeWrapped &&
+ // Don't break before a C# function when no break after return type.
+ (!Style.isCSharp() ||
+ Style.AlwaysBreakAfterReturnType != FormatStyle::RTBS_None) &&
+ // Don't always break between a JavaScript `function` and the function
+ // name.
+ !Style.isJavaScript() && Previous.isNot(tok::kw_template) &&
+ CurrentState.BreakBeforeParameter) {
return true;
}
diff --git a/contrib/llvm-project/clang/lib/Format/Format.cpp b/contrib/llvm-project/clang/lib/Format/Format.cpp
index 668e959a9416..f798d555bf99 100644
--- a/contrib/llvm-project/clang/lib/Format/Format.cpp
+++ b/contrib/llvm-project/clang/lib/Format/Format.cpp
@@ -1315,7 +1315,6 @@ static void expandPresetsBraceWrapping(FormatStyle &Expanded) {
Expanded.BraceWrapping.AfterStruct = true;
Expanded.BraceWrapping.AfterUnion = true;
Expanded.BraceWrapping.AfterExternBlock = true;
- Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
Expanded.BraceWrapping.SplitEmptyFunction = true;
Expanded.BraceWrapping.SplitEmptyRecord = false;
break;
@@ -1335,7 +1334,6 @@ static void expandPresetsBraceWrapping(FormatStyle &Expanded) {
Expanded.BraceWrapping.AfterStruct = true;
Expanded.BraceWrapping.AfterUnion = true;
Expanded.BraceWrapping.AfterExternBlock = true;
- Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
Expanded.BraceWrapping.BeforeCatch = true;
Expanded.BraceWrapping.BeforeElse = true;
Expanded.BraceWrapping.BeforeLambdaBody = true;
@@ -1350,7 +1348,6 @@ static void expandPresetsBraceWrapping(FormatStyle &Expanded) {
Expanded.BraceWrapping.AfterObjCDeclaration = true;
Expanded.BraceWrapping.AfterStruct = true;
Expanded.BraceWrapping.AfterExternBlock = true;
- Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
Expanded.BraceWrapping.BeforeCatch = true;
Expanded.BraceWrapping.BeforeElse = true;
Expanded.BraceWrapping.BeforeLambdaBody = true;
@@ -1375,7 +1372,6 @@ static void expandPresetsBraceWrapping(FormatStyle &Expanded) {
/*SplitEmptyFunction=*/true,
/*SplitEmptyRecord=*/true,
/*SplitEmptyNamespace=*/true};
- Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
break;
case FormatStyle::BS_WebKit:
Expanded.BraceWrapping.AfterFunction = true;
@@ -1702,6 +1698,9 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
/*BasedOnStyle=*/"google",
},
};
+ GoogleStyle.AttributeMacros.push_back("GUARDED_BY");
+ GoogleStyle.AttributeMacros.push_back("ABSL_GUARDED_BY");
+
GoogleStyle.SpacesBeforeTrailingComments = 2;
GoogleStyle.Standard = FormatStyle::LS_Auto;
@@ -1909,7 +1908,6 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
Style.BraceWrapping.AfterObjCDeclaration = true;
Style.BraceWrapping.AfterStruct = true;
Style.BraceWrapping.AfterExternBlock = true;
- Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
Style.BraceWrapping.BeforeCatch = true;
Style.BraceWrapping.BeforeElse = true;
Style.BraceWrapping.BeforeWhile = false;
diff --git a/contrib/llvm-project/clang/lib/Format/MatchFilePath.cpp b/contrib/llvm-project/clang/lib/Format/MatchFilePath.cpp
new file mode 100644
index 000000000000..412ee4954587
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Format/MatchFilePath.cpp
@@ -0,0 +1,122 @@
+//===--- MatchFilePath.cpp - Match file path with pattern -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements the functionality of matching a file path name to
+/// a pattern, similar to the POSIX fnmatch() function.
+///
+//===----------------------------------------------------------------------===//
+
+#include "MatchFilePath.h"
+
+using namespace llvm;
+
+namespace clang {
+namespace format {
+
+// Check whether `FilePath` matches `Pattern` based on POSIX (1003.1-2008)
+// 2.13.1, 2.13.2, and Rule 1 of 2.13.3.
+bool matchFilePath(StringRef Pattern, StringRef FilePath) {
+ assert(!Pattern.empty());
+ assert(!FilePath.empty());
+
+ // No match if `Pattern` ends with a non-meta character not equal to the last
+ // character of `FilePath`.
+ if (const auto C = Pattern.back(); !strchr("?*]", C) && C != FilePath.back())
+ return false;
+
+ constexpr auto Separator = '/';
+ const auto EOP = Pattern.size(); // End of `Pattern`.
+ const auto End = FilePath.size(); // End of `FilePath`.
+ unsigned I = 0; // Index to `Pattern`.
+
+ for (unsigned J = 0; J < End; ++J) {
+ if (I == EOP)
+ return false;
+
+ switch (const auto F = FilePath[J]; Pattern[I]) {
+ case '\\':
+ if (++I == EOP || F != Pattern[I])
+ return false;
+ break;
+ case '?':
+ if (F == Separator)
+ return false;
+ break;
+ case '*': {
+ while (++I < EOP && Pattern[I] == '*') { // Skip consecutive stars.
+ }
+ const auto K = FilePath.find(Separator, J); // Index of next `Separator`.
+ const bool NoMoreSeparatorsInFilePath = K == StringRef::npos;
+ if (I == EOP) // `Pattern` ends with a star.
+ return NoMoreSeparatorsInFilePath;
+ // `Pattern` ends with a lone backslash.
+ if (Pattern[I] == '\\' && ++I == EOP)
+ return false;
+ // The star is followed by a (possibly escaped) `Separator`.
+ if (Pattern[I] == Separator) {
+ if (NoMoreSeparatorsInFilePath)
+ return false;
+ J = K; // Skip to next `Separator` in `FilePath`.
+ break;
+ }
+ // Recurse.
+ for (auto Pat = Pattern.substr(I); J < End && FilePath[J] != Separator;
+ ++J) {
+ if (matchFilePath(Pat, FilePath.substr(J)))
+ return true;
+ }
+ return false;
+ }
+ case '[':
+ // Skip e.g. `[!]`.
+ if (I + 3 < EOP || (I + 3 == EOP && Pattern[I + 1] != '!')) {
+ // Skip unpaired `[`, brackets containing slashes, and `[]`.
+ if (const auto K = Pattern.find_first_of("]/", I + 1);
+ K != StringRef::npos && Pattern[K] == ']' && K > I + 1) {
+ if (F == Separator)
+ return false;
+ ++I; // After the `[`.
+ bool Negated = false;
+ if (Pattern[I] == '!') {
+ Negated = true;
+ ++I; // After the `!`.
+ }
+ bool Match = false;
+ do {
+ if (I + 2 < K && Pattern[I + 1] == '-') {
+ Match = Pattern[I] <= F && F <= Pattern[I + 2];
+ I += 3; // After the range, e.g. `A-Z`.
+ } else {
+ Match = F == Pattern[I++];
+ }
+ } while (!Match && I < K);
+ if (Negated ? Match : !Match)
+ return false;
+ I = K + 1; // After the `]`.
+ continue;
+ }
+ }
+ [[fallthrough]]; // Match `[` literally.
+ default:
+ if (F != Pattern[I])
+ return false;
+ }
+
+ ++I;
+ }
+
+ // Match trailing stars with null strings.
+ while (I < EOP && Pattern[I] == '*')
+ ++I;
+
+ return I == EOP;
+}
+
+} // namespace format
+} // namespace clang
diff --git a/contrib/llvm-project/clang/lib/Format/MatchFilePath.h b/contrib/llvm-project/clang/lib/Format/MatchFilePath.h
new file mode 100644
index 000000000000..482dab7c748e
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Format/MatchFilePath.h
@@ -0,0 +1,22 @@
+//===--- MatchFilePath.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_FORMAT_MATCHFILEPATH_H
+#define LLVM_CLANG_LIB_FORMAT_MATCHFILEPATH_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace format {
+
+bool matchFilePath(llvm::StringRef Pattern, llvm::StringRef FilePath);
+
+} // end namespace format
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp
index f3551af34243..3ac3aa3c5e3a 100644
--- a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp
+++ b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp
@@ -3403,7 +3403,8 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current,
continue;
}
if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
- Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) {
+ Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis,
+ TT_TypeName)) {
return true;
}
if (Tok->isOneOf(tok::l_brace, TT_ObjCMethodExpr) || Tok->Tok.isLiteral())
diff --git a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
index c38b4c884070..684609747a55 100644
--- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1650,8 +1650,10 @@ void UnwrappedLineParser::parseStructuralElement(
return;
}
// In Verilog labels can be any expression, so we don't do them here.
- if (!Style.isVerilog() && Tokens->peekNextToken()->is(tok::colon) &&
- !Line->MustBeDeclaration) {
+ // JS doesn't have macros, and within classes colons indicate fields, not
+ // labels.
+ if (!Style.isJavaScript() && !Style.isVerilog() &&
+ Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) {
nextToken();
Line->Tokens.begin()->Tok->MustBreakBefore = true;
FormatTok->setFinalizedType(TT_GotoLabelColon);
diff --git a/contrib/llvm-project/clang/lib/Headers/adcintrin.h b/contrib/llvm-project/clang/lib/Headers/adcintrin.h
new file mode 100644
index 000000000000..0065a1b543f8
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Headers/adcintrin.h
@@ -0,0 +1,160 @@
+/*===---- adcintrin.h - ADC intrinsics -------------------------------------===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __ADCINTRIN_H
+#define __ADCINTRIN_H
+
+#if !defined(__i386__) && !defined(__x86_64__)
+#error "This header is only meant to be used on x86 and x64 architecture"
+#endif
+
+/* Define the default attributes for the functions in this file. */
+#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
+
+/* Use C++ inline semantics in C++, GNU inline for C mode. */
+#if defined(__cplusplus)
+#define __INLINE __inline
+#else
+#define __INLINE static __inline
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated
+/// by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory
+/// at \a __p, and returns the 8-bit carry-out (carry flag).
+///
+/// \code{.operation}
+/// temp := (__cf == 0) ? 0 : 1
+/// Store32(__p, __x + __y + temp)
+/// result := CF
+/// \endcode
+///
+/// \headerfile <immintrin.h>
+///
+/// This intrinsic corresponds to the \c ADC instruction.
+///
+/// \param __cf
+/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
+/// \param __x
+/// A 32-bit unsigned addend.
+/// \param __y
+/// A 32-bit unsigned addend.
+/// \param __p
+/// Pointer to memory for storing the sum.
+/// \returns The 8-bit unsigned carry-out value.
+__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf,
+ unsigned int __x,
+ unsigned int __y,
+ unsigned int *__p) {
+ return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p);
+}
+
+/// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry
+/// flag \a __cf, and subtracts the result from unsigned 32-bit integer
+/// \a __x. Stores the unsigned 32-bit difference in the memory at \a __p,
+/// and returns the 8-bit carry-out (carry or overflow flag).
+///
+/// \code{.operation}
+/// temp := (__cf == 0) ? 0 : 1
+/// Store32(__p, __x - (__y + temp))
+/// result := CF
+/// \endcode
+///
+/// \headerfile <immintrin.h>
+///
+/// This intrinsic corresponds to the \c SBB instruction.
+///
+/// \param __cf
+/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
+/// \param __x
+/// The 32-bit unsigned minuend.
+/// \param __y
+/// The 32-bit unsigned subtrahend.
+/// \param __p
+/// Pointer to memory for storing the difference.
+/// \returns The 8-bit unsigned carry-out value.
+__INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf,
+ unsigned int __x,
+ unsigned int __y,
+ unsigned int *__p) {
+ return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p);
+}
+
+#ifdef __x86_64__
+/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated
+/// by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory
+/// at \a __p, and returns the 8-bit carry-out (carry flag).
+///
+/// \code{.operation}
+/// temp := (__cf == 0) ? 0 : 1
+/// Store64(__p, __x + __y + temp)
+/// result := CF
+/// \endcode
+///
+/// \headerfile <immintrin.h>
+///
+/// This intrinsic corresponds to the \c ADC instruction.
+///
+/// \param __cf
+/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
+/// \param __x
+/// A 64-bit unsigned addend.
+/// \param __y
+/// A 64-bit unsigned addend.
+/// \param __p
+/// Pointer to memory for storing the sum.
+/// \returns The 8-bit unsigned carry-out value.
+__INLINE unsigned char __DEFAULT_FN_ATTRS
+_addcarry_u64(unsigned char __cf, unsigned long long __x,
+ unsigned long long __y, unsigned long long *__p) {
+ return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p);
+}
+
+/// Adds unsigned 64-bit integer \a __y to 0 or 1 as indicated by the carry
+/// flag \a __cf, and subtracts the result from unsigned 64-bit integer
+/// \a __x. Stores the unsigned 64-bit difference in the memory at \a __p,
+/// and returns the 8-bit carry-out (carry or overflow flag).
+///
+/// \code{.operation}
+/// temp := (__cf == 0) ? 0 : 1
+/// Store64(__p, __x - (__y + temp))
+/// result := CF
+/// \endcode
+///
+/// \headerfile <immintrin.h>
+///
+/// This intrinsic corresponds to the \c ADC instruction.
+///
+/// \param __cf
+/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
+/// \param __x
+/// The 64-bit unsigned minuend.
+/// \param __y
+/// The 64-bit unsigned subtrahend.
+/// \param __p
+/// Pointer to memory for storing the difference.
+/// \returns The 8-bit unsigned carry-out value.
+__INLINE unsigned char __DEFAULT_FN_ATTRS
+_subborrow_u64(unsigned char __cf, unsigned long long __x,
+ unsigned long long __y, unsigned long long *__p) {
+ return __builtin_ia32_subborrow_u64(__cf, __x, __y, __p);
+}
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#undef __INLINE
+#undef __DEFAULT_FN_ATTRS
+
+#endif /* __ADCINTRIN_H */
diff --git a/contrib/llvm-project/clang/lib/Headers/adxintrin.h b/contrib/llvm-project/clang/lib/Headers/adxintrin.h
index 20f6211e567b..bc6a4caf3533 100644
--- a/contrib/llvm-project/clang/lib/Headers/adxintrin.h
+++ b/contrib/llvm-project/clang/lib/Headers/adxintrin.h
@@ -15,7 +15,8 @@
#define __ADXINTRIN_H
/* Define the default attributes for the functions in this file. */
-#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
+#define __DEFAULT_FN_ATTRS \
+ __attribute__((__always_inline__, __nodebug__, __target__("adx")))
/* Use C++ inline semantics in C++, GNU inline for C mode. */
#if defined(__cplusplus)
@@ -53,10 +54,10 @@ extern "C" {
/// \param __p
/// Pointer to memory for storing the sum.
/// \returns The 8-bit unsigned carry-out value.
-__INLINE unsigned char
- __attribute__((__always_inline__, __nodebug__, __target__("adx")))
- _addcarryx_u32(unsigned char __cf, unsigned int __x, unsigned int __y,
- unsigned int *__p) {
+__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarryx_u32(unsigned char __cf,
+ unsigned int __x,
+ unsigned int __y,
+ unsigned int *__p) {
return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p);
}
@@ -84,137 +85,10 @@ __INLINE unsigned char
/// \param __p
/// Pointer to memory for storing the sum.
/// \returns The 8-bit unsigned carry-out value.
-__INLINE unsigned char
- __attribute__((__always_inline__, __nodebug__, __target__("adx")))
- _addcarryx_u64(unsigned char __cf, unsigned long long __x,
- unsigned long long __y, unsigned long long *__p) {
- return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p);
-}
-#endif
-
-/* Intrinsics that are also available if __ADX__ is undefined. */
-
-/// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated
-/// by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory
-/// at \a __p, and returns the 8-bit carry-out (carry flag).
-///
-/// \code{.operation}
-/// temp := (__cf == 0) ? 0 : 1
-/// Store32(__p, __x + __y + temp)
-/// result := CF
-/// \endcode
-///
-/// \headerfile <immintrin.h>
-///
-/// This intrinsic corresponds to the \c ADC instruction.
-///
-/// \param __cf
-/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
-/// \param __x
-/// A 32-bit unsigned addend.
-/// \param __y
-/// A 32-bit unsigned addend.
-/// \param __p
-/// Pointer to memory for storing the sum.
-/// \returns The 8-bit unsigned carry-out value.
-__INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf,
- unsigned int __x,
- unsigned int __y,
- unsigned int *__p) {
- return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p);
-}
-
-#ifdef __x86_64__
-/// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated
-/// by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory
-/// at \a __p, and returns the 8-bit carry-out (carry flag).
-///
-/// \code{.operation}
-/// temp := (__cf == 0) ? 0 : 1
-/// Store64(__p, __x + __y + temp)
-/// result := CF
-/// \endcode
-///
-/// \headerfile <immintrin.h>
-///
-/// This intrinsic corresponds to the \c ADC instruction.
-///
-/// \param __cf
-/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
-/// \param __x
-/// A 64-bit unsigned addend.
-/// \param __y
-/// A 64-bit unsigned addend.
-/// \param __p
-/// Pointer to memory for storing the sum.
-/// \returns The 8-bit unsigned carry-out value.
__INLINE unsigned char __DEFAULT_FN_ATTRS
-_addcarry_u64(unsigned char __cf, unsigned long long __x,
- unsigned long long __y, unsigned long long *__p) {
- return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p);
-}
-#endif
-
-/// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry
-/// flag \a __cf, and subtracts the result from unsigned 32-bit integer
-/// \a __x. Stores the unsigned 32-bit difference in the memory at \a __p,
-/// and returns the 8-bit carry-out (carry or overflow flag).
-///
-/// \code{.operation}
-/// temp := (__cf == 0) ? 0 : 1
-/// Store32(__p, __x - (__y + temp))
-/// result := CF
-/// \endcode
-///
-/// \headerfile <immintrin.h>
-///
-/// This intrinsic corresponds to the \c SBB instruction.
-///
-/// \param __cf
-/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
-/// \param __x
-/// The 32-bit unsigned minuend.
-/// \param __y
-/// The 32-bit unsigned subtrahend.
-/// \param __p
-/// Pointer to memory for storing the difference.
-/// \returns The 8-bit unsigned carry-out value.
-__INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf,
- unsigned int __x,
- unsigned int __y,
- unsigned int *__p) {
- return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p);
-}
-
-#ifdef __x86_64__
-/// Adds unsigned 64-bit integer \a __y to 0 or 1 as indicated by the carry
-/// flag \a __cf, and subtracts the result from unsigned 64-bit integer
-/// \a __x. Stores the unsigned 64-bit difference in the memory at \a __p,
-/// and returns the 8-bit carry-out (carry or overflow flag).
-///
-/// \code{.operation}
-/// temp := (__cf == 0) ? 0 : 1
-/// Store64(__p, __x - (__y + temp))
-/// result := CF
-/// \endcode
-///
-/// \headerfile <immintrin.h>
-///
-/// This intrinsic corresponds to the \c ADC instruction.
-///
-/// \param __cf
-/// The 8-bit unsigned carry flag; any non-zero value indicates carry.
-/// \param __x
-/// The 64-bit unsigned minuend.
-/// \param __y
-/// The 64-bit unsigned subtrahend.
-/// \param __p
-/// Pointer to memory for storing the difference.
-/// \returns The 8-bit unsigned carry-out value.
-__INLINE unsigned char __DEFAULT_FN_ATTRS
-_subborrow_u64(unsigned char __cf, unsigned long long __x,
+_addcarryx_u64(unsigned char __cf, unsigned long long __x,
unsigned long long __y, unsigned long long *__p) {
- return __builtin_ia32_subborrow_u64(__cf, __x, __y, __p);
+ return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p);
}
#endif
@@ -222,6 +96,7 @@ _subborrow_u64(unsigned char __cf, unsigned long long __x,
}
#endif
+#undef __INLINE
#undef __DEFAULT_FN_ATTRS
#endif /* __ADXINTRIN_H */
diff --git a/contrib/llvm-project/clang/lib/Headers/immintrin.h b/contrib/llvm-project/clang/lib/Headers/immintrin.h
index 9bfe2fcdabdb..0149a1cdea63 100644
--- a/contrib/llvm-project/clang/lib/Headers/immintrin.h
+++ b/contrib/llvm-project/clang/lib/Headers/immintrin.h
@@ -580,9 +580,13 @@ _storebe_i64(void * __P, long long __D) {
#include <cetintrin.h>
#endif
-/* Some intrinsics inside adxintrin.h are available only on processors with ADX,
- * whereas others are also available at all times. */
+/* Intrinsics inside adcintrin.h are available at all times. */
+#include <adcintrin.h>
+
+#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
+ defined(__ADX__)
#include <adxintrin.h>
+#endif
#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
defined(__RDSEED__)
diff --git a/contrib/llvm-project/clang/lib/Headers/riscv_bitmanip.h b/contrib/llvm-project/clang/lib/Headers/riscv_bitmanip.h
index 1a81cc8618c9..2bc7ee022a96 100644
--- a/contrib/llvm-project/clang/lib/Headers/riscv_bitmanip.h
+++ b/contrib/llvm-project/clang/lib/Headers/riscv_bitmanip.h
@@ -34,7 +34,7 @@ __riscv_ctz_32(uint32_t __x) {
static __inline__ unsigned __attribute__((__always_inline__, __nodebug__))
__riscv_cpop_32(uint32_t __x) {
- return __builtin_riscv_cpop_32(__x);
+ return __builtin_popcount(__x);
}
#if __riscv_xlen == 64
@@ -55,7 +55,7 @@ __riscv_ctz_64(uint64_t __x) {
static __inline__ unsigned __attribute__((__always_inline__, __nodebug__))
__riscv_cpop_64(uint64_t __x) {
- return __builtin_riscv_cpop_64(__x);
+ return __builtin_popcountll(__x);
}
#endif
#endif // defined(__riscv_zbb)
@@ -120,7 +120,23 @@ __riscv_zip_32(uint32_t __x) {
#endif
#endif // defined(__riscv_zbkb)
-#if defined(__riscv_zbkc)
+#if defined(__riscv_zbc)
+#if __riscv_xlen == 32
+static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
+__riscv_clmulr_32(uint32_t __x, uint32_t __y) {
+ return __builtin_riscv_clmulr_32(__x, __y);
+}
+#endif
+
+#if __riscv_xlen == 64
+static __inline__ uint64_t __attribute__((__always_inline__, __nodebug__))
+__riscv_clmulr_64(uint64_t __x, uint64_t __y) {
+ return __builtin_riscv_clmulr_64(__x, __y);
+}
+#endif
+#endif // defined(__riscv_zbc)
+
+#if defined(__riscv_zbkc) || defined(__riscv_zbc)
static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
__riscv_clmul_32(uint32_t __x, uint32_t __y) {
return __builtin_riscv_clmul_32(__x, __y);
@@ -144,7 +160,7 @@ __riscv_clmulh_64(uint64_t __x, uint64_t __y) {
return __builtin_riscv_clmulh_64(__x, __y);
}
#endif
-#endif // defined(__riscv_zbkc)
+#endif // defined(__riscv_zbkc) || defined(__riscv_zbc)
#if defined(__riscv_zbkx)
#if __riscv_xlen == 32
diff --git a/contrib/llvm-project/clang/lib/Interpreter/CodeCompletion.cpp b/contrib/llvm-project/clang/lib/Interpreter/CodeCompletion.cpp
index c40e11b9d1ec..25183ae9eeb9 100644
--- a/contrib/llvm-project/clang/lib/Interpreter/CodeCompletion.cpp
+++ b/contrib/llvm-project/clang/lib/Interpreter/CodeCompletion.cpp
@@ -12,6 +12,7 @@
#include "clang/Interpreter/CodeCompletion.h"
#include "clang/AST/ASTImporter.h"
+#include "clang/AST/DeclLookups.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/Basic/IdentifierTable.h"
@@ -23,6 +24,8 @@
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Sema/CodeCompleteOptions.h"
#include "clang/Sema/Sema.h"
+#include "llvm/Support/Debug.h"
+#define DEBUG_TYPE "REPLCC"
namespace clang {
@@ -39,11 +42,15 @@ clang::CodeCompleteOptions getClangCompleteOpts() {
class ReplCompletionConsumer : public CodeCompleteConsumer {
public:
- ReplCompletionConsumer(std::vector<std::string> &Results)
+ ReplCompletionConsumer(std::vector<std::string> &Results,
+ ReplCodeCompleter &CC)
: CodeCompleteConsumer(getClangCompleteOpts()),
CCAllocator(std::make_shared<GlobalCodeCompletionAllocator>()),
- CCTUInfo(CCAllocator), Results(Results){};
+ CCTUInfo(CCAllocator), Results(Results), CC(CC) {}
+ // The entry of handling code completion. When the function is called, we
+ // create a `Context`-based handler (see classes defined below) to handle each
+ // completion result.
void ProcessCodeCompleteResults(class Sema &S, CodeCompletionContext Context,
CodeCompletionResult *InResults,
unsigned NumResults) final;
@@ -56,26 +63,147 @@ private:
std::shared_ptr<GlobalCodeCompletionAllocator> CCAllocator;
CodeCompletionTUInfo CCTUInfo;
std::vector<std::string> &Results;
+ ReplCodeCompleter &CC;
+};
+
+/// The class CompletionContextHandler contains four interfaces, each of
+/// which handles one type of completion result.
+/// Its derived classes are used to create concrete handlers based on
+/// \c CodeCompletionContext.
+class CompletionContextHandler {
+protected:
+ CodeCompletionContext CCC;
+ std::vector<std::string> &Results;
+
+private:
+ Sema &S;
+
+public:
+ CompletionContextHandler(Sema &S, CodeCompletionContext CCC,
+ std::vector<std::string> &Results)
+ : CCC(CCC), Results(Results), S(S) {}
+
+ virtual ~CompletionContextHandler() = default;
+ /// Converts a Declaration completion result to a completion string, and then
+ /// stores it in Results.
+ virtual void handleDeclaration(const CodeCompletionResult &Result) {
+ auto PreferredType = CCC.getPreferredType();
+ if (PreferredType.isNull()) {
+ Results.push_back(Result.Declaration->getName().str());
+ return;
+ }
+
+ if (auto *VD = dyn_cast<VarDecl>(Result.Declaration)) {
+ auto ArgumentType = VD->getType();
+ if (PreferredType->isReferenceType()) {
+ QualType RT = PreferredType->castAs<ReferenceType>()->getPointeeType();
+ Sema::ReferenceConversions RefConv;
+ Sema::ReferenceCompareResult RefRelationship =
+ S.CompareReferenceRelationship(SourceLocation(), RT, ArgumentType,
+ &RefConv);
+ switch (RefRelationship) {
+ case Sema::Ref_Compatible:
+ case Sema::Ref_Related:
+ Results.push_back(VD->getName().str());
+ break;
+ case Sema::Ref_Incompatible:
+ break;
+ }
+ } else if (S.Context.hasSameType(ArgumentType, PreferredType)) {
+ Results.push_back(VD->getName().str());
+ }
+ }
+ }
+
+ /// Converts a Keyword completion result to a completion string, and then
+ /// stores it in Results.
+ virtual void handleKeyword(const CodeCompletionResult &Result) {
+ auto Prefix = S.getPreprocessor().getCodeCompletionFilter();
+ // Add keyword to the completion results only if we are in a type-aware
+ // situation.
+ if (!CCC.getBaseType().isNull() || !CCC.getPreferredType().isNull())
+ return;
+ if (StringRef(Result.Keyword).starts_with(Prefix))
+ Results.push_back(Result.Keyword);
+ }
+
+ /// Converts a Pattern completion result to a completion string, and then
+ /// stores it in Results.
+ virtual void handlePattern(const CodeCompletionResult &Result) {}
+
+ /// Converts a Macro completion result to a completion string, and then stores
+ /// it in Results.
+ virtual void handleMacro(const CodeCompletionResult &Result) {}
+};
+
+class DotMemberAccessHandler : public CompletionContextHandler {
+public:
+ DotMemberAccessHandler(Sema &S, CodeCompletionContext CCC,
+ std::vector<std::string> &Results)
+ : CompletionContextHandler(S, CCC, Results) {}
+ void handleDeclaration(const CodeCompletionResult &Result) override {
+ auto *ID = Result.Declaration->getIdentifier();
+ if (!ID)
+ return;
+ if (!isa<CXXMethodDecl>(Result.Declaration))
+ return;
+ const auto *Fun = cast<CXXMethodDecl>(Result.Declaration);
+ if (Fun->getParent()->getCanonicalDecl() ==
+ CCC.getBaseType()->getAsCXXRecordDecl()->getCanonicalDecl()) {
+ LLVM_DEBUG(llvm::dbgs() << "[In HandleCodeCompleteDOT] Name : "
+ << ID->getName() << "\n");
+ Results.push_back(ID->getName().str());
+ }
+ }
+
+ void handleKeyword(const CodeCompletionResult &Result) override {}
};
void ReplCompletionConsumer::ProcessCodeCompleteResults(
class Sema &S, CodeCompletionContext Context,
CodeCompletionResult *InResults, unsigned NumResults) {
- for (unsigned I = 0; I < NumResults; ++I) {
+
+ auto Prefix = S.getPreprocessor().getCodeCompletionFilter();
+ CC.Prefix = Prefix;
+
+ std::unique_ptr<CompletionContextHandler> CCH;
+
+ // initialize fine-grained code completion handler based on the code
+ // completion context.
+ switch (Context.getKind()) {
+ case CodeCompletionContext::CCC_DotMemberAccess:
+ CCH.reset(new DotMemberAccessHandler(S, Context, this->Results));
+ break;
+ default:
+ CCH.reset(new CompletionContextHandler(S, Context, this->Results));
+ };
+
+ for (unsigned I = 0; I < NumResults; I++) {
auto &Result = InResults[I];
switch (Result.Kind) {
case CodeCompletionResult::RK_Declaration:
- if (auto *ID = Result.Declaration->getIdentifier()) {
- Results.push_back(ID->getName().str());
+ if (Result.Hidden) {
+ break;
+ }
+ if (!Result.Declaration->getDeclName().isIdentifier() ||
+ !Result.Declaration->getName().starts_with(Prefix)) {
+ break;
}
+ CCH->handleDeclaration(Result);
break;
case CodeCompletionResult::RK_Keyword:
- Results.push_back(Result.Keyword);
+ CCH->handleKeyword(Result);
break;
- default:
+ case CodeCompletionResult::RK_Macro:
+ CCH->handleMacro(Result);
+ break;
+ case CodeCompletionResult::RK_Pattern:
+ CCH->handlePattern(Result);
break;
}
}
+
+ std::sort(Results.begin(), Results.end());
}
class IncrementalSyntaxOnlyAction : public SyntaxOnlyAction {
@@ -118,6 +246,16 @@ void IncrementalSyntaxOnlyAction::ExecuteAction() {
CI.getASTContext().getTranslationUnitDecl()->setHasExternalVisibleStorage(
true);
+ // Load all external decls into current context. Under the hood, it calls
+ // ExternalSource::completeVisibleDeclsMap, which make all decls on the redecl
+ // chain visible.
+ //
+ // This is crucial to code completion on dot members, since a bound variable
+ // before "." would be otherwise treated out-of-scope.
+ //
+ // clang-repl> Foo f1;
+ // clang-repl> f1.<tab>
+ CI.getASTContext().getTranslationUnitDecl()->lookups();
SyntaxOnlyAction::ExecuteAction();
}
@@ -134,6 +272,7 @@ ExternalSource::ExternalSource(ASTContext &ChildASTCtxt, FileManager &ChildFM,
bool ExternalSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
+
IdentifierTable &ParentIdTable = ParentASTCtxt.Idents;
auto ParentDeclName =
@@ -159,29 +298,67 @@ void ExternalSource::completeVisibleDeclsMap(
for (auto *DeclCtxt = ParentTUDeclCtxt; DeclCtxt != nullptr;
DeclCtxt = DeclCtxt->getPreviousDecl()) {
for (auto &IDeclContext : DeclCtxt->decls()) {
- if (NamedDecl *Decl = llvm::dyn_cast<NamedDecl>(IDeclContext)) {
- if (auto DeclOrErr = Importer->Import(Decl)) {
- if (NamedDecl *importedNamedDecl =
- llvm::dyn_cast<NamedDecl>(*DeclOrErr)) {
- SetExternalVisibleDeclsForName(ChildDeclContext,
- importedNamedDecl->getDeclName(),
- importedNamedDecl);
- }
-
- } else {
- llvm::consumeError(DeclOrErr.takeError());
- }
+ if (!llvm::isa<NamedDecl>(IDeclContext))
+ continue;
+
+ NamedDecl *Decl = llvm::cast<NamedDecl>(IDeclContext);
+
+ auto DeclOrErr = Importer->Import(Decl);
+ if (!DeclOrErr) {
+ // if an error happens, it usually means the decl has already been
+ // imported or the decl is a result of a failed import. But in our
+ // case, every import is fresh each time code completion is
+ // triggered. So Import usually doesn't fail. If it does, it just means
+ // the related decl can't be used in code completion and we can safely
+ // drop it.
+ llvm::consumeError(DeclOrErr.takeError());
+ continue;
}
+
+ if (!llvm::isa<NamedDecl>(*DeclOrErr))
+ continue;
+
+ NamedDecl *importedNamedDecl = llvm::cast<NamedDecl>(*DeclOrErr);
+
+ SetExternalVisibleDeclsForName(ChildDeclContext,
+ importedNamedDecl->getDeclName(),
+ importedNamedDecl);
+
+ if (!llvm::isa<CXXRecordDecl>(importedNamedDecl))
+ continue;
+
+ auto *Record = llvm::cast<CXXRecordDecl>(importedNamedDecl);
+
+ if (auto Err = Importer->ImportDefinition(Decl)) {
+ // the same as above
+ consumeError(std::move(Err));
+ continue;
+ }
+
+ Record->setHasLoadedFieldsFromExternalStorage(true);
+ LLVM_DEBUG(llvm::dbgs()
+ << "\nCXXRecrod : " << Record->getName() << " size(methods): "
+ << std::distance(Record->method_begin(), Record->method_end())
+ << " has def?: " << Record->hasDefinition()
+ << " # (methods): "
+ << std::distance(Record->getDefinition()->method_begin(),
+ Record->getDefinition()->method_end())
+ << "\n");
+ for (auto *Meth : Record->methods())
+ SetExternalVisibleDeclsForName(ChildDeclContext, Meth->getDeclName(),
+ Meth);
}
ChildDeclContext->setHasExternalLexicalStorage(false);
}
}
-void codeComplete(CompilerInstance *InterpCI, llvm::StringRef Content,
- unsigned Line, unsigned Col, const CompilerInstance *ParentCI,
- std::vector<std::string> &CCResults) {
+void ReplCodeCompleter::codeComplete(CompilerInstance *InterpCI,
+ llvm::StringRef Content, unsigned Line,
+ unsigned Col,
+ const CompilerInstance *ParentCI,
+ std::vector<std::string> &CCResults) {
auto DiagOpts = DiagnosticOptions();
- auto consumer = ReplCompletionConsumer(CCResults);
+ auto consumer = ReplCompletionConsumer(CCResults, *this);
auto diag = InterpCI->getDiagnosticsPtr();
std::unique_ptr<ASTUnit> AU(ASTUnit::LoadFromCompilerInvocationAction(
diff --git a/contrib/llvm-project/clang/lib/Interpreter/Interpreter.cpp b/contrib/llvm-project/clang/lib/Interpreter/Interpreter.cpp
index 7968c62cbd3e..c9fcef5b5b5a 100644
--- a/contrib/llvm-project/clang/lib/Interpreter/Interpreter.cpp
+++ b/contrib/llvm-project/clang/lib/Interpreter/Interpreter.cpp
@@ -319,6 +319,10 @@ const CompilerInstance *Interpreter::getCompilerInstance() const {
return IncrParser->getCI();
}
+CompilerInstance *Interpreter::getCompilerInstance() {
+ return IncrParser->getCI();
+}
+
llvm::Expected<llvm::orc::LLJIT &> Interpreter::getExecutionEngine() {
if (!IncrExecutor) {
if (auto Err = CreateExecutor())
diff --git a/contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp b/contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp
index 112bc8dc572c..9f82a6d073e3 100644
--- a/contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp
+++ b/contrib/llvm-project/clang/lib/Lex/PPDirectives.cpp
@@ -1858,11 +1858,18 @@ static void diagnoseAutoModuleImport(
// path to the file, build a properly-cased replacement in the vector,
// and return true if the replacement should be suggested.
static bool trySimplifyPath(SmallVectorImpl<StringRef> &Components,
- StringRef RealPathName) {
+ StringRef RealPathName,
+ llvm::sys::path::Style Separator) {
auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);
auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);
int Cnt = 0;
bool SuggestReplacement = false;
+
+ auto IsSep = [Separator](StringRef Component) {
+ return Component.size() == 1 &&
+ llvm::sys::path::is_separator(Component[0], Separator);
+ };
+
// Below is a best-effort to handle ".." in paths. It is admittedly
// not 100% correct in the presence of symlinks.
for (auto &Component : llvm::reverse(Components)) {
@@ -1872,10 +1879,11 @@ static bool trySimplifyPath(SmallVectorImpl<StringRef> &Components,
} else if (Cnt) {
--Cnt;
} else if (RealPathComponentIter != RealPathComponentEnd) {
- if (Component != *RealPathComponentIter) {
- // If these path components differ by more than just case, then we
- // may be looking at symlinked paths. Bail on this diagnostic to avoid
- // noisy false positives.
+ if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&
+ Component != *RealPathComponentIter) {
+ // If these non-separator path components differ by more than just case,
+ // then we may be looking at symlinked paths. Bail on this diagnostic to
+ // avoid noisy false positives.
SuggestReplacement =
RealPathComponentIter->equals_insensitive(Component);
if (!SuggestReplacement)
@@ -2451,7 +2459,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
}
#endif
- if (trySimplifyPath(Components, RealPathName)) {
+ if (trySimplifyPath(Components, RealPathName, BackslashStyle)) {
SmallString<128> Path;
Path.reserve(Name.size()+2);
Path.push_back(isAngled ? '<' : '"');
@@ -2474,7 +2482,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
// got copied when the C: was processed and we want to skip that entry.
if (!(Component.size() == 1 && IsSep(Component[0])))
Path.append(Component);
- else if (!Path.empty())
+ else if (Path.size() != 1)
continue;
// Append the separator(s) the user used, or the close quote
diff --git a/contrib/llvm-project/clang/lib/Parse/ParseOpenACC.cpp b/contrib/llvm-project/clang/lib/Parse/ParseOpenACC.cpp
index f7f096762e91..67325f0a286a 100644
--- a/contrib/llvm-project/clang/lib/Parse/ParseOpenACC.cpp
+++ b/contrib/llvm-project/clang/lib/Parse/ParseOpenACC.cpp
@@ -69,6 +69,29 @@ OpenACCDirectiveKindEx getOpenACCDirectiveKind(Token Tok) {
.Default(OpenACCDirectiveKindEx::Invalid);
}
+// Translate single-token string representations to the OpenCC Clause Kind.
+OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
+ // auto is a keyword in some language modes, so make sure we parse it
+ // correctly.
+ if (Tok.is(tok::kw_auto))
+ return OpenACCClauseKind::Auto;
+
+ if (!Tok.is(tok::identifier))
+ return OpenACCClauseKind::Invalid;
+
+ return llvm::StringSwitch<OpenACCClauseKind>(
+ Tok.getIdentifierInfo()->getName())
+ .Case("auto", OpenACCClauseKind::Auto)
+ .Case("finalize", OpenACCClauseKind::Finalize)
+ .Case("if_present", OpenACCClauseKind::IfPresent)
+ .Case("independent", OpenACCClauseKind::Independent)
+ .Case("nohost", OpenACCClauseKind::NoHost)
+ .Case("seq", OpenACCClauseKind::Seq)
+ .Case("vector", OpenACCClauseKind::Vector)
+ .Case("worker", OpenACCClauseKind::Worker)
+ .Default(OpenACCClauseKind::Invalid);
+}
+
// Since 'atomic' is effectively a compound directive, this will decode the
// second part of the directive.
OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) {
@@ -164,6 +187,10 @@ ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok,
return OpenACCDirectiveKind::Invalid;
}
+ // Consume the second name anyway, this way we can continue on without making
+ // this oddly look like a clause.
+ P.ConsumeAnyToken();
+
if (!isOpenACCDirectiveKind(OpenACCDirectiveKind::Data, SecondTok)) {
if (!SecondTok.is(tok::identifier))
P.Diag(SecondTok, diag::err_expected) << tok::identifier;
@@ -174,8 +201,6 @@ ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok,
return OpenACCDirectiveKind::Invalid;
}
- P.ConsumeToken();
-
return ExtDirKind == OpenACCDirectiveKindEx::Enter
? OpenACCDirectiveKind::EnterData
: OpenACCDirectiveKind::ExitData;
@@ -208,6 +233,10 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
// introspect on the spelling before then.
if (FirstTok.isNot(tok::identifier)) {
P.Diag(FirstTok, diag::err_acc_missing_directive);
+
+ if (P.getCurToken().isNot(tok::annot_pragma_openacc_end))
+ P.ConsumeAnyToken();
+
return OpenACCDirectiveKind::Invalid;
}
@@ -262,12 +291,57 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
return DirKind;
}
+// The OpenACC Clause List is a comma or space-delimited list of clauses (see
+// the comment on ParseOpenACCClauseList). The concept of a 'clause' doesn't
+// really have its owner grammar and each individual one has its own definition.
+// However, they all are named with a single-identifier (or auto!) token,
+// followed in some cases by either braces or parens.
+bool ParseOpenACCClause(Parser &P) {
+ if (!P.getCurToken().isOneOf(tok::identifier, tok::kw_auto))
+ return P.Diag(P.getCurToken(), diag::err_expected) << tok::identifier;
+
+ OpenACCClauseKind Kind = getOpenACCClauseKind(P.getCurToken());
+
+ if (Kind == OpenACCClauseKind::Invalid)
+ return P.Diag(P.getCurToken(), diag::err_acc_invalid_clause)
+ << P.getCurToken().getIdentifierInfo();
+
+ // Consume the clause name.
+ P.ConsumeToken();
+
+ // FIXME: For future clauses, we need to handle parens/etc below.
+ return false;
+}
+
+// Skip until we see the end of pragma token, but don't consume it. This is us
+// just giving up on the rest of the pragma so we can continue executing. We
+// have to do this because 'SkipUntil' considers paren balancing, which isn't
+// what we want.
+void SkipUntilEndOfDirective(Parser &P) {
+ while (P.getCurToken().isNot(tok::annot_pragma_openacc_end))
+ P.ConsumeAnyToken();
+}
+
+// OpenACC 3.3, section 1.7:
+// To simplify the specification and convey appropriate constraint information,
+// a pqr-list is a comma-separated list of pdr items. The one exception is a
+// clause-list, which is a list of one or more clauses optionally separated by
+// commas.
void ParseOpenACCClauseList(Parser &P) {
- // FIXME: In the future, we'll start parsing the clauses here, but for now we
- // haven't implemented that, so just emit the unimplemented diagnostic and
- // fail reasonably.
- if (P.getCurToken().isNot(tok::annot_pragma_openacc_end))
- P.Diag(P.getCurToken(), diag::warn_pragma_acc_unimplemented_clause_parsing);
+ bool FirstClause = true;
+ while (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) {
+ // Comma is optional in a clause-list.
+ if (!FirstClause && P.getCurToken().is(tok::comma))
+ P.ConsumeToken();
+ FirstClause = false;
+
+ // Recovering from a bad clause is really difficult, so we just give up on
+ // error.
+ if (ParseOpenACCClause(P)) {
+ SkipUntilEndOfDirective(P);
+ return;
+ }
+ }
}
} // namespace
@@ -499,7 +573,9 @@ void Parser::ParseOpenACCDirective() {
ParseOpenACCClauseList(*this);
Diag(getCurToken(), diag::warn_pragma_acc_unimplemented);
- SkipUntil(tok::annot_pragma_openacc_end);
+ assert(Tok.is(tok::annot_pragma_openacc_end) &&
+ "Didn't parse all OpenACC Clauses");
+ ConsumeAnnotationToken();
}
// Parse OpenACC directive on a declaration.
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp
index d4a40b850cea..2a69325f0295 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp
@@ -3156,7 +3156,6 @@ static void checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall,
const FunctionDecl *FD,
ArmStreamingType BuiltinType) {
ArmStreamingType FnType = getArmStreamingFnType(FD);
-
if (FnType == ArmStreaming && BuiltinType == ArmNonStreaming) {
S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin)
<< TheCall->getSourceRange() << "streaming";
@@ -3168,9 +3167,77 @@ static void checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall,
<< TheCall->getSourceRange() << "streaming compatible";
return;
}
+
+ if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+ S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin)
+ << TheCall->getSourceRange() << "non-streaming";
+ }
+}
+
+static bool hasSMEZAState(const FunctionDecl *FD) {
+ if (FD->hasAttr<ArmNewZAAttr>())
+ return true;
+ if (const auto *T = FD->getType()->getAs<FunctionProtoType>())
+ if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateZASharedMask)
+ return true;
+ return false;
+}
+
+static bool hasSMEZAState(unsigned BuiltinID) {
+ switch (BuiltinID) {
+ default:
+ return false;
+#define GET_SME_BUILTIN_HAS_ZA_STATE
+#include "clang/Basic/arm_sme_builtins_za_state.inc"
+#undef GET_SME_BUILTIN_HAS_ZA_STATE
+ }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+ if (const FunctionDecl *FD = getCurFunctionDecl()) {
+ std::optional<ArmStreamingType> BuiltinType;
+
+ switch (BuiltinID) {
+#define GET_SME_STREAMING_ATTRS
+#include "clang/Basic/arm_sme_streaming_attrs.inc"
+#undef GET_SME_STREAMING_ATTRS
+ }
+
+ if (BuiltinType)
+ checkArmStreamingBuiltin(*this, TheCall, FD, *BuiltinType);
+
+ if (hasSMEZAState(BuiltinID) && !hasSMEZAState(FD))
+ Diag(TheCall->getBeginLoc(),
+ diag::warn_attribute_arm_za_builtin_no_za_state)
+ << TheCall->getSourceRange();
+ }
+
+ // Range check SME intrinsics that take immediate values.
+ SmallVector<std::tuple<int, int, int>, 3> ImmChecks;
+
+ switch (BuiltinID) {
+ default:
+ return false;
+#define GET_SME_IMMEDIATE_CHECK
+#include "clang/Basic/arm_sme_sema_rangechecks.inc"
+#undef GET_SME_IMMEDIATE_CHECK
+ }
+
+ return ParseSVEImmChecks(TheCall, ImmChecks);
}
bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+ if (const FunctionDecl *FD = getCurFunctionDecl()) {
+ std::optional<ArmStreamingType> BuiltinType;
+
+ switch (BuiltinID) {
+#define GET_SVE_STREAMING_ATTRS
+#include "clang/Basic/arm_sve_streaming_attrs.inc"
+#undef GET_SVE_STREAMING_ATTRS
+ }
+ if (BuiltinType)
+ checkArmStreamingBuiltin(*this, TheCall, FD, *BuiltinType);
+ }
// Range check SVE intrinsics that take immediate values.
SmallVector<std::tuple<int, int, int>, 3> ImmChecks;
@@ -3180,9 +3247,6 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
#define GET_SVE_IMMEDIATE_CHECK
#include "clang/Basic/arm_sve_sema_rangechecks.inc"
#undef GET_SVE_IMMEDIATE_CHECK
-#define GET_SME_IMMEDIATE_CHECK
-#include "clang/Basic/arm_sme_sema_rangechecks.inc"
-#undef GET_SME_IMMEDIATE_CHECK
}
return ParseSVEImmChecks(TheCall, ImmChecks);
@@ -3569,6 +3633,9 @@ bool Sema::CheckAArch64BuiltinFunctionCall(const TargetInfo &TI,
if (CheckSVEBuiltinFunctionCall(BuiltinID, TheCall))
return true;
+ if (CheckSMEBuiltinFunctionCall(BuiltinID, TheCall))
+ return true;
+
// For intrinsics which take an immediate value as part of the instruction,
// range check them here.
unsigned i = 0, l = 0, u = 0;
@@ -5322,7 +5389,7 @@ bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI,
QualType Op2Type = TheCall->getArg(1)->getType();
QualType Op3Type = TheCall->getArg(2)->getType();
uint64_t ElemSize = Op1Type->isRVVType(32, false) ? 32 : 64;
- if (ElemSize == 64 && !TI.hasFeature("experimental-zvknhb"))
+ if (ElemSize == 64 && !TI.hasFeature("zvknhb"))
return Diag(TheCall->getBeginLoc(),
diag::err_riscv_type_requires_extension)
<< Op1Type << "zvknhb";
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp
index be6a136ef37b..ffbe317d5599 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp
@@ -2005,12 +2005,12 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts,
if (D->isInvalidDecl())
return false;
- if (auto *DD = dyn_cast<DecompositionDecl>(D)) {
+ if (const auto *DD = dyn_cast<DecompositionDecl>(D)) {
// For a decomposition declaration, warn if none of the bindings are
// referenced, instead of if the variable itself is referenced (which
// it is, by the bindings' expressions).
bool IsAllPlaceholders = true;
- for (auto *BD : DD->bindings()) {
+ for (const auto *BD : DD->bindings()) {
if (BD->isReferenced())
return false;
IsAllPlaceholders = IsAllPlaceholders && BD->isPlaceholderVar(LangOpts);
@@ -2054,7 +2054,7 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts,
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
const Expr *Init = VD->getInit();
- if (const auto *Cleanups = dyn_cast_or_null<ExprWithCleanups>(Init))
+ if (const auto *Cleanups = dyn_cast_if_present<ExprWithCleanups>(Init))
Init = Cleanups->getSubExpr();
const auto *Ty = VD->getType().getTypePtr();
@@ -2068,11 +2068,10 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts,
// Warn for reference variables whose initializtion performs lifetime
// extension.
- if (const auto *MTE = dyn_cast_or_null<MaterializeTemporaryExpr>(Init)) {
- if (MTE->getExtendingDecl()) {
- Ty = VD->getType().getNonReferenceType().getTypePtr();
- Init = MTE->getSubExpr()->IgnoreImplicitAsWritten();
- }
+ if (const auto *MTE = dyn_cast_if_present<MaterializeTemporaryExpr>(Init);
+ MTE && MTE->getExtendingDecl()) {
+ Ty = VD->getType().getNonReferenceType().getTypePtr();
+ Init = MTE->getSubExpr()->IgnoreImplicitAsWritten();
}
// If we failed to complete the type for some reason, or if the type is
@@ -2089,15 +2088,14 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts,
if (Tag->hasAttr<UnusedAttr>())
return false;
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) {
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(Tag)) {
if (!RD->hasTrivialDestructor() && !RD->hasAttr<WarnUnusedAttr>())
return false;
if (Init) {
- const CXXConstructExpr *Construct =
- dyn_cast<CXXConstructExpr>(Init);
+ const auto *Construct = dyn_cast<CXXConstructExpr>(Init);
if (Construct && !Construct->isElidable()) {
- CXXConstructorDecl *CD = Construct->getConstructor();
+ const CXXConstructorDecl *CD = Construct->getConstructor();
if (!CD->isTrivial() && !RD->hasAttr<WarnUnusedAttr>() &&
(VD->getInit()->isValueDependent() || !VD->evaluateValue()))
return false;
@@ -2211,10 +2209,9 @@ void Sema::DiagnoseUnusedButSetDecl(const VarDecl *VD,
return;
// In C++, don't warn for record types that don't have WarnUnusedAttr, to
// mimic gcc's behavior.
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) {
- if (!RD->hasAttr<WarnUnusedAttr>())
- return;
- }
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(Tag);
+ RD && !RD->hasAttr<WarnUnusedAttr>())
+ return;
}
// Don't warn about __block Objective-C pointer variables, as they might
@@ -12957,7 +12954,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
// FIXME: Initialization should not be taking a mutable list of inits.
SmallVector<Expr*, 8> InitsCopy(DeduceInits.begin(), DeduceInits.end());
return DeduceTemplateSpecializationFromInitializer(TSI, Entity, Kind,
- InitsCopy, PL);
+ InitsCopy);
}
if (DirectInit) {
@@ -19518,20 +19515,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
CDecl->setIvarRBraceLoc(RBrac);
}
}
-
- // Check the "counted_by" attribute to ensure that the count field exists in
- // the struct. Make sure we're performing this check on the outer-most
- // record. This is a C-only feature.
- if (!getLangOpts().CPlusPlus && Record &&
- !isa<RecordDecl>(Record->getParent())) {
- auto Pred = [](const Decl *D) {
- if (const auto *FD = dyn_cast_if_present<FieldDecl>(D))
- return FD->hasAttr<CountedByAttr>();
- return false;
- };
- if (const FieldDecl *FD = Record->findFieldIf(Pred))
- CheckCountedByAttr(S, FD);
- }
}
/// Determine whether the given integral value is representable within
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp
index 5b29b05dee54..af8b90ecfed9 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp
@@ -8445,92 +8445,6 @@ static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL));
}
-static void handleCountedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!AL.isArgIdent(0)) {
- S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
- << AL << AANT_ArgumentIdentifier;
- return;
- }
-
- IdentifierLoc *IL = AL.getArgAsIdent(0);
- CountedByAttr *CBA =
- ::new (S.Context) CountedByAttr(S.Context, AL, IL->Ident);
- CBA->setCountedByFieldLoc(IL->Loc);
- D->addAttr(CBA);
-}
-
-bool Sema::CheckCountedByAttr(Scope *S, const FieldDecl *FD) {
- const auto *CBA = FD->getAttr<CountedByAttr>();
- const IdentifierInfo *FieldName = CBA->getCountedByField();
- DeclarationNameInfo NameInfo(FieldName,
- CBA->getCountedByFieldLoc().getBegin());
-
- LookupResult MemResult(*this, NameInfo, Sema::LookupMemberName);
- LookupName(MemResult, S);
-
- if (MemResult.empty()) {
- // The "counted_by" field needs to exist within the struct.
- LookupResult OrdResult(*this, NameInfo, Sema::LookupOrdinaryName);
- LookupName(OrdResult, S);
-
- if (!OrdResult.empty()) {
- SourceRange SR = FD->getLocation();
- Diag(SR.getBegin(), diag::err_counted_by_must_be_in_structure)
- << FieldName << SR;
-
- if (auto *ND = OrdResult.getAsSingle<NamedDecl>()) {
- SR = ND->getLocation();
- Diag(SR.getBegin(), diag::note_flexible_array_counted_by_attr_field)
- << ND << SR;
- }
- return true;
- }
-
- CXXScopeSpec SS;
- DeclFilterCCC<FieldDecl> Filter(FieldName);
- return DiagnoseEmptyLookup(S, SS, MemResult, Filter, nullptr, std::nullopt,
- const_cast<DeclContext *>(FD->getDeclContext()));
- }
-
- LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
- LangOptions::StrictFlexArraysLevelKind::IncompleteOnly;
-
- if (!Decl::isFlexibleArrayMemberLike(Context, FD, FD->getType(),
- StrictFlexArraysLevel, true)) {
- // The "counted_by" attribute must be on a flexible array member.
- SourceRange SR = FD->getLocation();
- Diag(SR.getBegin(), diag::err_counted_by_attr_not_on_flexible_array_member)
- << SR;
- return true;
- }
-
- if (const FieldDecl *Field = MemResult.getAsSingle<FieldDecl>()) {
- if (Field->hasAttr<CountedByAttr>()) {
- // The "counted_by" field can't point to the flexible array member.
- SourceRange SR = CBA->getCountedByFieldLoc();
- Diag(SR.getBegin(), diag::err_counted_by_attr_refers_to_flexible_array)
- << CBA->getCountedByField() << SR;
- return true;
- }
-
- if (!Field->getType()->isIntegerType() ||
- Field->getType()->isBooleanType()) {
- // The "counted_by" field must have an integer type.
- SourceRange SR = CBA->getCountedByFieldLoc();
- Diag(SR.getBegin(),
- diag::err_flexible_array_counted_by_attr_field_not_integer)
- << CBA->getCountedByField() << SR;
-
- SR = Field->getLocation();
- Diag(SR.getBegin(), diag::note_flexible_array_counted_by_attr_field)
- << Field << SR;
- return true;
- }
- }
-
- return false;
-}
-
static void handleFunctionReturnThunksAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
StringRef KindStr;
@@ -9488,10 +9402,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
handleAvailableOnlyInDefaultEvalMethod(S, D, AL);
break;
- case ParsedAttr::AT_CountedBy:
- handleCountedByAttr(S, D, AL);
- break;
-
// Microsoft attributes:
case ParsedAttr::AT_LayoutVersion:
handleLayoutVersion(S, D, AL);
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp
index c7185d56cc99..960f513d1111 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp
@@ -2469,8 +2469,7 @@ bool Sema::DiagnoseDependentMemberLookup(const LookupResult &R) {
bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
CorrectionCandidateCallback &CCC,
TemplateArgumentListInfo *ExplicitTemplateArgs,
- ArrayRef<Expr *> Args, DeclContext *LookupCtx,
- TypoExpr **Out) {
+ ArrayRef<Expr *> Args, TypoExpr **Out) {
DeclarationName Name = R.getLookupName();
unsigned diagnostic = diag::err_undeclared_var_use;
@@ -2486,8 +2485,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
// unqualified lookup. This is useful when (for example) the
// original lookup would not have found something because it was a
// dependent name.
- DeclContext *DC =
- LookupCtx ? LookupCtx : (SS.isEmpty() ? CurContext : nullptr);
+ DeclContext *DC = SS.isEmpty() ? CurContext : nullptr;
while (DC) {
if (isa<CXXRecordDecl>(DC)) {
LookupQualifiedName(R, DC);
@@ -2530,12 +2528,12 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, TypoLoc, Args,
diagnostic, diagnostic_suggest);
},
- nullptr, CTK_ErrorRecovery, LookupCtx);
+ nullptr, CTK_ErrorRecovery);
if (*Out)
return true;
- } else if (S && (Corrected =
- CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S,
- &SS, CCC, CTK_ErrorRecovery, LookupCtx))) {
+ } else if (S &&
+ (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(),
+ S, &SS, CCC, CTK_ErrorRecovery))) {
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
bool DroppedSpecifier =
Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr;
@@ -2825,7 +2823,7 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
// a template name, but we happen to have always already looked up the name
// before we get here if it must be a template name.
if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator, nullptr,
- std::nullopt, nullptr, &TE)) {
+ std::nullopt, &TE)) {
if (TE && KeywordReplacement) {
auto &State = getTypoExprState(TE);
auto BestTC = State.Consumer->getNextCorrection();
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
index 081b568762ae..4ae04358d5df 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
@@ -843,21 +843,21 @@ Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *Ex) {
// operation from the operand to the exception object (15.1) can be
// omitted by constructing the automatic object directly into the
// exception object
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex->IgnoreParens()))
- if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
- if (Var->hasLocalStorage() && !Var->getType().isVolatileQualified()) {
- for( ; S; S = S->getParent()) {
- if (S->isDeclScope(Var)) {
- IsThrownVarInScope = true;
- break;
- }
-
- // FIXME: Many of the scope checks here seem incorrect.
- if (S->getFlags() &
- (Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
- Scope::ObjCMethodScope | Scope::TryScope))
- break;
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(Ex->IgnoreParens()))
+ if (const auto *Var = dyn_cast<VarDecl>(DRE->getDecl());
+ Var && Var->hasLocalStorage() &&
+ !Var->getType().isVolatileQualified()) {
+ for (; S; S = S->getParent()) {
+ if (S->isDeclScope(Var)) {
+ IsThrownVarInScope = true;
+ break;
}
+
+ // FIXME: Many of the scope checks here seem incorrect.
+ if (S->getFlags() &
+ (Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
+ Scope::ObjCMethodScope | Scope::TryScope))
+ break;
}
}
}
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp b/contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp
index 473eea55bb6b..2abec3d86a27 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaExprMember.cpp
@@ -253,7 +253,9 @@ static void diagnoseInstanceReference(Sema &SemaRef,
SemaRef.Diag(Loc, diag::err_member_call_without_object)
<< Range << /*static*/ 0;
else {
- const auto *Callee = dyn_cast<CXXMethodDecl>(Rep);
+ if (const auto *Tpl = dyn_cast<FunctionTemplateDecl>(Rep))
+ Rep = Tpl->getTemplatedDecl();
+ const auto *Callee = cast<CXXMethodDecl>(Rep);
auto Diag = SemaRef.Diag(Loc, diag::err_member_call_without_object)
<< Range << Callee->isExplicitObjectMemberFunction();
if (!Replacement.empty())
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaInit.cpp b/contrib/llvm-project/clang/lib/Sema/SemaInit.cpp
index 035eaae58965..61d244f3bb97 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaInit.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaInit.cpp
@@ -25,6 +25,7 @@
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Ownership.h"
#include "clang/Sema/SemaInternal.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/FoldingSet.h"
@@ -465,8 +466,7 @@ class InitListChecker {
void FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
const InitializedEntity &ParentEntity,
InitListExpr *ILE, bool &RequiresSecondPass,
- bool FillWithNoInit = false,
- bool WarnIfMissing = false);
+ bool FillWithNoInit = false);
void FillInEmptyInitializations(const InitializedEntity &Entity,
InitListExpr *ILE, bool &RequiresSecondPass,
InitListExpr *OuterILE, unsigned OuterIndex,
@@ -655,16 +655,11 @@ void InitListChecker::FillInEmptyInitForBase(
}
}
-static bool hasAnyDesignatedInits(const InitListExpr *IL) {
- return llvm::any_of(*IL, [=](const Stmt *Init) {
- return isa_and_nonnull<DesignatedInitExpr>(Init);
- });
-}
-
-void InitListChecker::FillInEmptyInitForField(
- unsigned Init, FieldDecl *Field, const InitializedEntity &ParentEntity,
- InitListExpr *ILE, bool &RequiresSecondPass, bool FillWithNoInit,
- bool WarnIfMissing) {
+void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
+ const InitializedEntity &ParentEntity,
+ InitListExpr *ILE,
+ bool &RequiresSecondPass,
+ bool FillWithNoInit) {
SourceLocation Loc = ILE->getEndLoc();
unsigned NumInits = ILE->getNumInits();
InitializedEntity MemberEntity
@@ -732,52 +727,15 @@ void InitListChecker::FillInEmptyInitForField(
if (hadError || VerifyOnly) {
// Do nothing
- } else {
- if (WarnIfMissing) {
- auto CheckAnonMember = [&](const FieldDecl *FD,
- auto &&CheckAnonMember) -> FieldDecl * {
- FieldDecl *Uninitialized = nullptr;
- RecordDecl *RD = FD->getType()->getAsRecordDecl();
- assert(RD && "Not anonymous member checked?");
- for (auto *F : RD->fields()) {
- FieldDecl *UninitializedFieldInF = nullptr;
- if (F->isAnonymousStructOrUnion())
- UninitializedFieldInF = CheckAnonMember(F, CheckAnonMember);
- else if (!F->isUnnamedBitfield() &&
- !F->getType()->isIncompleteArrayType() &&
- !F->hasInClassInitializer())
- UninitializedFieldInF = F;
-
- if (RD->isUnion() && !UninitializedFieldInF)
- return nullptr;
- if (!Uninitialized)
- Uninitialized = UninitializedFieldInF;
- }
- return Uninitialized;
- };
-
- FieldDecl *FieldToDiagnose = nullptr;
- if (Field->isAnonymousStructOrUnion())
- FieldToDiagnose = CheckAnonMember(Field, CheckAnonMember);
- else if (!Field->isUnnamedBitfield() &&
- !Field->getType()->isIncompleteArrayType())
- FieldToDiagnose = Field;
-
- if (FieldToDiagnose)
- SemaRef.Diag(Loc, diag::warn_missing_field_initializers)
- << FieldToDiagnose;
- }
-
- if (Init < NumInits) {
- ILE->setInit(Init, MemberInit.getAs<Expr>());
- } else if (!isa<ImplicitValueInitExpr>(MemberInit.get())) {
- // Empty initialization requires a constructor call, so
- // extend the initializer list to include the constructor
- // call and make a note that we'll need to take another pass
- // through the initializer list.
- ILE->updateInit(SemaRef.Context, Init, MemberInit.getAs<Expr>());
- RequiresSecondPass = true;
- }
+ } else if (Init < NumInits) {
+ ILE->setInit(Init, MemberInit.getAs<Expr>());
+ } else if (!isa<ImplicitValueInitExpr>(MemberInit.get())) {
+ // Empty initialization requires a constructor call, so
+ // extend the initializer list to include the constructor
+ // call and make a note that we'll need to take another pass
+ // through the initializer list.
+ ILE->updateInit(SemaRef.Context, Init, MemberInit.getAs<Expr>());
+ RequiresSecondPass = true;
}
} else if (InitListExpr *InnerILE
= dyn_cast<InitListExpr>(ILE->getInit(Init))) {
@@ -845,36 +803,9 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
}
}
} else {
- InitListExpr *SForm =
- ILE->isSyntacticForm() ? ILE : ILE->getSyntacticForm();
// The fields beyond ILE->getNumInits() are default initialized, so in
// order to leave them uninitialized, the ILE is expanded and the extra
// fields are then filled with NoInitExpr.
-
- // Some checks that are required for missing fields warning are bound to
- // how many elements the initializer list originally was provided; perform
- // them before the list is expanded.
- bool WarnIfMissingField =
- !SForm->isIdiomaticZeroInitializer(SemaRef.getLangOpts()) &&
- ILE->getNumInits();
-
- // Disable check for missing fields when designators are used in C to
- // match gcc behaviour.
- // FIXME: Should we emulate possible gcc warning bug?
- WarnIfMissingField &=
- SemaRef.getLangOpts().CPlusPlus || !hasAnyDesignatedInits(SForm);
-
- if (OuterILE) {
- // When nested designators are present, there might be two nested init
- // lists created and only outer will contain designated initializer
- // expression, so check outer list as well.
- InitListExpr *OuterSForm = OuterILE->isSyntacticForm()
- ? OuterILE
- : OuterILE->getSyntacticForm();
- WarnIfMissingField &= SemaRef.getLangOpts().CPlusPlus ||
- !hasAnyDesignatedInits(OuterSForm);
- }
-
unsigned NumElems = numStructUnionElements(ILE->getType());
if (!RDecl->isUnion() && RDecl->hasFlexibleArrayMember())
++NumElems;
@@ -902,7 +833,7 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
return;
FillInEmptyInitForField(Init, Field, Entity, ILE, RequiresSecondPass,
- FillWithNoInit, WarnIfMissingField);
+ FillWithNoInit);
if (hadError)
return;
@@ -1017,6 +948,13 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
}
}
+static bool hasAnyDesignatedInits(const InitListExpr *IL) {
+ for (const Stmt *Init : *IL)
+ if (isa_and_nonnull<DesignatedInitExpr>(Init))
+ return true;
+ return false;
+}
+
InitListChecker::InitListChecker(
Sema &S, const InitializedEntity &Entity, InitListExpr *IL, QualType &T,
bool VerifyOnly, bool TreatUnavailableAsInvalid, bool InOverloadResolution,
@@ -2288,8 +2226,12 @@ void InitListChecker::CheckStructUnionTypes(
size_t NumRecordDecls = llvm::count_if(RD->decls(), [&](const Decl *D) {
return isa<FieldDecl>(D) || isa<RecordDecl>(D);
});
+ bool CheckForMissingFields =
+ !IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts());
bool HasDesignatedInit = false;
+ llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
+
while (Index < IList->getNumInits()) {
Expr *Init = IList->getInit(Index);
SourceLocation InitLoc = Init->getBeginLoc();
@@ -2313,17 +2255,24 @@ void InitListChecker::CheckStructUnionTypes(
// Find the field named by the designated initializer.
DesignatedInitExpr::Designator *D = DIE->getDesignator(0);
- if (!VerifyOnly && D->isFieldDesignator() && !DesignatedInitFailed) {
+ if (!VerifyOnly && D->isFieldDesignator()) {
FieldDecl *F = D->getFieldDecl();
- QualType ET = SemaRef.Context.getBaseElementType(F->getType());
- if (checkDestructorReference(ET, InitLoc, SemaRef)) {
- hadError = true;
- return;
+ InitializedFields.insert(F);
+ if (!DesignatedInitFailed) {
+ QualType ET = SemaRef.Context.getBaseElementType(F->getType());
+ if (checkDestructorReference(ET, InitLoc, SemaRef)) {
+ hadError = true;
+ return;
+ }
}
}
InitializedSomething = true;
+ // Disable check for missing fields when designators are used.
+ // This matches gcc behaviour.
+ if (!SemaRef.getLangOpts().CPlusPlus)
+ CheckForMissingFields = false;
continue;
}
@@ -2402,6 +2351,7 @@ void InitListChecker::CheckStructUnionTypes(
CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
StructuredList, StructuredIndex);
InitializedSomething = true;
+ InitializedFields.insert(*Field);
if (RD->isUnion() && StructuredList) {
// Initialize the first field within the union.
@@ -2411,6 +2361,28 @@ void InitListChecker::CheckStructUnionTypes(
++Field;
}
+ // Emit warnings for missing struct field initializers.
+ if (!VerifyOnly && InitializedSomething && CheckForMissingFields &&
+ !RD->isUnion()) {
+ // It is possible we have one or more unnamed bitfields remaining.
+ // Find first (if any) named field and emit warning.
+ for (RecordDecl::field_iterator it = HasDesignatedInit ? RD->field_begin()
+ : Field,
+ end = RD->field_end();
+ it != end; ++it) {
+ if (HasDesignatedInit && InitializedFields.count(*it))
+ continue;
+
+ if (!it->isUnnamedBitfield() && !it->hasInClassInitializer() &&
+ !it->getType()->isIncompleteArrayType()) {
+ SemaRef.Diag(IList->getSourceRange().getEnd(),
+ diag::warn_missing_field_initializers)
+ << *it;
+ break;
+ }
+ }
+ }
+
// Check that any remaining fields can be value-initialized if we're not
// building a structured list. (If we are, we'll check this later.)
if (!StructuredList && Field != FieldEnd && !RD->isUnion() &&
@@ -5458,18 +5430,12 @@ static void TryOrBuildParenListInitialization(
auto HandleInitializedEntity = [&](const InitializedEntity &SubEntity,
const InitializationKind &SubKind,
Expr *Arg, Expr **InitExpr = nullptr) {
- InitializationSequence IS = [&]() {
- if (Arg)
- return InitializationSequence(S, SubEntity, SubKind, Arg);
- return InitializationSequence(S, SubEntity, SubKind, std::nullopt);
- }();
+ InitializationSequence IS = InitializationSequence(
+ S, SubEntity, SubKind, Arg ? MultiExprArg(Arg) : std::nullopt);
if (IS.Failed()) {
if (!VerifyOnly) {
- if (Arg)
- IS.Diagnose(S, SubEntity, SubKind, Arg);
- else
- IS.Diagnose(S, SubEntity, SubKind, std::nullopt);
+ IS.Diagnose(S, SubEntity, SubKind, Arg ? ArrayRef(Arg) : std::nullopt);
} else {
Sequence.SetFailed(
InitializationSequence::FK_ParenthesizedListInitFailed);
@@ -5479,10 +5445,8 @@ static void TryOrBuildParenListInitialization(
}
if (!VerifyOnly) {
ExprResult ER;
- if (Arg)
- ER = IS.Perform(S, SubEntity, SubKind, Arg);
- else
- ER = IS.Perform(S, SubEntity, SubKind, std::nullopt);
+ ER = IS.Perform(S, SubEntity, SubKind,
+ Arg ? MultiExprArg(Arg) : std::nullopt);
if (InitExpr)
*InitExpr = ER.get();
else
@@ -10439,40 +10403,53 @@ static void DiagnoseNarrowingInInitList(Sema &S,
// No narrowing occurred.
return;
- case NK_Type_Narrowing:
+ case NK_Type_Narrowing: {
// This was a floating-to-integer conversion, which is always considered a
// narrowing conversion even if the value is a constant and can be
// represented exactly as an integer.
- S.Diag(PostInit->getBeginLoc(), NarrowingErrs(S.getLangOpts())
- ? diag::ext_init_list_type_narrowing
- : diag::warn_init_list_type_narrowing)
+ QualType T = EntityType.getNonReferenceType();
+ S.Diag(PostInit->getBeginLoc(),
+ NarrowingErrs(S.getLangOpts())
+ ? (T == EntityType
+ ? diag::ext_init_list_type_narrowing
+ : diag::ext_init_list_type_narrowing_const_reference)
+ : diag::warn_init_list_type_narrowing)
<< PostInit->getSourceRange()
<< PreNarrowingType.getLocalUnqualifiedType()
- << EntityType.getNonReferenceType().getLocalUnqualifiedType();
+ << T.getLocalUnqualifiedType();
break;
+ }
- case NK_Constant_Narrowing:
+ case NK_Constant_Narrowing: {
// A constant value was narrowed.
+ QualType T = EntityType.getNonReferenceType();
S.Diag(PostInit->getBeginLoc(),
NarrowingErrs(S.getLangOpts())
- ? diag::ext_init_list_constant_narrowing
+ ? (T == EntityType
+ ? diag::ext_init_list_constant_narrowing
+ : diag::ext_init_list_constant_narrowing_const_reference)
: diag::warn_init_list_constant_narrowing)
<< PostInit->getSourceRange()
<< ConstantValue.getAsString(S.getASTContext(), ConstantType)
<< EntityType.getNonReferenceType().getLocalUnqualifiedType();
break;
+ }
- case NK_Variable_Narrowing:
+ case NK_Variable_Narrowing: {
// A variable's value may have been narrowed.
+ QualType T = EntityType.getNonReferenceType();
S.Diag(PostInit->getBeginLoc(),
NarrowingErrs(S.getLangOpts())
- ? diag::ext_init_list_variable_narrowing
+ ? (T == EntityType
+ ? diag::ext_init_list_variable_narrowing
+ : diag::ext_init_list_variable_narrowing_const_reference)
: diag::warn_init_list_variable_narrowing)
<< PostInit->getSourceRange()
<< PreNarrowingType.getLocalUnqualifiedType()
<< EntityType.getNonReferenceType().getLocalUnqualifiedType();
break;
}
+ }
SmallString<128> StaticCast;
llvm::raw_svector_ostream OS(StaticCast);
@@ -10590,7 +10567,7 @@ static bool isOrIsDerivedFromSpecializationOf(CXXRecordDecl *RD,
QualType Sema::DeduceTemplateSpecializationFromInitializer(
TypeSourceInfo *TSInfo, const InitializedEntity &Entity,
- const InitializationKind &Kind, MultiExprArg Inits, ParenListExpr *PL) {
+ const InitializationKind &Kind, MultiExprArg Inits) {
auto *DeducedTST = dyn_cast<DeducedTemplateSpecializationType>(
TSInfo->getType()->getContainedDeducedType());
assert(DeducedTST && "not a deduced template specialization type");
@@ -10821,9 +10798,12 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
if (getLangOpts().CPlusPlus20 && !HasAnyDeductionGuide) {
if (ListInit && ListInit->getNumInits()) {
SynthesizeAggrGuide(ListInit);
- } else if (PL && PL->getNumExprs()) {
- InitListExpr TempListInit(getASTContext(), PL->getLParenLoc(),
- PL->exprs(), PL->getRParenLoc());
+ } else if (Inits.size()) { // parenthesized expression-list
+ // Inits are expressions inside the parentheses. We don't have
+ // the parentheses source locations, use the begin/end of Inits as the
+ // best heuristic.
+ InitListExpr TempListInit(getASTContext(), Inits.front()->getBeginLoc(),
+ Inits, Inits.back()->getEndLoc());
SynthesizeAggrGuide(&TempListInit);
}
}
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp b/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
index e400f248d15a..3826994ef212 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
@@ -14658,6 +14658,19 @@ StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
}
setFunctionHasBranchProtectedScope();
+ const OMPClause *BareClause = nullptr;
+ bool HasThreadLimitAndNumTeamsClause = hasClauses(Clauses, OMPC_num_teams) &&
+ hasClauses(Clauses, OMPC_thread_limit);
+ bool HasBareClause = llvm::any_of(Clauses, [&](const OMPClause *C) {
+ BareClause = C;
+ return C->getClauseKind() == OMPC_ompx_bare;
+ });
+
+ if (HasBareClause && !HasThreadLimitAndNumTeamsClause) {
+ Diag(BareClause->getBeginLoc(), diag::err_ompx_bare_no_grid);
+ return StmtError();
+ }
+
return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
AStmt);
}
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaRISCVVectorLookup.cpp b/contrib/llvm-project/clang/lib/Sema/SemaRISCVVectorLookup.cpp
index e4642e4da016..3ed3e6195441 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaRISCVVectorLookup.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaRISCVVectorLookup.cpp
@@ -206,15 +206,16 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
{"xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq},
{"xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod},
{"xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq},
- {"experimental-zvbb", RVV_REQ_Zvbb},
- {"experimental-zvbc", RVV_REQ_Zvbc},
- {"experimental-zvkb", RVV_REQ_Zvkb},
- {"experimental-zvkg", RVV_REQ_Zvkg},
- {"experimental-zvkned", RVV_REQ_Zvkned},
- {"experimental-zvknha", RVV_REQ_Zvknha},
- {"experimental-zvknhb", RVV_REQ_Zvknhb},
- {"experimental-zvksed", RVV_REQ_Zvksed},
- {"experimental-zvksh", RVV_REQ_Zvksh}};
+ {"zvbb", RVV_REQ_Zvbb},
+ {"zvbc", RVV_REQ_Zvbc},
+ {"zvkb", RVV_REQ_Zvkb},
+ {"zvkg", RVV_REQ_Zvkg},
+ {"zvkned", RVV_REQ_Zvkned},
+ {"zvknha", RVV_REQ_Zvknha},
+ {"zvknhb", RVV_REQ_Zvknhb},
+ {"zvksed", RVV_REQ_Zvksed},
+ {"zvksh", RVV_REQ_Zvksh},
+ {"experimental", RVV_REQ_Experimental}};
// Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics
// in RISCVVEmitter.cpp.
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp b/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp
index 63348d27a8c9..f0b03db69084 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp
@@ -1271,6 +1271,9 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
bool CaseListIsErroneous = false;
+ // FIXME: We'd better diagnose missing or duplicate default labels even
+ // in the dependent case. Because default labels themselves are never
+ // dependent.
for (SwitchCase *SC = SS->getSwitchCaseList(); SC && !HasDependentValue;
SC = SC->getNextSwitchCase()) {
@@ -1327,9 +1330,6 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
}
}
- if (!TheDefaultStmt)
- Diag(SwitchLoc, diag::warn_switch_default);
-
if (!HasDependentValue) {
// If we don't have a default statement, check whether the
// condition is constant.
@@ -1344,6 +1344,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
assert(!HasConstantCond ||
(ConstantCondValue.getBitWidth() == CondWidth &&
ConstantCondValue.isSigned() == CondIsSigned));
+ Diag(SwitchLoc, diag::warn_switch_default);
}
bool ShouldCheckConstantCond = HasConstantCond;
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp b/contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp
index f10abeaba0d4..5fcc39ec7005 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp
@@ -1824,6 +1824,15 @@ static void SetNestedNameSpecifier(Sema &S, TagDecl *T,
T->setQualifierInfo(SS.getWithLocInContext(S.Context));
}
+// Returns the template parameter list with all default template argument
+// information.
+static TemplateParameterList *GetTemplateParameterList(TemplateDecl *TD) {
+ // Make sure we get the template parameter list from the most
+ // recent declaration, since that is the only one that is guaranteed to
+ // have all the default template argument information.
+ return cast<TemplateDecl>(TD->getMostRecentDecl())->getTemplateParameters();
+}
+
DeclResult Sema::CheckClassTemplate(
Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc,
@@ -2061,13 +2070,13 @@ DeclResult Sema::CheckClassTemplate(
if (!(TUK == TUK_Friend && CurContext->isDependentContext()) &&
CheckTemplateParameterList(
TemplateParams,
- PrevClassTemplate
- ? PrevClassTemplate->getMostRecentDecl()->getTemplateParameters()
- : nullptr,
+ PrevClassTemplate ? GetTemplateParameterList(PrevClassTemplate)
+ : nullptr,
(SS.isSet() && SemanticContext && SemanticContext->isRecord() &&
SemanticContext->isDependentContext())
? TPC_ClassTemplateMember
- : TUK == TUK_Friend ? TPC_FriendClassTemplate : TPC_ClassTemplate,
+ : TUK == TUK_Friend ? TPC_FriendClassTemplate
+ : TPC_ClassTemplate,
SkipBody))
Invalid = true;
@@ -2298,7 +2307,7 @@ struct ConvertConstructorToDeductionGuideTransform {
// -- The template parameters are the template parameters of the class
// template followed by the template parameters (including default
// template arguments) of the constructor, if any.
- TemplateParameterList *TemplateParams = Template->getTemplateParameters();
+ TemplateParameterList *TemplateParams = GetTemplateParameterList(Template);
if (FTD) {
TemplateParameterList *InnerParams = FTD->getTemplateParameters();
SmallVector<NamedDecl *, 16> AllParams;
@@ -2424,7 +2433,7 @@ struct ConvertConstructorToDeductionGuideTransform {
Params.push_back(NewParam);
}
- return buildDeductionGuide(Template->getTemplateParameters(), nullptr,
+ return buildDeductionGuide(GetTemplateParameterList(Template), nullptr,
ExplicitSpecifier(), TSI, Loc, Loc, Loc);
}
@@ -5956,12 +5965,7 @@ bool Sema::CheckTemplateArgumentList(
// template.
TemplateArgumentListInfo NewArgs = TemplateArgs;
- // Make sure we get the template parameter list from the most
- // recent declaration, since that is the only one that is guaranteed to
- // have all the default template argument information.
- TemplateParameterList *Params =
- cast<TemplateDecl>(Template->getMostRecentDecl())
- ->getTemplateParameters();
+ TemplateParameterList *Params = GetTemplateParameterList(Template);
SourceLocation RAngleLoc = NewArgs.getRAngleLoc();
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
index 7140a14aefbf..d989707d5575 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -584,7 +584,18 @@ void ASTDeclReader::Visit(Decl *D) {
void ASTDeclReader::VisitDecl(Decl *D) {
BitsUnpacker DeclBits(Record.readInt());
+ auto ModuleOwnership =
+ (Decl::ModuleOwnershipKind)DeclBits.getNextBits(/*Width=*/3);
+ D->setReferenced(DeclBits.getNextBit());
+ D->Used = DeclBits.getNextBit();
+ IsDeclMarkedUsed |= D->Used;
+ D->setAccess((AccessSpecifier)DeclBits.getNextBits(/*Width=*/2));
+ D->setImplicit(DeclBits.getNextBit());
bool HasStandaloneLexicalDC = DeclBits.getNextBit();
+ bool HasAttrs = DeclBits.getNextBit();
+ D->setTopLevelDeclInObjCContainer(DeclBits.getNextBit());
+ D->InvalidDecl = DeclBits.getNextBit();
+ D->FromASTFile = true;
if (D->isTemplateParameter() || D->isTemplateParameterPack() ||
isa<ParmVarDecl, ObjCTypeParamDecl>(D)) {
@@ -623,20 +634,6 @@ void ASTDeclReader::VisitDecl(Decl *D) {
}
D->setLocation(ThisDeclLoc);
- D->InvalidDecl = DeclBits.getNextBit();
- bool HasAttrs = DeclBits.getNextBit();
- D->setImplicit(DeclBits.getNextBit());
- D->Used = DeclBits.getNextBit();
- IsDeclMarkedUsed |= D->Used;
- D->setReferenced(DeclBits.getNextBit());
- D->setTopLevelDeclInObjCContainer(DeclBits.getNextBit());
- D->setAccess((AccessSpecifier)DeclBits.getNextBits(/*Width=*/2));
- D->FromASTFile = true;
- auto ModuleOwnership =
- (Decl::ModuleOwnershipKind)DeclBits.getNextBits(/*Width=*/3);
- bool ModulePrivate =
- (ModuleOwnership == Decl::ModuleOwnershipKind::ModulePrivate);
-
if (HasAttrs) {
AttrVec Attrs;
Record.readAttributes(Attrs);
@@ -647,8 +644,9 @@ void ASTDeclReader::VisitDecl(Decl *D) {
// Determine whether this declaration is part of a (sub)module. If so, it
// may not yet be visible.
+ bool ModulePrivate =
+ (ModuleOwnership == Decl::ModuleOwnershipKind::ModulePrivate);
if (unsigned SubmoduleID = readSubmoduleID()) {
-
switch (ModuleOwnership) {
case Decl::ModuleOwnershipKind::Visible:
ModuleOwnership = Decl::ModuleOwnershipKind::VisibleWhenImported;
@@ -1065,9 +1063,11 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
// after everything else is read.
BitsUnpacker FunctionDeclBits(Record.readInt());
+ FD->setCachedLinkage((Linkage)FunctionDeclBits.getNextBits(/*Width=*/3));
FD->setStorageClass((StorageClass)FunctionDeclBits.getNextBits(/*Width=*/3));
FD->setInlineSpecified(FunctionDeclBits.getNextBit());
FD->setImplicitlyInline(FunctionDeclBits.getNextBit());
+ FD->setHasSkippedBody(FunctionDeclBits.getNextBit());
FD->setVirtualAsWritten(FunctionDeclBits.getNextBit());
// We defer calling `FunctionDecl::setPure()` here as for methods of
// `CXXTemplateSpecializationDecl`s, we may not have connected up the
@@ -1081,16 +1081,14 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->setDefaulted(FunctionDeclBits.getNextBit());
FD->setExplicitlyDefaulted(FunctionDeclBits.getNextBit());
FD->setIneligibleOrNotSelected(FunctionDeclBits.getNextBit());
- FD->setHasImplicitReturnZero(FunctionDeclBits.getNextBit());
FD->setConstexprKind(
(ConstexprSpecKind)FunctionDeclBits.getNextBits(/*Width=*/2));
- FD->setUsesSEHTry(FunctionDeclBits.getNextBit());
- FD->setHasSkippedBody(FunctionDeclBits.getNextBit());
+ FD->setHasImplicitReturnZero(FunctionDeclBits.getNextBit());
FD->setIsMultiVersion(FunctionDeclBits.getNextBit());
FD->setLateTemplateParsed(FunctionDeclBits.getNextBit());
FD->setFriendConstraintRefersToEnclosingTemplate(
FunctionDeclBits.getNextBit());
- FD->setCachedLinkage((Linkage)FunctionDeclBits.getNextBits(/*Width=*/3));
+ FD->setUsesSEHTry(FunctionDeclBits.getNextBit());
FD->EndRangeLoc = readSourceLocation();
if (FD->isExplicitlyDefaulted())
@@ -1597,6 +1595,8 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
VisitDeclaratorDecl(VD);
BitsUnpacker VarDeclBits(Record.readInt());
+ auto VarLinkage = Linkage(VarDeclBits.getNextBits(/*Width=*/3));
+ bool DefGeneratedInModule = VarDeclBits.getNextBit();
VD->VarDeclBits.SClass = (StorageClass)VarDeclBits.getNextBits(/*Width=*/3);
VD->VarDeclBits.TSCSpec = VarDeclBits.getNextBits(/*Width=*/2);
VD->VarDeclBits.InitStyle = VarDeclBits.getNextBits(/*Width=*/2);
@@ -1608,17 +1608,20 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
VD->NonParmVarDeclBits.ExceptionVar = VarDeclBits.getNextBit();
VD->NonParmVarDeclBits.NRVOVariable = VarDeclBits.getNextBit();
VD->NonParmVarDeclBits.CXXForRangeDecl = VarDeclBits.getNextBit();
- VD->NonParmVarDeclBits.ObjCForDecl = VarDeclBits.getNextBit();
+
VD->NonParmVarDeclBits.IsInline = VarDeclBits.getNextBit();
VD->NonParmVarDeclBits.IsInlineSpecified = VarDeclBits.getNextBit();
VD->NonParmVarDeclBits.IsConstexpr = VarDeclBits.getNextBit();
VD->NonParmVarDeclBits.IsInitCapture = VarDeclBits.getNextBit();
VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope =
VarDeclBits.getNextBit();
- VD->NonParmVarDeclBits.ImplicitParamKind =
- VarDeclBits.getNextBits(/*Width*/ 3);
+
VD->NonParmVarDeclBits.EscapingByref = VarDeclBits.getNextBit();
HasDeducedType = VarDeclBits.getNextBit();
+ VD->NonParmVarDeclBits.ImplicitParamKind =
+ VarDeclBits.getNextBits(/*Width*/ 3);
+
+ VD->NonParmVarDeclBits.ObjCForDecl = VarDeclBits.getNextBit();
}
// If this variable has a deduced type, defer reading that type until we are
@@ -1630,7 +1633,6 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
VD->setType(Reader.GetType(DeferredTypeID));
DeferredTypeID = 0;
- auto VarLinkage = Linkage(VarDeclBits.getNextBits(/*Width=*/3));
VD->setCachedLinkage(VarLinkage);
// Reconstruct the one piece of the IdentifierNamespace that we need.
@@ -1638,7 +1640,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
VD->getLexicalDeclContext()->isFunctionOrMethod())
VD->setLocalExternDecl();
- if (VarDeclBits.getNextBit()) {
+ if (DefGeneratedInModule) {
Reader.DefinitionSource[VD] =
Loc.F->Kind == ModuleKind::MK_MainFile ||
Reader.getContext().getLangOpts().BuildingPCHWithObjectFile;
@@ -2660,7 +2662,7 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
D->setDeclaredWithTypename(Record.readInt());
- if (Record.readBool()) {
+ if (D->hasTypeConstraint()) {
ConceptReference *CR = nullptr;
if (Record.readBool())
CR = Record.readConceptReference();
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp
index b3a6f619372b..21aed570ba26 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -73,6 +73,8 @@ namespace clang {
ASTRecordReader &Record;
llvm::BitstreamCursor &DeclsCursor;
+ std::optional<BitsUnpacker> CurrentUnpackingBits;
+
SourceLocation readSourceLocation() {
return Record.readSourceLocation();
}
@@ -110,6 +112,9 @@ namespace clang {
/// itself.
static const unsigned NumExprFields = NumStmtFields + 2;
+ /// The number of bits required for the packing bits for the Expr class.
+ static const unsigned NumExprBits = 10;
+
/// Read and initialize a ExplicitTemplateArgumentList structure.
void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args,
TemplateArgumentLoc *ArgsLocArray,
@@ -214,9 +219,11 @@ void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) {
void ASTStmtReader::VisitIfStmt(IfStmt *S) {
VisitStmt(S);
- bool HasElse = Record.readInt();
- bool HasVar = Record.readInt();
- bool HasInit = Record.readInt();
+ CurrentUnpackingBits.emplace(Record.readInt());
+
+ bool HasElse = CurrentUnpackingBits->getNextBit();
+ bool HasVar = CurrentUnpackingBits->getNextBit();
+ bool HasInit = CurrentUnpackingBits->getNextBit();
S->setStatementKind(static_cast<IfStatementKind>(Record.readInt()));
S->setCond(Record.readSubExpr());
@@ -523,14 +530,15 @@ void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) {
void ASTStmtReader::VisitExpr(Expr *E) {
VisitStmt(E);
+ CurrentUnpackingBits.emplace(Record.readInt());
+ E->setDependence(static_cast<ExprDependence>(
+ CurrentUnpackingBits->getNextBits(/*Width=*/5)));
+ E->setValueKind(static_cast<ExprValueKind>(
+ CurrentUnpackingBits->getNextBits(/*Width=*/2)));
+ E->setObjectKind(static_cast<ExprObjectKind>(
+ CurrentUnpackingBits->getNextBits(/*Width=*/3)));
+
E->setType(Record.readType());
- BitsUnpacker ExprBits(Record.readInt());
- E->setDependence(
- static_cast<ExprDependence>(ExprBits.getNextBits(/*Width=*/5)));
- E->setValueKind(
- static_cast<ExprValueKind>(ExprBits.getNextBits(/*Width=*/2)));
- E->setObjectKind(
- static_cast<ExprObjectKind>(ExprBits.getNextBits(/*Width=*/3)));
assert(Record.getIdx() == NumExprFields &&
"Incorrect expression field count");
}
@@ -591,13 +599,17 @@ void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
VisitExpr(E);
- E->DeclRefExprBits.HasQualifier = Record.readInt();
- E->DeclRefExprBits.HasFoundDecl = Record.readInt();
- E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record.readInt();
- E->DeclRefExprBits.HadMultipleCandidates = Record.readInt();
- E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = Record.readInt();
- E->DeclRefExprBits.NonOdrUseReason = Record.readInt();
- E->DeclRefExprBits.IsImmediateEscalating = Record.readInt();
+ CurrentUnpackingBits.emplace(Record.readInt());
+ E->DeclRefExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit();
+ E->DeclRefExprBits.RefersToEnclosingVariableOrCapture =
+ CurrentUnpackingBits->getNextBit();
+ E->DeclRefExprBits.NonOdrUseReason =
+ CurrentUnpackingBits->getNextBits(/*Width=*/2);
+ E->DeclRefExprBits.IsImmediateEscalating = CurrentUnpackingBits->getNextBit();
+ E->DeclRefExprBits.HasFoundDecl = CurrentUnpackingBits->getNextBit();
+ E->DeclRefExprBits.HasQualifier = CurrentUnpackingBits->getNextBit();
+ E->DeclRefExprBits.HasTemplateKWAndArgsInfo =
+ CurrentUnpackingBits->getNextBit();
E->DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
unsigned NumTemplateArgs = 0;
if (E->hasTemplateKWAndArgsInfo())
@@ -706,12 +718,13 @@ void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) {
void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) {
VisitExpr(E);
- bool hasFP_Features = Record.readInt();
+ bool hasFP_Features = CurrentUnpackingBits->getNextBit();
assert(hasFP_Features == E->hasStoredFPFeatures());
E->setSubExpr(Record.readSubExpr());
- E->setOpcode((UnaryOperator::Opcode)Record.readInt());
+ E->setOpcode(
+ (UnaryOperator::Opcode)CurrentUnpackingBits->getNextBits(/*Width=*/5));
E->setOperatorLoc(readSourceLocation());
- E->setCanOverflow(Record.readInt());
+ E->setCanOverflow(CurrentUnpackingBits->getNextBit());
if (hasFP_Features)
E->setStoredFPFeatures(
FPOptionsOverride::getFromOpaqueInt(Record.readInt()));
@@ -1000,12 +1013,11 @@ void ASTStmtReader::VisitOMPIteratorExpr(OMPIteratorExpr *E) {
void ASTStmtReader::VisitCallExpr(CallExpr *E) {
VisitExpr(E);
- BitsUnpacker CallExprBits = Record.readInt();
-
- unsigned NumArgs = CallExprBits.getNextBits(/*Width=*/16);
- bool HasFPFeatures = CallExprBits.getNextBit();
+ unsigned NumArgs = Record.readInt();
+ CurrentUnpackingBits.emplace(Record.readInt());
E->setADLCallKind(
- static_cast<CallExpr::ADLCallKind>(CallExprBits.getNextBit()));
+ static_cast<CallExpr::ADLCallKind>(CurrentUnpackingBits->getNextBit()));
+ bool HasFPFeatures = CurrentUnpackingBits->getNextBit();
assert((NumArgs == E->getNumArgs()) && "Wrong NumArgs!");
E->setRParenLoc(readSourceLocation());
E->setCallee(Record.readSubExpr());
@@ -1024,27 +1036,29 @@ void ASTStmtReader::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
void ASTStmtReader::VisitMemberExpr(MemberExpr *E) {
VisitExpr(E);
- bool HasQualifier = Record.readInt();
- bool HasFoundDecl = Record.readInt();
- bool HasTemplateInfo = Record.readInt();
+ CurrentUnpackingBits.emplace(Record.readInt());
+ bool HasQualifier = CurrentUnpackingBits->getNextBit();
+ bool HasFoundDecl = CurrentUnpackingBits->getNextBit();
+ bool HasTemplateInfo = CurrentUnpackingBits->getNextBit();
unsigned NumTemplateArgs = Record.readInt();
E->Base = Record.readSubExpr();
E->MemberDecl = Record.readDeclAs<ValueDecl>();
E->MemberDNLoc = Record.readDeclarationNameLoc(E->MemberDecl->getDeclName());
E->MemberLoc = Record.readSourceLocation();
- E->MemberExprBits.IsArrow = Record.readInt();
+ E->MemberExprBits.IsArrow = CurrentUnpackingBits->getNextBit();
E->MemberExprBits.HasQualifierOrFoundDecl = HasQualifier || HasFoundDecl;
E->MemberExprBits.HasTemplateKWAndArgsInfo = HasTemplateInfo;
- E->MemberExprBits.HadMultipleCandidates = Record.readInt();
- E->MemberExprBits.NonOdrUseReason = Record.readInt();
+ E->MemberExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit();
+ E->MemberExprBits.NonOdrUseReason =
+ CurrentUnpackingBits->getNextBits(/*Width=*/2);
E->MemberExprBits.OperatorLoc = Record.readSourceLocation();
if (HasQualifier || HasFoundDecl) {
DeclAccessPair FoundDecl;
if (HasFoundDecl) {
auto *FoundD = Record.readDeclAs<NamedDecl>();
- auto AS = (AccessSpecifier)Record.readInt();
+ auto AS = (AccessSpecifier)CurrentUnpackingBits->getNextBits(/*Width=*/2);
FoundDecl = DeclAccessPair::make(FoundD, AS);
} else {
FoundDecl = DeclAccessPair::make(E->MemberDecl,
@@ -1091,10 +1105,14 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) {
VisitExpr(E);
unsigned NumBaseSpecs = Record.readInt();
assert(NumBaseSpecs == E->path_size());
- unsigned HasFPFeatures = Record.readInt();
+
+ CurrentUnpackingBits.emplace(Record.readInt());
+ E->setCastKind((CastKind)CurrentUnpackingBits->getNextBits(/*Width=*/7));
+ unsigned HasFPFeatures = CurrentUnpackingBits->getNextBit();
assert(E->hasStoredFPFeatures() == HasFPFeatures);
+
E->setSubExpr(Record.readSubExpr());
- E->setCastKind((CastKind)Record.readInt());
+
CastExpr::path_iterator BaseI = E->path_begin();
while (NumBaseSpecs--) {
auto *BaseSpec = new (Record.getContext()) CXXBaseSpecifier;
@@ -1107,10 +1125,12 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) {
}
void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
- bool hasFP_Features;
VisitExpr(E);
- E->setHasStoredFPFeatures(hasFP_Features = Record.readInt());
- E->setOpcode((BinaryOperator::Opcode)Record.readInt());
+ CurrentUnpackingBits.emplace(Record.readInt());
+ E->setOpcode(
+ (BinaryOperator::Opcode)CurrentUnpackingBits->getNextBits(/*Width=*/6));
+ bool hasFP_Features = CurrentUnpackingBits->getNextBit();
+ E->setHasStoredFPFeatures(hasFP_Features);
E->setLHS(Record.readSubExpr());
E->setRHS(Record.readSubExpr());
E->setOperatorLoc(readSourceLocation());
@@ -1148,7 +1168,7 @@ ASTStmtReader::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) {
VisitCastExpr(E);
- E->setIsPartOfExplicitCast(Record.readInt());
+ E->setIsPartOfExplicitCast(CurrentUnpackingBits->getNextBit());
}
void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) {
@@ -1764,8 +1784,8 @@ void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
SourceRange R = readSourceRange();
E->Loc = R.getBegin();
E->RParenLoc = R.getEnd();
- R = readSourceRange();
- E->AngleBrackets = R;
+ if (CurrentUnpackingBits->getNextBit())
+ E->AngleBrackets = readSourceRange();
}
void ASTStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
@@ -1961,9 +1981,10 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr(
CXXDependentScopeMemberExpr *E) {
VisitExpr(E);
- bool HasTemplateKWAndArgsInfo = Record.readInt();
unsigned NumTemplateArgs = Record.readInt();
- bool HasFirstQualifierFoundInScope = Record.readInt();
+ CurrentUnpackingBits.emplace(Record.readInt());
+ bool HasTemplateKWAndArgsInfo = CurrentUnpackingBits->getNextBit();
+ bool HasFirstQualifierFoundInScope = CurrentUnpackingBits->getNextBit();
assert((HasTemplateKWAndArgsInfo == E->hasTemplateKWAndArgsInfo()) &&
"Wrong HasTemplateKWAndArgsInfo!");
@@ -1979,11 +2000,18 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr(
assert((NumTemplateArgs == E->getNumTemplateArgs()) &&
"Wrong NumTemplateArgs!");
- E->CXXDependentScopeMemberExprBits.IsArrow = Record.readInt();
- E->CXXDependentScopeMemberExprBits.OperatorLoc = readSourceLocation();
+ E->CXXDependentScopeMemberExprBits.IsArrow =
+ CurrentUnpackingBits->getNextBit();
+
E->BaseType = Record.readType();
E->QualifierLoc = Record.readNestedNameSpecifierLoc();
- E->Base = Record.readSubExpr();
+ // not ImplicitAccess
+ if (CurrentUnpackingBits->getNextBit())
+ E->Base = Record.readSubExpr();
+ else
+ E->Base = nullptr;
+
+ E->CXXDependentScopeMemberExprBits.OperatorLoc = readSourceLocation();
if (HasFirstQualifierFoundInScope)
*E->getTrailingObjects<NamedDecl *>() = readDeclAs<NamedDecl>();
@@ -1995,11 +2023,11 @@ void
ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
VisitExpr(E);
- if (Record.readInt()) // HasTemplateKWAndArgsInfo
+ if (CurrentUnpackingBits->getNextBit()) // HasTemplateKWAndArgsInfo
ReadTemplateKWAndArgsInfo(
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
E->getTrailingObjects<TemplateArgumentLoc>(),
- /*NumTemplateArgs=*/Record.readInt());
+ /*NumTemplateArgs=*/CurrentUnpackingBits->getNextBits(/*Width=*/16));
E->QualifierLoc = Record.readNestedNameSpecifierLoc();
E->NameInfo = Record.readDeclarationNameInfo();
@@ -2022,15 +2050,15 @@ ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(E);
- BitsUnpacker OverloadExprBits = Record.readInt();
- unsigned NumResults = OverloadExprBits.getNextBits(/*Width=*/14);
- bool HasTemplateKWAndArgsInfo = OverloadExprBits.getNextBit();
+ unsigned NumResults = Record.readInt();
+ CurrentUnpackingBits.emplace(Record.readInt());
+ bool HasTemplateKWAndArgsInfo = CurrentUnpackingBits->getNextBit();
assert((E->getNumDecls() == NumResults) && "Wrong NumResults!");
assert((E->hasTemplateKWAndArgsInfo() == HasTemplateKWAndArgsInfo) &&
"Wrong HasTemplateKWAndArgsInfo!");
if (HasTemplateKWAndArgsInfo) {
- unsigned NumTemplateArgs = OverloadExprBits.getNextBits(/*Width=*/14);
+ unsigned NumTemplateArgs = Record.readInt();
ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(),
E->getTrailingTemplateArgumentLoc(),
NumTemplateArgs);
@@ -2057,17 +2085,24 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
VisitOverloadExpr(E);
- E->UnresolvedMemberExprBits.IsArrow = Record.readInt();
- E->UnresolvedMemberExprBits.HasUnresolvedUsing = Record.readInt();
- E->Base = Record.readSubExpr();
- E->BaseType = Record.readType();
+ E->UnresolvedMemberExprBits.IsArrow = CurrentUnpackingBits->getNextBit();
+ E->UnresolvedMemberExprBits.HasUnresolvedUsing =
+ CurrentUnpackingBits->getNextBit();
+
+ if (/*!isImplicitAccess=*/CurrentUnpackingBits->getNextBit())
+ E->Base = Record.readSubExpr();
+ else
+ E->Base = nullptr;
+
E->OperatorLoc = readSourceLocation();
+
+ E->BaseType = Record.readType();
}
void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
VisitOverloadExpr(E);
- E->UnresolvedLookupExprBits.RequiresADL = Record.readInt();
- E->UnresolvedLookupExprBits.Overloaded = Record.readInt();
+ E->UnresolvedLookupExprBits.RequiresADL = CurrentUnpackingBits->getNextBit();
+ E->UnresolvedLookupExprBits.Overloaded = CurrentUnpackingBits->getNextBit();
E->NamingClass = readDeclAs<CXXRecordDecl>();
}
@@ -2142,9 +2177,12 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
VisitExpr(E);
E->AssociatedDeclAndRef.setPointer(readDeclAs<Decl>());
- E->AssociatedDeclAndRef.setInt(Record.readInt());
- E->Index = Record.readInt();
- E->PackIndex = Record.readInt();
+ E->AssociatedDeclAndRef.setInt(CurrentUnpackingBits->getNextBit());
+ E->Index = CurrentUnpackingBits->getNextBits(/*Width=*/12);
+ if (CurrentUnpackingBits->getNextBit())
+ E->PackIndex = Record.readInt();
+ else
+ E->PackIndex = 0;
E->SubstNonTypeTemplateParmExprBits.NameLoc = readSourceLocation();
E->Replacement = Record.readSubExpr();
}
@@ -2836,11 +2874,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = new (Context) NullStmt(Empty);
break;
- case STMT_COMPOUND:
- S = CompoundStmt::CreateEmpty(
- Context, /*NumStmts=*/Record[ASTStmtReader::NumStmtFields],
- /*HasFPFeatures=*/Record[ASTStmtReader::NumStmtFields + 1]);
+ case STMT_COMPOUND: {
+ unsigned NumStmts = Record[ASTStmtReader::NumStmtFields];
+ bool HasFPFeatures = Record[ASTStmtReader::NumStmtFields + 1];
+ S = CompoundStmt::CreateEmpty(Context, NumStmts, HasFPFeatures);
break;
+ }
case STMT_CASE:
S = CaseStmt::CreateEmpty(
@@ -2862,13 +2901,14 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
/*NumAttrs*/Record[ASTStmtReader::NumStmtFields]);
break;
- case STMT_IF:
- S = IfStmt::CreateEmpty(
- Context,
- /* HasElse=*/Record[ASTStmtReader::NumStmtFields],
- /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 1],
- /* HasInit=*/Record[ASTStmtReader::NumStmtFields + 2]);
+ case STMT_IF: {
+ BitsUnpacker IfStmtBits(Record[ASTStmtReader::NumStmtFields]);
+ bool HasElse = IfStmtBits.getNextBit();
+ bool HasVar = IfStmtBits.getNextBit();
+ bool HasInit = IfStmtBits.getNextBit();
+ S = IfStmt::CreateEmpty(Context, HasElse, HasVar, HasInit);
break;
+ }
case STMT_SWITCH:
S = SwitchStmt::CreateEmpty(
@@ -2945,17 +2985,19 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
/*HasFunctionName*/ Record[ASTStmtReader::NumExprFields]);
break;
- case EXPR_DECL_REF:
- S = DeclRefExpr::CreateEmpty(
- Context,
- /*HasQualifier=*/Record[ASTStmtReader::NumExprFields],
- /*HasFoundDecl=*/Record[ASTStmtReader::NumExprFields + 1],
- /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 2],
- /*NumTemplateArgs=*/
- Record[ASTStmtReader::NumExprFields + 2]
- ? Record[ASTStmtReader::NumExprFields + 7]
- : 0);
+ case EXPR_DECL_REF: {
+ BitsUnpacker DeclRefExprBits(Record[ASTStmtReader::NumExprFields]);
+ DeclRefExprBits.advance(5);
+ bool HasFoundDecl = DeclRefExprBits.getNextBit();
+ bool HasQualifier = DeclRefExprBits.getNextBit();
+ bool HasTemplateKWAndArgsInfo = DeclRefExprBits.getNextBit();
+ unsigned NumTemplateArgs = HasTemplateKWAndArgsInfo
+ ? Record[ASTStmtReader::NumExprFields + 1]
+ : 0;
+ S = DeclRefExpr::CreateEmpty(Context, HasQualifier, HasFoundDecl,
+ HasTemplateKWAndArgsInfo, NumTemplateArgs);
break;
+ }
case EXPR_INTEGER_LITERAL:
S = IntegerLiteral::Create(Context, Empty);
@@ -2995,10 +3037,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
/* NumExprs=*/Record[ASTStmtReader::NumExprFields]);
break;
- case EXPR_UNARY_OPERATOR:
- S = UnaryOperator::CreateEmpty(Context,
- Record[ASTStmtReader::NumExprFields]);
+ case EXPR_UNARY_OPERATOR: {
+ BitsUnpacker UnaryOperatorBits(Record[ASTStmtReader::NumStmtFields]);
+ UnaryOperatorBits.advance(ASTStmtReader::NumExprBits);
+ bool HasFPFeatures = UnaryOperatorBits.getNextBit();
+ S = UnaryOperator::CreateEmpty(Context, HasFPFeatures);
break;
+ }
case EXPR_OFFSETOF:
S = OffsetOfExpr::CreateEmpty(Context,
@@ -3033,8 +3078,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break;
case EXPR_CALL: {
- BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]);
- auto NumArgs = CallExprBits.getNextBits(/*Width=*/16);
+ auto NumArgs = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ CallExprBits.advance(1);
auto HasFPFeatures = CallExprBits.getNextBit();
S = CallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty);
break;
@@ -3045,22 +3091,32 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields]);
break;
- case EXPR_MEMBER:
- S = MemberExpr::CreateEmpty(Context, Record[ASTStmtReader::NumExprFields],
- Record[ASTStmtReader::NumExprFields + 1],
- Record[ASTStmtReader::NumExprFields + 2],
- Record[ASTStmtReader::NumExprFields + 3]);
+ case EXPR_MEMBER: {
+ BitsUnpacker ExprMemberBits(Record[ASTStmtReader::NumExprFields]);
+ bool HasQualifier = ExprMemberBits.getNextBit();
+ bool HasFoundDecl = ExprMemberBits.getNextBit();
+ bool HasTemplateInfo = ExprMemberBits.getNextBit();
+ unsigned NumTemplateArgs = Record[ASTStmtReader::NumExprFields + 1];
+ S = MemberExpr::CreateEmpty(Context, HasQualifier, HasFoundDecl,
+ HasTemplateInfo, NumTemplateArgs);
break;
+ }
- case EXPR_BINARY_OPERATOR:
- S = BinaryOperator::CreateEmpty(Context,
- Record[ASTStmtReader::NumExprFields]);
+ case EXPR_BINARY_OPERATOR: {
+ BitsUnpacker BinaryOperatorBits(Record[ASTStmtReader::NumExprFields]);
+ BinaryOperatorBits.advance(/*Size of opcode*/ 6);
+ bool HasFPFeatures = BinaryOperatorBits.getNextBit();
+ S = BinaryOperator::CreateEmpty(Context, HasFPFeatures);
break;
+ }
- case EXPR_COMPOUND_ASSIGN_OPERATOR:
- S = CompoundAssignOperator::CreateEmpty(
- Context, Record[ASTStmtReader::NumExprFields]);
+ case EXPR_COMPOUND_ASSIGN_OPERATOR: {
+ BitsUnpacker BinaryOperatorBits(Record[ASTStmtReader::NumExprFields]);
+ BinaryOperatorBits.advance(/*Size of opcode*/ 6);
+ bool HasFPFeatures = BinaryOperatorBits.getNextBit();
+ S = CompoundAssignOperator::CreateEmpty(Context, HasFPFeatures);
break;
+ }
case EXPR_CONDITIONAL_OPERATOR:
S = new (Context) ConditionalOperator(Empty);
@@ -3070,19 +3126,23 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = new (Context) BinaryConditionalOperator(Empty);
break;
- case EXPR_IMPLICIT_CAST:
- S = ImplicitCastExpr::CreateEmpty(
- Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields],
- /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
+ case EXPR_IMPLICIT_CAST: {
+ unsigned PathSize = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker CastExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ CastExprBits.advance(7);
+ bool HasFPFeatures = CastExprBits.getNextBit();
+ S = ImplicitCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures);
break;
+ }
- case EXPR_CSTYLE_CAST:
- S = CStyleCastExpr::CreateEmpty(
- Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields],
- /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
+ case EXPR_CSTYLE_CAST: {
+ unsigned PathSize = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker CastExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ CastExprBits.advance(7);
+ bool HasFPFeatures = CastExprBits.getNextBit();
+ S = CStyleCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures);
break;
+ }
case EXPR_COMPOUND_LITERAL:
S = new (Context) CompoundLiteralExpr(Empty);
@@ -3777,8 +3837,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
}
case EXPR_CXX_OPERATOR_CALL: {
- BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]);
- auto NumArgs = CallExprBits.getNextBits(/*Width=*/16);
+ auto NumArgs = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ CallExprBits.advance(1);
auto HasFPFeatures = CallExprBits.getNextBit();
S = CXXOperatorCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures,
Empty);
@@ -3786,8 +3847,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
}
case EXPR_CXX_MEMBER_CALL: {
- BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]);
- auto NumArgs = CallExprBits.getNextBits(/*Width=*/16);
+ auto NumArgs = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ CallExprBits.advance(1);
auto HasFPFeatures = CallExprBits.getNextBit();
S = CXXMemberCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures,
Empty);
@@ -3814,22 +3876,26 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
/* NumArgs=*/Record[ASTStmtReader::NumExprFields]);
break;
- case EXPR_CXX_STATIC_CAST:
- S = CXXStaticCastExpr::CreateEmpty(
- Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields],
- /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
+ case EXPR_CXX_STATIC_CAST: {
+ unsigned PathSize = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker CastExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ CastExprBits.advance(7);
+ bool HasFPFeatures = CastExprBits.getNextBit();
+ S = CXXStaticCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures);
break;
+ }
- case EXPR_CXX_DYNAMIC_CAST:
- S = CXXDynamicCastExpr::CreateEmpty(Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
+ case EXPR_CXX_DYNAMIC_CAST: {
+ unsigned PathSize = Record[ASTStmtReader::NumExprFields];
+ S = CXXDynamicCastExpr::CreateEmpty(Context, PathSize);
break;
+ }
- case EXPR_CXX_REINTERPRET_CAST:
- S = CXXReinterpretCastExpr::CreateEmpty(Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
+ case EXPR_CXX_REINTERPRET_CAST: {
+ unsigned PathSize = Record[ASTStmtReader::NumExprFields];
+ S = CXXReinterpretCastExpr::CreateEmpty(Context, PathSize);
break;
+ }
case EXPR_CXX_CONST_CAST:
S = CXXConstCastExpr::CreateEmpty(Context);
@@ -3839,21 +3905,28 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = CXXAddrspaceCastExpr::CreateEmpty(Context);
break;
- case EXPR_CXX_FUNCTIONAL_CAST:
- S = CXXFunctionalCastExpr::CreateEmpty(
- Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields],
- /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
+ case EXPR_CXX_FUNCTIONAL_CAST: {
+ unsigned PathSize = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker CastExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ CastExprBits.advance(7);
+ bool HasFPFeatures = CastExprBits.getNextBit();
+ S = CXXFunctionalCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures);
break;
+ }
- case EXPR_BUILTIN_BIT_CAST:
- assert(Record[ASTStmtReader::NumExprFields] == 0 && "Wrong PathSize!");
+ case EXPR_BUILTIN_BIT_CAST: {
+#ifndef NDEBUG
+ unsigned PathSize = Record[ASTStmtReader::NumExprFields];
+ assert(PathSize == 0 && "Wrong PathSize!");
+#endif
S = new (Context) BuiltinBitCastExpr(Empty);
break;
+ }
case EXPR_USER_DEFINED_LITERAL: {
- BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]);
- auto NumArgs = CallExprBits.getNextBits(/*Width=*/16);
+ auto NumArgs = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ CallExprBits.advance(1);
auto HasFPFeatures = CallExprBits.getNextBit();
S = UserDefinedLiteral::CreateEmpty(Context, NumArgs, HasFPFeatures,
Empty);
@@ -3944,47 +4017,62 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
Record[ASTStmtReader::NumExprFields]);
break;
- case EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
+ case EXPR_CXX_DEPENDENT_SCOPE_MEMBER: {
+ unsigned NumTemplateArgs = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker DependentScopeMemberBits(
+ Record[ASTStmtReader::NumExprFields + 1]);
+ bool HasTemplateKWAndArgsInfo = DependentScopeMemberBits.getNextBit();
+
+ bool HasFirstQualifierFoundInScope =
+ DependentScopeMemberBits.getNextBit();
S = CXXDependentScopeMemberExpr::CreateEmpty(
- Context,
- /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1],
- /*HasFirstQualifierFoundInScope=*/
- Record[ASTStmtReader::NumExprFields + 2]);
+ Context, HasTemplateKWAndArgsInfo, NumTemplateArgs,
+ HasFirstQualifierFoundInScope);
break;
+ }
- case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
- S = DependentScopeDeclRefExpr::CreateEmpty(Context,
- /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
- ? Record[ASTStmtReader::NumExprFields + 1]
- : 0);
+ case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF: {
+ BitsUnpacker DependentScopeDeclRefBits(
+ Record[ASTStmtReader::NumStmtFields]);
+ DependentScopeDeclRefBits.advance(ASTStmtReader::NumExprBits);
+ bool HasTemplateKWAndArgsInfo = DependentScopeDeclRefBits.getNextBit();
+ unsigned NumTemplateArgs =
+ HasTemplateKWAndArgsInfo
+ ? DependentScopeDeclRefBits.getNextBits(/*Width=*/16)
+ : 0;
+ S = DependentScopeDeclRefExpr::CreateEmpty(
+ Context, HasTemplateKWAndArgsInfo, NumTemplateArgs);
break;
+ }
case EXPR_CXX_UNRESOLVED_CONSTRUCT:
S = CXXUnresolvedConstructExpr::CreateEmpty(Context,
/*NumArgs=*/Record[ASTStmtReader::NumExprFields]);
break;
- case EXPR_CXX_UNRESOLVED_MEMBER:
+ case EXPR_CXX_UNRESOLVED_MEMBER: {
+ auto NumResults = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker OverloadExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ auto HasTemplateKWAndArgsInfo = OverloadExprBits.getNextBit();
+ auto NumTemplateArgs = HasTemplateKWAndArgsInfo
+ ? Record[ASTStmtReader::NumExprFields + 2]
+ : 0;
S = UnresolvedMemberExpr::CreateEmpty(
- Context,
- /*NumResults=*/Record[ASTStmtReader::NumExprFields] & ((1 << 14) - 1),
- /*HasTemplateKWAndArgsInfo=*/
- (Record[ASTStmtReader::NumExprFields] >> 14) & (0x1),
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] >> 14 &
- ((1 << 14) - 1));
+ Context, NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
break;
+ }
- case EXPR_CXX_UNRESOLVED_LOOKUP:
+ case EXPR_CXX_UNRESOLVED_LOOKUP: {
+ auto NumResults = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker OverloadExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ auto HasTemplateKWAndArgsInfo = OverloadExprBits.getNextBit();
+ auto NumTemplateArgs = HasTemplateKWAndArgsInfo
+ ? Record[ASTStmtReader::NumExprFields + 2]
+ : 0;
S = UnresolvedLookupExpr::CreateEmpty(
- Context,
- /*NumResults=*/Record[ASTStmtReader::NumExprFields] & ((1 << 14) - 1),
- /*HasTemplateKWAndArgsInfo=*/
- (Record[ASTStmtReader::NumExprFields] >> 14) & (0x1),
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] >> 14 &
- ((1 << 14) - 1));
+ Context, NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
break;
+ }
case EXPR_TYPE_TRAIT:
S = TypeTraitExpr::CreateDeserialized(Context,
@@ -4044,8 +4132,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break;
case EXPR_CUDA_KERNEL_CALL: {
- BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]);
- auto NumArgs = CallExprBits.getNextBits(/*Width=*/16);
+ auto NumArgs = Record[ASTStmtReader::NumExprFields];
+ BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields + 1]);
+ CallExprBits.advance(1);
auto HasFPFeatures = CallExprBits.getNextBit();
S = CUDAKernelCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures,
Empty);
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
index 91eb2af8f8ad..78939bfd533f 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
@@ -6003,12 +6003,17 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
BitsPacker DefinitionBits;
-#define FIELD(Name, Width, Merge) DefinitionBits.addBits(Data.Name, Width);
+#define FIELD(Name, Width, Merge) \
+ if (!DefinitionBits.canWriteNextNBits(Width)) { \
+ Record->push_back(DefinitionBits); \
+ DefinitionBits.reset(0); \
+ } \
+ DefinitionBits.addBits(Data.Name, Width);
+
#include "clang/AST/CXXRecordDeclDefinitionBits.def"
#undef FIELD
- while (DefinitionBits.hasUnconsumedValues())
- Record->push_back(DefinitionBits.getNextValue());
+ Record->push_back(DefinitionBits);
// getODRHash will compute the ODRHash if it has not been previously computed.
Record->push_back(D->getODRHash());
@@ -6047,7 +6052,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
LambdaBits.addBits(Lambda.CaptureDefault, /*Width=*/2);
LambdaBits.addBits(Lambda.NumCaptures, /*Width=*/15);
LambdaBits.addBit(Lambda.HasKnownInternalLinkage);
- Record->push_back(LambdaBits.getNextValue());
+ Record->push_back(LambdaBits);
Record->push_back(Lambda.NumExplicitCaptures);
Record->push_back(Lambda.ManglingNumber);
@@ -6058,10 +6063,12 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
const LambdaCapture &Capture = Lambda.Captures.front()[I];
AddSourceLocation(Capture.getLocation());
+
BitsPacker CaptureBits;
CaptureBits.addBit(Capture.isImplicit());
CaptureBits.addBits(Capture.getCaptureKind(), /*Width=*/3);
Record->push_back(CaptureBits);
+
switch (Capture.getCaptureKind()) {
case LCK_StarThis:
case LCK_This:
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
index 43169b2befc6..2554abc682a1 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -321,15 +321,25 @@ void ASTDeclWriter::Visit(Decl *D) {
void ASTDeclWriter::VisitDecl(Decl *D) {
BitsPacker DeclBits;
+
+ // The order matters here. It will be better to put the bit with higher
+ // probability to be 0 in the end of the bits.
+ //
+ // Since we're using VBR6 format to store it.
+ // It will be pretty effient if all the higher bits are 0.
+ // For example, if we need to pack 8 bits into a value and the stored value
+ // is 0xf0, the actual stored value will be 0b000111'110000, which takes 12
+ // bits actually. However, if we changed the order to be 0x0f, then we can
+ // store it as 0b001111, which takes 6 bits only now.
+ DeclBits.addBits((uint64_t)D->getModuleOwnershipKind(), /*BitWidth=*/3);
+ DeclBits.addBit(D->isReferenced());
+ DeclBits.addBit(D->isUsed(false));
+ DeclBits.addBits(D->getAccess(), /*BitWidth=*/2);
+ DeclBits.addBit(D->isImplicit());
DeclBits.addBit(D->getDeclContext() != D->getLexicalDeclContext());
- DeclBits.addBit(D->isInvalidDecl());
DeclBits.addBit(D->hasAttrs());
- DeclBits.addBit(D->isImplicit());
- DeclBits.addBit(D->isUsed(false));
- DeclBits.addBit(D->isReferenced());
DeclBits.addBit(D->isTopLevelDeclInObjCContainer());
- DeclBits.addBits(D->getAccess(), /*BitWidth=*/2);
- DeclBits.addBits((uint64_t)D->getModuleOwnershipKind(), /*BitWidth=*/3);
+ DeclBits.addBit(D->isInvalidDecl());
Record.push_back(DeclBits);
Record.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()));
@@ -493,21 +503,13 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
Record.AddDeclRef(nullptr);
}
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- !D->hasAttrs() &&
- !D->isImplicit() &&
- !D->isUsed(false) &&
- !D->hasExtInfo() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() &&
+ !D->isInvalidDecl() && !D->isImplicit() && !D->hasExtInfo() &&
!D->getTypedefNameForAnonDecl() &&
D->getFirstDecl() == D->getMostRecentDecl() &&
- !D->isInvalidDecl() &&
- !D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
- D->getAccess() == AS_none &&
- !D->isModulePrivate() &&
!CXXRecordDecl::classofKind(D->getKind()) &&
- !D->getIntegerTypeSourceInfo() &&
- !D->getMemberSpecializationInfo() &&
+ !D->getIntegerTypeSourceInfo() && !D->getMemberSpecializationInfo() &&
!needsAnonymousDeclarationNumber(D) &&
D->getDeclName().getNameKind() == DeclarationName::Identifier)
AbbrevToUse = Writer.getDeclEnumAbbrev();
@@ -542,18 +544,11 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
if (!isa<CXXRecordDecl>(D))
Record.push_back(D->getODRHash());
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- !D->hasAttrs() &&
- !D->isImplicit() &&
- !D->isUsed(false) &&
- !D->hasExtInfo() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() &&
+ !D->isImplicit() && !D->isInvalidDecl() && !D->hasExtInfo() &&
!D->getTypedefNameForAnonDecl() &&
D->getFirstDecl() == D->getMostRecentDecl() &&
- !D->isInvalidDecl() &&
- !D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
- D->getAccess() == AS_none &&
- !D->isModulePrivate() &&
!CXXRecordDecl::classofKind(D->getKind()) &&
!needsAnonymousDeclarationNumber(D) &&
D->getDeclName().getNameKind() == DeclarationName::Identifier)
@@ -674,11 +669,16 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
Record.push_back(D->getIdentifierNamespace());
+ // The order matters here. It will be better to put the bit with higher
+ // probability to be 0 in the end of the bits. See the comments in VisitDecl
+ // for details.
BitsPacker FunctionDeclBits;
// FIXME: stable encoding
+ FunctionDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), 3);
FunctionDeclBits.addBits((uint32_t)D->getStorageClass(), /*BitWidth=*/3);
FunctionDeclBits.addBit(D->isInlineSpecified());
FunctionDeclBits.addBit(D->isInlined());
+ FunctionDeclBits.addBit(D->hasSkippedBody());
FunctionDeclBits.addBit(D->isVirtualAsWritten());
FunctionDeclBits.addBit(D->isPure());
FunctionDeclBits.addBit(D->hasInheritedPrototype());
@@ -689,14 +689,12 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
FunctionDeclBits.addBit(D->isDefaulted());
FunctionDeclBits.addBit(D->isExplicitlyDefaulted());
FunctionDeclBits.addBit(D->isIneligibleOrNotSelected());
- FunctionDeclBits.addBit(D->hasImplicitReturnZero());
FunctionDeclBits.addBits((uint64_t)(D->getConstexprKind()), /*BitWidth=*/2);
- FunctionDeclBits.addBit(D->usesSEHTry());
- FunctionDeclBits.addBit(D->hasSkippedBody());
+ FunctionDeclBits.addBit(D->hasImplicitReturnZero());
FunctionDeclBits.addBit(D->isMultiVersion());
FunctionDeclBits.addBit(D->isLateTemplateParsed());
FunctionDeclBits.addBit(D->FriendConstraintRefersToEnclosingTemplate());
- FunctionDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), 3);
+ FunctionDeclBits.addBit(D->usesSEHTry());
Record.push_back(FunctionDeclBits);
Record.AddSourceLocation(D->getEndLoc());
@@ -1060,7 +1058,28 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
VisitRedeclarable(D);
VisitDeclaratorDecl(D);
+ // The order matters here. It will be better to put the bit with higher
+ // probability to be 0 in the end of the bits. See the comments in VisitDecl
+ // for details.
BitsPacker VarDeclBits;
+ VarDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()),
+ /*BitWidth=*/3);
+
+ bool ModulesCodegen = false;
+ if (Writer.WritingModule && D->getStorageDuration() == SD_Static &&
+ !D->getDescribedVarTemplate()) {
+ // When building a C++20 module interface unit or a partition unit, a
+ // strong definition in the module interface is provided by the
+ // compilation of that unit, not by its users. (Inline variables are still
+ // emitted in module users.)
+ ModulesCodegen =
+ (Writer.WritingModule->isInterfaceOrPartition() ||
+ (D->hasAttr<DLLExportAttr>() &&
+ Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) &&
+ Writer.Context->GetGVALinkageForVariable(D) >= GVA_StrongExternal;
+ }
+ VarDeclBits.addBit(ModulesCodegen);
+
VarDeclBits.addBits(D->getStorageClass(), /*BitWidth=*/3);
VarDeclBits.addBits(D->getTSCSpec(), /*BitWidth=*/2);
VarDeclBits.addBits(D->getInitStyle(), /*BitWidth=*/2);
@@ -1072,41 +1091,26 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
VarDeclBits.addBit(D->isExceptionVariable());
VarDeclBits.addBit(D->isNRVOVariable());
VarDeclBits.addBit(D->isCXXForRangeDecl());
- VarDeclBits.addBit(D->isObjCForDecl());
+
VarDeclBits.addBit(D->isInline());
VarDeclBits.addBit(D->isInlineSpecified());
VarDeclBits.addBit(D->isConstexpr());
VarDeclBits.addBit(D->isInitCapture());
VarDeclBits.addBit(D->isPreviousDeclInSameBlockScope());
+ VarDeclBits.addBit(D->isEscapingByref());
+ HasDeducedType = D->getType()->getContainedDeducedType();
+ VarDeclBits.addBit(HasDeducedType);
+
if (const auto *IPD = dyn_cast<ImplicitParamDecl>(D))
VarDeclBits.addBits(llvm::to_underlying(IPD->getParameterKind()),
/*Width=*/3);
else
VarDeclBits.addBits(0, /*Width=*/3);
- VarDeclBits.addBit(D->isEscapingByref());
- HasDeducedType = D->getType()->getContainedDeducedType();
- VarDeclBits.addBit(HasDeducedType);
- }
-
- VarDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), /*BitWidth=*/3);
-
- bool ModulesCodegen = false;
- if (Writer.WritingModule && D->getStorageDuration() == SD_Static &&
- !D->getDescribedVarTemplate()) {
- // When building a C++20 module interface unit or a partition unit, a
- // strong definition in the module interface is provided by the
- // compilation of that unit, not by its users. (Inline variables are still
- // emitted in module users.)
- ModulesCodegen =
- (Writer.WritingModule->isInterfaceOrPartition() ||
- (D->hasAttr<DLLExportAttr>() &&
- Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) &&
- Writer.Context->GetGVALinkageForVariable(D) >= GVA_StrongExternal;
+ VarDeclBits.addBit(D->isObjCForDecl());
}
- VarDeclBits.addBit(ModulesCodegen);
Record.push_back(VarDeclBits);
if (ModulesCodegen)
@@ -1135,29 +1139,17 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
Record.push_back(VarNotTemplate);
}
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- !D->hasAttrs() &&
- !D->isImplicit() &&
- !D->isUsed(false) &&
- !D->isInvalidDecl() &&
- !D->isReferenced() &&
+ if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() &&
!D->isTopLevelDeclInObjCContainer() &&
- D->getAccess() == AS_none &&
- !D->isModulePrivate() &&
!needsAnonymousDeclarationNumber(D) &&
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
- !D->hasExtInfo() &&
- D->getFirstDecl() == D->getMostRecentDecl() &&
- D->getKind() == Decl::Var &&
- !D->isInline() &&
- !D->isConstexpr() &&
- !D->isInitCapture() &&
- !D->isPreviousDeclInSameBlockScope() &&
- !D->isEscapingByref() &&
- !HasDeducedType &&
- D->getStorageDuration() != SD_Static &&
- !D->getDescribedVarTemplate() &&
- !D->getMemberSpecializationInfo())
+ !D->hasExtInfo() && D->getFirstDecl() == D->getMostRecentDecl() &&
+ D->getKind() == Decl::Var && !D->isInline() && !D->isConstexpr() &&
+ !D->isInitCapture() && !D->isPreviousDeclInSameBlockScope() &&
+ !D->isEscapingByref() && !HasDeducedType &&
+ D->getStorageDuration() != SD_Static && !D->getDescribedVarTemplate() &&
+ !D->getMemberSpecializationInfo() && !D->isObjCForDecl() &&
+ !isa<ImplicitParamDecl>(D) && !D->isEscapingByref())
AbbrevToUse = Writer.getDeclVarAbbrev();
Code = serialization::DECL_VAR;
@@ -1193,14 +1185,10 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
// we dynamically check for the properties that we optimize for, but don't
// know are true of all PARM_VAR_DECLs.
if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() &&
- !D->hasExtInfo() && !D->isImplicit() && !D->isUsed(false) &&
- !D->isInvalidDecl() && !D->isReferenced() && D->getAccess() == AS_none &&
- !D->isModulePrivate() && D->getStorageClass() == 0 &&
+ !D->hasExtInfo() && D->getStorageClass() == 0 && !D->isInvalidDecl() &&
+ !D->isTopLevelDeclInObjCContainer() &&
D->getInitStyle() == VarDecl::CInit && // Can params have anything else?
- D->getFunctionScopeDepth() == 0 && D->getObjCDeclQualifier() == 0 &&
- !D->isKNRPromoted() && !D->isExplicitObjectParameter() &&
- !D->hasInheritedDefaultArg() && D->getInit() == nullptr &&
- !D->hasUninstantiatedDefaultArg()) // No default expr.
+ D->getInit() == nullptr) // No default expr.
AbbrevToUse = Writer.getDeclParmVarAbbrev();
// Check things we know are true of *every* PARM_VAR_DECL, which is more than
@@ -1403,6 +1391,13 @@ void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
Record.push_back(D->getIdentifierNamespace());
Record.AddDeclRef(D->UsingOrNextShadow);
Record.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D));
+
+ if (D->getDeclContext() == D->getLexicalDeclContext() &&
+ D->getFirstDecl() == D->getMostRecentDecl() && !D->hasAttrs() &&
+ !needsAnonymousDeclarationNumber(D) &&
+ D->getDeclName().getNameKind() == DeclarationName::Identifier)
+ AbbrevToUse = Writer.getDeclUsingShadowAbbrev();
+
Code = serialization::DECL_USING_SHADOW;
}
@@ -1507,10 +1502,32 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() &&
!D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
- !D->hasExtInfo() && !D->hasInheritedPrototype() &&
- D->hasWrittenPrototype() &&
- D->getTemplatedKind() == FunctionDecl::TK_NonTemplate)
- AbbrevToUse = Writer.getDeclCXXMethodAbbrev();
+ !D->hasExtInfo() && !D->isExplicitlyDefaulted()) {
+ if (D->getTemplatedKind() == FunctionDecl::TK_NonTemplate ||
+ D->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate ||
+ D->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization ||
+ D->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate)
+ AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind());
+ else if (D->getTemplatedKind() ==
+ FunctionDecl::TK_FunctionTemplateSpecialization) {
+ FunctionTemplateSpecializationInfo *FTSInfo =
+ D->getTemplateSpecializationInfo();
+
+ if (FTSInfo->TemplateArguments->size() == 1) {
+ const TemplateArgument &TA = FTSInfo->TemplateArguments->get(0);
+ if (TA.getKind() == TemplateArgument::Type &&
+ !FTSInfo->TemplateArgumentsAsWritten &&
+ !FTSInfo->getMemberSpecializationInfo())
+ AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind());
+ }
+ } else if (D->getTemplatedKind() ==
+ FunctionDecl::TK_DependentFunctionTemplateSpecialization) {
+ DependentFunctionTemplateSpecializationInfo *DFTSInfo =
+ D->getDependentSpecializationInfo();
+ if (!DFTSInfo->TemplateArgumentsAsWritten)
+ AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind());
+ }
+ }
Code = serialization::DECL_CXX_METHOD;
}
@@ -1782,7 +1799,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Record.push_back(D->wasDeclaredWithTypename());
const TypeConstraint *TC = D->getTypeConstraint();
- Record.push_back(TC != nullptr);
+ assert((bool)TC == D->hasTypeConstraint());
if (TC) {
auto *CR = TC->getConceptReference();
Record.push_back(CR != nullptr);
@@ -1800,6 +1817,13 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
if (OwnsDefaultArg)
Record.AddTypeSourceInfo(D->getDefaultArgumentInfo());
+ if (!TC && !OwnsDefaultArg &&
+ D->getDeclContext() == D->getLexicalDeclContext() &&
+ !D->isInvalidDecl() && !D->hasAttrs() &&
+ !D->isTopLevelDeclInObjCContainer() && !D->isImplicit() &&
+ D->getDeclName().getNameKind() == DeclarationName::Identifier)
+ AbbrevToUse = Writer.getDeclTemplateTypeParmAbbrev();
+
Code = serialization::DECL_TEMPLATE_TYPE_PARM;
}
@@ -2031,6 +2055,106 @@ void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
// ASTWriter Implementation
//===----------------------------------------------------------------------===//
+namespace {
+template <FunctionDecl::TemplatedKind Kind>
+std::shared_ptr<llvm::BitCodeAbbrev>
+getFunctionDeclAbbrev(serialization::DeclCode Code) {
+ using namespace llvm;
+
+ auto Abv = std::make_shared<BitCodeAbbrev>();
+ Abv->Add(BitCodeAbbrevOp(Code));
+ // RedeclarableDecl
+ Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
+ Abv->Add(BitCodeAbbrevOp(Kind));
+ if constexpr (Kind == FunctionDecl::TK_NonTemplate) {
+
+ } else if constexpr (Kind == FunctionDecl::TK_FunctionTemplate) {
+ // DescribedFunctionTemplate
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ } else if constexpr (Kind == FunctionDecl::TK_DependentNonTemplate) {
+ // Instantiated From Decl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ } else if constexpr (Kind == FunctionDecl::TK_MemberSpecialization) {
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InstantiatedFrom
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+ 3)); // TemplateSpecializationKind
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Specialized Location
+ } else if constexpr (Kind ==
+ FunctionDecl::TK_FunctionTemplateSpecialization) {
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Template
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+ 3)); // TemplateSpecializationKind
+ Abv->Add(BitCodeAbbrevOp(1)); // Template Argument Size
+ Abv->Add(BitCodeAbbrevOp(TemplateArgument::Type)); // Template Argument Kind
+ Abv->Add(
+ BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Template Argument Type
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Is Defaulted
+ Abv->Add(BitCodeAbbrevOp(0)); // TemplateArgumentsAsWritten
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
+ Abv->Add(BitCodeAbbrevOp(0));
+ Abv->Add(
+ BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Canonical Decl of template
+ } else if constexpr (Kind == FunctionDecl::
+ TK_DependentFunctionTemplateSpecialization) {
+ // Candidates of specialization
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abv->Add(BitCodeAbbrevOp(0)); // TemplateArgumentsAsWritten
+ } else {
+ llvm_unreachable("Unknown templated kind?");
+ }
+ // Decl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+ 8)); // Packed DeclBits: ModuleOwnershipKind,
+ // isUsed, isReferenced, AccessSpecifier,
+ // isImplicit
+ //
+ // The following bits should be 0:
+ // HasStandaloneLexicalDC, HasAttrs,
+ // TopLevelDeclInObjCContainer,
+ // isInvalidDecl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
+ // NamedDecl
+ Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier
+ Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
+ // ValueDecl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ // DeclaratorDecl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart
+ Abv->Add(BitCodeAbbrevOp(0)); // HasExtInfo
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
+ // FunctionDecl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
+ Abv->Add(BitCodeAbbrevOp(
+ BitCodeAbbrevOp::Fixed,
+ 27)); // Packed Function Bits: StorageClass, Inline, InlineSpecified,
+ // VirtualAsWritten, Pure, HasInheritedProto, HasWrittenProto,
+ // Deleted, Trivial, TrivialForCall, Defaulted, ExplicitlyDefaulted,
+ // IsIneligibleOrNotSelected, ImplicitReturnZero, Constexpr,
+ // UsesSEHTry, SkippedBody, MultiVersion, LateParsed,
+ // FriendConstraintRefersToEnclosingTemplate, Linkage
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
+ // This Array slurps the rest of the record. Fortunately we want to encode
+ // (nearly) all the remaining (variable number of) fields in the same way.
+ //
+ // This is:
+ // NumParams and Params[] from FunctionDecl, and
+ // NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
+ //
+ // Add an AbbrevOp for 'size then elements' and use it here.
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+ return Abv;
+}
+
+template <FunctionDecl::TemplatedKind Kind>
+std::shared_ptr<llvm::BitCodeAbbrev> getCXXMethodAbbrev() {
+ return getFunctionDeclAbbrev<Kind>(serialization::DECL_CXX_METHOD);
+}
+} // namespace
+
void ASTWriter::WriteDeclAbbrevs() {
using namespace llvm;
@@ -2041,10 +2165,13 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD));
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- 12)); // Packed DeclBits: HasStandaloneLexicalDC,
- // isInvalidDecl, HasAttrs, isImplicit, isUsed,
- // isReferenced, TopLevelDeclInObjCContainer,
- // AccessSpecifier, ModuleOwnershipKind
+ 7)); // Packed DeclBits: ModuleOwnershipKind,
+ // isUsed, isReferenced, AccessSpecifier,
+ //
+ // The following bits should be 0:
+ // isImplicit, HasStandaloneLexicalDC, HasAttrs,
+ // TopLevelDeclInObjCContainer,
+ // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
// NamedDecl
@@ -2104,10 +2231,13 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- 12)); // Packed DeclBits: HasStandaloneLexicalDC,
- // isInvalidDecl, HasAttrs, isImplicit, isUsed,
- // isReferenced, TopLevelDeclInObjCContainer,
- // AccessSpecifier, ModuleOwnershipKind
+ 7)); // Packed DeclBits: ModuleOwnershipKind,
+ // isUsed, isReferenced, AccessSpecifier,
+ //
+ // The following bits should be 0:
+ // isImplicit, HasStandaloneLexicalDC, HasAttrs,
+ // TopLevelDeclInObjCContainer,
+ // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
// NamedDecl
@@ -2145,10 +2275,13 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- 12)); // Packed DeclBits: HasStandaloneLexicalDC,
- // isInvalidDecl, HasAttrs, isImplicit, isUsed,
- // isReferenced, TopLevelDeclInObjCContainer,
- // AccessSpecifier, ModuleOwnershipKind
+ 7)); // Packed DeclBits: ModuleOwnershipKind,
+ // isUsed, isReferenced, AccessSpecifier,
+ //
+ // The following bits should be 0:
+ // isImplicit, HasStandaloneLexicalDC, HasAttrs,
+ // TopLevelDeclInObjCContainer,
+ // isInvalidDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
// NamedDecl
@@ -2193,10 +2326,11 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- 12)); // Packed DeclBits: HasStandaloneLexicalDC,
- // isInvalidDecl, HasAttrs, isImplicit, isUsed,
- // isReferenced, TopLevelDeclInObjCContainer,
- // AccessSpecifier, ModuleOwnershipKind
+ 8)); // Packed DeclBits: ModuleOwnershipKind, isUsed,
+ // isReferenced, AccessSpecifier,
+ // HasStandaloneLexicalDC, HasAttrs, isImplicit,
+ // TopLevelDeclInObjCContainer,
+ // isInvalidDecl,
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
// NamedDecl
@@ -2233,10 +2367,11 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- 12)); // Packed DeclBits: HasStandaloneLexicalDC,
- // isInvalidDecl, HasAttrs, isImplicit, isUsed,
- // isReferenced, TopLevelDeclInObjCContainer,
- // AccessSpecifier, ModuleOwnershipKind
+ 7)); // Packed DeclBits: ModuleOwnershipKind,
+ // isReferenced, isUsed, AccessSpecifier. Other
+ // higher bits should be 0: isImplicit,
+ // HasStandaloneLexicalDC, HasAttrs,
+ // TopLevelDeclInObjCContainer, isInvalidDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
// NamedDecl
@@ -2277,12 +2412,13 @@ void ASTWriter::WriteDeclAbbrevs() {
// VarDecl
Abv->Add(BitCodeAbbrevOp(
BitCodeAbbrevOp::Fixed,
- 27)); // Packed Var Decl bits: SClass, TSCSpec, InitStyle,
+ 21)); // Packed Var Decl bits: Linkage, ModulesCodegen,
+ // SClass, TSCSpec, InitStyle,
// isARCPseudoStrong, IsThisDeclarationADemotedDefinition,
// isExceptionVariable, isNRVOVariable, isCXXForRangeDecl,
- // isObjCForDecl, isInline, isInlineSpecified, isConstexpr,
- // isInitCapture, isPrevDeclInSameScope, ImplicitParamKind,
- // EscapingByref, HasDeducedType, Linkage, ModulesCodegen
+ // isInline, isInlineSpecified, isConstexpr,
+ // isInitCapture, isPrevDeclInSameScope,
+ // EscapingByref, HasDeducedType, ImplicitParamKind, isObjCForDecl
Abv->Add(BitCodeAbbrevOp(0)); // VarKind (local enum)
// Type Source Info
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
@@ -2290,71 +2426,84 @@ void ASTWriter::WriteDeclAbbrevs() {
DeclVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
// Abbreviation for DECL_CXX_METHOD
+ DeclCXXMethodAbbrev =
+ Stream.EmitAbbrev(getCXXMethodAbbrev<FunctionDecl::TK_NonTemplate>());
+ DeclTemplateCXXMethodAbbrev = Stream.EmitAbbrev(
+ getCXXMethodAbbrev<FunctionDecl::TK_FunctionTemplate>());
+ DeclDependentNonTemplateCXXMethodAbbrev = Stream.EmitAbbrev(
+ getCXXMethodAbbrev<FunctionDecl::TK_DependentNonTemplate>());
+ DeclMemberSpecializedCXXMethodAbbrev = Stream.EmitAbbrev(
+ getCXXMethodAbbrev<FunctionDecl::TK_MemberSpecialization>());
+ DeclTemplateSpecializedCXXMethodAbbrev = Stream.EmitAbbrev(
+ getCXXMethodAbbrev<FunctionDecl::TK_FunctionTemplateSpecialization>());
+ DeclDependentSpecializationCXXMethodAbbrev = Stream.EmitAbbrev(
+ getCXXMethodAbbrev<
+ FunctionDecl::TK_DependentFunctionTemplateSpecialization>());
+
+ // Abbreviation for DECL_TEMPLATE_TYPE_PARM
Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD));
- // RedeclarableDecl
- Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
- // FIXME: Implement abbreviation for other template kinds.
- Abv->Add(BitCodeAbbrevOp(FunctionDecl::TK_NonTemplate)); // TemplateKind
+ Abv->Add(BitCodeAbbrevOp(serialization::DECL_TEMPLATE_TYPE_PARM));
+ Abv->Add(BitCodeAbbrevOp(0)); // hasTypeConstraint
+ // Decl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+ 7)); // Packed DeclBits: ModuleOwnershipKind,
+ // isReferenced, isUsed, AccessSpecifier. Other
+ // higher bits should be 0: isImplicit,
+ // HasStandaloneLexicalDC, HasAttrs,
+ // TopLevelDeclInObjCContainer, isInvalidDecl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
+ // NamedDecl
+ Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
+ Abv->Add(BitCodeAbbrevOp(0));
+ // TypeDecl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
+ // TemplateTypeParmDecl
+ Abv->Add(
+ BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // wasDeclaredWithTypename
+ Abv->Add(BitCodeAbbrevOp(0)); // OwnsDefaultArg
+ DeclTemplateTypeParmAbbrev = Stream.EmitAbbrev(std::move(Abv));
+
+ // Abbreviation for DECL_USING_SHADOW
+ Abv = std::make_shared<BitCodeAbbrev>();
+ Abv->Add(BitCodeAbbrevOp(serialization::DECL_USING_SHADOW));
+ // Redeclarable
+ Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
12)); // Packed DeclBits: HasStandaloneLexicalDC,
// isInvalidDecl, HasAttrs, isImplicit, isUsed,
// isReferenced, TopLevelDeclInObjCContainer,
// AccessSpecifier, ModuleOwnershipKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
// NamedDecl
- Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier
- Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
- // ValueDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- // DeclaratorDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart
- Abv->Add(BitCodeAbbrevOp(0)); // HasExtInfo
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
- // FunctionDecl
+ Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
+ Abv->Add(BitCodeAbbrevOp(0));
+ // UsingShadowDecl
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TargetDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
- Abv->Add(BitCodeAbbrevOp(
- BitCodeAbbrevOp::Fixed,
- 27)); // Packed Function Bits: StorageClass, Inline, InlineSpecified,
- // VirtualAsWritten, Pure, HasInheritedProto, HasWrittenProto,
- // Deleted, Trivial, TrivialForCall, Defaulted, ExplicitlyDefaulted,
- // IsIneligibleOrNotSelected, ImplicitReturnZero, Constexpr,
- // UsesSEHTry, SkippedBody, MultiVersion, LateParsed,
- // FriendConstraintRefersToEnclosingTemplate, Linkage
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Default
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
- // This Array slurps the rest of the record. Fortunately we want to encode
- // (nearly) all the remaining (variable number of) fields in the same way.
- //
- // This is:
- // NumParams and Params[] from FunctionDecl, and
- // NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
- //
- // Add an AbbrevOp for 'size then elements' and use it here.
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
- DeclCXXMethodAbbrev = Stream.EmitAbbrev(std::move(Abv));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // UsingOrNextShadow
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR,
+ 6)); // InstantiatedFromUsingShadowDecl
+ DeclUsingShadowAbbrev = Stream.EmitAbbrev(std::move(Abv));
// Abbreviation for EXPR_DECL_REF
Abv = std::make_shared<BitCodeAbbrev>();
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
- //Stmt
- // Expr
+ // Stmt
+ // Expr
+ // PackingBits: DependenceKind, ValueKind. ObjectKind should be 0.
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- // DependenceKind, ValueKind, ObjectKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
- //DeclRefExpr
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates
- Abv->Add(BitCodeAbbrevOp(0)); // RefersToEnclosingVariableOrCapture
- Abv->Add(BitCodeAbbrevOp(0)); // NonOdrUseReason
- Abv->Add(BitCodeAbbrevOp(0)); // IsImmediateEscalating
+ // DeclRefExpr
+ // Packing Bits: , HadMultipleCandidates, RefersToEnclosingVariableOrCapture,
+ // IsImmediateEscalating, NonOdrUseReason.
+ // GetDeclFound, HasQualifier and ExplicitTemplateArgs should be 0.
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5));
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
@@ -2364,10 +2513,10 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL));
//Stmt
// Expr
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
// DependenceKind, ValueKind, ObjectKind
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
- //Integer Literal
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ // Integer Literal
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
Abv->Add(BitCodeAbbrevOp(32)); // Bit Width
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
@@ -2378,10 +2527,10 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL));
//Stmt
// Expr
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
// DependenceKind, ValueKind, ObjectKind
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
- //Character Literal
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ // Character Literal
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // getKind
@@ -2392,17 +2541,108 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST));
// Stmt
// Expr
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- // DependenceKind, ValueKind, ObjectKind
+ // Packing Bits: DependenceKind, ValueKind, ObjectKind,
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
// CastExpr
Abv->Add(BitCodeAbbrevOp(0)); // PathSize
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasFPFeatures
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // PartOfExplicitCast
+ // Packing Bits: CastKind, StoredFPFeatures, isPartOfExplicitCast
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 9));
// ImplicitCastExpr
ExprImplicitCastAbbrev = Stream.EmitAbbrev(std::move(Abv));
+ // Abbreviation for EXPR_BINARY_OPERATOR
+ Abv = std::make_shared<BitCodeAbbrev>();
+ Abv->Add(BitCodeAbbrevOp(serialization::EXPR_BINARY_OPERATOR));
+ // Stmt
+ // Expr
+ // Packing Bits: DependenceKind. ValueKind and ObjectKind should
+ // be 0 in this case.
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ // BinaryOperator
+ Abv->Add(
+ BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpCode and HasFPFeatures
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
+ BinaryOperatorAbbrev = Stream.EmitAbbrev(std::move(Abv));
+
+ // Abbreviation for EXPR_COMPOUND_ASSIGN_OPERATOR
+ Abv = std::make_shared<BitCodeAbbrev>();
+ Abv->Add(BitCodeAbbrevOp(serialization::EXPR_COMPOUND_ASSIGN_OPERATOR));
+ // Stmt
+ // Expr
+ // Packing Bits: DependenceKind. ValueKind and ObjectKind should
+ // be 0 in this case.
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ // BinaryOperator
+ // Packing Bits: OpCode. The HasFPFeatures bit should be 0
+ Abv->Add(
+ BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpCode and HasFPFeatures
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
+ // CompoundAssignOperator
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHSType
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Result Type
+ CompoundAssignOperatorAbbrev = Stream.EmitAbbrev(std::move(Abv));
+
+ // Abbreviation for EXPR_CALL
+ Abv = std::make_shared<BitCodeAbbrev>();
+ Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CALL));
+ // Stmt
+ // Expr
+ // Packing Bits: DependenceKind, ValueKind, ObjectKind,
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ // CallExpr
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumArgs
+ Abv->Add(BitCodeAbbrevOp(0)); // ADLCallKind
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
+ CallExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
+
+ // Abbreviation for EXPR_CXX_OPERATOR_CALL
+ Abv = std::make_shared<BitCodeAbbrev>();
+ Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CXX_OPERATOR_CALL));
+ // Stmt
+ // Expr
+ // Packing Bits: DependenceKind, ValueKind, ObjectKind,
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ // CallExpr
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumArgs
+ Abv->Add(BitCodeAbbrevOp(0)); // ADLCallKind
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
+ // CXXOperatorCallExpr
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Operator Kind
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
+ CXXOperatorCallExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
+
+ // Abbreviation for EXPR_CXX_MEMBER_CALL
+ Abv = std::make_shared<BitCodeAbbrev>();
+ Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CXX_MEMBER_CALL));
+ // Stmt
+ // Expr
+ // Packing Bits: DependenceKind, ValueKind, ObjectKind,
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
+ // CallExpr
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumArgs
+ Abv->Add(BitCodeAbbrevOp(0)); // ADLCallKind
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
+ // CXXMemberCallExpr
+ CXXMemberCallExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
+
+ // Abbreviation for STMT_COMPOUND
+ Abv = std::make_shared<BitCodeAbbrev>();
+ Abv->Add(BitCodeAbbrevOp(serialization::STMT_COMPOUND));
+ // Stmt
+ // CompoundStmt
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Num Stmts
+ Abv->Add(BitCodeAbbrevOp(0)); // hasStoredFPFeatures
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
+ CompoundStmtAbbrev = Stream.EmitAbbrev(std::move(Abv));
+
Abv = std::make_shared<BitCodeAbbrev>();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
index 8524484ea8a0..7f888e44dde1 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -37,15 +37,70 @@ namespace clang {
serialization::StmtCode Code;
unsigned AbbrevToUse;
+ /// A helper that can help us to write a packed bit across function
+ /// calls. For example, we may write seperate bits in seperate functions:
+ ///
+ /// void VisitA(A* a) {
+ /// Record.push_back(a->isSomething());
+ /// }
+ ///
+ /// void Visitb(B *b) {
+ /// VisitA(b);
+ /// Record.push_back(b->isAnother());
+ /// }
+ ///
+ /// In such cases, it'll be better if we can pack these 2 bits. We achieve
+ /// this by writing a zero value in `VisitA` and recorded that first and add
+ /// the new bit to the recorded value.
+ class PakedBitsWriter {
+ public:
+ PakedBitsWriter(ASTRecordWriter &Record) : RecordRef(Record) {}
+ ~PakedBitsWriter() { assert(!CurrentIndex); }
+
+ void addBit(bool Value) {
+ assert(CurrentIndex && "Writing Bits without recording first!");
+ PackingBits.addBit(Value);
+ }
+ void addBits(uint32_t Value, uint32_t BitsWidth) {
+ assert(CurrentIndex && "Writing Bits without recording first!");
+ PackingBits.addBits(Value, BitsWidth);
+ }
+
+ void writeBits() {
+ if (!CurrentIndex)
+ return;
+
+ RecordRef[*CurrentIndex] = (uint32_t)PackingBits;
+ CurrentIndex = std::nullopt;
+ PackingBits.reset(0);
+ }
+
+ void updateBits() {
+ writeBits();
+
+ CurrentIndex = RecordRef.size();
+ RecordRef.push_back(0);
+ }
+
+ private:
+ BitsPacker PackingBits;
+ ASTRecordWriter &RecordRef;
+ std::optional<unsigned> CurrentIndex;
+ };
+
+ PakedBitsWriter CurrentPackingBits;
+
public:
ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
: Writer(Writer), Record(Writer, Record),
- Code(serialization::STMT_NULL_PTR), AbbrevToUse(0) {}
+ Code(serialization::STMT_NULL_PTR), AbbrevToUse(0),
+ CurrentPackingBits(this->Record) {}
ASTStmtWriter(const ASTStmtWriter&) = delete;
ASTStmtWriter &operator=(const ASTStmtWriter &) = delete;
uint64_t Emit() {
+ CurrentPackingBits.writeBits();
assert(Code != serialization::STMT_NULL_PTR &&
"unhandled sub-statement writing AST file");
return Record.EmitStmt(Code, AbbrevToUse);
@@ -82,14 +137,20 @@ void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
VisitStmt(S);
+
Record.push_back(S->size());
Record.push_back(S->hasStoredFPFeatures());
+
for (auto *CS : S->body())
Record.AddStmt(CS);
if (S->hasStoredFPFeatures())
Record.push_back(S->getStoredFPFeatures().getAsOpaqueInt());
Record.AddSourceLocation(S->getLBracLoc());
Record.AddSourceLocation(S->getRBracLoc());
+
+ if (!S->hasStoredFPFeatures())
+ AbbrevToUse = Writer.getCompoundStmtAbbrev();
+
Code = serialization::STMT_COMPOUND;
}
@@ -143,9 +204,11 @@ void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
bool HasInit = S->getInit() != nullptr;
- Record.push_back(HasElse);
- Record.push_back(HasVar);
- Record.push_back(HasInit);
+ CurrentPackingBits.updateBits();
+
+ CurrentPackingBits.addBit(HasElse);
+ CurrentPackingBits.addBit(HasVar);
+ CurrentPackingBits.addBit(HasInit);
Record.push_back(static_cast<uint64_t>(S->getStatementKind()));
Record.AddStmt(S->getCond());
Record.AddStmt(S->getThen());
@@ -548,15 +611,13 @@ void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
void ASTStmtWriter::VisitExpr(Expr *E) {
VisitStmt(E);
- Record.AddTypeRef(E->getType());
- BitsPacker ExprBits;
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBits(E->getDependence(), /*BitsWidth=*/5);
+ CurrentPackingBits.addBits(E->getValueKind(), /*BitsWidth=*/2);
+ CurrentPackingBits.addBits(E->getObjectKind(), /*BitsWidth=*/3);
- ExprBits.addBits(E->getDependence(), /*BitsWidth=*/5);
- ExprBits.addBits(E->getValueKind(), /*BitsWidth=*/2);
- ExprBits.addBits(E->getObjectKind(), /*BitsWidth=*/3);
-
- Record.push_back(ExprBits);
+ Record.AddTypeRef(E->getType());
}
void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
@@ -612,13 +673,15 @@ void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
VisitExpr(E);
- Record.push_back(E->hasQualifier());
- Record.push_back(E->getDecl() != E->getFoundDecl());
- Record.push_back(E->hasTemplateKWAndArgsInfo());
- Record.push_back(E->hadMultipleCandidates());
- Record.push_back(E->refersToEnclosingVariableOrCapture());
- Record.push_back(E->isNonOdrUse());
- Record.push_back(E->isImmediateEscalating());
+ CurrentPackingBits.updateBits();
+
+ CurrentPackingBits.addBit(E->hadMultipleCandidates());
+ CurrentPackingBits.addBit(E->refersToEnclosingVariableOrCapture());
+ CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
+ CurrentPackingBits.addBit(E->isImmediateEscalating());
+ CurrentPackingBits.addBit(E->getDecl() != E->getFoundDecl());
+ CurrentPackingBits.addBit(E->hasQualifier());
+ CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
if (E->hasTemplateKWAndArgsInfo()) {
unsigned NumTemplateArgs = E->getNumTemplateArgs();
@@ -629,9 +692,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
(E->getDecl() == E->getFoundDecl()) &&
- nk == DeclarationName::Identifier &&
- !E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse() &&
- !E->isImmediateEscalating()) {
+ nk == DeclarationName::Identifier && E->getObjectKind() == OK_Ordinary) {
AbbrevToUse = Writer.getDeclRefExprAbbrev();
}
@@ -742,11 +803,13 @@ void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
bool HasFPFeatures = E->hasStoredFPFeatures();
// Write this first for easy access when deserializing, as they affect the
// size of the UnaryOperator.
- Record.push_back(HasFPFeatures);
+ CurrentPackingBits.addBit(HasFPFeatures);
Record.AddStmt(E->getSubExpr());
- Record.push_back(E->getOpcode()); // FIXME: stable encoding
+ CurrentPackingBits.addBits(E->getOpcode(),
+ /*Width=*/5); // FIXME: stable encoding
Record.AddSourceLocation(E->getOperatorLoc());
- Record.push_back(E->canOverflow());
+ CurrentPackingBits.addBit(E->canOverflow());
+
if (HasFPFeatures)
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
Code = serialization::EXPR_UNARY_OPERATOR;
@@ -872,12 +935,10 @@ void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) {
void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
VisitExpr(E);
- BitsPacker CallExprBits;
- // 16 bits should be sufficient to store the number args;
- CallExprBits.addBits(E->getNumArgs(), /*BitsWidth=*/16);
- CallExprBits.addBit(E->hasStoredFPFeatures());
- CallExprBits.addBit(static_cast<bool>(E->getADLCallKind()));
- Record.push_back(CallExprBits);
+ Record.push_back(E->getNumArgs());
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBit(static_cast<bool>(E->getADLCallKind()));
+ CurrentPackingBits.addBit(E->hasStoredFPFeatures());
Record.AddSourceLocation(E->getRParenLoc());
Record.AddStmt(E->getCallee());
@@ -887,6 +948,11 @@ void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
if (E->hasStoredFPFeatures())
Record.push_back(E->getFPFeatures().getAsOpaqueInt());
+
+ if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()) &&
+ E->getStmtClass() == Stmt::CallExprClass)
+ AbbrevToUse = Writer.getCallExprAbbrev();
+
Code = serialization::EXPR_CALL;
}
@@ -913,9 +979,10 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
// Write these first for easy access when deserializing, as they affect the
// size of the MemberExpr.
- Record.push_back(HasQualifier);
- Record.push_back(HasFoundDecl);
- Record.push_back(HasTemplateInfo);
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBit(HasQualifier);
+ CurrentPackingBits.addBit(HasFoundDecl);
+ CurrentPackingBits.addBit(HasTemplateInfo);
Record.push_back(NumTemplateArgs);
Record.AddStmt(E->getBase());
@@ -923,15 +990,15 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
Record.AddDeclarationNameLoc(E->MemberDNLoc,
E->getMemberDecl()->getDeclName());
Record.AddSourceLocation(E->getMemberLoc());
- Record.push_back(E->isArrow());
- Record.push_back(E->hadMultipleCandidates());
- Record.push_back(E->isNonOdrUse());
+ CurrentPackingBits.addBit(E->isArrow());
+ CurrentPackingBits.addBit(E->hadMultipleCandidates());
+ CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
Record.AddSourceLocation(E->getOperatorLoc());
if (HasFoundDecl) {
DeclAccessPair FoundDecl = E->getFoundDecl();
Record.AddDeclRef(FoundDecl.getDecl());
- Record.push_back(FoundDecl.getAccess());
+ CurrentPackingBits.addBits(FoundDecl.getAccess(), /*BitWidth=*/2);
}
if (HasQualifier)
@@ -971,10 +1038,13 @@ void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
VisitExpr(E);
+
Record.push_back(E->path_size());
- Record.push_back(E->hasStoredFPFeatures());
+ CurrentPackingBits.updateBits();
+ // 7 bits should be enough to store the casting kinds.
+ CurrentPackingBits.addBits(E->getCastKind(), /*Width=*/7);
+ CurrentPackingBits.addBit(E->hasStoredFPFeatures());
Record.AddStmt(E->getSubExpr());
- Record.push_back(E->getCastKind()); // FIXME: stable encoding
for (CastExpr::path_iterator
PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
@@ -986,16 +1056,23 @@ void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
VisitExpr(E);
- bool HasFPFeatures = E->hasStoredFPFeatures();
+
// Write this first for easy access when deserializing, as they affect the
// size of the UnaryOperator.
- Record.push_back(HasFPFeatures);
- Record.push_back(E->getOpcode()); // FIXME: stable encoding
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBits(E->getOpcode(), /*Width=*/6);
+ bool HasFPFeatures = E->hasStoredFPFeatures();
+ CurrentPackingBits.addBit(HasFPFeatures);
Record.AddStmt(E->getLHS());
Record.AddStmt(E->getRHS());
Record.AddSourceLocation(E->getOperatorLoc());
if (HasFPFeatures)
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
+
+ if (!HasFPFeatures && E->getValueKind() == VK_PRValue &&
+ E->getObjectKind() == OK_Ordinary)
+ AbbrevToUse = Writer.getBinaryOperatorAbbrev();
+
Code = serialization::EXPR_BINARY_OPERATOR;
}
@@ -1003,6 +1080,11 @@ void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
VisitBinaryOperator(E);
Record.AddTypeRef(E->getComputationLHSType());
Record.AddTypeRef(E->getComputationResultType());
+
+ if (!E->hasStoredFPFeatures() && E->getValueKind() == VK_PRValue &&
+ E->getObjectKind() == OK_Ordinary)
+ AbbrevToUse = Writer.getCompoundAssignOperatorAbbrev();
+
Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
}
@@ -1031,7 +1113,7 @@ ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
VisitCastExpr(E);
- Record.push_back(E->isPartOfExplicitCast());
+ CurrentPackingBits.addBit(E->isPartOfExplicitCast());
if (E->path_size() == 0 && !E->hasStoredFPFeatures())
AbbrevToUse = Writer.getExprImplicitCastAbbrev();
@@ -1588,11 +1670,19 @@ void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
VisitCallExpr(E);
Record.push_back(E->getOperator());
Record.AddSourceRange(E->Range);
+
+ if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()))
+ AbbrevToUse = Writer.getCXXOperatorCallExprAbbrev();
+
Code = serialization::EXPR_CXX_OPERATOR_CALL;
}
void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
VisitCallExpr(E);
+
+ if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()))
+ AbbrevToUse = Writer.getCXXMemberCallExprAbbrev();
+
Code = serialization::EXPR_CXX_MEMBER_CALL;
}
@@ -1673,7 +1763,9 @@ void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E)
void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
VisitExplicitCastExpr(E);
Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()));
- Record.AddSourceRange(E->getAngleBrackets());
+ CurrentPackingBits.addBit(E->getAngleBrackets().isValid());
+ if (E->getAngleBrackets().isValid())
+ Record.AddSourceRange(E->getAngleBrackets());
}
void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
@@ -1750,6 +1842,7 @@ void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
VisitExpr(E);
Record.AddSourceLocation(E->getLocation());
Record.push_back(E->isImplicit());
+
Code = serialization::EXPR_CXX_THIS;
}
@@ -1883,10 +1976,10 @@ void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
// Don't emit anything here (or if you do you will have to update
// the corresponding deserialization function).
-
- Record.push_back(E->hasTemplateKWAndArgsInfo());
Record.push_back(E->getNumTemplateArgs());
- Record.push_back(E->hasFirstQualifierFoundInScope());
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
+ CurrentPackingBits.addBit(E->hasFirstQualifierFoundInScope());
if (E->hasTemplateKWAndArgsInfo()) {
const ASTTemplateKWAndArgsInfo &ArgInfo =
@@ -1895,14 +1988,15 @@ void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
E->getTrailingObjects<TemplateArgumentLoc>());
}
- Record.push_back(E->isArrow());
- Record.AddSourceLocation(E->getOperatorLoc());
+ CurrentPackingBits.addBit(E->isArrow());
+
Record.AddTypeRef(E->getBaseType());
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
+ CurrentPackingBits.addBit(!E->isImplicitAccess());
if (!E->isImplicitAccess())
Record.AddStmt(E->getBase());
- else
- Record.AddStmt(nullptr);
+
+ Record.AddSourceLocation(E->getOperatorLoc());
if (E->hasFirstQualifierFoundInScope())
Record.AddDeclRef(E->getFirstQualifierFoundInScope());
@@ -1917,12 +2011,14 @@ ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
// emitted first.
+ CurrentPackingBits.addBit(
+ E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
- Record.push_back(E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) {
const ASTTemplateKWAndArgsInfo &ArgInfo =
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- Record.push_back(ArgInfo.NumTemplateArgs);
+ // 16 bits should be enought to store the number of args
+ CurrentPackingBits.addBits(ArgInfo.NumTemplateArgs, /*Width=*/16);
AddTemplateKWAndArgsInfo(ArgInfo,
E->getTrailingObjects<TemplateArgumentLoc>());
}
@@ -1949,19 +2045,16 @@ ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(E);
- BitsPacker OverloadExprBits;
- // 14 Bits should enough to store the number of decls.
- OverloadExprBits.addBits(E->getNumDecls(), /*BitWidth=*/14);
- OverloadExprBits.addBit(E->hasTemplateKWAndArgsInfo());
+ Record.push_back(E->getNumDecls());
+
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
if (E->hasTemplateKWAndArgsInfo()) {
const ASTTemplateKWAndArgsInfo &ArgInfo =
*E->getTrailingASTTemplateKWAndArgsInfo();
- // 14 Bits should enough to store the number of template args.
- OverloadExprBits.addBits(ArgInfo.NumTemplateArgs, /*BitWidth=*/14);
- Record.push_back(OverloadExprBits);
+ Record.push_back(ArgInfo.NumTemplateArgs);
AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
- } else
- Record.push_back(OverloadExprBits);
+ }
for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
OvE = E->decls_end();
@@ -1976,18 +2069,22 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
VisitOverloadExpr(E);
- Record.push_back(E->isArrow());
- Record.push_back(E->hasUnresolvedUsing());
- Record.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr);
- Record.AddTypeRef(E->getBaseType());
+ CurrentPackingBits.addBit(E->isArrow());
+ CurrentPackingBits.addBit(E->hasUnresolvedUsing());
+ CurrentPackingBits.addBit(!E->isImplicitAccess());
+ if (!E->isImplicitAccess())
+ Record.AddStmt(E->getBase());
+
Record.AddSourceLocation(E->getOperatorLoc());
+
+ Record.AddTypeRef(E->getBaseType());
Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
}
void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
VisitOverloadExpr(E);
- Record.push_back(E->requiresADL());
- Record.push_back(E->isOverloaded());
+ CurrentPackingBits.addBit(E->requiresADL());
+ CurrentPackingBits.addBit(E->isOverloaded());
Record.AddDeclRef(E->getNamingClass());
Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
}
@@ -2059,12 +2156,12 @@ void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
VisitExpr(E);
Record.AddDeclRef(E->getAssociatedDecl());
- Record.push_back(E->isReferenceParameter());
- Record.push_back(E->getIndex());
+ CurrentPackingBits.addBit(E->isReferenceParameter());
+ CurrentPackingBits.addBits(E->getIndex(), /*Width=*/12);
+ CurrentPackingBits.addBit((bool)E->getPackIndex());
if (auto PackIndex = E->getPackIndex())
Record.push_back(*PackIndex + 1);
- else
- Record.push_back(0);
+
Record.AddSourceLocation(E->getNameLoc());
Record.AddStmt(E->getReplacement());
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 925fc90e3554..254b36ed0396 100644
--- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -266,6 +266,8 @@ private:
{&StreamChecker::preFseek, &StreamChecker::evalFseek, 0}},
{{{"ftell"}, 1},
{&StreamChecker::preDefault, &StreamChecker::evalFtell, 0}},
+ {{{"fflush"}, 1},
+ {&StreamChecker::preFflush, &StreamChecker::evalFflush, 0}},
{{{"rewind"}, 1},
{&StreamChecker::preDefault, &StreamChecker::evalRewind, 0}},
{{{"fgetpos"}, 2},
@@ -360,6 +362,12 @@ private:
CheckerContext &C,
const StreamErrorState &ErrorKind) const;
+ void preFflush(const FnDescription *Desc, const CallEvent &Call,
+ CheckerContext &C) const;
+
+ void evalFflush(const FnDescription *Desc, const CallEvent &Call,
+ CheckerContext &C) const;
+
/// Check that the stream (in StreamVal) is not NULL.
/// If it can only be NULL a fatal error is emitted and nullptr returned.
/// Otherwise the return value is a new state where the stream is constrained
@@ -1191,6 +1199,84 @@ void StreamChecker::evalSetFeofFerror(const FnDescription *Desc,
C.addTransition(State);
}
+void StreamChecker::preFflush(const FnDescription *Desc, const CallEvent &Call,
+ CheckerContext &C) const {
+ ProgramStateRef State = C.getState();
+ SVal StreamVal = getStreamArg(Desc, Call);
+ std::optional<DefinedSVal> Stream = StreamVal.getAs<DefinedSVal>();
+ if (!Stream)
+ return;
+
+ ProgramStateRef StateNotNull, StateNull;
+ std::tie(StateNotNull, StateNull) =
+ C.getConstraintManager().assumeDual(State, *Stream);
+ if (StateNotNull && !StateNull)
+ ensureStreamOpened(StreamVal, C, StateNotNull);
+}
+
+void StreamChecker::evalFflush(const FnDescription *Desc, const CallEvent &Call,
+ CheckerContext &C) const {
+ ProgramStateRef State = C.getState();
+ SVal StreamVal = getStreamArg(Desc, Call);
+ std::optional<DefinedSVal> Stream = StreamVal.getAs<DefinedSVal>();
+ if (!Stream)
+ return;
+
+ // Skip if the stream can be both NULL and non-NULL.
+ ProgramStateRef StateNotNull, StateNull;
+ std::tie(StateNotNull, StateNull) =
+ C.getConstraintManager().assumeDual(State, *Stream);
+ if (StateNotNull && StateNull)
+ return;
+ if (StateNotNull && !StateNull)
+ State = StateNotNull;
+ else
+ State = StateNull;
+
+ const CallExpr *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
+ if (!CE)
+ return;
+
+ // `fflush` returns EOF on failure, otherwise returns 0.
+ ProgramStateRef StateFailed = bindInt(*EofVal, State, C, CE);
+ ProgramStateRef StateNotFailed = bindInt(0, State, C, CE);
+
+ // Clear error states if `fflush` returns 0, but retain their EOF flags.
+ auto ClearErrorInNotFailed = [&StateNotFailed, Desc](SymbolRef Sym,
+ const StreamState *SS) {
+ if (SS->ErrorState & ErrorFError) {
+ StreamErrorState NewES =
+ (SS->ErrorState & ErrorFEof) ? ErrorFEof : ErrorNone;
+ StreamState NewSS = StreamState::getOpened(Desc, NewES, false);
+ StateNotFailed = StateNotFailed->set<StreamMap>(Sym, NewSS);
+ }
+ };
+
+ if (StateNotNull && !StateNull) {
+ // Skip if the input stream's state is unknown, open-failed or closed.
+ if (SymbolRef StreamSym = StreamVal.getAsSymbol()) {
+ const StreamState *SS = State->get<StreamMap>(StreamSym);
+ if (SS) {
+ assert(SS->isOpened() && "Stream is expected to be opened");
+ ClearErrorInNotFailed(StreamSym, SS);
+ } else
+ return;
+ }
+ } else {
+ // Clear error states for all streams.
+ const StreamMapTy &Map = StateNotFailed->get<StreamMap>();
+ for (const auto &I : Map) {
+ SymbolRef Sym = I.first;
+ const StreamState &SS = I.second;
+ if (SS.isOpened())
+ ClearErrorInNotFailed(Sym, &SS);
+ }
+ }
+
+ C.addTransition(StateNotFailed);
+ C.addTransition(StateFailed);
+}
+
ProgramStateRef
StreamChecker::ensureStreamNonNull(SVal StreamVal, const Expr *StreamE,
CheckerContext &C,
diff --git a/contrib/llvm-project/clang/lib/Support/RISCVVIntrinsicUtils.cpp b/contrib/llvm-project/clang/lib/Support/RISCVVIntrinsicUtils.cpp
index bb9f7dc7e7e3..bf47461b59e0 100644
--- a/contrib/llvm-project/clang/lib/Support/RISCVVIntrinsicUtils.cpp
+++ b/contrib/llvm-project/clang/lib/Support/RISCVVIntrinsicUtils.cpp
@@ -1217,7 +1217,7 @@ raw_ostream &operator<<(raw_ostream &OS, const RVVIntrinsicRecord &Record) {
OS << (int)Record.PrototypeLength << ",";
OS << (int)Record.SuffixLength << ",";
OS << (int)Record.OverloadedSuffixSize << ",";
- OS << (int)Record.RequiredExtensions << ",";
+ OS << Record.RequiredExtensions << ",";
OS << (int)Record.TypeRangeMask << ",";
OS << (int)Record.Log2LMULMask << ",";
OS << (int)Record.NF << ",";