aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/AST')
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/APNumericStorage.h71
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/APValue.h16
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTConcept.h146
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTContext.h477
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTDiagnostic.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTDumper.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTFwd.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTImportError.h50
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTImporter.h52
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTImporterSharedState.h26
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTLambda.h20
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h67
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTStructuralEquivalence.h18
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTTypeTraits.h101
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h21
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h21
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Attr.h57
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/AttrIterator.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def3
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CXXInheritance.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def3
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CanonicalType.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CharUnits.h13
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Comment.h330
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentCommands.td113
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentHTMLTags.td6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentLexer.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentParser.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentSema.h24
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentVisitor.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h13
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Decl.h706
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclBase.h372
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclCXX.h462
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h13
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclFriend.h11
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclObjC.h156
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h34
-rwxr-xr-xcontrib/llvm-project/clang/include/clang/AST/DeclTemplate.h397
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclarationName.h46
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DependenceFlags.h24
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DependentDiagnostic.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Expr.h908
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExprCXX.h568
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h228
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExprObjC.h60
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/FormatString.h30
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h9
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h25
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/LambdaCapture.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/LocInfoType.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Mangle.h61
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h10
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/NSAPI.h16
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ODRDiagsEmitter.h203
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ODRHash.h17
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/OSLog.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h1744
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/OperationKinds.def9
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h20
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h85
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td158
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Randstruct.h35
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/RawCommentList.h29
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h468
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Redeclarable.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Stmt.h403
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/StmtCXX.h39
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/StmtObjC.h41
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h1145
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TemplateArgumentVisitor.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TemplateBase.h197
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TemplateName.h169
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h17
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Type.h1137
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TypeLoc.h316
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TypeOrdering.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TypeProperties.td118
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h4
97 files changed, 8795 insertions, 3527 deletions
diff --git a/contrib/llvm-project/clang/include/clang/AST/APNumericStorage.h b/contrib/llvm-project/clang/include/clang/AST/APNumericStorage.h
new file mode 100644
index 000000000000..95eddbcd86e8
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/AST/APNumericStorage.h
@@ -0,0 +1,71 @@
+//===--- APNumericStorage.h - Store APInt/APFloat in ASTContext -*- 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_AST_APNUMERICSTORAGE_H
+#define LLVM_CLANG_AST_APNUMERICSTORAGE_H
+
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+
+namespace clang {
+class ASTContext;
+
+/// Used by IntegerLiteral/FloatingLiteral/EnumConstantDecl to store the
+/// numeric without leaking memory.
+///
+/// For large floats/integers, APFloat/APInt will allocate memory from the heap
+/// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator
+/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
+/// the APFloat/APInt values will never get freed. APNumericStorage uses
+/// ASTContext's allocator for memory allocation.
+class APNumericStorage {
+ union {
+ uint64_t VAL; ///< Used to store the <= 64 bits integer value.
+ uint64_t *pVal; ///< Used to store the >64 bits integer value.
+ };
+ unsigned BitWidth;
+
+ bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
+
+ APNumericStorage(const APNumericStorage &) = delete;
+ void operator=(const APNumericStorage &) = delete;
+
+protected:
+ APNumericStorage() : VAL(0), BitWidth(0) {}
+
+ llvm::APInt getIntValue() const {
+ unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
+ if (NumWords > 1)
+ return llvm::APInt(BitWidth, NumWords, pVal);
+ else
+ return llvm::APInt(BitWidth, VAL);
+ }
+ void setIntValue(const ASTContext &C, const llvm::APInt &Val);
+};
+
+class APIntStorage : private APNumericStorage {
+public:
+ llvm::APInt getValue() const { return getIntValue(); }
+ void setValue(const ASTContext &C, const llvm::APInt &Val) {
+ setIntValue(C, Val);
+ }
+};
+
+class APFloatStorage : private APNumericStorage {
+public:
+ llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
+ return llvm::APFloat(Semantics, getIntValue());
+ }
+ void setValue(const ASTContext &C, const llvm::APFloat &Val) {
+ setIntValue(C, Val.bitcastToAPInt());
+ }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_APNUMERICSTORAGE_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/APValue.h b/contrib/llvm-project/clang/include/clang/AST/APValue.h
index 5f4ac02f53c9..c4206b73b115 100644
--- a/contrib/llvm-project/clang/include/clang/AST/APValue.h
+++ b/contrib/llvm-project/clang/include/clang/AST/APValue.h
@@ -238,7 +238,7 @@ public:
}
};
class LValuePathSerializationHelper {
- const void *ElemTy;
+ const void *Ty;
public:
ArrayRef<LValuePathEntry> Path;
@@ -267,15 +267,19 @@ private:
};
struct LV;
struct Vec {
- APValue *Elts;
- unsigned NumElts;
- Vec() : Elts(nullptr), NumElts(0) {}
+ APValue *Elts = nullptr;
+ unsigned NumElts = 0;
+ Vec() = default;
+ Vec(const Vec &) = delete;
+ Vec &operator=(const Vec &) = delete;
~Vec() { delete[] Elts; }
};
struct Arr {
APValue *Elts;
unsigned NumElts, ArrSize;
Arr(unsigned NumElts, unsigned ArrSize);
+ Arr(const Arr &) = delete;
+ Arr &operator=(const Arr &) = delete;
~Arr();
};
struct StructData {
@@ -283,12 +287,16 @@ private:
unsigned NumBases;
unsigned NumFields;
StructData(unsigned NumBases, unsigned NumFields);
+ StructData(const StructData &) = delete;
+ StructData &operator=(const StructData &) = delete;
~StructData();
};
struct UnionData {
const FieldDecl *Field;
APValue *Value;
UnionData();
+ UnionData(const UnionData &) = delete;
+ UnionData &operator=(const UnionData &) = delete;
~UnionData();
};
struct AddrLabelDiffData {
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h b/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h
index d0526f4fa5c5..5f9aa41d3e6c 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h
@@ -1,9 +1,8 @@
//===--- ASTConcept.h - Concepts Related AST Data Structures ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
///
@@ -15,15 +14,21 @@
#ifndef LLVM_CLANG_AST_ASTCONCEPT_H
#define LLVM_CLANG_AST_ASTCONCEPT_H
-#include "clang/AST/Expr.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include <utility>
namespace clang {
+
class ConceptDecl;
-class ConceptSpecializationExpr;
+class Expr;
+class NamedDecl;
+struct PrintingPolicy;
/// The result of a constraint satisfaction check, containing the necessary
/// information to diagnose an unsatisfied constraint.
@@ -46,6 +51,7 @@ public:
using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;
bool IsSatisfied = false;
+ bool ContainsErrors = false;
/// \brief Pairs of unsatisfied atomic constraint expressions along with the
/// substituted constraint expr, if the template arguments could be
@@ -60,6 +66,13 @@ public:
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
const NamedDecl *ConstraintOwner,
ArrayRef<TemplateArgument> TemplateArgs);
+
+ bool HasSubstitutionFailure() {
+ for (const auto &Detail : Details)
+ if (Detail.second.dyn_cast<SubstitutionDiagnostic *>())
+ return true;
+ return false;
+ }
};
/// Pairs of unsatisfied atomic constraint expressions along with the
@@ -80,6 +93,7 @@ struct ASTConstraintSatisfaction final :
UnsatisfiedConstraintRecord> {
std::size_t NumRecords;
bool IsSatisfied : 1;
+ bool ContainsErrors : 1;
const UnsatisfiedConstraintRecord *begin() const {
return getTrailingObjects<UnsatisfiedConstraintRecord>();
@@ -91,15 +105,27 @@ struct ASTConstraintSatisfaction final :
ASTConstraintSatisfaction(const ASTContext &C,
const ConstraintSatisfaction &Satisfaction);
+ ASTConstraintSatisfaction(const ASTContext &C,
+ const ASTConstraintSatisfaction &Satisfaction);
static ASTConstraintSatisfaction *
Create(const ASTContext &C, const ConstraintSatisfaction &Satisfaction);
+ static ASTConstraintSatisfaction *
+ Rebuild(const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction);
};
-/// \brief Common data class for constructs that reference concepts with
-/// template arguments.
+/// A reference to a concept and its template args, as it appears in the code.
+///
+/// Examples:
+/// template <int X> requires is_even<X> int half = X/2;
+/// ~~~~~~~~~~ (in ConceptSpecializationExpr)
+///
+/// std::input_iterator auto I = Container.begin();
+/// ~~~~~~~~~~~~~~~~~~~ (in AutoTypeLoc)
+///
+/// template <std::derives_from<Expr> T> void dump();
+/// ~~~~~~~~~~~~~~~~~~~~~~~ (in TemplateTypeParmDecl)
class ConceptReference {
-protected:
// \brief The optional nested name specifier used when naming the concept.
NestedNameSpecifierLoc NestedNameSpec;
@@ -123,18 +149,20 @@ protected:
/// concept.
const ASTTemplateArgumentListInfo *ArgsAsWritten;
-public:
-
ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten) :
- NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
- ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
- NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
+ const ASTTemplateArgumentListInfo *ArgsAsWritten)
+ : NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
+ ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
+ NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
- ConceptReference() : NestedNameSpec(), TemplateKWLoc(), ConceptName(),
- FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {}
+public:
+ static ConceptReference *
+ Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
+ SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
+ NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
+ const ASTTemplateArgumentListInfo *ArgsAsWritten);
const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
return NestedNameSpec;
@@ -148,6 +176,26 @@ public:
SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
+ SourceLocation getLocation() const { return getConceptNameLoc(); }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ // Note that if the qualifier is null the template KW must also be null.
+ if (auto QualifierLoc = getNestedNameSpecifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return getConceptNameInfo().getBeginLoc();
+ }
+
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getTemplateArgsAsWritten() &&
+ getTemplateArgsAsWritten()->getRAngleLoc().isValid()
+ ? getTemplateArgsAsWritten()->getRAngleLoc()
+ : getConceptNameInfo().getEndLoc();
+ }
+
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return SourceRange(getBeginLoc(), getEndLoc());
+ }
+
NamedDecl *getFoundDecl() const {
return FoundDecl;
}
@@ -165,22 +213,32 @@ public:
bool hasExplicitTemplateArgs() const {
return ArgsAsWritten != nullptr;
}
+
+ void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
+ void dump() const;
+ void dump(llvm::raw_ostream &) const;
};
-class TypeConstraint : public ConceptReference {
+/// Models the abbreviated syntax to constrain a template type parameter:
+/// template <convertible_to<string> T> void print(T object);
+/// ~~~~~~~~~~~~~~~~~~~~~~
+/// Semantically, this adds an "immediately-declared constraint" with extra arg:
+/// requires convertible_to<T, string>
+///
+/// In the C++ grammar, a type-constraint is also used for auto types:
+/// convertible_to<string> auto X = ...;
+/// We do *not* model these as TypeConstraints, but AutoType(Loc) directly.
+class TypeConstraint {
/// \brief The immediately-declared constraint expression introduced by this
/// type-constraint.
Expr *ImmediatelyDeclaredConstraint = nullptr;
+ ConceptReference *ConceptRef;
public:
- TypeConstraint(NestedNameSpecifierLoc NNS,
- DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
- ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- Expr *ImmediatelyDeclaredConstraint) :
- ConceptReference(NNS, /*TemplateKWLoc=*/SourceLocation(), ConceptNameInfo,
- FoundDecl, NamedConcept, ArgsAsWritten),
- ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint) {}
+ TypeConstraint(ConceptReference *ConceptRef,
+ Expr *ImmediatelyDeclaredConstraint)
+ : ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint),
+ ConceptRef(ConceptRef) {}
/// \brief Get the immediately-declared constraint expression introduced by
/// this type-constraint, that is - the constraint expression that is added to
@@ -189,7 +247,41 @@ public:
return ImmediatelyDeclaredConstraint;
}
- void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const;
+ ConceptReference *getConceptReference() const { return ConceptRef; }
+
+ // FIXME: Instead of using these concept related functions the callers should
+ // directly work with the corresponding ConceptReference.
+ ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); }
+
+ SourceLocation getConceptNameLoc() const {
+ return ConceptRef->getConceptNameLoc();
+ }
+
+ bool hasExplicitTemplateArgs() const {
+ return ConceptRef->hasExplicitTemplateArgs();
+ }
+
+ const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
+ return ConceptRef->getTemplateArgsAsWritten();
+ }
+
+ SourceLocation getTemplateKWLoc() const {
+ return ConceptRef->getTemplateKWLoc();
+ }
+
+ NamedDecl *getFoundDecl() const { return ConceptRef->getFoundDecl(); }
+
+ const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
+ return ConceptRef->getNestedNameSpecifierLoc();
+ }
+
+ const DeclarationNameInfo &getConceptNameInfo() const {
+ return ConceptRef->getConceptNameInfo();
+ }
+
+ void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {
+ ConceptRef->print(OS, Policy);
+ }
};
} // clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h b/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h
index ecdd8e873e1e..ebcd8059284d 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h
@@ -33,12 +33,12 @@ namespace clang {
class ASTConsumer {
/// Whether this AST consumer also requires information about
/// semantic analysis.
- bool SemaConsumer;
+ bool SemaConsumer = false;
friend class SemaConsumer;
public:
- ASTConsumer() : SemaConsumer(false) { }
+ ASTConsumer() = default;
virtual ~ASTConsumer() {}
@@ -76,7 +76,7 @@ public:
virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {}
/// Invoked when a function is implicitly instantiated.
- /// Note that at this point point it does not have a body, its body is
+ /// Note that at this point it does not have a body, its body is
/// instantiated at the end of the translation unit and passed to
/// HandleTopLevelDecl.
virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTContext.h b/contrib/llvm-project/clang/include/clang/AST/ASTContext.h
index 34299581d89d..3e46a5da3fc0 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTContext.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTContext.h
@@ -14,65 +14,32 @@
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
#define LLVM_CLANG_AST_ASTCONTEXT_H
-#include "clang/AST/ASTContextAllocate.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/ComparisonCategories.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RawCommentList.h"
#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/AttrKinds.h"
-#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/Linkage.h"
-#include "clang/Basic/NoSanitizeList.h"
-#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/ProfileList.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/TargetCXXABI.h"
-#include "clang/Basic/XRayLists.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/TypeSize.h"
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <iterator>
-#include <memory>
-#include <string>
-#include <type_traits>
-#include <utility>
-#include <vector>
+#include <optional>
namespace llvm {
@@ -90,6 +57,7 @@ class ASTMutationListener;
class ASTRecordLayout;
class AtomicExpr;
class BlockExpr;
+struct BlockVarCopyInit;
class BuiltinTemplateDecl;
class CharUnits;
class ConceptDecl;
@@ -98,18 +66,19 @@ class CXXConstructorDecl;
class CXXMethodDecl;
class CXXRecordDecl;
class DiagnosticsEngine;
-class ParentMapContext;
-class DynTypedNode;
class DynTypedNodeList;
class Expr;
+enum class FloatModeKind;
class GlobalDecl;
-class ItaniumMangleContext;
+class IdentifierTable;
+class LangOptions;
class MangleContext;
class MangleNumberingContext;
-class MaterializeTemporaryExpr;
class MemberSpecializationInfo;
class Module;
struct MSGuidDeclParts;
+class NestedNameSpecifier;
+class NoSanitizeList;
class ObjCCategoryDecl;
class ObjCCategoryImplDecl;
class ObjCContainerDecl;
@@ -123,9 +92,10 @@ class ObjCPropertyImplDecl;
class ObjCProtocolDecl;
class ObjCTypeParamDecl;
class OMPTraitInfo;
+class ParentMapContext;
struct ParsedTargetAttr;
class Preprocessor;
-class Stmt;
+class ProfileList;
class StoredDeclsMap;
class TargetAttr;
class TargetInfo;
@@ -133,11 +103,12 @@ class TemplateDecl;
class TemplateParameterList;
class TemplateTemplateParmDecl;
class TemplateTypeParmDecl;
+class TypeConstraint;
class UnresolvedSetIterator;
class UsingShadowDecl;
class VarTemplateDecl;
class VTableContextBase;
-struct BlockVarCopyInit;
+class XRayFunctionFilter;
namespace Builtin {
@@ -164,24 +135,46 @@ namespace serialization {
template <class> class AbstractTypeReader;
} // namespace serialization
+enum class AlignRequirementKind {
+ /// The alignment was not explicit in code.
+ None,
+
+ /// The alignment comes from an alignment attribute on a typedef.
+ RequiredByTypedef,
+
+ /// The alignment comes from an alignment attribute on a record type.
+ RequiredByRecord,
+
+ /// The alignment comes from an alignment attribute on a enum type.
+ RequiredByEnum,
+};
+
struct TypeInfo {
uint64_t Width = 0;
unsigned Align = 0;
- bool AlignIsRequired : 1;
+ AlignRequirementKind AlignRequirement;
- TypeInfo() : AlignIsRequired(false) {}
- TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
- : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
+ TypeInfo() : AlignRequirement(AlignRequirementKind::None) {}
+ TypeInfo(uint64_t Width, unsigned Align,
+ AlignRequirementKind AlignRequirement)
+ : Width(Width), Align(Align), AlignRequirement(AlignRequirement) {}
+ bool isAlignRequired() {
+ return AlignRequirement != AlignRequirementKind::None;
+ }
};
struct TypeInfoChars {
CharUnits Width;
CharUnits Align;
- bool AlignIsRequired : 1;
+ AlignRequirementKind AlignRequirement;
- TypeInfoChars() : AlignIsRequired(false) {}
- TypeInfoChars(CharUnits Width, CharUnits Align, bool AlignIsRequired)
- : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
+ TypeInfoChars() : AlignRequirement(AlignRequirementKind::None) {}
+ TypeInfoChars(CharUnits Width, CharUnits Align,
+ AlignRequirementKind AlignRequirement)
+ : Width(Width), Align(Align), AlignRequirement(AlignRequirement) {}
+ bool isAlignRequired() {
+ return AlignRequirement != AlignRequirementKind::None;
+ }
};
/// Holds long-lived AST nodes (such as types and decls) that can be
@@ -192,7 +185,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable SmallVector<Type *, 0> Types;
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
mutable llvm::FoldingSet<ComplexType> ComplexTypes;
- mutable llvm::FoldingSet<PointerType> PointerTypes;
+ mutable llvm::FoldingSet<PointerType> PointerTypes{GeneralTypesLog2InitSize};
mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
@@ -202,20 +195,25 @@ class ASTContext : public RefCountedBase<ASTContext> {
ConstantArrayTypes;
mutable llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
mutable std::vector<VariableArrayType*> VariableArrayTypes;
- mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
- mutable llvm::FoldingSet<DependentSizedExtVectorType>
- DependentSizedExtVectorTypes;
- mutable llvm::FoldingSet<DependentAddressSpaceType>
+ mutable llvm::ContextualFoldingSet<DependentSizedArrayType, ASTContext &>
+ DependentSizedArrayTypes;
+ mutable llvm::ContextualFoldingSet<DependentSizedExtVectorType, ASTContext &>
+ DependentSizedExtVectorTypes;
+ mutable llvm::ContextualFoldingSet<DependentAddressSpaceType, ASTContext &>
DependentAddressSpaceTypes;
mutable llvm::FoldingSet<VectorType> VectorTypes;
- mutable llvm::FoldingSet<DependentVectorType> DependentVectorTypes;
+ mutable llvm::ContextualFoldingSet<DependentVectorType, ASTContext &>
+ DependentVectorTypes;
mutable llvm::FoldingSet<ConstantMatrixType> MatrixTypes;
- mutable llvm::FoldingSet<DependentSizedMatrixType> DependentSizedMatrixTypes;
+ mutable llvm::ContextualFoldingSet<DependentSizedMatrixType, ASTContext &>
+ DependentSizedMatrixTypes;
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
FunctionProtoTypes;
- mutable llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
- mutable llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
+ mutable llvm::ContextualFoldingSet<DependentTypeOfExprType, ASTContext &>
+ DependentTypeOfExprTypes;
+ mutable llvm::ContextualFoldingSet<DependentDecltypeType, ASTContext &>
+ DependentDecltypeTypes;
mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
mutable llvm::FoldingSet<ObjCTypeParamType> ObjCTypeParamTypes;
mutable llvm::FoldingSet<SubstTemplateTypeParmType>
@@ -224,8 +222,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
SubstTemplateTypeParmPackTypes;
mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
TemplateSpecializationTypes;
- mutable llvm::FoldingSet<ParenType> ParenTypes;
- mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
+ mutable llvm::FoldingSet<ParenType> ParenTypes{GeneralTypesLog2InitSize};
+ mutable llvm::FoldingSet<UsingType> UsingTypes;
+ mutable llvm::FoldingSet<TypedefType> TypedefTypes;
+ mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes{
+ GeneralTypesLog2InitSize};
mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
ASTContext&>
@@ -239,10 +240,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
DeducedTemplateSpecializationTypes;
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
- llvm::FoldingSet<AttributedType> AttributedTypes;
+ mutable llvm::FoldingSet<AttributedType> AttributedTypes;
mutable llvm::FoldingSet<PipeType> PipeTypes;
- mutable llvm::FoldingSet<ExtIntType> ExtIntTypes;
- mutable llvm::FoldingSet<DependentExtIntType> DependentExtIntTypes;
+ mutable llvm::FoldingSet<BitIntType> BitIntTypes;
+ mutable llvm::ContextualFoldingSet<DependentBitIntType, ASTContext &>
+ DependentBitIntTypes;
+ llvm::FoldingSet<BTFTagAttributedType> BTFTagAttributedTypes;
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
@@ -292,6 +295,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Mapping from GUIDs to the corresponding MSGuidDecl.
mutable llvm::FoldingSet<MSGuidDecl> MSGuidDecls;
+ /// Mapping from APValues to the corresponding UnnamedGlobalConstantDecl.
+ mutable llvm::FoldingSet<UnnamedGlobalConstantDecl>
+ UnnamedGlobalConstantDecls;
+
/// Mapping from APValues to the corresponding TemplateParamObjects.
mutable llvm::FoldingSet<TemplateParamObjectDecl> TemplateParamObjectDecls;
@@ -446,6 +453,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
};
llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers;
+ /// This is the top-level (C++20) Named module we are building.
+ Module *CurrentCXXNamedModule = nullptr;
+
+ static constexpr unsigned ConstantArrayTypesLog2InitSize = 8;
+ static constexpr unsigned GeneralTypesLog2InitSize = 9;
+ static constexpr unsigned FunctionProtoTypesLog2InitSize = 12;
+
ASTContext &this_() { return *this; }
public:
@@ -605,9 +619,6 @@ private:
std::unique_ptr<CXXABI> ABI;
CXXABI *createCXXABI(const TargetInfo &T);
- /// The logical -> physical address space map.
- const LangASMap *AddrSpaceMap = nullptr;
-
/// Address space map mangling must be used with language specific
/// address spaces (e.g. OpenCL/CUDA)
bool AddrSpaceMapMangling;
@@ -633,6 +644,20 @@ public:
/// Returns the clang bytecode interpreter context.
interp::Context &getInterpContext();
+ struct CUDAConstantEvalContext {
+ /// Do not allow wrong-sided variables in constant expressions.
+ bool NoWrongSidedVars = false;
+ } CUDAConstantEvalCtx;
+ struct CUDAConstantEvalContextRAII {
+ ASTContext &Ctx;
+ CUDAConstantEvalContext SavedCtx;
+ CUDAConstantEvalContextRAII(ASTContext &Ctx_, bool NoWrongSidedVars)
+ : Ctx(Ctx_), SavedCtx(Ctx_.CUDAConstantEvalCtx) {
+ Ctx_.CUDAConstantEvalCtx.NoWrongSidedVars = NoWrongSidedVars;
+ }
+ ~CUDAConstantEvalContextRAII() { Ctx.CUDAConstantEvalCtx = SavedCtx; }
+ };
+
/// Returns the dynamic AST node parent map context.
ParentMapContext &getParentMapContext();
@@ -672,6 +697,12 @@ public:
SourceManager& getSourceManager() { return SourceMgr; }
const SourceManager& getSourceManager() const { return SourceMgr; }
+ // Cleans up some of the data structures. This allows us to do cleanup
+ // normally done in the destructor earlier. Renders much of the ASTContext
+ // unusable, mostly the actual AST nodes, so should be called when we no
+ // longer need access to the AST.
+ void cleanup();
+
llvm::BumpPtrAllocator &getAllocator() const {
return BumpAlloc;
}
@@ -728,7 +759,8 @@ public:
/// getRealTypeForBitwidth -
/// sets floating point QualTy according to specified bitwidth.
/// Returns empty type if there is no appropriate target types.
- QualType getRealTypeForBitwidth(unsigned DestWidth, bool ExplicitIEEE) const;
+ QualType getRealTypeForBitwidth(unsigned DestWidth,
+ FloatModeKind ExplicitType) const;
bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;
@@ -1024,6 +1056,12 @@ public:
/// Get the initializations to perform when importing a module, if any.
ArrayRef<Decl*> getModuleInitializers(Module *M);
+ /// Set the (C++20) module we are building.
+ void setCurrentNamedModule(Module *M);
+
+ /// Get module under construction, nullptr if this is not a C++20 module.
+ Module *getCurrentNamedModule() const { return CurrentCXXNamedModule; }
+
TranslationUnitDecl *getTranslationUnitDecl() const {
return TUDecl->getMostRecentDecl();
}
@@ -1054,7 +1092,7 @@ public:
CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
- CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
+ CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty, Ibm128Ty;
CanQualType ShortAccumTy, AccumTy,
LongAccumTy; // ISO/IEC JTC1 SC22 WG14 N1169 Extension
CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy;
@@ -1069,8 +1107,6 @@ public:
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
CanQualType BFloat16Ty;
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
- CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
- CanQualType Float128ComplexTy;
CanQualType VoidPtrTy, NullPtrTy;
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
CanQualType BuiltinFnTy;
@@ -1096,6 +1132,8 @@ public:
#define RVV_TYPE(Name, Id, SingletonId) \
CanQualType SingletonId;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
@@ -1109,8 +1147,19 @@ public:
mutable TagDecl *MSGuidTagDecl = nullptr;
/// Keep track of CUDA/HIP device-side variables ODR-used by host code.
+ /// This does not include extern shared variables used by device host
+ /// functions as addresses of shared variables are per warp, therefore
+ /// cannot be accessed by host code.
llvm::DenseSet<const VarDecl *> CUDADeviceVarODRUsedByHost;
+ /// Keep track of CUDA/HIP external kernels or device variables ODR-used by
+ /// host code.
+ llvm::DenseSet<const ValueDecl *> CUDAExternalDeviceDeclODRUsedByHost;
+
+ /// Keep track of CUDA/HIP implicit host device functions used on device side
+ /// in device compilation.
+ llvm::DenseSet<const FunctionDecl *> CUDAImplicitHostDeviceFunUsedByDevice;
+
ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
SelectorTable &sels, Builtin::Context &builtins,
TranslationUnitKind TUKind);
@@ -1152,8 +1201,9 @@ public:
/// Create a new implicit TU-level CXXRecordDecl or RecordDecl
/// declaration.
- RecordDecl *buildImplicitRecord(StringRef Name,
- RecordDecl::TagKind TK = TTK_Struct) const;
+ RecordDecl *buildImplicitRecord(
+ StringRef Name,
+ RecordDecl::TagKind TK = RecordDecl::TagKind::Struct) const;
/// Create a new implicit TU-level typedef declaration.
TypedefDecl *buildImplicitTypedef(QualType T, StringRef Name) const;
@@ -1253,11 +1303,11 @@ public:
/// declaration of a function with an exception specification is permitted
/// and preserved. Other type sugar (for instance, typedefs) is not.
QualType getFunctionTypeWithExceptionSpec(
- QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI);
+ QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const;
/// Determine whether two function types are the same, ignoring
/// exception specifications in cases where they're part of the type.
- bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U);
+ bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U) const;
/// Change the exception specification on a function once it is
/// delay-parsed, instantiated, or computed.
@@ -1303,6 +1353,9 @@ public:
CanQualType getDecayedType(CanQualType T) const {
return CanQualType::CreateUnsafe(getDecayedType((QualType) T));
}
+ /// Return the uniqued reference to a specified decay from the original
+ /// type to the decayed type.
+ QualType getDecayedType(QualType Orig, QualType Decayed) const;
/// Return the uniqued reference to the atomic type for the specified
/// type.
@@ -1322,13 +1375,13 @@ public:
/// Return a write_only pipe type for the specified type.
QualType getWritePipeType(QualType T) const;
- /// Return an extended integer type with the specified signedness and bit
+ /// Return a bit-precise integer type with the specified signedness and bit
/// count.
- QualType getExtIntType(bool Unsigned, unsigned NumBits) const;
+ QualType getBitIntType(bool Unsigned, unsigned NumBits) const;
- /// Return a dependent extended integer type with the specified signedness and
- /// bit count.
- QualType getDependentExtIntType(bool Unsigned, Expr *BitsExpr) const;
+ /// Return a dependent bit-precise integer type with the specified signedness
+ /// and bit count.
+ QualType getDependentBitIntType(bool Unsigned, Expr *BitsExpr) const;
/// Gets the struct used to keep track of the extended descriptor for
/// pointer to blocks.
@@ -1340,6 +1393,12 @@ public:
/// Get address space for OpenCL type.
LangAS getOpenCLTypeAddrSpace(const Type *T) const;
+ /// Returns default address space based on OpenCL version and enabled features
+ inline LangAS getDefaultOpenCLPointeeAddrSpace() {
+ return LangOpts.OpenCLGenericAddressSpace ? LangAS::opencl_generic
+ : LangAS::opencl_private;
+ }
+
void setcudaConfigureCallDecl(FunctionDecl *FD) {
cudaConfigureCallDecl = FD;
}
@@ -1376,8 +1435,7 @@ public:
/// Return a non-unique reference to the type for a variable array of
/// the specified element type.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
- ArrayType::ArraySizeModifier ASM,
- unsigned IndexTypeQuals,
+ ArraySizeModifier ASM, unsigned IndexTypeQuals,
SourceRange Brackets) const;
/// Return a non-unique reference to the type for a dependently-sized
@@ -1386,21 +1444,19 @@ public:
/// FIXME: We will need these to be uniqued, or at least comparable, at some
/// point.
QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
- ArrayType::ArraySizeModifier ASM,
+ ArraySizeModifier ASM,
unsigned IndexTypeQuals,
SourceRange Brackets) const;
/// Return a unique reference to the type for an incomplete array of
/// the specified element type.
- QualType getIncompleteArrayType(QualType EltTy,
- ArrayType::ArraySizeModifier ASM,
+ QualType getIncompleteArrayType(QualType EltTy, ArraySizeModifier ASM,
unsigned IndexTypeQuals) const;
/// Return the unique reference to the type for a constant array of
/// the specified element type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
- const Expr *SizeExpr,
- ArrayType::ArraySizeModifier ASM,
+ const Expr *SizeExpr, ArraySizeModifier ASM,
unsigned IndexTypeQuals) const;
/// Return a type for a constant array for a string literal of the
@@ -1427,21 +1483,27 @@ public:
/// Return the unique reference to a scalable vector type of the specified
/// element type and scalable number of elements.
+ /// For RISC-V, number of fields is also provided when it fetching for
+ /// tuple type.
///
/// \pre \p EltTy must be a built-in type.
- QualType getScalableVectorType(QualType EltTy, unsigned NumElts) const;
+ QualType getScalableVectorType(QualType EltTy, unsigned NumElts,
+ unsigned NumFields = 1) const;
+
+ /// Return a WebAssembly externref type.
+ QualType getWebAssemblyExternrefType() const;
/// Return the unique reference to a vector type of the specified
/// element type and size.
///
/// \pre \p VectorType must be a built-in type.
QualType getVectorType(QualType VectorType, unsigned NumElts,
- VectorType::VectorKind VecKind) const;
+ VectorKind VecKind) const;
/// Return the unique reference to the type for a dependently sized vector of
/// the specified element type.
QualType getDependentVectorType(QualType VectorType, Expr *SizeExpr,
SourceLocation AttrLoc,
- VectorType::VectorKind VecKind) const;
+ VectorKind VecKind) const;
/// Return the unique reference to an extended vector type
/// of the specified element type and size.
@@ -1497,6 +1559,12 @@ private:
QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
const FunctionProtoType::ExtProtoInfo &EPI,
bool OnlyWantCanonical) const;
+ QualType
+ getAutoTypeInternal(QualType DeducedType, AutoTypeKeyword Keyword,
+ bool IsDependent, bool IsPack = false,
+ ConceptDecl *TypeConstraintConcept = nullptr,
+ ArrayRef<TemplateArgument> TypeConstraintArgs = {},
+ bool IsCanon = false) const;
public:
/// Return the unique reference to the type for the specified type
@@ -1515,6 +1583,9 @@ public:
return getTypeDeclTypeSlow(Decl);
}
+ QualType getUsingType(const UsingShadowDecl *Found,
+ QualType Underlying) const;
+
/// Return the unique reference to the type for the specified
/// typedef-name decl.
QualType getTypedefType(const TypedefNameDecl *Decl,
@@ -1524,16 +1595,23 @@ public:
QualType getEnumType(const EnumDecl *Decl) const;
+ QualType
+ getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const;
+
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
- QualType getAttributedType(attr::Kind attrKind,
- QualType modifiedType,
- QualType equivalentType);
+ QualType getAttributedType(attr::Kind attrKind, QualType modifiedType,
+ QualType equivalentType) const;
- QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
- QualType Replacement) const;
- QualType getSubstTemplateTypeParmPackType(
- const TemplateTypeParmType *Replaced,
+ QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
+ QualType Wrapped);
+
+ QualType
+ getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
+ unsigned Index,
+ std::optional<unsigned> PackIndex) const;
+ QualType getSubstTemplateTypeParmPackType(Decl *AssociatedDecl,
+ unsigned Index, bool Final,
const TemplateArgument &ArgPack);
QualType
@@ -1550,7 +1628,7 @@ public:
ArrayRef<TemplateArgument> Args) const;
QualType getTemplateSpecializationType(TemplateName T,
- const TemplateArgumentListInfo &Args,
+ ArrayRef<TemplateArgumentLoc> Args,
QualType Canon = QualType()) const;
TypeSourceInfo *
@@ -1571,10 +1649,9 @@ public:
const IdentifierInfo *Name,
QualType Canon = QualType()) const;
- QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- const TemplateArgumentListInfo &Args) const;
+ QualType getDependentTemplateSpecializationType(
+ ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name, ArrayRef<TemplateArgumentLoc> Args) const;
QualType getDependentTemplateSpecializationType(
ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;
@@ -1595,7 +1672,7 @@ public:
/// elsewhere, such as if the pattern contains a placeholder type or
/// if this is the canonical type of another pack expansion type.
QualType getPackExpansionType(QualType Pattern,
- Optional<unsigned> NumExpansions,
+ std::optional<unsigned> NumExpansions,
bool ExpectPackInType = true);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
@@ -1627,9 +1704,11 @@ public:
/// Return a ObjCObjectPointerType type for the given ObjCObjectType.
QualType getObjCObjectPointerType(QualType OIT) const;
- /// GCC extension.
- QualType getTypeOfExprType(Expr *e) const;
- QualType getTypeOfType(QualType t) const;
+ /// C23 feature and GCC extension.
+ QualType getTypeOfExprType(Expr *E, TypeOfKind Kind) const;
+ QualType getTypeOfType(QualType QT, TypeOfKind Kind) const;
+
+ QualType getReferenceQualifiedType(const Expr *e) const;
/// C++11 decltype.
QualType getDecltypeType(Expr *e, QualType UnderlyingType) const;
@@ -1650,6 +1729,10 @@ public:
/// C++11 deduction pattern for 'auto &&' type.
QualType getAutoRRefDeductType() const;
+ /// Remove any type constraints from a template parameter type, for
+ /// equivalence comparison of template parameters.
+ QualType getUnconstrainedType(QualType T) const;
+
/// C++17 deduced class template specialization type.
QualType getDeducedTemplateSpecializationType(TemplateName Template,
QualType DeducedType,
@@ -2106,16 +2189,20 @@ public:
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
bool TemplateKeyword,
- TemplateDecl *Template) const;
+ TemplateName Template) const;
TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
const IdentifierInfo *Name) const;
TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
OverloadedOperatorKind Operator) const;
- TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
- TemplateName replacement) const;
- TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
- const TemplateArgument &ArgPack) const;
+ TemplateName
+ getSubstTemplateTemplateParm(TemplateName replacement, Decl *AssociatedDecl,
+ unsigned Index,
+ std::optional<unsigned> PackIndex) const;
+ TemplateName getSubstTemplateTemplateParmPack(const TemplateArgument &ArgPack,
+ Decl *AssociatedDecl,
+ unsigned Index,
+ bool Final) const;
enum GetBuiltinTypeError {
/// No error
@@ -2179,6 +2266,17 @@ public:
/// false otherwise.
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType);
+ /// Return true if the given types are an RISC-V vector builtin type and a
+ /// VectorType that is a fixed-length representation of the RISC-V vector
+ /// builtin type for a specific vector-length.
+ bool areCompatibleRVVTypes(QualType FirstType, QualType SecondType);
+
+ /// Return true if the given vector types are lax-compatible RISC-V vector
+ /// types as defined by -flax-vector-conversions=, which permits implicit
+ /// conversions between vectors with different number of elements and/or
+ /// incompatible element types, false otherwise.
+ bool areLaxCompatibleRVVTypes(QualType FirstType, QualType SecondType);
+
/// Return true if the type has been explicitly qualified with ObjC ownership.
/// A type may be implicitly qualified with ownership under ObjC ARC, and in
/// some cases the compiler treats these differently.
@@ -2225,13 +2323,13 @@ public:
CharUnits getTypeSizeInChars(QualType T) const;
CharUnits getTypeSizeInChars(const Type *T) const;
- Optional<CharUnits> getTypeSizeInCharsIfKnown(QualType Ty) const {
+ std::optional<CharUnits> getTypeSizeInCharsIfKnown(QualType Ty) const {
if (Ty->isIncompleteType() || Ty->isDependentType())
- return None;
+ return std::nullopt;
return getTypeSizeInChars(Ty);
}
- Optional<CharUnits> getTypeSizeInCharsIfKnown(const Type *Ty) const {
+ std::optional<CharUnits> getTypeSizeInCharsIfKnown(const Type *Ty) const {
return getTypeSizeInCharsIfKnown(QualType(Ty, 0));
}
@@ -2287,6 +2385,9 @@ public:
bool isAlignmentRequired(const Type *T) const;
bool isAlignmentRequired(QualType T) const;
+ /// More type predicates useful for type checking/promotion
+ bool isPromotableIntegerType(QualType T) const; // C99 6.3.1.1p2
+
/// Return the "preferred" alignment of the specified type \p T for
/// the current target, in bits.
///
@@ -2415,7 +2516,9 @@ public:
/// Return true if the specified type has unique object representations
/// according to (C++17 [meta.unary.prop]p9)
- bool hasUniqueObjectRepresentations(QualType Ty) const;
+ bool
+ hasUniqueObjectRepresentations(QualType Ty,
+ bool CheckIfTriviallyCopyable = true) const;
//===--------------------------------------------------------------------===//
// Type Operators
@@ -2452,6 +2555,9 @@ public:
return getCanonicalType(T1) == getCanonicalType(T2);
}
+ /// Determine whether the given expressions \p X and \p Y are equivalent.
+ bool hasSameExpr(const Expr *X, const Expr *Y) const;
+
/// Return this type as a completely-unqualified array type,
/// capturing the qualifiers in \p Quals.
///
@@ -2476,9 +2582,9 @@ public:
bool hasSameNullabilityTypeQualifier(QualType SubT, QualType SuperT,
bool IsParam) const {
- auto SubTnullability = SubT->getNullability(*this);
- auto SuperTnullability = SuperT->getNullability(*this);
- if (SubTnullability.hasValue() == SuperTnullability.hasValue()) {
+ auto SubTnullability = SubT->getNullability();
+ auto SuperTnullability = SuperT->getNullability();
+ if (SubTnullability.has_value() == SuperTnullability.has_value()) {
// Neither has nullability; return true
if (!SubTnullability)
return true;
@@ -2505,8 +2611,10 @@ public:
bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
const ObjCMethodDecl *MethodImp);
- bool UnwrapSimilarTypes(QualType &T1, QualType &T2);
- void UnwrapSimilarArrayTypes(QualType &T1, QualType &T2);
+ bool UnwrapSimilarTypes(QualType &T1, QualType &T2,
+ bool AllowPiMismatch = true);
+ void UnwrapSimilarArrayTypes(QualType &T1, QualType &T2,
+ bool AllowPiMismatch = true);
/// Determine if two types are similar, according to the C++ rules. That is,
/// determine if they are the same other than qualifiers on the initial
@@ -2569,11 +2677,40 @@ public:
/// template name uses the shortest form of the dependent
/// nested-name-specifier, which itself contains all canonical
/// types, values, and templates.
- TemplateName getCanonicalTemplateName(TemplateName Name) const;
+ TemplateName getCanonicalTemplateName(const TemplateName &Name) const;
/// Determine whether the given template names refer to the same
/// template.
- bool hasSameTemplateName(TemplateName X, TemplateName Y);
+ bool hasSameTemplateName(const TemplateName &X, const TemplateName &Y) const;
+
+ /// Determine whether the two declarations refer to the same entity.
+ bool isSameEntity(const NamedDecl *X, const NamedDecl *Y) const;
+
+ /// Determine whether two template parameter lists are similar enough
+ /// that they may be used in declarations of the same template.
+ bool isSameTemplateParameterList(const TemplateParameterList *X,
+ const TemplateParameterList *Y) const;
+
+ /// Determine whether two template parameters are similar enough
+ /// that they may be used in declarations of the same template.
+ bool isSameTemplateParameter(const NamedDecl *X, const NamedDecl *Y) const;
+
+ /// Determine whether two 'requires' expressions are similar enough that they
+ /// may be used in re-declarations.
+ ///
+ /// Use of 'requires' isn't mandatory, works with constraints expressed in
+ /// other ways too.
+ bool isSameConstraintExpr(const Expr *XCE, const Expr *YCE) const;
+
+ /// Determine whether two type contraint are similar enough that they could
+ /// used in declarations of the same template.
+ bool isSameTypeConstraint(const TypeConstraint *XTC,
+ const TypeConstraint *YTC) const;
+
+ /// Determine whether two default template arguments are similar enough
+ /// that they may be used in declarations of the same template.
+ bool isSameDefaultTemplateArgument(const NamedDecl *X,
+ const NamedDecl *Y) const;
/// Retrieve the "canonical" template argument.
///
@@ -2614,6 +2751,10 @@ public:
/// Return number of constant array elements.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
+ /// Return number of elements initialized in an ArrayInitLoopExpr.
+ uint64_t
+ getArrayInitLoopExprElementCount(const ArrayInitLoopExpr *AILE) const;
+
/// Perform adjustment on the parameter type of a function.
///
/// This routine adjusts the given parameter type @p T to the actual
@@ -2671,22 +2812,6 @@ public:
/// long double and double on AArch64 will return 0).
int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const;
- /// Return a real floating point or a complex type (based on
- /// \p typeDomain/\p typeSize).
- ///
- /// \param typeDomain a real floating point or complex type.
- /// \param typeSize a real floating point or complex type.
- QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
- QualType typeDomain) const;
-
- unsigned getTargetAddressSpace(QualType T) const {
- return getTargetAddressSpace(T.getQualifiers());
- }
-
- unsigned getTargetAddressSpace(Qualifiers Q) const {
- return getTargetAddressSpace(Q.getAddressSpace());
- }
-
unsigned getTargetAddressSpace(LangAS AS) const;
LangAS getLangASForBuiltinAddressSpace(unsigned AS) const;
@@ -2699,6 +2824,23 @@ public:
return AddrSpaceMapMangling || isTargetAddressSpace(AS);
}
+ // Merges two exception specifications, such that the resulting
+ // exception spec is the union of both. For example, if either
+ // of them can throw something, the result can throw it as well.
+ FunctionProtoType::ExceptionSpecInfo
+ mergeExceptionSpecs(FunctionProtoType::ExceptionSpecInfo ESI1,
+ FunctionProtoType::ExceptionSpecInfo ESI2,
+ SmallVectorImpl<QualType> &ExceptionTypeStorage,
+ bool AcceptDependent);
+
+ // For two "same" types, return a type which has
+ // the common sugar between them. If Unqualified is true,
+ // both types need only be the same unqualified type.
+ // The result will drop the qualifiers which do not occur
+ // in both types.
+ QualType getCommonSugaredType(QualType X, QualType Y,
+ bool Unqualified = false);
+
private:
// Helper for integer ordering
unsigned getIntegerRank(const Type *T) const;
@@ -2716,14 +2858,20 @@ public:
bool typesAreBlockPointerCompatible(QualType, QualType);
bool isObjCIdType(QualType T) const {
+ if (const auto *ET = dyn_cast<ElaboratedType>(T))
+ T = ET->getNamedType();
return T == getObjCIdType();
}
bool isObjCClassType(QualType T) const {
+ if (const auto *ET = dyn_cast<ElaboratedType>(T))
+ T = ET->getNamedType();
return T == getObjCClassType();
}
bool isObjCSelType(QualType T) const {
+ if (const auto *ET = dyn_cast<ElaboratedType>(T))
+ T = ET->getNamedType();
return T == getObjCSelType();
}
@@ -2749,10 +2897,12 @@ public:
bool canBindObjCObjectType(QualType To, QualType From);
// Functions for calculating composite types
- QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false, bool BlockReturnType = false);
- QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false, bool AllowCXX = false);
+ QualType mergeTypes(QualType, QualType, bool OfBlockPointer = false,
+ bool Unqualified = false, bool BlockReturnType = false,
+ bool IsConditionalOperator = false);
+ QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer = false,
+ bool Unqualified = false, bool AllowCXX = false,
+ bool IsConditionalOperator = false);
QualType mergeFunctionParameterTypes(QualType, QualType,
bool OfBlockPointer = false,
bool Unqualified = false);
@@ -2923,7 +3073,7 @@ public:
}
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
- GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
+ GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const;
/// Determines if the decl can be CodeGen'ed or deserialized from PCH
/// lazily, only when used; this is only relevant for function or file scoped
@@ -2954,7 +3104,8 @@ public:
DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD);
void setManglingNumber(const NamedDecl *ND, unsigned Number);
- unsigned getManglingNumber(const NamedDecl *ND) const;
+ unsigned getManglingNumber(const NamedDecl *ND,
+ bool ForAuxTarget = false) const;
void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
unsigned getStaticLocalNumber(const VarDecl *VD) const;
@@ -2985,6 +3136,11 @@ public:
/// GUID value.
MSGuidDecl *getMSGuidDecl(MSGuidDeclParts Parts) const;
+ /// Return a declaration for a uniquified anonymous global constant
+ /// corresponding to a given APValue.
+ UnnamedGlobalConstantDecl *
+ getUnnamedGlobalConstantDecl(QualType Ty, const APValue &Value) const;
+
/// Return the template parameter object of the given type with the given
/// value.
TemplateParamObjectDecl *getTemplateParamObjectDecl(QualType T,
@@ -2994,6 +3150,9 @@ public:
/// valid feature names.
ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const;
+ std::vector<std::string>
+ filterFunctionTargetVersionAttrs(const TargetVersionAttr *TV) const;
+
void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
const FunctionDecl *) const;
void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
@@ -3065,7 +3224,6 @@ private:
public:
ObjCEncOptions() : Bits(0) {}
- ObjCEncOptions(const ObjCEncOptions &RHS) : Bits(RHS.Bits) {}
#define OPT_LIST(V) \
V(ExpandPointedToStructures, 0) \
@@ -3086,11 +3244,11 @@ OPT_LIST(V)
#undef OPT_LIST
- LLVM_NODISCARD ObjCEncOptions keepingOnly(ObjCEncOptions Mask) const {
+ [[nodiscard]] ObjCEncOptions keepingOnly(ObjCEncOptions Mask) const {
return Bits & Mask.Bits;
}
- LLVM_NODISCARD ObjCEncOptions forComponentType() const {
+ [[nodiscard]] ObjCEncOptions forComponentType() const {
ObjCEncOptions Mask = ObjCEncOptions()
.setIsOutermostType()
.setIsStructField();
@@ -3201,39 +3359,18 @@ public:
/// Return a new OMPTraitInfo object owned by this context.
OMPTraitInfo &getNewOMPTraitInfo();
- /// Whether a C++ static variable may be externalized.
- bool mayExternalizeStaticVar(const Decl *D) const;
+ /// Whether a C++ static variable or CUDA/HIP kernel may be externalized.
+ bool mayExternalize(const Decl *D) const;
- /// Whether a C++ static variable should be externalized.
- bool shouldExternalizeStaticVar(const Decl *D) const;
+ /// Whether a C++ static variable or CUDA/HIP kernel should be externalized.
+ bool shouldExternalize(const Decl *D) const;
StringRef getCUIDHash() const;
- void AddSYCLKernelNamingDecl(const CXXRecordDecl *RD);
- bool IsSYCLKernelNamingDecl(const NamedDecl *RD) const;
- unsigned GetSYCLKernelNamingIndex(const NamedDecl *RD);
- /// A SourceLocation to store whether we have evaluated a kernel name already,
- /// and where it happened. If so, we need to diagnose an illegal use of the
- /// builtin.
- llvm::MapVector<const SYCLUniqueStableNameExpr *, std::string>
- SYCLUniqueStableNameEvaluatedValues;
-
private:
/// All OMPTraitInfo objects live in this collection, one per
/// `pragma omp [begin] declare variant` directive.
SmallVector<std::unique_ptr<OMPTraitInfo>, 4> OMPTraitInfoVector;
-
- /// A list of the (right now just lambda decls) declarations required to
- /// name all the SYCL kernels in the translation unit, so that we can get the
- /// correct kernel name, as well as implement
- /// __builtin_sycl_unique_stable_name.
- llvm::DenseMap<const DeclContext *,
- llvm::SmallPtrSet<const CXXRecordDecl *, 4>>
- SYCLKernelNamingTypes;
- std::unique_ptr<ItaniumMangleContext> SYCLKernelFilterContext;
- void FilterSYCLKernelNamingDecls(
- const CXXRecordDecl *RD,
- llvm::SmallVectorImpl<const CXXRecordDecl *> &Decls);
};
/// Insertion operator for diagnostics.
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTDiagnostic.h b/contrib/llvm-project/clang/include/clang/AST/ASTDiagnostic.h
index d6549e12d92a..ef2224982862 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTDiagnostic.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTDiagnostic.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_AST_ASTDIAGNOSTIC_H
#define LLVM_CLANG_AST_ASTDIAGNOSTIC_H
+#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticAST.h"
@@ -31,6 +32,12 @@ namespace clang {
SmallVectorImpl<char> &Output,
void *Cookie,
ArrayRef<intptr_t> QualTypeVals);
+
+ /// Returns a desugared version of the QualType, and marks ShouldAKA as true
+ /// whenever we remove significant sugar from the type. Make sure ShouldAKA
+ /// is initialized before passing it in.
+ QualType desugarForDiagnostic(ASTContext &Context, QualType QT,
+ bool &ShouldAKA);
} // end namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTDumper.h b/contrib/llvm-project/clang/include/clang/AST/ASTDumper.h
index a154bc2db3a7..71ac467e5104 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTDumper.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTDumper.h
@@ -32,6 +32,7 @@ public:
TextNodeDumper &doGetNodeDelegate() { return NodeDumper; }
+ void dumpInvalidDeclContext(const DeclContext *DC);
void dumpLookups(const DeclContext *DC, bool DumpDecls);
template <typename SpecializationDecl>
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTFwd.h b/contrib/llvm-project/clang/include/clang/AST/ASTFwd.h
index 649b57113424..8823663386ea 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTFwd.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTFwd.h
@@ -30,6 +30,11 @@ class OMPClause;
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) class Class;
#include "llvm/Frontend/OpenMP/OMP.inc"
+class Attr;
+#define ATTR(A) class A##Attr;
+#include "clang/Basic/AttrList.inc"
+class ObjCProtocolLoc;
+class ConceptReference;
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTImportError.h b/contrib/llvm-project/clang/include/clang/AST/ASTImportError.h
new file mode 100644
index 000000000000..728314ca0936
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTImportError.h
@@ -0,0 +1,50 @@
+//===- ASTImportError.h - Define errors while importing AST -----*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ASTImportError class which basically defines the kind
+// of error while importing AST .
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTIMPORTERROR_H
+#define LLVM_CLANG_AST_ASTIMPORTERROR_H
+
+#include "llvm/Support/Error.h"
+
+namespace clang {
+
+class ASTImportError : public llvm::ErrorInfo<ASTImportError> {
+public:
+ /// \brief Kind of error when importing an AST component.
+ enum ErrorKind {
+ NameConflict, /// Naming ambiguity (likely ODR violation).
+ UnsupportedConstruct, /// Not supported node or case.
+ Unknown /// Other error.
+ };
+
+ ErrorKind Error;
+
+ static char ID;
+
+ ASTImportError() : Error(Unknown) {}
+ ASTImportError(const ASTImportError &Other) : Error(Other.Error) {}
+ ASTImportError &operator=(const ASTImportError &Other) {
+ Error = Other.Error;
+ return *this;
+ }
+ ASTImportError(ErrorKind Error) : Error(Error) {}
+
+ std::string toString() const;
+
+ void log(llvm::raw_ostream &OS) const override;
+ std::error_code convertToErrorCode() const override;
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTIMPORTERROR_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTImporter.h b/contrib/llvm-project/clang/include/clang/AST/ASTImporter.h
index 17e673a8471a..4ffd91384657 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTImporter.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTImporter.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
#define LLVM_CLANG_AST_ASTIMPORTER_H
-#include "clang/AST/APValue.h"
+#include "clang/AST/ASTImportError.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExprCXX.h"
@@ -27,9 +27,8 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Error.h"
+#include <optional>
#include <utility>
namespace clang {
@@ -49,33 +48,6 @@ class TagDecl;
class TranslationUnitDecl;
class TypeSourceInfo;
- class ImportError : public llvm::ErrorInfo<ImportError> {
- public:
- /// \brief Kind of error when importing an AST component.
- enum ErrorKind {
- NameConflict, /// Naming ambiguity (likely ODR violation).
- UnsupportedConstruct, /// Not supported node or case.
- Unknown /// Other error.
- };
-
- ErrorKind Error;
-
- static char ID;
-
- ImportError() : Error(Unknown) {}
- ImportError(const ImportError &Other) : Error(Other.Error) {}
- ImportError &operator=(const ImportError &Other) {
- Error = Other.Error;
- return *this;
- }
- ImportError(ErrorKind Error) : Error(Error) { }
-
- std::string toString() const;
-
- void log(raw_ostream &OS) const override;
- std::error_code convertToErrorCode() const override;
- };
-
// \brief Returns with a list of declarations started from the canonical decl
// then followed by subsequent decls in the translation unit.
// This gives a canonical list for each entry in the redecl chain.
@@ -259,7 +231,7 @@ class TypeSourceInfo;
/// imported. The same declaration may or may not be included in
/// ImportedDecls. This map is updated continuously during imports and never
/// cleared (like ImportedDecls).
- llvm::DenseMap<Decl *, ImportError> ImportDeclErrors;
+ llvm::DenseMap<Decl *, ASTImportError> ImportDeclErrors;
/// Mapping from the already-imported declarations in the "to"
/// context to the corresponding declarations in the "from" context.
@@ -286,6 +258,7 @@ class TypeSourceInfo;
FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);
void AddToLookupTable(Decl *ToD);
+ llvm::Error ImportAttrs(Decl *ToD, Decl *FromD);
protected:
/// Can be overwritten by subclasses to implement their own import logic.
@@ -332,7 +305,7 @@ class TypeSourceInfo;
/// \param From Object to import.
/// \return Error information (success or error).
template <typename ImportT>
- LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) {
+ [[nodiscard]] llvm::Error importInto(ImportT &To, const ImportT &From) {
auto ToOrErr = Import(From);
if (ToOrErr)
To = *ToOrErr;
@@ -379,6 +352,9 @@ class TypeSourceInfo;
return Import(const_cast<Decl *>(FromD));
}
+ llvm::Expected<InheritedConstructor>
+ Import(const InheritedConstructor &From);
+
/// Return the copy of the given declaration in the "to" context if
/// it has already been imported from the "from" context. Otherwise return
/// nullptr.
@@ -392,7 +368,7 @@ class TypeSourceInfo;
/// in the "to" context was imported. If it was not imported or of the wrong
/// type a null value is returned.
template <typename DeclT>
- llvm::Optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const {
+ std::optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const {
auto FromI = ImportedFromDecls.find(ToD);
if (FromI == ImportedFromDecls.end())
return {};
@@ -507,7 +483,7 @@ class TypeSourceInfo;
/// Import the definition of the given declaration, including all of
/// the declarations it contains.
- LLVM_NODISCARD llvm::Error ImportDefinition(Decl *From);
+ [[nodiscard]] llvm::Error ImportDefinition(Decl *From);
/// Cope with a name conflict when importing a declaration into the
/// given context.
@@ -589,10 +565,10 @@ class TypeSourceInfo;
/// Return if import of the given declaration has failed and if yes
/// the kind of the problem. This gives the first error encountered with
/// the node.
- llvm::Optional<ImportError> getImportDeclErrorIfAny(Decl *FromD) const;
+ std::optional<ASTImportError> getImportDeclErrorIfAny(Decl *FromD) const;
/// Mark (newly) imported declaration with error.
- void setImportDeclError(Decl *From, ImportError Error);
+ void setImportDeclError(Decl *From, ASTImportError Error);
/// Determine whether the given types are structurally
/// equivalent.
@@ -602,8 +578,8 @@ class TypeSourceInfo;
/// Determine the index of a field in its parent record.
/// F should be a field (or indirect field) declaration.
/// \returns The index of the field in its parent context (starting from 0).
- /// On error `None` is returned (parent context is non-record).
- static llvm::Optional<unsigned> getFieldIndex(Decl *F);
+ /// On error `std::nullopt` is returned (parent context is non-record).
+ static std::optional<unsigned> getFieldIndex(Decl *F);
};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h b/contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h
index 47dca2033839..2dbc44c5dcd4 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h
@@ -21,7 +21,6 @@
namespace clang {
-class ASTContext;
class NamedDecl;
class DeclContext;
@@ -75,6 +74,10 @@ public:
// The function should be called when the old context is definitely different
// from the new.
void update(NamedDecl *ND, DeclContext *OldDC);
+ // Same as 'update' but allow if 'ND' is not in the table or the old context
+ // is the same as the new.
+ // FIXME: The old redeclaration context is not handled.
+ void updateForced(NamedDecl *ND, DeclContext *OldDC);
using LookupResult = DeclList;
LookupResult lookup(DeclContext *DC, DeclarationName Name) const;
// Check if the `ND` is within the lookup table (with its current name) in
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTImporterSharedState.h b/contrib/llvm-project/clang/include/clang/AST/ASTImporterSharedState.h
index 829eb1c611c3..446d7ee61ea5 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTImporterSharedState.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTImporterSharedState.h
@@ -1,9 +1,8 @@
//===- ASTImporterSharedState.h - ASTImporter specific state --*- C++ -*---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
//
@@ -15,11 +14,11 @@
#ifndef LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H
#define LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H
+#include "clang/AST/ASTImportError.h"
#include "clang/AST/ASTImporterLookupTable.h"
#include "clang/AST/Decl.h"
#include "llvm/ADT/DenseMap.h"
-// FIXME We need this because of ImportError.
-#include "clang/AST/ASTImporter.h"
+#include <optional>
namespace clang {
@@ -38,7 +37,10 @@ class ASTImporterSharedState {
/// imported. The same declaration may or may not be included in
/// ImportedFromDecls. This map is updated continuously during imports and
/// never cleared (like ImportedFromDecls).
- llvm::DenseMap<Decl *, ImportError> ImportErrors;
+ llvm::DenseMap<Decl *, ASTImportError> ImportErrors;
+
+ /// Set of the newly created declarations.
+ llvm::DenseSet<Decl *> NewDecls;
// FIXME put ImportedFromDecls here!
// And from that point we can better encapsulate the lookup table.
@@ -64,17 +66,21 @@ public:
LookupTable->remove(ND);
}
- llvm::Optional<ImportError> getImportDeclErrorIfAny(Decl *ToD) const {
+ std::optional<ASTImportError> getImportDeclErrorIfAny(Decl *ToD) const {
auto Pos = ImportErrors.find(ToD);
if (Pos != ImportErrors.end())
return Pos->second;
else
- return Optional<ImportError>();
+ return std::nullopt;
}
- void setImportDeclError(Decl *To, ImportError Error) {
+ void setImportDeclError(Decl *To, ASTImportError Error) {
ImportErrors[To] = Error;
}
+
+ bool isNewDecl(const Decl *ToD) const { return NewDecls.count(ToD); }
+
+ void markAsNewDecl(Decl *ToD) { NewDecls.insert(ToD); }
};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTLambda.h b/contrib/llvm-project/clang/include/clang/AST/ASTLambda.h
index 6fd82d6af490..646cb574847f 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTLambda.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTLambda.h
@@ -35,6 +35,21 @@ inline bool isLambdaCallOperator(const DeclContext *DC) {
return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
}
+inline bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC) {
+ return isLambdaCallOperator(DC) &&
+ cast<CXXMethodDecl>(DC)->isExplicitObjectMemberFunction();
+}
+
+inline bool isLambdaCallWithImplicitObjectParameter(const DeclContext *DC) {
+ return isLambdaCallOperator(DC) &&
+ // FIXME: Checking for a null type is not great
+ // but lambdas with invalid captures or whose closure parameter list
+ // have not fully been parsed may have a call operator whose type is
+ // null.
+ !cast<CXXMethodDecl>(DC)->getType().isNull() &&
+ !cast<CXXMethodDecl>(DC)->isExplicitObjectMemberFunction();
+}
+
inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) {
if (!MD) return false;
const CXXRecordDecl *LambdaClass = MD->getParent();
@@ -65,8 +80,8 @@ inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) {
}
inline bool isGenericLambdaCallOperatorOrStaticInvokerSpecialization(
- DeclContext *DC) {
- CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC);
+ const DeclContext *DC) {
+ const auto *MD = dyn_cast<CXXMethodDecl>(DC);
if (!MD) return false;
const CXXRecordDecl *LambdaClass = MD->getParent();
if (LambdaClass && LambdaClass->isGenericLambda())
@@ -75,7 +90,6 @@ inline bool isGenericLambdaCallOperatorOrStaticInvokerSpecialization(
return false;
}
-
// This returns the parent DeclContext ensuring that the correct
// parent DeclContext is returned for Lambdas
inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) {
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h b/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h
index 18e7f491f222..cc8dab97f8b0 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h
@@ -104,7 +104,7 @@ public:
Visit(Comment, Comment);
// Decls within functions are visited by the body.
- if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
+ if (!isa<FunctionDecl, ObjCMethodDecl, BlockDecl>(*D)) {
if (Traversal != TK_AsIs) {
if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
auto SK = CTSD->getSpecializationKind();
@@ -246,12 +246,16 @@ public:
.getTypeConstraint()
->getImmediatelyDeclaredConstraint());
} else if (auto *NR = dyn_cast<concepts::NestedRequirement>(R)) {
- if (!NR->isSubstitutionFailure())
+ if (!NR->hasInvalidConstraint())
Visit(NR->getConstraintExpr());
}
});
}
+ void Visit(const ConceptReference *R) {
+ getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(R); });
+ }
+
void Visit(const APValue &Value, QualType Ty) {
getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); });
}
@@ -288,6 +292,8 @@ public:
Visit(C);
else if (const auto *T = N.get<TemplateArgument>())
Visit(*T);
+ else if (const auto *CR = N.get<ConceptReference>())
+ Visit(CR);
}
void dumpDeclContext(const DeclContext *DC) {
@@ -384,18 +390,19 @@ public:
}
void VisitAttributedType(const AttributedType *T) {
// FIXME: AttrKind
- Visit(T->getModifiedType());
+ if (T->getModifiedType() != T->getEquivalentType())
+ Visit(T->getModifiedType());
}
- void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
- Visit(T->getReplacedParameter());
+ void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
+ Visit(T->getWrappedType());
}
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {}
void
VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
- Visit(T->getReplacedParameter());
Visit(T->getArgumentPack());
}
void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
- for (const auto &Arg : *T)
+ for (const auto &Arg : T->template_arguments())
Visit(Arg);
}
void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
@@ -419,8 +426,12 @@ public:
}
void VisitFunctionDecl(const FunctionDecl *D) {
- if (const auto *FTSI = D->getTemplateSpecializationInfo())
+ if (FunctionTemplateSpecializationInfo *FTSI =
+ D->getTemplateSpecializationInfo())
dumpTemplateArgumentList(*FTSI->TemplateArguments);
+ else if (DependentFunctionTemplateSpecializationInfo *DFTSI =
+ D->getDependentSpecializationInfo())
+ dumpASTTemplateArgumentListInfo(DFTSI->TemplateArgumentsAsWritten);
if (D->param_begin())
for (const auto *Parameter : D->parameters())
@@ -464,6 +475,10 @@ public:
void VisitBindingDecl(const BindingDecl *D) {
if (Traversal == TK_IgnoreUnlessSpelledInSource)
return;
+
+ if (const auto *V = D->getHoldingVar())
+ Visit(V);
+
if (const auto *E = D->getBinding())
Visit(E);
}
@@ -472,6 +487,8 @@ public:
Visit(D->getAsmString());
}
+ void VisitTopLevelStmtDecl(const TopLevelStmtDecl *D) { Visit(D->getStmt()); }
+
void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); }
void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
@@ -565,11 +582,6 @@ public:
dumpTemplateParameters(D->getTemplateParameters());
}
- void VisitClassScopeFunctionSpecializationDecl(
- const ClassScopeFunctionSpecializationDecl *D) {
- Visit(D->getSpecialization());
- dumpASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
- }
void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); }
void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
@@ -619,7 +631,14 @@ public:
Visit(D->getConstraintExpr());
}
+ void VisitImplicitConceptSpecializationDecl(
+ const ImplicitConceptSpecializationDecl *CSD) {
+ for (const TemplateArgument &Arg : CSD->getTemplateArguments())
+ Visit(Arg);
+ }
+
void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) {
+ Visit(CSE->getSpecializationDecl());
if (CSE->hasExplicitTemplateArgs())
for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments())
dumpTemplateArgumentLoc(ArgLoc);
@@ -631,8 +650,15 @@ public:
}
void VisitFriendDecl(const FriendDecl *D) {
- if (!D->getFriendType())
+ if (D->getFriendType()) {
+ // Traverse any CXXRecordDecl owned by this type, since
+ // it will not be in the parent context:
+ if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
+ if (auto *TD = ET->getOwnedTagDecl())
+ Visit(TD);
+ } else {
Visit(D->getFriendDecl());
+ }
}
void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
@@ -697,6 +723,12 @@ public:
}
}
+ void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
+ if (auto *Filler = PLIE->getArrayFiller()) {
+ Visit(Filler, "array_filler");
+ }
+ }
+
void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }
void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
@@ -705,8 +737,11 @@ public:
}
void VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
- Visit(E->getControllingExpr());
- Visit(E->getControllingExpr()->getType()); // FIXME: remove
+ if (E->isExprPredicate()) {
+ Visit(E->getControllingExpr());
+ Visit(E->getControllingExpr()->getType()); // FIXME: remove
+ } else
+ Visit(E->getControllingType()->getType());
for (const auto Assoc : E->associations()) {
Visit(Assoc);
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTStructuralEquivalence.h b/contrib/llvm-project/clang/include/clang/AST/ASTStructuralEquivalence.h
index c958a16aba21..029439c8e9a3 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTStructuralEquivalence.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTStructuralEquivalence.h
@@ -17,7 +17,7 @@
#include "clang/AST/DeclBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/Optional.h"
+#include <optional>
#include <queue>
#include <utility>
@@ -69,15 +69,19 @@ struct StructuralEquivalenceContext {
/// \c true if the last diagnostic came from ToCtx.
bool LastDiagFromC2 = false;
+ /// Whether to ignore comparing the depth of template param(TemplateTypeParm)
+ bool IgnoreTemplateParmDepth;
+
StructuralEquivalenceContext(
ASTContext &FromCtx, ASTContext &ToCtx,
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
- StructuralEquivalenceKind EqKind,
- bool StrictTypeSpelling = false, bool Complain = true,
- bool ErrorOnTagTypeMismatch = false)
+ StructuralEquivalenceKind EqKind, bool StrictTypeSpelling = false,
+ bool Complain = true, bool ErrorOnTagTypeMismatch = false,
+ bool IgnoreTemplateParmDepth = false)
: FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling),
- ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {}
+ ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain),
+ IgnoreTemplateParmDepth(IgnoreTemplateParmDepth) {}
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
@@ -114,10 +118,10 @@ struct StructuralEquivalenceContext {
///
/// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It
/// probably makes more sense in some other common place then here.
- static llvm::Optional<unsigned>
+ static std::optional<unsigned>
findUntaggedStructOrUnionIndex(RecordDecl *Anon);
- // If ErrorOnTagTypeMismatch is set, return the the error, otherwise get the
+ // If ErrorOnTagTypeMismatch is set, return the error, otherwise get the
// relevant warning for the input error diagnostic.
unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic);
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTTypeTraits.h b/contrib/llvm-project/clang/include/clang/AST/ASTTypeTraits.h
index 57195a9d6066..3988a15971db 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTTypeTraits.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTTypeTraits.h
@@ -17,6 +17,7 @@
#include "clang/AST/ASTFwd.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/LambdaCapture.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TypeLoc.h"
@@ -25,10 +26,8 @@
#include "llvm/Support/AlignOf.h"
namespace llvm {
-
class raw_ostream;
-
-}
+} // namespace llvm
namespace clang {
@@ -52,11 +51,10 @@ enum TraversalKind {
class ASTNodeKind {
public:
/// Empty identifier. It matches nothing.
- ASTNodeKind() : KindId(NKI_None) {}
+ constexpr ASTNodeKind() : KindId(NKI_None) {}
/// Construct an identifier for T.
- template <class T>
- static ASTNodeKind getFromNodeKind() {
+ template <class T> static constexpr ASTNodeKind getFromNodeKind() {
return ASTNodeKind(KindToKindId<T>::Id);
}
@@ -65,27 +63,33 @@ public:
static ASTNodeKind getFromNode(const Decl &D);
static ASTNodeKind getFromNode(const Stmt &S);
static ASTNodeKind getFromNode(const Type &T);
+ static ASTNodeKind getFromNode(const TypeLoc &T);
+ static ASTNodeKind getFromNode(const LambdaCapture &L);
static ASTNodeKind getFromNode(const OMPClause &C);
+ static ASTNodeKind getFromNode(const Attr &A);
/// \}
/// Returns \c true if \c this and \c Other represent the same kind.
- bool isSame(ASTNodeKind Other) const {
+ constexpr bool isSame(ASTNodeKind Other) const {
return KindId != NKI_None && KindId == Other.KindId;
}
/// Returns \c true only for the default \c ASTNodeKind()
- bool isNone() const { return KindId == NKI_None; }
+ constexpr bool isNone() const { return KindId == NKI_None; }
+
+ /// Returns \c true if \c this is a base kind of (or same as) \c Other.
+ bool isBaseOf(ASTNodeKind Other) const;
/// Returns \c true if \c this is a base kind of (or same as) \c Other.
/// \param Distance If non-null, used to return the distance between \c this
/// and \c Other in the class hierarchy.
- bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
+ bool isBaseOf(ASTNodeKind Other, unsigned *Distance) const;
/// String representation of the kind.
StringRef asStringRef() const;
/// Strict weak ordering for ASTNodeKind.
- bool operator<(const ASTNodeKind &Other) const {
+ constexpr bool operator<(const ASTNodeKind &Other) const {
return KindId < Other.KindId;
}
@@ -119,7 +123,7 @@ public:
/// Check if the given ASTNodeKind identifies a type that offers pointer
/// identity. This is useful for the fast path in DynTypedNode.
- bool hasPointerIdentity() const {
+ constexpr bool hasPointerIdentity() const {
return KindId > NKI_LastKindWithoutPointerIdentity;
}
@@ -131,9 +135,12 @@ private:
NKI_None,
NKI_TemplateArgument,
NKI_TemplateArgumentLoc,
+ NKI_LambdaCapture,
NKI_TemplateName,
NKI_NestedNameSpecifierLoc,
NKI_QualType,
+#define TYPELOC(CLASS, PARENT) NKI_##CLASS##TypeLoc,
+#include "clang/AST/TypeLocNodes.def"
NKI_TypeLoc,
NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
NKI_CXXBaseSpecifier,
@@ -152,11 +159,20 @@ private:
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
#include "llvm/Frontend/OpenMP/OMP.inc"
+ NKI_Attr,
+#define ATTR(A) NKI_##A##Attr,
+#include "clang/Basic/AttrList.inc"
+ NKI_ObjCProtocolLoc,
+ NKI_ConceptReference,
NKI_NumberOfKinds
};
/// Use getFromNodeKind<T>() to construct the kind.
- ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
+ constexpr ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
+
+ /// Returns \c true if \c Base is a base kind of (or same as) \c
+ /// Derived.
+ static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
/// Returns \c true if \c Base is a base kind of (or same as) \c
/// Derived.
@@ -192,16 +208,22 @@ private:
KIND_TO_KIND_ID(CXXCtorInitializer)
KIND_TO_KIND_ID(TemplateArgument)
KIND_TO_KIND_ID(TemplateArgumentLoc)
+KIND_TO_KIND_ID(LambdaCapture)
KIND_TO_KIND_ID(TemplateName)
KIND_TO_KIND_ID(NestedNameSpecifier)
KIND_TO_KIND_ID(NestedNameSpecifierLoc)
KIND_TO_KIND_ID(QualType)
+#define TYPELOC(CLASS, PARENT) KIND_TO_KIND_ID(CLASS##TypeLoc)
+#include "clang/AST/TypeLocNodes.def"
KIND_TO_KIND_ID(TypeLoc)
KIND_TO_KIND_ID(Decl)
KIND_TO_KIND_ID(Stmt)
KIND_TO_KIND_ID(Type)
KIND_TO_KIND_ID(OMPClause)
+KIND_TO_KIND_ID(Attr)
+KIND_TO_KIND_ID(ObjCProtocolLoc)
KIND_TO_KIND_ID(CXXBaseSpecifier)
+KIND_TO_KIND_ID(ConceptReference)
#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
#include "clang/AST/DeclNodes.inc"
#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
@@ -211,6 +233,8 @@ KIND_TO_KIND_ID(CXXBaseSpecifier)
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
#include "llvm/Frontend/OpenMP/OMP.inc"
+#define ATTR(A) KIND_TO_KIND_ID(A##Attr)
+#include "clang/Basic/AttrList.inc"
#undef KIND_TO_KIND_ID
inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
@@ -299,7 +323,7 @@ public:
return getUnchecked<QualType>().getAsOpaquePtr() <
Other.getUnchecked<QualType>().getAsOpaquePtr();
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind)) {
+ if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind)) {
auto TLA = getUnchecked<TypeLoc>();
auto TLB = Other.getUnchecked<TypeLoc>();
return std::make_pair(TLA.getType().getAsOpaquePtr(),
@@ -331,7 +355,7 @@ public:
if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind))
+ if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind))
return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
@@ -360,7 +384,7 @@ public:
}
static unsigned getHashValue(const DynTypedNode &Val) {
// FIXME: Add hashing support for the remaining types.
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(Val.NodeKind)) {
+ if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(Val.NodeKind)) {
auto TL = Val.getUnchecked<TypeLoc>();
return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
TL.getOpaqueData());
@@ -450,6 +474,29 @@ private:
}
};
+ /// Converter that stores nodes by value. It must be possible to dynamically
+ /// cast the stored node within a type hierarchy without breaking (especially
+ /// through slicing).
+ template <typename T, typename BaseT,
+ typename = std::enable_if_t<(sizeof(T) == sizeof(BaseT))>>
+ struct DynCastValueConverter {
+ static const T *get(ASTNodeKind NodeKind, const void *Storage) {
+ if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
+ return &getUnchecked(NodeKind, Storage);
+ return nullptr;
+ }
+ static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
+ assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
+ return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
+ }
+ static DynTypedNode create(const T &Node) {
+ DynTypedNode Result;
+ Result.NodeKind = ASTNodeKind::getFromNode(Node);
+ new (&Result.Storage) T(Node);
+ return Result;
+ }
+ };
+
ASTNodeKind NodeKind;
/// Stores the data of the node.
@@ -462,7 +509,7 @@ private:
/// have storage or unique pointers and thus need to be stored by value.
llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
TemplateArgumentLoc, NestedNameSpecifierLoc,
- QualType, TypeLoc>
+ QualType, TypeLoc, ObjCProtocolLoc>
Storage;
};
@@ -486,6 +533,11 @@ struct DynTypedNode::BaseConverter<
T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
: public DynCastPtrConverter<T, OMPClause> {};
+template <typename T>
+struct DynTypedNode::BaseConverter<
+ T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
+ : public DynCastPtrConverter<T, Attr> {};
+
template <>
struct DynTypedNode::BaseConverter<
NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
@@ -503,6 +555,10 @@ struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
: public ValueConverter<TemplateArgumentLoc> {};
template <>
+struct DynTypedNode::BaseConverter<LambdaCapture, void>
+ : public ValueConverter<LambdaCapture> {};
+
+template <>
struct DynTypedNode::BaseConverter<
TemplateName, void> : public ValueConverter<TemplateName> {};
@@ -515,14 +571,23 @@ template <>
struct DynTypedNode::BaseConverter<QualType,
void> : public ValueConverter<QualType> {};
-template <>
+template <typename T>
struct DynTypedNode::BaseConverter<
- TypeLoc, void> : public ValueConverter<TypeLoc> {};
+ T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
+ : public DynCastValueConverter<T, TypeLoc> {};
template <>
struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
: public PtrConverter<CXXBaseSpecifier> {};
+template <>
+struct DynTypedNode::BaseConverter<ObjCProtocolLoc, void>
+ : public ValueConverter<ObjCProtocolLoc> {};
+
+template <>
+struct DynTypedNode::BaseConverter<ConceptReference, void>
+ : public PtrConverter<ConceptReference> {};
+
// The only operation we allow on unsupported types is \c get.
// This allows to conveniently use \c DynTypedNode when having an arbitrary
// AST node that is not supported, but prevents misuse - a user cannot create
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h b/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h
index 8d2b23b3539a..398ffb188c95 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h
@@ -69,7 +69,12 @@ public:
return false;
}
- void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); }
+ void erase(unsigned I) {
+ if (I == Decls.size() - 1)
+ Decls.pop_back();
+ else
+ Decls[I] = Decls.pop_back_val();
+ }
void clear() { Decls.clear(); }
diff --git a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h
index 5505d661b44e..1f2797cc7014 100644
--- a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h
+++ b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h
@@ -6,22 +6,22 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_AST_ABSTRACTBASICREADER_H
-#define CLANG_AST_ABSTRACTBASICREADER_H
+#ifndef LLVM_CLANG_AST_ABSTRACTBASICREADER_H
+#define LLVM_CLANG_AST_ABSTRACTBASICREADER_H
#include "clang/AST/DeclTemplate.h"
+#include <optional>
namespace clang {
namespace serialization {
template <class T>
-inline T makeNullableFromOptional(const Optional<T> &value) {
+inline T makeNullableFromOptional(const std::optional<T> &value) {
return (value ? *value : T());
}
-template <class T>
-inline T *makePointerFromOptional(Optional<T *> value) {
- return (value ? *value : nullptr);
+template <class T> inline T *makePointerFromOptional(std::optional<T *> value) {
+ return value.value_or(nullptr);
}
// PropertyReader is a class concept that requires the following method:
@@ -49,7 +49,7 @@ inline T *makePointerFromOptional(Optional<T *> value) {
// type-specific readers for all the enum types.
//
// template <class ValueType>
-// Optional<ValueType> writeOptional();
+// std::optional<ValueType> writeOptional();
//
// Reads an optional value from the current property.
//
@@ -157,7 +157,7 @@ public:
}
template <class T, class... Args>
- llvm::Optional<T> readOptional(Args &&...args) {
+ std::optional<T> readOptional(Args &&...args) {
return UnpackOptionalValue<T>::unpack(
ReadDispatcher<T>::read(asImpl(), std::forward<Args>(args)...));
}
@@ -190,7 +190,8 @@ public:
APValue::LValuePathSerializationHelper readLValuePathSerializationHelper(
SmallVectorImpl<APValue::LValuePathEntry> &path) {
- auto elemTy = asImpl().readQualType();
+ auto origTy = asImpl().readQualType();
+ auto elemTy = origTy;
unsigned pathLength = asImpl().readUInt32();
for (unsigned i = 0; i < pathLength; ++i) {
if (elemTy->template getAs<RecordType>()) {
@@ -208,7 +209,7 @@ public:
APValue::LValuePathEntry::ArrayIndex(asImpl().readUInt32()));
}
}
- return APValue::LValuePathSerializationHelper(path, elemTy);
+ return APValue::LValuePathSerializationHelper(path, origTy);
}
Qualifiers readQualifiers() {
diff --git a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h
index 75aef734ba9b..07afa388de2c 100644
--- a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h
+++ b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h
@@ -6,25 +6,23 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_AST_ABSTRACTBASICWRITER_H
-#define CLANG_AST_ABSTRACTBASICWRITER_H
+#ifndef LLVM_CLANG_AST_ABSTRACTBASICWRITER_H
+#define LLVM_CLANG_AST_ABSTRACTBASICWRITER_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
+#include <optional>
namespace clang {
namespace serialization {
template <class T>
-inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
- return (value.isNull()
- ? llvm::Optional<T>()
- : llvm::Optional<T>(value));
+inline std::optional<T> makeOptionalFromNullable(const T &value) {
+ return (value.isNull() ? std::optional<T>() : std::optional<T>(value));
}
-template <class T>
-inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
- return (value ? llvm::Optional<T*>(value) : llvm::Optional<T*>());
+template <class T> inline std::optional<T *> makeOptionalFromPointer(T *value) {
+ return (value ? std::optional<T *>(value) : std::optional<T *>());
}
// PropertyWriter is a class concept that requires the following method:
@@ -51,7 +49,7 @@ inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
// type-specific writers for all the enum types.
//
// template <class ValueType>
-// void writeOptional(Optional<ValueType> value);
+// void writeOptional(std::optional<ValueType> value);
//
// Writes an optional value as the current property.
//
@@ -148,8 +146,7 @@ public:
}
}
- template <class T>
- void writeOptional(llvm::Optional<T> value) {
+ template <class T> void writeOptional(std::optional<T> value) {
WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h b/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h
index 9fea7b26f678..e44bbf61c0ed 100644
--- a/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h
+++ b/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h
@@ -6,11 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_AST_ABSTRACTTYPEREADER_H
-#define CLANG_AST_ABSTRACTTYPEREADER_H
+#ifndef LLVM_CLANG_AST_ABSTRACTTYPEREADER_H
+#define LLVM_CLANG_AST_ABSTRACTTYPEREADER_H
-#include "clang/AST/Type.h"
#include "clang/AST/AbstractBasicReader.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Type.h"
namespace clang {
namespace serialization {
diff --git a/contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h b/contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h
index a63cb0be099d..62006ef0f26e 100644
--- a/contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h
+++ b/contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_AST_ABSTRACTTYPEWRITER_H
-#define CLANG_AST_ABSTRACTTYPEWRITER_H
+#ifndef LLVM_CLANG_AST_ABSTRACTTYPEWRITER_H
+#define LLVM_CLANG_AST_ABSTRACTTYPEWRITER_H
#include "clang/AST/Type.h"
#include "clang/AST/AbstractBasicWriter.h"
diff --git a/contrib/llvm-project/clang/include/clang/AST/Attr.h b/contrib/llvm-project/clang/include/clang/AST/Attr.h
index dbfecc125049..8e9b7ad8b468 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Attr.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Attr.h
@@ -19,12 +19,13 @@
#include "clang/AST/Type.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/AttributeCommonInfo.h"
-#include "clang/Basic/LangOptions.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Frontend/HLSL/HLSLResource.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/raw_ostream.h"
@@ -34,28 +35,29 @@
namespace clang {
class ASTContext;
class AttributeCommonInfo;
-class IdentifierInfo;
-class ObjCInterfaceDecl;
-class Expr;
-class QualType;
class FunctionDecl;
-class TypeSourceInfo;
class OMPTraitInfo;
/// Attr - This represents one attribute.
class Attr : public AttributeCommonInfo {
private:
+ LLVM_PREFERRED_TYPE(attr::Kind)
unsigned AttrKind : 16;
protected:
/// An index into the spelling list of an
/// attribute defined in Attr.td file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Inherited : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsPackExpansion : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned Implicit : 1;
// FIXME: These are properties of the attribute kind, not state for this
// instance of the attribute.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsLateParsed : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned InheritEvenIfAlreadyPresent : 1;
void *operator new(size_t bytes) noexcept {
@@ -109,6 +111,8 @@ public:
// Pretty print this attribute.
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
+
+ static StringRef getDocumentation(attr::Kind);
};
class TypeAttr : public Attr {
@@ -193,6 +197,22 @@ public:
}
};
+class HLSLAnnotationAttr : public InheritableAttr {
+protected:
+ HLSLAnnotationAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
+ attr::Kind AK, bool IsLateParsed,
+ bool InheritEvenIfAlreadyPresent)
+ : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
+ InheritEvenIfAlreadyPresent) {}
+
+public:
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() >= attr::FirstHLSLAnnotationAttr &&
+ A->getKind() <= attr::LastHLSLAnnotationAttr;
+ }
+};
+
/// A parameter attribute which changes the argument-passing ABI rule
/// for the parameter.
class ParameterABIAttr : public InheritableParamAttr {
@@ -230,7 +250,9 @@ public:
class ParamIdx {
// Idx is exposed only via accessors that specify specific encodings.
unsigned Idx : 30;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasThis : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsValid : 1;
void assertComparable(const ParamIdx &I) const {
@@ -350,30 +372,11 @@ public:
static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
"ParamIdx does not fit its serialization type");
-/// Contains information gathered from parsing the contents of TargetAttr.
-struct ParsedTargetAttr {
- std::vector<std::string> Features;
- StringRef Architecture;
- StringRef Tune;
- StringRef BranchProtection;
- bool DuplicateArchitecture = false;
- bool DuplicateTune = false;
- bool operator ==(const ParsedTargetAttr &Other) const {
- return DuplicateArchitecture == Other.DuplicateArchitecture &&
- DuplicateTune == Other.DuplicateTune &&
- Architecture == Other.Architecture &&
- Tune == Other.Tune &&
- BranchProtection == Other.BranchProtection &&
- Features == Other.Features;
- }
-};
-
#include "clang/AST/Attrs.inc"
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const Attr *At) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
- DiagnosticsEngine::ak_attr);
+ DB.AddTaggedVal(reinterpret_cast<uint64_t>(At), DiagnosticsEngine::ak_attr);
return DB;
}
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/AttrIterator.h b/contrib/llvm-project/clang/include/clang/AST/AttrIterator.h
index 78ce9314a2bb..66571e1cf0b8 100644
--- a/contrib/llvm-project/clang/include/clang/AST/AttrIterator.h
+++ b/contrib/llvm-project/clang/include/clang/AST/AttrIterator.h
@@ -22,7 +22,6 @@
namespace clang {
-class ASTContext;
class Attr;
/// AttrVec - A vector of Attr, which is how they are stored on the AST.
diff --git a/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def b/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def
index 039765dfdfea..c04f6f6f1271 100644
--- a/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def
+++ b/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def
@@ -218,6 +218,9 @@ FLOATING_TYPE(BFloat16, BFloat16Ty)
// '__float128'
FLOATING_TYPE(Float128, Float128Ty)
+// '__ibm128'
+FLOATING_TYPE(Ibm128, Ibm128Ty)
+
//===- Language-specific types --------------------------------------------===//
// This is the type of C++0x 'nullptr'.
diff --git a/contrib/llvm-project/clang/include/clang/AST/CXXInheritance.h b/contrib/llvm-project/clang/include/clang/AST/CXXInheritance.h
index 946b9e318baa..bbef01843e0b 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CXXInheritance.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CXXInheritance.h
@@ -20,7 +20,6 @@
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -131,6 +130,7 @@ class CXXBasePaths {
/// class subobjects for that class type. The key of the map is
/// the cv-unqualified canonical type of the base class subobject.
struct IsVirtBaseAndNumberNonVirtBases {
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsVirtBase : 1;
unsigned NumberOfNonVirtBases : 31;
};
@@ -315,7 +315,7 @@ public:
/// virtual function; in abstract classes, the final overrider for at
/// least one virtual function is a pure virtual function. Due to
/// multiple, virtual inheritance, it is possible for a class to have
-/// more than one final overrider. Athough this is an error (per C++
+/// more than one final overrider. Although this is an error (per C++
/// [class.virtual]p2), it is not considered an error here: the final
/// overrider map can represent multiple final overriders for a
/// method, and it is up to the client to determine whether they are
diff --git a/contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
index 9b270682f8cf..cdf0804680ad 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
+++ b/contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def
@@ -112,6 +112,9 @@ FIELD(HasVariantMembers, 1, NO_MERGE)
/// True if there no non-field members declared by the user.
FIELD(HasOnlyCMembers, 1, NO_MERGE)
+/// True if there is an '__init' method defined by the user.
+FIELD(HasInitMethod, 1, NO_MERGE)
+
/// True if any field has an in-class initializer, including those
/// within anonymous unions or structs.
FIELD(HasInClassInitializer, 1, NO_MERGE)
diff --git a/contrib/llvm-project/clang/include/clang/AST/CanonicalType.h b/contrib/llvm-project/clang/include/clang/AST/CanonicalType.h
index 15d7e9efc26a..dde08f0394c9 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CanonicalType.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CanonicalType.h
@@ -305,7 +305,6 @@ public:
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
@@ -529,7 +528,7 @@ struct CanProxyAdaptor<FunctionProtoType>
template<>
struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnmodifiedType)
};
template<>
diff --git a/contrib/llvm-project/clang/include/clang/AST/CharUnits.h b/contrib/llvm-project/clang/include/clang/AST/CharUnits.h
index f14d3abf71e5..c06354451dfb 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CharUnits.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CharUnits.h
@@ -64,6 +64,12 @@ namespace clang {
return CharUnits(Quantity);
}
+ /// fromQuantity - Construct a CharUnits quantity from an llvm::Align
+ /// quantity.
+ static CharUnits fromQuantity(llvm::Align Quantity) {
+ return CharUnits(Quantity.value());
+ }
+
// Compound assignment.
CharUnits& operator+= (const CharUnits &Other) {
Quantity += Other.Quantity;
@@ -182,6 +188,13 @@ namespace clang {
/// Beware llvm::Align assumes power of two 8-bit bytes.
llvm::Align getAsAlign() const { return llvm::Align(Quantity); }
+ /// getAsMaybeAlign - Returns Quantity as a valid llvm::Align or
+ /// std::nullopt, Beware llvm::MaybeAlign assumes power of two 8-bit
+ /// bytes.
+ llvm::MaybeAlign getAsMaybeAlign() const {
+ return llvm::MaybeAlign(Quantity);
+ }
+
/// alignTo - Returns the next integer (mod 2**64) that is
/// greater than or equal to this quantity and is a multiple of \p Align.
/// Align must be non-zero.
diff --git a/contrib/llvm-project/clang/include/clang/AST/Comment.h b/contrib/llvm-project/clang/include/clang/AST/Comment.h
index 54a4b0a9cfe6..dd9906727293 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Comment.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Comment.h
@@ -27,6 +27,8 @@ class TemplateParameterList;
namespace comments {
class FullComment;
+enum class InlineCommandRenderKind;
+enum class ParamCommandPassDirection;
/// Describes the syntax that was used in a documentation command.
///
@@ -47,6 +49,17 @@ enum CommandMarkerKind {
CMK_At = 1
};
+enum class CommentKind {
+ None = 0,
+#define COMMENT(CLASS, PARENT) CLASS,
+#define COMMENT_RANGE(BASE, FIRST, LAST) \
+ First##BASE##Constant = FIRST, Last##BASE##Constant = LAST,
+#define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
+ First##BASE##Constant = FIRST, Last##BASE##Constant = LAST
+#define ABSTRACT_COMMENT(COMMENT)
+#include "clang/AST/CommentNodes.inc"
+};
+
/// Any part of the comment.
/// Abstract class.
class Comment {
@@ -61,6 +74,7 @@ protected:
friend class Comment;
/// Type of this AST node.
+ LLVM_PREFERRED_TYPE(CommentKind)
unsigned Kind : 8;
};
enum { NumCommentBits = 8 };
@@ -68,10 +82,12 @@ protected:
class InlineContentCommentBitfields {
friend class InlineContentComment;
+ LLVM_PREFERRED_TYPE(CommentBitfields)
unsigned : NumCommentBits;
/// True if there is a newline after this inline content node.
/// (There is no separate AST node for a newline.)
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTrailingNewline : 1;
};
enum { NumInlineContentCommentBits = NumCommentBits + 1 };
@@ -79,12 +95,15 @@ protected:
class TextCommentBitfields {
friend class TextComment;
+ LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
unsigned : NumInlineContentCommentBits;
/// True if \c IsWhitespace field contains a valid value.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IsWhitespaceValid : 1;
/// True if this comment AST node contains only whitespace.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IsWhitespace : 1;
};
enum { NumTextCommentBits = NumInlineContentCommentBits + 2 };
@@ -92,10 +111,13 @@ protected:
class InlineCommandCommentBitfields {
friend class InlineCommandComment;
+ LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
unsigned : NumInlineContentCommentBits;
+ LLVM_PREFERRED_TYPE(InlineCommandRenderKind)
unsigned RenderKind : 3;
+ LLVM_PREFERRED_TYPE(CommandTraits::KnownCommandIDs)
unsigned CommandID : CommandInfo::NumCommandIDBits;
};
enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 3 +
@@ -104,9 +126,11 @@ protected:
class HTMLTagCommentBitfields {
friend class HTMLTagComment;
+ LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
unsigned : NumInlineContentCommentBits;
/// True if we found that this tag is malformed in some way.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsMalformed : 1;
};
enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 };
@@ -114,10 +138,12 @@ protected:
class HTMLStartTagCommentBitfields {
friend class HTMLStartTagComment;
+ LLVM_PREFERRED_TYPE(HTMLTagCommentBitfields)
unsigned : NumHTMLTagCommentBits;
/// True if this tag is self-closing (e. g., <br />). This is based on tag
/// spelling in comment (plain <br> would not set this flag).
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsSelfClosing : 1;
};
enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 };
@@ -125,12 +151,15 @@ protected:
class ParagraphCommentBitfields {
friend class ParagraphComment;
+ LLVM_PREFERRED_TYPE(CommentBitfields)
unsigned : NumCommentBits;
/// True if \c IsWhitespace field contains a valid value.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IsWhitespaceValid : 1;
/// True if this comment AST node contains only whitespace.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IsWhitespace : 1;
};
enum { NumParagraphCommentBits = NumCommentBits + 2 };
@@ -138,12 +167,15 @@ protected:
class BlockCommandCommentBitfields {
friend class BlockCommandComment;
+ LLVM_PREFERRED_TYPE(CommentBitfields)
unsigned : NumCommentBits;
+ LLVM_PREFERRED_TYPE(CommandTraits::KnownCommandIDs)
unsigned CommandID : CommandInfo::NumCommandIDBits;
/// Describes the syntax that was used in a documentation command.
/// Contains values from CommandMarkerKind enum.
+ LLVM_PREFERRED_TYPE(CommandMarkerKind)
unsigned CommandMarker : 1;
};
enum { NumBlockCommandCommentBits = NumCommentBits +
@@ -152,12 +184,15 @@ protected:
class ParamCommandCommentBitfields {
friend class ParamCommandComment;
+ LLVM_PREFERRED_TYPE(BlockCommandCommentBitfields)
unsigned : NumBlockCommandCommentBits;
- /// Parameter passing direction, see ParamCommandComment::PassDirection.
+ /// Parameter passing direction.
+ LLVM_PREFERRED_TYPE(ParamCommandPassDirection)
unsigned Direction : 2;
/// True if direction was specified explicitly in the comment.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsDirectionExplicit : 1;
};
enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 };
@@ -183,22 +218,16 @@ protected:
}
public:
- enum CommentKind {
- NoCommentKind = 0,
-#define COMMENT(CLASS, PARENT) CLASS##Kind,
-#define COMMENT_RANGE(BASE, FIRST, LAST) \
- First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind,
-#define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
- First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind
-#define ABSTRACT_COMMENT(COMMENT)
-#include "clang/AST/CommentNodes.inc"
+ struct Argument {
+ SourceRange Range;
+ StringRef Text;
};
Comment(CommentKind K,
SourceLocation LocBegin,
SourceLocation LocEnd) :
Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) {
- CommentBits.Kind = K;
+ CommentBits.Kind = llvm::to_underlying(K);
}
CommentKind getCommentKind() const {
@@ -244,8 +273,9 @@ protected:
public:
static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstInlineContentCommentConstant &&
- C->getCommentKind() <= LastInlineContentCommentConstant;
+ return C->getCommentKind() >=
+ CommentKind::FirstInlineContentCommentConstant &&
+ C->getCommentKind() <= CommentKind::LastInlineContentCommentConstant;
}
void addTrailingNewline() {
@@ -262,16 +292,14 @@ class TextComment : public InlineContentComment {
StringRef Text;
public:
- TextComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef Text) :
- InlineContentComment(TextCommentKind, LocBegin, LocEnd),
- Text(Text) {
+ TextComment(SourceLocation LocBegin, SourceLocation LocEnd, StringRef Text)
+ : InlineContentComment(CommentKind::TextComment, LocBegin, LocEnd),
+ Text(Text) {
TextCommentBits.IsWhitespaceValid = false;
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == TextCommentKind;
+ return C->getCommentKind() == CommentKind::TextComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -293,44 +321,35 @@ private:
bool isWhitespaceNoCache() const;
};
+/// The most appropriate rendering mode for this command, chosen on command
+/// semantics in Doxygen.
+enum class InlineCommandRenderKind {
+ Normal,
+ Bold,
+ Monospaced,
+ Emphasized,
+ Anchor
+};
+
/// A command with word-like arguments that is considered inline content.
class InlineCommandComment : public InlineContentComment {
-public:
- struct Argument {
- SourceRange Range;
- StringRef Text;
-
- Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
- };
-
- /// The most appropriate rendering mode for this command, chosen on command
- /// semantics in Doxygen.
- enum RenderKind {
- RenderNormal,
- RenderBold,
- RenderMonospaced,
- RenderEmphasized,
- RenderAnchor
- };
-
protected:
/// Command arguments.
ArrayRef<Argument> Args;
public:
- InlineCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- RenderKind RK,
- ArrayRef<Argument> Args) :
- InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
- Args(Args) {
- InlineCommandCommentBits.RenderKind = RK;
+ InlineCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID, InlineCommandRenderKind RK,
+ ArrayRef<Argument> Args)
+ : InlineContentComment(CommentKind::InlineCommandComment, LocBegin,
+ LocEnd),
+ Args(Args) {
+ InlineCommandCommentBits.RenderKind = llvm::to_underlying(RK);
InlineCommandCommentBits.CommandID = CommandID;
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == InlineCommandCommentKind;
+ return C->getCommentKind() == CommentKind::InlineCommandComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -349,8 +368,9 @@ public:
return SourceRange(getBeginLoc().getLocWithOffset(-1), getEndLoc());
}
- RenderKind getRenderKind() const {
- return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind);
+ InlineCommandRenderKind getRenderKind() const {
+ return static_cast<InlineCommandRenderKind>(
+ InlineCommandCommentBits.RenderKind);
}
unsigned getNumArgs() const {
@@ -388,8 +408,8 @@ protected:
public:
static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstHTMLTagCommentConstant &&
- C->getCommentKind() <= LastHTMLTagCommentConstant;
+ return C->getCommentKind() >= CommentKind::FirstHTMLTagCommentConstant &&
+ C->getCommentKind() <= CommentKind::LastHTMLTagCommentConstant;
}
StringRef getTagName() const LLVM_READONLY { return TagName; }
@@ -424,19 +444,13 @@ public:
Attribute() { }
- Attribute(SourceLocation NameLocBegin, StringRef Name) :
- NameLocBegin(NameLocBegin), Name(Name),
- EqualsLoc(SourceLocation()),
- ValueRange(SourceRange()), Value(StringRef())
- { }
+ Attribute(SourceLocation NameLocBegin, StringRef Name)
+ : NameLocBegin(NameLocBegin), Name(Name), EqualsLoc(SourceLocation()) {}
Attribute(SourceLocation NameLocBegin, StringRef Name,
- SourceLocation EqualsLoc,
- SourceRange ValueRange, StringRef Value) :
- NameLocBegin(NameLocBegin), Name(Name),
- EqualsLoc(EqualsLoc),
- ValueRange(ValueRange), Value(Value)
- { }
+ SourceLocation EqualsLoc, SourceRange ValueRange, StringRef Value)
+ : NameLocBegin(NameLocBegin), Name(Name), EqualsLoc(EqualsLoc),
+ ValueRange(ValueRange), Value(Value) {}
SourceLocation getNameLocEnd() const {
return NameLocBegin.getLocWithOffset(Name.size());
@@ -451,18 +465,16 @@ private:
ArrayRef<Attribute> Attributes;
public:
- HTMLStartTagComment(SourceLocation LocBegin,
- StringRef TagName) :
- HTMLTagComment(HTMLStartTagCommentKind,
- LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()),
- TagName,
- LocBegin.getLocWithOffset(1),
- LocBegin.getLocWithOffset(1 + TagName.size())) {
+ HTMLStartTagComment(SourceLocation LocBegin, StringRef TagName)
+ : HTMLTagComment(CommentKind::HTMLStartTagComment, LocBegin,
+ LocBegin.getLocWithOffset(1 + TagName.size()), TagName,
+ LocBegin.getLocWithOffset(1),
+ LocBegin.getLocWithOffset(1 + TagName.size())) {
HTMLStartTagCommentBits.IsSelfClosing = false;
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == HTMLStartTagCommentKind;
+ return C->getCommentKind() == CommentKind::HTMLStartTagComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -506,18 +518,14 @@ public:
/// A closing HTML tag.
class HTMLEndTagComment : public HTMLTagComment {
public:
- HTMLEndTagComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef TagName) :
- HTMLTagComment(HTMLEndTagCommentKind,
- LocBegin, LocEnd,
- TagName,
- LocBegin.getLocWithOffset(2),
- LocBegin.getLocWithOffset(2 + TagName.size()))
- { }
+ HTMLEndTagComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ StringRef TagName)
+ : HTMLTagComment(CommentKind::HTMLEndTagComment, LocBegin, LocEnd,
+ TagName, LocBegin.getLocWithOffset(2),
+ LocBegin.getLocWithOffset(2 + TagName.size())) {}
static bool classof(const Comment *C) {
- return C->getCommentKind() == HTMLEndTagCommentKind;
+ return C->getCommentKind() == CommentKind::HTMLEndTagComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -537,8 +545,9 @@ protected:
public:
static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstBlockContentCommentConstant &&
- C->getCommentKind() <= LastBlockContentCommentConstant;
+ return C->getCommentKind() >=
+ CommentKind::FirstBlockContentCommentConstant &&
+ C->getCommentKind() <= CommentKind::LastBlockContentCommentConstant;
}
};
@@ -547,11 +556,10 @@ class ParagraphComment : public BlockContentComment {
ArrayRef<InlineContentComment *> Content;
public:
- ParagraphComment(ArrayRef<InlineContentComment *> Content) :
- BlockContentComment(ParagraphCommentKind,
- SourceLocation(),
- SourceLocation()),
- Content(Content) {
+ ParagraphComment(ArrayRef<InlineContentComment *> Content)
+ : BlockContentComment(CommentKind::ParagraphComment, SourceLocation(),
+ SourceLocation()),
+ Content(Content) {
if (Content.empty()) {
ParagraphCommentBits.IsWhitespace = true;
ParagraphCommentBits.IsWhitespaceValid = true;
@@ -566,7 +574,7 @@ public:
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == ParagraphCommentKind;
+ return C->getCommentKind() == CommentKind::ParagraphComment;
}
child_iterator child_begin() const {
@@ -594,15 +602,6 @@ private:
/// arguments depends on command name) and a paragraph as an argument
/// (e. g., \\brief).
class BlockCommandComment : public BlockContentComment {
-public:
- struct Argument {
- SourceRange Range;
- StringRef Text;
-
- Argument() { }
- Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
- };
-
protected:
/// Word-like arguments.
ArrayRef<Argument> Args;
@@ -623,20 +622,19 @@ protected:
}
public:
- BlockCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
- Paragraph(nullptr) {
+ BlockCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID, CommandMarkerKind CommandMarker)
+ : BlockContentComment(CommentKind::BlockCommandComment, LocBegin, LocEnd),
+ Paragraph(nullptr) {
setLocation(getCommandNameBeginLoc());
BlockCommandCommentBits.CommandID = CommandID;
BlockCommandCommentBits.CommandMarker = CommandMarker;
}
static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstBlockCommandCommentConstant &&
- C->getCommentKind() <= LastBlockCommandCommentConstant;
+ return C->getCommentKind() >=
+ CommentKind::FirstBlockCommandCommentConstant &&
+ C->getCommentKind() <= CommentKind::LastBlockCommandCommentConstant;
}
child_iterator child_begin() const {
@@ -707,6 +705,8 @@ public:
}
};
+enum class ParamCommandPassDirection { In, Out, InOut };
+
/// Doxygen \\param command.
class ParamCommandComment : public BlockCommandComment {
private:
@@ -719,39 +719,33 @@ public:
VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
};
- ParamCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
- CommandID, CommandMarker),
- ParamIndex(InvalidParamIndex) {
- ParamCommandCommentBits.Direction = In;
+ ParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID, CommandMarkerKind CommandMarker)
+ : BlockCommandComment(CommentKind::ParamCommandComment, LocBegin, LocEnd,
+ CommandID, CommandMarker),
+ ParamIndex(InvalidParamIndex) {
+ ParamCommandCommentBits.Direction =
+ llvm::to_underlying(ParamCommandPassDirection::In);
ParamCommandCommentBits.IsDirectionExplicit = false;
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == ParamCommandCommentKind;
+ return C->getCommentKind() == CommentKind::ParamCommandComment;
}
- enum PassDirection {
- In,
- Out,
- InOut
- };
-
- static const char *getDirectionAsString(PassDirection D);
+ static const char *getDirectionAsString(ParamCommandPassDirection D);
- PassDirection getDirection() const LLVM_READONLY {
- return static_cast<PassDirection>(ParamCommandCommentBits.Direction);
+ ParamCommandPassDirection getDirection() const LLVM_READONLY {
+ return static_cast<ParamCommandPassDirection>(
+ ParamCommandCommentBits.Direction);
}
bool isDirectionExplicit() const LLVM_READONLY {
return ParamCommandCommentBits.IsDirectionExplicit;
}
- void setDirection(PassDirection Direction, bool Explicit) {
- ParamCommandCommentBits.Direction = Direction;
+ void setDirection(ParamCommandPassDirection Direction, bool Explicit) {
+ ParamCommandCommentBits.Direction = llvm::to_underlying(Direction);
ParamCommandCommentBits.IsDirectionExplicit = Explicit;
}
@@ -813,16 +807,13 @@ private:
ArrayRef<unsigned> Position;
public:
- TParamCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID,
- CommandMarker)
- { }
+ TParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID, CommandMarkerKind CommandMarker)
+ : BlockCommandComment(CommentKind::TParamCommandComment, LocBegin, LocEnd,
+ CommandID, CommandMarker) {}
static bool classof(const Comment *C) {
- return C->getCommentKind() == TParamCommandCommentKind;
+ return C->getCommentKind() == CommentKind::TParamCommandComment;
}
bool hasParamName() const {
@@ -864,16 +855,13 @@ class VerbatimBlockLineComment : public Comment {
StringRef Text;
public:
- VerbatimBlockLineComment(SourceLocation LocBegin,
- StringRef Text) :
- Comment(VerbatimBlockLineCommentKind,
- LocBegin,
- LocBegin.getLocWithOffset(Text.size())),
- Text(Text)
- { }
+ VerbatimBlockLineComment(SourceLocation LocBegin, StringRef Text)
+ : Comment(CommentKind::VerbatimBlockLineComment, LocBegin,
+ LocBegin.getLocWithOffset(Text.size())),
+ Text(Text) {}
static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimBlockLineCommentKind;
+ return C->getCommentKind() == CommentKind::VerbatimBlockLineComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -895,16 +883,15 @@ protected:
ArrayRef<VerbatimBlockLineComment *> Lines;
public:
- VerbatimBlockComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID) :
- BlockCommandComment(VerbatimBlockCommentKind,
- LocBegin, LocEnd, CommandID,
- CMK_At) // FIXME: improve source fidelity.
- { }
+ VerbatimBlockComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID)
+ : BlockCommandComment(CommentKind::VerbatimBlockComment, LocBegin, LocEnd,
+ CommandID,
+ CMK_At) // FIXME: improve source fidelity.
+ {}
static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimBlockCommentKind;
+ return C->getCommentKind() == CommentKind::VerbatimBlockComment;
}
child_iterator child_begin() const {
@@ -946,21 +933,16 @@ protected:
SourceLocation TextBegin;
public:
- VerbatimLineComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- SourceLocation TextBegin,
- StringRef Text) :
- BlockCommandComment(VerbatimLineCommentKind,
- LocBegin, LocEnd,
- CommandID,
- CMK_At), // FIXME: improve source fidelity.
- Text(Text),
- TextBegin(TextBegin)
- { }
+ VerbatimLineComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID, SourceLocation TextBegin,
+ StringRef Text)
+ : BlockCommandComment(CommentKind::VerbatimLineComment, LocBegin, LocEnd,
+ CommandID,
+ CMK_At), // FIXME: improve source fidelity.
+ Text(Text), TextBegin(TextBegin) {}
static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimLineCommentKind;
+ return C->getCommentKind() == CommentKind::VerbatimLineComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -1019,8 +1001,6 @@ struct DeclInfo {
/// \li member function template,
/// \li member function template specialization,
/// \li ObjC method,
- /// \li a typedef for a function pointer, member function pointer,
- /// ObjC block.
FunctionKind,
/// Something that we consider a "class":
@@ -1030,8 +1010,8 @@ struct DeclInfo {
ClassKind,
/// Something that we consider a "variable":
- /// \li namespace scope variables;
- /// \li static and non-static class data members;
+ /// \li namespace scope variables and variable templates;
+ /// \li static and non-static class data members and member templates;
/// \li enumerators.
VariableKind,
@@ -1055,27 +1035,37 @@ struct DeclInfo {
};
/// If false, only \c CommentDecl is valid.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsFilled : 1;
/// Simplified kind of \c CommentDecl, see \c DeclKind enum.
+ LLVM_PREFERRED_TYPE(DeclKind)
unsigned Kind : 3;
/// Is \c CommentDecl a template declaration.
+ LLVM_PREFERRED_TYPE(TemplateDeclKind)
unsigned TemplateKind : 2;
/// Is \c CommentDecl an ObjCMethodDecl.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsObjCMethod : 1;
/// Is \c CommentDecl a non-static member function of C++ class or
/// instance method of ObjC class.
/// Can be true only if \c IsFunctionDecl is true.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsInstanceMethod : 1;
/// Is \c CommentDecl a static member function of C++ class or
/// class method of ObjC class.
/// Can be true only if \c IsFunctionDecl is true.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsClassMethod : 1;
+ /// Is \c CommentDecl something we consider a "function" that's variadic.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsVariadic : 1;
+
void fill();
DeclKind getKind() const LLVM_READONLY {
@@ -1085,6 +1075,8 @@ struct DeclInfo {
TemplateDeclKind getTemplateKind() const LLVM_READONLY {
return static_cast<TemplateDeclKind>(TemplateKind);
}
+
+ bool involvesFunctionType() const { return !ReturnType.isNull(); }
};
/// A full comment attached to a declaration, contains block content.
@@ -1093,9 +1085,9 @@ class FullComment : public Comment {
DeclInfo *ThisDeclInfo;
public:
- FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
- Comment(FullCommentKind, SourceLocation(), SourceLocation()),
- Blocks(Blocks), ThisDeclInfo(D) {
+ FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D)
+ : Comment(CommentKind::FullComment, SourceLocation(), SourceLocation()),
+ Blocks(Blocks), ThisDeclInfo(D) {
if (Blocks.empty())
return;
@@ -1105,7 +1097,7 @@ public:
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == FullCommentKind;
+ return C->getCommentKind() == CommentKind::FullComment;
}
child_iterator child_begin() const {
diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td b/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td
index fbbfc9f7e0b7..e839031752cd 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td
@@ -31,6 +31,7 @@ class Command<string name> {
}
class InlineCommand<string name> : Command<name> {
+ let NumArgs = 1;
let IsInlineCommand = 1;
}
@@ -62,6 +63,11 @@ class VerbatimLineCommand<string name> : Command<name> {
let IsVerbatimLineCommand = 1;
}
+class PropertyCommand<string name> : Command<name> {
+ let NumArgs = 0;
+ let IsInlineCommand = 1;
+}
+
class DeclarationVerbatimLineCommand<string name> :
VerbatimLineCommand<name> {
let IsDeclarationCommand = 1;
@@ -86,9 +92,23 @@ def C : InlineCommand<"c">;
def P : InlineCommand<"p">;
def A : InlineCommand<"a">;
def E : InlineCommand<"e">;
+def N : InlineCommand<"n"> { let NumArgs = 0; }
def Em : InlineCommand<"em">;
-def Ref : InlineCommand<"ref">;
-def Anchor : InlineCommand<"anchor">;
+def Emoji : InlineCommand<"emoji">;
+
+def Anchor : InlineCommand<"anchor">;
+def Ref : InlineCommand<"ref">;
+def RefItem : InlineCommand<"refitem">;
+def Cite : InlineCommand<"cite">;
+
+def CopyBrief : InlineCommand<"copybrief">;
+def CopyDetails : InlineCommand<"copydetails">;
+def CopyDoc : InlineCommand<"copydoc">;
+
+// Typically not used inline, but they take a single word.
+def Extends : InlineCommand<"extends">;
+def Implements : InlineCommand<"implements">;
+def MemberOf : InlineCommand<"memberof">;
//===----------------------------------------------------------------------===//
// BlockCommand
@@ -141,13 +161,15 @@ def Post : BlockCommand<"post">;
def Pre : BlockCommand<"pre">;
def Remark : BlockCommand<"remark">;
def Remarks : BlockCommand<"remarks">;
-def Retval : BlockCommand<"retval">;
+def Retval : BlockCommand<"retval"> { let NumArgs = 1; }
def Sa : BlockCommand<"sa">;
def See : BlockCommand<"see">;
def Since : BlockCommand<"since">;
+def Test : BlockCommand<"test">;
def Todo : BlockCommand<"todo">;
def Version : BlockCommand<"version">;
def Warning : BlockCommand<"warning">;
+def XRefItem : BlockCommand<"xrefitem"> { let NumArgs = 3; }
// HeaderDoc commands
def Abstract : BlockCommand<"abstract"> { let IsBriefCommand = 1; }
def ClassDesign : RecordLikeDetailCommand<"classdesign">;
@@ -170,6 +192,8 @@ def SuperClass : RecordLikeDetailCommand<"superclass">;
defm Code : VerbatimBlockCommand<"code", "endcode">;
defm Verbatim : VerbatimBlockCommand<"verbatim", "endverbatim">;
+
+defm DocbookOnly : VerbatimBlockCommand<"docbookonly", "enddocbookonly">;
defm Htmlonly : VerbatimBlockCommand<"htmlonly", "endhtmlonly">;
defm Latexonly : VerbatimBlockCommand<"latexonly", "endlatexonly">;
defm Xmlonly : VerbatimBlockCommand<"xmlonly", "endxmlonly">;
@@ -178,10 +202,19 @@ defm Rtfonly : VerbatimBlockCommand<"rtfonly", "endrtfonly">;
defm Dot : VerbatimBlockCommand<"dot", "enddot">;
defm Msc : VerbatimBlockCommand<"msc", "endmsc">;
+defm Uml : VerbatimBlockCommand<"startuml", "enduml">;
+
+// Actually not verbatim blocks, we should also parse commands within them.
+defm Internal : VerbatimBlockCommand<"internal", "endinternal">;
+// TODO: conflicts with HeaderDoc link, /link.
+//defm Link : VerbatimBlockCommand<"link", "endlink">;
+defm ParBlock : VerbatimBlockCommand<"parblock", "endparblock">;
+defm SecRefList : VerbatimBlockCommand<"secreflist", "endsecreflist">;
// These three commands have special support in CommentLexer to recognize their
// names.
def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula
+defm FParen : VerbatimBlockCommand<"f(", "f)">; // Inline LaTeX text
defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula
defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment
@@ -199,11 +232,18 @@ def Addtogroup : VerbatimLineCommand<"addtogroup">;
def Weakgroup : VerbatimLineCommand<"weakgroup">;
def Name : VerbatimLineCommand<"name">;
+// These actually take a single word, but it's optional.
+// And they're used on a separate line typically, not inline.
+def Dir : VerbatimLineCommand<"dir">;
+def File : VerbatimLineCommand<"file">;
+
def Section : VerbatimLineCommand<"section">;
def Subsection : VerbatimLineCommand<"subsection">;
def Subsubsection : VerbatimLineCommand<"subsubsection">;
def Paragraph : VerbatimLineCommand<"paragraph">;
+def TableOfContents : VerbatimLineCommand<"tableofcontents">;
+def Page : VerbatimLineCommand<"page">;
def Mainpage : VerbatimLineCommand<"mainpage">;
def Subpage : VerbatimLineCommand<"subpage">;
@@ -212,13 +252,80 @@ def Related : VerbatimLineCommand<"related">;
def RelatesAlso : VerbatimLineCommand<"relatesalso">;
def RelatedAlso : VerbatimLineCommand<"relatedalso">;
+def AddIndex : VerbatimLineCommand<"addindex">;
+
+// These take a single argument mostly, but since they include a file they'll
+// typically be on their own line.
+def DocbookInclude : VerbatimLineCommand<"docbookinclude">;
+def DontInclude : VerbatimLineCommand<"dontinclude">;
+def Example : VerbatimLineCommand<"example">;
+def HtmlInclude : VerbatimLineCommand<"htmlinclude">;
+def Include : VerbatimLineCommand<"include">;
+def ManInclude : VerbatimLineCommand<"maninclude">;
+def LatexInclude : VerbatimLineCommand<"latexinclude">;
+def RtfInclude : VerbatimLineCommand<"rtfinclude">;
+def Snippet : VerbatimLineCommand<"snippet">;
+def VerbInclude : VerbatimLineCommand<"verbinclude">;
+def XmlInclude : VerbatimLineCommand<"xmlinclude">;
+
+def Image : VerbatimLineCommand<"image">;
+def DotFile : VerbatimLineCommand<"dotfile">;
+def MscFile : VerbatimLineCommand<"mscfile">;
+def DiaFile : VerbatimLineCommand<"diafile">;
+
+def Line : VerbatimLineCommand<"line">;
+def Skip : VerbatimLineCommand<"skip">;
+def SkipLine : VerbatimLineCommand<"skipline">;
+def Until : VerbatimLineCommand<"until">;
+
+def NoOp : VerbatimLineCommand<"noop">;
+
+// We might also build proper support for if/ifnot/else/elseif/endif.
+def If : VerbatimLineCommand<"if">;
+def IfNot : VerbatimLineCommand<"ifnot">;
+def Else : VerbatimLineCommand<"else">;
+def ElseIf : VerbatimLineCommand<"elseif">;
+def Endif : VerbatimLineCommand<"endif">;
+
+// Not treated as VerbatimBlockCommand because it spans multiple comments.
+def Cond : VerbatimLineCommand<"cond">;
+def EndCond : VerbatimLineCommand<"endcond">;
+
+//===----------------------------------------------------------------------===//
+// PropertyCommand
+//===----------------------------------------------------------------------===//
+
+def CallGraph : PropertyCommand<"callgraph">;
+def HideCallGraph : PropertyCommand<"hidecallgraph">;
+def CallerGraph : PropertyCommand<"callergraph">;
+def HideCallerGraph : PropertyCommand<"hidecallergraph">;
+def ShowInitializer : PropertyCommand<"showinitializer">;
+def HideInitializer : PropertyCommand<"hideinitializer">;
+def ShowRefBy : PropertyCommand<"showrefby">;
+def HideRefBy : PropertyCommand<"hiderefby">;
+def ShowRefs : PropertyCommand<"showrefs">;
+def HideRefs : PropertyCommand<"hiderefs">;
+
+def Private : PropertyCommand<"private">;
+def Protected : PropertyCommand<"protected">;
+def Public : PropertyCommand<"public">;
+def Pure : PropertyCommand<"pure">;
+def Static : PropertyCommand<"static">;
+
+def NoSubgrouping : PropertyCommand<"nosubgrouping">;
+def PrivateSection : PropertyCommand<"privatesection">;
+def ProtectedSection : PropertyCommand<"protectedsection">;
+def PublicSection : PropertyCommand<"publicsection">;
+
//===----------------------------------------------------------------------===//
// DeclarationVerbatimLineCommand
//===----------------------------------------------------------------------===//
// Doxygen commands.
+def Concept : DeclarationVerbatimLineCommand<"concept">;
def Def : DeclarationVerbatimLineCommand<"def">;
def Fn : DeclarationVerbatimLineCommand<"fn">;
+def IDLExcept : DeclarationVerbatimLineCommand<"idlexcept">;
def Namespace : DeclarationVerbatimLineCommand<"namespace">;
def Overload : DeclarationVerbatimLineCommand<"overload">;
def Property : DeclarationVerbatimLineCommand<"property">;
diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentHTMLTags.td b/contrib/llvm-project/clang/include/clang/AST/CommentHTMLTags.td
index 251490094940..a1ce8c6da96c 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentHTMLTags.td
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentHTMLTags.td
@@ -52,11 +52,11 @@ def Tr : Tag<"tr"> { let EndTagOptional = 1; }
def Th : Tag<"th"> { let EndTagOptional = 1; }
def Td : Tag<"td"> { let EndTagOptional = 1; }
-// Define a blacklist of attributes that are not safe to pass through to HTML
+// Define a list of attributes that are not safe to pass through to HTML
// output if the input is untrusted.
//
-// FIXME: this should be a whitelist. When changing this to a whitelist, don't
-// forget to change the default in the TableGen backend.
+// FIXME: This should be a list of attributes that _are_ safe. When changing
+// this change, don't forget to change the default in the TableGen backend.
class Attribute<string spelling> {
string Spelling = spelling;
bit IsSafeToPassThrough = 1;
diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentLexer.h b/contrib/llvm-project/clang/include/clang/AST/CommentLexer.h
index 94f778501e75..9aa1681cb2c5 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentLexer.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentLexer.h
@@ -320,6 +320,9 @@ private:
/// Eat string matching regexp \code \s*\* \endcode.
void skipLineStartingDecorations();
+ /// Skip over pure text.
+ const char *skipTextToken();
+
/// Lex comment text, including commands if ParseCommands is set to true.
void lexCommentText(Token &T);
diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentParser.h b/contrib/llvm-project/clang/include/clang/AST/CommentParser.h
index 1a0cfb06e52b..e11e818b1af0 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentParser.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentParser.h
@@ -97,9 +97,8 @@ public:
void parseTParamCommandArgs(TParamCommandComment *TPC,
TextTokenRetokenizer &Retokenizer);
- void parseBlockCommandArgs(BlockCommandComment *BC,
- TextTokenRetokenizer &Retokenizer,
- unsigned NumArgs);
+ ArrayRef<Comment::Argument>
+ parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs);
BlockCommandComment *parseBlockCommand();
InlineCommandComment *parseInlineCommand();
diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentSema.h b/contrib/llvm-project/clang/include/clang/AST/CommentSema.h
index 6dfe0f4920d0..03f13283ac0d 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentSema.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentSema.h
@@ -80,7 +80,7 @@ public:
ArrayRef<T> copyArray(ArrayRef<T> Source) {
if (!Source.empty())
return Source.copy(Allocator);
- return None;
+ return std::nullopt;
}
ParagraphComment *actOnParagraphComment(
@@ -130,14 +130,8 @@ public:
InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
SourceLocation CommandLocEnd,
- unsigned CommandID);
-
- InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
- SourceLocation CommandLocEnd,
unsigned CommandID,
- SourceLocation ArgLocBegin,
- SourceLocation ArgLocEnd,
- StringRef Arg);
+ ArrayRef<Comment::Argument> Args);
InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
SourceLocation LocEnd,
@@ -181,6 +175,7 @@ public:
FullComment *actOnFullComment(ArrayRef<BlockContentComment *> Blocks);
+private:
void checkBlockCommandEmptyParagraph(BlockCommandComment *Command);
void checkReturnsCommand(const BlockCommandComment *Command);
@@ -198,19 +193,19 @@ public:
void checkContainerDecl(const BlockCommandComment *Comment);
/// Resolve parameter names to parameter indexes in function declaration.
- /// Emit diagnostics about unknown parametrs.
+ /// Emit diagnostics about unknown parameters.
void resolveParamCommandIndexes(const FullComment *FC);
+ /// \returns \c true if the declaration that this comment is attached to
+ /// is a pointer to function/method/block type or has such a type.
+ bool involvesFunctionType();
+
bool isFunctionDecl();
bool isAnyFunctionDecl();
/// \returns \c true if declaration that this comment is attached to declares
/// a function pointer.
bool isFunctionPointerVarDecl();
- /// \returns \c true if the declaration that this comment is attached to
- /// declares a variable or a field whose type is a function or a block
- /// pointer.
- bool isFunctionOrBlockPointerVarLikeDecl();
bool isFunctionOrMethodVariadic();
bool isObjCMethodDecl();
bool isObjCPropertyDecl();
@@ -249,8 +244,7 @@ public:
StringRef Typo,
const TemplateParameterList *TemplateParameters);
- InlineCommandComment::RenderKind
- getInlineCommandRenderKind(StringRef Name) const;
+ InlineCommandRenderKind getInlineCommandRenderKind(StringRef Name) const;
};
} // end namespace comments
diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentVisitor.h b/contrib/llvm-project/clang/include/clang/AST/CommentVisitor.h
index d9a7439f7cc0..bbb624a23e68 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentVisitor.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentVisitor.h
@@ -31,8 +31,9 @@ public:
switch (C->getCommentKind()) {
default: llvm_unreachable("Unknown comment kind!");
#define ABSTRACT_COMMENT(COMMENT)
-#define COMMENT(CLASS, PARENT) \
- case Comment::CLASS##Kind: DISPATCH(CLASS, CLASS);
+#define COMMENT(CLASS, PARENT) \
+ case CommentKind::CLASS: \
+ DISPATCH(CLASS, CLASS);
#include "clang/AST/CommentNodes.inc"
#undef ABSTRACT_COMMENT
#undef COMMENT
diff --git a/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h b/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h
index b41e934142ee..b4ad37e394ce 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/DenseMap.h"
#include <array>
#include <cassert>
+#include <optional>
#include <vector>
namespace llvm {
@@ -38,9 +39,8 @@ class NamespaceDecl;
/// An enumeration representing the different comparison categories
/// types.
///
-/// C++2a [cmp.categories.pre] The types weak_equality, strong_equality,
-/// partial_ordering, weak_ordering, and strong_ordering are collectively
-/// termed the comparison category types.
+/// C++20 [cmp.categories.pre] The types partial_ordering, weak_ordering, and
+/// strong_ordering are collectively termed the comparison category types.
enum class ComparisonCategoryType : unsigned char {
PartialOrdering,
WeakOrdering,
@@ -58,7 +58,8 @@ inline ComparisonCategoryType commonComparisonType(ComparisonCategoryType A,
/// Get the comparison category that should be used when comparing values of
/// type \c T.
-Optional<ComparisonCategoryType> getComparisonCategoryForBuiltinCmp(QualType T);
+std::optional<ComparisonCategoryType>
+getComparisonCategoryForBuiltinCmp(QualType T);
/// An enumeration representing the possible results of a three-way
/// comparison. These values map onto instances of comparison category types
@@ -115,8 +116,7 @@ private:
public:
/// The declaration for the comparison category type from the
/// standard library.
- // FIXME: Make this const
- CXXRecordDecl *Record = nullptr;
+ const CXXRecordDecl *Record = nullptr;
/// The Kind of the comparison category type
ComparisonCategoryType Kind;
@@ -146,7 +146,7 @@ public:
return Kind == CCK::PartialOrdering;
}
- /// Converts the specified result kind into the the correct result kind
+ /// Converts the specified result kind into the correct result kind
/// for this category. Specifically it lowers strong equality results to
/// weak equivalence if needed.
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const {
diff --git a/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h b/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h
index 8db09e6b57d0..f62611cb4c3c 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h
@@ -10,8 +10,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H
-#define LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H
+#ifndef LLVM_CLANG_AST_COMPUTEDEPENDENCE_H
+#define LLVM_CLANG_AST_COMPUTEDEPENDENCE_H
#include "clang/AST/DependenceFlags.h"
#include "clang/Basic/ExceptionSpecificationType.h"
@@ -30,7 +30,8 @@ class UnaryExprOrTypeTraitExpr;
class ArraySubscriptExpr;
class MatrixSubscriptExpr;
class CompoundLiteralExpr;
-class CastExpr;
+class ImplicitCastExpr;
+class ExplicitCastExpr;
class BinaryOperator;
class ConditionalOperator;
class BinaryConditionalOperator;
@@ -70,6 +71,7 @@ class CXXPseudoDestructorExpr;
class OverloadExpr;
class DependentScopeDeclRefExpr;
class CXXConstructExpr;
+class CXXTemporaryObjectExpr;
class CXXDefaultInitExpr;
class CXXDefaultArgExpr;
class LambdaExpr;
@@ -77,6 +79,7 @@ class CXXUnresolvedConstructExpr;
class CXXDependentScopeMemberExpr;
class MaterializeTemporaryExpr;
class CXXFoldExpr;
+class CXXParenListInitExpr;
class TypeTraitExpr;
class ConceptSpecializationExpr;
class SYCLUniqueStableNameExpr;
@@ -114,7 +117,8 @@ ExprDependence computeDependence(UnaryExprOrTypeTraitExpr *E);
ExprDependence computeDependence(ArraySubscriptExpr *E);
ExprDependence computeDependence(MatrixSubscriptExpr *E);
ExprDependence computeDependence(CompoundLiteralExpr *E);
-ExprDependence computeDependence(CastExpr *E);
+ExprDependence computeDependence(ImplicitCastExpr *E);
+ExprDependence computeDependence(ExplicitCastExpr *E);
ExprDependence computeDependence(BinaryOperator *E);
ExprDependence computeDependence(ConditionalOperator *E);
ExprDependence computeDependence(BinaryConditionalOperator *E);
@@ -156,6 +160,7 @@ ExprDependence computeDependence(OverloadExpr *E, bool KnownDependent,
bool KnownContainsUnexpandedParameterPack);
ExprDependence computeDependence(DependentScopeDeclRefExpr *E);
ExprDependence computeDependence(CXXConstructExpr *E);
+ExprDependence computeDependence(CXXTemporaryObjectExpr *E);
ExprDependence computeDependence(CXXDefaultInitExpr *E);
ExprDependence computeDependence(CXXDefaultArgExpr *E);
ExprDependence computeDependence(LambdaExpr *E,
@@ -164,6 +169,7 @@ ExprDependence computeDependence(CXXUnresolvedConstructExpr *E);
ExprDependence computeDependence(CXXDependentScopeMemberExpr *E);
ExprDependence computeDependence(MaterializeTemporaryExpr *E);
ExprDependence computeDependence(CXXFoldExpr *E);
+ExprDependence computeDependence(CXXParenListInitExpr *E);
ExprDependence computeDependence(TypeTraitExpr *E);
ExprDependence computeDependence(ConceptSpecializationExpr *E,
bool ValueDependent);
diff --git a/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h b/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h
index 4ebbdf63abb5..4f8343efad16 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h
@@ -1,9 +1,8 @@
//===--- CurrentSourceLocExprScope.h ----------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
//
@@ -12,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H
-#define LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H
+#ifndef LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H
+#define LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H
#include <cassert>
@@ -72,4 +71,4 @@ private:
} // end namespace clang
-#endif // LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H
+#endif // LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/Decl.h b/contrib/llvm-project/clang/include/clang/AST/Decl.h
index 30a9458bc2ee..f26fb5ad5f13 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Decl.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Decl.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_AST_DECL_H
#define LLVM_CLANG_AST_DECL_H
+#include "clang/AST/APNumericStorage.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContextAllocate.h"
#include "clang/AST/DeclAccessPair.h"
@@ -35,7 +36,6 @@
#include "clang/Basic/Visibility.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
@@ -46,6 +46,7 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
+#include <optional>
#include <string>
#include <utility>
@@ -53,7 +54,6 @@ namespace clang {
class ASTContext;
struct ASTTemplateArgumentListInfo;
-class Attr;
class CompoundStmt;
class DependentFunctionTemplateSpecializationInfo;
class EnumDecl;
@@ -74,9 +74,9 @@ class TemplateArgumentList;
class TemplateArgumentListInfo;
class TemplateParameterList;
class TypeAliasTemplateDecl;
-class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;
+enum class ImplicitParamKind;
/// The top declaration context.
class TranslationUnitDecl : public Decl,
@@ -293,7 +293,9 @@ public:
/// Pretty-print the unqualified name of this declaration. Can be overloaded
/// by derived classes to provide a more user-friendly name when appropriate.
- virtual void printName(raw_ostream &os) const;
+ virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const;
+ /// Calls printName() with the ASTContext printing policy from the decl.
+ void printName(raw_ostream &OS) const;
/// Get the actual, stored name of the declaration, which may be a special
/// name.
@@ -357,7 +359,8 @@ public:
///
/// \param IsKnownNewer \c true if this declaration is known to be newer
/// than \p OldD (for instance, if this declaration is newly-created).
- bool declarationReplaces(NamedDecl *OldD, bool IsKnownNewer = true) const;
+ bool declarationReplaces(const NamedDecl *OldD,
+ bool IsKnownNewer = true) const;
/// Determine whether this declaration has linkage.
bool hasLinkage() const;
@@ -395,9 +398,7 @@ public:
/// Get the linkage from a semantic point of view. Entities in
/// anonymous namespaces are external (in c++98).
- Linkage getFormalLinkage() const {
- return clang::getFormalLinkage(getLinkageInternal());
- }
+ Linkage getFormalLinkage() const;
/// True if this decl has external linkage.
bool hasExternalFormalLinkage() const {
@@ -437,7 +438,7 @@ public:
/// If visibility was explicitly specified for this
/// declaration, return that visibility.
- Optional<Visibility>
+ std::optional<Visibility>
getExplicitVisibility(ExplicitVisibilityKind kind) const;
/// True if the computed linkage is valid. Used for consistency
@@ -454,6 +455,8 @@ public:
return hasCachedLinkage();
}
+ bool isPlaceholderVar(const LangOptions &LangOpts) const;
+
/// Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
NamedDecl *getUnderlyingDecl() {
@@ -542,6 +545,9 @@ public:
class NamespaceDecl : public NamedDecl, public DeclContext,
public Redeclarable<NamespaceDecl>
{
+
+ enum Flags : unsigned { F_Inline = 1 << 0, F_Nested = 1 << 1 };
+
/// The starting location of the source range, pointing
/// to either the namespace or the inline keyword.
SourceLocation LocStart;
@@ -553,11 +559,12 @@ class NamespaceDecl : public NamedDecl, public DeclContext,
/// this namespace or to the first namespace in the chain (the latter case
/// only when this is not the first in the chain), along with a
/// boolean value indicating whether this is an inline namespace.
- llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline;
+ llvm::PointerIntPair<NamespaceDecl *, 2, unsigned>
+ AnonOrFirstNamespaceAndFlags;
NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, NamespaceDecl *PrevDecl);
+ IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested);
using redeclarable_base = Redeclarable<NamespaceDecl>;
@@ -569,10 +576,10 @@ public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
- static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
- bool Inline, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- NamespaceDecl *PrevDecl);
+ static NamespaceDecl *Create(ASTContext &C, DeclContext *DC, bool Inline,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, NamespaceDecl *PrevDecl,
+ bool Nested);
static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -601,12 +608,33 @@ public:
/// Returns true if this is an inline namespace declaration.
bool isInline() const {
- return AnonOrFirstNamespaceAndInline.getInt();
+ return AnonOrFirstNamespaceAndFlags.getInt() & F_Inline;
}
/// Set whether this is an inline namespace declaration.
void setInline(bool Inline) {
- AnonOrFirstNamespaceAndInline.setInt(Inline);
+ unsigned F = AnonOrFirstNamespaceAndFlags.getInt();
+ if (Inline)
+ AnonOrFirstNamespaceAndFlags.setInt(F | F_Inline);
+ else
+ AnonOrFirstNamespaceAndFlags.setInt(F & ~F_Inline);
+ }
+
+ /// Returns true if this is a nested namespace declaration.
+ /// \code
+ /// namespace outer::nested { }
+ /// \endcode
+ bool isNested() const {
+ return AnonOrFirstNamespaceAndFlags.getInt() & F_Nested;
+ }
+
+ /// Set whether this is a nested namespace declaration.
+ void setNested(bool Nested) {
+ unsigned F = AnonOrFirstNamespaceAndFlags.getInt();
+ if (Nested)
+ AnonOrFirstNamespaceAndFlags.setInt(F | F_Nested);
+ else
+ AnonOrFirstNamespaceAndFlags.setInt(F & ~F_Nested);
}
/// Returns true if the inline qualifier for \c Name is redundant.
@@ -614,7 +642,9 @@ public:
if (!isInline())
return false;
auto X = lookup(Name);
- auto Y = getParent()->lookup(Name);
+ // We should not perform a lookup within a transparent context, so find a
+ // non-transparent parent context.
+ auto Y = getParent()->getNonTransparentContext()->lookup(Name);
return std::distance(X.begin(), X.end()) ==
std::distance(Y.begin(), Y.end());
}
@@ -633,11 +663,11 @@ public:
/// Retrieve the anonymous namespace nested inside this namespace,
/// if any.
NamespaceDecl *getAnonymousNamespace() const {
- return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer();
+ return getOriginalNamespace()->AnonOrFirstNamespaceAndFlags.getPointer();
}
void setAnonymousNamespace(NamespaceDecl *D) {
- getOriginalNamespace()->AnonOrFirstNamespaceAndInline.setPointer(D);
+ getOriginalNamespace()->AnonOrFirstNamespaceAndFlags.setPointer(D);
}
/// Retrieves the canonical declaration of this namespace.
@@ -668,6 +698,8 @@ public:
}
};
+class VarDecl;
+
/// Represent the declaration of a variable (in which case it is
/// an lvalue) a function (in which case it is a function designator) or
/// an enum constant.
@@ -689,6 +721,18 @@ public:
/// or declared with the weak or weak-ref attr.
bool isWeak() const;
+ /// Whether this variable is the implicit variable for a lambda init-capture.
+ /// Only VarDecl can be init captures, but both VarDecl and BindingDecl
+ /// can be captured.
+ bool isInitCapture() const;
+
+ // If this is a VarDecl, or a BindindDecl with an
+ // associated decomposed VarDecl, return that VarDecl.
+ VarDecl *getPotentiallyDecomposedVarDecl();
+ const VarDecl *getPotentiallyDecomposedVarDecl() const {
+ return const_cast<ValueDecl *>(this)->getPotentiallyDecomposedVarDecl();
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
@@ -861,7 +905,7 @@ struct EvaluatedStmt {
bool HasICEInit : 1;
bool CheckedForICEInit : 1;
- Stmt *Value;
+ LazyDeclStmtPtr Value;
APValue Evaluated;
EvaluatedStmt()
@@ -882,7 +926,10 @@ public:
CallInit,
/// Direct list-initialization (C++11)
- ListInit
+ ListInit,
+
+ /// Parenthesized list-initialization (C++20)
+ ParenListInit
};
/// Kinds of thread-local storage.
@@ -925,12 +972,16 @@ private:
friend class ASTDeclReader;
friend class VarDecl;
+ LLVM_PREFERRED_TYPE(StorageClass)
unsigned SClass : 3;
+ LLVM_PREFERRED_TYPE(ThreadStorageClassSpecifier)
unsigned TSCSpec : 2;
+ LLVM_PREFERRED_TYPE(InitializationStyle)
unsigned InitStyle : 2;
/// Whether this variable is an ARC pseudo-__strong variable; see
/// isARCPseudoStrong() for details.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ARCPseudoStrong : 1;
};
enum { NumVarDeclBits = 8 };
@@ -951,22 +1002,27 @@ protected:
friend class ASTDeclReader;
friend class ParmVarDecl;
+ LLVM_PREFERRED_TYPE(VarDeclBitfields)
unsigned : NumVarDeclBits;
/// Whether this parameter inherits a default argument from a
/// prior declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasInheritedDefaultArg : 1;
/// Describes the kind of default argument for this parameter. By default
/// this is none. If this is normal, then the default argument is stored in
/// the \c VarDecl initializer expression unless we were unable to parse
/// (even an invalid) expression for the default argument.
+ LLVM_PREFERRED_TYPE(DefaultArgKind)
unsigned DefaultArgKind : 2;
/// Whether this parameter undergoes K&R argument promotion.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsKNRPromoted : 1;
/// Whether this parameter is an ObjC method parameter or not.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsObjCMethodParam : 1;
/// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
@@ -985,51 +1041,64 @@ protected:
friend class ImplicitParamDecl;
friend class VarDecl;
+ LLVM_PREFERRED_TYPE(VarDeclBitfields)
unsigned : NumVarDeclBits;
// FIXME: We need something similar to CXXRecordDecl::DefinitionData.
/// Whether this variable is a definition which was demoted due to
/// module merge.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsThisDeclarationADemotedDefinition : 1;
/// Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ExceptionVar : 1;
/// Whether this local variable could be allocated in the return
/// slot of its function, enabling the named return value optimization
/// (NRVO).
+ LLVM_PREFERRED_TYPE(bool)
unsigned NRVOVariable : 1;
/// Whether this variable is the for-range-declaration in a C++0x
/// for-range statement.
+ LLVM_PREFERRED_TYPE(bool)
unsigned CXXForRangeDecl : 1;
/// Whether this variable is the for-in loop declaration in Objective-C.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ObjCForDecl : 1;
/// Whether this variable is (C++1z) inline.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsInline : 1;
/// Whether this variable has (C++1z) inline explicitly specified.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsInlineSpecified : 1;
/// Whether this variable is (C++0x) constexpr.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsConstexpr : 1;
/// Whether this variable is the implicit variable for a lambda
/// init-capture.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsInitCapture : 1;
/// Whether this local extern variable's previous declaration was
/// declared in the same block scope. This controls whether we should merge
/// the type of this declaration with its previous declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned PreviousDeclInSameBlockScope : 1;
/// Defines kind of the ImplicitParamDecl: 'this', 'self', 'vtt', '_cmd' or
/// something else.
+ LLVM_PREFERRED_TYPE(ImplicitParamKind)
unsigned ImplicitParamKind : 3;
+ LLVM_PREFERRED_TYPE(bool)
unsigned EscapingByref : 1;
};
@@ -1041,7 +1110,7 @@ protected:
};
VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+ SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, StorageClass SC);
using redeclarable_base = Redeclarable<VarDecl>;
@@ -1071,8 +1140,8 @@ public:
static VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
- StorageClass S);
+ const IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo, StorageClass S);
static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -1316,12 +1385,15 @@ public:
EvaluatedStmt *getEvaluatedStmt() const;
/// Attempt to evaluate the value of the initializer attached to this
- /// declaration, and produce notes explaining why it cannot be evaluated or is
- /// not a constant expression. Returns a pointer to the value if evaluation
- /// succeeded, 0 otherwise.
+ /// declaration, and produce notes explaining why it cannot be evaluated.
+ /// Returns a pointer to the value if evaluation succeeded, 0 otherwise.
APValue *evaluateValue() const;
- APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+private:
+ APValue *evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes,
+ bool IsConstantInitialization) const;
+
+public:
/// Return the already-evaluated value of this variable's
/// initializer, or NULL if the value is not yet known. Returns pointer
/// to untyped APValue if the value could not be evaluated.
@@ -1588,38 +1660,55 @@ public:
/// kind?
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const;
+ /// Whether this variable has a flexible array member initialized with one
+ /// or more elements. This can only be called for declarations where
+ /// hasInit() is true.
+ ///
+ /// (The standard doesn't allow initializing flexible array members; this is
+ /// a gcc/msvc extension.)
+ bool hasFlexibleArrayInit(const ASTContext &Ctx) const;
+
+ /// If hasFlexibleArrayInit is true, compute the number of additional bytes
+ /// necessary to store those elements. Otherwise, returns zero.
+ ///
+ /// This can only be called for declarations where hasInit() is true.
+ CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
};
-class ImplicitParamDecl : public VarDecl {
- void anchor() override;
+/// Defines the kind of the implicit parameter: is this an implicit parameter
+/// with pointer to 'this', 'self', '_cmd', virtual table pointers, captured
+/// context or something else.
+enum class ImplicitParamKind {
+ /// Parameter for Objective-C 'self' argument
+ ObjCSelf,
-public:
- /// Defines the kind of the implicit parameter: is this an implicit parameter
- /// with pointer to 'this', 'self', '_cmd', virtual table pointers, captured
- /// context or something else.
- enum ImplicitParamKind : unsigned {
- /// Parameter for Objective-C 'self' argument
- ObjCSelf,
+ /// Parameter for Objective-C '_cmd' argument
+ ObjCCmd,
- /// Parameter for Objective-C '_cmd' argument
- ObjCCmd,
+ /// Parameter for C++ 'this' argument
+ CXXThis,
- /// Parameter for C++ 'this' argument
- CXXThis,
+ /// Parameter for C++ virtual table pointers
+ CXXVTT,
- /// Parameter for C++ virtual table pointers
- CXXVTT,
+ /// Parameter for captured context
+ CapturedContext,
- /// Parameter for captured context
- CapturedContext,
+ /// Parameter for Thread private variable
+ ThreadPrivateVar,
- /// Other implicit parameter
- Other,
- };
+ /// Other implicit parameter
+ Other,
+};
+class ImplicitParamDecl : public VarDecl {
+ void anchor() override;
+
+public:
/// Create implicit parameter.
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc, IdentifierInfo *Id,
@@ -1634,7 +1723,7 @@ public:
ImplicitParamKind ParamKind)
: VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
/*TInfo=*/nullptr, SC_None) {
- NonParmVarDeclBits.ImplicitParamKind = ParamKind;
+ NonParmVarDeclBits.ImplicitParamKind = llvm::to_underlying(ParamKind);
setImplicit();
}
@@ -1642,7 +1731,7 @@ public:
: VarDecl(ImplicitParam, C, /*DC=*/nullptr, SourceLocation(),
SourceLocation(), /*Id=*/nullptr, Type,
/*TInfo=*/nullptr, SC_None) {
- NonParmVarDeclBits.ImplicitParamKind = ParamKind;
+ NonParmVarDeclBits.ImplicitParamKind = llvm::to_underlying(ParamKind);
setImplicit();
}
@@ -1745,6 +1834,18 @@ public:
ParmVarDeclBits.IsKNRPromoted = promoted;
}
+ bool isExplicitObjectParameter() const {
+ return ExplicitObjectParameterIntroducerLoc.isValid();
+ }
+
+ void setExplicitObjectParameterLoc(SourceLocation Loc) {
+ ExplicitObjectParameterIntroducerLoc = Loc;
+ }
+
+ SourceLocation getExplicitObjectParamThisLoc() const {
+ return ExplicitObjectParameterIntroducerLoc;
+ }
+
Expr *getDefaultArg();
const Expr *getDefaultArg() const {
return const_cast<ParmVarDecl *>(this)->getDefaultArg();
@@ -1811,7 +1912,10 @@ public:
static bool classofKind(Kind K) { return K == ParmVar; }
private:
+ friend class ASTDeclReader;
+
enum { ParameterIndexSentinel = (1 << NumParameterIndexBits) - 1 };
+ SourceLocation ExplicitObjectParameterIntroducerLoc;
void setParameterIndex(unsigned parameterIndex) {
if (parameterIndex >= ParameterIndexSentinel) {
@@ -1835,7 +1939,9 @@ enum class MultiVersionKind {
None,
Target,
CPUSpecific,
- CPUDispatch
+ CPUDispatch,
+ TargetClones,
+ TargetVersion
};
/// Represents a function declaration or definition.
@@ -1869,7 +1975,10 @@ public:
TK_FunctionTemplateSpecialization,
// A function template specialization that hasn't yet been resolved to a
// particular specialized function template.
- TK_DependentFunctionTemplateSpecialization
+ TK_DependentFunctionTemplateSpecialization,
+ // A non-template function which is in a dependent scope.
+ TK_DependentNonTemplate
+
};
/// Stashed information about a defaulted function definition whose body has
@@ -1915,23 +2024,26 @@ private:
/// EndRangeLoc.
SourceLocation EndRangeLoc;
+ SourceLocation DefaultKWLoc;
+
/// The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
- /// For non-templates, this value will be NULL. For function
- /// declarations that describe a function template, this will be a
- /// pointer to a FunctionTemplateDecl. For member functions
- /// of class template specializations, this will be a MemberSpecializationInfo
+ /// For non-templates this value will be NULL, unless this declaration was
+ /// declared directly inside of a function template, in which case it will
+ /// have a pointer to a FunctionDecl, stored in the NamedDecl. For function
+ /// declarations that describe a function template, this will be a pointer to
+ /// a FunctionTemplateDecl, stored in the NamedDecl. For member functions of
+ /// class template specializations, this will be a MemberSpecializationInfo
/// pointer containing information about the specialization.
/// For function template specializations, this will be a
/// FunctionTemplateSpecializationInfo, which contains information about
/// the template being specialized and the template arguments involved in
/// that specialization.
- llvm::PointerUnion<FunctionTemplateDecl *,
- MemberSpecializationInfo *,
+ llvm::PointerUnion<NamedDecl *, MemberSpecializationInfo *,
FunctionTemplateSpecializationInfo *,
DependentFunctionTemplateSpecializationInfo *>
- TemplateOrSpecialization;
+ TemplateOrSpecialization;
/// Provides source/type location info for the declaration name embedded in
/// the DeclaratorDecl base class.
@@ -1987,8 +2099,8 @@ private:
protected:
FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified,
- ConstexprSpecKind ConstexprKind,
+ TypeSourceInfo *TInfo, StorageClass S, bool UsesFPIntrin,
+ bool isInlineSpecified, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr);
using redeclarable_base = Redeclarable<FunctionDecl>;
@@ -2022,23 +2134,23 @@ public:
static FunctionDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation NLoc, DeclarationName N, QualType T,
- TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false,
- bool hasWrittenPrototype = true,
+ TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin = false,
+ bool isInlineSpecified = false, bool hasWrittenPrototype = true,
ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified,
Expr *TrailingRequiresClause = nullptr) {
DeclarationNameInfo NameInfo(N, NLoc);
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC,
- isInlineSpecified, hasWrittenPrototype,
- ConstexprKind, TrailingRequiresClause);
+ UsesFPIntrin, isInlineSpecified,
+ hasWrittenPrototype, ConstexprKind,
+ TrailingRequiresClause);
}
- static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, StorageClass SC,
- bool isInlineSpecified, bool hasWrittenPrototype,
- ConstexprSpecKind ConstexprKind,
- Expr *TrailingRequiresClause);
+ static FunctionDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
+ StorageClass SC, bool UsesFPIntrin, bool isInlineSpecified,
+ bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind,
+ Expr *TrailingRequiresClause);
static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2098,7 +2210,7 @@ public:
/// declaration to the declaration that is a definition (if there is one).
///
/// \param CheckForPendingFriendDefinition If \c true, also check for friend
- /// declarations that were instantiataed from function definitions.
+ /// declarations that were instantiated from function definitions.
/// Such a declaration behaves as if it is a definition for the
/// purpose of redefinition checking, but isn't actually a "real"
/// definition until its body is instantiated.
@@ -2182,8 +2294,8 @@ public:
/// Whether this virtual function is pure, i.e. makes the containing class
/// abstract.
- bool isPure() const { return FunctionDeclBits.IsPure; }
- void setPure(bool P = true);
+ bool isPureVirtual() const { return FunctionDeclBits.IsPureVirtual; }
+ void setIsPureVirtual(bool P = true);
/// Whether this templated function will be late parsed.
bool isLateTemplateParsed() const {
@@ -2220,6 +2332,16 @@ public:
FunctionDeclBits.IsExplicitlyDefaulted = ED;
}
+ SourceLocation getDefaultLoc() const {
+ return isExplicitlyDefaulted() ? DefaultKWLoc : SourceLocation();
+ }
+
+ void setDefaultLoc(SourceLocation NewLoc) {
+ assert((NewLoc.isInvalid() || isExplicitlyDefaulted()) &&
+ "Can't set default loc is function isn't explicitly defaulted");
+ DefaultKWLoc = NewLoc;
+ }
+
/// True if this method is user-declared and was not
/// deleted or defaulted on its first declaration.
bool isUserProvided() const {
@@ -2230,6 +2352,13 @@ public:
DeclAsWritten->getCanonicalDecl()->isDefaulted());
}
+ bool isIneligibleOrNotSelected() const {
+ return FunctionDeclBits.IsIneligibleOrNotSelected;
+ }
+ void setIneligibleOrNotSelected(bool II) {
+ FunctionDeclBits.IsIneligibleOrNotSelected = II;
+ }
+
/// Whether falling off this function implicitly returns null/zero.
/// If a more specific implicit return value is required, front-ends
/// should synthesize the appropriate return statements.
@@ -2291,6 +2420,21 @@ public:
return getConstexprKind() == ConstexprSpecKind::Consteval;
}
+ void setBodyContainsImmediateEscalatingExpressions(bool Set) {
+ FunctionDeclBits.BodyContainsImmediateEscalatingExpression = Set;
+ }
+
+ bool BodyContainsImmediateEscalatingExpressions() const {
+ return FunctionDeclBits.BodyContainsImmediateEscalatingExpression;
+ }
+
+ bool isImmediateEscalating() const;
+
+ // The function is a C++ immediate function.
+ // This can be either a consteval function, or an immediate escalating
+ // function containing an immediate escalating expression.
+ bool isImmediateFunction() const;
+
/// Whether the instantiation of this function is pending.
/// This bit is set when the decision to instantiate this function is made
/// and unset if and when the function body is created. That leaves out
@@ -2385,7 +2529,7 @@ public:
/// If this function is an allocation/deallocation function that takes
/// the `std::nothrow_t` tag, return true through IsNothrow,
bool isReplaceableGlobalAllocationFunction(
- Optional<unsigned> *AlignmentParam = nullptr,
+ std::optional<unsigned> *AlignmentParam = nullptr,
bool *IsNothrow = nullptr) const;
/// Determine if this function provides an inline implementation of a builtin.
@@ -2437,6 +2581,23 @@ public:
getCanonicalDecl()->FunctionDeclBits.IsMultiVersion = V;
}
+ // Sets that this is a constrained friend where the constraint refers to an
+ // enclosing template.
+ void setFriendConstraintRefersToEnclosingTemplate(bool V = true) {
+ getCanonicalDecl()
+ ->FunctionDeclBits.FriendConstraintRefersToEnclosingTemplate = V;
+ }
+ // Indicates this function is a constrained friend, where the constraint
+ // refers to an enclosing template for hte purposes of [temp.friend]p9.
+ bool FriendConstraintRefersToEnclosingTemplate() const {
+ return getCanonicalDecl()
+ ->FunctionDeclBits.FriendConstraintRefersToEnclosingTemplate;
+ }
+
+ /// Determine whether a function is a friend function that cannot be
+ /// redeclared outside of its class, per C++ [temp.friend]p9.
+ bool isMemberLikeConstrainedFriend() const;
+
/// Gets the kind of multiversioning attribute this declaration has. Note that
/// this can return a value even if the function is not multiversion, such as
/// the case of 'target'.
@@ -2454,6 +2615,10 @@ public:
/// the target functionality.
bool isTargetMultiVersion() const;
+ /// True if this function is a multiversioned dispatch function as a part of
+ /// the target-clones functionality.
+ bool isTargetClonesMultiVersion() const;
+
/// \brief Get the associated-constraints of this function declaration.
/// Currently, this will either be a vector of size 1 containing the
/// trailing-requires-clause or an empty vector.
@@ -2515,6 +2680,23 @@ public:
/// parameters have default arguments (in C++).
unsigned getMinRequiredArguments() const;
+ /// Returns the minimum number of non-object arguments needed to call this
+ /// function. This produces the same value as getMinRequiredArguments except
+ /// it does not count the explicit object argument, if any.
+ unsigned getMinRequiredExplicitArguments() const;
+
+ bool hasCXXExplicitFunctionObjectParameter() const;
+
+ unsigned getNumNonObjectParams() const;
+
+ const ParmVarDecl *getNonObjectParameter(unsigned I) const {
+ return getParamDecl(hasCXXExplicitFunctionObjectParameter() ? I + 1 : I);
+ }
+
+ ParmVarDecl *getNonObjectParameter(unsigned I) {
+ return getParamDecl(hasCXXExplicitFunctionObjectParameter() ? I + 1 : I);
+ }
+
/// Determine whether this function has a single parameter, or multiple
/// parameters where all but the first have default arguments.
///
@@ -2591,6 +2773,14 @@ public:
FunctionDeclBits.IsInline = I;
}
+ /// Determine whether the function was declared in source context
+ /// that requires constrained FP intrinsics
+ bool UsesFPIntrin() const { return FunctionDeclBits.UsesFPIntrin; }
+
+ /// Set whether the function was declared in source context
+ /// that requires constrained FP intrinsics
+ void setUsesFPIntrin(bool I) { FunctionDeclBits.UsesFPIntrin = I; }
+
/// Flag that this function is implicitly inline.
void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; }
@@ -2655,6 +2845,13 @@ public:
setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
}
+ /// Specify that this function declaration was instantiated from a
+ /// FunctionDecl FD. This is only used if this is a function declaration
+ /// declared locally inside of a function template.
+ void setInstantiatedFromDecl(FunctionDecl *FD);
+
+ FunctionDecl *getInstantiatedFromDecl() const;
+
/// Retrieves the function template that is described by this
/// function declaration.
///
@@ -2673,9 +2870,7 @@ public:
/// Determine whether this function is a function template
/// specialization.
- bool isFunctionTemplateSpecialization() const {
- return getPrimaryTemplate() != nullptr;
- }
+ bool isFunctionTemplateSpecialization() const;
/// If this function is actually a function template specialization,
/// retrieve information about this function template specialization.
@@ -2758,9 +2953,9 @@ public:
/// Specifies that this function declaration is actually a
/// dependent function template specialization.
- void setDependentTemplateSpecialization(ASTContext &Context,
- const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
+ void setDependentTemplateSpecialization(
+ ASTContext &Context, const UnresolvedSetImpl &Templates,
+ const TemplateArgumentListInfo *TemplateArgs);
DependentFunctionTemplateSpecializationInfo *
getDependentSpecializationInfo() const;
@@ -2820,11 +3015,7 @@ public:
/// Represents a member of a struct/union/class.
class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
- unsigned BitField : 1;
- unsigned Mutable : 1;
- mutable unsigned CachedFieldIndex : 30;
-
- /// The kinds of value we can store in InitializerOrBitWidth.
+ /// The kinds of value we can store in StorageKind.
///
/// Note that this is compatible with InClassInitStyle except for
/// ISK_CapturedVLAType.
@@ -2847,10 +3038,18 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
ISK_CapturedVLAType,
};
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned BitField : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned Mutable : 1;
+ LLVM_PREFERRED_TYPE(InitStorageKind)
+ unsigned StorageKind : 2;
+ mutable unsigned CachedFieldIndex : 28;
+
/// If this is a bitfield with a default member initializer, this
/// structure is used to represent the two expressions.
- struct InitAndBitWidth {
- Expr *Init;
+ struct InitAndBitWidthStorage {
+ LazyDeclStmtPtr Init;
Expr *BitWidth;
};
@@ -2863,16 +3062,25 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
/// and attached.
// FIXME: Tail-allocate this to reduce the size of FieldDecl in the
// overwhelmingly common case that we have none of these things.
- llvm::PointerIntPair<void *, 2, InitStorageKind> InitStorage;
+ union {
+ // Active member if ISK is not ISK_CapturedVLAType and BitField is false.
+ LazyDeclStmtPtr Init;
+ // Active member if ISK is ISK_NoInit and BitField is true.
+ Expr *BitWidth;
+ // Active member if ISK is ISK_InClass*Init and BitField is true.
+ InitAndBitWidthStorage *InitAndBitWidth;
+ // Active member if ISK is ISK_CapturedVLAType.
+ const VariableArrayType *CapturedVLAType;
+ };
protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
+ SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
InClassInitStyle InitStyle)
- : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
- BitField(false), Mutable(Mutable), CachedFieldIndex(0),
- InitStorage(nullptr, (InitStorageKind) InitStyle) {
+ : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false),
+ Mutable(Mutable), StorageKind((InitStorageKind)InitStyle),
+ CachedFieldIndex(0), Init() {
if (BW)
setBitWidth(BW);
}
@@ -2908,15 +3116,16 @@ public:
/// store the data for the anonymous union or struct.
bool isAnonymousStructOrUnion() const;
+ /// Returns the expression that represents the bit width, if this field
+ /// is a bit field. For non-bitfields, this returns \c nullptr.
Expr *getBitWidth() const {
if (!BitField)
return nullptr;
- void *Ptr = InitStorage.getPointer();
- if (getInClassInitStyle())
- return static_cast<InitAndBitWidth*>(Ptr)->BitWidth;
- return static_cast<Expr*>(Ptr);
+ return hasInClassInitializer() ? InitAndBitWidth->BitWidth : BitWidth;
}
+ /// Computes the bit width of this field, if this is a bit field.
+ /// May not be called on non-bitfields.
unsigned getBitWidthValue(const ASTContext &Ctx) const;
/// Set the bit-field width for this member.
@@ -2925,11 +3134,11 @@ public:
assert(!hasCapturedVLAType() && !BitField &&
"bit width or captured type already set");
assert(Width && "no bit width specified");
- InitStorage.setPointer(
- InitStorage.getInt()
- ? new (getASTContext())
- InitAndBitWidth{getInClassInitializer(), Width}
- : static_cast<void*>(Width));
+ if (hasInClassInitializer())
+ InitAndBitWidth =
+ new (getASTContext()) InitAndBitWidthStorage{Init, Width};
+ else
+ BitWidth = Width;
BitField = true;
}
@@ -2937,7 +3146,11 @@ public:
// Note: used by some clients (i.e., do not remove it).
void removeBitWidth() {
assert(isBitField() && "no bitfield width to remove");
- InitStorage.setPointer(getInClassInitializer());
+ if (hasInClassInitializer()) {
+ // Read the old initializer before we change the active union member.
+ auto ExistingInit = InitAndBitWidth->Init;
+ Init = ExistingInit;
+ }
BitField = false;
}
@@ -2951,11 +3164,14 @@ public:
/// [[no_unique_address]] attribute.
bool isZeroSize(const ASTContext &Ctx) const;
+ /// Determine if this field is of potentially-overlapping class type, that
+ /// is, subobject with the [[no_unique_address]] attribute
+ bool isPotentiallyOverlapping() const;
+
/// Get the kind of (C++11) default member initializer that this field has.
InClassInitStyle getInClassInitStyle() const {
- InitStorageKind storageKind = InitStorage.getInt();
- return (storageKind == ISK_CapturedVLAType
- ? ICIS_NoInit : (InClassInitStyle) storageKind);
+ return (StorageKind == ISK_CapturedVLAType ? ICIS_NoInit
+ : (InClassInitStyle)StorageKind);
}
/// Determine whether this member has a C++11 default member initializer.
@@ -2963,44 +3179,44 @@ public:
return getInClassInitStyle() != ICIS_NoInit;
}
+ /// Determine whether getInClassInitializer() would return a non-null pointer
+ /// without deserializing the initializer.
+ bool hasNonNullInClassInitializer() const {
+ return hasInClassInitializer() && (BitField ? InitAndBitWidth->Init : Init);
+ }
+
/// Get the C++11 default member initializer for this member, or null if one
/// has not been set. If a valid declaration has a default member initializer,
/// but this returns null, then we have not parsed and attached it yet.
- Expr *getInClassInitializer() const {
- if (!hasInClassInitializer())
- return nullptr;
- void *Ptr = InitStorage.getPointer();
- if (BitField)
- return static_cast<InitAndBitWidth*>(Ptr)->Init;
- return static_cast<Expr*>(Ptr);
- }
+ Expr *getInClassInitializer() const;
/// Set the C++11 in-class initializer for this member.
- void setInClassInitializer(Expr *Init) {
- assert(hasInClassInitializer() && !getInClassInitializer());
- if (BitField)
- static_cast<InitAndBitWidth*>(InitStorage.getPointer())->Init = Init;
- else
- InitStorage.setPointer(Init);
- }
+ void setInClassInitializer(Expr *NewInit);
+private:
+ void setLazyInClassInitializer(LazyDeclStmtPtr NewInit);
+
+public:
/// Remove the C++11 in-class initializer from this member.
void removeInClassInitializer() {
assert(hasInClassInitializer() && "no initializer to remove");
- InitStorage.setPointerAndInt(getBitWidth(), ISK_NoInit);
+ StorageKind = ISK_NoInit;
+ if (BitField) {
+ // Read the bit width before we change the active union member.
+ Expr *ExistingBitWidth = InitAndBitWidth->BitWidth;
+ BitWidth = ExistingBitWidth;
+ }
}
/// Determine whether this member captures the variable length array
/// type.
bool hasCapturedVLAType() const {
- return InitStorage.getInt() == ISK_CapturedVLAType;
+ return StorageKind == ISK_CapturedVLAType;
}
/// Get the captured variable length array type.
const VariableArrayType *getCapturedVLAType() const {
- return hasCapturedVLAType() ? static_cast<const VariableArrayType *>(
- InitStorage.getPointer())
- : nullptr;
+ return hasCapturedVLAType() ? CapturedVLAType : nullptr;
}
/// Set the captured variable length array type for this field.
@@ -3028,21 +3244,24 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
+
+ void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
};
/// An instance of this object exists for each enum constant
/// that is defined. For example, in "enum X {a,b}", each of a/b are
/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
/// TagType for the X EnumDecl.
-class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> {
+class EnumConstantDecl : public ValueDecl,
+ public Mergeable<EnumConstantDecl>,
+ public APIntStorage {
Stmt *Init; // an integer constant expression
- llvm::APSInt Val; // The value.
+ bool IsUnsigned;
protected:
- EnumConstantDecl(DeclContext *DC, SourceLocation L,
+ EnumConstantDecl(const ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, Expr *E,
- const llvm::APSInt &V)
- : ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {}
+ const llvm::APSInt &V);
public:
friend class StmtIteratorBase;
@@ -3055,10 +3274,15 @@ public:
const Expr *getInitExpr() const { return (const Expr*) Init; }
Expr *getInitExpr() { return (Expr*) Init; }
- const llvm::APSInt &getInitVal() const { return Val; }
+ llvm::APSInt getInitVal() const {
+ return llvm::APSInt(getValue(), IsUnsigned);
+ }
void setInitExpr(Expr *E) { Init = (Stmt*) E; }
- void setInitVal(const llvm::APSInt &V) { Val = V; }
+ void setInitVal(const ASTContext &C, const llvm::APSInt &V) {
+ setValue(C, V);
+ IsUnsigned = V.isUnsigned();
+ }
SourceRange getSourceRange() const override LLVM_READONLY;
@@ -3096,7 +3320,7 @@ public:
using chain_iterator = ArrayRef<NamedDecl *>::const_iterator;
ArrayRef<NamedDecl *> chain() const {
- return llvm::makeArrayRef(Chaining, ChainingSize);
+ return llvm::ArrayRef(Chaining, ChainingSize);
}
chain_iterator chain_begin() const { return chain().begin(); }
chain_iterator chain_end() const { return chain().end(); }
@@ -3470,6 +3694,24 @@ public:
/// parameters.
bool isDependentType() const { return isDependentContext(); }
+ /// Whether this declaration was a definition in some module but was forced
+ /// to be a declaration.
+ ///
+ /// Useful for clients checking if a module has a definition of a specific
+ /// symbol and not interested in the final AST with deduplicated definitions.
+ bool isThisDeclarationADemotedDefinition() const {
+ return TagDeclBits.IsThisDeclarationADemotedDefinition;
+ }
+
+ /// Mark a definition as a declaration and maintain information it _was_
+ /// a definition.
+ void demoteThisDefinitionToDeclaration() {
+ assert(isCompleteDefinition() &&
+ "Should demote definitions only, not forward declarations");
+ setCompleteDefinition(false);
+ TagDeclBits.IsThisDeclarationADemotedDefinition = true;
+ }
+
/// Starts the definition of this tag declaration.
///
/// This method should be invoked at the beginning of the definition
@@ -3495,13 +3737,15 @@ public:
return static_cast<TagKind>(TagDeclBits.TagDeclKind);
}
- void setTagKind(TagKind TK) { TagDeclBits.TagDeclKind = TK; }
+ void setTagKind(TagKind TK) {
+ TagDeclBits.TagDeclKind = llvm::to_underlying(TK);
+ }
- bool isStruct() const { return getTagKind() == TTK_Struct; }
- bool isInterface() const { return getTagKind() == TTK_Interface; }
- bool isClass() const { return getTagKind() == TTK_Class; }
- bool isUnion() const { return getTagKind() == TTK_Union; }
- bool isEnum() const { return getTagKind() == TTK_Enum; }
+ bool isStruct() const { return getTagKind() == TagTypeKind::Struct; }
+ bool isInterface() const { return getTagKind() == TagTypeKind::Interface; }
+ bool isClass() const { return getTagKind() == TagTypeKind::Class; }
+ bool isUnion() const { return getTagKind() == TagTypeKind::Union; }
+ bool isEnum() const { return getTagKind() == TagTypeKind::Enum; }
/// Is this tag type named, either directly or via being defined in
/// a typedef of this type?
@@ -3555,6 +3799,9 @@ public:
return getExtInfo()->TemplParamLists[i];
}
+ using TypeDecl::printName;
+ void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
+
void setTemplateParameterListsInfo(ASTContext &Context,
ArrayRef<TemplateParameterList *> TPLists);
@@ -3688,6 +3935,10 @@ public:
bool IsFixed);
static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ /// Overrides to provide correct range when there's an enum-base specifier
+ /// with forward declarations.
+ SourceRange getSourceRange() const override LLVM_READONLY;
+
/// When created, the EnumDecl corresponds to a
/// forward-declared enum. This method is used to mark the
/// declaration as being defined; its enumerators have already been
@@ -3769,6 +4020,11 @@ public:
/// -101 1001011 8
unsigned getNumNegativeBits() const { return EnumDeclBits.NumNegativeBits; }
+ /// Calculates the [Min,Max) values the enum can store based on the
+ /// NumPositiveBits and NumNegativeBits. This matters for enums that do not
+ /// have a fixed underlying type.
+ void getValueRange(llvm::APInt &Max, llvm::APInt &Min) const;
+
/// Returns true if this is a C++11 scoped enumeration.
bool isScoped() const { return EnumDeclBits.IsScoped; }
@@ -3839,6 +4095,29 @@ public:
static bool classofKind(Kind K) { return K == Enum; }
};
+/// Enum that represents the different ways arguments are passed to and
+/// returned from function calls. This takes into account the target-specific
+/// and version-specific rules along with the rules determined by the
+/// language.
+enum class RecordArgPassingKind {
+ /// The argument of this type can be passed directly in registers.
+ CanPassInRegs,
+
+ /// The argument of this type cannot be passed directly in registers.
+ /// Records containing this type as a subobject are not forced to be passed
+ /// indirectly. This value is used only in C++. This value is required by
+ /// C++ because, in uncommon situations, it is possible for a class to have
+ /// only trivial copy/move constructors even when one of its subobjects has
+ /// a non-trivial copy/move constructor (if e.g. the corresponding copy/move
+ /// constructor in the derived class is deleted).
+ CannotPassInRegs,
+
+ /// The argument of this type cannot be passed directly in registers.
+ /// Records containing this type as a subobject are forced to be passed
+ /// indirectly.
+ CanNeverPassInRegs
+};
+
/// Represents a struct/union/class. For example:
/// struct X; // Forward declaration, no "body".
/// union Y { int A, B; }; // Has body with members A and B (FieldDecls).
@@ -3848,28 +4127,7 @@ class RecordDecl : public TagDecl {
// to save some space. Use the provided accessors to access it.
public:
friend class DeclContext;
- /// Enum that represents the different ways arguments are passed to and
- /// returned from function calls. This takes into account the target-specific
- /// and version-specific rules along with the rules determined by the
- /// language.
- enum ArgPassingKind : unsigned {
- /// The argument of this type can be passed directly in registers.
- APK_CanPassInRegs,
-
- /// The argument of this type cannot be passed directly in registers.
- /// Records containing this type as a subobject are not forced to be passed
- /// indirectly. This value is used only in C++. This value is required by
- /// C++ because, in uncommon situations, it is possible for a class to have
- /// only trivial copy/move constructors even when one of its subobjects has
- /// a non-trivial copy/move constructor (if e.g. the corresponding copy/move
- /// constructor in the derived class is deleted).
- APK_CannotPassInRegs,
-
- /// The argument of this type cannot be passed directly in registers.
- /// Records containing this type as a subobject are forced to be passed
- /// indirectly.
- APK_CanNeverPassInRegs
- };
+ friend class ASTDeclReader;
protected:
RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
@@ -3994,15 +4252,16 @@ public:
/// it must have at least one trivial, non-deleted copy or move constructor.
/// FIXME: This should be set as part of completeDefinition.
bool canPassInRegisters() const {
- return getArgPassingRestrictions() == APK_CanPassInRegs;
+ return getArgPassingRestrictions() == RecordArgPassingKind::CanPassInRegs;
}
- ArgPassingKind getArgPassingRestrictions() const {
- return static_cast<ArgPassingKind>(RecordDeclBits.ArgPassingRestrictions);
+ RecordArgPassingKind getArgPassingRestrictions() const {
+ return static_cast<RecordArgPassingKind>(
+ RecordDeclBits.ArgPassingRestrictions);
}
- void setArgPassingRestrictions(ArgPassingKind Kind) {
- RecordDeclBits.ArgPassingRestrictions = Kind;
+ void setArgPassingRestrictions(RecordArgPassingKind Kind) {
+ RecordDeclBits.ArgPassingRestrictions = llvm::to_underlying(Kind);
}
bool isParamDestroyedInCallee() const {
@@ -4013,6 +4272,12 @@ public:
RecordDeclBits.ParamDestroyedInCallee = V;
}
+ bool isRandomized() const { return RecordDeclBits.IsRandomized; }
+
+ void setIsRandomized(bool V) { RecordDeclBits.IsRandomized = V; }
+
+ void reorderDecls(const SmallVectorImpl<Decl *> &Decls);
+
/// Determines whether this declaration represents the
/// injected class name.
///
@@ -4097,9 +4362,16 @@ public:
/// nullptr is returned if no named data member exists.
const FieldDecl *findFirstNamedDataMember() const;
+ /// Get precomputed ODRHash or add a new one.
+ unsigned getODRHash();
+
private:
/// Deserialize just the fields.
void LoadFieldsFromExternalStorage() const;
+
+ /// True if a valid hash is stored in ODRHash.
+ bool hasODRHash() const { return RecordDeclBits.ODRHash; }
+ void setODRHash(unsigned Hash) { RecordDeclBits.ODRHash = Hash; }
};
class FileScopeAsmDecl : public Decl {
@@ -4134,6 +4406,41 @@ public:
static bool classofKind(Kind K) { return K == FileScopeAsm; }
};
+/// A declaration that models statements at global scope. This declaration
+/// supports incremental and interactive C/C++.
+///
+/// \note This is used in libInterpreter, clang -cc1 -fincremental-extensions
+/// and in tools such as clang-repl.
+class TopLevelStmtDecl : public Decl {
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
+ Stmt *Statement = nullptr;
+ bool IsSemiMissing = false;
+
+ TopLevelStmtDecl(DeclContext *DC, SourceLocation L, Stmt *S)
+ : Decl(TopLevelStmt, DC, L), Statement(S) {}
+
+ virtual void anchor();
+
+public:
+ static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement);
+ static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
+ Stmt *getStmt() { return Statement; }
+ const Stmt *getStmt() const { return Statement; }
+ void setStmt(Stmt *S) {
+ assert(IsSemiMissing && "Operation supported for printing values only!");
+ Statement = S;
+ }
+ bool isSemiMissing() const { return IsSemiMissing; }
+ void setSemiMissing(bool Missing = true) { IsSemiMissing = Missing; }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == TopLevelStmt; }
+};
+
/// Represents a block literal declaration, which is like an
/// unnamed FunctionDecl. For example:
/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
@@ -4429,6 +4736,16 @@ public:
/// @import std.vector;
/// \endcode
///
+/// A C++20 module import declaration imports the named module or partition.
+/// Periods are permitted in C++20 module names, but have no semantic meaning.
+/// For example:
+/// \code
+/// import NamedModule;
+/// import :SomePartition; // Must be a partition of the current module.
+/// import Names.Like.this; // Allowed.
+/// import :and.Also.Partition.names;
+/// \endcode
+///
/// Import declarations can also be implicitly generated from
/// \#include/\#import directives.
class ImportDecl final : public Decl,
@@ -4505,7 +4822,7 @@ public:
static bool classofKind(Kind K) { return K == Import; }
};
-/// Represents a C++ Modules TS module export declaration.
+/// Represents a standard C++ module export declaration.
///
/// For example:
/// \code
@@ -4572,11 +4889,56 @@ public:
static bool classofKind(Kind K) { return K == Empty; }
};
+/// HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
+class HLSLBufferDecl final : public NamedDecl, public DeclContext {
+ /// LBraceLoc - The ending location of the source range.
+ SourceLocation LBraceLoc;
+ /// RBraceLoc - The ending location of the source range.
+ SourceLocation RBraceLoc;
+ /// KwLoc - The location of the cbuffer or tbuffer keyword.
+ SourceLocation KwLoc;
+ /// IsCBuffer - Whether the buffer is a cbuffer (and not a tbuffer).
+ bool IsCBuffer;
+
+ HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc,
+ IdentifierInfo *ID, SourceLocation IDLoc,
+ SourceLocation LBrace);
+
+public:
+ static HLSLBufferDecl *Create(ASTContext &C, DeclContext *LexicalParent,
+ bool CBuffer, SourceLocation KwLoc,
+ IdentifierInfo *ID, SourceLocation IDLoc,
+ SourceLocation LBrace);
+ static HLSLBufferDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
+ return SourceRange(getLocStart(), RBraceLoc);
+ }
+ SourceLocation getLocStart() const LLVM_READONLY { return KwLoc; }
+ SourceLocation getLBraceLoc() const { return LBraceLoc; }
+ SourceLocation getRBraceLoc() const { return RBraceLoc; }
+ void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+ bool isCBuffer() const { return IsCBuffer; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == HLSLBuffer; }
+ static DeclContext *castToDeclContext(const HLSLBufferDecl *D) {
+ return static_cast<DeclContext *>(const_cast<HLSLBufferDecl *>(D));
+ }
+ static HLSLBufferDecl *castFromDeclContext(const DeclContext *DC) {
+ return static_cast<HLSLBufferDecl *>(const_cast<DeclContext *>(DC));
+ }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+};
+
/// Insertion operator for diagnostics. This allows sending NamedDecl's
/// into a diagnostic with <<.
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
const NamedDecl *ND) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
+ PD.AddTaggedVal(reinterpret_cast<uint64_t>(ND),
DiagnosticsEngine::ak_nameddecl);
return PD;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h
index 482d2889a25a..eb7a1a320600 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h
@@ -16,8 +16,10 @@
#include "clang/AST/ASTDumperUtils.h"
#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/SelectorLocationsKind.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
@@ -48,18 +50,12 @@ class ExternalSourceSymbolAttr;
class FunctionDecl;
class FunctionType;
class IdentifierInfo;
-enum Linkage : unsigned char;
+enum class Linkage : unsigned char;
class LinkageSpecDecl;
class Module;
class NamedDecl;
-class ObjCCategoryDecl;
-class ObjCCategoryImplDecl;
class ObjCContainerDecl;
-class ObjCImplDecl;
-class ObjCImplementationDecl;
-class ObjCInterfaceDecl;
class ObjCMethodDecl;
-class ObjCProtocolDecl;
struct PrintingPolicy;
class RecordDecl;
class SourceManager;
@@ -216,7 +212,7 @@ public:
/// The kind of ownership a declaration has, for visibility purposes.
/// This enumeration is designed such that higher values represent higher
/// levels of name hiding.
- enum class ModuleOwnershipKind : unsigned {
+ enum class ModuleOwnershipKind : unsigned char {
/// This declaration is not owned by a module.
Unowned,
@@ -231,8 +227,15 @@ public:
/// module is imported.
VisibleWhenImported,
+ /// This declaration has an owning module, and is visible to lookups
+ /// that occurs within that module. And it is reachable in other module
+ /// when the owning module is transitively imported.
+ ReachableWhenImported,
+
/// This declaration has an owning module, but is only visible to
/// lookups that occur within that module.
+ /// The discarded declarations in global module fragment belongs
+ /// to this group too.
ModulePrivate
};
@@ -241,8 +244,8 @@ protected:
/// DeclContext. These pointers form the linked list that is
/// traversed via DeclContext's decls_begin()/decls_end().
///
- /// The extra two bits are used for the ModuleOwnershipKind.
- llvm::PointerIntPair<Decl *, 2, ModuleOwnershipKind> NextInContextAndBits;
+ /// The extra three bits are used for the ModuleOwnershipKind.
+ llvm::PointerIntPair<Decl *, 3, ModuleOwnershipKind> NextInContextAndBits;
private:
friend class DeclContext;
@@ -282,31 +285,38 @@ private:
SourceLocation Loc;
/// DeclKind - This indicates which class this is.
+ LLVM_PREFERRED_TYPE(Kind)
unsigned DeclKind : 7;
/// InvalidDecl - This indicates a semantic error occurred.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InvalidDecl : 1;
/// HasAttrs - This indicates whether the decl has attributes or not.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasAttrs : 1;
/// Implicit - Whether this declaration was implicitly generated by
/// the implementation rather than explicitly written by the user.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Implicit : 1;
/// Whether this declaration was "used", meaning that a definition is
/// required.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Used : 1;
/// Whether this declaration was "referenced".
/// The difference with 'Used' is whether the reference appears in a
/// evaluated context or not, e.g. functions used in uninstantiated templates
/// are regarded as "referenced" but not "used".
+ LLVM_PREFERRED_TYPE(bool)
unsigned Referenced : 1;
/// Whether this declaration is a top-level declaration (function,
/// global variable, etc.) that is lexically inside an objc container
/// definition.
+ LLVM_PREFERRED_TYPE(bool)
unsigned TopLevelDeclInObjCContainer : 1;
/// Whether statistic collection is enabled.
@@ -319,20 +329,24 @@ protected:
friend class ASTReader;
friend class CXXClassMemberWrapper;
friend class LinkageComputer;
+ friend class RecordDecl;
template<typename decl_type> friend class Redeclarable;
/// Access - Used by C++ decls for the access specifier.
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
+ LLVM_PREFERRED_TYPE(AccessSpecifier)
unsigned Access : 2;
/// Whether this declaration was loaded from an AST file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned FromASTFile : 1;
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
+ LLVM_PREFERRED_TYPE(IdentifierNamespace)
unsigned IdentifierNamespace : 14;
/// If 0, we have not computed the linkage of this declaration.
- /// Otherwise, it is the linkage + 1.
+ LLVM_PREFERRED_TYPE(Linkage)
mutable unsigned CacheValidAndLinkage : 3;
/// Allocate memory for a deserialized declaration.
@@ -352,7 +366,7 @@ protected:
DeclContext *Parent, std::size_t Extra = 0);
private:
- bool AccessDeclContextSanity() const;
+ bool AccessDeclContextCheck() const;
/// Get the module ownership kind to use for a local lexical child of \p DC,
/// which may be either a local or (rarely) an imported declaration.
@@ -383,7 +397,7 @@ protected:
Implicit(false), Used(false), Referenced(false),
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- CacheValidAndLinkage(0) {
+ CacheValidAndLinkage(llvm::to_underlying(Linkage::Invalid)) {
if (StatisticsEnabled) add(DK);
}
@@ -392,7 +406,7 @@ protected:
Used(false), Referenced(false), TopLevelDeclInObjCContainer(false),
Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- CacheValidAndLinkage(0) {
+ CacheValidAndLinkage(llvm::to_underlying(Linkage::Invalid)) {
if (StatisticsEnabled) add(DK);
}
@@ -402,11 +416,11 @@ protected:
void updateOutOfDate(IdentifierInfo &II) const;
Linkage getCachedLinkage() const {
- return Linkage(CacheValidAndLinkage - 1);
+ return static_cast<Linkage>(CacheValidAndLinkage);
}
void setCachedLinkage(Linkage L) const {
- CacheValidAndLinkage = L + 1;
+ CacheValidAndLinkage = llvm::to_underlying(L);
}
bool hasCachedLinkage() const {
@@ -445,6 +459,14 @@ public:
return const_cast<Decl*>(this)->getDeclContext();
}
+ /// Return the non transparent context.
+ /// See the comment of `DeclContext::isTransparentContext()` for the
+ /// definition of transparent context.
+ DeclContext *getNonTransparentDeclContext();
+ const DeclContext *getNonTransparentDeclContext() const {
+ return const_cast<Decl *>(this)->getNonTransparentDeclContext();
+ }
+
/// Find the innermost non-closure ancestor of this declaration,
/// walking up through blocks, lambdas, etc. If that ancestor is
/// not a code context (!isFunctionOrMethod()), returns null.
@@ -464,6 +486,18 @@ public:
bool isInStdNamespace() const;
+ // Return true if this is a FileContext Decl.
+ bool isFileContextDecl() const;
+
+ /// Whether it resembles a flexible array member. This is a static member
+ /// because we want to be able to call it with a nullptr. That allows us to
+ /// perform non-Decl specific checks based on the object's type and strict
+ /// flex array level.
+ static bool isFlexibleArrayMemberLike(
+ ASTContext &Context, const Decl *D, QualType Ty,
+ LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
+ bool IgnoreTemplateOrMacroSubstitution);
+
ASTContext &getASTContext() const LLVM_READONLY;
/// Helper to get the language options from the ASTContext.
@@ -472,11 +506,11 @@ public:
void setAccess(AccessSpecifier AS) {
Access = AS;
- assert(AccessDeclContextSanity());
+ assert(AccessDeclContextCheck());
}
AccessSpecifier getAccess() const {
- assert(AccessDeclContextSanity());
+ assert(AccessDeclContextCheck());
return AccessSpecifier(Access);
}
@@ -514,17 +548,18 @@ public:
return hasAttrs() ? getAttrs().end() : nullptr;
}
- template <typename T>
- void dropAttr() {
+ template <typename... Ts> void dropAttrs() {
if (!HasAttrs) return;
AttrVec &Vec = getAttrs();
- llvm::erase_if(Vec, [](Attr *A) { return isa<T>(A); });
+ llvm::erase_if(Vec, [](Attr *A) { return isa<Ts...>(A); });
if (Vec.empty())
HasAttrs = false;
}
+ template <typename T> void dropAttr() { dropAttrs<T>(); }
+
template <typename T>
llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
return llvm::make_range(specific_attr_begin<T>(), specific_attr_end<T>());
@@ -613,6 +648,41 @@ public:
return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate;
}
+ /// Whether this declaration was exported in a lexical context.
+ /// e.g.:
+ ///
+ /// export namespace A {
+ /// void f1(); // isInExportDeclContext() == true
+ /// }
+ /// void A::f1(); // isInExportDeclContext() == false
+ ///
+ /// namespace B {
+ /// void f2(); // isInExportDeclContext() == false
+ /// }
+ /// export void B::f2(); // isInExportDeclContext() == true
+ bool isInExportDeclContext() const;
+
+ bool isInvisibleOutsideTheOwningModule() const {
+ return getModuleOwnershipKind() > ModuleOwnershipKind::VisibleWhenImported;
+ }
+
+ /// Whether this declaration comes from another module unit.
+ bool isInAnotherModuleUnit() const;
+
+ /// FIXME: Implement discarding declarations actually in global module
+ /// fragment. See [module.global.frag]p3,4 for details.
+ bool isDiscardedInGlobalModuleFragment() const { return false; }
+
+ /// Check if we should skip checking ODRHash for declaration \param D.
+ ///
+ /// The existing ODRHash mechanism seems to be not stable enough and
+ /// the false positive ODR violation reports are annoying and we rarely see
+ /// true ODR violation reports. Also we learned that MSVC disabled ODR checks
+ /// for declarations in GMF. So we try to disable ODR checks in the GMF to
+ /// get better user experiences before we make the ODR violation checks stable
+ /// enough.
+ bool shouldSkipCheckingODR() const;
+
/// Return true if this declaration has an attribute which acts as
/// definition of the entity, such as 'alias' or 'ifunc'.
bool hasDefiningAttr() const;
@@ -775,7 +845,7 @@ public:
}
/// Get the module that owns this declaration for linkage purposes.
- /// There only ever is such a module under the C++ Modules TS.
+ /// There only ever is such a standard C++ module.
///
/// \param IgnoreLinkage Ignore the linkage of the entity; assume that
/// all declarations in a global module fragment are unowned.
@@ -790,6 +860,11 @@ public:
return (int)getModuleOwnershipKind() <= (int)ModuleOwnershipKind::Visible;
}
+ bool isReachable() const {
+ return (int)getModuleOwnershipKind() <=
+ (int)ModuleOwnershipKind::ReachableWhenImported;
+ }
+
/// Set that this declaration is globally visible, even if it came from a
/// module that is not visible.
void setVisibleDespiteOwningModule() {
@@ -891,10 +966,12 @@ public:
/// If this decl is defined inside a function/method/block it returns
/// the corresponding DeclContext, otherwise it returns null.
- const DeclContext *getParentFunctionOrMethod() const;
- DeclContext *getParentFunctionOrMethod() {
- return const_cast<DeclContext*>(
- const_cast<const Decl*>(this)->getParentFunctionOrMethod());
+ const DeclContext *
+ getParentFunctionOrMethod(bool LexicalParent = false) const;
+ DeclContext *getParentFunctionOrMethod(bool LexicalParent = false) {
+ return const_cast<DeclContext *>(
+ const_cast<const Decl *>(this)->getParentFunctionOrMethod(
+ LexicalParent));
}
/// Retrieves the "canonical" declaration of the given declaration.
@@ -1089,7 +1166,7 @@ public:
/// Determine whether this is a block-scope declaration with linkage.
/// This will either be a local variable declaration declared 'extern', or a
/// local function declaration.
- bool isLocalExternDecl() {
+ bool isLocalExternDecl() const {
return IdentifierNamespace & IDNS_LocalExtern;
}
@@ -1130,6 +1207,12 @@ public:
}
}
+ /// Clears the namespace of this declaration.
+ ///
+ /// This is useful if we want this declaration to be available for
+ /// redeclaration lookup but otherwise hidden for ordinary name lookups.
+ void clearIdentifierNamespace() { IdentifierNamespace = 0; }
+
enum FriendObjectKind {
FOK_None, ///< Not a friend object.
FOK_Declared, ///< A friend of a previously-declared entity.
@@ -1185,6 +1268,10 @@ public:
/// have a FunctionType.
const FunctionType *getFunctionType(bool BlocksToo = true) const;
+ // Looks through the Decl's underlying type to determine if it's a
+ // function pointer type.
+ bool isFunctionPointerType() const;
+
private:
void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
@@ -1327,6 +1414,18 @@ public:
}
};
+/// Only used by CXXDeductionGuideDecl.
+enum class DeductionCandidate : unsigned char {
+ Normal,
+ Copy,
+ Aggregate,
+};
+
+enum class RecordArgPassingKind;
+enum class OMPDeclareReductionInitKind;
+enum class ObjCImplementationControl;
+enum class LinkageSpecLanguageIDs;
+
/// DeclContext - This is used only as base class of specific decl types that
/// can act as declaration contexts. These decls are (only the top classes
/// that directly derive from DeclContext are mentioned, not their subclasses):
@@ -1347,6 +1446,8 @@ public:
class DeclContext {
/// For makeDeclVisibleInContextImpl
friend class ASTDeclReader;
+ /// For checking the new bits in the Serialization part.
+ friend class ASTDeclWriter;
/// For reconcileExternalVisibleStorage, CreateStoredDeclsMap,
/// hasNeedToReconcileExternalVisibleStorage
friend class ExternalASTSource;
@@ -1365,35 +1466,42 @@ class DeclContext {
class DeclContextBitfields {
friend class DeclContext;
/// DeclKind - This indicates which class this is.
+ LLVM_PREFERRED_TYPE(Decl::Kind)
uint64_t DeclKind : 7;
/// Whether this declaration context also has some external
/// storage that contains additional declarations that are lexically
/// part of this context.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t ExternalLexicalStorage : 1;
/// Whether this declaration context also has some external
/// storage that contains additional declarations that are visible
/// in this context.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t ExternalVisibleStorage : 1;
/// Whether this declaration context has had externally visible
/// storage added since the last lookup. In this case, \c LookupPtr's
/// invariant may not hold and needs to be fixed before we perform
/// another lookup.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t NeedToReconcileExternalVisibleStorage : 1;
/// If \c true, this context may have local lexical declarations
/// that are missing from the lookup table.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t HasLazyLocalLexicalLookups : 1;
/// If \c true, the external source may have lexical declarations
/// that are missing from the lookup table.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t HasLazyExternalLexicalLookups : 1;
/// If \c true, lookups should only return identifier from
/// DeclContext scope (for example TranslationUnit). Used in
/// LookupQualifiedName()
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t UseQualifiedLookup : 1;
};
@@ -1406,48 +1514,60 @@ class DeclContext {
class TagDeclBitfields {
friend class TagDecl;
/// For the bits in DeclContextBitfields
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
/// The TagKind enum.
+ LLVM_PREFERRED_TYPE(TagTypeKind)
uint64_t TagDeclKind : 3;
/// True if this is a definition ("struct foo {};"), false if it is a
/// declaration ("struct foo;"). It is not considered a definition
/// until the definition has been fully processed.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsCompleteDefinition : 1;
/// True if this is currently being defined.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsBeingDefined : 1;
/// True if this tag declaration is "embedded" (i.e., defined or declared
/// for the very first time) in the syntax of a declarator.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsEmbeddedInDeclarator : 1;
/// True if this tag is free standing, e.g. "struct foo;".
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsFreeStanding : 1;
/// Indicates whether it is possible for declarations of this kind
/// to have an out-of-date definition.
///
/// This option is only enabled when modules are enabled.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t MayHaveOutOfDateDef : 1;
/// Has the full definition of this type been required by a use somewhere in
/// the TU.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsCompleteDefinitionRequired : 1;
+
+ /// Whether this tag is a definition which was demoted due to
+ /// a module merge.
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t IsThisDeclarationADemotedDefinition : 1;
};
- /// Number of non-inherited bits in TagDeclBitfields.
- enum { NumTagDeclBits = 9 };
+ /// Number of inherited and non-inherited bits in TagDeclBitfields.
+ enum { NumTagDeclBits = NumDeclContextBits + 10 };
/// Stores the bits used by EnumDecl.
/// If modified NumEnumDeclBit and the accessor
/// methods in EnumDecl should be updated appropriately.
class EnumDeclBitfields {
friend class EnumDecl;
- /// For the bits in DeclContextBitfields.
- uint64_t : NumDeclContextBits;
/// For the bits in TagDeclBitfields.
+ LLVM_PREFERRED_TYPE(TagDeclBitfields)
uint64_t : NumTagDeclBits;
/// Width in bits required to store all the non-negative
@@ -1460,78 +1580,102 @@ class DeclContext {
/// True if this tag declaration is a scoped enumeration. Only
/// possible in C++11 mode.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsScoped : 1;
/// If this tag declaration is a scoped enum,
/// then this is true if the scoped enum was declared using the class
/// tag, false if it was declared with the struct tag. No meaning is
/// associated if this tag declaration is not a scoped enum.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsScopedUsingClassTag : 1;
/// True if this is an enumeration with fixed underlying type. Only
/// possible in C++11, Microsoft extensions, or Objective C mode.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsFixed : 1;
/// True if a valid hash is stored in ODRHash.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasODRHash : 1;
};
- /// Number of non-inherited bits in EnumDeclBitfields.
- enum { NumEnumDeclBits = 20 };
+ /// Number of inherited and non-inherited bits in EnumDeclBitfields.
+ enum { NumEnumDeclBits = NumTagDeclBits + 20 };
/// Stores the bits used by RecordDecl.
/// If modified NumRecordDeclBits and the accessor
/// methods in RecordDecl should be updated appropriately.
class RecordDeclBitfields {
friend class RecordDecl;
- /// For the bits in DeclContextBitfields.
- uint64_t : NumDeclContextBits;
/// For the bits in TagDeclBitfields.
+ LLVM_PREFERRED_TYPE(TagDeclBitfields)
uint64_t : NumTagDeclBits;
/// This is true if this struct ends with a flexible
/// array member (e.g. int X[]) or if this union contains a struct that does.
/// If so, this cannot be contained in arrays or other structs as a member.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasFlexibleArrayMember : 1;
/// Whether this is the type of an anonymous struct or union.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t AnonymousStructOrUnion : 1;
/// This is true if this struct has at least one member
/// containing an Objective-C object pointer type.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasObjectMember : 1;
/// This is true if struct has at least one member of
/// 'volatile' type.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasVolatileMember : 1;
/// Whether the field declarations of this record have been loaded
/// from external storage. To avoid unnecessary deserialization of
/// methods/nested types we allow deserialization of just the fields
/// when needed.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t LoadedFieldsFromExternalStorage : 1;
/// Basic properties of non-trivial C structs.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t NonTrivialToPrimitiveDefaultInitialize : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t NonTrivialToPrimitiveCopy : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t NonTrivialToPrimitiveDestroy : 1;
/// The following bits indicate whether this is or contains a C union that
/// is non-trivial to default-initialize, destruct, or copy. These bits
/// imply the associated basic non-triviality predicates declared above.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasNonTrivialToPrimitiveDefaultInitializeCUnion : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasNonTrivialToPrimitiveDestructCUnion : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasNonTrivialToPrimitiveCopyCUnion : 1;
/// Indicates whether this struct is destroyed in the callee.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t ParamDestroyedInCallee : 1;
/// Represents the way this type is passed to a function.
+ LLVM_PREFERRED_TYPE(RecordArgPassingKind)
uint64_t ArgPassingRestrictions : 2;
+
+ /// Indicates whether this struct has had its field layout randomized.
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t IsRandomized : 1;
+
+ /// True if a valid hash is stored in ODRHash. This should shave off some
+ /// extra storage and prevent CXXRecordDecl to store unused bits.
+ uint64_t ODRHash : 26;
};
- /// Number of non-inherited bits in RecordDeclBitfields.
- enum { NumRecordDeclBits = 14 };
+ /// Number of inherited and non-inherited bits in RecordDeclBitfields.
+ enum { NumRecordDeclBits = NumTagDeclBits + 41 };
/// Stores the bits used by OMPDeclareReductionDecl.
/// If modified NumOMPDeclareReductionDeclBits and the accessor
@@ -1539,113 +1683,156 @@ class DeclContext {
class OMPDeclareReductionDeclBitfields {
friend class OMPDeclareReductionDecl;
/// For the bits in DeclContextBitfields
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
/// Kind of initializer,
- /// function call or omp_priv<init_expr> initializtion.
+ /// function call or omp_priv<init_expr> initialization.
+ LLVM_PREFERRED_TYPE(OMPDeclareReductionInitKind)
uint64_t InitializerKind : 2;
};
- /// Number of non-inherited bits in OMPDeclareReductionDeclBitfields.
- enum { NumOMPDeclareReductionDeclBits = 2 };
+ /// Number of inherited and non-inherited bits in
+ /// OMPDeclareReductionDeclBitfields.
+ enum { NumOMPDeclareReductionDeclBits = NumDeclContextBits + 2 };
/// Stores the bits used by FunctionDecl.
/// If modified NumFunctionDeclBits and the accessor
/// methods in FunctionDecl and CXXDeductionGuideDecl
- /// (for IsCopyDeductionCandidate) should be updated appropriately.
+ /// (for DeductionCandidateKind) should be updated appropriately.
class FunctionDeclBitfields {
friend class FunctionDecl;
- /// For IsCopyDeductionCandidate
+ /// For DeductionCandidateKind
friend class CXXDeductionGuideDecl;
/// For the bits in DeclContextBitfields.
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
+ LLVM_PREFERRED_TYPE(StorageClass)
uint64_t SClass : 3;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsInline : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsInlineSpecified : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsVirtualAsWritten : 1;
- uint64_t IsPure : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t IsPureVirtual : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasInheritedPrototype : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasWrittenPrototype : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsDeleted : 1;
/// Used by CXXMethodDecl
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsTrivial : 1;
/// This flag indicates whether this function is trivial for the purpose of
/// calls. This is meaningful only when this function is a copy/move
/// constructor or a destructor.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsTrivialForCall : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsDefaulted : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsExplicitlyDefaulted : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasDefaultedFunctionInfo : 1;
+
+ /// For member functions of complete types, whether this is an ineligible
+ /// special member function or an unselected destructor. See
+ /// [class.mem.special].
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t IsIneligibleOrNotSelected : 1;
+
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasImplicitReturnZero : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsLateTemplateParsed : 1;
/// Kind of contexpr specifier as defined by ConstexprSpecKind.
+ LLVM_PREFERRED_TYPE(ConstexprSpecKind)
uint64_t ConstexprKind : 2;
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t BodyContainsImmediateEscalatingExpression : 1;
+
+ LLVM_PREFERRED_TYPE(bool)
uint64_t InstantiationIsPending : 1;
/// Indicates if the function uses __try.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t UsesSEHTry : 1;
/// Indicates if the function was a definition
/// but its body was skipped.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasSkippedBody : 1;
/// Indicates if the function declaration will
/// have a body, once we're done parsing it.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t WillHaveBody : 1;
/// Indicates that this function is a multiversioned
/// function using attribute 'target'.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsMultiVersion : 1;
- /// [C++17] Only used by CXXDeductionGuideDecl. Indicates that
- /// the Deduction Guide is the implicitly generated 'copy
- /// deduction candidate' (is used during overload resolution).
- uint64_t IsCopyDeductionCandidate : 1;
+ /// Only used by CXXDeductionGuideDecl. Indicates the kind
+ /// of the Deduction Guide that is implicitly generated
+ /// (used during overload resolution).
+ LLVM_PREFERRED_TYPE(DeductionCandidate)
+ uint64_t DeductionCandidateKind : 2;
/// Store the ODRHash after first calculation.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasODRHash : 1;
/// Indicates if the function uses Floating Point Constrained Intrinsics
+ LLVM_PREFERRED_TYPE(bool)
uint64_t UsesFPIntrin : 1;
+
+ // Indicates this function is a constrained friend, where the constraint
+ // refers to an enclosing template for hte purposes of [temp.friend]p9.
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t FriendConstraintRefersToEnclosingTemplate : 1;
};
- /// Number of non-inherited bits in FunctionDeclBitfields.
- enum { NumFunctionDeclBits = 27 };
+ /// Number of inherited and non-inherited bits in FunctionDeclBitfields.
+ enum { NumFunctionDeclBits = NumDeclContextBits + 31 };
/// Stores the bits used by CXXConstructorDecl. If modified
/// NumCXXConstructorDeclBits and the accessor
/// methods in CXXConstructorDecl should be updated appropriately.
class CXXConstructorDeclBitfields {
friend class CXXConstructorDecl;
- /// For the bits in DeclContextBitfields.
- uint64_t : NumDeclContextBits;
/// For the bits in FunctionDeclBitfields.
+ LLVM_PREFERRED_TYPE(FunctionDeclBitfields)
uint64_t : NumFunctionDeclBits;
- /// 24 bits to fit in the remaining available space.
+ /// 20 bits to fit in the remaining available space.
/// Note that this makes CXXConstructorDeclBitfields take
/// exactly 64 bits and thus the width of NumCtorInitializers
/// will need to be shrunk if some bit is added to NumDeclContextBitfields,
/// NumFunctionDeclBitfields or CXXConstructorDeclBitfields.
- uint64_t NumCtorInitializers : 21;
+ uint64_t NumCtorInitializers : 17;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsInheritingConstructor : 1;
/// Whether this constructor has a trail-allocated explicit specifier.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasTrailingExplicitSpecifier : 1;
/// If this constructor does't have a trail-allocated explicit specifier.
/// Whether this constructor is explicit specified.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsSimpleExplicit : 1;
};
- /// Number of non-inherited bits in CXXConstructorDeclBitfields.
- enum {
- NumCXXConstructorDeclBits = 64 - NumDeclContextBits - NumFunctionDeclBits
- };
+ /// Number of inherited and non-inherited bits in CXXConstructorDeclBitfields.
+ enum { NumCXXConstructorDeclBits = NumFunctionDeclBits + 20 };
/// Stores the bits used by ObjCMethodDecl.
/// If modified NumObjCMethodDeclBits and the accessor
@@ -1654,43 +1841,56 @@ class DeclContext {
friend class ObjCMethodDecl;
/// For the bits in DeclContextBitfields.
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
/// The conventional meaning of this method; an ObjCMethodFamily.
/// This is not serialized; instead, it is computed on demand and
/// cached.
+ LLVM_PREFERRED_TYPE(ObjCMethodFamily)
mutable uint64_t Family : ObjCMethodFamilyBitWidth;
/// instance (true) or class (false) method.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsInstance : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsVariadic : 1;
/// True if this method is the getter or setter for an explicit property.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsPropertyAccessor : 1;
/// True if this method is a synthesized property accessor stub.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsSynthesizedAccessorStub : 1;
/// Method has a definition.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsDefined : 1;
/// Method redeclaration in the same interface.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsRedeclaration : 1;
/// Is redeclared in the same interface.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t HasRedeclaration : 1;
/// \@required/\@optional
+ LLVM_PREFERRED_TYPE(ObjCImplementationControl)
uint64_t DeclImplementation : 2;
/// in, inout, etc.
+ LLVM_PREFERRED_TYPE(Decl::ObjCDeclQualifier)
uint64_t objcDeclQualifier : 7;
/// Indicates whether this method has a related result type.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t RelatedResultType : 1;
/// Whether the locations of the selector identifiers are in a
/// "standard" position, a enum SelectorLocationsKind.
+ LLVM_PREFERRED_TYPE(SelectorLocationsKind)
uint64_t SelLocsKind : 2;
/// Whether this method overrides any other in the class hierarchy.
@@ -1700,14 +1900,16 @@ class DeclContext {
/// the same selector and is of the same kind (class or instance).
/// A method in an implementation is not considered as overriding the same
/// method in the interface or its categories.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsOverriding : 1;
/// Indicates if the method was a definition but its body was skipped.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasSkippedBody : 1;
};
- /// Number of non-inherited bits in ObjCMethodDeclBitfields.
- enum { NumObjCMethodDeclBits = 24 };
+ /// Number of inherited and non-inherited bits in ObjCMethodDeclBitfields.
+ enum { NumObjCMethodDeclBits = NumDeclContextBits + 24 };
/// Stores the bits used by ObjCContainerDecl.
/// If modified NumObjCContainerDeclBits and the accessor
@@ -1715,6 +1917,7 @@ class DeclContext {
class ObjCContainerDeclBitfields {
friend class ObjCContainerDecl;
/// For the bits in DeclContextBitfields
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint32_t : NumDeclContextBits;
// Not a bitfield but this saves space.
@@ -1722,10 +1925,10 @@ class DeclContext {
SourceLocation AtStart;
};
- /// Number of non-inherited bits in ObjCContainerDeclBitfields.
+ /// Number of inherited and non-inherited bits in ObjCContainerDeclBitfields.
/// Note that here we rely on the fact that SourceLocation is 32 bits
/// wide. We check this with the static_assert in the ctor of DeclContext.
- enum { NumObjCContainerDeclBits = 64 - NumDeclContextBits };
+ enum { NumObjCContainerDeclBits = 64 };
/// Stores the bits used by LinkageSpecDecl.
/// If modified NumLinkageSpecDeclBits and the accessor
@@ -1733,21 +1936,23 @@ class DeclContext {
class LinkageSpecDeclBitfields {
friend class LinkageSpecDecl;
/// For the bits in DeclContextBitfields.
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
- /// The language for this linkage specification with values
- /// in the enum LinkageSpecDecl::LanguageIDs.
+ /// The language for this linkage specification.
+ LLVM_PREFERRED_TYPE(LinkageSpecLanguageIDs)
uint64_t Language : 3;
/// True if this linkage spec has braces.
/// This is needed so that hasBraces() returns the correct result while the
/// linkage spec body is being parsed. Once RBraceLoc has been set this is
/// not used, so it doesn't need to be serialized.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasBraces : 1;
};
- /// Number of non-inherited bits in LinkageSpecDeclBitfields.
- enum { NumLinkageSpecDeclBits = 4 };
+ /// Number of inherited and non-inherited bits in LinkageSpecDeclBitfields.
+ enum { NumLinkageSpecDeclBits = NumDeclContextBits + 4 };
/// Stores the bits used by BlockDecl.
/// If modified NumBlockDeclBits and the accessor
@@ -1755,25 +1960,32 @@ class DeclContext {
class BlockDeclBitfields {
friend class BlockDecl;
/// For the bits in DeclContextBitfields.
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsVariadic : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t CapturesCXXThis : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t BlockMissingReturnType : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsConversionFromLambda : 1;
/// A bit that indicates this block is passed directly to a function as a
/// non-escaping parameter.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t DoesNotEscape : 1;
/// A bit that indicates whether it's possible to avoid coying this block to
/// the heap when it initializes or is assigned to a local variable with
/// automatic storage.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t CanAvoidCopyToHeap : 1;
};
- /// Number of non-inherited bits in BlockDeclBitfields.
- enum { NumBlockDeclBits = 5 };
+ /// Number of inherited and non-inherited bits in BlockDeclBitfields.
+ enum { NumBlockDeclBits = NumDeclContextBits + 5 };
/// Pointer to the data structure used to lookup declarations
/// within this context (or a DependentStoredDeclsMap if this is a
@@ -1850,6 +2062,10 @@ protected:
public:
~DeclContext();
+ // For use when debugging; hasValidDeclKind() will always return true for
+ // a correctly constructed object within its lifetime.
+ bool hasValidDeclKind() const;
+
Decl::Kind getDeclKind() const {
return static_cast<Decl::Kind>(DeclContextBits.DeclKind);
}
@@ -1965,7 +2181,7 @@ public:
/// Here, E is a transparent context, so its enumerator (Val1) will
/// appear (semantically) that it is in the same context of E.
/// Examples of transparent contexts include: enumerations (except for
- /// C++0x scoped enums), and C++ linkage specifications.
+ /// C++0x scoped enums), C++ linkage specifications and export declaration.
bool isTransparentContext() const;
/// Determines whether this context or some of its ancestors is a
@@ -1997,6 +2213,12 @@ public:
return const_cast<DeclContext*>(this)->getNonClosureAncestor();
}
+ // Retrieve the nearest context that is not a transparent context.
+ DeclContext *getNonTransparentContext();
+ const DeclContext *getNonTransparentContext() const {
+ return const_cast<DeclContext *>(this)->getNonTransparentContext();
+ }
+
/// getPrimaryContext - There may be many different
/// declarations of the same entity (including forward declarations
/// of classes, multiple definitions of namespaces, etc.), each with
@@ -2452,10 +2674,8 @@ public:
D == LastDecl);
}
- bool setUseQualifiedLookup(bool use = true) const {
- bool old_value = DeclContextBits.UseQualifiedLookup;
+ void setUseQualifiedLookup(bool use = true) const {
DeclContextBits.UseQualifiedLookup = use;
- return old_value;
}
bool shouldUseQualifiedLookup() const {
@@ -2465,6 +2685,8 @@ public:
static bool classof(const Decl *D);
static bool classof(const DeclContext *D) { return true; }
+ void dumpAsDecl() const;
+ void dumpAsDecl(const ASTContext *Ctx) const;
void dumpDeclContext() const;
void dumpLookups() const;
void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false,
@@ -2514,14 +2736,6 @@ private:
void reconcileExternalVisibleStorage() const;
bool LoadLexicalDeclsFromExternalStorage() const;
- /// Makes a declaration visible within this context, but
- /// suppresses searches for external declarations with the same
- /// name.
- ///
- /// Analogous to makeDeclVisibleInContext, but for the exclusive
- /// use of addDeclInternal().
- void makeDeclVisibleInContextInternal(NamedDecl *D);
-
StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
void loadLazyLocalLexicalLookups();
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h b/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h
index 0d5ad40fc19e..9cebaff63bb0 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h
@@ -64,7 +64,6 @@ class CXXFinalOverriderMap;
class CXXIndirectPrimaryBaseSet;
class CXXMethodDecl;
class DecompositionDecl;
-class DiagnosticBuilder;
class FriendDecl;
class FunctionTemplateDecl;
class IdentifierInfo;
@@ -155,22 +154,26 @@ class CXXBaseSpecifier {
SourceLocation EllipsisLoc;
/// Whether this is a virtual base class or not.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Virtual : 1;
/// Whether this is the base of a class (true) or of a struct (false).
///
/// This determines the mapping from the access specifier as written in the
/// source code to the access specifier used for semantic analysis.
+ LLVM_PREFERRED_TYPE(bool)
unsigned BaseOfClass : 1;
/// Access specifier as written in the source code (may be AS_none).
///
/// The actual type of data stored here is an AccessSpecifier, but we use
- /// "unsigned" here to work around a VC++ bug.
+ /// "unsigned" here to work around Microsoft ABI.
+ LLVM_PREFERRED_TYPE(AccessSpecifier)
unsigned Access : 2;
/// Whether the class contains a using declaration
/// to inherit the named class's constructors.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InheritConstructors : 1;
/// The type of the base class.
@@ -261,8 +264,9 @@ class CXXRecordDecl : public RecordDecl {
friend class ASTWriter;
friend class DeclContext;
friend class LambdaExpr;
+ friend class ODRDiagsEmitter;
- friend void FunctionDecl::setPure(bool);
+ friend void FunctionDecl::setIsPureVirtual(bool);
friend void TagDecl::startDefinition();
/// Values used in DefinitionData fields to represent special members.
@@ -276,21 +280,33 @@ class CXXRecordDecl : public RecordDecl {
SMF_All = 0x3f
};
+public:
+ enum LambdaDependencyKind {
+ LDK_Unknown = 0,
+ LDK_AlwaysDependent,
+ LDK_NeverDependent,
+ };
+
+private:
struct DefinitionData {
#define FIELD(Name, Width, Merge) \
unsigned Name : Width;
#include "CXXRecordDeclDefinitionBits.def"
/// Whether this class describes a C++ lambda.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsLambda : 1;
/// Whether we are currently parsing base specifiers.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsParsingBaseSpecifiers : 1;
/// True when visible conversion functions are already computed
/// and are available.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ComputedVisibleConversions : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasODRHash : 1;
/// A hash of parts of the class to help in ODR checking.
@@ -349,11 +365,11 @@ class CXXRecordDecl : public RecordDecl {
}
ArrayRef<CXXBaseSpecifier> bases() const {
- return llvm::makeArrayRef(getBases(), NumBases);
+ return llvm::ArrayRef(getBases(), NumBases);
}
ArrayRef<CXXBaseSpecifier> vbases() const {
- return llvm::makeArrayRef(getVBases(), NumVBases);
+ return llvm::ArrayRef(getVBases(), NumVBases);
}
private:
@@ -375,46 +391,56 @@ class CXXRecordDecl : public RecordDecl {
/// lambda will have been created with the enclosing context as its
/// declaration context, rather than function. This is an unfortunate
/// artifact of having to parse the default arguments before.
- unsigned Dependent : 1;
+ LLVM_PREFERRED_TYPE(LambdaDependencyKind)
+ unsigned DependencyKind : 2;
/// Whether this lambda is a generic lambda.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsGenericLambda : 1;
/// The Default Capture.
+ LLVM_PREFERRED_TYPE(LambdaCaptureDefault)
unsigned CaptureDefault : 2;
/// The number of captures in this lambda is limited 2^NumCaptures.
unsigned NumCaptures : 15;
/// The number of explicit captures in this lambda.
- unsigned NumExplicitCaptures : 13;
+ unsigned NumExplicitCaptures : 12;
/// Has known `internal` linkage.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasKnownInternalLinkage : 1;
/// The number used to indicate this lambda expression for name
/// mangling in the Itanium C++ ABI.
unsigned ManglingNumber : 31;
+ /// The index of this lambda within its context declaration. This is not in
+ /// general the same as the mangling number.
+ unsigned IndexInContext;
+
/// The declaration that provides context for this lambda, if the
/// actual DeclContext does not suffice. This is used for lambdas that
/// occur within default arguments of function parameters within the class
/// or within a data member initializer.
LazyDeclPtr ContextDecl;
- /// The list of captures, both explicit and implicit, for this
- /// lambda.
- Capture *Captures = nullptr;
+ /// The lists of captures, both explicit and implicit, for this
+ /// lambda. One list is provided for each merged copy of the lambda.
+ /// The first list corresponds to the canonical definition.
+ /// The destructor is registered by AddCaptureList when necessary.
+ llvm::TinyPtrVector<Capture*> Captures;
/// The type of the call method.
TypeSourceInfo *MethodTyInfo;
- LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent,
+ LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, unsigned DK,
bool IsGeneric, LambdaCaptureDefault CaptureDefault)
- : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
+ : DefinitionData(D), DependencyKind(DK), IsGenericLambda(IsGeneric),
CaptureDefault(CaptureDefault), NumCaptures(0),
NumExplicitCaptures(0), HasKnownInternalLinkage(0), ManglingNumber(0),
- MethodTyInfo(Info) {
+ IndexInContext(0), MethodTyInfo(Info) {
IsLambda = true;
// C++1z [expr.prim.lambda]p4:
@@ -422,6 +448,9 @@ class CXXRecordDecl : public RecordDecl {
Aggregate = false;
PlainOldData = false;
}
+
+ // Add a list of captures.
+ void AddCaptureList(ASTContext &Ctx, Capture *CaptureList);
};
struct DefinitionData *dataPtr() const {
@@ -548,7 +577,7 @@ public:
bool DelayTypeCreation = false);
static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
TypeSourceInfo *Info, SourceLocation Loc,
- bool DependentLambda, bool IsGeneric,
+ unsigned DependencyKind, bool IsGeneric,
LambdaCaptureDefault CaptureDefault);
static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
@@ -1035,6 +1064,12 @@ public:
return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault);
}
+ bool isCapturelessLambda() const {
+ if (!isLambda())
+ return false;
+ return getLambdaCaptureDefault() == LCD_None && capture_size() == 0;
+ }
+
/// Set the captures for this lambda closure type.
void setCaptures(ASTContext &Context, ArrayRef<LambdaCapture> Captures);
@@ -1050,8 +1085,14 @@ public:
///
/// \note No entries will be added for init-captures, as they do not capture
/// variables.
- void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
- FieldDecl *&ThisCapture) const;
+ ///
+ /// \note If multiple versions of the lambda are merged together, they may
+ /// have different variable declarations corresponding to the same capture.
+ /// In that case, all of those variable declarations will be added to the
+ /// Captures list, so it may have more than one variable listed per field.
+ void
+ getCaptureFields(llvm::DenseMap<const ValueDecl *, FieldDecl *> &Captures,
+ FieldDecl *&ThisCapture) const;
using capture_const_iterator = const LambdaCapture *;
using capture_const_range = llvm::iterator_range<capture_const_iterator>;
@@ -1061,7 +1102,9 @@ public:
}
capture_const_iterator captures_begin() const {
- return isLambda() ? getLambdaData().Captures : nullptr;
+ if (!isLambda()) return nullptr;
+ LambdaDefinitionData &LambdaData = getLambdaData();
+ return LambdaData.Captures.empty() ? nullptr : LambdaData.Captures.front();
}
capture_const_iterator captures_end() const {
@@ -1071,6 +1114,11 @@ public:
unsigned capture_size() const { return getLambdaData().NumCaptures; }
+ const LambdaCapture *getCapture(unsigned I) const {
+ assert(isLambda() && I < capture_size() && "invalid index for capture");
+ return captures_begin() + I;
+ }
+
using conversion_iterator = UnresolvedSetIterator;
conversion_iterator conversion_begin() const {
@@ -1139,6 +1187,13 @@ public:
///
/// \note This does NOT include a check for union-ness.
bool isEmpty() const { return data().Empty; }
+ /// Marks this record as empty. This is used by DWARFASTParserClang
+ /// when parsing records with empty fields having [[no_unique_address]]
+ /// attribute
+ void markEmpty() { data().Empty = true; }
+
+ void setInitMethod(bool Val) { data().HasInitMethod = Val; }
+ bool hasInitMethod() const { return data().HasInitMethod; }
bool hasPrivateFields() const {
return data().HasPrivateFields;
@@ -1160,7 +1215,7 @@ public:
/// Determine whether this class has a pure virtual function.
///
- /// The class is is abstract per (C++ [class.abstract]p2) if it declares
+ /// The class is abstract per (C++ [class.abstract]p2) if it declares
/// a pure virtual function or inherits a pure virtual function that is
/// not overridden.
bool isAbstract() const { return data().Abstract; }
@@ -1370,6 +1425,9 @@ public:
/// (C++11 [class]p6).
bool isTriviallyCopyable() const;
+ /// Determine whether this class is considered trivially copyable per
+ bool isTriviallyCopyConstructible() const;
+
/// Determine whether this class is considered trivial.
///
/// C++11 [class]p6:
@@ -1381,37 +1439,39 @@ public:
/// Determine whether this class is a literal type.
///
- /// C++11 [basic.types]p10:
+ /// C++20 [basic.types]p10:
/// A class type that has all the following properties:
- /// - it has a trivial destructor
- /// - every constructor call and full-expression in the
- /// brace-or-equal-intializers for non-static data members (if any) is
- /// a constant expression.
- /// - it is an aggregate type or has at least one constexpr constructor
- /// or constructor template that is not a copy or move constructor, and
- /// - all of its non-static data members and base classes are of literal
- /// types
- ///
- /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
- /// treating types with trivial default constructors as literal types.
- ///
- /// Only in C++17 and beyond, are lambdas literal types.
- bool isLiteral() const {
- const LangOptions &LangOpts = getLangOpts();
- return (LangOpts.CPlusPlus20 ? hasConstexprDestructor()
- : hasTrivialDestructor()) &&
- (!isLambda() || LangOpts.CPlusPlus17) &&
- !hasNonLiteralTypeFieldsOrBases() &&
- (isAggregate() || isLambda() ||
- hasConstexprNonCopyMoveConstructor() ||
- hasTrivialDefaultConstructor());
- }
+ /// - it has a constexpr destructor
+ /// - all of its non-static non-variant data members and base classes
+ /// are of non-volatile literal types, and it:
+ /// - is a closure type
+ /// - is an aggregate union type that has either no variant members
+ /// or at least one variant member of non-volatile literal type
+ /// - is a non-union aggregate type for which each of its anonymous
+ /// union members satisfies the above requirements for an aggregate
+ /// union type, or
+ /// - has at least one constexpr constructor or constructor template
+ /// that is not a copy or move constructor.
+ bool isLiteral() const;
/// Determine whether this is a structural type.
bool isStructural() const {
return isLiteral() && data().StructuralIfLiteral;
}
+ /// Notify the class that this destructor is now selected.
+ ///
+ /// Important properties of the class depend on destructor properties. Since
+ /// C++20, it is possible to have multiple destructor declarations in a class
+ /// out of which one will be selected at the end.
+ /// This is called separately from addedMember because it has to be deferred
+ /// to the completion of the class.
+ void addedSelectedDestructor(CXXDestructorDecl *DD);
+
+ /// Notify the class that an eligible SMF has been added.
+ /// This updates triviality and destructor based properties of the class accordingly.
+ void addedEligibleSpecialMemberFunction(const CXXMethodDecl *MD, unsigned SMKind);
+
/// If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
@@ -1726,18 +1786,31 @@ public:
/// the declaration context suffices.
Decl *getLambdaContextDecl() const;
- /// Set the mangling number and context declaration for a lambda
- /// class.
- void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl,
- bool HasKnownInternalLinkage = false) {
+ /// Retrieve the index of this lambda within the context declaration returned
+ /// by getLambdaContextDecl().
+ unsigned getLambdaIndexInContext() const {
assert(isLambda() && "Not a lambda closure type!");
- getLambdaData().ManglingNumber = ManglingNumber;
- getLambdaData().ContextDecl = ContextDecl;
- getLambdaData().HasKnownInternalLinkage = HasKnownInternalLinkage;
+ return getLambdaData().IndexInContext;
}
- /// Set the device side mangling number.
- void setDeviceLambdaManglingNumber(unsigned Num) const;
+ /// Information about how a lambda is numbered within its context.
+ struct LambdaNumbering {
+ Decl *ContextDecl = nullptr;
+ unsigned IndexInContext = 0;
+ unsigned ManglingNumber = 0;
+ unsigned DeviceManglingNumber = 0;
+ bool HasKnownInternalLinkage = false;
+ };
+
+ /// Set the mangling numbers and context declaration for a lambda class.
+ void setLambdaNumbering(LambdaNumbering Numbering);
+
+ // Get the mangling numbers and context declaration for a lambda class.
+ LambdaNumbering getLambdaNumbering() const {
+ return {getLambdaContextDecl(), getLambdaIndexInContext(),
+ getLambdaManglingNumber(), getDeviceLambdaManglingNumber(),
+ hasKnownLambdaInternalLinkage()};
+ }
/// Retrieve the device side mangling number.
unsigned getDeviceLambdaManglingNumber() const;
@@ -1772,13 +1845,37 @@ public:
/// function declaration itself is dependent. This flag indicates when we
/// know that the lambda is dependent despite that.
bool isDependentLambda() const {
- return isLambda() && getLambdaData().Dependent;
+ return isLambda() && getLambdaData().DependencyKind == LDK_AlwaysDependent;
+ }
+
+ bool isNeverDependentLambda() const {
+ return isLambda() && getLambdaData().DependencyKind == LDK_NeverDependent;
+ }
+
+ unsigned getLambdaDependencyKind() const {
+ if (!isLambda())
+ return LDK_Unknown;
+ return getLambdaData().DependencyKind;
}
TypeSourceInfo *getLambdaTypeInfo() const {
return getLambdaData().MethodTyInfo;
}
+ void setLambdaTypeInfo(TypeSourceInfo *TS) {
+ assert(DefinitionData && DefinitionData->IsLambda &&
+ "setting lambda property of non-lambda class");
+ auto &DL = static_cast<LambdaDefinitionData &>(*DefinitionData);
+ DL.MethodTyInfo = TS;
+ }
+
+ void setLambdaIsGeneric(bool IsGeneric) {
+ assert(DefinitionData && DefinitionData->IsLambda &&
+ "setting lambda property of non-lambda class");
+ auto &DL = static_cast<LambdaDefinitionData &>(*DefinitionData);
+ DL.IsGenericLambda = IsGeneric;
+ }
+
// Determine whether this type is an Interface Like type for
// __interface inheritance purposes.
bool isInterfaceLike() const;
@@ -1855,13 +1952,13 @@ private:
ExplicitSpecifier ES,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, SourceLocation EndLocation,
- CXXConstructorDecl *Ctor)
+ CXXConstructorDecl *Ctor, DeductionCandidate Kind)
: FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
- SC_None, false, ConstexprSpecKind::Unspecified),
+ SC_None, false, false, ConstexprSpecKind::Unspecified),
Ctor(Ctor), ExplicitSpec(ES) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
- setIsCopyDeductionCandidate(false);
+ setDeductionCandidateKind(Kind);
}
CXXConstructorDecl *Ctor;
@@ -1876,14 +1973,15 @@ public:
Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, SourceLocation EndLocation,
- CXXConstructorDecl *Ctor = nullptr);
+ CXXConstructorDecl *Ctor = nullptr,
+ DeductionCandidate Kind = DeductionCandidate::Normal);
static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID);
ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; }
const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; }
- /// Return true if the declartion is already resolved to be explicit.
+ /// Return true if the declaration is already resolved to be explicit.
bool isExplicit() const { return ExplicitSpec.isExplicit(); }
/// Get the template for which this guide performs deduction.
@@ -1893,16 +1991,15 @@ public:
/// Get the constructor from which this deduction guide was generated, if
/// this is an implicit deduction guide.
- CXXConstructorDecl *getCorrespondingConstructor() const {
- return Ctor;
- }
+ CXXConstructorDecl *getCorrespondingConstructor() const { return Ctor; }
- void setIsCopyDeductionCandidate(bool isCDC = true) {
- FunctionDeclBits.IsCopyDeductionCandidate = isCDC;
+ void setDeductionCandidateKind(DeductionCandidate K) {
+ FunctionDeclBits.DeductionCandidateKind = static_cast<unsigned char>(K);
}
- bool isCopyDeductionCandidate() const {
- return FunctionDeclBits.IsCopyDeductionCandidate;
+ DeductionCandidate getDeductionCandidateKind() const {
+ return static_cast<DeductionCandidate>(
+ FunctionDeclBits.DeductionCandidateKind);
}
// Implement isa/cast/dyncast/etc.
@@ -1939,6 +2036,14 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == RequiresExprBody; }
+
+ static DeclContext *castToDeclContext(const RequiresExprBodyDecl *D) {
+ return static_cast<DeclContext *>(const_cast<RequiresExprBodyDecl *>(D));
+ }
+
+ static RequiresExprBodyDecl *castFromDeclContext(const DeclContext *DC) {
+ return static_cast<RequiresExprBodyDecl *>(const_cast<DeclContext *>(DC));
+ }
};
/// Represents a static or instance method of a struct/union/class.
@@ -1952,29 +2057,39 @@ protected:
CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo, StorageClass SC,
- bool isInline, ConstexprSpecKind ConstexprKind,
- SourceLocation EndLocation,
+ bool UsesFPIntrin, bool isInline,
+ ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr)
- : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, isInline,
- ConstexprKind, TrailingRequiresClause) {
+ : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
+ isInline, ConstexprKind, TrailingRequiresClause) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
}
public:
- static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, StorageClass SC,
- bool isInline, ConstexprSpecKind ConstexprKind,
- SourceLocation EndLocation,
- Expr *TrailingRequiresClause = nullptr);
+ static CXXMethodDecl *
+ Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
+ StorageClass SC, bool UsesFPIntrin, bool isInline,
+ ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
+ Expr *TrailingRequiresClause = nullptr);
static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
bool isStatic() const;
bool isInstance() const { return !isStatic(); }
+ /// [C++2b][dcl.fct]/p7
+ /// An explicit object member function is a non-static
+ /// member function with an explicit object parameter. e.g.,
+ /// void func(this SomeType);
+ bool isExplicitObjectMemberFunction() const;
+
+ /// [C++2b][dcl.fct]/p7
+ /// An implicit object member function is a non-static
+ /// member function without an explicit object parameter.
+ bool isImplicitObjectMemberFunction() const;
+
/// Returns true if the given operator is implicitly static in a record
/// context.
static bool isStaticOverloadedOperator(OverloadedOperatorKind OOK) {
@@ -1995,7 +2110,7 @@ public:
// Member function is virtual if it is marked explicitly so, or if it is
// declared in __interface -- then it is automatically pure virtual.
- if (CD->isVirtualAsWritten() || CD->isPure())
+ if (CD->isVirtualAsWritten() || CD->isPureVirtual())
return true;
return CD->size_overridden_methods() != 0;
@@ -2083,14 +2198,19 @@ public:
/// Return the type of the object pointed by \c this.
///
/// See getThisType() for usage restriction.
- QualType getThisObjectType() const;
+
+ QualType getFunctionObjectParameterReferenceType() const;
+ QualType getFunctionObjectParameterType() const {
+ return getFunctionObjectParameterReferenceType().getNonReferenceType();
+ }
+
+ unsigned getNumExplicitParams() const {
+ return getNumParams() - (isExplicitObjectMemberFunction() ? 1 : 0);
+ }
static QualType getThisType(const FunctionProtoType *FPT,
const CXXRecordDecl *Decl);
- static QualType getThisObjectType(const FunctionProtoType *FPT,
- const CXXRecordDecl *Decl);
-
Qualifiers getMethodQualifiers() const {
return getType()->castAs<FunctionProtoType>()->getMethodQuals();
}
@@ -2197,14 +2317,17 @@ class CXXCtorInitializer final {
/// If the initializee is a type, whether that type makes this
/// a delegating initialization.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsDelegating : 1;
/// If the initializer is a base initializer, this keeps track
/// of whether the base is virtual or not.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsVirtual : 1;
/// Whether or not the initializer is explicitly written
/// in the sources.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsWritten : 1;
/// If IsWritten is true, then this number keeps track of the textual order
@@ -2413,7 +2536,8 @@ class CXXConstructorDecl final
CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool isInline,
+ TypeSourceInfo *TInfo, ExplicitSpecifier ES,
+ bool UsesFPIntrin, bool isInline,
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
InheritedConstructor Inherited,
Expr *TrailingRequiresClause);
@@ -2456,8 +2580,8 @@ public:
static CXXConstructorDecl *
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
- ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
- ConstexprSpecKind ConstexprKind,
+ ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
+ bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
InheritedConstructor Inherited = InheritedConstructor(),
Expr *TrailingRequiresClause = nullptr);
@@ -2479,7 +2603,7 @@ public:
return getCanonicalDecl()->getExplicitSpecifierInternal();
}
- /// Return true if the declartion is already resolved to be explicit.
+ /// Return true if the declaration is already resolved to be explicit.
bool isExplicit() const { return getExplicitSpecifier().isExplicit(); }
/// Iterates through the member/base initializer list.
@@ -2676,25 +2800,24 @@ class CXXDestructorDecl : public CXXMethodDecl {
CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, bool isInline,
+ TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr)
: CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, ConstexprKind, SourceLocation(),
- TrailingRequiresClause) {
+ SC_None, UsesFPIntrin, isInline, ConstexprKind,
+ SourceLocation(), TrailingRequiresClause) {
setImplicit(isImplicitlyDeclared);
}
void anchor() override;
public:
- static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isImplicitlyDeclared,
- ConstexprSpecKind ConstexprKind,
- Expr *TrailingRequiresClause = nullptr);
+ static CXXDestructorDecl *
+ Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
+ bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
+ ConstexprSpecKind ConstexprKind,
+ Expr *TrailingRequiresClause = nullptr);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
@@ -2732,12 +2855,13 @@ public:
class CXXConversionDecl : public CXXMethodDecl {
CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, bool isInline, ExplicitSpecifier ES,
- ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
+ TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
+ ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
+ SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr)
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, ConstexprKind, EndLocation,
- TrailingRequiresClause),
+ SC_None, UsesFPIntrin, isInline, ConstexprKind,
+ EndLocation, TrailingRequiresClause),
ExplicitSpec(ES) {}
void anchor() override;
@@ -2750,8 +2874,9 @@ public:
static CXXConversionDecl *
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
- bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
- SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr);
+ bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
+ ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
+ Expr *TrailingRequiresClause = nullptr);
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
ExplicitSpecifier getExplicitSpecifier() {
@@ -2762,7 +2887,7 @@ public:
return getCanonicalDecl()->ExplicitSpec;
}
- /// Return true if the declartion is already resolved to be explicit.
+ /// Return true if the declaration is already resolved to be explicit.
bool isExplicit() const { return getExplicitSpecifier().isExplicit(); }
void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; }
@@ -2787,6 +2912,12 @@ public:
static bool classofKind(Kind K) { return K == CXXConversion; }
};
+/// Represents the language in a linkage specification.
+///
+/// The values are part of the serialization ABI for
+/// ASTs and cannot be changed without altering that ABI.
+enum class LinkageSpecLanguageIDs { C = 1, CXX = 2 };
+
/// Represents a linkage specification.
///
/// For example:
@@ -2797,14 +2928,7 @@ class LinkageSpecDecl : public Decl, public DeclContext {
virtual void anchor();
// This class stores some data in DeclContext::LinkageSpecDeclBits to save
// some space. Use the provided accessors to access it.
-public:
- /// Represents the language in a linkage specification.
- ///
- /// The values are part of the serialization ABI for
- /// ASTs and cannot be changed without altering that ABI.
- enum LanguageIDs { lang_c = 1, lang_cxx = 2 };
-private:
/// The source location for the extern keyword.
SourceLocation ExternLoc;
@@ -2812,22 +2936,25 @@ private:
SourceLocation RBraceLoc;
LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
- SourceLocation LangLoc, LanguageIDs lang, bool HasBraces);
+ SourceLocation LangLoc, LinkageSpecLanguageIDs lang,
+ bool HasBraces);
public:
static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation ExternLoc,
- SourceLocation LangLoc, LanguageIDs Lang,
- bool HasBraces);
+ SourceLocation LangLoc,
+ LinkageSpecLanguageIDs Lang, bool HasBraces);
static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// Return the language specified by this linkage specification.
- LanguageIDs getLanguage() const {
- return static_cast<LanguageIDs>(LinkageSpecDeclBits.Language);
+ LinkageSpecLanguageIDs getLanguage() const {
+ return static_cast<LinkageSpecLanguageIDs>(LinkageSpecDeclBits.Language);
}
/// Set the language specified by this linkage specification.
- void setLanguage(LanguageIDs L) { LinkageSpecDeclBits.Language = L; }
+ void setLanguage(LinkageSpecLanguageIDs L) {
+ LinkageSpecDeclBits.Language = llvm::to_underlying(L);
+ }
/// Determines whether this linkage specification had braces in
/// its syntactic form.
@@ -3290,7 +3417,7 @@ class BaseUsingDecl : public NamedDecl {
protected:
BaseUsingDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
- : NamedDecl(DK, DC, L, N), FirstUsingShadow(nullptr, 0) {}
+ : NamedDecl(DK, DC, L, N), FirstUsingShadow(nullptr, false) {}
private:
void anchor() override;
@@ -3476,6 +3603,7 @@ class ConstructorUsingShadowDecl final : public UsingShadowDecl {
/// \c true if the constructor ultimately named by this using shadow
/// declaration is within a virtual base class subobject of the class that
/// contains this declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsVirtual : 1;
ConstructorUsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
@@ -3578,17 +3706,15 @@ public:
class UsingEnumDecl : public BaseUsingDecl, public Mergeable<UsingEnumDecl> {
/// The source location of the 'using' keyword itself.
SourceLocation UsingLocation;
-
- /// Location of the 'enum' keyword.
+ /// The source location of the 'enum' keyword.
SourceLocation EnumLocation;
-
- /// The enum
- EnumDecl *Enum;
+ /// 'qual::SomeEnum' as an EnumType, possibly with Elaborated/Typedef sugar.
+ TypeSourceInfo *EnumType;
UsingEnumDecl(DeclContext *DC, DeclarationName DN, SourceLocation UL,
- SourceLocation EL, SourceLocation NL, EnumDecl *ED)
- : BaseUsingDecl(UsingEnum, DC, NL, DN), UsingLocation(UL),
- EnumLocation(EL), Enum(ED) {}
+ SourceLocation EL, SourceLocation NL, TypeSourceInfo *EnumType)
+ : BaseUsingDecl(UsingEnum, DC, NL, DN), UsingLocation(UL), EnumLocation(EL),
+ EnumType(EnumType){}
void anchor() override;
@@ -3603,13 +3729,29 @@ public:
/// The source location of the 'enum' keyword.
SourceLocation getEnumLoc() const { return EnumLocation; }
void setEnumLoc(SourceLocation L) { EnumLocation = L; }
+ NestedNameSpecifier *getQualifier() const {
+ return getQualifierLoc().getNestedNameSpecifier();
+ }
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ if (auto ETL = EnumType->getTypeLoc().getAs<ElaboratedTypeLoc>())
+ return ETL.getQualifierLoc();
+ return NestedNameSpecifierLoc();
+ }
+ // Returns the "qualifier::Name" part as a TypeLoc.
+ TypeLoc getEnumTypeLoc() const {
+ return EnumType->getTypeLoc();
+ }
+ TypeSourceInfo *getEnumType() const {
+ return EnumType;
+ }
+ void setEnumType(TypeSourceInfo *TSI) { EnumType = TSI; }
public:
- EnumDecl *getEnumDecl() const { return Enum; }
+ EnumDecl *getEnumDecl() const { return cast<EnumDecl>(EnumType->getType()->getAsTagDecl()); }
static UsingEnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation UsingL, SourceLocation EnumL,
- SourceLocation NameL, EnumDecl *ED);
+ SourceLocation NameL, TypeSourceInfo *EnumType);
static UsingEnumDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -3677,7 +3819,7 @@ public:
/// Get the set of using declarations that this pack expanded into. Note that
/// some of these may still be unresolved.
ArrayRef<NamedDecl *> expansions() const {
- return llvm::makeArrayRef(getTrailingObjects<NamedDecl *>(), NumExpansions);
+ return llvm::ArrayRef(getTrailingObjects<NamedDecl *>(), NumExpansions);
}
static UsingPackDecl *Create(ASTContext &C, DeclContext *DC,
@@ -3908,12 +4050,12 @@ public:
/// Represents a C++11 static_assert declaration.
class StaticAssertDecl : public Decl {
llvm::PointerIntPair<Expr *, 1, bool> AssertExprAndFailed;
- StringLiteral *Message;
+ Expr *Message;
SourceLocation RParenLoc;
StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc,
- Expr *AssertExpr, StringLiteral *Message,
- SourceLocation RParenLoc, bool Failed)
+ Expr *AssertExpr, Expr *Message, SourceLocation RParenLoc,
+ bool Failed)
: Decl(StaticAssert, DC, StaticAssertLoc),
AssertExprAndFailed(AssertExpr, Failed), Message(Message),
RParenLoc(RParenLoc) {}
@@ -3925,15 +4067,15 @@ public:
static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StaticAssertLoc,
- Expr *AssertExpr, StringLiteral *Message,
+ Expr *AssertExpr, Expr *Message,
SourceLocation RParenLoc, bool Failed);
static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID);
Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); }
const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); }
- StringLiteral *getMessage() { return Message; }
- const StringLiteral *getMessage() const { return Message; }
+ Expr *getMessage() { return Message; }
+ const Expr *getMessage() const { return Message; }
bool isFailed() const { return AssertExprAndFailed.getInt(); }
@@ -4047,10 +4189,10 @@ public:
unsigned NumBindings);
ArrayRef<BindingDecl *> bindings() const {
- return llvm::makeArrayRef(getTrailingObjects<BindingDecl *>(), NumBindings);
+ return llvm::ArrayRef(getTrailingObjects<BindingDecl *>(), NumBindings);
}
- void printName(raw_ostream &os) const override;
+ void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decomposition; }
@@ -4163,7 +4305,8 @@ private:
public:
/// Print this UUID in a human-readable format.
- void printName(llvm::raw_ostream &OS) const override;
+ void printName(llvm::raw_ostream &OS,
+ const PrintingPolicy &Policy) const override;
/// Get the decomposed parts of this declaration.
Parts getParts() const { return PartVal; }
@@ -4185,6 +4328,55 @@ public:
static bool classofKind(Kind K) { return K == Decl::MSGuid; }
};
+/// An artificial decl, representing a global anonymous constant value which is
+/// uniquified by value within a translation unit.
+///
+/// These is currently only used to back the LValue returned by
+/// __builtin_source_location, but could potentially be used for other similar
+/// situations in the future.
+class UnnamedGlobalConstantDecl : public ValueDecl,
+ public Mergeable<UnnamedGlobalConstantDecl>,
+ public llvm::FoldingSetNode {
+
+ // The constant value of this global.
+ APValue Value;
+
+ void anchor() override;
+
+ UnnamedGlobalConstantDecl(const ASTContext &C, DeclContext *DC, QualType T,
+ const APValue &Val);
+
+ static UnnamedGlobalConstantDecl *Create(const ASTContext &C, QualType T,
+ const APValue &APVal);
+ static UnnamedGlobalConstantDecl *CreateDeserialized(ASTContext &C,
+ unsigned ID);
+
+ // Only ASTContext::getUnnamedGlobalConstantDecl and deserialization create
+ // these.
+ friend class ASTContext;
+ friend class ASTReader;
+ friend class ASTDeclReader;
+
+public:
+ /// Print this in a human-readable format.
+ void printName(llvm::raw_ostream &OS,
+ const PrintingPolicy &Policy) const override;
+
+ const APValue &getValue() const { return Value; }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Ty,
+ const APValue &APVal) {
+ Ty.Profile(ID);
+ APVal.Profile(ID);
+ }
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getType(), getValue());
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == Decl::UnnamedGlobalConstant; }
+};
+
/// Insertion operator for diagnostics. This allows sending an AccessSpecifier
/// into a diagnostic with <<.
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h b/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h
index 2eef2343b750..903cdb7bfcc8 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h
@@ -78,8 +78,7 @@ class StoredDeclsList {
}
Data.setPointer(NewHead);
- assert(llvm::find_if(getLookupResult(), ShouldErase) ==
- getLookupResult().end() && "Still exists!");
+ assert(llvm::none_of(getLookupResult(), ShouldErase) && "Still exists!");
}
void erase(NamedDecl *ND) {
@@ -91,7 +90,7 @@ public:
StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
RHS.Data.setPointer(nullptr);
- RHS.Data.setInt(0);
+ RHS.Data.setInt(false);
}
void MaybeDeallocList() {
@@ -115,7 +114,7 @@ public:
Data = RHS.Data;
RHS.Data.setPointer(nullptr);
- RHS.Data.setInt(0);
+ RHS.Data.setInt(false);
return *this;
}
@@ -143,7 +142,7 @@ public:
}
void setHasExternalDecls() {
- Data.setInt(1);
+ Data.setInt(true);
}
void remove(NamedDecl *D) {
@@ -156,7 +155,7 @@ public:
erase_if([](NamedDecl *ND) { return ND->isFromASTFile(); });
// Don't have any pending external decls any more.
- Data.setInt(0);
+ Data.setInt(false);
}
void replaceExternalDecls(ArrayRef<NamedDecl*> Decls) {
@@ -172,7 +171,7 @@ public:
});
// Don't have any pending external decls any more.
- Data.setInt(0);
+ Data.setInt(false);
if (Decls.empty())
return;
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h b/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h
index 6f8306c6025e..3e6ca5b32192 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h
@@ -23,7 +23,6 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
@@ -74,6 +73,7 @@ private:
/// True if this 'friend' declaration is unsupported. Eventually we
/// will support every possible friend declaration, but for now we
/// silently ignore some and set this flag to authorize all access.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UnsupportedFriend : 1;
// The number of "outer" template parameter lists in non-templatic
@@ -108,11 +108,10 @@ public:
friend class ASTNodeImporter;
friend TrailingObjects;
- static FriendDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, FriendUnion Friend_,
- SourceLocation FriendL,
- ArrayRef<TemplateParameterList*> FriendTypeTPLists
- = None);
+ static FriendDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_,
+ SourceLocation FriendL,
+ ArrayRef<TemplateParameterList *> FriendTypeTPLists = std::nullopt);
static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned FriendTypeNumTPLists);
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h b/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h
index 6bb9cdf67034..f8f894b4b10d 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h
@@ -25,9 +25,8 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/None.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -116,6 +115,8 @@ public:
const SourceLocation *Locs, ASTContext &Ctx);
};
+enum class ObjCImplementationControl { None, Required, Optional };
+
/// ObjCMethodDecl - Represents an instance or class method declaration.
/// ObjC methods can be declared within 4 contexts: class interfaces,
/// categories, protocols, and class implementations. While C++ member
@@ -140,10 +141,6 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
// This class stores some data in DeclContext::ObjCMethodDeclBits
// to save some space. Use the provided accessors to access it.
-public:
- enum ImplementationControl { None, Required, Optional };
-
-private:
/// Return type of this method.
QualType MethodDeclType;
@@ -169,14 +166,14 @@ private:
/// constructed by createImplicitParams.
ImplicitParamDecl *CmdDecl = nullptr;
- ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
- DeclContext *contextDecl, bool isInstance = true,
- bool isVariadic = false, bool isPropertyAccessor = false,
- bool isSynthesizedAccessorStub = false,
- bool isImplicitlyDeclared = false, bool isDefined = false,
- ImplementationControl impControl = None,
- bool HasRelatedResultType = false);
+ ObjCMethodDecl(
+ SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo,
+ QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl,
+ bool isInstance = true, bool isVariadic = false,
+ bool isPropertyAccessor = false, bool isSynthesizedAccessorStub = false,
+ bool isImplicitlyDeclared = false, bool isDefined = false,
+ ObjCImplementationControl impControl = ObjCImplementationControl::None,
+ bool HasRelatedResultType = false);
SelectorLocationsKind getSelLocsKind() const {
return static_cast<SelectorLocationsKind>(ObjCMethodDeclBits.SelLocsKind);
@@ -236,7 +233,7 @@ public:
bool isVariadic = false, bool isPropertyAccessor = false,
bool isSynthesizedAccessorStub = false,
bool isImplicitlyDeclared = false, bool isDefined = false,
- ImplementationControl impControl = None,
+ ObjCImplementationControl impControl = ObjCImplementationControl::None,
bool HasRelatedResultType = false);
static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -374,8 +371,7 @@ public:
// ArrayRef access to formal parameters. This should eventually
// replace the iterator interface above.
ArrayRef<ParmVarDecl*> parameters() const {
- return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
- NumParams);
+ return llvm::ArrayRef(const_cast<ParmVarDecl **>(getParams()), NumParams);
}
ParmVarDecl *getParamDecl(unsigned Idx) {
@@ -389,9 +385,8 @@ public:
/// Sets the method's parameters and selector source locations.
/// If the method is implicit (not coming from source) \p SelLocs is
/// ignored.
- void setMethodParams(ASTContext &C,
- ArrayRef<ParmVarDecl*> Params,
- ArrayRef<SourceLocation> SelLocs = llvm::None);
+ void setMethodParams(ASTContext &C, ArrayRef<ParmVarDecl *> Params,
+ ArrayRef<SourceLocation> SelLocs = std::nullopt);
// Iterator access to parameter types.
struct GetTypeFn {
@@ -487,6 +482,9 @@ public:
/// True if the method is tagged as objc_direct
bool isDirectMethod() const;
+ /// True if the method has a parameter that's destroyed in the callee.
+ bool hasParamDestroyedInCallee() const;
+
/// Returns the property associated with this method's selector.
///
/// Note that even if this particular method is not marked as a property
@@ -495,16 +493,17 @@ public:
const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
// Related to protocols declared in \@protocol
- void setDeclImplementation(ImplementationControl ic) {
- ObjCMethodDeclBits.DeclImplementation = ic;
+ void setDeclImplementation(ObjCImplementationControl ic) {
+ ObjCMethodDeclBits.DeclImplementation = llvm::to_underlying(ic);
}
- ImplementationControl getImplementationControl() const {
- return ImplementationControl(ObjCMethodDeclBits.DeclImplementation);
+ ObjCImplementationControl getImplementationControl() const {
+ return static_cast<ObjCImplementationControl>(
+ ObjCMethodDeclBits.DeclImplementation);
}
bool isOptional() const {
- return getImplementationControl() == Optional;
+ return getImplementationControl() == ObjCImplementationControl::Optional;
}
/// Returns true if this specific method declaration is marked with the
@@ -581,6 +580,7 @@ class ObjCTypeParamDecl : public TypedefNameDecl {
unsigned Index : 14;
/// The variance of the type parameter.
+ LLVM_PREFERRED_TYPE(ObjCTypeParamVariance)
unsigned Variance : 2;
/// The location of the variance, if any.
@@ -742,10 +742,13 @@ private:
QualType DeclType;
TypeSourceInfo *DeclTypeSourceInfo;
+ LLVM_PREFERRED_TYPE(ObjCPropertyAttribute::Kind)
unsigned PropertyAttributes : NumObjCPropertyAttrsBits;
+ LLVM_PREFERRED_TYPE(ObjCPropertyAttribute::Kind)
unsigned PropertyAttributesAsWritten : NumObjCPropertyAttrsBits;
// \@required/\@optional
+ LLVM_PREFERRED_TYPE(PropertyControl)
unsigned PropertyImplementation : 2;
// getter name of NULL if no getter
@@ -776,17 +779,13 @@ private:
LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
PropertyAttributes(ObjCPropertyAttribute::kind_noattr),
PropertyAttributesAsWritten(ObjCPropertyAttribute::kind_noattr),
- PropertyImplementation(propControl), GetterName(Selector()),
- SetterName(Selector()) {}
+ PropertyImplementation(propControl) {}
public:
- static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- IdentifierInfo *Id, SourceLocation AtLocation,
- SourceLocation LParenLocation,
- QualType T,
- TypeSourceInfo *TSI,
- PropertyControl propControl = None);
+ static ObjCPropertyDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+ SourceLocation AtLocation, SourceLocation LParenLocation, QualType T,
+ TypeSourceInfo *TSI, PropertyControl propControl = None);
static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -1072,21 +1071,23 @@ public:
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
+ ObjCPropertyDecl *getProperty(const IdentifierInfo *Id,
+ bool IsInstance) const;
+
ObjCPropertyDecl *
FindPropertyDeclaration(const IdentifierInfo *PropertyId,
ObjCPropertyQueryKind QueryKind) const;
using PropertyMap =
- llvm::DenseMap<std::pair<IdentifierInfo *, unsigned/*isClassProperty*/>,
- ObjCPropertyDecl *>;
+ llvm::MapVector<std::pair<IdentifierInfo *, unsigned /*isClassProperty*/>,
+ ObjCPropertyDecl *>;
using ProtocolPropertySet = llvm::SmallDenseSet<const ObjCProtocolDecl *, 8>;
using PropertyDeclOrder = llvm::SmallVector<ObjCPropertyDecl *, 8>;
/// This routine collects list of properties to be implemented in the class.
/// This includes, class's and its conforming protocols' properties.
/// Note, the superclass's properties are not included in the list.
- virtual void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const {}
+ virtual void collectPropertiesToImplement(PropertyMap &PM) const {}
SourceLocation getAtStartLoc() const { return ObjCContainerDeclBits.AtStart; }
@@ -1148,6 +1149,7 @@ public:
class ObjCInterfaceDecl : public ObjCContainerDecl
, public Redeclarable<ObjCInterfaceDecl> {
friend class ASTContext;
+ friend class ODRDiagsEmitter;
/// TypeForDecl - This indicates the Type object that represents this
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
@@ -1180,14 +1182,17 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// Indicates that the contents of this Objective-C class will be
/// completed by the external AST source when required.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned ExternallyCompleted : 1;
/// Indicates that the ivar cache does not yet include ivars
/// declared in the implementation.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IvarListMissingImplementation : 1;
/// Indicates that this interface decl contains at least one initializer
/// marked with the 'objc_designated_initializer' attribute.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasDesignatedInitializers : 1;
enum InheritedDesignatedInitializersState {
@@ -1203,8 +1208,16 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
};
/// One of the \c InheritedDesignatedInitializersState enumeratos.
+ LLVM_PREFERRED_TYPE(InheritedDesignatedInitializersState)
mutable unsigned InheritedDesignatedInitializers : 2;
+ /// Tracks whether a ODR hash has been computed for this interface.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasODRHash : 1;
+
+ /// A hash of parts of the class to help in ODR checking.
+ unsigned ODRHash = 0;
+
/// The location of the last location in this declaration, before
/// the properties/methods. For example, this will be the '>', '}', or
/// identifier,
@@ -1213,7 +1226,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
DefinitionData()
: ExternallyCompleted(false), IvarListMissingImplementation(true),
HasDesignatedInitializers(false),
- InheritedDesignatedInitializers(IDI_Unknown) {}
+ InheritedDesignatedInitializers(IDI_Unknown), HasODRHash(false) {}
};
/// The type parameters associated with this class, if any.
@@ -1537,6 +1550,13 @@ public:
/// a forward declaration (\@class) to a definition (\@interface).
void startDefinition();
+ /// Starts the definition without sharing it with other redeclarations.
+ /// Such definition shouldn't be used for anything but only to compare if
+ /// a duplicate is compatible with previous definition or if it is
+ /// a distinct duplicate.
+ void startDuplicateDefinitionForComparison();
+ void mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl *Definition);
+
/// Retrieve the superclass type.
const ObjCObjectType *getSuperClassType() const {
if (TypeSourceInfo *TInfo = getSuperClassTInfo())
@@ -1778,8 +1798,7 @@ public:
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId,
ObjCPropertyQueryKind QueryKind) const;
- void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const override;
+ void collectPropertiesToImplement(PropertyMap &PM) const override;
/// isSuperClassOf - Return true if this class is the specified class or is a
/// super class of the specified interface class.
@@ -1895,10 +1914,17 @@ public:
const Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
+ /// Get precomputed ODRHash or add a new one.
+ unsigned getODRHash();
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCInterface; }
private:
+ /// True if a valid hash is stored in ODRHash.
+ bool hasODRHash() const;
+ void setHasODRHash(bool HasHash);
+
const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
bool inheritsDesignatedInitializers() const;
};
@@ -1949,12 +1975,22 @@ public:
/// in; this is either the interface where the ivar was declared, or the
/// interface the ivar is conceptually a part of in the case of synthesized
/// ivars.
- const ObjCInterfaceDecl *getContainingInterface() const;
+ ObjCInterfaceDecl *getContainingInterface();
+ const ObjCInterfaceDecl *getContainingInterface() const {
+ return const_cast<ObjCIvarDecl *>(this)->getContainingInterface();
+ }
ObjCIvarDecl *getNextIvar() { return NextIvar; }
const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
+ ObjCIvarDecl *getCanonicalDecl() override {
+ return cast<ObjCIvarDecl>(FieldDecl::getCanonicalDecl());
+ }
+ const ObjCIvarDecl *getCanonicalDecl() const {
+ return const_cast<ObjCIvarDecl *>(this)->getCanonicalDecl();
+ }
+
void setAccessControl(AccessControl ac) { DeclAccess = ac; }
AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
@@ -1980,7 +2016,9 @@ private:
ObjCIvarDecl *NextIvar = nullptr;
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
+ LLVM_PREFERRED_TYPE(AccessControl)
unsigned DeclAccess : 3;
+ LLVM_PREFERRED_TYPE(bool)
unsigned Synthesized : 1;
};
@@ -2045,6 +2083,13 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
/// Referenced protocols
ObjCProtocolList ReferencedProtocols;
+
+ /// Tracks whether a ODR hash has been computed for this protocol.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasODRHash : 1;
+
+ /// A hash of parts of the class to help in ODR checking.
+ unsigned ODRHash = 0;
};
/// Contains a pointer to the data associated with this class,
@@ -2081,10 +2126,15 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
return getMostRecentDecl();
}
+ /// True if a valid hash is stored in ODRHash.
+ bool hasODRHash() const;
+ void setHasODRHash(bool HasHash);
+
public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
friend class ASTReader;
+ friend class ODRDiagsEmitter;
static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
@@ -2209,6 +2259,13 @@ public:
/// Starts the definition of this Objective-C protocol.
void startDefinition();
+ /// Starts the definition without sharing it with other redeclarations.
+ /// Such definition shouldn't be used for anything but only to compare if
+ /// a duplicate is compatible with previous definition or if it is
+ /// a distinct duplicate.
+ void startDuplicateDefinitionForComparison();
+ void mergeDuplicateDefinitionWithCommon(const ObjCProtocolDecl *Definition);
+
/// Produce a name to be used for protocol's metadata. It comes either via
/// objc_runtime_name attribute or protocol name.
StringRef getObjCRuntimeNameAsString() const;
@@ -2234,13 +2291,15 @@ public:
ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
- void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const override;
+ void collectPropertiesToImplement(PropertyMap &PM) const override;
void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
ProtocolPropertySet &PS,
PropertyDeclOrder &PO) const;
+ /// Get precomputed ODRHash or add a new one.
+ unsigned getODRHash();
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCProtocol; }
};
@@ -2549,9 +2608,11 @@ class ObjCImplementationDecl : public ObjCImplDecl {
/// Do the ivars of this class require initialization other than
/// zero-initialization?
+ LLVM_PREFERRED_TYPE(bool)
bool HasNonZeroConstructors : 1;
/// Do the ivars of this class require non-trivial destruction?
+ LLVM_PREFERRED_TYPE(bool)
bool HasDestructors : 1;
ObjCImplementationDecl(DeclContext *DC,
@@ -2876,15 +2937,16 @@ ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() {
}
inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
- return Cat->isUnconditionallyVisible();
+ return !Cat->isInvalidDecl() && Cat->isUnconditionallyVisible();
}
inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension() && Cat->isUnconditionallyVisible();
+ return !Cat->isInvalidDecl() && Cat->IsClassExtension() &&
+ Cat->isUnconditionallyVisible();
}
inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension();
+ return !Cat->isInvalidDecl() && Cat->IsClassExtension();
}
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h b/contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h
index 5f03bce6e9a8..42c97204a613 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_DECLOBJC_COMMON_H
-#define LLVM_CLANG_AST_DECLOBJC_COMMON_H
+#ifndef LLVM_CLANG_AST_DECLOBJCCOMMON_H
+#define LLVM_CLANG_AST_DECLOBJCCOMMON_H
namespace clang {
@@ -52,4 +52,4 @@ enum {
} // namespace clang
-#endif // LLVM_CLANG_AST_DECLOBJC_COMMON_H
+#endif // LLVM_CLANG_AST_DECLOBJCCOMMON_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h b/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h
index 4aa5bde92e12..73725e6e8566 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h
@@ -34,7 +34,7 @@ template <typename U> class OMPDeclarativeDirective : public U {
/// Get the clauses storage.
MutableArrayRef<OMPClause *> getClauses() {
if (!Data)
- return llvm::None;
+ return std::nullopt;
return Data->getClauses();
}
@@ -90,7 +90,7 @@ public:
ArrayRef<OMPClause *> clauses() const {
if (!Data)
- return llvm::None;
+ return std::nullopt;
return Data->getClauses();
}
};
@@ -118,12 +118,12 @@ class OMPThreadPrivateDecl final : public OMPDeclarativeDirective<Decl> {
ArrayRef<const Expr *> getVars() const {
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
- return llvm::makeArrayRef(Storage, Data->getNumChildren());
+ return llvm::ArrayRef(Storage, Data->getNumChildren());
}
MutableArrayRef<Expr *> getVars() {
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
- return llvm::makeMutableArrayRef(Storage, Data->getNumChildren());
+ return llvm::MutableArrayRef(Storage, Data->getNumChildren());
}
void setVars(ArrayRef<Expr *> VL);
@@ -158,6 +158,12 @@ public:
static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
};
+enum class OMPDeclareReductionInitKind {
+ Call, // Initialized by function call.
+ Direct, // omp_priv(<expr>)
+ Copy // omp_priv = <expr>
+};
+
/// This represents '#pragma omp declare reduction ...' directive.
/// For example, in the following, declared reduction 'foo' for types 'int' and
/// 'float':
@@ -171,14 +177,7 @@ public:
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
// This class stores some data in DeclContext::OMPDeclareReductionDeclBits
// to save some space. Use the provided accessors to access it.
-public:
- enum InitKind {
- CallInit, // Initialized by function call.
- DirectInit, // omp_priv(<expr>)
- CopyInit // omp_priv = <expr>
- };
-private:
friend class ASTDeclReader;
/// Combiner for declare reduction construct.
Expr *Combiner = nullptr;
@@ -239,8 +238,9 @@ public:
Expr *getInitializer() { return Initializer; }
const Expr *getInitializer() const { return Initializer; }
/// Get initializer kind.
- InitKind getInitializerKind() const {
- return static_cast<InitKind>(OMPDeclareReductionDeclBits.InitializerKind);
+ OMPDeclareReductionInitKind getInitializerKind() const {
+ return static_cast<OMPDeclareReductionInitKind>(
+ OMPDeclareReductionDeclBits.InitializerKind);
}
/// Get Orig variable of the initializer.
Expr *getInitOrig() { return Orig; }
@@ -249,9 +249,9 @@ public:
Expr *getInitPriv() { return Priv; }
const Expr *getInitPriv() const { return Priv; }
/// Set initializer expression for the declare reduction construct.
- void setInitializer(Expr *E, InitKind IK) {
+ void setInitializer(Expr *E, OMPDeclareReductionInitKind IK) {
Initializer = E;
- OMPDeclareReductionDeclBits.InitializerKind = IK;
+ OMPDeclareReductionDeclBits.InitializerKind = llvm::to_underlying(IK);
}
/// Set initializer Orig and Priv vars.
void setInitializerData(Expr *OrigE, Expr *PrivE) {
@@ -481,12 +481,12 @@ class OMPAllocateDecl final : public OMPDeclarativeDirective<Decl> {
ArrayRef<const Expr *> getVars() const {
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
- return llvm::makeArrayRef(Storage, Data->getNumChildren());
+ return llvm::ArrayRef(Storage, Data->getNumChildren());
}
MutableArrayRef<Expr *> getVars() {
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
- return llvm::makeMutableArrayRef(Storage, Data->getNumChildren());
+ return llvm::MutableArrayRef(Storage, Data->getNumChildren());
}
void setVars(ArrayRef<Expr *> VL);
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h
index cbaa287f225a..832ad2de6b08 100755
--- a/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_DECLTEMPLATE_H
#include "clang/AST/ASTConcept.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
@@ -38,6 +39,7 @@
#include <cstddef>
#include <cstdint>
#include <iterator>
+#include <optional>
#include <utility>
namespace clang {
@@ -81,13 +83,16 @@ class TemplateParameterList final
/// Whether this template parameter list contains an unexpanded parameter
/// pack.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ContainsUnexpandedParameterPack : 1;
/// Whether this template parameter list has a requires clause.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasRequiresClause : 1;
/// Whether any of the template parameters has constrained-parameter
/// constraint-expression.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasConstrainedParameters : 1;
protected:
@@ -115,6 +120,8 @@ public:
SourceLocation RAngleLoc,
Expr *RequiresClause);
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
+
/// Iterates through the template parameters in this list.
using iterator = NamedDecl **;
@@ -128,11 +135,9 @@ public:
unsigned size() const { return NumParams; }
- ArrayRef<NamedDecl*> asArray() {
- return llvm::makeArrayRef(begin(), end());
- }
+ ArrayRef<NamedDecl *> asArray() { return llvm::ArrayRef(begin(), end()); }
ArrayRef<const NamedDecl*> asArray() const {
- return llvm::makeArrayRef(begin(), size());
+ return llvm::ArrayRef(begin(), size());
}
NamedDecl* getParam(unsigned Idx) {
@@ -203,7 +208,8 @@ public:
void print(raw_ostream &Out, const ASTContext &Context,
const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
- static bool shouldIncludeTypeForArgument(const TemplateParameterList *TPL,
+ static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy,
+ const TemplateParameterList *TPL,
unsigned Idx);
};
@@ -272,8 +278,7 @@ public:
///
/// This operation assumes that the input argument list outlives it.
/// This takes the list as a pointer to avoid looking like a copy
- /// constructor, since this really really isn't safe to use that
- /// way.
+ /// constructor, since this really isn't safe to use that way.
explicit TemplateArgumentList(const TemplateArgumentList *Other)
: Arguments(Other->data()), NumArguments(Other->size()) {}
@@ -288,7 +293,7 @@ public:
/// Produce this as an array ref.
ArrayRef<TemplateArgument> asArray() const {
- return llvm::makeArrayRef(data(), size());
+ return llvm::ArrayRef(data(), size());
}
/// Retrieve the number of template arguments in this
@@ -372,11 +377,20 @@ public:
/// Set that the default argument was inherited from another parameter.
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
- assert(!isInherited() && "default argument already inherited");
InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
if (!isSet())
ValueOrInherited = InheritedFrom;
- else
+ else if ([[maybe_unused]] auto *D =
+ ValueOrInherited.template dyn_cast<ParmDecl *>()) {
+ assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
+ ValueOrInherited =
+ new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
+ } else if (auto *Inherited =
+ ValueOrInherited.template dyn_cast<Chain *>()) {
+ assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
+ InheritedFrom));
+ Inherited->PrevDeclWithDefaultArg = InheritedFrom;
+ } else
ValueOrInherited = new (allocateDefaultArgStorageChain(C))
Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
}
@@ -430,6 +444,9 @@ public:
/// Get the underlying, templated declaration.
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
+ // Should a specialization behave like an alias for another type.
+ bool isTypeAlias() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -446,18 +463,17 @@ protected:
NamedDecl *TemplatedDecl;
TemplateParameterList *TemplateParams;
+public:
void setTemplateParameters(TemplateParameterList *TParams) {
TemplateParams = TParams;
}
-public:
- /// Initialize the underlying templated declaration and
- /// template parameters.
- void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
- assert(!TemplatedDecl && "TemplatedDecl already set!");
- assert(!TemplateParams && "TemplateParams already set!");
- TemplatedDecl = templatedDecl;
- TemplateParams = templateParams;
+ /// Initialize the underlying templated declaration.
+ void init(NamedDecl *NewTemplatedDecl) {
+ if (TemplatedDecl)
+ assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
+ else
+ TemplatedDecl = NewTemplatedDecl;
}
};
@@ -497,7 +513,7 @@ private:
TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
SourceLocation POI, MemberSpecializationInfo *MSInfo)
- : Function(FD, MSInfo ? 1 : 0), Template(Template, TSK - 1),
+ : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
TemplateArguments(TemplateArgs),
TemplateArgumentsAsWritten(TemplateArgsAsWritten),
PointOfInstantiation(POI) {
@@ -570,7 +586,7 @@ public:
/// \code
/// template<typename> struct A {
/// template<typename> void f();
- /// template<> void f<int>(); // ClassScopeFunctionSpecializationDecl
+ /// template<> void f<int>();
/// };
/// \endcode
///
@@ -606,7 +622,7 @@ public:
static void
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
+ const ASTContext &Context) {
ID.AddInteger(TemplateArgs.size());
for (const TemplateArgument &TemplateArg : TemplateArgs)
TemplateArg.Profile(ID, Context);
@@ -669,78 +685,48 @@ public:
/// Provides information about a dependent function-template
/// specialization declaration.
///
-/// Since explicit function template specialization and instantiation
-/// declarations can only appear in namespace scope, and you can only
-/// specialize a member of a fully-specialized class, the only way to
-/// get one of these is in a friend declaration like the following:
+/// This is used for function templates explicit specializations declared
+/// within class templates:
+///
+/// \code
+/// template<typename> struct A {
+/// template<typename> void f();
+/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
+/// };
+/// \endcode
+///
+/// As well as dependent friend declarations naming function template
+/// specializations declared within class templates:
///
/// \code
/// template \<class T> void foo(T);
/// template \<class T> class A {
-/// friend void foo<>(T);
+/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
/// };
/// \endcode
class DependentFunctionTemplateSpecializationInfo final
: private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
- TemplateArgumentLoc,
FunctionTemplateDecl *> {
- /// The number of potential template candidates.
- unsigned NumTemplates;
-
- /// The number of template arguments.
- unsigned NumArgs;
-
- /// The locations of the left and right angle brackets.
- SourceRange AngleLocs;
+ friend TrailingObjects;
- size_t numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
- return NumArgs;
- }
- size_t numTrailingObjects(OverloadToken<FunctionTemplateDecl *>) const {
- return NumTemplates;
- }
+ /// The number of candidates for the primary template.
+ unsigned NumCandidates;
DependentFunctionTemplateSpecializationInfo(
- const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
+ const UnresolvedSetImpl &Candidates,
+ const ASTTemplateArgumentListInfo *TemplateArgsWritten);
public:
- friend TrailingObjects;
+ /// The template arguments as written in the sources, if provided.
+ const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
static DependentFunctionTemplateSpecializationInfo *
- Create(ASTContext &Context, const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
+ Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
+ const TemplateArgumentListInfo *TemplateArgs);
- /// Returns the number of function templates that this might
- /// be a specialization of.
- unsigned getNumTemplates() const { return NumTemplates; }
-
- /// Returns the i'th template candidate.
- FunctionTemplateDecl *getTemplate(unsigned I) const {
- assert(I < getNumTemplates() && "template index out of range");
- return getTrailingObjects<FunctionTemplateDecl *>()[I];
- }
-
- /// Returns the explicit template arguments that were given.
- const TemplateArgumentLoc *getTemplateArgs() const {
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// Returns the number of explicit template arguments that were given.
- unsigned getNumTemplateArgs() const { return NumArgs; }
-
- /// Returns the nth template argument.
- const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
- assert(I < getNumTemplateArgs() && "template arg index out of range");
- return getTemplateArgs()[I];
- }
-
- SourceLocation getLAngleLoc() const {
- return AngleLocs.getBegin();
- }
-
- SourceLocation getRAngleLoc() const {
- return AngleLocs.getEnd();
+ /// Returns the candidates for the primary function template.
+ ArrayRef<FunctionTemplateDecl *> getCandidates() const {
+ return {getTrailingObjects<FunctionTemplateDecl *>(), NumCandidates};
}
};
@@ -831,6 +817,15 @@ protected:
/// The first value in the array is the number of specializations/partial
/// specializations that follow.
uint32_t *LazySpecializations = nullptr;
+
+ /// The set of "injected" template arguments used within this
+ /// template.
+ ///
+ /// This pointer refers to the template arguments (there are as
+ /// many template arguments as template parameters) for the
+ /// template, and is allocated lazily, since most templates do not
+ /// require the use of this information.
+ TemplateArgument *InjectedArgs = nullptr;
};
/// Pointer to the common data shared by all declarations of this
@@ -938,6 +933,14 @@ public:
getCommonPtr()->InstantiatedFromMember.setPointer(TD);
}
+ /// Retrieve the "injected" template arguments that correspond to the
+ /// template parameters of this template.
+ ///
+ /// Although the C++ standard has no notion of the "injected" template
+ /// arguments for a template, the notion is convenient when
+ /// we need to perform substitutions inside the definition of a template.
+ ArrayRef<TemplateArgument> getInjectedTemplateArgs();
+
using redecl_range = redeclarable_base::redecl_range;
using redecl_iterator = redeclarable_base::redecl_iterator;
@@ -982,15 +985,6 @@ protected:
/// template, including explicit specializations and instantiations.
llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
- /// The set of "injected" template arguments used within this
- /// function template.
- ///
- /// This pointer refers to the template arguments (there are as
- /// many template arguments as template parameaters) for the function
- /// template, and is allocated lazily, since most function templates do not
- /// require the use of this information.
- TemplateArgument *InjectedArgs = nullptr;
-
Common() = default;
};
@@ -1090,21 +1084,12 @@ public:
return makeSpecIterator(getSpecializations(), true);
}
- /// Retrieve the "injected" template arguments that correspond to the
- /// template parameters of this function template.
- ///
- /// Although the C++ standard has no notion of the "injected" template
- /// arguments for a function template, the notion is convenient when
- /// we need to perform substitutions inside the definition of a function
- /// template.
- ArrayRef<TemplateArgument> getInjectedTemplateArgs();
-
/// Return whether this function template is an abbreviated function template,
/// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
bool isAbbreviated() const {
// Since the invented template parameters generated from 'auto' parameters
// are either appended to the end of the explicit template parameter list or
- // form a new template paramter list, we can simply observe the last
+ // form a new template parameter list, we can simply observe the last
// parameter to determine if such a thing happened.
const TemplateParameterList *TPL = getTemplateParameters();
return TPL->getParam(TPL->size() - 1)->isImplicit();
@@ -1143,23 +1128,40 @@ public:
/// parameters and is not part of the Decl hierarchy. Just a facility.
class TemplateParmPosition {
protected:
- // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
- // position? Maybe?
- unsigned Depth;
- unsigned Position;
+ enum { DepthWidth = 20, PositionWidth = 12 };
+ unsigned Depth : DepthWidth;
+ unsigned Position : PositionWidth;
- TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {}
+ static constexpr unsigned MaxDepth = (1U << DepthWidth) - 1;
+ static constexpr unsigned MaxPosition = (1U << PositionWidth) - 1;
+
+ TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {
+ // The input may fill maximum values to show that it is invalid.
+ // Add one here to convert it to zero.
+ assert((D + 1) <= MaxDepth &&
+ "The depth of template parmeter position is more than 2^20!");
+ assert((P + 1) <= MaxPosition &&
+ "The position of template parmeter position is more than 2^12!");
+ }
public:
TemplateParmPosition() = delete;
/// Get the nesting depth of the template parameter.
unsigned getDepth() const { return Depth; }
- void setDepth(unsigned D) { Depth = D; }
+ void setDepth(unsigned D) {
+ assert((D + 1) <= MaxDepth &&
+ "The depth of template parmeter position is more than 2^20!");
+ Depth = D;
+ }
/// Get the position of the template parameter within its parameter list.
unsigned getPosition() const { return Position; }
- void setPosition(unsigned P) { Position = P; }
+ void setPosition(unsigned P) {
+ assert((P + 1) <= MaxPosition &&
+ "The position of template parmeter position is more than 2^12!");
+ Position = P;
+ }
/// Get the index of the template parameter within its parameter list.
unsigned getIndex() const { return Position; }
@@ -1189,10 +1191,10 @@ class TemplateTypeParmDecl final : public TypeDecl,
/// Whether the type constraint has been initialized. This can be false if the
/// constraint was not initialized yet or if there was an error forming the
- /// type constriant.
+ /// type constraint.
bool TypeConstraintInitialized : 1;
- /// Whether this non-type template parameter is an "expanded"
+ /// Whether this type template parameter is an "expanded"
/// parameter pack, meaning that its type is a pack expansion and we
/// already know the set of types that expansion expands to.
bool ExpandedParameterPack : 1;
@@ -1206,23 +1208,20 @@ class TemplateTypeParmDecl final : public TypeDecl,
DefArgStorage DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- bool Typename, bool HasTypeConstraint,
- Optional<unsigned> NumExpanded)
+ SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
+ bool HasTypeConstraint,
+ std::optional<unsigned> NumExpanded)
: TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
- HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
- ExpandedParameterPack(NumExpanded),
- NumExpanded(NumExpanded ? *NumExpanded : 0) {}
+ HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
+ ExpandedParameterPack(NumExpanded),
+ NumExpanded(NumExpanded.value_or(0)) {}
public:
- static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation KeyLoc,
- SourceLocation NameLoc,
- unsigned D, unsigned P,
- IdentifierInfo *Id, bool Typename,
- bool ParameterPack,
- bool HasTypeConstraint = false,
- Optional<unsigned> NumExpanded = None);
+ static TemplateTypeParmDecl *
+ Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
+ SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
+ bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
+ std::optional<unsigned> NumExpanded = std::nullopt);
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
unsigned ID);
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
@@ -1344,10 +1343,7 @@ public:
nullptr;
}
- void setTypeConstraint(NestedNameSpecifierLoc NNS,
- DeclarationNameInfo NameInfo, NamedDecl *FoundDecl,
- ConceptDecl *CD,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
+ void setTypeConstraint(ConceptReference *CR,
Expr *ImmediatelyDeclaredConstraint);
/// Determine whether this template parameter has a type-constraint.
@@ -1358,7 +1354,7 @@ public:
/// \brief Get the associated-constraints of this template parameter.
/// This will either be the immediately-introduced constraint or empty.
///
- /// Use this instead of getConstraintExpression for concepts APIs that
+ /// Use this instead of getTypeConstraint for concepts APIs that
/// accept an ArrayRef of constraint expressions.
void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
if (HasTypeConstraint)
@@ -1840,7 +1836,7 @@ class ClassTemplateSpecializationDecl
SourceLocation PointOfInstantiation;
/// The kind of specialization this declaration refers to.
- /// Really a value of type TemplateSpecializationKind.
+ LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
unsigned SpecializationKind : 3;
protected:
@@ -2054,7 +2050,7 @@ public:
static void
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
+ const ASTContext &Context) {
ID.AddInteger(TemplateArgs.size());
for (const TemplateArgument &TemplateArg : TemplateArgs)
TemplateArg.Profile(ID, Context);
@@ -2230,7 +2226,7 @@ public:
static void
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- TemplateParameterList *TPL, ASTContext &Context);
+ TemplateParameterList *TPL, const ASTContext &Context);
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2280,9 +2276,15 @@ protected:
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
}
+ void setCommonPtr(Common *C) {
+ RedeclarableTemplateDecl::Common = C;
+ }
+
public:
+
friend class ASTDeclReader;
friend class ASTDeclWriter;
+ friend class TemplateDeclInstantiator;
/// Load any lazily-loaded specializations from the external source.
void LoadLazySpecializations() const;
@@ -2457,10 +2459,10 @@ private:
SourceLocation FriendLoc;
FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
- MutableArrayRef<TemplateParameterList *> Params,
+ TemplateParameterList **Params, unsigned NumParams,
FriendUnion Friend, SourceLocation FriendLoc)
- : Decl(Decl::FriendTemplate, DC, Loc), NumParams(Params.size()),
- Params(Params.data()), Friend(Friend), FriendLoc(FriendLoc) {}
+ : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
+ Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
@@ -2580,70 +2582,6 @@ public:
static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
};
-/// Declaration of a function specialization at template class scope.
-///
-/// For example:
-/// \code
-/// template <class T>
-/// class A {
-/// template <class U> void foo(U a) { }
-/// template<> void foo(int a) { }
-/// }
-/// \endcode
-///
-/// "template<> foo(int a)" will be saved in Specialization as a normal
-/// CXXMethodDecl. Then during an instantiation of class A, it will be
-/// transformed into an actual function specialization.
-///
-/// FIXME: This is redundant; we could store the same information directly on
-/// the CXXMethodDecl as a DependentFunctionTemplateSpecializationInfo.
-class ClassScopeFunctionSpecializationDecl : public Decl {
- CXXMethodDecl *Specialization;
- const ASTTemplateArgumentListInfo *TemplateArgs;
-
- ClassScopeFunctionSpecializationDecl(
- DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD,
- const ASTTemplateArgumentListInfo *TemplArgs)
- : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
- Specialization(FD), TemplateArgs(TemplArgs) {}
-
- ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
- : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
-
- virtual void anchor();
-
-public:
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-
- CXXMethodDecl *getSpecialization() const { return Specialization; }
- bool hasExplicitTemplateArgs() const { return TemplateArgs; }
- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
- return TemplateArgs;
- }
-
- static ClassScopeFunctionSpecializationDecl *
- Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD,
- bool HasExplicitTemplateArgs,
- const TemplateArgumentListInfo &TemplateArgs) {
- return new (C, DC) ClassScopeFunctionSpecializationDecl(
- DC, Loc, FD,
- HasExplicitTemplateArgs
- ? ASTTemplateArgumentListInfo::Create(C, TemplateArgs)
- : nullptr);
- }
-
- static ClassScopeFunctionSpecializationDecl *
- CreateDeserialized(ASTContext &Context, unsigned ID);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
-
- static bool classofKind(Kind K) {
- return K == Decl::ClassScopeFunctionSpecialization;
- }
-};
-
/// Represents a variable template specialization, which refers to
/// a variable template with a given set of template arguments.
///
@@ -2697,19 +2635,20 @@ class VarTemplateSpecializationDecl : public VarDecl,
/// The template arguments used to describe this specialization.
const TemplateArgumentList *TemplateArgs;
- TemplateArgumentListInfo TemplateArgsInfo;
+ const ASTTemplateArgumentListInfo *TemplateArgsInfo = nullptr;
/// The point where this template was instantiated (if any).
SourceLocation PointOfInstantiation;
/// The kind of specialization this declaration refers to.
- /// Really a value of type TemplateSpecializationKind.
+ LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
unsigned SpecializationKind : 3;
/// Whether this declaration is a complete definition of the
/// variable template specialization. We can't otherwise tell apart
/// an instantiated declaration from an instantiated definition with
/// no initializer.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsCompleteDefinition : 1;
protected:
@@ -2752,8 +2691,9 @@ public:
// TODO: Always set this when creating the new specialization?
void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
+ void setTemplateArgsInfo(const ASTTemplateArgumentListInfo *ArgsInfo);
- const TemplateArgumentListInfo &getTemplateArgsInfo() const {
+ const ASTTemplateArgumentListInfo *getTemplateArgsInfo() const {
return TemplateArgsInfo;
}
@@ -2898,13 +2838,15 @@ public:
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
}
+ SourceRange getSourceRange() const override LLVM_READONLY;
+
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, TemplateArgs->asArray(), getASTContext());
}
static void Profile(llvm::FoldingSetNodeID &ID,
ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
+ const ASTContext &Context) {
ID.AddInteger(TemplateArgs.size());
for (const TemplateArgument &TemplateArg : TemplateArgs)
TemplateArg.Profile(ID, Context);
@@ -3055,6 +2997,8 @@ public:
return First->InstantiatedFromMember.setInt(true);
}
+ SourceRange getSourceRange() const override LLVM_READONLY;
+
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, getTemplateArgs().asArray(), getTemplateParameters(),
getASTContext());
@@ -3062,7 +3006,7 @@ public:
static void
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- TemplateParameterList *TPL, ASTContext &Context);
+ TemplateParameterList *TPL, const ASTContext &Context);
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3227,7 +3171,7 @@ public:
static bool classofKind(Kind K) { return K == VarTemplate; }
};
-/// Declaration of a C++2a concept.
+/// Declaration of a C++20 concept.
class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
protected:
Expr *ConstraintExpr;
@@ -3256,8 +3200,12 @@ public:
return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
}
- ConceptDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const ConceptDecl *getCanonicalDecl() const { return getFirstDecl(); }
+ ConceptDecl *getCanonicalDecl() override {
+ return cast<ConceptDecl>(getPrimaryMergedDecl(this));
+ }
+ const ConceptDecl *getCanonicalDecl() const {
+ return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3268,6 +3216,40 @@ public:
friend class ASTDeclWriter;
};
+// An implementation detail of ConceptSpecialicationExpr that holds the template
+// arguments, so we can later use this to reconstitute the template arguments
+// during constraint checking.
+class ImplicitConceptSpecializationDecl final
+ : public Decl,
+ private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
+ TemplateArgument> {
+ unsigned NumTemplateArgs;
+
+ ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL,
+ ArrayRef<TemplateArgument> ConvertedArgs);
+ ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
+
+public:
+ static ImplicitConceptSpecializationDecl *
+ Create(const ASTContext &C, DeclContext *DC, SourceLocation SL,
+ ArrayRef<TemplateArgument> ConvertedArgs);
+ static ImplicitConceptSpecializationDecl *
+ CreateDeserialized(const ASTContext &C, unsigned ID,
+ unsigned NumTemplateArgs);
+
+ ArrayRef<TemplateArgument> getTemplateArguments() const {
+ return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
+ NumTemplateArgs);
+ }
+ void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
+
+ static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
+ friend TrailingObjects;
+ friend class ASTDeclReader;
+};
+
/// A template parameter object.
///
/// Template parameter objects represent values of class type used as template
@@ -3305,14 +3287,17 @@ private:
public:
/// Print this template parameter object in a human-readable format.
- void printName(llvm::raw_ostream &OS) const override;
+ void printName(llvm::raw_ostream &OS,
+ const PrintingPolicy &Policy) const override;
/// Print this object as an equivalent expression.
void printAsExpr(llvm::raw_ostream &OS) const;
+ void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
/// Print this object as an initializer suitable for a variable of the
/// object's type.
void printAsInit(llvm::raw_ostream &OS) const;
+ void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
const APValue &getValue() const { return Value; }
@@ -3365,7 +3350,7 @@ inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
///
/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
/// is not a pack expansion, so returns an empty Optional.
-inline Optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
+inline std::optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
if (TTP->isExpandedParameterPack())
return TTP->getNumExpansionParameters();
@@ -3381,9 +3366,13 @@ inline Optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
return TTP->getNumExpansionTemplateParameters();
}
- return None;
+ return std::nullopt;
}
+/// Internal helper used by Subst* nodes to retrieve the parameter list
+/// for their AssociatedDecl.
+TemplateParameterList *getReplacedTemplateParameterList(Decl *D);
+
} // namespace clang
#endif // LLVM_CLANG_AST_DECLTEMPLATE_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h b/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h
index 38da6fc727fb..c9b01dc53964 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h
@@ -21,6 +21,7 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
@@ -34,11 +35,9 @@ class ASTContext;
template <typename> class CanQual;
class DeclarationName;
class DeclarationNameTable;
-class MultiKeywordSelector;
struct PrintingPolicy;
class TemplateDecl;
class TypeSourceInfo;
-class UsingDirectiveDecl;
using CanQualType = CanQual<Type>;
@@ -119,14 +118,14 @@ class alignas(IdentifierInfoAlignment) CXXLiteralOperatorIdName
friend class clang::DeclarationName;
friend class clang::DeclarationNameTable;
- IdentifierInfo *ID;
+ const IdentifierInfo *ID;
/// Extra information associated with this operator name that
/// can be used by the front end. All bits are really needed
/// so it is not possible to stash something in the low order bits.
void *FETokenInfo;
- CXXLiteralOperatorIdName(IdentifierInfo *II)
+ CXXLiteralOperatorIdName(const IdentifierInfo *II)
: DeclarationNameExtra(CXXLiteralOperatorName), ID(II),
FETokenInfo(nullptr) {}
@@ -194,6 +193,13 @@ class DeclarationName {
"The various classes that DeclarationName::Ptr can point to"
" must be at least aligned to 8 bytes!");
+ static_assert(
+ std::is_same<std::underlying_type_t<StoredNameKind>,
+ std::underlying_type_t<
+ detail::DeclarationNameExtra::ExtraKind>>::value,
+ "The various enums used to compute values for NameKind should "
+ "all have the same underlying type");
+
public:
/// The kind of the name stored in this DeclarationName.
/// The first 7 enumeration values are stored inline and correspond
@@ -207,15 +213,18 @@ public:
CXXDestructorName = StoredCXXDestructorName,
CXXConversionFunctionName = StoredCXXConversionFunctionName,
CXXOperatorName = StoredCXXOperatorName,
- CXXDeductionGuideName = UncommonNameKindOffset +
- detail::DeclarationNameExtra::CXXDeductionGuideName,
- CXXLiteralOperatorName =
- UncommonNameKindOffset +
- detail::DeclarationNameExtra::CXXLiteralOperatorName,
- CXXUsingDirective = UncommonNameKindOffset +
- detail::DeclarationNameExtra::CXXUsingDirective,
- ObjCMultiArgSelector = UncommonNameKindOffset +
- detail::DeclarationNameExtra::ObjCMultiArgSelector
+ CXXDeductionGuideName = llvm::addEnumValues(
+ UncommonNameKindOffset,
+ detail::DeclarationNameExtra::CXXDeductionGuideName),
+ CXXLiteralOperatorName = llvm::addEnumValues(
+ UncommonNameKindOffset,
+ detail::DeclarationNameExtra::CXXLiteralOperatorName),
+ CXXUsingDirective =
+ llvm::addEnumValues(UncommonNameKindOffset,
+ detail::DeclarationNameExtra::CXXUsingDirective),
+ ObjCMultiArgSelector =
+ llvm::addEnumValues(UncommonNameKindOffset,
+ detail::DeclarationNameExtra::ObjCMultiArgSelector),
};
private:
@@ -353,7 +362,8 @@ public:
}
/// Construct a declaration name from an Objective-C selector.
- DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
+ DeclarationName(Selector Sel)
+ : Ptr(reinterpret_cast<uintptr_t>(Sel.InfoPtr.getOpaqueValue())) {}
/// Returns the name for all C++ using-directives.
static DeclarationName getUsingDirectiveName() {
@@ -469,7 +479,7 @@ public:
/// If this name is the name of a literal operator,
/// retrieve the identifier associated with it.
- IdentifierInfo *getCXXLiteralIdentifier() const {
+ const IdentifierInfo *getCXXLiteralIdentifier() const {
if (getNameKind() == CXXLiteralOperatorName) {
assert(getPtr() && "getCXXLiteralIdentifier on a null DeclarationName!");
return castAsCXXLiteralOperatorIdName()->ID;
@@ -641,7 +651,7 @@ public:
}
/// Get the name of the literal operator function with II as the identifier.
- DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
+ DeclarationName getCXXLiteralOperatorName(const IdentifierInfo *II);
};
/// DeclarationNameLoc - Additional source/type location info
@@ -754,7 +764,7 @@ public:
};
/// DeclarationNameInfo - A collector data type for bundling together
-/// a DeclarationName and the correspnding source/type location info.
+/// a DeclarationName and the corresponding source/type location info.
struct DeclarationNameInfo {
private:
/// Name - The declaration name, also encoding name kind.
@@ -932,7 +942,7 @@ class AssumedTemplateStorage : public UncommonTemplateNameStorage {
friend class ASTContext;
AssumedTemplateStorage(DeclarationName Name)
- : UncommonTemplateNameStorage(Assumed, 0), Name(Name) {}
+ : UncommonTemplateNameStorage(Assumed, 0, 0), Name(Name) {}
DeclarationName Name;
public:
diff --git a/contrib/llvm-project/clang/include/clang/AST/DependenceFlags.h b/contrib/llvm-project/clang/include/clang/AST/DependenceFlags.h
index 62efdb4ce6e4..3b3c1afb096a 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DependenceFlags.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DependenceFlags.h
@@ -130,6 +130,14 @@ public:
// Dependence that is propagated syntactically, regardless of semantics.
Syntactic = UnexpandedPack | Instantiation | Error,
+ // Dependence that is propagated semantically, even in cases where the
+ // type doesn't syntactically appear. This currently excludes only
+ // UnexpandedPack. Even though Instantiation dependence is also notionally
+ // syntactic, we also want to propagate it semantically because anything
+ // that semantically depends on an instantiation-dependent entity should
+ // always be instantiated when that instantiation-dependent entity is.
+ Semantic =
+ Instantiation | Type | Value | Dependent | Error | VariablyModified,
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified)
};
@@ -175,6 +183,14 @@ public:
return Result;
}
+ /// Extract the semantic portions of this type's dependence that apply even
+ /// to uses where the type does not appear syntactically.
+ Dependence semantic() {
+ Dependence Result = *this;
+ Result.V &= Semantic;
+ return Result;
+ }
+
TypeDependence type() const {
return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) |
translate(V, Instantiation, TypeDependence::Instantiation) |
@@ -231,7 +247,10 @@ private:
inline ExprDependence toExprDependence(TemplateArgumentDependence TA) {
return Dependence(TA).expr();
}
-inline ExprDependence toExprDependence(TypeDependence D) {
+inline ExprDependence toExprDependenceForImpliedType(TypeDependence D) {
+ return Dependence(D).semantic().expr();
+}
+inline ExprDependence toExprDependenceAsWritten(TypeDependence D) {
return Dependence(D).expr();
}
// Note: it's often necessary to strip `Dependent` from qualifiers.
@@ -269,6 +288,9 @@ inline TypeDependence toTypeDependence(TemplateArgumentDependence D) {
inline TypeDependence toSyntacticDependence(TypeDependence D) {
return Dependence(D).syntactic().type();
}
+inline TypeDependence toSemanticDependence(TypeDependence D) {
+ return Dependence(D).semantic().type();
+}
inline NestedNameSpecifierDependence
toNestedNameSpecifierDependendence(TypeDependence D) {
diff --git a/contrib/llvm-project/clang/include/clang/AST/DependentDiagnostic.h b/contrib/llvm-project/clang/include/clang/AST/DependentDiagnostic.h
index 18276d54d540..cadf97062004 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DependentDiagnostic.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DependentDiagnostic.h
@@ -113,7 +113,9 @@ private:
struct {
SourceLocation Loc;
+ LLVM_PREFERRED_TYPE(AccessSpecifier)
unsigned Access : 2;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsMember : 1;
NamedDecl *TargetDecl;
CXXRecordDecl *NamingClass;
diff --git a/contrib/llvm-project/clang/include/clang/AST/Expr.h b/contrib/llvm-project/clang/include/clang/AST/Expr.h
index 8efa8fdbe2bb..9820bd11da86 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Expr.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Expr.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_AST_EXPR_H
#define LLVM_CLANG_AST_EXPR_H
+#include "clang/AST/APNumericStorage.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTVector.h"
#include "clang/AST/ComputeDependence.h"
@@ -36,6 +37,7 @@
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
+#include <optional>
namespace clang {
class APValue;
@@ -134,8 +136,8 @@ protected:
void setDependence(ExprDependence Deps) {
ExprBits.Dependent = static_cast<unsigned>(Deps);
}
- friend class ASTImporter; // Sets dependence dircetly.
- friend class ASTStmtReader; // Sets dependence dircetly.
+ friend class ASTImporter; // Sets dependence directly.
+ friend class ASTStmtReader; // Sets dependence directly.
public:
QualType getType() const { return TR; }
@@ -170,7 +172,7 @@ public:
}
/// Determines whether the type of this expression depends on
- /// - a template paramter (C++ [temp.dep.expr], which means that its type
+ /// - a template parameter (C++ [temp.dep.expr], which means that its type
/// could change from one template instantiation to the next)
/// - or an error
///
@@ -523,15 +525,25 @@ public:
/// semantically correspond to a bool.
bool isKnownToHaveBooleanValue(bool Semantic = true) const;
+ /// Check whether this array fits the idiom of a flexible array member,
+ /// depending on the value of -fstrict-flex-array.
+ /// When IgnoreTemplateOrMacroSubstitution is set, it doesn't consider sizes
+ /// resulting from the substitution of a macro or a template as special sizes.
+ bool isFlexibleArrayMemberLike(
+ ASTContext &Context,
+ LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
+ bool IgnoreTemplateOrMacroSubstitution = false) const;
+
/// isIntegerConstantExpr - Return the value if this expression is a valid
- /// integer constant expression. If not a valid i-c-e, return None and fill
- /// in Loc (if specified) with the location of the invalid expression.
+ /// integer constant expression. If not a valid i-c-e, return std::nullopt
+ /// and fill in Loc (if specified) with the location of the invalid
+ /// expression.
///
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
- Optional<llvm::APSInt> getIntegerConstantExpr(const ASTContext &Ctx,
- SourceLocation *Loc = nullptr,
- bool isEvaluated = true) const;
+ std::optional<llvm::APSInt>
+ getIntegerConstantExpr(const ASTContext &Ctx,
+ SourceLocation *Loc = nullptr) const;
bool isIntegerConstantExpr(const ASTContext &Ctx,
SourceLocation *Loc = nullptr) const;
@@ -555,7 +567,7 @@ public:
SmallVectorImpl<
PartialDiagnosticAt> &Diags);
- /// isPotentialConstantExprUnevaluted - Return true if this expression might
+ /// isPotentialConstantExprUnevaluated - Return true if this expression might
/// be usable in a constant expression in C++11 in an unevaluated context, if
/// it were in function FD marked constexpr. Return false if the function can
/// never produce a constant expression, along with diagnostics describing
@@ -572,16 +584,22 @@ public:
bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
const Expr **Culprit = nullptr) const;
+ /// If this expression is an unambiguous reference to a single declaration,
+ /// in the style of __builtin_function_start, return that declaration. Note
+ /// that this may return a non-static member function or field in C++ if this
+ /// expression is a member pointer constant.
+ const ValueDecl *getAsBuiltinConstantDeclRef(const ASTContext &Context) const;
+
/// EvalStatus is a struct with detailed info about an evaluation in progress.
struct EvalStatus {
/// Whether the evaluated expression has side effects.
/// For example, (f() && 0) can be folded, but it still has side effects.
- bool HasSideEffects;
+ bool HasSideEffects = false;
/// Whether the evaluation hit undefined behavior.
/// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior.
/// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
- bool HasUndefinedBehavior;
+ bool HasUndefinedBehavior = false;
/// Diag - If this is non-null, it will be filled in with a stack of notes
/// indicating why evaluation failed (or why it failed to produce a constant
@@ -590,10 +608,16 @@ public:
/// foldable. If the expression is foldable, but not a constant expression,
/// the notes will describes why it isn't a constant expression. If the
/// expression *is* a constant expression, no notes will be produced.
- SmallVectorImpl<PartialDiagnosticAt> *Diag;
+ ///
+ /// FIXME: this causes significant performance concerns and should be
+ /// refactored at some point. Not all evaluations of the constant
+ /// expression interpreter will display the given diagnostics, this means
+ /// those kinds of uses are paying the expense of generating a diagnostic
+ /// (which may include expensive operations like converting APValue objects
+ /// to a string representation).
+ SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr;
- EvalStatus()
- : HasSideEffects(false), HasUndefinedBehavior(false), Diag(nullptr) {}
+ EvalStatus() = default;
// hasSideEffects - Return true if the evaluated expression has
// side effects.
@@ -648,8 +672,8 @@ public:
SideEffectsKind AllowSideEffects = SE_NoSideEffects,
bool InConstantContext = false) const;
- /// EvaluateAsFloat - Return true if this is a constant which we can fold and
- /// convert to a fixed point value.
+ /// EvaluateAsFixedPoint - Return true if this is a constant which we can fold
+ /// and convert to a fixed point value.
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects = SE_NoSideEffects,
bool InConstantContext = false) const;
@@ -697,7 +721,8 @@ public:
/// notes will be produced if the expression is not a constant expression.
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx,
const VarDecl *VD,
- SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+ SmallVectorImpl<PartialDiagnosticAt> &Notes,
+ bool IsConstantInitializer) const;
/// EvaluateWithSubstitution - Evaluate an expression as if from the context
/// of a call to the given function with the given arguments, inside an
@@ -739,6 +764,17 @@ public:
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx,
unsigned Type) const;
+ /// If the current Expr is a pointer, this will try to statically
+ /// determine the strlen of the string pointed to.
+ /// Returns true if all of the above holds and we were able to figure out the
+ /// strlen, false otherwise.
+ bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const;
+
+ bool EvaluateCharRangeAsString(std::string &Result,
+ const Expr *SizeExpression,
+ const Expr *PtrExpression, ASTContext &Ctx,
+ EvalResult &Status) const;
+
/// Enumeration used to describe the kind of Null pointer constant
/// returned from \c isNullPointerConstant().
enum NullPointerConstantKind {
@@ -796,7 +832,7 @@ public:
/// member expression.
static QualType findBoundMemberType(const Expr *expr);
- /// Skip past any invisble AST nodes which might surround this
+ /// Skip past any invisible AST nodes which might surround this
/// statement, such as ExprWithCleanups or ImplicitCastExpr nodes,
/// but also injected CXXMemberExpr and CXXConstructExpr which represent
/// implicit conversions.
@@ -900,7 +936,7 @@ public:
return const_cast<Expr *>(this)->IgnoreParenLValueCasts();
}
- /// Skip past any parenthese and casts which do not change the value
+ /// Skip past any parentheses and casts which do not change the value
/// (including ptr->int casts of the same size) until reaching a fixed point.
/// Skips:
/// * What IgnoreParens() skips
@@ -1014,6 +1050,9 @@ public:
}
};
+/// Describes the kind of result that can be tail-allocated.
+enum class ConstantResultStorageKind { None, Int64, APValue };
+
/// ConstantExpr - An expression that occurs in a constant context and
/// optionally the result of evaluating the expression.
class ConstantExpr final
@@ -1026,20 +1065,15 @@ class ConstantExpr final
friend class ASTStmtReader;
friend class ASTStmtWriter;
-public:
- /// Describes the kind of result that can be tail-allocated.
- enum ResultStorageKind { RSK_None, RSK_Int64, RSK_APValue };
-
-private:
size_t numTrailingObjects(OverloadToken<APValue>) const {
- return ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue;
+ return getResultStorageKind() == ConstantResultStorageKind::APValue;
}
size_t numTrailingObjects(OverloadToken<uint64_t>) const {
- return ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64;
+ return getResultStorageKind() == ConstantResultStorageKind::Int64;
}
uint64_t &Int64Result() {
- assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64 &&
+ assert(getResultStorageKind() == ConstantResultStorageKind::Int64 &&
"invalid accessor");
return *getTrailingObjects<uint64_t>();
}
@@ -1047,7 +1081,7 @@ private:
return const_cast<ConstantExpr *>(this)->Int64Result();
}
APValue &APValueResult() {
- assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue &&
+ assert(getResultStorageKind() == ConstantResultStorageKind::APValue &&
"invalid accessor");
return *getTrailingObjects<APValue>();
}
@@ -1055,22 +1089,23 @@ private:
return const_cast<ConstantExpr *>(this)->APValueResult();
}
- ConstantExpr(Expr *SubExpr, ResultStorageKind StorageKind,
+ ConstantExpr(Expr *SubExpr, ConstantResultStorageKind StorageKind,
bool IsImmediateInvocation);
- ConstantExpr(EmptyShell Empty, ResultStorageKind StorageKind);
+ ConstantExpr(EmptyShell Empty, ConstantResultStorageKind StorageKind);
public:
static ConstantExpr *Create(const ASTContext &Context, Expr *E,
const APValue &Result);
- static ConstantExpr *Create(const ASTContext &Context, Expr *E,
- ResultStorageKind Storage = RSK_None,
- bool IsImmediateInvocation = false);
+ static ConstantExpr *
+ Create(const ASTContext &Context, Expr *E,
+ ConstantResultStorageKind Storage = ConstantResultStorageKind::None,
+ bool IsImmediateInvocation = false);
static ConstantExpr *CreateEmpty(const ASTContext &Context,
- ResultStorageKind StorageKind);
+ ConstantResultStorageKind StorageKind);
- static ResultStorageKind getStorageKind(const APValue &Value);
- static ResultStorageKind getStorageKind(const Type *T,
- const ASTContext &Context);
+ static ConstantResultStorageKind getStorageKind(const APValue &Value);
+ static ConstantResultStorageKind getStorageKind(const Type *T,
+ const ASTContext &Context);
SourceLocation getBeginLoc() const LLVM_READONLY {
return SubExpr->getBeginLoc();
@@ -1091,8 +1126,8 @@ public:
APValue::ValueKind getResultAPValueKind() const {
return static_cast<APValue::ValueKind>(ConstantExprBits.APValueKind);
}
- ResultStorageKind getResultStorageKind() const {
- return static_cast<ResultStorageKind>(ConstantExprBits.ResultKind);
+ ConstantResultStorageKind getResultStorageKind() const {
+ return static_cast<ConstantResultStorageKind>(ConstantExprBits.ResultKind);
}
bool isImmediateInvocation() const {
return ConstantExprBits.IsImmediateInvocation;
@@ -1101,7 +1136,6 @@ public:
return ConstantExprBits.APValueKind != APValue::None;
}
APValue getAPValueResult() const;
- APValue &getResultAsAPValue() const { return APValueResult(); }
llvm::APSInt getResultAsAPSInt() const;
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
@@ -1413,68 +1447,35 @@ public:
return DeclRefExprBits.RefersToEnclosingVariableOrCapture;
}
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclRefExprClass;
+ bool isImmediateEscalating() const {
+ return DeclRefExprBits.IsImmediateEscalating;
}
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
+ void setIsImmediateEscalating(bool Set) {
+ DeclRefExprBits.IsImmediateEscalating = Set;
}
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ bool isCapturedByCopyInLambdaWithExplicitObjectParameter() const {
+ return DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter;
}
-};
-/// Used by IntegerLiteral/FloatingLiteral to store the numeric without
-/// leaking memory.
-///
-/// For large floats/integers, APFloat/APInt will allocate memory from the heap
-/// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator
-/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
-/// the APFloat/APInt values will never get freed. APNumericStorage uses
-/// ASTContext's allocator for memory allocation.
-class APNumericStorage {
- union {
- uint64_t VAL; ///< Used to store the <= 64 bits integer value.
- uint64_t *pVal; ///< Used to store the >64 bits integer value.
- };
- unsigned BitWidth;
-
- bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
-
- APNumericStorage(const APNumericStorage &) = delete;
- void operator=(const APNumericStorage &) = delete;
-
-protected:
- APNumericStorage() : VAL(0), BitWidth(0) { }
-
- llvm::APInt getIntValue() const {
- unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
- if (NumWords > 1)
- return llvm::APInt(BitWidth, NumWords, pVal);
- else
- return llvm::APInt(BitWidth, VAL);
+ void setCapturedByCopyInLambdaWithExplicitObjectParameter(
+ bool Set, const ASTContext &Context) {
+ DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = Set;
+ setDependence(computeDependence(this, Context));
}
- void setIntValue(const ASTContext &C, const llvm::APInt &Val);
-};
-class APIntStorage : private APNumericStorage {
-public:
- llvm::APInt getValue() const { return getIntValue(); }
- void setValue(const ASTContext &C, const llvm::APInt &Val) {
- setIntValue(C, Val);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DeclRefExprClass;
}
-};
-class APFloatStorage : private APNumericStorage {
-public:
- llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
- return llvm::APFloat(Semantics, getIntValue());
+ // Iterators
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
}
- void setValue(const ASTContext &C, const llvm::APFloat &Val) {
- setIntValue(C, Val.bitcastToAPInt());
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
}
};
@@ -1568,26 +1569,18 @@ class FixedPointLiteral : public Expr, public APIntStorage {
}
};
-class CharacterLiteral : public Expr {
-public:
- enum CharacterKind {
- Ascii,
- Wide,
- UTF8,
- UTF16,
- UTF32
- };
+enum class CharacterLiteralKind { Ascii, Wide, UTF8, UTF16, UTF32 };
-private:
+class CharacterLiteral : public Expr {
unsigned Value;
SourceLocation Loc;
public:
// type should be IntTy
- CharacterLiteral(unsigned value, CharacterKind kind, QualType type,
+ CharacterLiteral(unsigned value, CharacterLiteralKind kind, QualType type,
SourceLocation l)
: Expr(CharacterLiteralClass, type, VK_PRValue, OK_Ordinary),
Value(value), Loc(l) {
- CharacterLiteralBits.Kind = kind;
+ CharacterLiteralBits.Kind = llvm::to_underlying(kind);
setDependence(ExprDependence::None);
}
@@ -1595,8 +1588,8 @@ public:
CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { }
SourceLocation getLocation() const { return Loc; }
- CharacterKind getKind() const {
- return static_cast<CharacterKind>(CharacterLiteralBits.Kind);
+ CharacterLiteralKind getKind() const {
+ return static_cast<CharacterLiteralKind>(CharacterLiteralBits.Kind);
}
SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
@@ -1605,14 +1598,16 @@ public:
unsigned getValue() const { return Value; }
void setLocation(SourceLocation Location) { Loc = Location; }
- void setKind(CharacterKind kind) { CharacterLiteralBits.Kind = kind; }
+ void setKind(CharacterLiteralKind kind) {
+ CharacterLiteralBits.Kind = llvm::to_underlying(kind);
+ }
void setValue(unsigned Val) { Value = Val; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CharacterLiteralClass;
}
- static void print(unsigned val, CharacterKind Kind, raw_ostream &OS);
+ static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS);
// Iterators
child_range children() {
@@ -1734,6 +1729,15 @@ public:
}
};
+enum class StringLiteralKind {
+ Ordinary,
+ Wide,
+ UTF8,
+ UTF16,
+ UTF32,
+ Unevaluated
+};
+
/// StringLiteral - This represents a string literal expression, e.g. "foo"
/// or L"bar" (wide strings). The actual string data can be obtained with
/// getBytes() and is NOT null-terminated. The length of the string data is
@@ -1772,10 +1776,6 @@ class StringLiteral final
///
/// * An array of getByteLength() char used to store the string data.
-public:
- enum StringKind { Ascii, Wide, UTF8, UTF16, UTF32 };
-
-private:
unsigned numTrailingObjects(OverloadToken<unsigned>) const { return 1; }
unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
return getNumConcatenated();
@@ -1797,7 +1797,7 @@ private:
}
/// Build a string literal.
- StringLiteral(const ASTContext &Ctx, StringRef Str, StringKind Kind,
+ StringLiteral(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind,
bool Pascal, QualType Ty, const SourceLocation *Loc,
unsigned NumConcatenated);
@@ -1806,7 +1806,8 @@ private:
unsigned CharByteWidth);
/// Map a target and string kind to the appropriate character width.
- static unsigned mapCharByteWidth(TargetInfo const &Target, StringKind SK);
+ static unsigned mapCharByteWidth(TargetInfo const &Target,
+ StringLiteralKind SK);
/// Set one of the string literal token.
void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
@@ -1818,13 +1819,13 @@ public:
/// This is the "fully general" constructor that allows representation of
/// strings formed from multiple concatenated tokens.
static StringLiteral *Create(const ASTContext &Ctx, StringRef Str,
- StringKind Kind, bool Pascal, QualType Ty,
+ StringLiteralKind Kind, bool Pascal, QualType Ty,
const SourceLocation *Loc,
unsigned NumConcatenated);
/// Simple constructor for string literals made from one token.
static StringLiteral *Create(const ASTContext &Ctx, StringRef Str,
- StringKind Kind, bool Pascal, QualType Ty,
+ StringLiteralKind Kind, bool Pascal, QualType Ty,
SourceLocation Loc) {
return Create(Ctx, Str, Kind, Pascal, Ty, &Loc, 1);
}
@@ -1835,7 +1836,7 @@ public:
unsigned CharByteWidth);
StringRef getString() const {
- assert(getCharByteWidth() == 1 &&
+ assert((isUnevaluated() || getCharByteWidth() == 1) &&
"This function is used in places that assume strings use char");
return StringRef(getStrDataAsChar(), getByteLength());
}
@@ -1866,15 +1867,16 @@ public:
unsigned getLength() const { return *getTrailingObjects<unsigned>(); }
unsigned getCharByteWidth() const { return StringLiteralBits.CharByteWidth; }
- StringKind getKind() const {
- return static_cast<StringKind>(StringLiteralBits.Kind);
+ StringLiteralKind getKind() const {
+ return static_cast<StringLiteralKind>(StringLiteralBits.Kind);
}
- bool isAscii() const { return getKind() == Ascii; }
- bool isWide() const { return getKind() == Wide; }
- bool isUTF8() const { return getKind() == UTF8; }
- bool isUTF16() const { return getKind() == UTF16; }
- bool isUTF32() const { return getKind() == UTF32; }
+ bool isOrdinary() const { return getKind() == StringLiteralKind::Ordinary; }
+ bool isWide() const { return getKind() == StringLiteralKind::Wide; }
+ bool isUTF8() const { return getKind() == StringLiteralKind::UTF8; }
+ bool isUTF16() const { return getKind() == StringLiteralKind::UTF16; }
+ bool isUTF32() const { return getKind() == StringLiteralKind::UTF32; }
+ bool isUnevaluated() const { return getKind() == StringLiteralKind::Unevaluated; }
bool isPascal() const { return StringLiteralBits.IsPascal; }
bool containsNonAscii() const {
@@ -1942,6 +1944,19 @@ public:
}
};
+enum class PredefinedIdentKind {
+ Func,
+ Function,
+ LFunction, // Same as Function, but as wide string.
+ FuncDName,
+ FuncSig,
+ LFuncSig, // Same as FuncSig, but as wide string
+ PrettyFunction,
+ /// The same as PrettyFunction, except that the
+ /// 'virtual' keyword is omitted for virtual member functions.
+ PrettyFunctionNoVirtual
+};
+
/// [C99 6.4.2.2] - A predefined identifier such as __func__.
class PredefinedExpr final
: public Expr,
@@ -1953,23 +1968,8 @@ class PredefinedExpr final
// "Stmt *" for the predefined identifier. It is present if and only if
// hasFunctionName() is true and is always a "StringLiteral *".
-public:
- enum IdentKind {
- Func,
- Function,
- LFunction, // Same as Function, but as wide string.
- FuncDName,
- FuncSig,
- LFuncSig, // Same as FuncSig, but as as wide string
- PrettyFunction,
- /// The same as PrettyFunction, except that the
- /// 'virtual' keyword is omitted for virtual member functions.
- PrettyFunctionNoVirtual
- };
-
-private:
- PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
- StringLiteral *SL);
+ PredefinedExpr(SourceLocation L, QualType FNTy, PredefinedIdentKind IK,
+ bool IsTransparent, StringLiteral *SL);
explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName);
@@ -1984,17 +1984,23 @@ private:
public:
/// Create a PredefinedExpr.
+ ///
+ /// If IsTransparent, the PredefinedExpr is transparently handled as a
+ /// StringLiteral.
static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
- QualType FNTy, IdentKind IK, StringLiteral *SL);
+ QualType FNTy, PredefinedIdentKind IK,
+ bool IsTransparent, StringLiteral *SL);
/// Create an empty PredefinedExpr.
static PredefinedExpr *CreateEmpty(const ASTContext &Ctx,
bool HasFunctionName);
- IdentKind getIdentKind() const {
- return static_cast<IdentKind>(PredefinedExprBits.Kind);
+ PredefinedIdentKind getIdentKind() const {
+ return static_cast<PredefinedIdentKind>(PredefinedExprBits.Kind);
}
+ bool isTransparent() const { return PredefinedExprBits.IsTransparent; }
+
SourceLocation getLocation() const { return PredefinedExprBits.Loc; }
void setLocation(SourceLocation L) { PredefinedExprBits.Loc = L; }
@@ -2010,12 +2016,13 @@ public:
: nullptr;
}
- static StringRef getIdentKindName(IdentKind IK);
+ static StringRef getIdentKindName(PredefinedIdentKind IK);
StringRef getIdentKindName() const {
return getIdentKindName(getIdentKind());
}
- static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl);
+ static std::string ComputeName(PredefinedIdentKind IK,
+ const Decl *CurrentDecl);
SourceLocation getBeginLoc() const { return getLocation(); }
SourceLocation getEndLoc() const { return getLocation(); }
@@ -2210,14 +2217,14 @@ public:
bool canOverflow() const { return UnaryOperatorBits.CanOverflow; }
void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; }
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FP contractability status of this operator. Only meaningful for
+ /// operations on floating point types.
bool isFPContractableWithinStatement(const LangOptions &LO) const {
return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
}
- // Get the FENV_ACCESS status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FENV_ACCESS status of this operator. Only meaningful for
+ /// operations on floating point types.
bool isFEnvAccessOn(const LangOptions &LO) const {
return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
}
@@ -2298,12 +2305,12 @@ public:
}
protected:
- /// Set FPFeatures in trailing storage, used only by Serialization
+ /// Set FPFeatures in trailing storage, used by Serialization & ASTImporter.
void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
public:
- // Get the FP features status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FP features status of this operator. Only meaningful for
+ /// operations on floating point types.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
if (UnaryOperatorBits.HasFPFeatures)
return getStoredFPFeatures().applyOverrides(LO);
@@ -2316,6 +2323,7 @@ public:
}
friend TrailingObjects;
+ friend class ASTNodeImporter;
friend class ASTReader;
friend class ASTStmtReader;
friend class ASTStmtWriter;
@@ -2375,7 +2383,7 @@ public:
/// Create an offsetof node that refers into a C++ base class.
explicit OffsetOfNode(const CXXBaseSpecifier *Base)
- : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
+ : Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
/// Determine what kind of offsetof node this is.
Kind getKind() const { return static_cast<Kind>(Data & Mask); }
@@ -2791,7 +2799,7 @@ class CallExpr : public Expr {
/// The number of arguments in the call expression.
unsigned NumArgs;
- /// The location of the right parenthese. This has a different meaning for
+ /// The location of the right parentheses. This has a different meaning for
/// the derived classes of CallExpr.
SourceLocation RParenLoc;
@@ -2997,7 +3005,7 @@ public:
/// Compute and set dependence bits.
void computeDependence() {
setDependence(clang::computeDependence(
- this, llvm::makeArrayRef(
+ this, llvm::ArrayRef(
reinterpret_cast<Expr **>(getTrailingStmts() + PREARGS_START),
getNumPreArgs())));
}
@@ -3044,14 +3052,10 @@ public:
/// interface. This provides efficient reverse iteration of the
/// subexpressions. This is currently used for CFG construction.
ArrayRef<Stmt *> getRawSubExprs() {
- return llvm::makeArrayRef(getTrailingStmts(),
- PREARGS_START + getNumPreArgs() + getNumArgs());
+ return llvm::ArrayRef(getTrailingStmts(),
+ PREARGS_START + getNumPreArgs() + getNumArgs());
}
- /// getNumCommas - Return the number of commas that must have been present in
- /// this function call.
- unsigned getNumCommas() const { return getNumArgs() ? getNumArgs() - 1 : 0; }
-
/// Get FPOptionsOverride from trailing storage.
FPOptionsOverride getStoredFPFeatures() const {
assert(hasStoredFPFeatures());
@@ -3063,8 +3067,8 @@ public:
*getTrailingFPFeatures() = F;
}
- // Get the FP features status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FP features status of this operator. Only meaningful for
+ /// operations on floating point types.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
if (hasStoredFPFeatures())
return getStoredFPFeatures().applyOverrides(LO);
@@ -3115,11 +3119,7 @@ public:
setDependence(getDependence() | ExprDependence::TypeValueInstantiation);
}
- bool isCallToStdMove() const {
- const FunctionDecl *FD = getDirectCallee();
- return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
- FD->getIdentifier() && FD->getIdentifier()->isStr("move");
- }
+ bool isCallToStdMove() const;
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstCallExprConstant &&
@@ -3484,7 +3484,6 @@ protected:
CastExprBits.BasePathSize = BasePathSize;
assert((CastExprBits.BasePathSize == BasePathSize) &&
"BasePathSize overflow!");
- setDependence(computeDependence(this));
assert(CastConsistency());
CastExprBits.HasFPFeatures = HasFPFeatures;
}
@@ -3559,8 +3558,8 @@ public:
return *getTrailingFPFeatures();
}
- // Get the FP features status of this operation. Only meaningful for
- // operations on floating point types.
+ /// Get the FP features status of this operation. Only meaningful for
+ /// operations on floating point types.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
if (hasStoredFPFeatures())
return getStoredFPFeatures().applyOverrides(LO);
@@ -3573,6 +3572,19 @@ public:
return FPOptionsOverride();
}
+ /// Return
+ // True : if this conversion changes the volatile-ness of a gl-value.
+ // Qualification conversions on gl-values currently use CK_NoOp, but
+ // it's important to recognize volatile-changing conversions in
+ // clients code generation that normally eagerly peephole loads. Note
+ // that the query is answering for this specific node; Sema may
+ // produce multiple cast nodes for any particular conversion sequence.
+ // False : Otherwise.
+ bool changesVolatileQualification() const {
+ return (isGLValue() && (getType().isVolatileQualified() !=
+ getSubExpr()->getType().isVolatileQualified()));
+ }
+
static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType,
QualType opType);
static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD,
@@ -3618,6 +3630,7 @@ class ImplicitCastExpr final
ExprValueKind VK)
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength,
FPO.requiresTrailingStorage()) {
+ setDependence(computeDependence(this));
if (hasStoredFPFeatures())
*getTrailingFPFeatures() = FPO;
}
@@ -3695,7 +3708,9 @@ protected:
CastKind kind, Expr *op, unsigned PathSize,
bool HasFPFeatures, TypeSourceInfo *writtenTy)
: CastExpr(SC, exprTy, VK, kind, op, PathSize, HasFPFeatures),
- TInfo(writtenTy) {}
+ TInfo(writtenTy) {
+ setDependence(computeDependence(this));
+ }
/// Construct an empty explicit cast.
ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize,
@@ -3954,11 +3969,12 @@ public:
return isShiftAssignOp(getOpcode());
}
- // Return true if a binary operator using the specified opcode and operands
- // would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized
- // integer to a pointer.
+ /// Return true if a binary operator using the specified opcode and operands
+ /// would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized
+ /// integer to a pointer.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc,
- Expr *LHS, Expr *RHS);
+ const Expr *LHS,
+ const Expr *RHS);
static bool classof(const Stmt *S) {
return S->getStmtClass() >= firstBinaryOperatorConstant &&
@@ -3989,8 +4005,8 @@ public:
*getTrailingFPFeatures() = F;
}
- // Get the FP features status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FP features status of this operator. Only meaningful for
+ /// operations on floating point types.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
if (BinaryOperatorBits.HasFPFeatures)
return getStoredFPFeatures().applyOverrides(LO);
@@ -3998,20 +4014,20 @@ public:
}
// This is used in ASTImporter
- FPOptionsOverride getFPFeatures(const LangOptions &LO) const {
+ FPOptionsOverride getFPFeatures() const {
if (BinaryOperatorBits.HasFPFeatures)
return getStoredFPFeatures();
return FPOptionsOverride();
}
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FP contractability status of this operator. Only meaningful for
+ /// operations on floating point types.
bool isFPContractableWithinStatement(const LangOptions &LO) const {
return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
}
- // Get the FENV_ACCESS status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FENV_ACCESS status of this operator. Only meaningful for
+ /// operations on floating point types.
bool isFEnvAccessOn(const LangOptions &LO) const {
return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
}
@@ -4107,17 +4123,17 @@ protected:
: Expr(SC, Empty) { }
public:
- // getCond - Return the expression representing the condition for
- // the ?: operator.
+ /// getCond - Return the expression representing the condition for
+ /// the ?: operator.
Expr *getCond() const;
- // getTrueExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to true.
+ /// getTrueExpr - Return the subexpression representing the value of
+ /// the expression if the condition evaluates to true.
Expr *getTrueExpr() const;
- // getFalseExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to false. This is
- // the same as getRHS.
+ /// getFalseExpr - Return the subexpression representing the value of
+ /// the expression if the condition evaluates to false. This is
+ /// the same as getRHS.
Expr *getFalseExpr() const;
SourceLocation getQuestionLoc() const { return QuestionLoc; }
@@ -4152,17 +4168,17 @@ public:
explicit ConditionalOperator(EmptyShell Empty)
: AbstractConditionalOperator(ConditionalOperatorClass, Empty) { }
- // getCond - Return the expression representing the condition for
- // the ?: operator.
+ /// getCond - Return the expression representing the condition for
+ /// the ?: operator.
Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
- // getTrueExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to true.
+ /// getTrueExpr - Return the subexpression representing the value of
+ /// the expression if the condition evaluates to true.
Expr *getTrueExpr() const { return cast<Expr>(SubExprs[LHS]); }
- // getFalseExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to false. This is
- // the same as getRHS.
+ /// getFalseExpr - Return the subexpression representing the value of
+ /// the expression if the condition evaluates to false. This is
+ /// the same as getRHS.
Expr *getFalseExpr() const { return cast<Expr>(SubExprs[RHS]); }
Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
@@ -4666,16 +4682,26 @@ public:
}
};
+enum class SourceLocIdentKind {
+ Function,
+ FuncSig,
+ File,
+ FileName,
+ Line,
+ Column,
+ SourceLocStruct
+};
+
/// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(),
-/// __builtin_FUNCTION(), or __builtin_FILE().
+/// __builtin_FUNCTION(), __builtin_FUNCSIG(), __builtin_FILE(),
+/// __builtin_FILE_NAME() or __builtin_source_location().
class SourceLocExpr final : public Expr {
SourceLocation BuiltinLoc, RParenLoc;
DeclContext *ParentContext;
public:
- enum IdentKind { Function, File, Line, Column };
-
- SourceLocExpr(const ASTContext &Ctx, IdentKind Type, SourceLocation BLoc,
+ SourceLocExpr(const ASTContext &Ctx, SourceLocIdentKind Type,
+ QualType ResultTy, SourceLocation BLoc,
SourceLocation RParenLoc, DeclContext *Context);
/// Build an empty call expression.
@@ -4689,22 +4715,24 @@ public:
/// Return a string representing the name of the specific builtin function.
StringRef getBuiltinStr() const;
- IdentKind getIdentKind() const {
- return static_cast<IdentKind>(SourceLocExprBits.Kind);
+ SourceLocIdentKind getIdentKind() const {
+ return static_cast<SourceLocIdentKind>(SourceLocExprBits.Kind);
}
- bool isStringType() const {
+ bool isIntType() const {
switch (getIdentKind()) {
- case File:
- case Function:
- return true;
- case Line:
- case Column:
+ case SourceLocIdentKind::File:
+ case SourceLocIdentKind::FileName:
+ case SourceLocIdentKind::Function:
+ case SourceLocIdentKind::FuncSig:
+ case SourceLocIdentKind::SourceLocStruct:
return false;
+ case SourceLocIdentKind::Line:
+ case SourceLocIdentKind::Column:
+ return true;
}
llvm_unreachable("unknown source location expression kind");
}
- bool isIntType() const LLVM_READONLY { return !isStringType(); }
/// If the SourceLocExpr has been resolved return the subexpression
/// representing the resolved value. Otherwise return null.
@@ -4727,6 +4755,17 @@ public:
return T->getStmtClass() == SourceLocExprClass;
}
+ static bool MayBeDependent(SourceLocIdentKind Kind) {
+ switch (Kind) {
+ case SourceLocIdentKind::Function:
+ case SourceLocIdentKind::FuncSig:
+ case SourceLocIdentKind::SourceLocStruct:
+ return true;
+ default:
+ return false;
+ }
+ }
+
private:
friend class ASTStmtReader;
};
@@ -4816,12 +4855,10 @@ public:
return reinterpret_cast<Expr * const *>(InitExprs.data());
}
- ArrayRef<Expr *> inits() {
- return llvm::makeArrayRef(getInits(), getNumInits());
- }
+ ArrayRef<Expr *> inits() { return llvm::ArrayRef(getInits(), getNumInits()); }
ArrayRef<Expr *> inits() const {
- return llvm::makeArrayRef(getInits(), getNumInits());
+ return llvm::ArrayRef(getInits(), getNumInits());
}
const Expr *getInit(unsigned Init) const {
@@ -4884,6 +4921,13 @@ public:
/// has been set.
bool hasArrayFiller() const { return getArrayFiller(); }
+ /// Determine whether this initializer list contains a designated initializer.
+ bool hasDesignatedInit() const {
+ return std::any_of(begin(), end(), [](const Stmt *S) {
+ return isa<DesignatedInitExpr>(S);
+ });
+ }
+
/// If this initializes a union, specifies which field in the
/// union to initialize.
///
@@ -4912,8 +4956,8 @@ public:
return LBraceLoc.isValid() && RBraceLoc.isValid();
}
- // Is this an initializer for an array of characters, initialized by a string
- // literal or an @encode?
+ /// Is this an initializer for an array of characters, initialized by a string
+ /// literal or an @encode?
bool isStringLiteralInit() const;
/// Is this a transparent initializer list (that is, an InitListExpr that is
@@ -5028,6 +5072,7 @@ private:
/// Whether this designated initializer used the GNU deprecated
/// syntax rather than the C99 '=' syntax.
+ LLVM_PREFERRED_TYPE(bool)
unsigned GNUSyntax : 1;
/// The number of designators in this initializer expression.
@@ -5052,37 +5097,6 @@ private:
NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
public:
- /// A field designator, e.g., ".x".
- struct FieldDesignator {
- /// Refers to the field that is being initialized. The low bit
- /// of this field determines whether this is actually a pointer
- /// to an IdentifierInfo (if 1) or a FieldDecl (if 0). When
- /// initially constructed, a field designator will store an
- /// IdentifierInfo*. After semantic analysis has resolved that
- /// name, the field designator will instead store a FieldDecl*.
- uintptr_t NameOrField;
-
- /// The location of the '.' in the designated initializer.
- SourceLocation DotLoc;
-
- /// The location of the field name in the designated initializer.
- SourceLocation FieldLoc;
- };
-
- /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
- struct ArrayOrRangeDesignator {
- /// Location of the first index expression within the designated
- /// initializer expression's list of subexpressions.
- unsigned Index;
- /// The location of the '[' starting the array range designator.
- SourceLocation LBracketLoc;
- /// The location of the ellipsis separating the start and end
- /// indices. Only valid for GNU array-range designators.
- SourceLocation EllipsisLoc;
- /// The location of the ']' terminating the array range designator.
- SourceLocation RBracketLoc;
- };
-
/// Represents a single C99 designator.
///
/// @todo This class is infuriatingly similar to clang::Designator,
@@ -5090,118 +5104,177 @@ public:
/// keep us from reusing it. Try harder, later, to rectify these
/// differences.
class Designator {
+ /// A field designator, e.g., ".x".
+ struct FieldDesignatorInfo {
+ /// Refers to the field that is being initialized. The low bit
+ /// of this field determines whether this is actually a pointer
+ /// to an IdentifierInfo (if 1) or a FieldDecl (if 0). When
+ /// initially constructed, a field designator will store an
+ /// IdentifierInfo*. After semantic analysis has resolved that
+ /// name, the field designator will instead store a FieldDecl*.
+ uintptr_t NameOrField;
+
+ /// The location of the '.' in the designated initializer.
+ SourceLocation DotLoc;
+
+ /// The location of the field name in the designated initializer.
+ SourceLocation FieldLoc;
+
+ FieldDesignatorInfo(const IdentifierInfo *II, SourceLocation DotLoc,
+ SourceLocation FieldLoc)
+ : NameOrField(reinterpret_cast<uintptr_t>(II) | 0x1), DotLoc(DotLoc),
+ FieldLoc(FieldLoc) {}
+ };
+
+ /// An array or GNU array-range designator, e.g., "[9]" or "[10...15]".
+ struct ArrayOrRangeDesignatorInfo {
+ /// Location of the first index expression within the designated
+ /// initializer expression's list of subexpressions.
+ unsigned Index;
+
+ /// The location of the '[' starting the array range designator.
+ SourceLocation LBracketLoc;
+
+ /// The location of the ellipsis separating the start and end
+ /// indices. Only valid for GNU array-range designators.
+ SourceLocation EllipsisLoc;
+
+ /// The location of the ']' terminating the array range designator.
+ SourceLocation RBracketLoc;
+
+ ArrayOrRangeDesignatorInfo(unsigned Index, SourceLocation LBracketLoc,
+ SourceLocation RBracketLoc)
+ : Index(Index), LBracketLoc(LBracketLoc), RBracketLoc(RBracketLoc) {}
+
+ ArrayOrRangeDesignatorInfo(unsigned Index,
+ SourceLocation LBracketLoc,
+ SourceLocation EllipsisLoc,
+ SourceLocation RBracketLoc)
+ : Index(Index), LBracketLoc(LBracketLoc), EllipsisLoc(EllipsisLoc),
+ RBracketLoc(RBracketLoc) {}
+ };
+
/// The kind of designator this describes.
- enum {
+ enum DesignatorKind {
FieldDesignator,
ArrayDesignator,
ArrayRangeDesignator
- } Kind;
+ };
+
+ DesignatorKind Kind;
union {
/// A field designator, e.g., ".x".
- struct FieldDesignator Field;
+ struct FieldDesignatorInfo FieldInfo;
+
/// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
- struct ArrayOrRangeDesignator ArrayOrRange;
+ struct ArrayOrRangeDesignatorInfo ArrayOrRangeInfo;
};
- friend class DesignatedInitExpr;
+
+ Designator(DesignatorKind Kind) : Kind(Kind) {}
public:
Designator() {}
- /// Initializes a field designator.
- Designator(const IdentifierInfo *FieldName, SourceLocation DotLoc,
- SourceLocation FieldLoc)
- : Kind(FieldDesignator) {
- new (&Field) DesignatedInitExpr::FieldDesignator;
- Field.NameOrField = reinterpret_cast<uintptr_t>(FieldName) | 0x01;
- Field.DotLoc = DotLoc;
- Field.FieldLoc = FieldLoc;
- }
-
- /// Initializes an array designator.
- Designator(unsigned Index, SourceLocation LBracketLoc,
- SourceLocation RBracketLoc)
- : Kind(ArrayDesignator) {
- new (&ArrayOrRange) DesignatedInitExpr::ArrayOrRangeDesignator;
- ArrayOrRange.Index = Index;
- ArrayOrRange.LBracketLoc = LBracketLoc;
- ArrayOrRange.EllipsisLoc = SourceLocation();
- ArrayOrRange.RBracketLoc = RBracketLoc;
- }
-
- /// Initializes a GNU array-range designator.
- Designator(unsigned Index, SourceLocation LBracketLoc,
- SourceLocation EllipsisLoc, SourceLocation RBracketLoc)
- : Kind(ArrayRangeDesignator) {
- new (&ArrayOrRange) DesignatedInitExpr::ArrayOrRangeDesignator;
- ArrayOrRange.Index = Index;
- ArrayOrRange.LBracketLoc = LBracketLoc;
- ArrayOrRange.EllipsisLoc = EllipsisLoc;
- ArrayOrRange.RBracketLoc = RBracketLoc;
- }
-
bool isFieldDesignator() const { return Kind == FieldDesignator; }
bool isArrayDesignator() const { return Kind == ArrayDesignator; }
bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
- IdentifierInfo *getFieldName() const;
+ //===------------------------------------------------------------------===//
+ // FieldDesignatorInfo
+
+ /// Creates a field designator.
+ static Designator CreateFieldDesignator(const IdentifierInfo *FieldName,
+ SourceLocation DotLoc,
+ SourceLocation FieldLoc) {
+ Designator D(FieldDesignator);
+ new (&D.FieldInfo) FieldDesignatorInfo(FieldName, DotLoc, FieldLoc);
+ return D;
+ }
- FieldDecl *getField() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- if (Field.NameOrField & 0x01)
+ const IdentifierInfo *getFieldName() const;
+
+ FieldDecl *getFieldDecl() const {
+ assert(isFieldDesignator() && "Only valid on a field designator");
+ if (FieldInfo.NameOrField & 0x01)
return nullptr;
- else
- return reinterpret_cast<FieldDecl *>(Field.NameOrField);
+ return reinterpret_cast<FieldDecl *>(FieldInfo.NameOrField);
}
- void setField(FieldDecl *FD) {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- Field.NameOrField = reinterpret_cast<uintptr_t>(FD);
+ void setFieldDecl(FieldDecl *FD) {
+ assert(isFieldDesignator() && "Only valid on a field designator");
+ FieldInfo.NameOrField = reinterpret_cast<uintptr_t>(FD);
}
SourceLocation getDotLoc() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- return Field.DotLoc;
+ assert(isFieldDesignator() && "Only valid on a field designator");
+ return FieldInfo.DotLoc;
}
SourceLocation getFieldLoc() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- return Field.FieldLoc;
+ assert(isFieldDesignator() && "Only valid on a field designator");
+ return FieldInfo.FieldLoc;
}
- SourceLocation getLBracketLoc() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+ //===------------------------------------------------------------------===//
+ // ArrayOrRangeDesignator
+
+ /// Creates an array designator.
+ static Designator CreateArrayDesignator(unsigned Index,
+ SourceLocation LBracketLoc,
+ SourceLocation RBracketLoc) {
+ Designator D(ArrayDesignator);
+ new (&D.ArrayOrRangeInfo) ArrayOrRangeDesignatorInfo(Index, LBracketLoc,
+ RBracketLoc);
+ return D;
+ }
+
+ /// Creates a GNU array-range designator.
+ static Designator CreateArrayRangeDesignator(unsigned Index,
+ SourceLocation LBracketLoc,
+ SourceLocation EllipsisLoc,
+ SourceLocation RBracketLoc) {
+ Designator D(ArrayRangeDesignator);
+ new (&D.ArrayOrRangeInfo) ArrayOrRangeDesignatorInfo(Index, LBracketLoc,
+ EllipsisLoc,
+ RBracketLoc);
+ return D;
+ }
+
+ unsigned getArrayIndex() const {
+ assert((isArrayDesignator() || isArrayRangeDesignator()) &&
"Only valid on an array or array-range designator");
- return ArrayOrRange.LBracketLoc;
+ return ArrayOrRangeInfo.Index;
}
- SourceLocation getRBracketLoc() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+ SourceLocation getLBracketLoc() const {
+ assert((isArrayDesignator() || isArrayRangeDesignator()) &&
"Only valid on an array or array-range designator");
- return ArrayOrRange.RBracketLoc;
+ return ArrayOrRangeInfo.LBracketLoc;
}
SourceLocation getEllipsisLoc() const {
- assert(Kind == ArrayRangeDesignator &&
+ assert(isArrayRangeDesignator() &&
"Only valid on an array-range designator");
- return ArrayOrRange.EllipsisLoc;
+ return ArrayOrRangeInfo.EllipsisLoc;
}
- unsigned getFirstExprIndex() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+ SourceLocation getRBracketLoc() const {
+ assert((isArrayDesignator() || isArrayRangeDesignator()) &&
"Only valid on an array or array-range designator");
- return ArrayOrRange.Index;
+ return ArrayOrRangeInfo.RBracketLoc;
}
SourceLocation getBeginLoc() const LLVM_READONLY {
- if (Kind == FieldDesignator)
- return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
- else
- return getLBracketLoc();
+ if (isFieldDesignator())
+ return getDotLoc().isInvalid() ? getFieldLoc() : getDotLoc();
+ return getLBracketLoc();
}
+
SourceLocation getEndLoc() const LLVM_READONLY {
- return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
+ return isFieldDesignator() ? getFieldLoc() : getRBracketLoc();
}
+
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getBeginLoc(), getEndLoc());
}
@@ -5563,9 +5636,7 @@ public:
return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>());
}
- ArrayRef<Expr *> exprs() {
- return llvm::makeArrayRef(getExprs(), getNumExprs());
- }
+ ArrayRef<Expr *> exprs() { return llvm::ArrayRef(getExprs(), getNumExprs()); }
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -5613,6 +5684,12 @@ public:
/// which names a dependent type in its association list is result-dependent,
/// which means that the choice of result expression is dependent.
/// Result-dependent generic associations are both type- and value-dependent.
+///
+/// We also allow an extended form in both C and C++ where the controlling
+/// predicate for the selection expression is a type rather than an expression.
+/// This type argument form does not perform any conversions for the
+/// controlling type, which makes it suitable for use with qualified type
+/// associations, which is not possible with the expression form.
class GenericSelectionExpr final
: public Expr,
private llvm::TrailingObjects<GenericSelectionExpr, Stmt *,
@@ -5625,31 +5702,68 @@ class GenericSelectionExpr final
/// expression in the case where the generic selection expression is not
/// result-dependent. The result index is equal to ResultDependentIndex
/// if and only if the generic selection expression is result-dependent.
- unsigned NumAssocs, ResultIndex;
+ unsigned NumAssocs : 15;
+ unsigned ResultIndex : 15; // NB: ResultDependentIndex is tied to this width.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsExprPredicate : 1;
enum : unsigned {
- ResultDependentIndex = std::numeric_limits<unsigned>::max(),
- ControllingIndex = 0,
- AssocExprStartIndex = 1
+ ResultDependentIndex = 0x7FFF
};
+ unsigned getIndexOfControllingExpression() const {
+ // If controlled by an expression, the first offset into the Stmt *
+ // trailing array is the controlling expression, the associated expressions
+ // follow this.
+ assert(isExprPredicate() && "Asking for the controlling expression of a "
+ "selection expr predicated by a type");
+ return 0;
+ }
+
+ unsigned getIndexOfControllingType() const {
+ // If controlled by a type, the first offset into the TypeSourceInfo *
+ // trailing array is the controlling type, the associated types follow this.
+ assert(isTypePredicate() && "Asking for the controlling type of a "
+ "selection expr predicated by an expression");
+ return 0;
+ }
+
+ unsigned getIndexOfStartOfAssociatedExprs() const {
+ // If the predicate is a type, then the associated expressions are the only
+ // Stmt * in the trailing array, otherwise we need to offset past the
+ // predicate expression.
+ return (int)isExprPredicate();
+ }
+
+ unsigned getIndexOfStartOfAssociatedTypes() const {
+ // If the predicate is a type, then the associated types follow it in the
+ // trailing array. Otherwise, the associated types are the only
+ // TypeSourceInfo * in the trailing array.
+ return (int)isTypePredicate();
+ }
+
+
/// The location of the "default" and of the right parenthesis.
SourceLocation DefaultLoc, RParenLoc;
// GenericSelectionExpr is followed by several trailing objects.
// They are (in order):
//
- // * A single Stmt * for the controlling expression.
+ // * A single Stmt * for the controlling expression or a TypeSourceInfo * for
+ // the controlling type, depending on the result of isTypePredicate() or
+ // isExprPredicate().
// * An array of getNumAssocs() Stmt * for the association expressions.
// * An array of getNumAssocs() TypeSourceInfo *, one for each of the
// association expressions.
unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
// Add one to account for the controlling expression; the remainder
// are the associated expressions.
- return 1 + getNumAssocs();
+ return getNumAssocs() + (int)isExprPredicate();
}
unsigned numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
- return getNumAssocs();
+ // Add one to account for the controlling type predicate, the remainder
+ // are the associated types.
+ return getNumAssocs() + (int)isTypePredicate();
}
template <bool Const> class AssociationIteratorTy;
@@ -5730,7 +5844,8 @@ class GenericSelectionExpr final
bool operator==(AssociationIteratorTy Other) const { return E == Other.E; }
}; // class AssociationIterator
- /// Build a non-result-dependent generic selection expression.
+ /// Build a non-result-dependent generic selection expression accepting an
+ /// expression predicate.
GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
Expr *ControllingExpr,
ArrayRef<TypeSourceInfo *> AssocTypes,
@@ -5739,7 +5854,8 @@ class GenericSelectionExpr final
bool ContainsUnexpandedParameterPack,
unsigned ResultIndex);
- /// Build a result-dependent generic selection expression.
+ /// Build a result-dependent generic selection expression accepting an
+ /// expression predicate.
GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
Expr *ControllingExpr,
ArrayRef<TypeSourceInfo *> AssocTypes,
@@ -5747,11 +5863,31 @@ class GenericSelectionExpr final
SourceLocation RParenLoc,
bool ContainsUnexpandedParameterPack);
+ /// Build a non-result-dependent generic selection expression accepting a
+ /// type predicate.
+ GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
+ TypeSourceInfo *ControllingType,
+ ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack,
+ unsigned ResultIndex);
+
+ /// Build a result-dependent generic selection expression accepting a type
+ /// predicate.
+ GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
+ TypeSourceInfo *ControllingType,
+ ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack);
+
/// Build an empty generic selection expression for deserialization.
explicit GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs);
public:
- /// Create a non-result-dependent generic selection expression.
+ /// Create a non-result-dependent generic selection expression accepting an
+ /// expression predicate.
static GenericSelectionExpr *
Create(const ASTContext &Context, SourceLocation GenericLoc,
Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes,
@@ -5759,13 +5895,31 @@ public:
SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack,
unsigned ResultIndex);
- /// Create a result-dependent generic selection expression.
+ /// Create a result-dependent generic selection expression accepting an
+ /// expression predicate.
static GenericSelectionExpr *
Create(const ASTContext &Context, SourceLocation GenericLoc,
Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes,
ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack);
+ /// Create a non-result-dependent generic selection expression accepting a
+ /// type predicate.
+ static GenericSelectionExpr *
+ Create(const ASTContext &Context, SourceLocation GenericLoc,
+ TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack,
+ unsigned ResultIndex);
+
+ /// Create a result-dependent generic selection expression accepting a type
+ /// predicate
+ static GenericSelectionExpr *
+ Create(const ASTContext &Context, SourceLocation GenericLoc,
+ TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack);
+
/// Create an empty generic selection expression for deserialization.
static GenericSelectionExpr *CreateEmpty(const ASTContext &Context,
unsigned NumAssocs);
@@ -5793,32 +5947,56 @@ public:
/// Whether this generic selection is result-dependent.
bool isResultDependent() const { return ResultIndex == ResultDependentIndex; }
+ /// Whether this generic selection uses an expression as its controlling
+ /// argument.
+ bool isExprPredicate() const { return IsExprPredicate; }
+ /// Whether this generic selection uses a type as its controlling argument.
+ bool isTypePredicate() const { return !IsExprPredicate; }
+
/// Return the controlling expression of this generic selection expression.
+ /// Only valid to call if the selection expression used an expression as its
+ /// controlling argument.
Expr *getControllingExpr() {
- return cast<Expr>(getTrailingObjects<Stmt *>()[ControllingIndex]);
+ return cast<Expr>(
+ getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()]);
}
const Expr *getControllingExpr() const {
- return cast<Expr>(getTrailingObjects<Stmt *>()[ControllingIndex]);
+ return cast<Expr>(
+ getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()]);
+ }
+
+ /// Return the controlling type of this generic selection expression. Only
+ /// valid to call if the selection expression used a type as its controlling
+ /// argument.
+ TypeSourceInfo *getControllingType() {
+ return getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()];
+ }
+ const TypeSourceInfo* getControllingType() const {
+ return getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()];
}
/// Return the result expression of this controlling expression. Defined if
/// and only if the generic selection expression is not result-dependent.
Expr *getResultExpr() {
return cast<Expr>(
- getTrailingObjects<Stmt *>()[AssocExprStartIndex + getResultIndex()]);
+ getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
+ getResultIndex()]);
}
const Expr *getResultExpr() const {
return cast<Expr>(
- getTrailingObjects<Stmt *>()[AssocExprStartIndex + getResultIndex()]);
+ getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
+ getResultIndex()]);
}
ArrayRef<Expr *> getAssocExprs() const {
return {reinterpret_cast<Expr *const *>(getTrailingObjects<Stmt *>() +
- AssocExprStartIndex),
+ getIndexOfStartOfAssociatedExprs()),
NumAssocs};
}
ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const {
- return {getTrailingObjects<TypeSourceInfo *>(), NumAssocs};
+ return {getTrailingObjects<TypeSourceInfo *>() +
+ getIndexOfStartOfAssociatedTypes(),
+ NumAssocs};
}
/// Return the Ith association expression with its TypeSourceInfo,
@@ -5827,23 +6005,30 @@ public:
assert(I < getNumAssocs() &&
"Out-of-range index in GenericSelectionExpr::getAssociation!");
return Association(
- cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + I]),
- getTrailingObjects<TypeSourceInfo *>()[I],
+ cast<Expr>(
+ getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
+ I]),
+ getTrailingObjects<
+ TypeSourceInfo *>()[getIndexOfStartOfAssociatedTypes() + I],
!isResultDependent() && (getResultIndex() == I));
}
ConstAssociation getAssociation(unsigned I) const {
assert(I < getNumAssocs() &&
"Out-of-range index in GenericSelectionExpr::getAssociation!");
return ConstAssociation(
- cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + I]),
- getTrailingObjects<TypeSourceInfo *>()[I],
+ cast<Expr>(
+ getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
+ I]),
+ getTrailingObjects<
+ TypeSourceInfo *>()[getIndexOfStartOfAssociatedTypes() + I],
!isResultDependent() && (getResultIndex() == I));
}
association_range associations() {
AssociationIterator Begin(getTrailingObjects<Stmt *>() +
- AssocExprStartIndex,
- getTrailingObjects<TypeSourceInfo *>(),
+ getIndexOfStartOfAssociatedExprs(),
+ getTrailingObjects<TypeSourceInfo *>() +
+ getIndexOfStartOfAssociatedTypes(),
/*Offset=*/0, ResultIndex);
AssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs,
/*Offset=*/NumAssocs, ResultIndex);
@@ -5852,8 +6037,9 @@ public:
const_association_range associations() const {
ConstAssociationIterator Begin(getTrailingObjects<Stmt *>() +
- AssocExprStartIndex,
- getTrailingObjects<TypeSourceInfo *>(),
+ getIndexOfStartOfAssociatedExprs(),
+ getTrailingObjects<TypeSourceInfo *>() +
+ getIndexOfStartOfAssociatedTypes(),
/*Offset=*/0, ResultIndex);
ConstAssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs,
/*Offset=*/NumAssocs, ResultIndex);
@@ -6166,11 +6352,11 @@ public:
return getSubExprsBuffer() + getNumSubExprs();
}
- llvm::iterator_range<semantics_iterator> semantics() {
- return llvm::make_range(semantics_begin(), semantics_end());
+ ArrayRef<Expr*> semantics() {
+ return ArrayRef(semantics_begin(), semantics_end());
}
- llvm::iterator_range<const_semantics_iterator> semantics() const {
- return llvm::make_range(semantics_begin(), semantics_end());
+ ArrayRef<const Expr*> semantics() const {
+ return ArrayRef(semantics_begin(), semantics_end());
}
Expr *getSemanticExpr(unsigned index) {
@@ -6272,7 +6458,7 @@ public:
return cast<Expr>(SubExprs[ORDER_FAIL]);
}
Expr *getVal2() const {
- if (Op == AO__atomic_exchange)
+ if (Op == AO__atomic_exchange || Op == AO__scoped_atomic_exchange)
return cast<Expr>(SubExprs[ORDER_FAIL]);
assert(NumSubExprs > VAL2);
return cast<Expr>(SubExprs[VAL2]);
@@ -6284,6 +6470,16 @@ public:
QualType getValueType() const;
AtomicOp getOp() const { return Op; }
+ StringRef getOpAsString() const {
+ switch (Op) {
+#define BUILTIN(ID, TYPE, ATTRS)
+#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
+ case AO##ID: \
+ return #ID;
+#include "clang/Basic/Builtins.def"
+ }
+ llvm_unreachable("not an atomic operator?");
+ }
unsigned getNumSubExprs() const { return NumSubExprs; }
Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
@@ -6298,10 +6494,14 @@ public:
bool isCmpXChg() const {
return getOp() == AO__c11_atomic_compare_exchange_strong ||
getOp() == AO__c11_atomic_compare_exchange_weak ||
+ getOp() == AO__hip_atomic_compare_exchange_strong ||
getOp() == AO__opencl_atomic_compare_exchange_strong ||
getOp() == AO__opencl_atomic_compare_exchange_weak ||
+ getOp() == AO__hip_atomic_compare_exchange_weak ||
getOp() == AO__atomic_compare_exchange ||
- getOp() == AO__atomic_compare_exchange_n;
+ getOp() == AO__atomic_compare_exchange_n ||
+ getOp() == AO__scoped_atomic_compare_exchange ||
+ getOp() == AO__scoped_atomic_compare_exchange_n;
}
bool isOpenCL() const {
@@ -6331,11 +6531,13 @@ public:
/// \return empty atomic scope model if the atomic op code does not have
/// scope operand.
static std::unique_ptr<AtomicScopeModel> getScopeModel(AtomicOp Op) {
- auto Kind =
- (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max)
- ? AtomicScopeModelKind::OpenCL
- : AtomicScopeModelKind::None;
- return AtomicScopeModel::create(Kind);
+ if (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max)
+ return AtomicScopeModel::create(AtomicScopeModelKind::OpenCL);
+ else if (Op >= AO__hip_atomic_load && Op <= AO__hip_atomic_fetch_max)
+ return AtomicScopeModel::create(AtomicScopeModelKind::HIP);
+ else if (Op >= AO__scoped_atomic_load && Op <= AO__scoped_atomic_fetch_max)
+ return AtomicScopeModel::create(AtomicScopeModelKind::Generic);
+ return AtomicScopeModel::create(AtomicScopeModelKind::None);
}
/// Get atomic scope model.
@@ -6412,7 +6614,7 @@ public:
ArrayRef<Expr *> subExpressions() {
auto *B = getTrailingObjects<Expr *>();
- return llvm::makeArrayRef(B, B + NumExprs);
+ return llvm::ArrayRef(B, B + NumExprs);
}
ArrayRef<const Expr *> subExpressions() const {
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h b/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h
index 161287adce4c..9a7c632c36c5 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h
@@ -40,8 +40,6 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
@@ -52,6 +50,7 @@
#include <cstddef>
#include <cstdint>
#include <memory>
+#include <optional>
namespace clang {
@@ -730,6 +729,11 @@ public:
explicit CXXBoolLiteralExpr(EmptyShell Empty)
: Expr(CXXBoolLiteralExprClass, Empty) {}
+ static CXXBoolLiteralExpr *Create(const ASTContext &C, bool Val, QualType Ty,
+ SourceLocation Loc) {
+ return new (C) CXXBoolLiteralExpr(Val, Ty, Loc);
+ }
+
bool getValue() const { return CXXBoolLiteralExprBits.Value; }
void setValue(bool V) { CXXBoolLiteralExprBits.Value = V; }
@@ -756,6 +760,8 @@ public:
/// The null pointer literal (C++11 [lex.nullptr])
///
/// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr.
+/// This also implements the null pointer literal in C23 (C23 6.4.1) which is
+/// intended to have the same semantics as the feature in C++.
class CXXNullPtrLiteralExpr : public Expr {
public:
CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc)
@@ -1140,9 +1146,8 @@ public:
/// };
/// \endcode
class CXXThisExpr : public Expr {
-public:
- CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit)
- : Expr(CXXThisExprClass, Ty, VK_PRValue, OK_Ordinary) {
+ CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit, ExprValueKind VK)
+ : Expr(CXXThisExprClass, Ty, VK, OK_Ordinary) {
CXXThisExprBits.IsImplicit = IsImplicit;
CXXThisExprBits.Loc = L;
setDependence(computeDependence(this));
@@ -1150,6 +1155,12 @@ public:
CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
+public:
+ static CXXThisExpr *Create(const ASTContext &Ctx, SourceLocation L,
+ QualType Ty, bool IsImplicit);
+
+ static CXXThisExpr *CreateEmpty(const ASTContext &Ctx);
+
SourceLocation getLocation() const { return CXXThisExprBits.Loc; }
void setLocation(SourceLocation L) { CXXThisExprBits.Loc = L; }
@@ -1238,8 +1249,12 @@ public:
/// This wraps up a function call argument that was created from the
/// corresponding parameter's default argument, when the call did not
/// explicitly supply arguments for all of the parameters.
-class CXXDefaultArgExpr final : public Expr {
+class CXXDefaultArgExpr final
+ : public Expr,
+ private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {
friend class ASTStmtReader;
+ friend class ASTReader;
+ friend TrailingObjects;
/// The parameter whose default is being used.
ParmVarDecl *Param;
@@ -1248,7 +1263,7 @@ class CXXDefaultArgExpr final : public Expr {
DeclContext *UsedContext;
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param,
- DeclContext *UsedContext)
+ Expr *RewrittenExpr, DeclContext *UsedContext)
: Expr(SC,
Param->hasUnparsedDefaultArg()
? Param->getType().getNonReferenceType()
@@ -1257,28 +1272,54 @@ class CXXDefaultArgExpr final : public Expr {
Param->getDefaultArg()->getObjectKind()),
Param(Param), UsedContext(UsedContext) {
CXXDefaultArgExprBits.Loc = Loc;
+ CXXDefaultArgExprBits.HasRewrittenInit = RewrittenExpr != nullptr;
+ if (RewrittenExpr)
+ *getTrailingObjects<Expr *>() = RewrittenExpr;
setDependence(computeDependence(this));
}
+ CXXDefaultArgExpr(EmptyShell Empty, bool HasRewrittenInit)
+ : Expr(CXXDefaultArgExprClass, Empty) {
+ CXXDefaultArgExprBits.HasRewrittenInit = HasRewrittenInit;
+ }
+
public:
- CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
+ static CXXDefaultArgExpr *CreateEmpty(const ASTContext &C,
+ bool HasRewrittenInit);
// \p Param is the parameter whose default argument is used by this
// expression.
static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
- ParmVarDecl *Param,
- DeclContext *UsedContext) {
- return new (C)
- CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, UsedContext);
- }
-
+ ParmVarDecl *Param, Expr *RewrittenExpr,
+ DeclContext *UsedContext);
// Retrieve the parameter that the argument was created from.
const ParmVarDecl *getParam() const { return Param; }
ParmVarDecl *getParam() { return Param; }
- // Retrieve the actual argument to the function call.
- const Expr *getExpr() const { return getParam()->getDefaultArg(); }
- Expr *getExpr() { return getParam()->getDefaultArg(); }
+ bool hasRewrittenInit() const {
+ return CXXDefaultArgExprBits.HasRewrittenInit;
+ }
+
+ // Retrieve the argument to the function call.
+ Expr *getExpr();
+ const Expr *getExpr() const {
+ return const_cast<CXXDefaultArgExpr *>(this)->getExpr();
+ }
+
+ Expr *getRewrittenExpr() {
+ return hasRewrittenInit() ? *getTrailingObjects<Expr *>() : nullptr;
+ }
+
+ const Expr *getRewrittenExpr() const {
+ return const_cast<CXXDefaultArgExpr *>(this)->getRewrittenExpr();
+ }
+
+ // Retrieve the rewritten init expression (for an init expression containing
+ // immediate calls) with the top level FullExpr and ConstantExpr stripped off.
+ Expr *getAdjustedRewrittenExpr();
+ const Expr *getAdjustedRewrittenExpr() const {
+ return const_cast<CXXDefaultArgExpr *>(this)->getAdjustedRewrittenExpr();
+ }
const DeclContext *getUsedContext() const { return UsedContext; }
DeclContext *getUsedContext() { return UsedContext; }
@@ -1315,10 +1356,13 @@ public:
/// is implicitly used in a mem-initializer-list in a constructor
/// (C++11 [class.base.init]p8) or in aggregate initialization
/// (C++1y [dcl.init.aggr]p7).
-class CXXDefaultInitExpr : public Expr {
- friend class ASTReader;
- friend class ASTStmtReader;
+class CXXDefaultInitExpr final
+ : public Expr,
+ private llvm::TrailingObjects<CXXDefaultInitExpr, Expr *> {
+ friend class ASTStmtReader;
+ friend class ASTReader;
+ friend TrailingObjects;
/// The field whose default is being used.
FieldDecl *Field;
@@ -1326,16 +1370,25 @@ class CXXDefaultInitExpr : public Expr {
DeclContext *UsedContext;
CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc,
- FieldDecl *Field, QualType Ty, DeclContext *UsedContext);
+ FieldDecl *Field, QualType Ty, DeclContext *UsedContext,
+ Expr *RewrittenInitExpr);
- CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
+ CXXDefaultInitExpr(EmptyShell Empty, bool HasRewrittenInit)
+ : Expr(CXXDefaultInitExprClass, Empty) {
+ CXXDefaultInitExprBits.HasRewrittenInit = HasRewrittenInit;
+ }
public:
+ static CXXDefaultInitExpr *CreateEmpty(const ASTContext &C,
+ bool HasRewrittenInit);
/// \p Field is the non-static data member whose default initializer is used
/// by this expression.
static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc,
- FieldDecl *Field, DeclContext *UsedContext) {
- return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType(), UsedContext);
+ FieldDecl *Field, DeclContext *UsedContext,
+ Expr *RewrittenInitExpr);
+
+ bool hasRewrittenInit() const {
+ return CXXDefaultInitExprBits.HasRewrittenInit;
}
/// Get the field whose initializer will be used.
@@ -1343,13 +1396,23 @@ public:
const FieldDecl *getField() const { return Field; }
/// Get the initialization expression that will be used.
+ Expr *getExpr();
const Expr *getExpr() const {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
+ return const_cast<CXXDefaultInitExpr *>(this)->getExpr();
}
- Expr *getExpr() {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
+
+ /// Retrieve the initializing expression with evaluated immediate calls, if
+ /// any.
+ const Expr *getRewrittenExpr() const {
+ assert(hasRewrittenInit() && "expected a rewritten init expression");
+ return *getTrailingObjects<Expr *>();
+ }
+
+ /// Retrieve the initializing expression with evaluated immediate calls, if
+ /// any.
+ Expr *getRewrittenExpr() {
+ assert(hasRewrittenInit() && "expected a rewritten init expression");
+ return *getTrailingObjects<Expr *>();
}
const DeclContext *getUsedContext() const { return UsedContext; }
@@ -1456,19 +1519,17 @@ public:
}
};
+enum class CXXConstructionKind {
+ Complete,
+ NonVirtualBase,
+ VirtualBase,
+ Delegating
+};
+
/// Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
friend class ASTStmtReader;
-public:
- enum ConstructionKind {
- CK_Complete,
- CK_NonVirtualBase,
- CK_VirtualBase,
- CK_Delegating
- };
-
-private:
/// A pointer to the constructor which will be ultimately called.
CXXConstructorDecl *Constructor;
@@ -1504,7 +1565,7 @@ protected:
CXXConstructorDecl *Ctor, bool Elidable,
ArrayRef<Expr *> Args, bool HadMultipleCandidates,
bool ListInitialization, bool StdInitListInitialization,
- bool ZeroInitialization, ConstructionKind ConstructKind,
+ bool ZeroInitialization, CXXConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
/// Build an empty C++ construction expression.
@@ -1523,7 +1584,7 @@ public:
CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args,
bool HadMultipleCandidates, bool ListInitialization,
bool StdInitListInitialization, bool ZeroInitialization,
- ConstructionKind ConstructKind, SourceRange ParenOrBraceRange);
+ CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange);
/// Create an empty C++ construction expression.
static CXXConstructExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs);
@@ -1577,11 +1638,12 @@ public:
/// Determine whether this constructor is actually constructing
/// a base class (rather than a complete object).
- ConstructionKind getConstructionKind() const {
- return static_cast<ConstructionKind>(CXXConstructExprBits.ConstructionKind);
+ CXXConstructionKind getConstructionKind() const {
+ return static_cast<CXXConstructionKind>(
+ CXXConstructExprBits.ConstructionKind);
}
- void setConstructionKind(ConstructionKind CK) {
- CXXConstructExprBits.ConstructionKind = CK;
+ void setConstructionKind(CXXConstructionKind CK) {
+ CXXConstructExprBits.ConstructionKind = llvm::to_underlying(CK);
}
using arg_iterator = ExprIterator;
@@ -1623,6 +1685,14 @@ public:
getArgs()[Arg] = ArgExpr;
}
+ bool isImmediateEscalating() const {
+ return CXXConstructExprBits.IsImmediateEscalating;
+ }
+
+ void setIsImmediateEscalating(bool Set) {
+ CXXConstructExprBits.IsImmediateEscalating = Set;
+ }
+
SourceLocation getBeginLoc() const LLVM_READONLY;
SourceLocation getEndLoc() const LLVM_READONLY;
SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; }
@@ -1656,10 +1726,12 @@ private:
SourceLocation Loc;
/// Whether this is the construction of a virtual base.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ConstructsVirtualBase : 1;
/// Whether the constructor is inherited from a virtual base class of the
/// class that we construct.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InheritedFromVirtualBase : 1;
public:
@@ -1688,9 +1760,9 @@ public:
/// Determine whether this constructor is actually constructing
/// a base class (rather than a complete object).
bool constructsVBase() const { return ConstructsVirtualBase; }
- CXXConstructExpr::ConstructionKind getConstructionKind() const {
- return ConstructsVirtualBase ? CXXConstructExpr::CK_VirtualBase
- : CXXConstructExpr::CK_NonVirtualBase;
+ CXXConstructionKind getConstructionKind() const {
+ return ConstructsVirtualBase ? CXXConstructionKind::VirtualBase
+ : CXXConstructionKind::NonVirtualBase;
}
/// Determine whether the inherited constructor is inherited from a
@@ -2134,6 +2206,17 @@ public:
}
};
+enum class CXXNewInitializationStyle {
+ /// New-expression has no initializer as written.
+ None,
+
+ /// New-expression has a C++98 paren-delimited initializer.
+ Parens,
+
+ /// New-expression has a C++11 list-initializer.
+ Braces
+};
+
/// Represents a new-expression for memory allocation and constructor
/// calls, e.g: "new CXXNewExpr(foo)".
class CXXNewExpr final
@@ -2187,25 +2270,12 @@ class CXXNewExpr final
return isParenTypeId();
}
-public:
- enum InitializationStyle {
- /// New-expression has no initializer as written.
- NoInit,
-
- /// New-expression has a C++98 paren-delimited initializer.
- CallInit,
-
- /// New-expression has a C++11 list-initializer.
- ListInit
- };
-
-private:
/// Build a c++ new expression.
CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
- SourceRange TypeIdParens, Optional<Expr *> ArraySize,
- InitializationStyle InitializationStyle, Expr *Initializer,
+ SourceRange TypeIdParens, std::optional<Expr *> ArraySize,
+ CXXNewInitializationStyle InitializationStyle, Expr *Initializer,
QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
SourceRange DirectInitRange);
@@ -2219,8 +2289,8 @@ public:
Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew,
FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
- SourceRange TypeIdParens, Optional<Expr *> ArraySize,
- InitializationStyle InitializationStyle, Expr *Initializer,
+ SourceRange TypeIdParens, std::optional<Expr *> ArraySize,
+ CXXNewInitializationStyle InitializationStyle, Expr *Initializer,
QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
SourceRange DirectInitRange);
@@ -2261,15 +2331,32 @@ public:
bool isArray() const { return CXXNewExprBits.IsArray; }
- Optional<Expr *> getArraySize() {
+ /// This might return std::nullopt even if isArray() returns true,
+ /// since there might not be an array size expression.
+ /// If the result is not std::nullopt, it will never wrap a nullptr.
+ std::optional<Expr *> getArraySize() {
if (!isArray())
- return None;
- return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]);
+ return std::nullopt;
+
+ if (auto *Result =
+ cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]))
+ return Result;
+
+ return std::nullopt;
}
- Optional<const Expr *> getArraySize() const {
+
+ /// This might return std::nullopt even if isArray() returns true,
+ /// since there might not be an array size expression.
+ /// If the result is not std::nullopt, it will never wrap a nullptr.
+ std::optional<const Expr *> getArraySize() const {
if (!isArray())
- return None;
- return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]);
+ return std::nullopt;
+
+ if (auto *Result =
+ cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]))
+ return Result;
+
+ return std::nullopt;
}
unsigned getNumPlacementArgs() const {
@@ -2298,16 +2385,12 @@ public:
bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; }
/// Whether this new-expression has any initializer at all.
- bool hasInitializer() const {
- return CXXNewExprBits.StoredInitializationStyle > 0;
- }
+ bool hasInitializer() const { return CXXNewExprBits.HasInitializer; }
/// The kind of initializer this new-expression has.
- InitializationStyle getInitializationStyle() const {
- if (CXXNewExprBits.StoredInitializationStyle == 0)
- return NoInit;
- return static_cast<InitializationStyle>(
- CXXNewExprBits.StoredInitializationStyle - 1);
+ CXXNewInitializationStyle getInitializationStyle() const {
+ return static_cast<CXXNewInitializationStyle>(
+ CXXNewExprBits.StoredInitializationStyle);
}
/// The initializer of this new-expression.
@@ -2522,6 +2605,7 @@ class CXXPseudoDestructorExpr : public Expr {
/// Whether the operator was an arrow ('->'); otherwise, it was a
/// period ('.').
+ LLVM_PREFERRED_TYPE(bool)
bool IsArrow : 1;
/// The location of the '.' or '->' operator.
@@ -2721,8 +2805,7 @@ public:
/// Retrieve the argument types.
ArrayRef<TypeSourceInfo *> getArgs() const {
- return llvm::makeArrayRef(getTrailingObjects<TypeSourceInfo *>(),
- getNumArgs());
+ return llvm::ArrayRef(getTrailingObjects<TypeSourceInfo *>(), getNumArgs());
}
SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
@@ -2752,6 +2835,7 @@ public:
/// \endcode
class ArrayTypeTraitExpr : public Expr {
/// The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
+ LLVM_PREFERRED_TYPE(ArrayTypeTrait)
unsigned ATT : 2;
/// The value of the type trait. Unspecified if dependent.
@@ -2822,9 +2906,11 @@ public:
/// \endcode
class ExpressionTraitExpr : public Expr {
/// The trait. A ExpressionTrait enum in MSVC compatible unsigned.
+ LLVM_PREFERRED_TYPE(ExpressionTrait)
unsigned ET : 31;
/// The value of the type trait. Unspecified if dependent.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Value : 1;
/// The location of the type trait keyword.
@@ -3104,7 +3190,8 @@ class UnresolvedLookupExpr final
const DeclarationNameInfo &NameInfo, bool RequiresADL,
bool Overloaded,
const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End,
+ bool KnownDependent);
UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults,
bool HasTemplateKWAndArgsInfo);
@@ -3124,12 +3211,15 @@ public:
const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+ // After canonicalization, there may be dependent template arguments in
+ // CanonicalConverted But none of Args is dependent. When any of
+ // CanonicalConverted dependent, KnownDependent is true.
static UnresolvedLookupExpr *
Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo, bool RequiresADL,
const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
+ UnresolvedSetIterator End, bool KnownDependent);
static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context,
unsigned NumResults,
@@ -3368,8 +3458,7 @@ public:
ArrayRef<CleanupObject> objects);
ArrayRef<CleanupObject> getObjects() const {
- return llvm::makeArrayRef(getTrailingObjects<CleanupObject>(),
- getNumObjects());
+ return llvm::ArrayRef(getTrailingObjects<CleanupObject>(), getNumObjects());
}
unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
@@ -3431,8 +3520,9 @@ class CXXUnresolvedConstructExpr final
friend class ASTStmtReader;
friend TrailingObjects;
- /// The type being constructed.
- TypeSourceInfo *TSI;
+ /// The type being constructed, and whether the construct expression models
+ /// list initialization or not.
+ llvm::PointerIntPair<TypeSourceInfo *, 1> TypeAndInitForm;
/// The location of the left parentheses ('(').
SourceLocation LParenLoc;
@@ -3442,30 +3532,31 @@ class CXXUnresolvedConstructExpr final
CXXUnresolvedConstructExpr(QualType T, TypeSourceInfo *TSI,
SourceLocation LParenLoc, ArrayRef<Expr *> Args,
- SourceLocation RParenLoc);
+ SourceLocation RParenLoc, bool IsListInit);
CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(CXXUnresolvedConstructExprClass, Empty), TSI(nullptr) {
+ : Expr(CXXUnresolvedConstructExprClass, Empty) {
CXXUnresolvedConstructExprBits.NumArgs = NumArgs;
}
public:
- static CXXUnresolvedConstructExpr *Create(const ASTContext &Context,
- QualType T, TypeSourceInfo *TSI,
- SourceLocation LParenLoc,
- ArrayRef<Expr *> Args,
- SourceLocation RParenLoc);
+ static CXXUnresolvedConstructExpr *
+ Create(const ASTContext &Context, QualType T, TypeSourceInfo *TSI,
+ SourceLocation LParenLoc, ArrayRef<Expr *> Args,
+ SourceLocation RParenLoc, bool IsListInit);
static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &Context,
unsigned NumArgs);
/// Retrieve the type that is being constructed, as specified
/// in the source code.
- QualType getTypeAsWritten() const { return TSI->getType(); }
+ QualType getTypeAsWritten() const { return getTypeSourceInfo()->getType(); }
/// Retrieve the type source information for the type being
/// constructed.
- TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
+ TypeSourceInfo *getTypeSourceInfo() const {
+ return TypeAndInitForm.getPointer();
+ }
/// Retrieve the location of the left parentheses ('(') that
/// precedes the argument list.
@@ -3480,7 +3571,7 @@ public:
/// Determine whether this expression models list-initialization.
/// If so, there will be exactly one subexpression, which will be
/// an InitListExpr.
- bool isListInitialization() const { return LParenLoc.isInvalid(); }
+ bool isListInitialization() const { return TypeAndInitForm.getInt(); }
/// Retrieve the number of arguments.
unsigned getNumArgs() const { return CXXUnresolvedConstructExprBits.NumArgs; }
@@ -4065,7 +4156,7 @@ class PackExpansionExpr : public Expr {
public:
PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions)
+ std::optional<unsigned> NumExpansions)
: Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
Pattern->getObjectKind()),
EllipsisLoc(EllipsisLoc),
@@ -4088,11 +4179,11 @@ public:
/// Determine the number of expansions that will be produced when
/// this pack expansion is instantiated, if already known.
- Optional<unsigned> getNumExpansions() const {
+ std::optional<unsigned> getNumExpansions() const {
if (NumExpansions)
return NumExpansions - 1;
- return None;
+ return std::nullopt;
}
SourceLocation getBeginLoc() const LLVM_READONLY {
@@ -4159,7 +4250,7 @@ class SizeOfPackExpr final
/// the given parameter pack.
SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
SourceLocation PackLoc, SourceLocation RParenLoc,
- Optional<unsigned> Length,
+ std::optional<unsigned> Length,
ArrayRef<TemplateArgument> PartialArgs)
: Expr(SizeOfPackExprClass, SizeType, VK_PRValue, OK_Ordinary),
OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
@@ -4177,11 +4268,11 @@ class SizeOfPackExpr final
: Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs) {}
public:
- static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc,
- NamedDecl *Pack, SourceLocation PackLoc,
- SourceLocation RParenLoc,
- Optional<unsigned> Length = None,
- ArrayRef<TemplateArgument> PartialArgs = None);
+ static SizeOfPackExpr *
+ Create(ASTContext &Context, SourceLocation OperatorLoc, NamedDecl *Pack,
+ SourceLocation PackLoc, SourceLocation RParenLoc,
+ std::optional<unsigned> Length = std::nullopt,
+ ArrayRef<TemplateArgument> PartialArgs = std::nullopt);
static SizeOfPackExpr *CreateDeserialized(ASTContext &Context,
unsigned NumPartialArgs);
@@ -4220,7 +4311,7 @@ public:
ArrayRef<TemplateArgument> getPartialArguments() const {
assert(isPartiallySubstituted());
const auto *Args = getTrailingObjects<TemplateArgument>();
- return llvm::makeArrayRef(Args, Args + Length);
+ return llvm::ArrayRef(Args, Args + Length);
}
SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; }
@@ -4246,24 +4337,30 @@ class SubstNonTypeTemplateParmExpr : public Expr {
friend class ASTReader;
friend class ASTStmtReader;
- /// The replaced parameter and a flag indicating if it was a reference
+ /// The replacement expression.
+ Stmt *Replacement;
+
+ /// The associated declaration and a flag indicating if it was a reference
/// parameter. For class NTTPs, we can't determine that based on the value
/// category alone.
- llvm::PointerIntPair<NonTypeTemplateParmDecl*, 1, bool> ParamAndRef;
+ llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndRef;
- /// The replacement expression.
- Stmt *Replacement;
+ unsigned Index : 15;
+ unsigned PackIndex : 16;
explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
: Expr(SubstNonTypeTemplateParmExprClass, Empty) {}
public:
SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind,
- SourceLocation Loc,
- NonTypeTemplateParmDecl *Param, bool RefParam,
- Expr *Replacement)
+ SourceLocation Loc, Expr *Replacement,
+ Decl *AssociatedDecl, unsigned Index,
+ std::optional<unsigned> PackIndex, bool RefParam)
: Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary),
- ParamAndRef(Param, RefParam), Replacement(Replacement) {
+ Replacement(Replacement),
+ AssociatedDeclAndRef(AssociatedDecl, RefParam), Index(Index),
+ PackIndex(PackIndex ? *PackIndex + 1 : 0) {
+ assert(AssociatedDecl != nullptr);
SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
setDependence(computeDependence(this));
}
@@ -4276,11 +4373,23 @@ public:
Expr *getReplacement() const { return cast<Expr>(Replacement); }
- NonTypeTemplateParmDecl *getParameter() const {
- return ParamAndRef.getPointer();
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will own a set of template parameters.
+ Decl *getAssociatedDecl() const { return AssociatedDeclAndRef.getPointer(); }
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getParameter()->getIndex()`.
+ unsigned getIndex() const { return Index; }
+
+ std::optional<unsigned> getPackIndex() const {
+ if (PackIndex == 0)
+ return std::nullopt;
+ return PackIndex - 1;
}
- bool isReferenceParameter() const { return ParamAndRef.getInt(); }
+ NonTypeTemplateParmDecl *getParameter() const;
+
+ bool isReferenceParameter() const { return AssociatedDeclAndRef.getInt(); }
/// Determine the substituted type of the template parameter.
QualType getParameterType(const ASTContext &Ctx) const;
@@ -4314,14 +4423,16 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
friend class ASTStmtReader;
/// The non-type template parameter pack itself.
- NonTypeTemplateParmDecl *Param;
+ Decl *AssociatedDecl;
/// A pointer to the set of template arguments that this
/// parameter pack is instantiated with.
const TemplateArgument *Arguments;
/// The number of template arguments in \c Arguments.
- unsigned NumArguments;
+ unsigned NumArguments : 16;
+
+ unsigned Index : 16;
/// The location of the non-type template parameter pack reference.
SourceLocation NameLoc;
@@ -4330,14 +4441,21 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
: Expr(SubstNonTypeTemplateParmPackExprClass, Empty) {}
public:
- SubstNonTypeTemplateParmPackExpr(QualType T,
- ExprValueKind ValueKind,
- NonTypeTemplateParmDecl *Param,
+ SubstNonTypeTemplateParmPackExpr(QualType T, ExprValueKind ValueKind,
SourceLocation NameLoc,
- const TemplateArgument &ArgPack);
+ const TemplateArgument &ArgPack,
+ Decl *AssociatedDecl, unsigned Index);
+
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will own a set of template parameters.
+ Decl *getAssociatedDecl() const { return AssociatedDecl; }
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getParameterPack()->getIndex()`.
+ unsigned getIndex() const { return Index; }
/// Retrieve the non-type template parameter pack being substituted.
- NonTypeTemplateParmDecl *getParameterPack() const { return Param; }
+ NonTypeTemplateParmDecl *getParameterPack() const;
/// Retrieve the location of the parameter pack name.
SourceLocation getParameterPackLocation() const { return NameLoc; }
@@ -4590,7 +4708,7 @@ public:
CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode,
SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc,
- Optional<unsigned> NumExpansions)
+ std::optional<unsigned> NumExpansions)
: Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary),
LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
@@ -4627,10 +4745,10 @@ public:
SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
BinaryOperatorKind getOperator() const { return Opcode; }
- Optional<unsigned> getNumExpansions() const {
+ std::optional<unsigned> getNumExpansions() const {
if (NumExpansions)
return NumExpansions - 1;
- return None;
+ return std::nullopt;
}
SourceLocation getBeginLoc() const LLVM_READONLY {
@@ -4663,6 +4781,140 @@ public:
}
};
+/// Represents a list-initialization with parenthesis.
+///
+/// As per P0960R3, this is a C++20 feature that allows aggregate to
+/// be initialized with a parenthesized list of values:
+/// ```
+/// struct A {
+/// int a;
+/// double b;
+/// };
+///
+/// void foo() {
+/// A a1(0); // Well-formed in C++20
+/// A a2(1.5, 1.0); // Well-formed in C++20
+/// }
+/// ```
+/// It has some sort of similiarity to braced
+/// list-initialization, with some differences such as
+/// it allows narrowing conversion whilst braced
+/// list-initialization doesn't.
+/// ```
+/// struct A {
+/// char a;
+/// };
+/// void foo() {
+/// A a(1.5); // Well-formed in C++20
+/// A b{1.5}; // Ill-formed !
+/// }
+/// ```
+class CXXParenListInitExpr final
+ : public Expr,
+ private llvm::TrailingObjects<CXXParenListInitExpr, Expr *> {
+ friend class TrailingObjects;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
+ unsigned NumExprs;
+ unsigned NumUserSpecifiedExprs;
+ SourceLocation InitLoc, LParenLoc, RParenLoc;
+ llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
+
+ CXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
+ unsigned NumUserSpecifiedExprs, SourceLocation InitLoc,
+ SourceLocation LParenLoc, SourceLocation RParenLoc)
+ : Expr(CXXParenListInitExprClass, T, getValueKindForType(T), OK_Ordinary),
+ NumExprs(Args.size()), NumUserSpecifiedExprs(NumUserSpecifiedExprs),
+ InitLoc(InitLoc), LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
+ std::copy(Args.begin(), Args.end(), getTrailingObjects<Expr *>());
+ assert(NumExprs >= NumUserSpecifiedExprs &&
+ "number of user specified inits is greater than the number of "
+ "passed inits");
+ setDependence(computeDependence(this));
+ }
+
+ size_t numTrailingObjects(OverloadToken<Expr *>) const { return NumExprs; }
+
+public:
+ static CXXParenListInitExpr *
+ Create(ASTContext &C, ArrayRef<Expr *> Args, QualType T,
+ unsigned NumUserSpecifiedExprs, SourceLocation InitLoc,
+ SourceLocation LParenLoc, SourceLocation RParenLoc);
+
+ static CXXParenListInitExpr *CreateEmpty(ASTContext &C, unsigned numExprs,
+ EmptyShell Empty);
+
+ explicit CXXParenListInitExpr(EmptyShell Empty, unsigned NumExprs)
+ : Expr(CXXParenListInitExprClass, Empty), NumExprs(NumExprs),
+ NumUserSpecifiedExprs(0) {}
+
+ void updateDependence() { setDependence(computeDependence(this)); }
+
+ ArrayRef<Expr *> getInitExprs() {
+ return ArrayRef(getTrailingObjects<Expr *>(), NumExprs);
+ }
+
+ const ArrayRef<Expr *> getInitExprs() const {
+ return ArrayRef(getTrailingObjects<Expr *>(), NumExprs);
+ }
+
+ ArrayRef<Expr *> getUserSpecifiedInitExprs() {
+ return ArrayRef(getTrailingObjects<Expr *>(), NumUserSpecifiedExprs);
+ }
+
+ const ArrayRef<Expr *> getUserSpecifiedInitExprs() const {
+ return ArrayRef(getTrailingObjects<Expr *>(), NumUserSpecifiedExprs);
+ }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
+
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+
+ SourceLocation getInitLoc() const LLVM_READONLY { return InitLoc; }
+
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return SourceRange(getBeginLoc(), getEndLoc());
+ }
+
+ void setArrayFiller(Expr *E) { ArrayFillerOrUnionFieldInit = E; }
+
+ Expr *getArrayFiller() {
+ return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
+ }
+
+ const Expr *getArrayFiller() const {
+ return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
+ }
+
+ void setInitializedFieldInUnion(FieldDecl *FD) {
+ ArrayFillerOrUnionFieldInit = FD;
+ }
+
+ FieldDecl *getInitializedFieldInUnion() {
+ return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
+ }
+
+ const FieldDecl *getInitializedFieldInUnion() const {
+ return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
+ }
+
+ child_range children() {
+ Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
+ return child_range(Begin, Begin + NumExprs);
+ }
+
+ const_child_range children() const {
+ Stmt *const *Begin =
+ reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
+ return const_child_range(Begin, Begin + NumExprs);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXParenListInitExprClass;
+ }
+};
+
/// Represents an expression that might suspend coroutine execution;
/// either a co_await or co_yield expression.
///
@@ -4681,18 +4933,19 @@ class CoroutineSuspendExpr : public Expr {
SourceLocation KeywordLoc;
- enum SubExpr { Common, Ready, Suspend, Resume, Count };
+ enum SubExpr { Operand, Common, Ready, Suspend, Resume, Count };
Stmt *SubExprs[SubExpr::Count];
OpaqueValueExpr *OpaqueValue = nullptr;
public:
- CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common,
- Expr *Ready, Expr *Suspend, Expr *Resume,
+ CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Operand,
+ Expr *Common, Expr *Ready, Expr *Suspend, Expr *Resume,
OpaqueValueExpr *OpaqueValue)
: Expr(SC, Resume->getType(), Resume->getValueKind(),
Resume->getObjectKind()),
KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) {
+ SubExprs[SubExpr::Operand] = Operand;
SubExprs[SubExpr::Common] = Common;
SubExprs[SubExpr::Ready] = Ready;
SubExprs[SubExpr::Suspend] = Suspend;
@@ -4701,10 +4954,11 @@ public:
}
CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty,
- Expr *Common)
+ Expr *Operand, Expr *Common)
: Expr(SC, Ty, VK_PRValue, OK_Ordinary), KeywordLoc(KeywordLoc) {
assert(Common->isTypeDependent() && Ty->isDependentType() &&
"wrong constructor for non-dependent co_await/co_yield expression");
+ SubExprs[SubExpr::Operand] = Operand;
SubExprs[SubExpr::Common] = Common;
SubExprs[SubExpr::Ready] = nullptr;
SubExprs[SubExpr::Suspend] = nullptr;
@@ -4713,14 +4967,13 @@ public:
}
CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
+ SubExprs[SubExpr::Operand] = nullptr;
SubExprs[SubExpr::Common] = nullptr;
SubExprs[SubExpr::Ready] = nullptr;
SubExprs[SubExpr::Suspend] = nullptr;
SubExprs[SubExpr::Resume] = nullptr;
}
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
-
Expr *getCommonExpr() const {
return static_cast<Expr*>(SubExprs[SubExpr::Common]);
}
@@ -4740,10 +4993,17 @@ public:
return static_cast<Expr*>(SubExprs[SubExpr::Resume]);
}
+ // The syntactic operand written in the code
+ Expr *getOperand() const {
+ return static_cast<Expr *>(SubExprs[SubExpr::Operand]);
+ }
+
+ SourceLocation getKeywordLoc() const { return KeywordLoc; }
+
SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
SourceLocation getEndLoc() const LLVM_READONLY {
- return getCommonExpr()->getEndLoc();
+ return getOperand()->getEndLoc();
}
child_range children() {
@@ -4765,28 +5025,24 @@ class CoawaitExpr : public CoroutineSuspendExpr {
friend class ASTStmtReader;
public:
- CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue,
- bool IsImplicit = false)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready,
- Suspend, Resume, OpaqueValue) {
+ CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Common,
+ Expr *Ready, Expr *Suspend, Expr *Resume,
+ OpaqueValueExpr *OpaqueValue, bool IsImplicit = false)
+ : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Common,
+ Ready, Suspend, Resume, OpaqueValue) {
CoawaitBits.IsImplicit = IsImplicit;
}
CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand,
- bool IsImplicit = false)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {
+ Expr *Common, bool IsImplicit = false)
+ : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand,
+ Common) {
CoawaitBits.IsImplicit = IsImplicit;
}
CoawaitExpr(EmptyShell Empty)
: CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
-
bool isImplicit() const { return CoawaitBits.IsImplicit; }
void setIsImplicit(bool value = true) { CoawaitBits.IsImplicit = value; }
@@ -4850,20 +5106,18 @@ class CoyieldExpr : public CoroutineSuspendExpr {
friend class ASTStmtReader;
public:
- CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready,
- Suspend, Resume, OpaqueValue) {}
- CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {}
+ CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Common,
+ Expr *Ready, Expr *Suspend, Expr *Resume,
+ OpaqueValueExpr *OpaqueValue)
+ : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Common,
+ Ready, Suspend, Resume, OpaqueValue) {}
+ CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand,
+ Expr *Common)
+ : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand,
+ Common) {}
CoyieldExpr(EmptyShell Empty)
: CoroutineSuspendExpr(CoyieldExprClass, Empty) {}
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
-
static bool classof(const Stmt *T) {
return T->getStmtClass() == CoyieldExprClass;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h b/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h
index 1544c498ef66..29913fd84c58 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h
@@ -14,19 +14,21 @@
#ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H
#define LLVM_CLANG_AST_EXPRCONCEPTS_H
-#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConcept.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TrailingObjects.h"
-#include <utility>
#include <string>
+#include <utility>
namespace clang {
class ASTStmtReader;
@@ -37,74 +39,91 @@ class ASTStmtWriter;
///
/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
/// specialization of a concept results in a prvalue of type bool.
-class ConceptSpecializationExpr final : public Expr, public ConceptReference,
- private llvm::TrailingObjects<ConceptSpecializationExpr,
- TemplateArgument> {
+class ConceptSpecializationExpr final : public Expr {
+ friend class ASTReader;
friend class ASTStmtReader;
- friend TrailingObjects;
-public:
- using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
-protected:
- /// \brief The number of template arguments in the tail-allocated list of
- /// converted template arguments.
- unsigned NumTemplateArgs;
+private:
+ ConceptReference *ConceptRef;
+
+ /// \brief The Implicit Concept Specialization Decl, which holds the template
+ /// arguments for this specialization.
+ ImplicitConceptSpecializationDecl *SpecDecl;
/// \brief Information about the satisfaction of the named concept with the
/// given arguments. If this expression is value dependent, this is to be
/// ignored.
ASTConstraintSatisfaction *Satisfaction;
- ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc,
- DeclarationNameInfo ConceptNameInfo,
- NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs,
+ ConceptSpecializationExpr(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction);
- ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept,
- ArrayRef<TemplateArgument> ConvertedArgs,
+ ConceptSpecializationExpr(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction,
bool Dependent,
bool ContainsUnexpandedParameterPack);
-
- ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
+ ConceptSpecializationExpr(EmptyShell Empty);
public:
-
static ConceptSpecializationExpr *
- Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
- NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs,
+ Create(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction);
static ConceptSpecializationExpr *
- Create(const ASTContext &C, ConceptDecl *NamedConcept,
- ArrayRef<TemplateArgument> ConvertedArgs,
- const ConstraintSatisfaction *Satisfaction,
- bool Dependent,
+ Create(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
+ const ConstraintSatisfaction *Satisfaction, bool Dependent,
bool ContainsUnexpandedParameterPack);
- static ConceptSpecializationExpr *
- Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
-
ArrayRef<TemplateArgument> getTemplateArguments() const {
- return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
- NumTemplateArgs);
+ return SpecDecl->getTemplateArguments();
+ }
+
+ ConceptReference *getConceptReference() const { return ConceptRef; }
+
+ ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); }
+
+ // FIXME: Several of the following functions can be removed. Instead the
+ // caller can directly work with the ConceptReference.
+ bool hasExplicitTemplateArgs() const {
+ return ConceptRef->hasExplicitTemplateArgs();
+ }
+
+ SourceLocation getConceptNameLoc() const {
+ return ConceptRef->getConceptNameLoc();
+ }
+ const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
+ return ConceptRef->getTemplateArgsAsWritten();
+ }
+
+ const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
+ return ConceptRef->getNestedNameSpecifierLoc();
+ }
+
+ SourceLocation getTemplateKWLoc() const {
+ return ConceptRef->getTemplateKWLoc();
}
- /// \brief Set new template arguments for this concept specialization.
- void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
+ NamedDecl *getFoundDecl() const { return ConceptRef->getFoundDecl(); }
+
+ const DeclarationNameInfo &getConceptNameInfo() const {
+ return ConceptRef->getConceptNameInfo();
+ }
+
+ const ImplicitConceptSpecializationDecl *getSpecializationDecl() const {
+ assert(SpecDecl && "Template Argument Decl not initialized");
+ return SpecDecl;
+ }
/// \brief Whether or not the concept with the given arguments was satisfied
/// when the expression was created.
/// The expression must not be dependent.
bool isSatisfied() const {
- assert(!isValueDependent()
- && "isSatisfied called on a dependent ConceptSpecializationExpr");
+ assert(!isValueDependent() &&
+ "isSatisfied called on a dependent ConceptSpecializationExpr");
return Satisfaction->IsSatisfied;
}
@@ -112,8 +131,8 @@ public:
/// satisfaction of the named concept.
/// The expression must not be dependent.
const ASTConstraintSatisfaction &getSatisfaction() const {
- assert(!isValueDependent()
- && "getSatisfaction called on dependent ConceptSpecializationExpr");
+ assert(!isValueDependent() &&
+ "getSatisfaction called on dependent ConceptSpecializationExpr");
return *Satisfaction;
}
@@ -122,15 +141,15 @@ public:
}
SourceLocation getBeginLoc() const LLVM_READONLY {
- return ConceptName.getBeginLoc();
+ return ConceptRef->getBeginLoc();
}
SourceLocation getEndLoc() const LLVM_READONLY {
- // If the ConceptSpecializationExpr is the ImmediatelyDeclaredConstraint
- // of a TypeConstraint written syntactically as a constrained-parameter,
- // there may not be a template argument list.
- return ArgsAsWritten->RAngleLoc.isValid() ? ArgsAsWritten->RAngleLoc
- : ConceptName.getEndLoc();
+ return ConceptRef->getEndLoc();
+ }
+
+ SourceLocation getExprLoc() const LLVM_READONLY {
+ return ConceptRef->getLocation();
}
// Iterators
@@ -154,8 +173,11 @@ public:
private:
const RequirementKind Kind;
// FIXME: use RequirementDependence to model dependence?
+ LLVM_PREFERRED_TYPE(bool)
bool Dependent : 1;
+ LLVM_PREFERRED_TYPE(bool)
bool ContainsUnexpandedParameterPack : 1;
+ LLVM_PREFERRED_TYPE(bool)
bool Satisfied : 1;
public:
struct SubstitutionDiagnostic {
@@ -275,12 +297,12 @@ public:
friend ASTStmtWriter;
/// \brief No return type requirement was specified.
- ReturnTypeRequirement() : TypeConstraintInfo(nullptr, 0) {}
+ ReturnTypeRequirement() : TypeConstraintInfo(nullptr, false) {}
/// \brief A return type requirement was specified but it was a
/// substitution failure.
ReturnTypeRequirement(SubstitutionDiagnostic *SubstDiag) :
- TypeConstraintInfo(SubstDiag, 0) {}
+ TypeConstraintInfo(SubstDiag, false) {}
/// \brief A 'type constraint' style return type requirement.
/// \param TPL an invented template parameter list containing a single
@@ -405,57 +427,61 @@ public:
/// \brief A requires-expression requirement which is satisfied when a general
/// constraint expression is satisfied ('nested' requirements).
class NestedRequirement : public Requirement {
- llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value;
+ Expr *Constraint = nullptr;
const ASTConstraintSatisfaction *Satisfaction = nullptr;
+ bool HasInvalidConstraint = false;
+ StringRef InvalidConstraintEntity;
public:
friend ASTStmtReader;
friend ASTStmtWriter;
- NestedRequirement(SubstitutionDiagnostic *SubstDiag) :
- Requirement(RK_Nested, /*Dependent=*/false,
- /*ContainsUnexpandedParameterPack*/false,
- /*Satisfied=*/false), Value(SubstDiag) {}
-
- NestedRequirement(Expr *Constraint) :
- Requirement(RK_Nested, /*Dependent=*/true,
- Constraint->containsUnexpandedParameterPack()),
- Value(Constraint) {
+ NestedRequirement(Expr *Constraint)
+ : Requirement(RK_Nested, /*IsDependent=*/true,
+ Constraint->containsUnexpandedParameterPack()),
+ Constraint(Constraint) {
assert(Constraint->isInstantiationDependent() &&
"Nested requirement with non-dependent constraint must be "
"constructed with a ConstraintSatisfaction object");
}
NestedRequirement(ASTContext &C, Expr *Constraint,
- const ConstraintSatisfaction &Satisfaction) :
- Requirement(RK_Nested, Constraint->isInstantiationDependent(),
- Constraint->containsUnexpandedParameterPack(),
- Satisfaction.IsSatisfied),
- Value(Constraint),
- Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
-
- bool isSubstitutionFailure() const {
- return Value.is<SubstitutionDiagnostic *>();
- }
-
- SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
- assert(isSubstitutionFailure() &&
- "getSubstitutionDiagnostic() may not be called when there was no "
- "substitution failure.");
- return Value.get<SubstitutionDiagnostic *>();
+ const ConstraintSatisfaction &Satisfaction)
+ : Requirement(RK_Nested, Constraint->isInstantiationDependent(),
+ Constraint->containsUnexpandedParameterPack(),
+ Satisfaction.IsSatisfied),
+ Constraint(Constraint),
+ Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
+
+ NestedRequirement(StringRef InvalidConstraintEntity,
+ const ASTConstraintSatisfaction *Satisfaction)
+ : Requirement(RK_Nested,
+ /*IsDependent=*/false,
+ /*ContainsUnexpandedParameterPack*/ false,
+ Satisfaction->IsSatisfied),
+ Satisfaction(Satisfaction), HasInvalidConstraint(true),
+ InvalidConstraintEntity(InvalidConstraintEntity) {}
+
+ NestedRequirement(ASTContext &C, StringRef InvalidConstraintEntity,
+ const ConstraintSatisfaction &Satisfaction)
+ : NestedRequirement(InvalidConstraintEntity,
+ ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
+
+ bool hasInvalidConstraint() const { return HasInvalidConstraint; }
+
+ StringRef getInvalidConstraintEntity() {
+ assert(hasInvalidConstraint());
+ return InvalidConstraintEntity;
}
Expr *getConstraintExpr() const {
- assert(!isSubstitutionFailure() && "getConstraintExpr() may not be called "
- "on nested requirements with "
- "substitution failures.");
- return Value.get<Expr *>();
+ assert(!hasInvalidConstraint() &&
+ "getConstraintExpr() may not be called "
+ "on nested requirements with invalid constraint.");
+ return Constraint;
}
const ASTConstraintSatisfaction &getConstraintSatisfaction() const {
- assert(!isSubstitutionFailure() && "getConstraintSatisfaction() may not be "
- "called on nested requirements with "
- "substitution failures.");
return *Satisfaction;
}
@@ -464,6 +490,13 @@ public:
}
};
+using EntityPrinter = llvm::function_ref<void(llvm::raw_ostream &)>;
+
+/// \brief create a Requirement::SubstitutionDiagnostic with only a
+/// SubstitutedEntity and DiagLoc using Sema's allocator.
+Requirement::SubstitutionDiagnostic *
+createSubstDiagAt(Sema &S, SourceLocation Location, EntityPrinter Printer);
+
} // namespace concepts
/// C++2a [expr.prim.req]:
@@ -481,6 +514,8 @@ class RequiresExpr final : public Expr,
unsigned NumLocalParameters;
unsigned NumRequirements;
RequiresExprBodyDecl *Body;
+ SourceLocation LParenLoc;
+ SourceLocation RParenLoc;
SourceLocation RBraceLoc;
unsigned numTrailingObjects(OverloadToken<ParmVarDecl *>) const {
@@ -492,19 +527,22 @@ class RequiresExpr final : public Expr,
}
RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
- RequiresExprBodyDecl *Body,
+ RequiresExprBodyDecl *Body, SourceLocation LParenLoc,
ArrayRef<ParmVarDecl *> LocalParameters,
+ SourceLocation RParenLoc,
ArrayRef<concepts::Requirement *> Requirements,
SourceLocation RBraceLoc);
RequiresExpr(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
unsigned NumRequirements);
public:
- static RequiresExpr *
- Create(ASTContext &C, SourceLocation RequiresKWLoc,
- RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> LocalParameters,
- ArrayRef<concepts::Requirement *> Requirements,
- SourceLocation RBraceLoc);
+ static RequiresExpr *Create(ASTContext &C, SourceLocation RequiresKWLoc,
+ RequiresExprBodyDecl *Body,
+ SourceLocation LParenLoc,
+ ArrayRef<ParmVarDecl *> LocalParameters,
+ SourceLocation RParenLoc,
+ ArrayRef<concepts::Requirement *> Requirements,
+ SourceLocation RBraceLoc);
static RequiresExpr *
Create(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
unsigned NumRequirements);
@@ -527,10 +565,18 @@ public:
return RequiresExprBits.IsSatisfied;
}
+ void setSatisfied(bool IsSatisfied) {
+ assert(!isValueDependent() &&
+ "setSatisfied called on a dependent RequiresExpr");
+ RequiresExprBits.IsSatisfied = IsSatisfied;
+ }
+
SourceLocation getRequiresKWLoc() const {
return RequiresExprBits.RequiresKWLoc;
}
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
static bool classof(const Stmt *T) {
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h b/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h
index b0f057dbaa02..f833916c91aa 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h
@@ -27,8 +27,6 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
@@ -41,6 +39,7 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
+#include <optional>
namespace clang {
@@ -272,7 +271,7 @@ struct ObjCDictionaryElement {
/// The number of elements this pack expansion will expand to, if
/// this is a pack expansion and is known.
- Optional<unsigned> NumExpansions;
+ std::optional<unsigned> NumExpansions;
/// Determines whether this dictionary element is a pack expansion.
bool isPackExpansion() const { return EllipsisLoc.isValid(); }
@@ -318,6 +317,7 @@ class ObjCDictionaryLiteral final
/// key/value pairs, which provide the locations of the ellipses (if
/// any) and number of elements in the expansion (if known). If
/// there are no pack expansions, we optimize away this storage.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasPackExpansions : 1;
SourceRange Range;
@@ -362,7 +362,8 @@ public:
ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
assert((Index < NumElements) && "Arg access out of range!");
const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index];
- ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
+ ObjCDictionaryElement Result = {KV.Key, KV.Value, SourceLocation(),
+ std::nullopt};
if (HasPackExpansions) {
const ExpansionData &Expansion =
getTrailingObjects<ExpansionData>()[Index];
@@ -554,9 +555,11 @@ class ObjCIvarRefExpr : public Expr {
SourceLocation OpLoc;
// True if this is "X->F", false if this is "X.F".
+ LLVM_PREFERRED_TYPE(bool)
bool IsArrow : 1;
// True if ivar reference has no base (self assumed).
+ LLVM_PREFERRED_TYPE(bool)
bool IsFreeIvar : 1;
public:
@@ -940,6 +943,23 @@ private:
class ObjCMessageExpr final
: public Expr,
private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
+public:
+ /// The kind of receiver this message is sending to.
+ enum ReceiverKind {
+ /// The receiver is a class.
+ Class = 0,
+
+ /// The receiver is an object instance.
+ Instance,
+
+ /// The receiver is a superclass.
+ SuperClass,
+
+ /// The receiver is the instance of the superclass object.
+ SuperInstance
+ };
+
+private:
/// Stores either the selector that this message is sending
/// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
/// referring to the method that we type-checked against.
@@ -955,6 +975,7 @@ class ObjCMessageExpr final
/// ReceiverKind values.
///
/// We pad this out to a byte to avoid excessive masking and shifting.
+ LLVM_PREFERRED_TYPE(ReceiverKind)
unsigned Kind : 8;
/// Whether we have an actual method prototype in \c
@@ -962,18 +983,22 @@ class ObjCMessageExpr final
///
/// When non-zero, we have a method declaration; otherwise, we just
/// have a selector.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasMethod : 1;
/// Whether this message send is a "delegate init call",
/// i.e. a call of an init method on self from within an init method.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsDelegateInitCall : 1;
/// Whether this message send was implicitly generated by
/// the implementation rather than explicitly written by the user.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsImplicit : 1;
/// Whether the locations of the selector identifiers are in a
/// "standard" position, a enum SelectorLocationsKind.
+ LLVM_PREFERRED_TYPE(SelectorLocationsKind)
unsigned SelLocsKind : 2;
/// When the message expression is a send to 'super', this is
@@ -1082,21 +1107,6 @@ public:
friend class ASTStmtWriter;
friend TrailingObjects;
- /// The kind of receiver this message is sending to.
- enum ReceiverKind {
- /// The receiver is a class.
- Class = 0,
-
- /// The receiver is an object instance.
- Instance,
-
- /// The receiver is a superclass.
- SuperClass,
-
- /// The receiver is the instance of the superclass object.
- SuperInstance
- };
-
/// Create a message send to super.
///
/// \param Context The ASTContext in which this expression will be created.
@@ -1415,11 +1425,10 @@ public:
SourceLocation getSelectorLoc(unsigned Index) const {
assert(Index < getNumSelectorLocs() && "Index out of range!");
if (hasStandardSelLocs())
- return getStandardSelectorLoc(Index, getSelector(),
- getSelLocsKind() == SelLoc_StandardWithSpace,
- llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
- getNumArgs()),
- RBracLoc);
+ return getStandardSelectorLoc(
+ Index, getSelector(), getSelLocsKind() == SelLoc_StandardWithSpace,
+ llvm::ArrayRef(const_cast<Expr **>(getArgs()), getNumArgs()),
+ RBracLoc);
return getStoredSelLocs()[Index];
}
@@ -1632,6 +1641,7 @@ class ObjCBridgedCastExpr final
SourceLocation LParenLoc;
SourceLocation BridgeKeywordLoc;
+ LLVM_PREFERRED_TYPE(ObjCBridgeCastKind)
unsigned Kind : 2;
public:
@@ -1706,7 +1716,7 @@ public:
/// This may be '*', in which case this should fold to true.
bool hasVersion() const { return !VersionToCheck.empty(); }
- VersionTuple getVersion() { return VersionToCheck; }
+ VersionTuple getVersion() const { return VersionToCheck; }
child_range children() {
return child_range(child_iterator(), child_iterator());
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h b/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h
index be5dda992334..be5b1f3fdd11 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h
@@ -202,12 +202,12 @@ public:
/// Fetches the dimensions for array shaping expression.
ArrayRef<Expr *> getDimensions() const {
- return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumDims);
+ return llvm::ArrayRef(getTrailingObjects<Expr *>(), NumDims);
}
/// Fetches source ranges for the brackets os the array shaping expression.
ArrayRef<SourceRange> getBracketsRanges() const {
- return llvm::makeArrayRef(getTrailingObjects<SourceRange>(), NumDims);
+ return llvm::ArrayRef(getTrailingObjects<SourceRange>(), NumDims);
}
/// Fetches base expression of array shaping expression.
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h b/contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h
index 0230495a5ef3..ec4cfbe2175c 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h
@@ -118,7 +118,7 @@ public:
/// Asks all connected ASTImporters if any of them imported the given
/// declaration. If any ASTImporter did import the given declaration,
/// then this function returns the declaration that D was imported from.
- /// Returns nullptr if no ASTImporter did import import D.
+ /// Returns nullptr if no ASTImporter did import D.
Decl *FindOriginalDecl(Decl *D);
/// Add a set of ASTContexts as possible origins.
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h b/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h
index b1851afcda37..8e573965b0a3 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h
@@ -20,7 +20,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
@@ -30,6 +29,7 @@
#include <cstddef>
#include <cstdint>
#include <iterator>
+#include <optional>
#include <utility>
namespace clang {
@@ -160,7 +160,7 @@ public:
virtual Module *getModule(unsigned ID) { return nullptr; }
/// Return a descriptor for the corresponding module, if one exists.
- virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
+ virtual std::optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
enum ExtKind { EK_Always, EK_Never, EK_ReplyHazy };
@@ -371,7 +371,7 @@ public:
/// \param Source the external AST source.
///
/// \returns a pointer to the AST node.
- T* get(ExternalASTSource *Source) const {
+ T *get(ExternalASTSource *Source) const {
if (isOffset()) {
assert(Source &&
"Cannot deserialize a lazy pointer without an AST source");
@@ -379,6 +379,14 @@ public:
}
return reinterpret_cast<T*>(Ptr);
}
+
+ /// Retrieve the address of the AST node pointer. Deserializes the pointee if
+ /// necessary.
+ T **getAddressOfPointer(ExternalASTSource *Source) const {
+ // Ensure the integer is in pointer form.
+ (void)get(Source);
+ return reinterpret_cast<T**>(&Ptr);
+ }
};
/// A lazy value (of type T) that is within an AST node of type Owner,
diff --git a/contrib/llvm-project/clang/include/clang/AST/FormatString.h b/contrib/llvm-project/clang/include/clang/AST/FormatString.h
index 8c944451f796..5c4ad9baaef6 100644
--- a/contrib/llvm-project/clang/include/clang/AST/FormatString.h
+++ b/contrib/llvm-project/clang/include/clang/AST/FormatString.h
@@ -15,10 +15,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
+#ifndef LLVM_CLANG_AST_FORMATSTRING_H
+#define LLVM_CLANG_AST_FORMATSTRING_H
#include "clang/AST/CanonicalType.h"
+#include <optional>
namespace clang {
@@ -127,8 +128,12 @@ public:
dArg,
DArg, // Apple extension
iArg,
+ // C23 conversion specifiers.
+ bArg,
+ BArg,
+
IntArgBeg = dArg,
- IntArgEnd = iArg,
+ IntArgEnd = BArg,
oArg,
OArg, // Apple extension
@@ -237,7 +242,7 @@ public:
bool isPrintfKind() const { return IsPrintf; }
- Optional<ConversionSpecifier> getStandardSpecifier() const;
+ std::optional<ConversionSpecifier> getStandardSpecifier() const;
protected:
bool IsPrintf;
@@ -257,8 +262,14 @@ public:
/// instance, "%d" and float.
NoMatch = 0,
/// The conversion specifier and the argument type are compatible. For
- /// instance, "%d" and _Bool.
+ /// instance, "%d" and int.
Match = 1,
+ /// The conversion specifier and the argument type are compatible because of
+ /// default argument promotions. For instance, "%hhd" and int.
+ MatchPromotion,
+ /// The conversion specifier and the argument type are compatible but still
+ /// seems likely to be an error. For instanace, "%hhd" and short.
+ NoMatchPromotionTypeConfusion,
/// The conversion specifier and the argument type are disallowed by the C
/// standard, but are in practice harmless. For instance, "%p" and int*.
NoMatchPedantic,
@@ -332,11 +343,11 @@ public:
unsigned amountLength,
bool usesPositionalArg)
: start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
- UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
+ UsesPositionalArg(usesPositionalArg), UsesDotPrefix(false) {}
OptionalAmount(bool valid = true)
: start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
- UsesPositionalArg(0), UsesDotPrefix(0) {}
+ UsesPositionalArg(false), UsesDotPrefix(false) {}
explicit OptionalAmount(unsigned Amount)
: start(nullptr), length(0), hs(Constant), amt(Amount),
@@ -456,7 +467,7 @@ public:
bool hasStandardLengthModifier() const;
- Optional<LengthModifier> getCorrectedLengthModifier() const;
+ std::optional<LengthModifier> getCorrectedLengthModifier() const;
bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
@@ -726,7 +737,8 @@ public:
virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
- unsigned specifierLen) {
+ unsigned specifierLen,
+ const TargetInfo &Target) {
return true;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h b/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h
index 8cb56fb4ae90..88abba28c991 100644
--- a/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h
+++ b/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h
@@ -18,6 +18,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/ABI.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMapInfo.h"
@@ -129,8 +130,12 @@ public:
}
KernelReferenceKind getKernelReferenceKind() const {
- assert(isa<FunctionDecl>(getDecl()) &&
- cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
+ assert(((isa<FunctionDecl>(getDecl()) &&
+ cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>()) ||
+ (isa<FunctionTemplateDecl>(getDecl()) &&
+ cast<FunctionTemplateDecl>(getDecl())
+ ->getTemplatedDecl()
+ ->hasAttr<CUDAGlobalAttr>())) &&
"Decl is not a GPU kernel!");
return static_cast<KernelReferenceKind>(Value.getInt());
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h b/contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h
index a7e9b07bef6c..917bada61fa6 100644
--- a/contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h
+++ b/contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h
@@ -23,7 +23,8 @@ namespace detail {
inline Expr *IgnoreExprNodesImpl(Expr *E) { return E; }
template <typename FnTy, typename... FnTys>
Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) {
- return IgnoreExprNodesImpl(Fn(E), std::forward<FnTys>(Fns)...);
+ return IgnoreExprNodesImpl(std::forward<FnTy>(Fn)(E),
+ std::forward<FnTys>(Fns)...);
}
} // namespace detail
@@ -165,6 +166,11 @@ inline Expr *IgnoreParensSingleStep(Expr *E) {
return CE->getChosenSubExpr();
}
+ else if (auto *PE = dyn_cast<PredefinedExpr>(E)) {
+ if (PE->isTransparent() && PE->getFunctionName())
+ return PE->getFunctionName();
+ }
+
return E;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h b/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h
index a96e21993e20..4def5389137f 100644
--- a/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h
+++ b/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h
@@ -1,9 +1,8 @@
//===--- JSONNodeDumper.h - Printing of AST nodes to JSON -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
//
@@ -161,6 +160,7 @@ class JSONNodeDumper
std::string createPointerRepresentation(const void *Ptr);
llvm::json::Object createQualType(QualType QT, bool Desugar = true);
llvm::json::Object createBareDeclRef(const Decl *D);
+ llvm::json::Object createFPOptions(FPOptionsOverride FPO);
void writeBareDeclRef(const Decl *D);
llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS);
@@ -208,7 +208,16 @@ public:
void Visit(const concepts::Requirement *R);
void Visit(const APValue &Value, QualType Ty);
+ void VisitAliasAttr(const AliasAttr *AA);
+ void VisitCleanupAttr(const CleanupAttr *CA);
+ void VisitDeprecatedAttr(const DeprecatedAttr *DA);
+ void VisitUnavailableAttr(const UnavailableAttr *UA);
+ void VisitSectionAttr(const SectionAttr *SA);
+ void VisitVisibilityAttr(const VisibilityAttr *VA);
+ void VisitTLSModelAttr(const TLSModelAttr *TA);
+
void VisitTypedefType(const TypedefType *TT);
+ void VisitUsingType(const UsingType *TT);
void VisitFunctionType(const FunctionType *T);
void VisitFunctionProtoType(const FunctionProtoType *T);
void VisitRValueReferenceType(const ReferenceType *RT);
@@ -220,6 +229,9 @@ public:
void VisitUnaryTransformType(const UnaryTransformType *UTT);
void VisitTagType(const TagType *TT);
void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT);
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT);
+ void
+ VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T);
void VisitAutoType(const AutoType *AT);
void VisitTemplateSpecializationType(const TemplateSpecializationType *TST);
void VisitInjectedClassNameType(const InjectedClassNameType *ICNT);
@@ -245,6 +257,7 @@ public:
void VisitEnumConstantDecl(const EnumConstantDecl *ECD);
void VisitRecordDecl(const RecordDecl *RD);
void VisitCXXRecordDecl(const CXXRecordDecl *RD);
+ void VisitHLSLBufferDecl(const HLSLBufferDecl *D);
void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
@@ -272,6 +285,7 @@ public:
void VisitBinaryOperator(const BinaryOperator *BO);
void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO);
void VisitMemberExpr(const MemberExpr *ME);
+ void VisitAtomicExpr(const AtomicExpr *AE);
void VisitCXXNewExpr(const CXXNewExpr *NE);
void VisitCXXDeleteExpr(const CXXDeleteExpr *DE);
void VisitCXXThisExpr(const CXXThisExpr *TE);
@@ -318,6 +332,7 @@ public:
void VisitGotoStmt(const GotoStmt *GS);
void VisitWhileStmt(const WhileStmt *WS);
void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);
+ void VisitCompoundStmt(const CompoundStmt *IS);
void VisitNullTemplateArgument(const TemplateArgument &TA);
void VisitTypeTemplateArgument(const TemplateArgument &TA);
@@ -379,7 +394,7 @@ class JSONDumper : public ASTNodeTraverser<JSONDumper, JSONNodeDumper> {
case TSK_ExplicitInstantiationDefinition:
if (!DumpExplicitInst)
break;
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
if (DumpRefOnly)
diff --git a/contrib/llvm-project/clang/include/clang/AST/LambdaCapture.h b/contrib/llvm-project/clang/include/clang/AST/LambdaCapture.h
index 8e2806545dd6..62e7716ed369 100644
--- a/contrib/llvm-project/clang/include/clang/AST/LambdaCapture.h
+++ b/contrib/llvm-project/clang/include/clang/AST/LambdaCapture.h
@@ -71,7 +71,7 @@ public:
/// capture that is a pack expansion, or an invalid source
/// location to indicate that this is not a pack expansion.
LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
- VarDecl *Var = nullptr,
+ ValueDecl *Var = nullptr,
SourceLocation EllipsisLoc = SourceLocation());
/// Determine the kind of capture.
@@ -86,7 +86,7 @@ public:
/// Determine whether this capture handles a variable.
bool capturesVariable() const {
- return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
+ return isa_and_nonnull<ValueDecl>(DeclAndBits.getPointer());
}
/// Determine whether this captures a variable length array bound
@@ -101,9 +101,9 @@ public:
///
/// This operation is only valid if this capture is a variable capture
/// (other than a capture of \c this).
- VarDecl *getCapturedVar() const {
+ ValueDecl *getCapturedVar() const {
assert(capturesVariable() && "No variable available for capture");
- return static_cast<VarDecl *>(DeclAndBits.getPointer());
+ return static_cast<ValueDecl *>(DeclAndBits.getPointer());
}
/// Determine whether this was an implicit capture (not
diff --git a/contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h b/contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
index e42f0449f6db..054220b8a32c 100644
--- a/contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
+++ b/contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
-#define LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
+#ifndef LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H
+#define LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/LLVM.h"
@@ -160,4 +160,4 @@ private:
} // end namespace clang
-#endif // LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
+#endif // LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/LocInfoType.h b/contrib/llvm-project/clang/include/clang/AST/LocInfoType.h
index 7e845ad03587..876c7deeceb9 100644
--- a/contrib/llvm-project/clang/include/clang/AST/LocInfoType.h
+++ b/contrib/llvm-project/clang/include/clang/AST/LocInfoType.h
@@ -10,8 +10,8 @@
// source-location information.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_LOCINFOTYPE_H
-#define LLVM_CLANG_SEMA_LOCINFOTYPE_H
+#ifndef LLVM_CLANG_AST_LOCINFOTYPE_H
+#define LLVM_CLANG_AST_LOCINFOTYPE_H
#include "clang/AST/Type.h"
@@ -54,4 +54,4 @@ public:
} // end namespace clang
-#endif // LLVM_CLANG_SEMA_LOCINFOTYPE_H
+#endif // LLVM_CLANG_AST_LOCINFOTYPE_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/Mangle.h b/contrib/llvm-project/clang/include/clang/AST/Mangle.h
index 7d02f08e0120..e586b0cec43d 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Mangle.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Mangle.h
@@ -19,6 +19,7 @@
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Casting.h"
+#include <optional>
namespace llvm {
class raw_ostream;
@@ -54,18 +55,23 @@ private:
ASTContext &Context;
DiagnosticsEngine &Diags;
const ManglerKind Kind;
+ /// For aux target. If true, uses mangling number for aux target from
+ /// ASTContext.
+ bool IsAux = false;
llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
llvm::DenseMap<const NamedDecl*, uint64_t> AnonStructIds;
+ llvm::DenseMap<const FunctionDecl*, unsigned> FuncAnonStructSize;
public:
ManglerKind getKind() const { return Kind; }
- explicit MangleContext(ASTContext &Context,
- DiagnosticsEngine &Diags,
- ManglerKind Kind)
- : Context(Context), Diags(Diags), Kind(Kind) {}
+ bool isAux() const { return IsAux; }
+
+ explicit MangleContext(ASTContext &Context, DiagnosticsEngine &Diags,
+ ManglerKind Kind, bool IsAux = false)
+ : Context(Context), Diags(Diags), Kind(Kind), IsAux(IsAux) {}
virtual ~MangleContext() { }
@@ -83,9 +89,17 @@ public:
return Result.first->second;
}
- uint64_t getAnonymousStructId(const NamedDecl *D) {
+ uint64_t getAnonymousStructId(const NamedDecl *D,
+ const FunctionDecl *FD = nullptr) {
+ auto FindResult = AnonStructIds.find(D);
+ if (FindResult != AnonStructIds.end())
+ return FindResult->second;
+
+ // If FunctionDecl is passed in, the anonymous structID will be per-function
+ // based.
+ unsigned Id = FD ? FuncAnonStructSize[FD]++ : AnonStructIds.size();
std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
- Result = AnonStructIds.insert(std::make_pair(D, AnonStructIds.size()));
+ Result = AnonStructIds.insert(std::make_pair(D, Id));
return Result.first->second;
}
@@ -126,7 +140,8 @@ public:
unsigned ManglingNumber,
raw_ostream &) = 0;
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
- virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
+ virtual void mangleCXXRTTIName(QualType T, raw_ostream &,
+ bool NormalizeIntegers = false) = 0;
virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
@@ -153,17 +168,18 @@ public:
virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &) = 0;
- virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
+ virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
raw_ostream &Out) = 0;
- virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
+ virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
raw_ostream &Out) = 0;
/// Generates a unique string for an externally visible type for use with TBAA
/// or type uniquing.
/// TODO: Extend this to internal types by generating names that are unique
/// across translation units so it can be used with LTO.
- virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
+ virtual void mangleCanonicalTypeName(QualType T, raw_ostream &,
+ bool NormalizeIntegers = false) = 0;
/// @}
};
@@ -171,9 +187,10 @@ public:
class ItaniumMangleContext : public MangleContext {
public:
using DiscriminatorOverrideTy =
- llvm::Optional<unsigned> (*)(ASTContext &, const NamedDecl *);
- explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
- : MangleContext(C, D, MK_Itanium) {}
+ std::optional<unsigned> (*)(ASTContext &, const NamedDecl *);
+ explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D,
+ bool IsAux = false)
+ : MangleContext(C, D, MK_Itanium, IsAux) {}
virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
@@ -194,6 +211,8 @@ public:
virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
+ virtual void mangleModuleInitializer(const Module *Module, raw_ostream &) = 0;
+
// This has to live here, otherwise the CXXNameMangler won't have access to
// it.
virtual DiscriminatorOverrideTy getDiscriminatorOverride() const = 0;
@@ -201,17 +220,19 @@ public:
return C->getKind() == MK_Itanium;
}
- static ItaniumMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
+ static ItaniumMangleContext *
+ create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
static ItaniumMangleContext *create(ASTContext &Context,
DiagnosticsEngine &Diags,
- DiscriminatorOverrideTy Discriminator);
+ DiscriminatorOverrideTy Discriminator,
+ bool IsAux = false);
};
class MicrosoftMangleContext : public MangleContext {
public:
- explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
- : MangleContext(C, D, MK_Microsoft) {}
+ explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D,
+ bool IsAux = false)
+ : MangleContext(C, D, MK_Microsoft, IsAux) {}
/// Mangle vftable symbols. Only a subset of the bases along the path
/// to the vftable are included in the name. It's up to the caller to pick
@@ -270,8 +291,8 @@ public:
return C->getKind() == MK_Microsoft;
}
- static MicrosoftMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
+ static MicrosoftMangleContext *
+ create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
};
class ASTNameGenerator {
diff --git a/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h b/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h
index eb33759682d6..1313c94eb122 100644
--- a/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h
+++ b/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h
@@ -21,14 +21,15 @@ namespace clang {
class BlockDecl;
class CXXMethodDecl;
-class IdentifierInfo;
class TagDecl;
-class Type;
class VarDecl;
/// Keeps track of the mangled names of lambda expressions and block
/// literals within a particular context.
class MangleNumberingContext {
+ // The index of the next lambda we encounter in this context.
+ unsigned LambdaIndex = 0;
+
public:
virtual ~MangleNumberingContext() {}
@@ -57,6 +58,11 @@ public:
/// given call operator within the device context. No device number is
/// assigned if there's no device numbering context is associated.
virtual unsigned getDeviceManglingNumber(const CXXMethodDecl *) { return 0; }
+
+ // Retrieve the index of the next lambda appearing in this context, which is
+ // used for deduplicating lambdas across modules. Note that this is a simple
+ // sequence number and is not ABI-dependent.
+ unsigned getNextLambdaIndex() { return LambdaIndex++; }
};
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/NSAPI.h b/contrib/llvm-project/clang/include/clang/AST/NSAPI.h
index a8bd2d0f17e6..d411c34191ed 100644
--- a/contrib/llvm-project/clang/include/clang/AST/NSAPI.h
+++ b/contrib/llvm-project/clang/include/clang/AST/NSAPI.h
@@ -11,7 +11,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
+#include <optional>
namespace clang {
class ASTContext;
@@ -89,7 +89,7 @@ public:
Selector getNSArraySelector(NSArrayMethodKind MK) const;
/// Return NSArrayMethodKind if \p Sel is such a selector.
- Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
+ std::optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
/// Enumerates the NSDictionary/NSMutableDictionary methods used
/// to generate literals and to apply some checks.
@@ -114,7 +114,7 @@ public:
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
/// Return NSDictionaryMethodKind if \p Sel is such a selector.
- Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
+ std::optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
/// Enumerates the NSMutableSet/NSOrderedSet methods used
/// to apply some checks.
@@ -131,7 +131,7 @@ public:
Selector getNSSetSelector(NSSetMethodKind MK) const;
/// Return NSSetMethodKind if \p Sel is such a selector.
- Optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel);
+ std::optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel);
/// Returns selector for "objectForKeyedSubscript:".
Selector getObjectForKeyedSubscriptSelector() const {
@@ -203,13 +203,13 @@ public:
}
/// Return NSNumberLiteralMethodKind if \p Sel is such a selector.
- Optional<NSNumberLiteralMethodKind>
- getNSNumberLiteralMethodKind(Selector Sel) const;
+ std::optional<NSNumberLiteralMethodKind>
+ getNSNumberLiteralMethodKind(Selector Sel) const;
/// Determine the appropriate NSNumber factory method kind for a
/// literal of the given type.
- Optional<NSNumberLiteralMethodKind>
- getNSNumberFactoryMethodKind(QualType T) const;
+ std::optional<NSNumberLiteralMethodKind>
+ getNSNumberFactoryMethodKind(QualType T) const;
/// Returns true if \param T is a typedef of "BOOL" in objective-c.
bool isObjCBOOLType(QualType T) const;
diff --git a/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h b/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h
index 8bc3e25c0f4b..3b6cf9721185 100644
--- a/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h
+++ b/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h
@@ -162,7 +162,7 @@ public:
/// Return the prefix of this nested name specifier.
///
/// The prefix contains all of the parts of the nested name
- /// specifier that preced this current specifier. For example, for a
+ /// specifier that precede this current specifier. For example, for a
/// nested name specifier that represents "foo::bar::", the current
/// specifier will contain "bar::" and the prefix will contain
/// "foo::".
@@ -521,7 +521,7 @@ public:
/// NestedNameSpecifiers into a diagnostic with <<.
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
NestedNameSpecifier *NNS) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
+ DB.AddTaggedVal(reinterpret_cast<uint64_t>(NNS),
DiagnosticsEngine::ak_nestednamespec);
return DB;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h b/contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h
index c95516538ad1..cf320c8a478a 100644
--- a/contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h
+++ b/contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
-#define LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
+#ifndef LLVM_CLANG_AST_NONTRIVIALTYPEVISITOR_H
+#define LLVM_CLANG_AST_NONTRIVIALTYPEVISITOR_H
#include "clang/AST/Type.h"
diff --git a/contrib/llvm-project/clang/include/clang/AST/ODRDiagsEmitter.h b/contrib/llvm-project/clang/include/clang/AST/ODRDiagsEmitter.h
new file mode 100644
index 000000000000..1f7faaa06e54
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/AST/ODRDiagsEmitter.h
@@ -0,0 +1,203 @@
+//===- ODRDiagsEmitter.h - Emits diagnostic for ODR mismatches --*- 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_AST_ODRDIAGSEMITTER_H
+#define LLVM_CLANG_AST_ODRDIAGSEMITTER_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LangOptions.h"
+
+namespace clang {
+
+class ODRDiagsEmitter {
+public:
+ ODRDiagsEmitter(DiagnosticsEngine &Diags, const ASTContext &Context,
+ const LangOptions &LangOpts)
+ : Diags(Diags), Context(Context), LangOpts(LangOpts) {}
+
+ /// Diagnose ODR mismatch between 2 FunctionDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseMismatch(const FunctionDecl *FirstFunction,
+ const FunctionDecl *SecondFunction) const;
+
+ /// Diagnose ODR mismatch between 2 EnumDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseMismatch(const EnumDecl *FirstEnum,
+ const EnumDecl *SecondEnum) const;
+
+ /// Diagnose ODR mismatch between 2 CXXRecordDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ /// To compare 2 declarations with merged and identical definition data
+ /// you need to provide pre-merge definition data in \p SecondDD.
+ bool
+ diagnoseMismatch(const CXXRecordDecl *FirstRecord,
+ const CXXRecordDecl *SecondRecord,
+ const struct CXXRecordDecl::DefinitionData *SecondDD) const;
+
+ /// Diagnose ODR mismatch between 2 RecordDecl that are not CXXRecordDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseMismatch(const RecordDecl *FirstRecord,
+ const RecordDecl *SecondRecord) const;
+
+ /// Diagnose ODR mismatch between 2 ObjCInterfaceDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseMismatch(
+ const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,
+ const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const;
+
+ /// Diagnose ODR mismatch between ObjCInterfaceDecl with different
+ /// definitions.
+ bool diagnoseMismatch(const ObjCInterfaceDecl *FirstID,
+ const ObjCInterfaceDecl *SecondID) const {
+ assert(FirstID->data().Definition != SecondID->data().Definition &&
+ "Don't diagnose differences when definitions are merged already");
+ return diagnoseMismatch(FirstID, SecondID, &SecondID->data());
+ }
+
+ /// Diagnose ODR mismatch between 2 ObjCProtocolDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ /// To compare 2 declarations with merged and identical definition data
+ /// you need to provide pre-merge definition data in \p SecondDD.
+ bool diagnoseMismatch(
+ const ObjCProtocolDecl *FirstProtocol,
+ const ObjCProtocolDecl *SecondProtocol,
+ const struct ObjCProtocolDecl::DefinitionData *SecondDD) const;
+
+ /// Diagnose ODR mismatch between ObjCProtocolDecl with different definitions.
+ bool diagnoseMismatch(const ObjCProtocolDecl *FirstProtocol,
+ const ObjCProtocolDecl *SecondProtocol) const {
+ assert(FirstProtocol->data().Definition !=
+ SecondProtocol->data().Definition &&
+ "Don't diagnose differences when definitions are merged already");
+ return diagnoseMismatch(FirstProtocol, SecondProtocol,
+ &SecondProtocol->data());
+ }
+
+ /// Get the best name we know for the module that owns the given
+ /// declaration, or an empty string if the declaration is not from a module.
+ static std::string getOwningModuleNameForDiagnostic(const Decl *D);
+
+private:
+ using DeclHashes = llvm::SmallVector<std::pair<const Decl *, unsigned>, 4>;
+
+ // Used with err_module_odr_violation_mismatch_decl,
+ // note_module_odr_violation_mismatch_decl,
+ // err_module_odr_violation_mismatch_decl_unknown,
+ // and note_module_odr_violation_mismatch_decl_unknown
+ // This list should be the same Decl's as in ODRHash::isSubDeclToBeProcessed
+ enum ODRMismatchDecl {
+ EndOfClass,
+ PublicSpecifer,
+ PrivateSpecifer,
+ ProtectedSpecifer,
+ StaticAssert,
+ Field,
+ CXXMethod,
+ TypeAlias,
+ TypeDef,
+ Var,
+ Friend,
+ FunctionTemplate,
+ ObjCMethod,
+ ObjCIvar,
+ ObjCProperty,
+ Other
+ };
+
+ struct DiffResult {
+ const Decl *FirstDecl = nullptr, *SecondDecl = nullptr;
+ ODRMismatchDecl FirstDiffType = Other, SecondDiffType = Other;
+ };
+
+ // If there is a diagnoseable difference, FirstDiffType and
+ // SecondDiffType will not be Other and FirstDecl and SecondDecl will be
+ // filled in if not EndOfClass.
+ static DiffResult FindTypeDiffs(DeclHashes &FirstHashes,
+ DeclHashes &SecondHashes);
+
+ DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
+ return Diags.Report(Loc, DiagID);
+ }
+
+ // Use this to diagnose that an unexpected Decl was encountered
+ // or no difference was detected. This causes a generic error
+ // message to be emitted.
+ void diagnoseSubMismatchUnexpected(DiffResult &DR,
+ const NamedDecl *FirstRecord,
+ StringRef FirstModule,
+ const NamedDecl *SecondRecord,
+ StringRef SecondModule) const;
+
+ void diagnoseSubMismatchDifferentDeclKinds(DiffResult &DR,
+ const NamedDecl *FirstRecord,
+ StringRef FirstModule,
+ const NamedDecl *SecondRecord,
+ StringRef SecondModule) const;
+
+ bool diagnoseSubMismatchField(const NamedDecl *FirstRecord,
+ StringRef FirstModule, StringRef SecondModule,
+ const FieldDecl *FirstField,
+ const FieldDecl *SecondField) const;
+
+ bool diagnoseSubMismatchTypedef(const NamedDecl *FirstRecord,
+ StringRef FirstModule, StringRef SecondModule,
+ const TypedefNameDecl *FirstTD,
+ const TypedefNameDecl *SecondTD,
+ bool IsTypeAlias) const;
+
+ bool diagnoseSubMismatchVar(const NamedDecl *FirstRecord,
+ StringRef FirstModule, StringRef SecondModule,
+ const VarDecl *FirstVD,
+ const VarDecl *SecondVD) const;
+
+ /// Check if protocol lists are the same and diagnose if they are different.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseSubMismatchProtocols(const ObjCProtocolList &FirstProtocols,
+ const ObjCContainerDecl *FirstContainer,
+ StringRef FirstModule,
+ const ObjCProtocolList &SecondProtocols,
+ const ObjCContainerDecl *SecondContainer,
+ StringRef SecondModule) const;
+
+ /// Check if Objective-C methods are the same and diagnose if different.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseSubMismatchObjCMethod(const NamedDecl *FirstObjCContainer,
+ StringRef FirstModule,
+ StringRef SecondModule,
+ const ObjCMethodDecl *FirstMethod,
+ const ObjCMethodDecl *SecondMethod) const;
+
+ /// Check if Objective-C properties are the same and diagnose if different.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool
+ diagnoseSubMismatchObjCProperty(const NamedDecl *FirstObjCContainer,
+ StringRef FirstModule, StringRef SecondModule,
+ const ObjCPropertyDecl *FirstProp,
+ const ObjCPropertyDecl *SecondProp) const;
+
+private:
+ DiagnosticsEngine &Diags;
+ const ASTContext &Context;
+ const LangOptions &LangOpts;
+};
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/AST/ODRHash.h b/contrib/llvm-project/clang/include/clang/AST/ODRHash.h
index 2e8593e0b835..a1caa6d39a87 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ODRHash.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ODRHash.h
@@ -25,6 +25,7 @@
namespace clang {
+class APValue;
class Decl;
class IdentifierInfo;
class NestedNameSpecifier;
@@ -55,6 +56,14 @@ public:
// more information than the AddDecl class.
void AddCXXRecordDecl(const CXXRecordDecl *Record);
+ // Use this for ODR checking records in C/Objective-C between modules. This
+ // method compares more information than the AddDecl class.
+ void AddRecordDecl(const RecordDecl *Record);
+
+ // Use this for ODR checking ObjC interfaces. This
+ // method compares more information than the AddDecl class.
+ void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record);
+
// Use this for ODR checking functions between modules. This method compares
// more information than the AddDecl class. SkipBody will process the
// hash as if the function has no body.
@@ -64,6 +73,10 @@ public:
// more information than the AddDecl class.
void AddEnumDecl(const EnumDecl *Enum);
+ // Use this for ODR checking ObjC protocols. This
+ // method compares more information than the AddDecl class.
+ void AddObjCProtocolDecl(const ObjCProtocolDecl *P);
+
// Process SubDecls of the main Decl. This method calls the DeclVisitor
// while AddDecl does not.
void AddSubDecl(const Decl *D);
@@ -89,7 +102,9 @@ public:
// Save booleans until the end to lower the size of data to process.
void AddBoolean(bool value);
- static bool isDeclToBeProcessed(const Decl* D, const DeclContext *Parent);
+ void AddStructuralValue(const APValue &);
+
+ static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent);
private:
void AddDeclarationNameImpl(DeclarationName Name);
diff --git a/contrib/llvm-project/clang/include/clang/AST/OSLog.h b/contrib/llvm-project/clang/include/clang/AST/OSLog.h
index c24e79ce6da0..3772597e2616 100644
--- a/contrib/llvm-project/clang/include/clang/AST/OSLog.h
+++ b/contrib/llvm-project/clang/include/clang/AST/OSLog.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
-#define LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
+#ifndef LLVM_CLANG_AST_OSLOG_H
+#define LLVM_CLANG_AST_OSLOG_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
diff --git a/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h b/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h
index aaddcfa307da..924ca189381b 100644
--- a/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h
+++ b/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h
@@ -32,6 +32,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/Frontend/OpenMP/OMPAssume.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/Frontend/OpenMP/OMPContext.h"
#include "llvm/Support/Casting.h"
@@ -106,6 +107,89 @@ public:
static bool classof(const OMPClause *) { return true; }
};
+template <OpenMPClauseKind ClauseKind>
+struct OMPNoChildClause : public OMPClause {
+ /// Build '\p ClauseKind' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPNoChildClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(ClauseKind, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPNoChildClause()
+ : OMPClause(ClauseKind, SourceLocation(), SourceLocation()) {}
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == ClauseKind;
+ }
+};
+
+template <OpenMPClauseKind ClauseKind, class Base>
+class OMPOneStmtClause : public Base {
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// Sub-expression.
+ Stmt *S = nullptr;
+
+protected:
+ void setStmt(Stmt *S) { this->S = S; }
+
+public:
+ OMPOneStmtClause(Stmt *S, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : Base(ClauseKind, StartLoc, EndLoc), LParenLoc(LParenLoc), S(S) {}
+
+ OMPOneStmtClause() : Base(ClauseKind, SourceLocation(), SourceLocation()) {}
+
+ /// Return the associated statement, potentially casted to \p T.
+ template <typename T> T *getStmtAs() const { return cast_or_null<T>(S); }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ using child_iterator = StmtIterator;
+ using const_child_iterator = ConstStmtIterator;
+ using child_range = llvm::iterator_range<child_iterator>;
+ using const_child_range = llvm::iterator_range<const_child_iterator>;
+
+ child_range children() { return child_range(&S, &S + 1); }
+
+ const_child_range children() const { return const_child_range(&S, &S + 1); }
+
+ // TODO: Consider making the getAddrOfExprAsWritten version the default.
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == ClauseKind;
+ }
+};
+
/// Class that handles pre-initialization statement for some clauses, like
/// 'shedule', 'firstprivate' etc.
class OMPClauseWithPreInit {
@@ -252,7 +336,7 @@ public:
/// Fetches list of all variables in the clause.
ArrayRef<const Expr *> getVarRefs() const {
- return llvm::makeArrayRef(
+ return llvm::ArrayRef(
static_cast<const T *>(this)->template getTrailingObjects<Expr *>(),
NumVars);
}
@@ -266,17 +350,12 @@ public:
/// \endcode
/// In this example directive '#pragma omp allocate' has simple 'allocator'
/// clause with the allocator 'omp_default_mem_alloc'.
-class OMPAllocatorClause : public OMPClause {
+class OMPAllocatorClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_allocator, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Expression with the allocator.
- Stmt *Allocator = nullptr;
-
/// Set allocator.
- void setAllocator(Expr *A) { Allocator = A; }
+ void setAllocator(Expr *A) { setStmt(A); }
public:
/// Build 'allocator' clause with the given allocator.
@@ -287,39 +366,58 @@ public:
/// \param EndLoc Ending location of the clause.
OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Allocator(A) {}
+ : OMPOneStmtClause(A, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- OMPAllocatorClause()
- : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(),
- SourceLocation()) {}
+ OMPAllocatorClause() : OMPOneStmtClause() {}
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// Returns allocator.
+ Expr *getAllocator() const { return getStmtAs<Expr>(); }
+};
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+/// This represents the 'align' clause in the '#pragma omp allocate'
+/// directive.
+///
+/// \code
+/// #pragma omp allocate(a) allocator(omp_default_mem_alloc) align(8)
+/// \endcode
+/// In this example directive '#pragma omp allocate' has simple 'allocator'
+/// clause with the allocator 'omp_default_mem_alloc' and align clause with
+/// value of 8.
+class OMPAlignClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_align, OMPClause> {
+ friend class OMPClauseReader;
- /// Returns allocator.
- Expr *getAllocator() const { return cast_or_null<Expr>(Allocator); }
+ /// Set alignment value.
+ void setAlignment(Expr *A) { setStmt(A); }
- child_range children() { return child_range(&Allocator, &Allocator + 1); }
+ /// Build 'align' clause with the given alignment
+ ///
+ /// \param A Alignment value.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPAlignClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPOneStmtClause(A, StartLoc, LParenLoc, EndLoc) {}
- const_child_range children() const {
- return const_child_range(&Allocator, &Allocator + 1);
- }
+ /// Build an empty clause.
+ OMPAlignClause() : OMPOneStmtClause() {}
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
+public:
+ /// Build 'align' clause with the given alignment
+ ///
+ /// \param A Alignment value.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ static OMPAlignClause *Create(const ASTContext &C, Expr *A,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_allocator;
- }
+ /// Returns alignment
+ Expr *getAlignment() const { return getStmtAs<Expr>(); }
};
/// This represents clause 'allocate' in the '#pragma omp ...' directives.
@@ -527,17 +625,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp task' has simple 'final'
/// clause with condition 'a > 5'.
-class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit {
+class OMPFinalClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_final, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'if' clause.
- Stmt *Condition = nullptr;
-
/// Set condition.
- void setCondition(Expr *Cond) { Condition = Cond; }
+ void setCondition(Expr *Cond) { setStmt(Cond); }
public:
/// Build 'final' clause with condition \a Cond.
@@ -552,42 +646,23 @@ public:
OMPFinalClause(Expr *Cond, Stmt *HelperCond,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
+ : OMPOneStmtClause(Cond, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
- OMPFinalClause()
- : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPFinalClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-
- const_child_range children() const {
- return const_child_range(&Condition, &Condition + 1);
- }
+ Expr *getCondition() const { return getStmtAs<Expr>(); }
child_range used_children();
const_child_range used_children() const {
auto Children = const_cast<OMPFinalClause *>(this)->used_children();
return const_child_range(Children.begin(), Children.end());
}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_final;
- }
};
-
/// This represents 'num_threads' clause in the '#pragma omp ...'
/// directive.
///
@@ -596,17 +671,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'num_threads'
/// clause with number of threads '6'.
-class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit {
+class OMPNumThreadsClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_num_threads, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'num_threads' clause.
- Stmt *NumThreads = nullptr;
-
/// Set condition.
- void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
+ void setNumThreads(Expr *NThreads) { setStmt(NThreads); }
public:
/// Build 'num_threads' clause with condition \a NumThreads.
@@ -622,43 +693,16 @@ public:
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc),
- NumThreads(NumThreads) {
+ : OMPOneStmtClause(NumThreads, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperNumThreads, CaptureRegion);
}
/// Build an empty clause.
- OMPNumThreadsClause()
- : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(),
- SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPNumThreadsClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns number of threads.
- Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
-
- child_range children() { return child_range(&NumThreads, &NumThreads + 1); }
-
- const_child_range children() const {
- return const_child_range(&NumThreads, &NumThreads + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_num_threads;
- }
+ Expr *getNumThreads() const { return getStmtAs<Expr>(); }
};
/// This represents 'safelen' clause in the '#pragma omp ...'
@@ -673,17 +717,12 @@ public:
/// concurrently with SIMD instructions can have a greater distance
/// in the logical iteration space than its value. The parameter of
/// the safelen clause must be a constant positive integer expression.
-class OMPSafelenClause : public OMPClause {
+class OMPSafelenClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_safelen, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Safe iteration space distance.
- Stmt *Safelen = nullptr;
-
/// Set safelen.
- void setSafelen(Expr *Len) { Safelen = Len; }
+ void setSafelen(Expr *Len) { setStmt(Len); }
public:
/// Build 'safelen' clause.
@@ -693,39 +732,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Safelen(Len) {}
+ : OMPOneStmtClause(Len, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- explicit OMPSafelenClause()
- : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) {
- }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ explicit OMPSafelenClause() : OMPOneStmtClause() {}
/// Return safe iteration space distance.
- Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
-
- child_range children() { return child_range(&Safelen, &Safelen + 1); }
-
- const_child_range children() const {
- return const_child_range(&Safelen, &Safelen + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_safelen;
- }
+ Expr *getSafelen() const { return getStmtAs<Expr>(); }
};
/// This represents 'simdlen' clause in the '#pragma omp ...'
@@ -739,17 +752,12 @@ public:
/// If the 'simdlen' clause is used then it specifies the preferred number of
/// iterations to be executed concurrently. The parameter of the 'simdlen'
/// clause must be a constant positive integer expression.
-class OMPSimdlenClause : public OMPClause {
+class OMPSimdlenClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_simdlen, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Safe iteration space distance.
- Stmt *Simdlen = nullptr;
-
/// Set simdlen.
- void setSimdlen(Expr *Len) { Simdlen = Len; }
+ void setSimdlen(Expr *Len) { setStmt(Len); }
public:
/// Build 'simdlen' clause.
@@ -759,39 +767,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Simdlen(Len) {}
+ : OMPOneStmtClause(Len, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- explicit OMPSimdlenClause()
- : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) {
- }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ explicit OMPSimdlenClause() : OMPOneStmtClause() {}
/// Return safe iteration space distance.
- Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); }
-
- child_range children() { return child_range(&Simdlen, &Simdlen + 1); }
-
- const_child_range children() const {
- return const_child_range(&Simdlen, &Simdlen + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_simdlen;
- }
+ Expr *getSimdlen() const { return getStmtAs<Expr>(); }
};
/// This represents the 'sizes' clause in the '#pragma omp tile' directive.
@@ -894,11 +876,11 @@ public:
/// #pragma omp unroll full
/// for (int i = 0; i < 64; ++i)
/// \endcode
-class OMPFullClause final : public OMPClause {
+class OMPFullClause final : public OMPNoChildClause<llvm::omp::OMPC_full> {
friend class OMPClauseReader;
/// Build an empty clause.
- explicit OMPFullClause() : OMPClause(llvm::omp::OMPC_full, {}, {}) {}
+ explicit OMPFullClause() : OMPNoChildClause() {}
public:
/// Build an AST node for a 'full' clause.
@@ -913,22 +895,6 @@ public:
///
/// \param C Context of the AST.
static OMPFullClause *CreateEmpty(const ASTContext &C);
-
- child_range children() { return {child_iterator(), child_iterator()}; }
- const_child_range children() const {
- return {const_child_iterator(), const_child_iterator()};
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_full;
- }
};
/// Representation of the 'partial' clause of the '#pragma omp unroll'
@@ -1007,17 +973,12 @@ public:
/// The parameter must be a constant positive integer expression, it specifies
/// the number of nested loops that should be collapsed into a single iteration
/// space.
-class OMPCollapseClause : public OMPClause {
+class OMPCollapseClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_collapse, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Number of for-loops.
- Stmt *NumForLoops = nullptr;
-
/// Set the number of associated for-loops.
- void setNumForLoops(Expr *Num) { NumForLoops = Num; }
+ void setNumForLoops(Expr *Num) { setStmt(Num); }
public:
/// Build 'collapse' clause.
@@ -1028,39 +989,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc),
- LParenLoc(LParenLoc), NumForLoops(Num) {}
+ : OMPOneStmtClause(Num, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- explicit OMPCollapseClause()
- : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(),
- SourceLocation()) {}
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ explicit OMPCollapseClause() : OMPOneStmtClause() {}
/// Return the number of associated for-loops.
- Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
-
- child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
-
- const_child_range children() const {
- return const_child_range(&NumForLoops, &NumForLoops + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_collapse;
- }
+ Expr *getNumForLoops() const { return getStmtAs<Expr>(); }
};
/// This represents 'default' clause in the '#pragma omp ...' directive.
@@ -1233,7 +1168,8 @@ public:
/// \endcode
/// In this example directive '#pragma omp requires' has 'unified_address'
/// clause.
-class OMPUnifiedAddressClause final : public OMPClause {
+class OMPUnifiedAddressClause final
+ : public OMPNoChildClause<llvm::omp::OMPC_unified_address> {
public:
friend class OMPClauseReader;
/// Build 'unified_address' clause.
@@ -1241,31 +1177,10 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {}
+ : OMPNoChildClause(StartLoc, EndLoc) {}
/// Build an empty clause.
- OMPUnifiedAddressClause()
- : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(),
- SourceLocation()) {}
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_unified_address;
- }
+ OMPUnifiedAddressClause() : OMPNoChildClause() {}
};
/// This represents 'unified_shared_memory' clause in the '#pragma omp requires'
@@ -1487,6 +1402,231 @@ public:
}
};
+/// This represents 'at' clause in the '#pragma omp error' directive
+///
+/// \code
+/// #pragma omp error at(compilation)
+/// \endcode
+/// In this example directive '#pragma omp error' has simple
+/// 'at' clause with kind 'complilation'.
+class OMPAtClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('
+ SourceLocation LParenLoc;
+
+ /// A kind of the 'at' clause.
+ OpenMPAtClauseKind Kind = OMPC_AT_unknown;
+
+ /// Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// Set kind of the clause.
+ ///
+ /// \param K Kind of clause.
+ void setAtKind(OpenMPAtClauseKind K) { Kind = K; }
+
+ /// Set clause kind location.
+ ///
+ /// \param KLoc Kind location.
+ void setAtKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+ /// Build 'at' clause with argument \a A ('compilation' or 'execution').
+ ///
+ /// \param A Argument of the clause ('compilation' or 'execution').
+ /// \param ALoc Starting location of the argument.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPAtClause(OpenMPAtClauseKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_at, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Kind(A), KindKwLoc(ALoc) {}
+
+ /// Build an empty clause.
+ OMPAtClause()
+ : OMPClause(llvm::omp::OMPC_at, SourceLocation(), SourceLocation()) {}
+
+ /// Returns the locaiton of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns kind of the clause.
+ OpenMPAtClauseKind getAtKind() const { return Kind; }
+
+ /// Returns location of clause kind.
+ SourceLocation getAtKindKwLoc() const { return KindKwLoc; }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_at;
+ }
+};
+
+/// This represents 'severity' clause in the '#pragma omp error' directive
+///
+/// \code
+/// #pragma omp error severity(fatal)
+/// \endcode
+/// In this example directive '#pragma omp error' has simple
+/// 'severity' clause with kind 'fatal'.
+class OMPSeverityClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('
+ SourceLocation LParenLoc;
+
+ /// A kind of the 'severity' clause.
+ OpenMPSeverityClauseKind Kind = OMPC_SEVERITY_unknown;
+
+ /// Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// Set kind of the clause.
+ ///
+ /// \param K Kind of clause.
+ void setSeverityKind(OpenMPSeverityClauseKind K) { Kind = K; }
+
+ /// Set clause kind location.
+ ///
+ /// \param KLoc Kind location.
+ void setSeverityKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+ /// Build 'severity' clause with argument \a A ('fatal' or 'warning').
+ ///
+ /// \param A Argument of the clause ('fatal' or 'warning').
+ /// \param ALoc Starting location of the argument.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPSeverityClause(OpenMPSeverityClauseKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_severity, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
+
+ /// Build an empty clause.
+ OMPSeverityClause()
+ : OMPClause(llvm::omp::OMPC_severity, SourceLocation(),
+ SourceLocation()) {}
+
+ /// Returns the locaiton of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns kind of the clause.
+ OpenMPSeverityClauseKind getSeverityKind() const { return Kind; }
+
+ /// Returns location of clause kind.
+ SourceLocation getSeverityKindKwLoc() const { return KindKwLoc; }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_severity;
+ }
+};
+
+/// This represents 'message' clause in the '#pragma omp error' directive
+///
+/// \code
+/// #pragma omp error message("GNU compiler required.")
+/// \endcode
+/// In this example directive '#pragma omp error' has simple
+/// 'message' clause with user error message of "GNU compiler required.".
+class OMPMessageClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('
+ SourceLocation LParenLoc;
+
+ // Expression of the 'message' clause.
+ Stmt *MessageString = nullptr;
+
+ /// Set message string of the clause.
+ void setMessageString(Expr *MS) { MessageString = MS; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+ /// Build 'message' clause with message string argument
+ ///
+ /// \param MS Argument of the clause (message string).
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPMessageClause(Expr *MS, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_message, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), MessageString(MS) {}
+
+ /// Build an empty clause.
+ OMPMessageClause()
+ : OMPClause(llvm::omp::OMPC_message, SourceLocation(), SourceLocation()) {
+ }
+
+ /// Returns the locaiton of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns message string of the clause.
+ Expr *getMessageString() const { return cast_or_null<Expr>(MessageString); }
+
+ child_range children() {
+ return child_range(&MessageString, &MessageString + 1);
+ }
+
+ const_child_range children() const {
+ return const_child_range(&MessageString, &MessageString + 1);
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_message;
+ }
+};
+
/// This represents 'schedule' clause in the '#pragma omp ...' directive.
///
/// \code
@@ -1782,37 +1922,15 @@ public:
/// #pragma omp for nowait
/// \endcode
/// In this example directive '#pragma omp for' has 'nowait' clause.
-class OMPNowaitClause : public OMPClause {
+class OMPNowaitClause final : public OMPNoChildClause<llvm::omp::OMPC_nowait> {
public:
/// Build 'nowait' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {}
-
- /// Build an empty clause.
- OMPNowaitClause()
- : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {}
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_nowait;
- }
+ OMPNowaitClause(SourceLocation StartLoc = SourceLocation(),
+ SourceLocation EndLoc = SourceLocation())
+ : OMPNoChildClause(StartLoc, EndLoc) {}
};
/// This represents 'untied' clause in the '#pragma omp ...' directive.
@@ -2005,13 +2123,13 @@ class OMPUpdateClause final
return IsExtended ? 2 : 0;
}
- /// Sets the the location of '(' in clause for 'depobj' directive.
+ /// Sets the location of '(' in clause for 'depobj' directive.
void setLParenLoc(SourceLocation Loc) {
assert(IsExtended && "Expected extended clause.");
*getTrailingObjects<SourceLocation>() = Loc;
}
- /// Sets the the location of '(' in clause for 'depobj' directive.
+ /// Sets the location of '(' in clause for 'depobj' directive.
void setArgumentLoc(SourceLocation Loc) {
assert(IsExtended && "Expected extended clause.");
*std::next(getTrailingObjects<SourceLocation>(), 1) = Loc;
@@ -2085,13 +2203,13 @@ public:
return const_child_range(const_child_iterator(), const_child_iterator());
}
- /// Gets the the location of '(' in clause for 'depobj' directive.
+ /// Gets the location of '(' in clause for 'depobj' directive.
SourceLocation getLParenLoc() const {
assert(IsExtended && "Expected extended clause.");
return *getTrailingObjects<SourceLocation>();
}
- /// Gets the the location of argument in clause for 'depobj' directive.
+ /// Gets the location of argument in clause for 'depobj' directive.
SourceLocation getArgumentLoc() const {
assert(IsExtended && "Expected extended clause.");
return *std::next(getTrailingObjects<SourceLocation>(), 1);
@@ -2149,6 +2267,47 @@ public:
}
};
+/// This represents 'compare' clause in the '#pragma omp atomic'
+/// directive.
+///
+/// \code
+/// #pragma omp atomic compare
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'compare' clause.
+class OMPCompareClause final : public OMPClause {
+public:
+ /// Build 'compare' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPCompareClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_compare, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPCompareClause()
+ : OMPClause(llvm::omp::OMPC_compare, SourceLocation(), SourceLocation()) {
+ }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_compare;
+ }
+};
+
/// This represents 'seq_cst' clause in the '#pragma omp atomic'
/// directive.
///
@@ -2354,6 +2513,89 @@ public:
}
};
+/// This represents 'fail' clause in the '#pragma omp atomic'
+/// directive.
+///
+/// \code
+/// #pragma omp atomic compare fail
+/// \endcode
+/// In this example directive '#pragma omp atomic compare' has 'fail' clause.
+class OMPFailClause final : public OMPClause {
+
+ // FailParameter is a memory-order-clause. Storing the ClauseKind is
+ // sufficient for our purpose.
+ OpenMPClauseKind FailParameter = llvm::omp::Clause::OMPC_unknown;
+ SourceLocation FailParameterLoc;
+ SourceLocation LParenLoc;
+
+ friend class OMPClauseReader;
+
+ /// Sets the location of '(' in fail clause.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Sets the location of memoryOrder clause argument in fail clause.
+ void setFailParameterLoc(SourceLocation Loc) { FailParameterLoc = Loc; }
+
+ /// Sets the mem_order clause for 'atomic compare fail' directive.
+ void setFailParameter(OpenMPClauseKind FailParameter) {
+ this->FailParameter = FailParameter;
+ assert(checkFailClauseParameter(FailParameter) &&
+ "Invalid fail clause parameter");
+ }
+
+public:
+ /// Build 'fail' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPFailClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_fail, StartLoc, EndLoc) {}
+
+ OMPFailClause(OpenMPClauseKind FailParameter, SourceLocation FailParameterLoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_fail, StartLoc, EndLoc),
+ FailParameterLoc(FailParameterLoc), LParenLoc(LParenLoc) {
+
+ setFailParameter(FailParameter);
+ }
+
+ /// Build an empty clause.
+ OMPFailClause()
+ : OMPClause(llvm::omp::OMPC_fail, SourceLocation(), SourceLocation()) {}
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_fail;
+ }
+
+ /// Gets the location of '(' (for the parameter) in fail clause.
+ SourceLocation getLParenLoc() const {
+ return LParenLoc;
+ }
+
+ /// Gets the location of Fail Parameter (type memory-order-clause) in
+ /// fail clause.
+ SourceLocation getFailParameterLoc() const { return FailParameterLoc; }
+
+ /// Gets the parameter (type memory-order-clause) in Fail clause.
+ OpenMPClauseKind getFailParameter() const { return FailParameter; }
+};
+
/// This represents clause 'private' in the '#pragma omp ...' directives.
///
/// \code
@@ -2398,7 +2640,7 @@ class OMPPrivateClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
public:
@@ -2507,7 +2749,7 @@ class OMPFirstprivateClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Sets the list of references to initializer variables for new
@@ -2521,7 +2763,7 @@ class OMPFirstprivateClause final
return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
}
ArrayRef<const Expr *> getInits() const {
- return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
+ return llvm::ArrayRef(getPrivateCopies().end(), varlist_size());
}
public:
@@ -2669,7 +2911,7 @@ class OMPLastprivateClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -2683,7 +2925,7 @@ class OMPLastprivateClause final
return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
}
ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
+ return llvm::ArrayRef(getPrivateCopies().end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -2697,7 +2939,7 @@ class OMPLastprivateClause final
return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
+ return llvm::ArrayRef(getSourceExprs().end(), varlist_size());
}
/// Set list of helper assignment expressions, required for proper
@@ -2710,7 +2952,7 @@ class OMPLastprivateClause final
return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
+ return llvm::ArrayRef(getDestinationExprs().end(), varlist_size());
}
/// Sets lastprivate kind.
@@ -2998,7 +3240,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -3011,7 +3253,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
}
ArrayRef<const Expr *> getLHSExprs() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
+ return llvm::ArrayRef(getPrivates().end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -3026,7 +3268,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getRHSExprs() const {
- return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getLHSExprs().end(), varlist_size());
}
/// Set list of helper reduction expressions, required for proper
@@ -3040,7 +3282,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getReductionOps() const {
- return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getRHSExprs().end(), varlist_size());
}
/// Set list of helper copy operations for inscan reductions.
@@ -3052,7 +3294,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size());
}
ArrayRef<const Expr *> getInscanCopyOps() const {
- return llvm::makeArrayRef(getReductionOps().end(), varlist_size());
+ return llvm::ArrayRef(getReductionOps().end(), varlist_size());
}
/// Set list of helper temp vars for inscan copy array operations.
@@ -3063,7 +3305,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(getInscanCopyOps().end(), varlist_size());
}
ArrayRef<const Expr *> getInscanCopyArrayTemps() const {
- return llvm::makeArrayRef(getInscanCopyOps().end(), varlist_size());
+ return llvm::ArrayRef(getInscanCopyOps().end(), varlist_size());
}
/// Set list of helper temp elements vars for inscan copy array operations.
@@ -3075,7 +3317,7 @@ class OMPReductionClause final
varlist_size());
}
ArrayRef<const Expr *> getInscanCopyArrayElems() const {
- return llvm::makeArrayRef(getInscanCopyArrayTemps().end(), varlist_size());
+ return llvm::ArrayRef(getInscanCopyArrayTemps().end(), varlist_size());
}
public:
@@ -3317,7 +3559,7 @@ class OMPTaskReductionClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the clause.
@@ -3330,7 +3572,7 @@ class OMPTaskReductionClause final
return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
}
ArrayRef<const Expr *> getLHSExprs() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
+ return llvm::ArrayRef(getPrivates().end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the clause.
@@ -3344,7 +3586,7 @@ class OMPTaskReductionClause final
return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getRHSExprs() const {
- return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getLHSExprs().end(), varlist_size());
}
/// Set list of helper reduction expressions, required for proper
@@ -3358,7 +3600,7 @@ class OMPTaskReductionClause final
return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getReductionOps() const {
- return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getRHSExprs().end(), varlist_size());
}
public:
@@ -3548,7 +3790,7 @@ class OMPInReductionClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the clause.
@@ -3561,7 +3803,7 @@ class OMPInReductionClause final
return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
}
ArrayRef<const Expr *> getLHSExprs() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
+ return llvm::ArrayRef(getPrivates().end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the clause.
@@ -3575,7 +3817,7 @@ class OMPInReductionClause final
return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getRHSExprs() const {
- return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getLHSExprs().end(), varlist_size());
}
/// Set list of helper reduction expressions, required for proper
@@ -3589,7 +3831,7 @@ class OMPInReductionClause final
return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getReductionOps() const {
- return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getRHSExprs().end(), varlist_size());
}
/// Set list of helper reduction taskgroup descriptors.
@@ -3600,7 +3842,7 @@ class OMPInReductionClause final
return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size());
}
ArrayRef<const Expr *> getTaskgroupDescriptors() const {
- return llvm::makeArrayRef(getReductionOps().end(), varlist_size());
+ return llvm::ArrayRef(getReductionOps().end(), varlist_size());
}
public:
@@ -3759,6 +4001,9 @@ class OMPLinearClause final
/// Location of ':'.
SourceLocation ColonLoc;
+ /// Location of 'step' modifier.
+ SourceLocation StepModifierLoc;
+
/// Sets the linear step for clause.
void setStep(Expr *Step) { *(getFinals().end()) = Step; }
@@ -3770,16 +4015,18 @@ class OMPLinearClause final
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param ColonLoc Location of ':'.
+ /// \param StepModifierLoc Location of 'step' modifier.
/// \param EndLoc Ending location of the clause.
/// \param NumVars Number of variables.
OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc,
- unsigned NumVars)
+ SourceLocation ColonLoc, SourceLocation StepModifierLoc,
+ SourceLocation EndLoc, unsigned NumVars)
: OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear, StartLoc,
LParenLoc, EndLoc, NumVars),
OMPClauseWithPostUpdate(this), Modifier(Modifier),
- ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {}
+ ModifierLoc(ModifierLoc), ColonLoc(ColonLoc),
+ StepModifierLoc(StepModifierLoc) {}
/// Build an empty clause.
///
@@ -3806,14 +4053,14 @@ class OMPLinearClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
MutableArrayRef<Expr *> getInits() {
return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
}
ArrayRef<const Expr *> getInits() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
+ return llvm::ArrayRef(getPrivates().end(), varlist_size());
}
/// Sets the list of update expressions for linear variables.
@@ -3821,7 +4068,7 @@ class OMPLinearClause final
return MutableArrayRef<Expr *>(getInits().end(), varlist_size());
}
ArrayRef<const Expr *> getUpdates() const {
- return llvm::makeArrayRef(getInits().end(), varlist_size());
+ return llvm::ArrayRef(getInits().end(), varlist_size());
}
/// Sets the list of final update expressions for linear variables.
@@ -3829,7 +4076,7 @@ class OMPLinearClause final
return MutableArrayRef<Expr *>(getUpdates().end(), varlist_size());
}
ArrayRef<const Expr *> getFinals() const {
- return llvm::makeArrayRef(getUpdates().end(), varlist_size());
+ return llvm::ArrayRef(getUpdates().end(), varlist_size());
}
/// Gets the list of used expressions for linear variables.
@@ -3837,7 +4084,7 @@ class OMPLinearClause final
return MutableArrayRef<Expr *>(getFinals().end() + 2, varlist_size() + 1);
}
ArrayRef<const Expr *> getUsedExprs() const {
- return llvm::makeArrayRef(getFinals().end() + 2, varlist_size() + 1);
+ return llvm::ArrayRef(getFinals().end() + 2, varlist_size() + 1);
}
/// Sets the list of the copies of original linear variables.
@@ -3858,6 +4105,7 @@ public:
/// \param Modifier Modifier of 'linear' clause.
/// \param ModifierLoc Modifier location.
/// \param ColonLoc Location of ':'.
+ /// \param StepModifierLoc Location of 'step' modifier.
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
/// \param PL List of private copies of original variables.
@@ -3871,9 +4119,10 @@ public:
static OMPLinearClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
- ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
- Stmt *PreInit, Expr *PostUpdate);
+ SourceLocation ColonLoc, SourceLocation StepModifierLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL,
+ ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,
+ Expr *PostUpdate);
/// Creates an empty clause with the place for \a NumVars variables.
///
@@ -3896,9 +4145,15 @@ public:
/// Sets the location of ':'.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ /// Sets the location of 'step' modifier.
+ void setStepModifierLoc(SourceLocation Loc) { StepModifierLoc = Loc; }
+
/// Returns the location of ':'.
SourceLocation getColonLoc() const { return ColonLoc; }
+ /// Returns the location of 'step' modifier.
+ SourceLocation getStepModifierLoc() const { return StepModifierLoc; }
+
/// Returns linear step.
Expr *getStep() { return *(getFinals().end()); }
@@ -4166,7 +4421,7 @@ class OMPCopyinClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -4179,7 +4434,7 @@ class OMPCopyinClause final
return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
+ return llvm::ArrayRef(getSourceExprs().end(), varlist_size());
}
/// Set list of helper assignment expressions, required for proper
@@ -4193,7 +4448,7 @@ class OMPCopyinClause final
return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
+ return llvm::ArrayRef(getDestinationExprs().end(), varlist_size());
}
public:
@@ -4331,7 +4586,7 @@ class OMPCopyprivateClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -4344,7 +4599,7 @@ class OMPCopyprivateClause final
return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
+ return llvm::ArrayRef(getSourceExprs().end(), varlist_size());
}
/// Set list of helper assignment expressions, required for proper
@@ -4358,7 +4613,7 @@ class OMPCopyprivateClause final
return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
+ return llvm::ArrayRef(getDestinationExprs().end(), varlist_size());
}
public:
@@ -4629,14 +4884,24 @@ class OMPDependClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// Dependency type (one of in, out, inout).
- OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
+public:
+ struct DependDataTy final {
+ /// Dependency type (one of in, out, inout).
+ OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
- /// Dependency type location.
- SourceLocation DepLoc;
+ /// Dependency type location.
+ SourceLocation DepLoc;
- /// Colon location.
- SourceLocation ColonLoc;
+ /// Colon location.
+ SourceLocation ColonLoc;
+
+ /// Location of 'omp_all_memory'.
+ SourceLocation OmpAllMemoryLoc;
+ };
+
+private:
+ /// Dependency type and source locations.
+ DependDataTy Data;
/// Number of loops, associated with the depend clause.
unsigned NumLoops = 0;
@@ -4667,13 +4932,16 @@ class OMPDependClause final
NumLoops(NumLoops) {}
/// Set dependency kind.
- void setDependencyKind(OpenMPDependClauseKind K) { DepKind = K; }
+ void setDependencyKind(OpenMPDependClauseKind K) { Data.DepKind = K; }
/// Set dependency kind and its location.
- void setDependencyLoc(SourceLocation Loc) { DepLoc = Loc; }
+ void setDependencyLoc(SourceLocation Loc) { Data.DepLoc = Loc; }
/// Set colon location.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ void setColonLoc(SourceLocation Loc) { Data.ColonLoc = Loc; }
+
+ /// Set the 'omp_all_memory' location.
+ void setOmpAllMemoryLoc(SourceLocation Loc) { Data.OmpAllMemoryLoc = Loc; }
/// Sets optional dependency modifier.
void setModifier(Expr *DepModifier);
@@ -4685,18 +4953,15 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- /// \param DepKind Dependency type.
- /// \param DepLoc Location of the dependency type.
- /// \param ColonLoc Colon location.
+ /// \param Data Dependency type and source locations.
/// \param VL List of references to the variables.
/// \param NumLoops Number of loops that is associated with this depend
/// clause.
static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc,
- SourceLocation EndLoc, Expr *DepModifier,
- OpenMPDependClauseKind DepKind,
- SourceLocation DepLoc, SourceLocation ColonLoc,
- ArrayRef<Expr *> VL, unsigned NumLoops);
+ SourceLocation EndLoc, DependDataTy Data,
+ Expr *DepModifier, ArrayRef<Expr *> VL,
+ unsigned NumLoops);
/// Creates an empty clause with \a N variables.
///
@@ -4708,7 +4973,16 @@ public:
unsigned NumLoops);
/// Get dependency type.
- OpenMPDependClauseKind getDependencyKind() const { return DepKind; }
+ OpenMPDependClauseKind getDependencyKind() const { return Data.DepKind; }
+
+ /// Get dependency type location.
+ SourceLocation getDependencyLoc() const { return Data.DepLoc; }
+
+ /// Get colon location.
+ SourceLocation getColonLoc() const { return Data.ColonLoc; }
+
+ /// Get 'omp_all_memory' location.
+ SourceLocation getOmpAllMemoryLoc() const { return Data.OmpAllMemoryLoc; }
/// Return optional depend modifier.
Expr *getModifier();
@@ -4716,12 +4990,6 @@ public:
return const_cast<OMPDependClause *>(this)->getModifier();
}
- /// Get dependency type location.
- SourceLocation getDependencyLoc() const { return DepLoc; }
-
- /// Get colon location.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
/// Get number of loops associated with the clause.
unsigned getNumLoops() const { return NumLoops; }
@@ -4857,38 +5125,18 @@ public:
/// #pragma omp ordered threads
/// \endcode
/// In this example directive '#pragma omp ordered' has simple 'threads' clause.
-class OMPThreadsClause : public OMPClause {
+class OMPThreadsClause final
+ : public OMPNoChildClause<llvm::omp::OMPC_threads> {
public:
/// Build 'threads' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {}
+ : OMPNoChildClause(StartLoc, EndLoc) {}
/// Build an empty clause.
- OMPThreadsClause()
- : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) {
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_threads;
- }
+ OMPThreadsClause() : OMPNoChildClause() {}
};
/// This represents 'simd' clause in the '#pragma omp ...' directive.
@@ -5273,7 +5521,7 @@ protected:
MutableArrayRef<Expr *> getUDMapperRefs() {
assert(SupportsMapper &&
"Must be a clause that is possible to have user-defined mappers");
- return llvm::makeMutableArrayRef<Expr *>(
+ return llvm::MutableArrayRef<Expr *>(
static_cast<T *>(this)->template getTrailingObjects<Expr *>() +
OMPVarListClause<T>::varlist_size(),
OMPVarListClause<T>::varlist_size());
@@ -5284,7 +5532,7 @@ protected:
ArrayRef<Expr *> getUDMapperRefs() const {
assert(SupportsMapper &&
"Must be a clause that is possible to have user-defined mappers");
- return llvm::makeArrayRef<Expr *>(
+ return llvm::ArrayRef<Expr *>(
static_cast<const T *>(this)->template getTrailingObjects<Expr *>() +
OMPVarListClause<T>::varlist_size(),
OMPVarListClause<T>::varlist_size());
@@ -5483,14 +5731,14 @@ public:
return const_component_lists_iterator(
getUniqueDeclsRef(), getDeclNumListsRef(), getComponentListSizesRef(),
getComponentsRef(), SupportsMapper,
- SupportsMapper ? getUDMapperRefs() : llvm::None);
+ SupportsMapper ? getUDMapperRefs() : std::nullopt);
}
const_component_lists_iterator component_lists_end() const {
return const_component_lists_iterator(
ArrayRef<ValueDecl *>(), ArrayRef<unsigned>(), ArrayRef<unsigned>(),
MappableExprComponentListRef(getComponentsRef().end(),
getComponentsRef().end()),
- SupportsMapper, llvm::None);
+ SupportsMapper, std::nullopt);
}
const_component_lists_range component_lists() const {
return {component_lists_begin(), component_lists_end()};
@@ -5503,7 +5751,7 @@ public:
return const_component_lists_iterator(
VD, getUniqueDeclsRef(), getDeclNumListsRef(),
getComponentListSizesRef(), getComponentsRef(), SupportsMapper,
- SupportsMapper ? getUDMapperRefs() : llvm::None);
+ SupportsMapper ? getUDMapperRefs() : std::nullopt);
}
const_component_lists_iterator decl_component_lists_end() const {
return component_lists_end();
@@ -5593,7 +5841,7 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
size_t numTrailingObjects(OverloadToken<Expr *>) const {
// There are varlist_size() of expressions, and varlist_size() of
// user-defined mappers.
- return 2 * varlist_size();
+ return 2 * varlist_size() + 1;
}
size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
return getUniqueDeclarationsNum();
@@ -5606,6 +5854,7 @@ private:
/// Map-type-modifiers for the 'map' clause.
OpenMPMapModifierKind MapTypeModifiers[NumberOfOMPMapClauseModifiers] = {
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
+ OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
/// Location of map-type-modifiers for the 'map' clause.
@@ -5654,12 +5903,11 @@ private:
/*SupportsMapper=*/true, &MapperQualifierLoc,
&MapperIdInfo),
MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {
- assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() &&
+ assert(std::size(MapTypeModifiers) == MapModifiers.size() &&
"Unexpected number of map type modifiers.");
llvm::copy(MapModifiers, std::begin(MapTypeModifiers));
- assert(llvm::array_lengthof(MapTypeModifiersLoc) ==
- MapModifiersLoc.size() &&
+ assert(std::size(MapTypeModifiersLoc) == MapModifiersLoc.size() &&
"Unexpected number of map type modifier locations.");
llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc));
}
@@ -5708,6 +5956,11 @@ private:
/// Set colon location.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ /// Set iterator modifier.
+ void setIteratorModifier(Expr *IteratorModifier) {
+ getTrailingObjects<Expr *>()[2 * varlist_size()] = IteratorModifier;
+ }
+
public:
/// Creates clause with a list of variables \a VL.
///
@@ -5720,6 +5973,7 @@ public:
/// \param ComponentLists Component lists used in the clause.
/// \param UDMapperRefs References to user-defined mappers associated with
/// expressions used in the clause.
+ /// \param IteratorModifier Iterator modifier.
/// \param MapModifiers Map-type-modifiers.
/// \param MapModifiersLoc Location of map-type-modifiers.
/// \param UDMQualifierLoc C++ nested name specifier for the associated
@@ -5732,7 +5986,7 @@ public:
Create(const ASTContext &C, const OMPVarListLocTy &Locs,
ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists,
- ArrayRef<Expr *> UDMapperRefs,
+ ArrayRef<Expr *> UDMapperRefs, Expr *IteratorModifier,
ArrayRef<OpenMPMapModifierKind> MapModifiers,
ArrayRef<SourceLocation> MapModifiersLoc,
NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
@@ -5751,6 +6005,11 @@ public:
static OMPMapClause *CreateEmpty(const ASTContext &C,
const OMPMappableExprListSizeTy &Sizes);
+ /// Fetches Expr * of iterator modifier.
+ Expr *getIteratorModifier() {
+ return getTrailingObjects<Expr *>()[2 * varlist_size()];
+ }
+
/// Fetches mapping kind for the clause.
OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; }
@@ -5782,12 +6041,12 @@ public:
/// Fetches ArrayRef of map-type-modifiers.
ArrayRef<OpenMPMapModifierKind> getMapTypeModifiers() const LLVM_READONLY {
- return llvm::makeArrayRef(MapTypeModifiers);
+ return llvm::ArrayRef(MapTypeModifiers);
}
/// Fetches ArrayRef of location of map-type-modifiers.
ArrayRef<SourceLocation> getMapTypeModifiersLoc() const LLVM_READONLY {
- return llvm::makeArrayRef(MapTypeModifiersLoc);
+ return llvm::ArrayRef(MapTypeModifiersLoc);
}
/// Fetches location of clause mapping kind.
@@ -6065,26 +6324,43 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit {
/// Location of '('.
SourceLocation LParenLoc;
+ /// Modifiers for 'grainsize' clause.
+ OpenMPGrainsizeClauseModifier Modifier = OMPC_GRAINSIZE_unknown;
+
+ /// Location of the modifier.
+ SourceLocation ModifierLoc;
+
/// Safe iteration space distance.
Stmt *Grainsize = nullptr;
/// Set safelen.
void setGrainsize(Expr *Size) { Grainsize = Size; }
+ /// Sets modifier.
+ void setModifier(OpenMPGrainsizeClauseModifier M) { Modifier = M; }
+
+ /// Sets modifier location.
+ void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }
+
public:
/// Build 'grainsize' clause.
///
+ /// \param Modifier Clause modifier.
/// \param Size Expression associated with this clause.
/// \param HelperSize Helper grainsize for the construct.
/// \param CaptureRegion Innermost OpenMP region where expressions in this
/// clause must be captured.
/// \param StartLoc Starting location of the clause.
+ /// \param ModifierLoc Modifier location.
+ /// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- OMPGrainsizeClause(Expr *Size, Stmt *HelperSize,
- OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
+ OMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, Expr *Size,
+ Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ModifierLoc, SourceLocation EndLoc)
: OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) {
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier),
+ ModifierLoc(ModifierLoc), Grainsize(Size) {
setPreInitStmt(HelperSize, CaptureRegion);
}
@@ -6103,6 +6379,12 @@ public:
/// Return safe iteration space distance.
Expr *getGrainsize() const { return cast_or_null<Expr>(Grainsize); }
+ /// Gets modifier.
+ OpenMPGrainsizeClauseModifier getModifier() const { return Modifier; }
+
+ /// Gets modifier location.
+ SourceLocation getModifierLoc() const { return ModifierLoc; }
+
child_range children() { return child_range(&Grainsize, &Grainsize + 1); }
const_child_range children() const {
@@ -6174,26 +6456,43 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit {
/// Location of '('.
SourceLocation LParenLoc;
+ /// Modifiers for 'num_tasks' clause.
+ OpenMPNumTasksClauseModifier Modifier = OMPC_NUMTASKS_unknown;
+
+ /// Location of the modifier.
+ SourceLocation ModifierLoc;
+
/// Safe iteration space distance.
Stmt *NumTasks = nullptr;
/// Set safelen.
void setNumTasks(Expr *Size) { NumTasks = Size; }
+ /// Sets modifier.
+ void setModifier(OpenMPNumTasksClauseModifier M) { Modifier = M; }
+
+ /// Sets modifier location.
+ void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }
+
public:
/// Build 'num_tasks' clause.
///
+ /// \param Modifier Clause modifier.
/// \param Size Expression associated with this clause.
/// \param HelperSize Helper grainsize for the construct.
/// \param CaptureRegion Innermost OpenMP region where expressions in this
/// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- OMPNumTasksClause(Expr *Size, Stmt *HelperSize,
- OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
+ /// \param ModifierLoc Modifier location.
+ /// \param LParenLoc Location of '('.
+ OMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, Expr *Size,
+ Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ModifierLoc, SourceLocation EndLoc)
: OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) {
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier),
+ ModifierLoc(ModifierLoc), NumTasks(Size) {
setPreInitStmt(HelperSize, CaptureRegion);
}
@@ -6212,6 +6511,12 @@ public:
/// Return safe iteration space distance.
Expr *getNumTasks() const { return cast_or_null<Expr>(NumTasks); }
+ /// Gets modifier.
+ OpenMPNumTasksClauseModifier getModifier() const { return Modifier; }
+
+ /// Gets modifier location.
+ SourceLocation getModifierLoc() const { return ModifierLoc; }
+
child_range children() { return child_range(&NumTasks, &NumTasks + 1); }
const_child_range children() const {
@@ -6576,12 +6881,11 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
: OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes,
/*SupportsMapper=*/true, &MapperQualifierLoc,
&MapperIdInfo) {
- assert(llvm::array_lengthof(MotionModifiers) == TheMotionModifiers.size() &&
+ assert(std::size(MotionModifiers) == TheMotionModifiers.size() &&
"Unexpected number of motion modifiers.");
llvm::copy(TheMotionModifiers, std::begin(MotionModifiers));
- assert(llvm::array_lengthof(MotionModifiersLoc) ==
- TheMotionModifiersLoc.size() &&
+ assert(std::size(MotionModifiersLoc) == TheMotionModifiersLoc.size() &&
"Unexpected number of motion modifier locations.");
llvm::copy(TheMotionModifiersLoc, std::begin(MotionModifiersLoc));
}
@@ -6693,12 +6997,12 @@ public:
/// Fetches ArrayRef of motion-modifiers.
ArrayRef<OpenMPMotionModifierKind> getMotionModifiers() const LLVM_READONLY {
- return llvm::makeArrayRef(MotionModifiers);
+ return llvm::ArrayRef(MotionModifiers);
}
/// Fetches ArrayRef of location of motion-modifiers.
ArrayRef<SourceLocation> getMotionModifiersLoc() const LLVM_READONLY {
- return llvm::makeArrayRef(MotionModifiersLoc);
+ return llvm::ArrayRef(MotionModifiersLoc);
}
/// Get colon location.
@@ -6778,12 +7082,11 @@ class OMPFromClause final
: OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes,
/*SupportsMapper=*/true, &MapperQualifierLoc,
&MapperIdInfo) {
- assert(llvm::array_lengthof(MotionModifiers) == TheMotionModifiers.size() &&
+ assert(std::size(MotionModifiers) == TheMotionModifiers.size() &&
"Unexpected number of motion modifiers.");
llvm::copy(TheMotionModifiers, std::begin(MotionModifiers));
- assert(llvm::array_lengthof(MotionModifiersLoc) ==
- TheMotionModifiersLoc.size() &&
+ assert(std::size(MotionModifiersLoc) == TheMotionModifiersLoc.size() &&
"Unexpected number of motion modifier locations.");
llvm::copy(TheMotionModifiersLoc, std::begin(MotionModifiersLoc));
}
@@ -6894,12 +7197,12 @@ public:
/// Fetches ArrayRef of motion-modifiers.
ArrayRef<OpenMPMotionModifierKind> getMotionModifiers() const LLVM_READONLY {
- return llvm::makeArrayRef(MotionModifiers);
+ return llvm::ArrayRef(MotionModifiers);
}
/// Fetches ArrayRef of location of motion-modifiers.
ArrayRef<SourceLocation> getMotionModifiersLoc() const LLVM_READONLY {
- return llvm::makeArrayRef(MotionModifiersLoc);
+ return llvm::ArrayRef(MotionModifiersLoc);
}
/// Get colon location.
@@ -6994,7 +7297,7 @@ class OMPUseDevicePtrClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Sets the list of references to initializer variables for new private
@@ -7008,7 +7311,7 @@ class OMPUseDevicePtrClause final
return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
}
ArrayRef<const Expr *> getInits() const {
- return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
+ return llvm::ArrayRef(getPrivateCopies().end(), varlist_size());
}
public:
@@ -7298,6 +7601,110 @@ public:
}
};
+/// This represents clause 'has_device_ptr' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp target has_device_addr(a,b)
+/// \endcode
+/// In this example directive '#pragma omp target' has clause
+/// 'has_device_ptr' with the variables 'a' and 'b'.
+class OMPHasDeviceAddrClause final
+ : public OMPMappableExprListClause<OMPHasDeviceAddrClause>,
+ private llvm::TrailingObjects<
+ OMPHasDeviceAddrClause, Expr *, ValueDecl *, unsigned,
+ OMPClauseMappableExprCommon::MappableComponent> {
+ friend class OMPClauseReader;
+ friend OMPMappableExprListClause;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Build clause with number of variables \a NumVars.
+ ///
+ /// \param Locs Locations needed to build a mappable clause. It includes 1)
+ /// StartLoc: starting location of the clause (the clause keyword); 2)
+ /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
+ /// \param Sizes All required sizes to build a mappable clause. It includes 1)
+ /// NumVars: number of expressions listed in this clause; 2)
+ /// NumUniqueDeclarations: number of unique base declarations in this clause;
+ /// 3) NumComponentLists: number of component lists in this clause; and 4)
+ /// NumComponents: total number of expression components in the clause.
+ explicit OMPHasDeviceAddrClause(const OMPVarListLocTy &Locs,
+ const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(llvm::omp::OMPC_has_device_addr, Locs,
+ Sizes) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param Sizes All required sizes to build a mappable clause. It includes 1)
+ /// NumVars: number of expressions listed in this clause; 2)
+ /// NumUniqueDeclarations: number of unique base declarations in this clause;
+ /// 3) NumComponentLists: number of component lists in this clause; and 4)
+ /// NumComponents: total number of expression components in the clause.
+ explicit OMPHasDeviceAddrClause(const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(llvm::omp::OMPC_has_device_addr,
+ OMPVarListLocTy(), Sizes) {}
+
+ /// Define the sizes of each trailing object array except the last one. This
+ /// is required for TrailingObjects to work properly.
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return varlist_size();
+ }
+ size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
+ return getUniqueDeclarationsNum();
+ }
+ size_t numTrailingObjects(OverloadToken<unsigned>) const {
+ return getUniqueDeclarationsNum() + getTotalComponentListNum();
+ }
+
+public:
+ /// Creates clause with a list of variables \a Vars.
+ ///
+ /// \param C AST context.
+ /// \param Locs Locations needed to build a mappable clause. It includes 1)
+ /// StartLoc: starting location of the clause (the clause keyword); 2)
+ /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
+ /// \param Vars The original expression used in the clause.
+ /// \param Declarations Declarations used in the clause.
+ /// \param ComponentLists Component lists used in the clause.
+ static OMPHasDeviceAddrClause *
+ Create(const ASTContext &C, const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
+ MappableExprComponentListsRef ComponentLists);
+
+ /// Creates an empty clause with the place for \a NumVars variables.
+ ///
+ /// \param C AST context.
+ /// \param Sizes All required sizes to build a mappable clause. It includes 1)
+ /// NumVars: number of expressions listed in this clause; 2)
+ /// NumUniqueDeclarations: number of unique base declarations in this clause;
+ /// 3) NumComponentLists: number of component lists in this clause; and 4)
+ /// NumComponents: total number of expression components in the clause.
+ static OMPHasDeviceAddrClause *
+ CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes);
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<OMPHasDeviceAddrClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_has_device_addr;
+ }
+};
+
/// This represents clause 'nontemporal' in the '#pragma omp ...' directives.
///
/// \code
@@ -7338,7 +7745,7 @@ class OMPNontemporalClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateRefs() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
public:
@@ -7408,12 +7815,18 @@ class OMPOrderClause final : public OMPClause {
/// Location of '('.
SourceLocation LParenLoc;
- /// A kind of the 'default' clause.
+ /// A kind of the 'order' clause.
OpenMPOrderClauseKind Kind = OMPC_ORDER_unknown;
/// Start location of the kind in source code.
SourceLocation KindKwLoc;
+ /// A modifier for order clause
+ OpenMPOrderClauseModifier Modifier = OMPC_ORDER_MODIFIER_unknown;
+
+ /// Start location of the modifier in source code.
+ SourceLocation ModifierKwLoc;
+
/// Set kind of the clause.
///
/// \param K Argument of clause.
@@ -7424,6 +7837,16 @@ class OMPOrderClause final : public OMPClause {
/// \param KLoc Argument location.
void setKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+ /// Set modifier of the clause.
+ ///
+ /// \param M Argument of clause.
+ void setModifier(OpenMPOrderClauseModifier M) { Modifier = M; }
+
+ /// Set modifier location.
+ ///
+ /// \param MLoc Modifier keyword location.
+ void setModifierKwLoc(SourceLocation MLoc) { ModifierKwLoc = MLoc; }
+
public:
/// Build 'order' clause with argument \p A ('concurrent').
///
@@ -7432,11 +7855,15 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
+ /// \param Modifier The modifier applied to 'order' clause.
+ /// \param MLoc Location of the modifier
OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
+ SourceLocation EndLoc, OpenMPOrderClauseModifier Modifier,
+ SourceLocation MLoc)
: OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
+ LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc), Modifier(Modifier),
+ ModifierKwLoc(MLoc) {}
/// Build an empty clause.
OMPOrderClause()
@@ -7454,6 +7881,12 @@ public:
/// Returns location of clause kind.
SourceLocation getKindKwLoc() const { return KindKwLoc; }
+ /// Returns Modifier of the clause.
+ OpenMPOrderClauseModifier getModifier() const { return Modifier; }
+
+ /// Returns location of clause modifier.
+ SourceLocation getModifierKwLoc() const { return ModifierKwLoc; }
+
child_range children() {
return child_range(child_iterator(), child_iterator());
}
@@ -7528,16 +7961,14 @@ public:
///
/// \param C AST context.
/// \param InteropVar The interop variable.
- /// \param PrefExprs The list of preference expressions.
- /// \param IsTarget Uses the 'target' interop-type.
- /// \param IsTargetSync Uses the 'targetsync' interop-type.
+ /// \param InteropInfo The interop-type and prefer_type list.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param VarLoc Location of the interop variable.
/// \param EndLoc Ending location of the clause.
static OMPInitClause *Create(const ASTContext &C, Expr *InteropVar,
- ArrayRef<Expr *> PrefExprs, bool IsTarget,
- bool IsTargetSync, SourceLocation StartLoc,
+ OMPInteropInfo &InteropInfo,
+ SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation VarLoc,
SourceLocation EndLoc);
@@ -7764,21 +8195,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp dispatch' has simple 'novariants'
/// clause with condition 'a > 5'.
-class OMPNovariantsClause final : public OMPClause,
- public OMPClauseWithPreInit {
+class OMPNovariantsClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_novariants, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'if' clause.
- Stmt *Condition = nullptr;
-
/// Set condition.
- void setCondition(Expr *Cond) { Condition = Cond; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setCondition(Expr *Cond) { setStmt(Cond); }
public:
/// Build 'novariants' clause with condition \a Cond.
@@ -7794,38 +8217,22 @@ public:
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_novariants, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
+ : OMPOneStmtClause(Cond, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
- OMPNovariantsClause()
- : OMPClause(llvm::omp::OMPC_novariants, SourceLocation(),
- SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPNovariantsClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-
- const_child_range children() const {
- return const_child_range(&Condition, &Condition + 1);
- }
+ Expr *getCondition() const { return getStmtAs<Expr>(); }
child_range used_children();
const_child_range used_children() const {
auto Children = const_cast<OMPNovariantsClause *>(this)->used_children();
return const_child_range(Children.begin(), Children.end());
}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_novariants;
- }
};
/// This represents 'nocontext' clause in the '#pragma omp ...' directive.
@@ -7835,20 +8242,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp dispatch' has simple 'nocontext'
/// clause with condition 'a > 5'.
-class OMPNocontextClause final : public OMPClause, public OMPClauseWithPreInit {
+class OMPNocontextClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_nocontext, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'if' clause.
- Stmt *Condition = nullptr;
-
/// Set condition.
- void setCondition(Expr *Cond) { Condition = Cond; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setCondition(Expr *Cond) { setStmt(Cond); }
public:
/// Build 'nocontext' clause with condition \a Cond.
@@ -7863,38 +8263,22 @@ public:
OMPNocontextClause(Expr *Cond, Stmt *HelperCond,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_nocontext, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
+ : OMPOneStmtClause(Cond, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
- OMPNocontextClause()
- : OMPClause(llvm::omp::OMPC_nocontext, SourceLocation(),
- SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPNocontextClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-
- const_child_range children() const {
- return const_child_range(&Condition, &Condition + 1);
- }
+ Expr *getCondition() const { return getStmtAs<Expr>(); }
child_range used_children();
const_child_range used_children() const {
auto Children = const_cast<OMPNocontextClause *>(this)->used_children();
return const_child_range(Children.begin(), Children.end());
}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_nocontext;
- }
};
/// This represents 'detach' clause in the '#pragma omp task' directive.
@@ -7904,20 +8288,12 @@ public:
/// \endcode
/// In this example directive '#pragma omp detach' has simple 'detach' clause
/// with the variable 'evt'.
-class OMPDetachClause final : public OMPClause {
+class OMPDetachClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_detach, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Expression of the 'detach' clause.
- Stmt *Evt = nullptr;
-
/// Set condition.
- void setEventHandler(Expr *E) { Evt = E; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setEventHandler(Expr *E) { setStmt(E); }
public:
/// Build 'detach' clause with event-handler \a Evt.
@@ -7928,35 +8304,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Evt(Evt) {}
+ : OMPOneStmtClause(Evt, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- OMPDetachClause()
- : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {}
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPDetachClause() : OMPOneStmtClause() {}
/// Returns event-handler expression.
- Expr *getEventHandler() const { return cast_or_null<Expr>(Evt); }
-
- child_range children() { return child_range(&Evt, &Evt + 1); }
-
- const_child_range children() const {
- return const_child_range(&Evt, &Evt + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_detach;
- }
+ Expr *getEventHandler() const { return getStmtAs<Expr>(); }
};
/// This represents clause 'inclusive' in the '#pragma omp scan' directive.
@@ -8156,14 +8510,14 @@ private:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- /// \param N Number of allocators asssociated with the clause.
+ /// \param N Number of allocators associated with the clause.
OMPUsesAllocatorsClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPClause(llvm::omp::OMPC_uses_allocators, StartLoc, EndLoc),
LParenLoc(LParenLoc), NumOfAllocators(N) {}
/// Build an empty clause.
- /// \param N Number of allocators asssociated with the clause.
+ /// \param N Number of allocators associated with the clause.
///
explicit OMPUsesAllocatorsClause(unsigned N)
: OMPClause(llvm::omp::OMPC_uses_allocators, SourceLocation(),
@@ -8257,14 +8611,14 @@ class OMPAffinityClause final
/// \param LParenLoc Location of '('.
/// \param ColonLoc Location of ':'.
/// \param EndLoc Ending location of the clause.
- /// \param N Number of locators asssociated with the clause.
+ /// \param N Number of locators associated with the clause.
OMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity, StartLoc,
LParenLoc, EndLoc, N) {}
/// Build an empty clause.
- /// \param N Number of locators asssociated with the clause.
+ /// \param N Number of locators associated with the clause.
///
explicit OMPAffinityClause(unsigned N)
: OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity,
@@ -8340,20 +8694,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp masked' has 'filter' clause with
/// thread id.
-class OMPFilterClause final : public OMPClause, public OMPClauseWithPreInit {
+class OMPFilterClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_filter, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Express of the 'filter' clause.
- Stmt *ThreadID = nullptr;
-
/// Sets the thread identifier.
- void setThreadID(Expr *TID) { ThreadID = TID; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setThreadID(Expr *TID) { setStmt(TID); }
public:
/// Build 'filter' clause with thread-id \a ThreadID.
@@ -8368,40 +8715,89 @@ public:
OMPFilterClause(Expr *ThreadID, Stmt *HelperE,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_filter, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadID(ThreadID) {
+ : OMPOneStmtClause(ThreadID, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperE, CaptureRegion);
}
/// Build an empty clause.
- OMPFilterClause()
- : OMPClause(llvm::omp::OMPC_filter, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this) {}
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPFilterClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Return thread identifier.
- Expr *getThreadID() { return cast<Expr>(ThreadID); }
+ Expr *getThreadID() const { return getStmtAs<Expr>(); }
/// Return thread identifier.
- Expr *getThreadID() const { return cast<Expr>(ThreadID); }
+ Expr *getThreadID() { return getStmtAs<Expr>(); }
+};
+
+/// This represents 'bind' clause in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp loop bind(parallel)
+/// \endcode
+class OMPBindClause final : public OMPNoChildClause<llvm::omp::OMPC_bind> {
+ friend class OMPClauseReader;
- child_range children() { return child_range(&ThreadID, &ThreadID + 1); }
+ /// Location of '('.
+ SourceLocation LParenLoc;
- const_child_range children() const {
- return const_child_range(&ThreadID, &ThreadID + 1);
- }
+ /// The binding kind of 'bind' clause.
+ OpenMPBindClauseKind Kind = OMPC_BIND_unknown;
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
+ /// Start location of the kind in source code.
+ SourceLocation KindLoc;
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_filter;
- }
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Set the binding kind.
+ void setBindKind(OpenMPBindClauseKind K) { Kind = K; }
+
+ /// Set the binding kind location.
+ void setBindKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+
+ /// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread').
+ ///
+ /// \param K Binding kind of the clause ('teams', 'parallel' or 'thread').
+ /// \param KLoc Starting location of the binding kind.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPBindClause(OpenMPBindClauseKind K, SourceLocation KLoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPNoChildClause(StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(K),
+ KindLoc(KLoc) {}
+
+ /// Build an empty clause.
+ OMPBindClause() : OMPNoChildClause() {}
+
+public:
+ /// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread').
+ ///
+ /// \param C AST context
+ /// \param K Binding kind of the clause ('teams', 'parallel' or 'thread').
+ /// \param KLoc Starting location of the binding kind.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ static OMPBindClause *Create(const ASTContext &C, OpenMPBindClauseKind K,
+ SourceLocation KLoc, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc);
+
+ /// Build an empty 'bind' clause.
+ ///
+ /// \param C AST context
+ static OMPBindClause *CreateEmpty(const ASTContext &C);
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns kind of the clause.
+ OpenMPBindClauseKind getBindKind() const { return Kind; }
+
+ /// Returns location of clause kind.
+ SourceLocation getBindKindLoc() const { return KindLoc; }
};
/// This class implements a simple visitor for OMPClause
@@ -8546,10 +8942,11 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI);
/// Clang specific specialization of the OMPContext to lookup target features.
struct TargetOMPContext final : public llvm::omp::OMPContext {
-
TargetOMPContext(ASTContext &ASTCtx,
std::function<void(StringRef)> &&DiagUnknownTrait,
- const FunctionDecl *CurrentFunctionDecl);
+ const FunctionDecl *CurrentFunctionDecl,
+ ArrayRef<llvm::omp::TraitProperty> ConstructTraits);
+
virtual ~TargetOMPContext() = default;
/// See llvm::omp::OMPContext::matchesISATrait
@@ -8630,7 +9027,7 @@ public:
/// Get the clauses storage.
MutableArrayRef<OMPClause *> getClauses() {
- return llvm::makeMutableArrayRef(getTrailingObjects<OMPClause *>(),
+ return llvm::MutableArrayRef(getTrailingObjects<OMPClause *>(),
NumClauses);
}
ArrayRef<OMPClause *> getClauses() const {
@@ -8644,9 +9041,7 @@ public:
const CapturedStmt *
getCapturedStmt(OpenMPDirectiveKind RegionKind,
ArrayRef<OpenMPDirectiveKind> CaptureRegions) const {
- assert(llvm::any_of(
- CaptureRegions,
- [=](const OpenMPDirectiveKind K) { return K == RegionKind; }) &&
+ assert(llvm::is_contained(CaptureRegions, RegionKind) &&
"RegionKind not found in OpenMP CaptureRegions.");
auto *CS = cast<CapturedStmt>(getAssociatedStmt());
for (auto ThisCaptureRegion : CaptureRegions) {
@@ -8705,6 +9100,243 @@ public:
}
};
+/// This represents 'ompx_dyn_cgroup_mem' clause in the '#pragma omp target ...'
+/// directive.
+///
+/// \code
+/// #pragma omp target [...] ompx_dyn_cgroup_mem(N)
+/// \endcode
+class OMPXDynCGroupMemClause
+ : public OMPOneStmtClause<llvm::omp::OMPC_ompx_dyn_cgroup_mem, OMPClause>,
+ public OMPClauseWithPreInit {
+ friend class OMPClauseReader;
+
+ /// Set size.
+ void setSize(Expr *E) { setStmt(E); }
+
+public:
+ /// Build 'ompx_dyn_cgroup_mem' clause.
+ ///
+ /// \param Size Size expression.
+ /// \param HelperSize Helper Size expression
+ /// \param CaptureRegion Innermost OpenMP region where expressions in this
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPXDynCGroupMemClause(Expr *Size, Stmt *HelperSize,
+ OpenMPDirectiveKind CaptureRegion,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPOneStmtClause(Size, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
+ setPreInitStmt(HelperSize, CaptureRegion);
+ }
+
+ /// Build an empty clause.
+ OMPXDynCGroupMemClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
+
+ /// Return the size expression.
+ Expr *getSize() { return getStmtAs<Expr>(); }
+
+ /// Return the size expression.
+ Expr *getSize() const { return getStmtAs<Expr>(); }
+};
+
+/// This represents the 'doacross' clause for the '#pragma omp ordered'
+/// directive.
+///
+/// \code
+/// #pragma omp ordered doacross(sink: i-1, j-1)
+/// \endcode
+/// In this example directive '#pragma omp ordered' with clause 'doacross' with
+/// a dependence-type 'sink' and loop-iteration vector expressions i-1 and j-1.
+class OMPDoacrossClause final
+ : public OMPVarListClause<OMPDoacrossClause>,
+ private llvm::TrailingObjects<OMPDoacrossClause, Expr *> {
+ friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Dependence type (sink or source).
+ OpenMPDoacrossClauseModifier DepType = OMPC_DOACROSS_unknown;
+
+ /// Dependence type location.
+ SourceLocation DepLoc;
+
+ /// Colon location.
+ SourceLocation ColonLoc;
+
+ /// Number of loops, associated with the doacross clause.
+ unsigned NumLoops = 0;
+
+ /// Build clause with number of expressions \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of expressions in the clause.
+ /// \param NumLoops Number of loops associated with the clause.
+ OMPDoacrossClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N, unsigned NumLoops)
+ : OMPVarListClause<OMPDoacrossClause>(llvm::omp::OMPC_doacross, StartLoc,
+ LParenLoc, EndLoc, N),
+ NumLoops(NumLoops) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param N Number of expressions in the clause.
+ /// \param NumLoops Number of loops associated with the clause.
+ explicit OMPDoacrossClause(unsigned N, unsigned NumLoops)
+ : OMPVarListClause<OMPDoacrossClause>(llvm::omp::OMPC_doacross,
+ SourceLocation(), SourceLocation(),
+ SourceLocation(), N),
+ NumLoops(NumLoops) {}
+
+ /// Set dependence type.
+ void setDependenceType(OpenMPDoacrossClauseModifier M) { DepType = M; }
+
+ /// Set dependence type location.
+ void setDependenceLoc(SourceLocation Loc) { DepLoc = Loc; }
+
+ /// Set colon location.
+ void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+
+public:
+ /// Creates clause with a list of expressions \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param DepType The dependence type.
+ /// \param DepLoc Location of the dependence type.
+ /// \param ColonLoc Location of ':'.
+ /// \param VL List of references to the expressions.
+ /// \param NumLoops Number of loops that associated with the clause.
+ static OMPDoacrossClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, OpenMPDoacrossClauseModifier DepType,
+ SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
+ unsigned NumLoops);
+
+ /// Creates an empty clause with \a N expressions.
+ ///
+ /// \param C AST context.
+ /// \param N The number of expressions.
+ /// \param NumLoops Number of loops that is associated with this clause.
+ static OMPDoacrossClause *CreateEmpty(const ASTContext &C, unsigned N,
+ unsigned NumLoops);
+
+ /// Get dependence type.
+ OpenMPDoacrossClauseModifier getDependenceType() const { return DepType; }
+
+ /// Get dependence type location.
+ SourceLocation getDependenceLoc() const { return DepLoc; }
+
+ /// Get colon location.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+
+ /// Get number of loops associated with the clause.
+ unsigned getNumLoops() const { return NumLoops; }
+
+ /// Set the loop data.
+ void setLoopData(unsigned NumLoop, Expr *Cnt);
+
+ /// Get the loop data.
+ Expr *getLoopData(unsigned NumLoop);
+ const Expr *getLoopData(unsigned NumLoop) const;
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<OMPDoacrossClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_doacross;
+ }
+};
+
+/// This represents 'ompx_attribute' clause in a directive that might generate
+/// an outlined function. An example is given below.
+///
+/// \code
+/// #pragma omp target [...] ompx_attribute(flatten)
+/// \endcode
+class OMPXAttributeClause
+ : public OMPNoChildClause<llvm::omp::OMPC_ompx_attribute> {
+ friend class OMPClauseReader;
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// The parsed attributes (clause arguments)
+ SmallVector<const Attr *> Attrs;
+
+public:
+ /// Build 'ompx_attribute' clause.
+ ///
+ /// \param Attrs The parsed attributes (clause arguments)
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPXAttributeClause(ArrayRef<const Attr *> Attrs, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc)
+ : OMPNoChildClause(StartLoc, EndLoc), LParenLoc(LParenLoc), Attrs(Attrs) {
+ }
+
+ /// Build an empty clause.
+ OMPXAttributeClause() : OMPNoChildClause() {}
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returned the attributes parsed from this clause.
+ ArrayRef<const Attr *> getAttrs() const { return Attrs; }
+
+private:
+ /// Replace the attributes with \p NewAttrs.
+ void setAttrs(ArrayRef<Attr *> NewAttrs) {
+ Attrs.clear();
+ Attrs.append(NewAttrs.begin(), NewAttrs.end());
+ }
+};
+
+/// This represents 'ompx_bare' clause in the '#pragma omp target teams ...'
+/// directive.
+///
+/// \code
+/// #pragma omp target teams ompx_bare
+/// \endcode
+/// In this example directive '#pragma omp target teams' has a 'ompx_bare'
+/// clause.
+class OMPXBareClause : public OMPNoChildClause<llvm::omp::OMPC_ompx_bare> {
+public:
+ /// Build 'ompx_bare' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPXBareClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPNoChildClause(StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPXBareClause() = default;
+};
+
} // namespace clang
#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def b/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def
index b05b9d81569e..8dd98730dff7 100644
--- a/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def
+++ b/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def
@@ -80,6 +80,7 @@ CAST_OPERATION(LValueToRValue)
/// (possibly) adding qualifiers or removing noexcept.
/// int -> int
/// char** -> const char * const *
+/// int[1] -> int[]
/// void () noexcept -> void ()
CAST_OPERATION(NoOp)
@@ -362,8 +363,8 @@ CAST_OPERATION(IntToOCLSampler)
//===- Binary Operations -------------------------------------------------===//
// Operators listed in order of precedence.
-// Note that additions to this should also update the StmtVisitor class and
-// BinaryOperator::getOverloadedOperator.
+// Note that additions to this should also update the StmtVisitor class,
+// BinaryOperator::getOverloadedOperator and CXBinaryOperatorKind enum.
// [C++ 5.5] Pointer-to-member operators.
BINARY_OPERATION(PtrMemD, ".*")
@@ -415,8 +416,8 @@ BINARY_OPERATION(Comma, ",")
//===- Unary Operations ---------------------------------------------------===//
-// Note that additions to this should also update the StmtVisitor class and
-// UnaryOperator::getOverloadedOperator.
+// Note that additions to this should also update the StmtVisitor class,
+// UnaryOperator::getOverloadedOperator and CXUnaryOperatorKind enum.
// [C99 6.5.2.4] Postfix increment and decrement
UNARY_OPERATION(PostInc, "++")
diff --git a/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h b/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h
index 2edbc987850d..d3b2e3986a99 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h
@@ -77,7 +77,7 @@ class TraversalKindScope {
TraversalKind TK = TK_AsIs;
public:
- TraversalKindScope(ASTContext &ASTCtx, llvm::Optional<TraversalKind> ScopeTK)
+ TraversalKindScope(ASTContext &ASTCtx, std::optional<TraversalKind> ScopeTK)
: Ctx(ASTCtx.getParentMapContext()) {
TK = Ctx.getTraversalKind();
if (ScopeTK)
@@ -90,29 +90,27 @@ public:
/// Container for either a single DynTypedNode or for an ArrayRef to
/// DynTypedNode. For use with ParentMap.
class DynTypedNodeList {
- llvm::AlignedCharArrayUnion<DynTypedNode, ArrayRef<DynTypedNode>> Storage;
+ union {
+ DynTypedNode SingleNode;
+ ArrayRef<DynTypedNode> Nodes;
+ };
bool IsSingleNode;
public:
DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
- new (&Storage) DynTypedNode(N);
+ new (&SingleNode) DynTypedNode(N);
}
DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
- new (&Storage) ArrayRef<DynTypedNode>(A);
+ new (&Nodes) ArrayRef<DynTypedNode>(A);
}
const DynTypedNode *begin() const {
- if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(&Storage)
- ->begin();
- return reinterpret_cast<const DynTypedNode *>(&Storage);
+ return !IsSingleNode ? Nodes.begin() : &SingleNode;
}
const DynTypedNode *end() const {
- if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(&Storage)->end();
- return reinterpret_cast<const DynTypedNode *>(&Storage) + 1;
+ return !IsSingleNode ? Nodes.end() : &SingleNode + 1;
}
size_t size() const { return end() - begin(); }
diff --git a/contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h b/contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h
index 899bbcb3be45..82df031d4126 100644
--- a/contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h
+++ b/contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h
@@ -22,7 +22,6 @@ namespace clang {
class ASTContext;
class Decl;
-class SourceManager;
/// PrettyDeclStackTraceEntry - If a crash occurs in the parser while
/// parsing something related to a declaration, include that
diff --git a/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h b/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h
index 3baf2b2ba94d..da276e26049b 100644
--- a/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h
+++ b/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h
@@ -20,9 +20,7 @@ namespace clang {
class DeclContext;
class LangOptions;
-class SourceManager;
class Stmt;
-class TagDecl;
class PrinterHelper {
public:
@@ -62,19 +60,24 @@ struct PrintingPolicy {
: Indentation(2), SuppressSpecifiers(false),
SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false),
SuppressScope(false), SuppressUnwrittenScope(false),
- SuppressInlineNamespace(true), SuppressInitializers(false),
- ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
- SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
+ SuppressInlineNamespace(true), SuppressElaboration(false),
+ SuppressInitializers(false), ConstantArraySizeAsWritten(false),
+ AnonymousTagLocations(true), SuppressStrongLifetime(false),
+ SuppressLifetimeQualifiers(false),
SuppressTemplateArgsInCXXConstructors(false),
SuppressDefaultTemplateArgs(true), Bool(LO.Bool),
- Nullptr(LO.CPlusPlus11), Restrict(LO.C99), Alignof(LO.CPlusPlus11),
- UnderscoreAlignof(LO.C11), UseVoidForZeroParams(!LO.CPlusPlus),
+ Nullptr(LO.CPlusPlus11 || LO.C23), NullptrTypeInNamespace(LO.CPlusPlus),
+ Restrict(LO.C99), Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11),
+ UseVoidForZeroParams(!LO.CPlusPlus),
SplitTemplateClosers(!LO.CPlusPlus11), TerseOutput(false),
PolishForDeclaration(false), Half(LO.Half),
MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
MSVCFormatting(false), ConstantsAsWritten(false),
SuppressImplicitBase(false), FullyQualifiedName(false),
- PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true) {}
+ PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true),
+ UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false),
+ CleanUglifiedParameters(false), EntireContentsOfLargeArray(true),
+ UseEnumerators(true) {}
/// Adjust this printing policy for cases where it's known that we're
/// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -103,6 +106,7 @@ struct PrintingPolicy {
/// declaration for "x", so that we will print "int *x"; it will be
/// \c true when we print "y", so that we suppress printing the
/// "const int" type specifier and instead only print the "*y".
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressSpecifiers : 1;
/// Whether type printing should skip printing the tag keyword.
@@ -113,6 +117,7 @@ struct PrintingPolicy {
/// \code
/// struct Geometry::Point;
/// \endcode
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressTagKeyword : 1;
/// When true, include the body of a tag definition.
@@ -123,20 +128,29 @@ struct PrintingPolicy {
/// \code
/// typedef struct { int x, y; } Point;
/// \endcode
+ LLVM_PREFERRED_TYPE(bool)
unsigned IncludeTagDefinition : 1;
/// Suppresses printing of scope specifiers.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressScope : 1;
/// Suppress printing parts of scope specifiers that are never
/// written, e.g., for anonymous namespaces.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressUnwrittenScope : 1;
/// Suppress printing parts of scope specifiers that correspond
/// to inline namespaces, where the name is unambiguous with the specifier
/// removed.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressInlineNamespace : 1;
+ /// Ignore qualifiers and tag keywords as specified by elaborated type sugar,
+ /// instead letting the underlying type print as normal.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned SuppressElaboration : 1;
+
/// Suppress printing of variable initializers.
///
/// This flag is used when printing the loop variable in a for-range
@@ -148,6 +162,7 @@ struct PrintingPolicy {
///
/// SuppressInitializers will be true when printing "auto x", so that the
/// internal initializer constructed for x will not be printed.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressInitializers : 1;
/// Whether we should print the sizes of constant array expressions as written
@@ -166,50 +181,67 @@ struct PrintingPolicy {
/// int a[104];
/// char a[9] = "A string";
/// \endcode
+ LLVM_PREFERRED_TYPE(bool)
unsigned ConstantArraySizeAsWritten : 1;
/// When printing an anonymous tag name, also print the location of that
/// entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just prints
/// "(anonymous)" for the name.
+ LLVM_PREFERRED_TYPE(bool)
unsigned AnonymousTagLocations : 1;
/// When true, suppress printing of the __strong lifetime qualifier in ARC.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressStrongLifetime : 1;
/// When true, suppress printing of lifetime qualifier in ARC.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressLifetimeQualifiers : 1;
/// When true, suppresses printing template arguments in names of C++
/// constructors.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressTemplateArgsInCXXConstructors : 1;
/// When true, attempt to suppress template arguments that match the default
/// argument for the parameter.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressDefaultTemplateArgs : 1;
/// Whether we can use 'bool' rather than '_Bool' (even if the language
/// doesn't actually have 'bool', because, e.g., it is defined as a macro).
+ LLVM_PREFERRED_TYPE(bool)
unsigned Bool : 1;
/// Whether we should use 'nullptr' rather than '0' as a null pointer
/// constant.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Nullptr : 1;
+ /// Whether 'nullptr_t' is in namespace 'std' or not.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned NullptrTypeInNamespace : 1;
+
/// Whether we can use 'restrict' rather than '__restrict'.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Restrict : 1;
/// Whether we can use 'alignof' rather than '__alignof'.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Alignof : 1;
/// Whether we can use '_Alignof' rather than '__alignof'.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UnderscoreAlignof : 1;
/// Whether we should use '(void)' rather than '()' for a function prototype
/// with zero parameters.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseVoidForZeroParams : 1;
/// Whether nested templates must be closed like 'a\<b\<c\> \>' rather than
/// 'a\<b\<c\>\>'.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SplitTemplateClosers : 1;
/// Provide a 'terse' output.
@@ -217,27 +249,33 @@ struct PrintingPolicy {
/// For example, in this mode we don't print function bodies, class members,
/// declarations inside namespaces etc. Effectively, this should print
/// only the requested declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned TerseOutput : 1;
/// When true, do certain refinement needed for producing proper declaration
/// tag; such as, do not print attributes attached to the declaration.
///
+ LLVM_PREFERRED_TYPE(bool)
unsigned PolishForDeclaration : 1;
/// When true, print the half-precision floating-point type as 'half'
/// instead of '__fp16'
+ LLVM_PREFERRED_TYPE(bool)
unsigned Half : 1;
/// When true, print the built-in wchar_t type as __wchar_t. For use in
/// Microsoft mode when wchar_t is not available.
+ LLVM_PREFERRED_TYPE(bool)
unsigned MSWChar : 1;
/// When true, include newlines after statements like "break", etc.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IncludeNewlines : 1;
/// Use whitespace and punctuation like MSVC does. In particular, this prints
/// anonymous namespaces as `anonymous namespace' and does not insert spaces
/// after template arguments.
+ LLVM_PREFERRED_TYPE(bool)
unsigned MSVCFormatting : 1;
/// Whether we should print the constant expressions as written in the
@@ -256,23 +294,54 @@ struct PrintingPolicy {
/// 0x10
/// 2.5e3
/// \endcode
+ LLVM_PREFERRED_TYPE(bool)
unsigned ConstantsAsWritten : 1;
/// When true, don't print the implicit 'self' or 'this' expressions.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressImplicitBase : 1;
/// When true, print the fully qualified name of function declarations.
/// This is the opposite of SuppressScope and thus overrules it.
+ LLVM_PREFERRED_TYPE(bool)
unsigned FullyQualifiedName : 1;
/// Whether to print types as written or canonically.
+ LLVM_PREFERRED_TYPE(bool)
unsigned PrintCanonicalTypes : 1;
/// Whether to print an InjectedClassNameType with template arguments or as
/// written. When a template argument is unnamed, printing it results in
/// invalid C++ code.
+ LLVM_PREFERRED_TYPE(bool)
unsigned PrintInjectedClassNameWithArguments : 1;
+ /// Whether to use C++ template preferred_name attributes when printing
+ /// templates.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned UsePreferredNames : 1;
+
+ /// Whether to use type suffixes (eg: 1U) on integral non-type template
+ /// parameters.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned AlwaysIncludeTypeForTemplateArgument : 1;
+
+ /// Whether to strip underscores when printing reserved parameter names.
+ /// e.g. std::vector<class _Tp> becomes std::vector<class Tp>.
+ /// This only affects parameter names, and so describes a compatible API.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned CleanUglifiedParameters : 1;
+
+ /// Whether to print the entire array initializers, especially on non-type
+ /// template parameters, no matter how many elements there are.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned EntireContentsOfLargeArray : 1;
+
+ /// Whether to print enumerator non-type template parameters with a matching
+ /// enumerator name or via cast of an integer.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned UseEnumerators : 1;
+
/// Callbacks to use to allow the behavior of printing to be customized.
const PrintingCallbacks *Callbacks = nullptr;
};
diff --git a/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td b/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td
index a087cb406b29..0270c086d06b 100644
--- a/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td
+++ b/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td
@@ -41,7 +41,7 @@ class RefPropertyType<string className> : PropertyType<className # "*"> {
let PackOptional =
"value ? *value : nullptr";
let UnpackOptional =
- "value ? llvm::Optional<" # CXXName # ">(value) : llvm::None";
+ "value ? std::optional<" # CXXName # ">(value) : std::nullopt";
}
/// Property types that correspond to a specific subclass of another type.
@@ -58,7 +58,7 @@ class DefaultValuePropertyType<string typeName = ""> : PropertyType<typeName> {
let PackOptional =
"value ? *value : " # CXXName # "()";
let UnpackOptional =
- "value.isNull() ? llvm::None : llvm::Optional<" # CXXName # ">(value)";
+ "value.isNull() ? std::nullopt : std::optional<" # CXXName # ">(value)";
}
/// Property types that correspond to integer types and support optional
@@ -67,18 +67,19 @@ class CountPropertyType<string typeName = ""> : PropertyType<typeName> {
let PackOptional =
"value ? *value + 1 : 0";
let UnpackOptional =
- "value ? llvm::Optional<" # CXXName # ">(value - 1) : llvm::None";
+ "value ? std::optional<" # CXXName # ">(value - 1) : std::nullopt";
}
def APInt : PropertyType<"llvm::APInt"> { let PassByReference = 1; }
def APSInt : PropertyType<"llvm::APSInt"> { let PassByReference = 1; }
def APValue : PropertyType { let PassByReference = 1; }
def APValueKind : EnumPropertyType<"APValue::ValueKind">;
-def ArraySizeModifier : EnumPropertyType<"ArrayType::ArraySizeModifier">;
+def ArraySizeModifier : EnumPropertyType<"ArraySizeModifier">;
def AttrKind : EnumPropertyType<"attr::Kind">;
def AutoTypeKeyword : EnumPropertyType;
def Bool : PropertyType<"bool">;
def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">;
+def BTFTypeTagAttr : PropertyType<"const BTFTypeTagAttr *">;
def CallingConv : EnumPropertyType;
def DeclarationName : PropertyType;
def DeclarationNameKind : EnumPropertyType<"DeclarationName::NameKind">;
@@ -107,6 +108,8 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
def TemplateTemplateParmDeclRef :
SubclassPropertyType<"TemplateTemplateParmDecl", DeclRef>;
+ def UsingShadowDeclRef :
+ SubclassPropertyType<"UsingShadowDecl", DeclRef>;
def ValueDeclRef :
SubclassPropertyType<"ValueDecl", DeclRef>;
def ElaboratedTypeKeyword : EnumPropertyType;
@@ -135,10 +138,11 @@ def TemplateArgument : PropertyType;
def TemplateArgumentKind : EnumPropertyType<"TemplateArgument::ArgKind">;
def TemplateName : DefaultValuePropertyType;
def TemplateNameKind : EnumPropertyType<"TemplateName::NameKind">;
+def TypeOfKind : EnumPropertyType<"TypeOfKind">;
def UInt32 : CountPropertyType<"uint32_t">;
def UInt64 : CountPropertyType<"uint64_t">;
def UnaryTypeTransformKind : EnumPropertyType<"UnaryTransformType::UTTKind">;
-def VectorKind : EnumPropertyType<"VectorType::VectorKind">;
+def VectorKind : EnumPropertyType<"VectorKind">;
def ExceptionSpecInfo : PropertyType<"FunctionProtoType::ExceptionSpecInfo"> {
let BufferElementTypes = [ QualType ];
@@ -151,7 +155,7 @@ class Array<PropertyType element> : PropertyType {
let BufferElementTypes = [ element ];
}
-/// llvm::Optional<T>. The corresponding C++ type is generally just the
+/// std::optional<T>. The corresponding C++ type is generally just the
/// corresponding C++ type of the element.
///
/// Optional<Unsigned> may restrict the range of the operand for some
@@ -446,10 +450,13 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
lvalueBase ? lvalueBase.dyn_cast<const Expr *>() : nullptr;
bool lvalueBaseIsExpr = (bool) expr;
bool lvalueBaseIsTypeInfo = lvalueBase.is<TypeInfoLValue>();
+ bool lvalueBaseIsDynamicAlloc = lvalueBase.is<DynamicAllocLValue>();
QualType elemTy;
if (lvalueBase) {
if (lvalueBaseIsTypeInfo) {
elemTy = lvalueBase.getTypeInfoType();
+ } else if (lvalueBaseIsDynamicAlloc) {
+ elemTy = lvalueBase.getDynamicAllocType();
} else if (lvalueBaseIsExpr) {
elemTy = expr->getType();
} else {
@@ -469,6 +476,9 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
def : Property<"isTypeInfo", Bool> {
let Read = [{ lvalueBaseIsTypeInfo }];
}
+ def : Property<"isDynamicAlloc", Bool> {
+ let Read = [{ lvalueBaseIsDynamicAlloc }];
+ }
def : Property<"hasBase", Bool> {
let Read = [{ static_cast<bool>(lvalueBase) }];
}
@@ -481,9 +491,17 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
QualType(node.getLValueBase().get<TypeInfoLValue>().getType(), 0)
}];
}
+ def : Property<"dynamicAlloc", UInt32> {
+ let Conditional = [{ hasBase && isDynamicAlloc }];
+ let Read = [{ node.getLValueBase().get<DynamicAllocLValue>().getIndex() }];
+ }
def : Property<"type", QualType> {
- let Conditional = [{ hasBase && isTypeInfo }];
- let Read = [{ node.getLValueBase().getTypeInfoType() }];
+ let Conditional = [{ hasBase && (isTypeInfo || isDynamicAlloc) }];
+ let Read = [{
+ isTypeInfo
+ ? node.getLValueBase().getTypeInfoType()
+ : node.getLValueBase().getDynamicAllocType()
+ }];
}
def : Property<"callIndex", UInt32> {
let Conditional = [{ hasBase && !isTypeInfo }];
@@ -498,7 +516,7 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
let Read = [{ const_cast<Expr *>(expr) }];
}
def : Property<"decl", DeclRef> {
- let Conditional = [{ hasBase && !isTypeInfo && !isExpr }];
+ let Conditional = [{ hasBase && !isTypeInfo && !isDynamicAlloc && !isExpr }];
let Read = [{ lvalueBase.get<const ValueDecl *>() }];
}
def : Property<"offsetQuantity", UInt32> {
@@ -513,20 +531,19 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
def : Creator<[{
(void)ctx;
APValue::LValueBase base;
- QualType elemTy;
if (hasBase) {
if (isTypeInfo) {
base = APValue::LValueBase::getTypeInfo(
- TypeInfoLValue(typeInfo.getValue().getTypePtr()), type.getValue());
- elemTy = base.getTypeInfoType();
+ TypeInfoLValue(typeInfo->getTypePtr()), *type);
+ } else if (isDynamicAlloc) {
+ base = APValue::LValueBase::getDynamicAlloc(
+ DynamicAllocLValue(*dynamicAlloc), *type);
} else if (isExpr) {
- base = APValue::LValueBase(cast<Expr>(stmt.getValue()),
- callIndex.getValue(), version.getValue());
- elemTy = base.get<const Expr *>()->getType();
+ base = APValue::LValueBase(cast<Expr>(*stmt),
+ *callIndex, *version);
} else {
- base = APValue::LValueBase(cast<ValueDecl>(decl.getValue()),
- callIndex.getValue(), version.getValue());
- elemTy = base.get<const ValueDecl *>()->getType();
+ base = APValue::LValueBase(cast<ValueDecl>(*decl),
+ *callIndex, *version);
}
}
CharUnits offset = CharUnits::fromQuantity(offsetQuantity);
@@ -539,7 +556,6 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
auto pathLength = lvaluePath->Path.size();
APValue::LValuePathEntry *path = result.setLValueUninit(
base, offset, pathLength, isLValueOnePastTheEnd, isNullPtr).data();
- assert(lvaluePath->getType() == elemTy && "Unexpected type reference!");
llvm::copy(lvaluePath->Path, path);
return result;
}]>;
@@ -617,6 +633,16 @@ let Class = PropertyTypeCase<TemplateName, "Template"> in {
return TemplateName(declaration);
}]>;
}
+
+let Class = PropertyTypeCase<TemplateName, "UsingTemplate"> in {
+ def : Property<"foundDecl", UsingShadowDeclRef> {
+ let Read = [{ node.getAsUsingShadowDecl() }];
+ }
+ def : Creator<[{
+ return TemplateName(foundDecl);
+ }]>;
+}
+
let Class = PropertyTypeCase<TemplateName, "OverloadedTemplate"> in {
def : Property<"overloads", Array<NamedDeclRef>> {
let Read = [{ node.getAsOverloadedTemplate()->decls() }];
@@ -650,12 +676,12 @@ let Class = PropertyTypeCase<TemplateName, "QualifiedTemplate"> in {
def : Property<"hasTemplateKeyword", Bool> {
let Read = [{ qtn->hasTemplateKeyword() }];
}
- def : Property<"declaration", TemplateDeclRef> {
- let Read = [{ qtn->getTemplateDecl() }];
+ def : Property<"underlyingTemplateName", TemplateName> {
+ let Read = [{ qtn->getUnderlyingTemplate() }];
}
def : Creator<[{
return ctx.getQualifiedTemplateName(qualifier, hasTemplateKeyword,
- declaration);
+ underlyingTemplateName);
}]>;
}
let Class = PropertyTypeCase<TemplateName, "DependentTemplate"> in {
@@ -687,28 +713,40 @@ let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParm"> in {
def : ReadHelper<[{
auto parm = node.getAsSubstTemplateTemplateParm();
}]>;
- def : Property<"parameter", TemplateTemplateParmDeclRef> {
- let Read = [{ parm->getParameter() }];
- }
def : Property<"replacement", TemplateName> {
let Read = [{ parm->getReplacement() }];
}
+ def : Property<"associatedDecl", DeclRef> {
+ let Read = [{ parm->getAssociatedDecl() }];
+ }
+ def : Property<"index", UInt32> {
+ let Read = [{ parm->getIndex() }];
+ }
+ def : Property<"packIndex", Optional<UInt32>> {
+ let Read = [{ parm->getPackIndex() }];
+ }
def : Creator<[{
- return ctx.getSubstTemplateTemplateParm(parameter, replacement);
+ return ctx.getSubstTemplateTemplateParm(replacement, associatedDecl, index, packIndex);
}]>;
}
let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in {
def : ReadHelper<[{
auto parm = node.getAsSubstTemplateTemplateParmPack();
}]>;
- def : Property<"parameterPack", TemplateTemplateParmDeclRef> {
- let Read = [{ parm->getParameterPack() }];
- }
def : Property<"argumentPack", TemplateArgument> {
let Read = [{ parm->getArgumentPack() }];
}
+ def : Property<"associatedDecl", DeclRef> {
+ let Read = [{ parm->getAssociatedDecl() }];
+ }
+ def : Property<"index", UInt32> {
+ let Read = [{ parm->getIndex() }];
+ }
+ def : Property<"final", Bool> {
+ let Read = [{ parm->getFinal() }];
+ }
def : Creator<[{
- return ctx.getSubstTemplateTemplateParmPack(parameterPack, argumentPack);
+ return ctx.getSubstTemplateTemplateParmPack(argumentPack, associatedDecl, index, final);
}]>;
}
@@ -724,8 +762,11 @@ let Class = PropertyTypeCase<TemplateArgument, "Type"> in {
def : Property<"type", QualType> {
let Read = [{ node.getAsType() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(type);
+ return TemplateArgument(type, /* isNullPtr */ false, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in {
@@ -735,16 +776,22 @@ let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in {
def : Property<"parameterType", QualType> {
let Read = [{ node.getParamTypeForDecl() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(declaration, parameterType);
+ return TemplateArgument(declaration, parameterType, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "NullPtr"> in {
def : Property<"type", QualType> {
let Read = [{ node.getNullPtrType() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(type, /*nullptr*/ true);
+ return TemplateArgument(type, /*nullptr*/ true, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
@@ -754,16 +801,36 @@ let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
def : Property<"type", QualType> {
let Read = [{ node.getIntegralType() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
+ def : Creator<[{
+ return TemplateArgument(ctx, value, type, isDefaulted);
+ }]>;
+}
+let Class = PropertyTypeCase<TemplateArgument, "StructuralValue"> in {
+ def : Property<"value", APValue> {
+ let Read = [{ node.getAsStructuralValue() }];
+ }
+ def : Property<"type", QualType> {
+ let Read = [{ node.getStructuralValueType() }];
+ }
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(ctx, value, type);
+ return TemplateArgument(ctx, type, value, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Template"> in {
def : Property<"name", TemplateName> {
let Read = [{ node.getAsTemplateOrTemplatePattern() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(name);
+ return TemplateArgument(name, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in {
@@ -773,22 +840,29 @@ let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in {
def : Property<"numExpansions", Optional<UInt32>> {
let Read = [{
// Translate unsigned -> uint32_t just in case.
- node.getNumTemplateExpansions().map(
- [](unsigned i) { return uint32_t(i); })
+ llvm::transformOptional(node.getNumTemplateExpansions(),
+ [](unsigned i) { return uint32_t(i); })
}];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- auto numExpansionsUnsigned =
- numExpansions.map([](uint32_t i) { return unsigned(i); });
- return TemplateArgument(name, numExpansionsUnsigned);
+ auto numExpansionsUnsigned = llvm::transformOptional(
+ numExpansions, [](uint32_t i) { return unsigned(i); });
+
+ return TemplateArgument(name, numExpansionsUnsigned, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Expression"> in {
def : Property<"expression", ExprRef> {
let Read = [{ node.getAsExpr() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(expression);
+ return TemplateArgument(expression, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {
@@ -800,6 +874,6 @@ let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {
TemplateArgument *ctxElements = new (ctx) TemplateArgument[elements.size()];
for (size_t i = 0, e = elements.size(); i != e; ++i)
ctxElements[i] = elements[i];
- return TemplateArgument(llvm::makeArrayRef(ctxElements, elements.size()));
+ return TemplateArgument(llvm::ArrayRef(ctxElements, elements.size()));
}]>;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h b/contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h
index 8313e0441be5..daa86cda2d99 100644
--- a/contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h
+++ b/contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h
@@ -89,4 +89,4 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
bool WithGlobalNsPrefix = false);
} // end namespace TypeName
} // end namespace clang
-#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
+#endif // LLVM_CLANG_AST_QUALTYPENAMES_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/Randstruct.h b/contrib/llvm-project/clang/include/clang/AST/Randstruct.h
new file mode 100644
index 000000000000..d5eaf30919e3
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/AST/Randstruct.h
@@ -0,0 +1,35 @@
+//===- Randstruct.h - Interfact for structure randomization -------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the interface for Clang's structure field layout
+// randomization.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_RANDSTRUCT_H
+#define LLVM_CLANG_AST_RANDSTRUCT_H
+
+namespace llvm {
+template <typename T> class SmallVectorImpl;
+} // end namespace llvm
+
+namespace clang {
+
+class ASTContext;
+class Decl;
+class RecordDecl;
+
+namespace randstruct {
+
+bool randomizeStructureLayout(const ASTContext &Context, RecordDecl *RD,
+ llvm::SmallVectorImpl<Decl *> &FinalOrdering);
+
+} // namespace randstruct
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_RANDSTRUCT_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h b/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h
index a18432c2b768..53aae24fa7bb 100644
--- a/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h
+++ b/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h
@@ -115,6 +115,17 @@ public:
return extractBriefText(Context);
}
+ bool hasUnsupportedSplice(const SourceManager &SourceMgr) const {
+ if (!isInvalid())
+ return false;
+ StringRef Text = getRawText(SourceMgr);
+ if (Text.size() < 6 || Text[0] != '/')
+ return false;
+ if (Text[1] == '*')
+ return Text[Text.size() - 1] != '/' || Text[Text.size() - 2] != '*';
+ return Text[1] != '/';
+ }
+
/// Returns sanitized comment text, suitable for presentation in editor UIs.
/// E.g. will transform:
/// // This is a long multiline comment.
@@ -139,6 +150,21 @@ public:
std::string getFormattedText(const SourceManager &SourceMgr,
DiagnosticsEngine &Diags) const;
+ struct CommentLine {
+ std::string Text;
+ PresumedLoc Begin;
+ PresumedLoc End;
+
+ CommentLine(StringRef Text, PresumedLoc Begin, PresumedLoc End)
+ : Text(Text), Begin(Begin), End(End) {}
+ };
+
+ /// Returns sanitized comment text as separated lines with locations in
+ /// source, suitable for further processing and rendering requiring source
+ /// locations.
+ std::vector<CommentLine> getFormattedLines(const SourceManager &SourceMgr,
+ DiagnosticsEngine &Diags) const;
+
/// Parse the comment, assuming it is attached to decl \c D.
comments::FullComment *parse(const ASTContext &Context,
const Preprocessor *PP, const Decl *D) const;
@@ -147,11 +173,12 @@ private:
SourceRange Range;
mutable StringRef RawText;
- mutable const char *BriefText;
+ mutable const char *BriefText = nullptr;
mutable bool RawTextValid : 1; ///< True if RawText is valid
mutable bool BriefTextValid : 1; ///< True if BriefText is valid
+ LLVM_PREFERRED_TYPE(CommentKind)
unsigned Kind : 3;
/// True if comment is attached to a declaration in ASTContext.
diff --git a/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h b/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h
index 9bfa5b9c2326..2aee6a947141 100644
--- a/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -13,18 +13,19 @@
#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
+#include "clang/AST/ASTConcept.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/LambdaCapture.h"
@@ -68,30 +69,17 @@ template <typename T, typename U, typename R, typename... P>
struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
: std::true_type {};
-template <bool has_same_type> struct is_same_method_impl {
- template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
- static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
- SecondMethodPtrTy SecondMethodPtr) {
- return false;
- }
-};
-
-template <> struct is_same_method_impl<true> {
- template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
- static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
- SecondMethodPtrTy SecondMethodPtr) {
- return FirstMethodPtr == SecondMethodPtr;
- }
-};
-
/// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr
/// are pointers to the same non-static member function.
template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
-bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
- SecondMethodPtrTy SecondMethodPtr) {
- return is_same_method_impl<has_same_member_pointer_type<
- FirstMethodPtrTy,
- SecondMethodPtrTy>::value>::isSameMethod(FirstMethodPtr, SecondMethodPtr);
+LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG auto
+isSameMethod([[maybe_unused]] FirstMethodPtrTy FirstMethodPtr,
+ [[maybe_unused]] SecondMethodPtrTy SecondMethodPtr)
+ -> bool {
+ if constexpr (has_same_member_pointer_type<FirstMethodPtrTy,
+ SecondMethodPtrTy>::value)
+ return FirstMethodPtr == SecondMethodPtr;
+ return false;
}
} // end namespace detail
@@ -288,8 +276,7 @@ public:
///
/// \returns false if the visitation was terminated early, true otherwise.
// FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
- bool TraverseTemplateArguments(const TemplateArgument *Args,
- unsigned NumArgs);
+ bool TraverseTemplateArguments(ArrayRef<TemplateArgument> Args);
/// Recursively visit a base specifier. This can be overridden by a
/// subclass.
@@ -319,11 +306,19 @@ public:
bool TraverseSynOrSemInitListExpr(InitListExpr *S,
DataRecursionQueue *Queue = nullptr);
- /// Recursively visit a reference to a concept with potential arguments.
+ /// Recursively visit an Objective-C protocol reference with location
+ /// information.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc);
+
+ /// Recursively visit concept reference with location information.
///
/// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseConceptReference(const ConceptReference &C);
+ bool TraverseConceptReference(ConceptReference *CR);
+ // Visit concept reference.
+ bool VisitConceptReference(ConceptReference *CR) { return true; }
// ---- Methods on Attrs ----
// Visit an attribute.
@@ -469,6 +464,13 @@ public:
DEF_TRAVERSE_TMPL_INST(Function)
#undef DEF_TRAVERSE_TMPL_INST
+ bool TraverseTypeConstraint(const TypeConstraint *C);
+
+ bool TraverseConceptRequirement(concepts::Requirement *R);
+ bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R);
+ bool TraverseConceptExprRequirement(concepts::ExprRequirement *R);
+ bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R);
+
bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue);
private:
@@ -506,6 +508,43 @@ private:
};
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTypeConstraint(
+ const TypeConstraint *C) {
+ if (!getDerived().shouldVisitImplicitCode()) {
+ TRY_TO(TraverseConceptReference(C->getConceptReference()));
+ return true;
+ }
+ if (Expr *IDC = C->getImmediatelyDeclaredConstraint()) {
+ TRY_TO(TraverseStmt(IDC));
+ } else {
+ // Avoid traversing the ConceptReference in the TypeConstraint
+ // if we have an immediately-declared-constraint, otherwise
+ // we'll end up visiting the concept and the arguments in
+ // the TC twice.
+ TRY_TO(TraverseConceptReference(C->getConceptReference()));
+ }
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConceptRequirement(
+ concepts::Requirement *R) {
+ switch (R->getKind()) {
+ case concepts::Requirement::RK_Type:
+ return getDerived().TraverseConceptTypeRequirement(
+ cast<concepts::TypeRequirement>(R));
+ case concepts::Requirement::RK_Simple:
+ case concepts::Requirement::RK_Compound:
+ return getDerived().TraverseConceptExprRequirement(
+ cast<concepts::ExprRequirement>(R));
+ case concepts::Requirement::RK_Nested:
+ return getDerived().TraverseConceptNestedRequirement(
+ cast<concepts::NestedRequirement>(R));
+ }
+ llvm_unreachable("unexpected case");
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
DataRecursionQueue *Queue) {
// Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
@@ -525,6 +564,40 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
#undef DISPATCH_STMT
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConceptTypeRequirement(
+ concepts::TypeRequirement *R) {
+ if (R->isSubstitutionFailure())
+ return true;
+ return getDerived().TraverseTypeLoc(R->getType()->getTypeLoc());
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConceptExprRequirement(
+ concepts::ExprRequirement *R) {
+ if (!R->isExprSubstitutionFailure())
+ TRY_TO(TraverseStmt(R->getExpr()));
+ auto &RetReq = R->getReturnTypeRequirement();
+ if (RetReq.isTypeConstraint()) {
+ if (getDerived().shouldVisitImplicitCode()) {
+ TRY_TO(TraverseTemplateParameterListHelper(
+ RetReq.getTypeConstraintTemplateParameterList()));
+ } else {
+ // Template parameter list is implicit, visit constraint directly.
+ TRY_TO(TraverseTypeConstraint(RetReq.getTypeConstraint()));
+ }
+ }
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConceptNestedRequirement(
+ concepts::NestedRequirement *R) {
+ if (!R->hasInvalidConstraint())
+ return getDerived().TraverseStmt(R->getConstraintExpr());
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
// In pre-order traversal mode, each Traverse##STMT method is responsible for
// calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and
@@ -777,6 +850,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
case TemplateArgument::NullPtr:
+ case TemplateArgument::StructuralValue:
return true;
case TemplateArgument::Type:
@@ -791,8 +865,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
return getDerived().TraverseStmt(Arg.getAsExpr());
case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
+ return getDerived().TraverseTemplateArguments(Arg.pack_elements());
}
return true;
@@ -810,6 +883,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
case TemplateArgument::NullPtr:
+ case TemplateArgument::StructuralValue:
return true;
case TemplateArgument::Type: {
@@ -832,8 +906,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
+ return getDerived().TraverseTemplateArguments(Arg.pack_elements());
}
return true;
@@ -841,10 +914,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
- const TemplateArgument *Args, unsigned NumArgs) {
- for (unsigned I = 0; I != NumArgs; ++I) {
- TRY_TO(TraverseTemplateArgument(Args[I]));
- }
+ ArrayRef<TemplateArgument> Args) {
+ for (const TemplateArgument &Arg : Args)
+ TRY_TO(TraverseTemplateArgument(Arg));
return true;
}
@@ -981,13 +1053,14 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
TRY_TO(TraverseStmt(NE));
})
+DEF_TRAVERSE_TYPE(UsingType, {})
DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
DEF_TRAVERSE_TYPE(TypedefType, {})
DEF_TRAVERSE_TYPE(TypeOfExprType,
{ TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
-DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
+DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnmodifiedType())); })
DEF_TRAVERSE_TYPE(DecltypeType,
{ TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
@@ -1000,8 +1073,7 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
DEF_TRAVERSE_TYPE(AutoType, {
TRY_TO(TraverseType(T->getDeducedType()));
if (T->isConstrained()) {
- TRY_TO(TraverseDecl(T->getTypeConstraintConcept()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ TRY_TO(TraverseTemplateArguments(T->getTypeConstraintArguments()));
}
})
DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
@@ -1021,7 +1093,7 @@ DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {
DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ TRY_TO(TraverseTemplateArguments(T->template_arguments()));
})
DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
@@ -1029,6 +1101,9 @@ DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
DEF_TRAVERSE_TYPE(AttributedType,
{ TRY_TO(TraverseType(T->getModifiedType())); })
+DEF_TRAVERSE_TYPE(BTFTagAttributedType,
+ { TRY_TO(TraverseType(T->getWrappedType())); })
+
DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
DEF_TRAVERSE_TYPE(MacroQualifiedType,
@@ -1046,7 +1121,7 @@ DEF_TRAVERSE_TYPE(DependentNameType,
DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ TRY_TO(TraverseTemplateArguments(T->template_arguments()));
})
DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
@@ -1072,8 +1147,8 @@ DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(ExtIntType, {})
-DEF_TRAVERSE_TYPE(DependentExtIntType,
+DEF_TRAVERSE_TYPE(BitIntType, {})
+DEF_TRAVERSE_TYPE(DependentBitIntType,
{ TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
#undef DEF_TRAVERSE_TYPE
@@ -1252,6 +1327,7 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
TRY_TO(TraverseStmt(NE));
})
+DEF_TRAVERSE_TYPELOC(UsingType, {})
DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
DEF_TRAVERSE_TYPELOC(TypedefType, {})
@@ -1259,7 +1335,7 @@ DEF_TRAVERSE_TYPELOC(TypeOfExprType,
{ TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
DEF_TRAVERSE_TYPELOC(TypeOfType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+ TRY_TO(TraverseTypeLoc(TL.getUnmodifiedTInfo()->getTypeLoc()));
})
// FIXME: location of underlying expr
@@ -1274,10 +1350,7 @@ DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
DEF_TRAVERSE_TYPELOC(AutoType, {
TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
if (TL.isConstrained()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ TRY_TO(TraverseConceptReference(TL.getConceptReference()));
}
})
@@ -1314,6 +1387,9 @@ DEF_TRAVERSE_TYPELOC(MacroQualifiedType,
DEF_TRAVERSE_TYPELOC(AttributedType,
{ TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
+DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
+ { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
+
DEF_TRAVERSE_TYPELOC(ElaboratedType, {
if (TL.getQualifierLoc()) {
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
@@ -1338,7 +1414,12 @@ DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
DEF_TRAVERSE_TYPELOC(PackExpansionType,
{ TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
-DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {})
+DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {
+ for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
+ ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
+ TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
+ }
+})
DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
@@ -1349,6 +1430,10 @@ DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
+ for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
+ ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
+ TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
+ }
})
DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
@@ -1358,8 +1443,8 @@ DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
-DEF_TRAVERSE_TYPELOC(ExtIntType, {})
-DEF_TRAVERSE_TYPELOC(DependentExtIntType, {
+DEF_TRAVERSE_TYPELOC(BitIntType, {})
+DEF_TRAVERSE_TYPELOC(DependentBitIntType, {
TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
})
@@ -1440,6 +1525,8 @@ DEF_TRAVERSE_DECL(CapturedDecl, {
DEF_TRAVERSE_DECL(EmptyDecl, {})
+DEF_TRAVERSE_DECL(HLSLBufferDecl, {})
+
DEF_TRAVERSE_DECL(LifetimeExtendedTemporaryDecl, {
TRY_TO(TraverseStmt(D->getTemporaryExpr()));
})
@@ -1447,14 +1534,21 @@ DEF_TRAVERSE_DECL(LifetimeExtendedTemporaryDecl, {
DEF_TRAVERSE_DECL(FileScopeAsmDecl,
{ TRY_TO(TraverseStmt(D->getAsmString())); })
+DEF_TRAVERSE_DECL(TopLevelStmtDecl, { TRY_TO(TraverseStmt(D->getStmt())); })
+
DEF_TRAVERSE_DECL(ImportDecl, {})
DEF_TRAVERSE_DECL(FriendDecl, {
// Friend is either decl or a type.
- if (D->getFriendType())
+ if (D->getFriendType()) {
TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
+ // Traverse any CXXRecordDecl owned by this type, since
+ // it will not be in the parent context:
+ if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
+ TRY_TO(TraverseDecl(ET->getOwnedTagDecl()));
+ } else {
TRY_TO(TraverseDecl(D->getFriendDecl()));
+ }
})
DEF_TRAVERSE_DECL(FriendTemplateDecl, {
@@ -1471,16 +1565,6 @@ DEF_TRAVERSE_DECL(FriendTemplateDecl, {
}
})
-DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
- TRY_TO(TraverseDecl(D->getSpecialization()));
-
- if (D->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- D->getTemplateArgsAsWritten()->getTemplateArgs(),
- D->getTemplateArgsAsWritten()->NumTemplateArgs));
- }
-})
-
DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
DEF_TRAVERSE_DECL(ExportDecl, {})
@@ -1539,12 +1623,16 @@ DEF_TRAVERSE_DECL(
DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
})
-DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
for (auto typeParam : *typeParamList) {
TRY_TO(TraverseObjCTypeParamDecl(typeParam));
}
}
+ for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
+ ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
+ TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
+ }
})
DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
@@ -1553,7 +1641,7 @@ DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
})
-DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
for (auto typeParam : *typeParamList) {
TRY_TO(TraverseObjCTypeParamDecl(typeParam));
@@ -1563,10 +1651,22 @@ DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
}
+ if (D->isThisDeclarationADefinition()) {
+ for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
+ ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
+ TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
+ }
+ }
})
-DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
- })
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
+ if (D->isThisDeclarationADefinition()) {
+ for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
+ ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
+ TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
+ }
+ }
+})
DEF_TRAVERSE_DECL(ObjCMethodDecl, {
if (D->getReturnTypeSourceInfo()) {
@@ -1603,7 +1703,8 @@ DEF_TRAVERSE_DECL(UsingDecl, {
TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
})
-DEF_TRAVERSE_DECL(UsingEnumDecl, {})
+DEF_TRAVERSE_DECL(UsingEnumDecl,
+ { TRY_TO(TraverseTypeLoc(D->getEnumTypeLoc())); })
DEF_TRAVERSE_DECL(UsingPackDecl, {})
@@ -1681,10 +1782,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
ClassTemplateDecl *D) {
for (auto *SD : D->specializations()) {
for (auto *RD : SD->redecls()) {
- // We don't want to visit injected-class-names in this traversal.
- if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
- continue;
-
+ assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName());
switch (
cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
// Visit the implicit instantiations with the requested pattern.
@@ -1802,17 +1900,8 @@ DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
const TemplateTypeParmDecl *D) {
- if (const auto *TC = D->getTypeConstraint()) {
- if (Expr *IDC = TC->getImmediatelyDeclaredConstraint()) {
- TRY_TO(TraverseStmt(IDC));
- } else {
- // Avoid traversing the ConceptReference in the TypeCosntraint
- // if we have an immediately-declared-constraint, otherwise
- // we'll end up visiting the concept and the arguments in
- // the TC twice.
- TRY_TO(TraverseConceptReference(*TC));
- }
- }
+ if (const auto *TC = D->getTypeConstraint())
+ TRY_TO(TraverseTypeConstraint(TC));
return true;
}
@@ -1863,10 +1952,9 @@ DEF_TRAVERSE_DECL(UnresolvedUsingIfExistsDecl, {})
DEF_TRAVERSE_DECL(EnumDecl, {
TRY_TO(TraverseDeclTemplateParameterLists(D));
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ if (auto *TSI = D->getIntegerTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
// The enumerators are already traversed by
// decls_begin()/decls_end().
})
@@ -1907,7 +1995,7 @@ DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
-#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND) \
+#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
/* For implicit instantiations ("set<int> x;"), we don't want to \
recurse at all, since the instatiated template isn't written in \
@@ -1920,18 +2008,23 @@ DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \
\
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \
- if (!getDerived().shouldVisitTemplateInstantiations() && \
- D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \
+ if (getDerived().shouldVisitTemplateInstantiations() || \
+ D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
+ /* Traverse base definition for explicit specializations */ \
+ TRY_TO(Traverse##DECLKIND##Helper(D)); \
+ } else { \
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \
+ \
/* Returning from here skips traversing the \
declaration context of the *TemplateSpecializationDecl \
(embedded in the DEF_TRAVERSE_DECL() macro) \
which contains the instantiated members of the template. */ \
return true; \
+ } \
})
-DEF_TRAVERSE_TMPL_SPEC_DECL(Class)
-DEF_TRAVERSE_TMPL_SPEC_DECL(Var)
+DEF_TRAVERSE_TMPL_SPEC_DECL(Class, CXXRecord)
+DEF_TRAVERSE_TMPL_SPEC_DECL(Var, Var)
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
@@ -1945,12 +2038,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
/* The partial specialization. */ \
- if (TemplateParameterList *TPL = D->getTemplateParameters()) { \
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \
- I != E; ++I) { \
- TRY_TO(TraverseDecl(*I)); \
- } \
- } \
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
/* The args that remains unspecialized. */ \
TRY_TO(TraverseTemplateArgumentLocsHelper( \
D->getTemplateArgsAsWritten()->getTemplateArgs(), \
@@ -2004,6 +2092,7 @@ DEF_TRAVERSE_DECL(BindingDecl, {
DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
DEF_TRAVERSE_DECL(MSGuidDecl, {})
+DEF_TRAVERSE_DECL(UnnamedGlobalConstantDecl, {})
DEF_TRAVERSE_DECL(TemplateParamObjectDecl, {})
@@ -2011,7 +2100,7 @@ DEF_TRAVERSE_DECL(FieldDecl, {
TRY_TO(TraverseDeclaratorHelper(D));
if (D->isBitField())
TRY_TO(TraverseStmt(D->getBitWidth()));
- else if (D->hasInClassInitializer())
+ if (D->hasInClassInitializer())
TRY_TO(TraverseStmt(D->getInClassInitializer()));
})
@@ -2052,6 +2141,13 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
TALI->NumTemplateArgs));
}
}
+ } else if (const DependentFunctionTemplateSpecializationInfo *DFSI =
+ D->getDependentSpecializationInfo()) {
+ if (const ASTTemplateArgumentListInfo *TALI =
+ DFSI->TemplateArgumentsAsWritten) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
+ TALI->NumTemplateArgs));
+ }
}
// Visit the function type itself, which can be either
@@ -2099,7 +2195,13 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
}
if (VisitBody) {
- TRY_TO(TraverseStmt(D->getBody())); // Function body.
+ TRY_TO(TraverseStmt(D->getBody()));
+ // Body may contain using declarations whose shadows are parented to the
+ // FunctionDecl itself.
+ for (auto *Child : D->decls()) {
+ if (isa<UsingShadowDecl>(Child))
+ TRY_TO(TraverseDecl(Child));
+ }
}
return true;
}
@@ -2183,6 +2285,10 @@ DEF_TRAVERSE_DECL(ParmVarDecl, {
DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {})
+DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
+ TRY_TO(TraverseTemplateArguments(D->getTemplateArguments()));
+})
+
#undef DEF_TRAVERSE_DECL
// ----------------- Stmt traversal -----------------
@@ -2393,15 +2499,25 @@ bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
return true;
}
-template<typename Derived>
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseObjCProtocolLoc(
+ ObjCProtocolLoc ProtocolLoc) {
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseConceptReference(
- const ConceptReference &C) {
- TRY_TO(TraverseNestedNameSpecifierLoc(C.getNestedNameSpecifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(C.getConceptNameInfo()));
- if (C.hasExplicitTemplateArgs())
+ ConceptReference *CR) {
+ if (!getDerived().shouldTraversePostOrder())
+ TRY_TO(VisitConceptReference(CR));
+ TRY_TO(TraverseNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(CR->getConceptNameInfo()));
+ if (CR->hasExplicitTemplateArgs())
TRY_TO(TraverseTemplateArgumentLocsHelper(
- C.getTemplateArgsAsWritten()->getTemplateArgs(),
- C.getTemplateArgsAsWritten()->NumTemplateArgs));
+ CR->getTemplateArgsAsWritten()->getTemplateArgs(),
+ CR->getTemplateArgsAsWritten()->NumTemplateArgs));
+ if (getDerived().shouldTraversePostOrder())
+ TRY_TO(VisitConceptReference(CR));
return true;
}
@@ -2436,7 +2552,11 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(
// are interleaved. We also need to watch out for null types (default
// generic associations).
DEF_TRAVERSE_STMT(GenericSelectionExpr, {
- TRY_TO(TraverseStmt(S->getControllingExpr()));
+ if (S->isExprPredicate())
+ TRY_TO(TraverseStmt(S->getControllingExpr()));
+ else
+ TRY_TO(TraverseTypeLoc(S->getControllingType()->getTypeLoc()));
+
for (const GenericSelectionExpr::Association Assoc : S->associations()) {
if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
@@ -2606,7 +2726,11 @@ DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {
TRY_TO(TraverseStmt(S->getExpr()));
})
-DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {
+ if (getDerived().shouldVisitImplicitCode())
+ TRY_TO(TraverseStmt(S->getExpr()));
+})
+
DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
DEF_TRAVERSE_STMT(ExprWithCleanups, {})
DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {})
@@ -2735,6 +2859,7 @@ DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
DEF_TRAVERSE_STMT(CXXFoldExpr, {})
DEF_TRAVERSE_STMT(AtomicExpr, {})
+DEF_TRAVERSE_STMT(CXXParenListInitExpr, {})
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {
if (S->getLifetimeExtendedTemporaryDecl()) {
@@ -2778,7 +2903,7 @@ DEF_TRAVERSE_STMT(CoyieldExpr, {
})
DEF_TRAVERSE_STMT(ConceptSpecializationExpr, {
- TRY_TO(TraverseConceptReference(*S));
+ TRY_TO(TraverseConceptReference(S->getConceptReference()));
})
DEF_TRAVERSE_STMT(RequiresExpr, {
@@ -2786,21 +2911,7 @@ DEF_TRAVERSE_STMT(RequiresExpr, {
for (ParmVarDecl *Parm : S->getLocalParameters())
TRY_TO(TraverseDecl(Parm));
for (concepts::Requirement *Req : S->getRequirements())
- if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
- if (!TypeReq->isSubstitutionFailure())
- TRY_TO(TraverseTypeLoc(TypeReq->getType()->getTypeLoc()));
- } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
- if (!ExprReq->isExprSubstitutionFailure())
- TRY_TO(TraverseStmt(ExprReq->getExpr()));
- auto &RetReq = ExprReq->getReturnTypeRequirement();
- if (RetReq.isTypeConstraint())
- TRY_TO(TraverseTemplateParameterListHelper(
- RetReq.getTypeConstraintTemplateParameterList()));
- } else {
- auto *NestedReq = cast<concepts::NestedRequirement>(Req);
- if (!NestedReq->isSubstitutionFailure())
- TRY_TO(TraverseStmt(NestedReq->getConstraintExpr()));
- }
+ TRY_TO(TraverseConceptRequirement(Req));
})
// These literals (all of them) do not need any action.
@@ -2842,6 +2953,9 @@ RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
return TraverseOMPExecutableDirective(S);
}
+DEF_TRAVERSE_STMT(OMPMetaDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPParallelDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2866,6 +2980,9 @@ DEF_TRAVERSE_STMT(OMPSectionsDirective,
DEF_TRAVERSE_STMT(OMPSectionDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPScopeDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPSingleDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2886,6 +3003,9 @@ DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPParallelMaskedDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2967,6 +3087,18 @@ DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPMaskedTaskLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPMaskedTaskLoopSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPDistributeDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -3021,6 +3153,24 @@ DEF_TRAVERSE_STMT(OMPDispatchDirective,
DEF_TRAVERSE_STMT(OMPMaskedDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetTeamsGenericLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPErrorDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
@@ -3092,6 +3242,12 @@ RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignClause(OMPAlignClause *C) {
+ TRY_TO(TraverseStmt(C->getAlignment()));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
TRY_TO(TraverseStmt(C->getSafelen()));
return true;
@@ -3169,6 +3325,22 @@ bool RecursiveASTVisitor<Derived>::VisitOMPAtomicDefaultMemOrderClause(
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAtClause(OMPAtClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSeverityClause(OMPSeverityClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPMessageClause(OMPMessageClause *C) {
+ TRY_TO(TraverseStmt(C->getMessageString()));
+ return true;
+}
+
+template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
TRY_TO(VisitOMPClauseWithPreInit(C));
@@ -3219,6 +3391,16 @@ bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCompareClause(OMPCompareClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFailClause(OMPFailClause *) {
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
return true;
}
@@ -3627,6 +3809,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPIsDevicePtrClause(
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPHasDeviceAddrClause(
+ OMPHasDeviceAddrClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPNontemporalClause(
OMPNontemporalClause *C) {
TRY_TO(VisitOMPClauseList(C));
@@ -3674,6 +3863,37 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFilterClause(OMPFilterClause *C) {
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPBindClause(OMPBindClause *C) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPXDynCGroupMemClause(
+ OMPXDynCGroupMemClause *C) {
+ TRY_TO(VisitOMPClauseWithPreInit(C));
+ TRY_TO(TraverseStmt(C->getSize()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDoacrossClause(
+ OMPDoacrossClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPXAttributeClause(
+ OMPXAttributeClause *C) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPXBareClause(OMPXBareClause *C) {
+ return true;
+}
+
// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
// returning decls or qualtypes or nestednamespecifier -- though I'm
diff --git a/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h b/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h
index 77b827c52bfb..091bb886f2d4 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h
@@ -240,7 +240,7 @@ public:
class redecl_iterator {
/// Current - The current declaration.
decl_type *Current = nullptr;
- decl_type *Starter;
+ decl_type *Starter = nullptr;
bool PassedFirst = false;
public:
@@ -258,7 +258,8 @@ public:
redecl_iterator& operator++() {
assert(Current && "Advancing while iterator has reached end");
- // Sanity check to avoid infinite loop on invalid redecl chain.
+ // Make sure we don't infinitely loop on an invalid redecl chain. This
+ // should never happen.
if (Current->isFirstDecl()) {
if (PassedFirst) {
assert(0 && "Passed first decl twice, invalid redecl chain!");
diff --git a/contrib/llvm-project/clang/include/clang/AST/Stmt.h b/contrib/llvm-project/clang/include/clang/AST/Stmt.h
index 8e1d7df97096..55eca4007d17 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Stmt.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Stmt.h
@@ -13,13 +13,21 @@
#ifndef LLVM_CLANG_AST_STMT_H
#define LLVM_CLANG_AST_STMT_H
+#include "clang/AST/APValue.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/DependenceFlags.h"
+#include "clang/AST/OperationKinds.h"
#include "clang/AST/StmtIterator.h"
#include "clang/Basic/CapturedStmt.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Lambda.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TypeTraits.h"
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/PointerIntPair.h"
@@ -33,6 +41,7 @@
#include <cassert>
#include <cstddef>
#include <iterator>
+#include <optional>
#include <string>
namespace llvm {
@@ -58,6 +67,13 @@ class SourceManager;
class StringLiteral;
class Token;
class VarDecl;
+enum class CharacterLiteralKind;
+enum class ConstantResultStorageKind;
+enum class CXXConstructionKind;
+enum class CXXNewInitializationStyle;
+enum class PredefinedIdentKind;
+enum class SourceLocIdentKind;
+enum class StringLiteralKind;
//===----------------------------------------------------------------------===//
// AST classes for statements.
@@ -99,6 +115,7 @@ protected:
friend class Stmt;
/// The statement class.
+ LLVM_PREFERRED_TYPE(StmtClass)
unsigned sClass : 8;
};
enum { NumStmtBits = 8 };
@@ -108,6 +125,7 @@ protected:
friend class ASTStmtWriter;
friend class NullStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// True if the null statement was preceded by an empty macro, e.g:
@@ -115,6 +133,7 @@ protected:
/// #define CALL(x)
/// CALL(0);
/// @endcode
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasLeadingEmptyMacro : 1;
/// The location of the semi-colon.
@@ -125,17 +144,21 @@ protected:
friend class ASTStmtReader;
friend class CompoundStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
- unsigned NumStmts : 32 - NumStmtBits;
+ /// True if the compound statement has one or more pragmas that set some
+ /// floating-point features.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasFPFeatures : 1;
- /// The location of the opening "{".
- SourceLocation LBraceLoc;
+ unsigned NumStmts;
};
class LabelStmtBitfields {
friend class LabelStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
SourceLocation IdentLoc;
@@ -145,6 +168,7 @@ protected:
friend class ASTStmtReader;
friend class AttributedStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// Number of attributes.
@@ -158,18 +182,23 @@ protected:
friend class ASTStmtReader;
friend class IfStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
- /// True if this if statement is a constexpr if.
- unsigned IsConstexpr : 1;
+ /// Whether this is a constexpr if, or a consteval if, or neither.
+ LLVM_PREFERRED_TYPE(IfStatementKind)
+ unsigned Kind : 3;
/// True if this if statement has storage for an else statement.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasElse : 1;
/// True if this if statement has storage for a variable declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasVar : 1;
/// True if this if statement has storage for an init statement.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasInit : 1;
/// The location of the "if".
@@ -179,17 +208,21 @@ protected:
class SwitchStmtBitfields {
friend class SwitchStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// True if the SwitchStmt has storage for an init statement.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasInit : 1;
/// True if the SwitchStmt has storage for a condition variable.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasVar : 1;
/// If the SwitchStmt is a switch on an enum value, records whether all
/// the enum values were covered by CaseStmts. The coverage information
/// value is meant to be a hint for possible clients.
+ LLVM_PREFERRED_TYPE(bool)
unsigned AllEnumCasesCovered : 1;
/// The location of the "switch".
@@ -200,9 +233,11 @@ protected:
friend class ASTStmtReader;
friend class WhileStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// True if the WhileStmt has storage for a condition variable.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasVar : 1;
/// The location of the "while".
@@ -212,6 +247,7 @@ protected:
class DoStmtBitfields {
friend class DoStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// The location of the "do".
@@ -221,6 +257,7 @@ protected:
class ForStmtBitfields {
friend class ForStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// The location of the "for".
@@ -231,6 +268,7 @@ protected:
friend class GotoStmt;
friend class IndirectGotoStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// The location of the "goto".
@@ -240,6 +278,7 @@ protected:
class ContinueStmtBitfields {
friend class ContinueStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// The location of the "continue".
@@ -249,6 +288,7 @@ protected:
class BreakStmtBitfields {
friend class BreakStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// The location of the "break".
@@ -258,9 +298,11 @@ protected:
class ReturnStmtBitfields {
friend class ReturnStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// True if this ReturnStmt has storage for an NRVO candidate.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasNRVOCandidate : 1;
/// The location of the "return".
@@ -271,10 +313,12 @@ protected:
friend class SwitchCase;
friend class CaseStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// Used by CaseStmt to store whether it is a case statement
/// of the form case LHS ... RHS (a GNU extension).
+ LLVM_PREFERRED_TYPE(bool)
unsigned CaseStmtIsGNURange : 1;
/// The location of the "case" or "default" keyword.
@@ -307,11 +351,15 @@ protected:
friend class PseudoObjectExpr; // ctor
friend class ShuffleVectorExpr; // ctor
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
+ LLVM_PREFERRED_TYPE(ExprValueKind)
unsigned ValueKind : 2;
+ LLVM_PREFERRED_TYPE(ExprObjectKind)
unsigned ObjectKind : 3;
- unsigned /*ExprDependence*/ Dependent : llvm::BitWidth<ExprDependence>;
+ LLVM_PREFERRED_TYPE(ExprDependence)
+ unsigned Dependent : llvm::BitWidth<ExprDependence>;
};
enum { NumExprBits = NumStmtBits + 5 + llvm::BitWidth<ExprDependence> };
@@ -320,28 +368,35 @@ protected:
friend class ASTStmtWriter;
friend class ConstantExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The kind of result that is tail-allocated.
+ LLVM_PREFERRED_TYPE(ConstantResultStorageKind)
unsigned ResultKind : 2;
- /// The kind of Result as defined by APValue::Kind.
+ /// The kind of Result as defined by APValue::ValueKind.
+ LLVM_PREFERRED_TYPE(APValue::ValueKind)
unsigned APValueKind : 4;
- /// When ResultKind == RSK_Int64, true if the tail-allocated integer is
- /// unsigned.
+ /// When ResultKind == ConstantResultStorageKind::Int64, true if the
+ /// tail-allocated integer is unsigned.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsUnsigned : 1;
- /// When ResultKind == RSK_Int64. the BitWidth of the tail-allocated
- /// integer. 7 bits because it is the minimal number of bits to represent a
- /// value from 0 to 64 (the size of the tail-allocated integer).
+ /// When ResultKind == ConstantResultStorageKind::Int64. the BitWidth of the
+ /// tail-allocated integer. 7 bits because it is the minimal number of bits
+ /// to represent a value from 0 to 64 (the size of the tail-allocated
+ /// integer).
unsigned BitWidth : 7;
- /// When ResultKind == RSK_APValue, true if the ASTContext will cleanup the
- /// tail-allocated APValue.
+ /// When ResultKind == ConstantResultStorageKind::APValue, true if the
+ /// ASTContext will cleanup the tail-allocated APValue.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasCleanup : 1;
/// True if this ConstantExpr was created for immediate invocation.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsImmediateInvocation : 1;
};
@@ -349,16 +404,22 @@ protected:
friend class ASTStmtReader;
friend class PredefinedExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
- /// The kind of this PredefinedExpr. One of the enumeration values
- /// in PredefinedExpr::IdentKind.
+ LLVM_PREFERRED_TYPE(PredefinedIdentKind)
unsigned Kind : 4;
/// True if this PredefinedExpr has a trailing "StringLiteral *"
/// for the predefined identifier.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFunctionName : 1;
+ /// True if this PredefinedExpr should be treated as a StringLiteral (for
+ /// MSVC compatibility).
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsTransparent : 1;
+
/// The location of this PredefinedExpr.
SourceLocation Loc;
};
@@ -367,14 +428,25 @@ protected:
friend class ASTStmtReader; // deserialization
friend class DeclRefExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasQualifier : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFoundDecl : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HadMultipleCandidates : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned RefersToEnclosingVariableOrCapture : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned CapturedByCopyInLambdaWithExplicitObjectParameter : 1;
+ LLVM_PREFERRED_TYPE(NonOdrUseReason)
unsigned NonOdrUseReason : 2;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsImmediateEscalating : 1;
/// The location of the declaration name itself.
SourceLocation Loc;
@@ -384,9 +456,15 @@ protected:
class FloatingLiteralBitfields {
friend class FloatingLiteral;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
- unsigned Semantics : 3; // Provides semantics for APFloat construction
+ static_assert(
+ llvm::APFloat::S_MaxSemantics < 16,
+ "Too many Semantics enum values to fit in bitfield of size 4");
+ LLVM_PREFERRED_TYPE(llvm::APFloat::Semantics)
+ unsigned Semantics : 4; // Provides semantics for APFloat construction
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsExact : 1;
};
@@ -394,10 +472,12 @@ protected:
friend class ASTStmtReader;
friend class StringLiteral;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The kind of this string literal.
/// One of the enumeration values of StringLiteral::StringKind.
+ LLVM_PREFERRED_TYPE(StringLiteralKind)
unsigned Kind : 3;
/// The width of a single character in bytes. Only values of 1, 2,
@@ -405,6 +485,7 @@ protected:
/// the target + string kind to the appropriate CharByteWidth.
unsigned CharByteWidth : 3;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsPascal : 1;
/// The number of concatenated token this string is made of.
@@ -415,22 +496,28 @@ protected:
class CharacterLiteralBitfields {
friend class CharacterLiteral;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(CharacterLiteralKind)
unsigned Kind : 3;
};
class UnaryOperatorBitfields {
friend class UnaryOperator;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(UnaryOperatorKind)
unsigned Opc : 5;
+ LLVM_PREFERRED_TYPE(bool)
unsigned CanOverflow : 1;
//
/// This is only meaningful for operations on floating point
/// types when additional values need to be in trailing storage.
/// It is 0 otherwise.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFPFeatures : 1;
SourceLocation Loc;
@@ -439,9 +526,12 @@ protected:
class UnaryExprOrTypeTraitExprBitfields {
friend class UnaryExprOrTypeTraitExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(UnaryExprOrTypeTrait)
unsigned Kind : 3;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsType : 1; // true if operand is a type, false if an expression.
};
@@ -449,6 +539,7 @@ protected:
friend class ArraySubscriptExpr;
friend class MatrixSubscriptExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
SourceLocation RBracketLoc;
@@ -457,14 +548,17 @@ protected:
class CallExprBitfields {
friend class CallExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
unsigned NumPreArgs : 1;
/// True if the callee of the call expression was found using ADL.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UsesADL : 1;
/// True if the call expression has some floating-point features.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFPFeatures : 1;
/// Padding used to align OffsetToTrailingObjects to a byte multiple.
@@ -481,15 +575,18 @@ protected:
friend class ASTStmtReader;
friend class MemberExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// IsArrow - True if this is "X->F", false if this is "X.F".
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsArrow : 1;
/// True if this member expression used a nested-name-specifier to
/// refer to the member, e.g., "x->Base::f", or found its member via
/// a using declaration. When true, a MemberExprNameQualifier
/// structure is allocated immediately after the MemberExpr.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasQualifierOrFoundDecl : 1;
/// True if this member expression specified a template keyword
@@ -497,15 +594,18 @@ protected:
/// x->template f, x->template f<int>.
/// When true, an ASTTemplateKWAndArgsInfo structure and its
/// TemplateArguments (if any) are present.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;
/// True if this member expression refers to a method that
/// was resolved from an overloaded set having size greater than 1.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HadMultipleCandidates : 1;
/// Value of type NonOdrUseReason indicating why this MemberExpr does
/// not constitute an odr-use of the named declaration. Meaningful only
/// when naming a static member.
+ LLVM_PREFERRED_TYPE(NonOdrUseReason)
unsigned NonOdrUseReason : 2;
/// This is the location of the -> or . in the expression.
@@ -516,12 +616,16 @@ protected:
friend class CastExpr;
friend class ImplicitCastExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(CastKind)
unsigned Kind : 7;
+ LLVM_PREFERRED_TYPE(bool)
unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
/// True if the call expression has some floating-point features.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFPFeatures : 1;
/// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough
@@ -532,13 +636,16 @@ protected:
class BinaryOperatorBitfields {
friend class BinaryOperator;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(BinaryOperatorKind)
unsigned Opc : 6;
/// This is only meaningful for operations on floating point
/// types when additional values need to be in trailing storage.
/// It is 0 otherwise.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFPFeatures : 1;
SourceLocation OpLoc;
@@ -547,10 +654,12 @@ protected:
class InitListExprBitfields {
friend class InitListExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether this initializer list originally had a GNU array-range
/// designator in it. This is a temporary marker used by CodeGen.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HadArrayRangeDesignator : 1;
};
@@ -558,6 +667,7 @@ protected:
friend class ASTStmtReader;
friend class ParenListExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The number of expressions in the paren list.
@@ -568,6 +678,7 @@ protected:
friend class ASTStmtReader;
friend class GenericSelectionExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The location of the "_Generic".
@@ -578,29 +689,31 @@ protected:
friend class ASTStmtReader; // deserialization
friend class PseudoObjectExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
- // These don't need to be particularly wide, because they're
- // strictly limited by the forms of expressions we permit.
- unsigned NumSubExprs : 8;
- unsigned ResultIndex : 32 - 8 - NumExprBits;
+ unsigned NumSubExprs : 16;
+ unsigned ResultIndex : 16;
};
class SourceLocExprBitfields {
friend class ASTStmtReader;
friend class SourceLocExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The kind of source location builtin represented by the SourceLocExpr.
- /// Ex. __builtin_LINE, __builtin_FUNCTION, ect.
- unsigned Kind : 2;
+ /// Ex. __builtin_LINE, __builtin_FUNCTION, etc.
+ LLVM_PREFERRED_TYPE(SourceLocIdentKind)
+ unsigned Kind : 3;
};
class StmtExprBitfields {
friend class ASTStmtReader;
friend class StmtExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The number of levels of template parameters enclosing this statement
@@ -615,10 +728,12 @@ protected:
friend class ASTStmtReader;
friend class CXXOperatorCallExpr;
+ LLVM_PREFERRED_TYPE(CallExprBitfields)
unsigned : NumCallExprBits;
/// The kind of this overloaded operator. One of the enumerator
/// value of OverloadedOperatorKind.
+ LLVM_PREFERRED_TYPE(OverloadedOperatorKind)
unsigned OperatorKind : 6;
};
@@ -626,17 +741,21 @@ protected:
friend class ASTStmtReader;
friend class CXXRewrittenBinaryOperator;
+ LLVM_PREFERRED_TYPE(CallExprBitfields)
unsigned : NumCallExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsReversed : 1;
};
class CXXBoolLiteralExprBitfields {
friend class CXXBoolLiteralExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The value of the boolean literal.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Value : 1;
/// The location of the boolean literal.
@@ -646,6 +765,7 @@ protected:
class CXXNullPtrLiteralExprBitfields {
friend class CXXNullPtrLiteralExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The location of the null pointer literal.
@@ -655,9 +775,11 @@ protected:
class CXXThisExprBitfields {
friend class CXXThisExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether this is an implicit "this".
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsImplicit : 1;
/// The location of the "this".
@@ -668,9 +790,11 @@ protected:
friend class ASTStmtReader;
friend class CXXThrowExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether the thrown variable (if any) is in scope.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsThrownVariableInScope : 1;
/// The location of the "throw".
@@ -681,8 +805,13 @@ protected:
friend class ASTStmtReader;
friend class CXXDefaultArgExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ /// Whether this CXXDefaultArgExpr rewrote its argument and stores a copy.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasRewrittenInit : 1;
+
/// The location where the default argument expression was used.
SourceLocation Loc;
};
@@ -691,8 +820,14 @@ protected:
friend class ASTStmtReader;
friend class CXXDefaultInitExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ /// Whether this CXXDefaultInitExprBitfields rewrote its argument and stores
+ /// a copy.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasRewrittenInit : 1;
+
/// The location where the default initializer expression was used.
SourceLocation Loc;
};
@@ -701,6 +836,7 @@ protected:
friend class ASTStmtReader;
friend class CXXScalarValueInitExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
SourceLocation RParenLoc;
@@ -711,28 +847,37 @@ protected:
friend class ASTStmtWriter;
friend class CXXNewExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Was the usage ::new, i.e. is the global new to be used?
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsGlobalNew : 1;
/// Do we allocate an array? If so, the first trailing "Stmt *" is the
/// size expression.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsArray : 1;
/// Should the alignment be passed to the allocation function?
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShouldPassAlignment : 1;
/// If this is an array allocation, does the usual deallocation
/// function for the allocated type want to know the allocated size?
+ LLVM_PREFERRED_TYPE(bool)
unsigned UsualArrayDeleteWantsSize : 1;
- /// What kind of initializer do we have? Could be none, parens, or braces.
- /// In storage, we distinguish between "none, and no initializer expr", and
- /// "none, but an implicit initializer expr".
+ // Is initializer expr present?
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasInitializer : 1;
+
+ /// What kind of initializer syntax used? Could be none, parens, or braces.
+ LLVM_PREFERRED_TYPE(CXXNewInitializationStyle)
unsigned StoredInitializationStyle : 2;
/// True if the allocated type was expressed as a parenthesized type-id.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsParenTypeId : 1;
/// The number of placement new arguments.
@@ -743,21 +888,26 @@ protected:
friend class ASTStmtReader;
friend class CXXDeleteExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Is this a forced global delete, i.e. "::delete"?
+ LLVM_PREFERRED_TYPE(bool)
unsigned GlobalDelete : 1;
/// Is this the array form of delete, i.e. "delete[]"?
+ LLVM_PREFERRED_TYPE(bool)
unsigned ArrayForm : 1;
/// ArrayFormAsWritten can be different from ArrayForm if 'delete' is
/// applied to pointer-to-array type (ArrayFormAsWritten will be false
/// while ArrayForm will be true).
+ LLVM_PREFERRED_TYPE(bool)
unsigned ArrayFormAsWritten : 1;
/// Does the usual deallocation function for the element type require
/// a size_t argument?
+ LLVM_PREFERRED_TYPE(bool)
unsigned UsualArrayDeleteWantsSize : 1;
/// Location of the expression.
@@ -769,13 +919,16 @@ protected:
friend class ASTStmtWriter;
friend class TypeTraitExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The kind of type trait, which is a value of a TypeTrait enumerator.
+ LLVM_PREFERRED_TYPE(TypeTrait)
unsigned Kind : 8;
/// If this expression is not value-dependent, this indicates whether
/// the trait evaluated true or false.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Value : 1;
/// The number of arguments to this type trait. According to [implimits]
@@ -789,10 +942,12 @@ protected:
friend class ASTStmtWriter;
friend class DependentScopeDeclRefExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether the name includes info for explicit template
/// keyword and arguments.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;
};
@@ -800,14 +955,23 @@ protected:
friend class ASTStmtReader;
friend class CXXConstructExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned Elidable : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HadMultipleCandidates : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ListInitialization : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned StdInitListInitialization : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ZeroInitialization : 1;
+ LLVM_PREFERRED_TYPE(CXXConstructionKind)
unsigned ConstructionKind : 3;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsImmediateEscalating : 1;
SourceLocation Loc;
};
@@ -816,9 +980,11 @@ protected:
friend class ASTStmtReader; // deserialization
friend class ExprWithCleanups;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
// When false, it must not have side effects.
+ LLVM_PREFERRED_TYPE(bool)
unsigned CleanupsHaveSideEffects : 1;
unsigned NumObjects : 32 - 1 - NumExprBits;
@@ -828,6 +994,7 @@ protected:
friend class ASTStmtReader;
friend class CXXUnresolvedConstructExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The number of arguments used to construct the type.
@@ -838,18 +1005,22 @@ protected:
friend class ASTStmtReader;
friend class CXXDependentScopeMemberExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether this member expression used the '->' operator or
/// the '.' operator.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsArrow : 1;
/// Whether this member expression has info for explicit template
/// keyword and arguments.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;
/// See getFirstQualifierFoundInScope() and the comment listing
/// the trailing objects.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFirstQualifierFoundInScope : 1;
/// The location of the '->' or '.' operator.
@@ -860,10 +1031,12 @@ protected:
friend class ASTStmtReader;
friend class OverloadExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether the name includes info for explicit template
/// keyword and arguments.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;
/// Padding used by the derived classes to store various bits. If you
@@ -880,14 +1053,17 @@ protected:
friend class ASTStmtReader;
friend class UnresolvedLookupExpr;
+ LLVM_PREFERRED_TYPE(OverloadExprBitfields)
unsigned : NumOverloadExprBits;
/// True if these lookup results should be extended by
/// argument-dependent lookup if this is the operand of a function call.
+ LLVM_PREFERRED_TYPE(bool)
unsigned RequiresADL : 1;
/// True if these lookup results are overloaded. This is pretty trivially
/// rederivable if we urgently need to kill this field.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Overloaded : 1;
};
static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4,
@@ -898,13 +1074,16 @@ protected:
friend class ASTStmtReader;
friend class UnresolvedMemberExpr;
+ LLVM_PREFERRED_TYPE(OverloadExprBitfields)
unsigned : NumOverloadExprBits;
/// Whether this member expression used the '->' operator or
/// the '.' operator.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsArrow : 1;
/// Whether the lookup results contain an unresolved using declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasUnresolvedUsing : 1;
};
static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4,
@@ -915,8 +1094,10 @@ protected:
friend class ASTStmtReader;
friend class CXXNoexceptExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned Value : 1;
};
@@ -924,6 +1105,7 @@ protected:
friend class ASTStmtReader;
friend class SubstNonTypeTemplateParmExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The location of the non-type template parameter reference.
@@ -935,17 +1117,21 @@ protected:
friend class ASTStmtWriter;
friend class LambdaExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The default capture kind, which is a value of type
/// LambdaCaptureDefault.
+ LLVM_PREFERRED_TYPE(LambdaCaptureDefault)
unsigned CaptureDefault : 2;
/// Whether this lambda had an explicit parameter list vs. an
/// implicit (and empty) parameter list.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ExplicitParams : 1;
/// Whether this lambda had the result type explicitly specified.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ExplicitResultType : 1;
/// The number of captures.
@@ -957,19 +1143,23 @@ protected:
friend class ASTStmtWriter;
friend class RequiresExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsSatisfied : 1;
SourceLocation RequiresKWLoc;
};
- //===--- C++ Coroutines TS bitfields classes ---===//
+ //===--- C++ Coroutines bitfields classes ---===//
class CoawaitExprBitfields {
friend class CoawaitExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsImplicit : 1;
};
@@ -978,8 +1168,10 @@ protected:
class ObjCIndirectCopyRestoreExprBitfields {
friend class ObjCIndirectCopyRestoreExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShouldCopy : 1;
};
@@ -989,10 +1181,12 @@ protected:
friend class ASTStmtReader;
friend class OpaqueValueExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The OVE is a unique semantic reference to its source expression if this
/// bit is set to true.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsUnique : 1;
SourceLocation Loc;
@@ -1067,7 +1261,7 @@ protected:
LambdaExprBitfields LambdaExprBits;
RequiresExprBitfields RequiresExprBits;
- // C++ Coroutines TS expressions
+ // C++ Coroutines expressions
CoawaitExprBitfields CoawaitBits;
// Obj-C Expressions
@@ -1215,6 +1409,11 @@ public:
const PrintingPolicy &Policy, unsigned Indentation = 0,
StringRef NewlineSymbol = "\n",
const ASTContext *Context = nullptr) const;
+ void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper,
+ const PrintingPolicy &Policy,
+ unsigned Indentation = 0,
+ StringRef NewlineSymbol = "\n",
+ const ASTContext *Context = nullptr) const;
/// Pretty-prints in JSON format.
void printJson(raw_ostream &Out, PrinterHelper *Helper,
@@ -1238,7 +1437,7 @@ public:
}
/// Child Iterators: All subclasses must implement 'children'
- /// to permit easy iteration over the substatements/subexpessions of an
+ /// to permit easy iteration over the substatements/subexpressions of an
/// AST node. This permits easy iteration over all nodes in the AST.
using child_iterator = StmtIterator;
using const_child_iterator = ConstStmtIterator;
@@ -1271,8 +1470,13 @@ public:
/// parameters are identified by index/level rather than their
/// declaration pointers) or the exact representation of the statement as
/// written in the source.
+ /// \param ProfileLambdaExpr whether or not to profile lambda expressions.
+ /// When false, the lambda expressions are never considered to be equal to
+ /// other lambda expressions. When true, the lambda expressions with the same
+ /// implementation will be considered to be the same. ProfileLambdaExpr should
+ /// only be true when we try to merge two declarations within modules.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- bool Canonical) const;
+ bool Canonical, bool ProfileLambdaExpr = false) const;
/// Calculate a unique representation for a statement that is
/// stable across compiler invocations.
@@ -1395,36 +1599,63 @@ public:
};
/// CompoundStmt - This represents a group of statements like { stmt stmt }.
-class CompoundStmt final : public Stmt,
- private llvm::TrailingObjects<CompoundStmt, Stmt *> {
+class CompoundStmt final
+ : public Stmt,
+ private llvm::TrailingObjects<CompoundStmt, Stmt *, FPOptionsOverride> {
friend class ASTStmtReader;
friend TrailingObjects;
- /// The location of the closing "}". LBraceLoc is stored in CompoundStmtBits.
+ /// The location of the opening "{".
+ SourceLocation LBraceLoc;
+
+ /// The location of the closing "}".
SourceLocation RBraceLoc;
- CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB, SourceLocation RB);
+ CompoundStmt(ArrayRef<Stmt *> Stmts, FPOptionsOverride FPFeatures,
+ SourceLocation LB, SourceLocation RB);
explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {}
void setStmts(ArrayRef<Stmt *> Stmts);
+ /// Set FPOptionsOverride in trailing storage. Used only by Serialization.
+ void setStoredFPFeatures(FPOptionsOverride F) {
+ assert(hasStoredFPFeatures());
+ *getTrailingObjects<FPOptionsOverride>() = F;
+ }
+
+ size_t numTrailingObjects(OverloadToken<Stmt *>) const {
+ return CompoundStmtBits.NumStmts;
+ }
+
public:
static CompoundStmt *Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
- SourceLocation LB, SourceLocation RB);
+ FPOptionsOverride FPFeatures, SourceLocation LB,
+ SourceLocation RB);
// Build an empty compound statement with a location.
- explicit CompoundStmt(SourceLocation Loc)
- : Stmt(CompoundStmtClass), RBraceLoc(Loc) {
+ explicit CompoundStmt(SourceLocation Loc) : CompoundStmt(Loc, Loc) {}
+
+ CompoundStmt(SourceLocation Loc, SourceLocation EndLoc)
+ : Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(EndLoc) {
CompoundStmtBits.NumStmts = 0;
- CompoundStmtBits.LBraceLoc = Loc;
+ CompoundStmtBits.HasFPFeatures = 0;
}
// Build an empty compound statement.
- static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts);
+ static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts,
+ bool HasFPFeatures);
bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
unsigned size() const { return CompoundStmtBits.NumStmts; }
+ bool hasStoredFPFeatures() const { return CompoundStmtBits.HasFPFeatures; }
+
+ /// Get FPOptionsOverride from trailing storage.
+ FPOptionsOverride getStoredFPFeatures() const {
+ assert(hasStoredFPFeatures());
+ return *getTrailingObjects<FPOptionsOverride>();
+ }
+
using body_iterator = Stmt **;
using body_range = llvm::iterator_range<body_iterator>;
@@ -1499,10 +1730,10 @@ public:
return const_cast<CompoundStmt *>(this)->getStmtExprResult();
}
- SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; }
+ SourceLocation getBeginLoc() const { return LBraceLoc; }
SourceLocation getEndLoc() const { return RBraceLoc; }
- SourceLocation getLBracLoc() const { return CompoundStmtBits.LBraceLoc; }
+ SourceLocation getLBracLoc() const { return LBraceLoc; }
SourceLocation getRBracLoc() const { return RBraceLoc; }
static bool classof(const Stmt *T) {
@@ -1879,7 +2110,7 @@ public:
SourceLocation getAttrLoc() const { return AttributedStmtBits.AttrLoc; }
ArrayRef<const Attr *> getAttrs() const {
- return llvm::makeArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs);
+ return llvm::ArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs);
}
Stmt *getSubStmt() { return SubStmt; }
@@ -1950,8 +2181,8 @@ class IfStmt final
unsigned elseOffset() const { return condOffset() + ElseOffsetFromCond; }
/// Build an if/then/else statement.
- IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr, Stmt *Init,
- VarDecl *Var, Expr *Cond, SourceLocation LParenLoc,
+ IfStmt(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind,
+ Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LParenLoc,
SourceLocation RParenLoc, Stmt *Then, SourceLocation EL, Stmt *Else);
/// Build an empty if/then/else statement.
@@ -1960,9 +2191,9 @@ class IfStmt final
public:
/// Create an IfStmt.
static IfStmt *Create(const ASTContext &Ctx, SourceLocation IL,
- bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond,
- SourceLocation LPL, SourceLocation RPL, Stmt *Then,
- SourceLocation EL = SourceLocation(),
+ IfStatementKind Kind, Stmt *Init, VarDecl *Var,
+ Expr *Cond, SourceLocation LPL, SourceLocation RPL,
+ Stmt *Then, SourceLocation EL = SourceLocation(),
Stmt *Else = nullptr);
/// Create an empty IfStmt optionally with storage for an else statement,
@@ -2047,6 +2278,11 @@ public:
: nullptr;
}
+ void setConditionVariableDeclStmt(DeclStmt *CondVar) {
+ assert(hasVarStorage());
+ getTrailingObjects<Stmt *>()[varOffset()] = CondVar;
+ }
+
Stmt *getInit() {
return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
: nullptr;
@@ -2077,13 +2313,35 @@ public:
*getTrailingObjects<SourceLocation>() = ElseLoc;
}
- bool isConstexpr() const { return IfStmtBits.IsConstexpr; }
- void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; }
+ bool isConsteval() const {
+ return getStatementKind() == IfStatementKind::ConstevalNonNegated ||
+ getStatementKind() == IfStatementKind::ConstevalNegated;
+ }
+
+ bool isNonNegatedConsteval() const {
+ return getStatementKind() == IfStatementKind::ConstevalNonNegated;
+ }
+
+ bool isNegatedConsteval() const {
+ return getStatementKind() == IfStatementKind::ConstevalNegated;
+ }
+
+ bool isConstexpr() const {
+ return getStatementKind() == IfStatementKind::Constexpr;
+ }
+
+ void setStatementKind(IfStatementKind Kind) {
+ IfStmtBits.Kind = static_cast<unsigned>(Kind);
+ }
+
+ IfStatementKind getStatementKind() const {
+ return static_cast<IfStatementKind>(IfStmtBits.Kind);
+ }
/// If this is an 'if constexpr', determine which substatement will be taken.
- /// Otherwise, or if the condition is value-dependent, returns None.
- Optional<const Stmt*> getNondiscardedCase(const ASTContext &Ctx) const;
- Optional<Stmt *> getNondiscardedCase(const ASTContext &Ctx);
+ /// Otherwise, or if the condition is value-dependent, returns std::nullopt.
+ std::optional<const Stmt *> getNondiscardedCase(const ASTContext &Ctx) const;
+ std::optional<Stmt *> getNondiscardedCase(const ASTContext &Ctx);
bool isObjCAvailabilityCheck() const;
@@ -2101,13 +2359,19 @@ public:
// Iterators over subexpressions. The iterators will include iterating
// over the initialization expression referenced by the condition variable.
child_range children() {
- return child_range(getTrailingObjects<Stmt *>(),
+ // We always store a condition, but there is none for consteval if
+ // statements, so skip it.
+ return child_range(getTrailingObjects<Stmt *>() +
+ (isConsteval() ? thenOffset() : 0),
getTrailingObjects<Stmt *>() +
numTrailingObjects(OverloadToken<Stmt *>()));
}
const_child_range children() const {
- return const_child_range(getTrailingObjects<Stmt *>(),
+ // We always store a condition, but there is none for consteval if
+ // statements, so skip it.
+ return const_child_range(getTrailingObjects<Stmt *>() +
+ (isConsteval() ? thenOffset() : 0),
getTrailingObjects<Stmt *>() +
numTrailingObjects(OverloadToken<Stmt *>()));
}
@@ -2251,6 +2515,11 @@ public:
: nullptr;
}
+ void setConditionVariableDeclStmt(DeclStmt *CondVar) {
+ assert(hasVarStorage());
+ getTrailingObjects<Stmt *>()[varOffset()] = CondVar;
+ }
+
SwitchCase *getSwitchCaseList() { return FirstCase; }
const SwitchCase *getSwitchCaseList() const { return FirstCase; }
void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
@@ -2414,6 +2683,11 @@ public:
: nullptr;
}
+ void setConditionVariableDeclStmt(DeclStmt *CondVar) {
+ assert(hasVarStorage());
+ getTrailingObjects<Stmt *>()[varOffset()] = CondVar;
+ }
+
SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; }
void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; }
@@ -2503,6 +2777,8 @@ public:
/// the init/cond/inc parts of the ForStmt will be null if they were not
/// specified in the source.
class ForStmt : public Stmt {
+ friend class ASTStmtReader;
+
enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
SourceLocation LParenLoc, RParenLoc;
@@ -2530,10 +2806,18 @@ public:
/// If this ForStmt has a condition variable, return the faux DeclStmt
/// associated with the creation of that condition variable.
+ DeclStmt *getConditionVariableDeclStmt() {
+ return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
+ }
+
const DeclStmt *getConditionVariableDeclStmt() const {
return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
}
+ void setConditionVariableDeclStmt(DeclStmt *CondVar) {
+ SubExprs[CONDVAR] = CondVar;
+ }
+
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
Stmt *getBody() { return SubExprs[BODY]; }
@@ -3262,16 +3546,16 @@ public:
//===--- Other ---===//
ArrayRef<StringRef> getAllConstraints() const {
- return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
+ return llvm::ArrayRef(Constraints, NumInputs + NumOutputs);
}
ArrayRef<StringRef> getClobbers() const {
- return llvm::makeArrayRef(Clobbers, NumClobbers);
+ return llvm::ArrayRef(Clobbers, NumClobbers);
}
ArrayRef<Expr*> getAllExprs() const {
- return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
- NumInputs + NumOutputs);
+ return llvm::ArrayRef(reinterpret_cast<Expr **>(Exprs),
+ NumInputs + NumOutputs);
}
StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
@@ -3485,8 +3769,11 @@ public:
llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
SourceLocation Loc;
+ Capture() = default;
+
public:
friend class ASTStmtReader;
+ friend class CapturedStmt;
/// Create a new capture.
///
diff --git a/contrib/llvm-project/clang/include/clang/AST/StmtCXX.h b/contrib/llvm-project/clang/include/clang/AST/StmtCXX.h
index 4d1f3e8ef255..8b4ef24ed376 100644
--- a/contrib/llvm-project/clang/include/clang/AST/StmtCXX.h
+++ b/contrib/llvm-project/clang/include/clang/AST/StmtCXX.h
@@ -75,7 +75,8 @@ class CXXTryStmt final : public Stmt,
unsigned NumHandlers;
size_t numTrailingObjects(OverloadToken<Stmt *>) const { return NumHandlers; }
- CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers);
+ CXXTryStmt(SourceLocation tryLoc, CompoundStmt *tryBlock,
+ ArrayRef<Stmt *> handlers);
CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
: Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
@@ -84,7 +85,7 @@ class CXXTryStmt final : public Stmt,
public:
static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc,
- Stmt *tryBlock, ArrayRef<Stmt*> handlers);
+ CompoundStmt *tryBlock, ArrayRef<Stmt *> handlers);
static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
unsigned numHandlers);
@@ -326,8 +327,8 @@ class CoroutineBodyStmt final
OnFallthrough, ///< Handler for control flow falling off the body.
Allocate, ///< Coroutine frame memory allocation.
Deallocate, ///< Coroutine frame memory deallocation.
- ReturnValue, ///< Return value for thunk function: p.get_return_object().
ResultDecl, ///< Declaration holding the result of get_return_object.
+ ReturnValue, ///< Return value for thunk function: p.get_return_object().
ReturnStmt, ///< Return statement for the thunk function.
ReturnStmtOnAllocFailure, ///< Return statement if allocation failed.
FirstParamMove ///< First offset for move construction of parameter copies.
@@ -353,8 +354,8 @@ public:
Stmt *OnFallthrough = nullptr;
Expr *Allocate = nullptr;
Expr *Deallocate = nullptr;
- Expr *ReturnValue = nullptr;
Stmt *ResultDecl = nullptr;
+ Expr *ReturnValue = nullptr;
Stmt *ReturnStmt = nullptr;
Stmt *ReturnStmtOnAllocFailure = nullptr;
ArrayRef<Stmt *> ParamMoves;
@@ -374,9 +375,10 @@ public:
}
/// Retrieve the body of the coroutine as written. This will be either
- /// a CompoundStmt or a TryStmt.
- Stmt *getBody() const {
- return getStoredStmts()[SubStmt::Body];
+ /// a CompoundStmt. If the coroutine is in function-try-block, we will
+ /// wrap the CXXTryStmt into a CompoundStmt to keep consistency.
+ CompoundStmt *getBody() const {
+ return cast<CompoundStmt>(getStoredStmts()[SubStmt::Body]);
}
Stmt *getPromiseDeclStmt() const {
@@ -406,10 +408,14 @@ public:
Expr *getDeallocate() const {
return cast_or_null<Expr>(getStoredStmts()[SubStmt::Deallocate]);
}
+ Stmt *getResultDecl() const { return getStoredStmts()[SubStmt::ResultDecl]; }
Expr *getReturnValueInit() const {
return cast<Expr>(getStoredStmts()[SubStmt::ReturnValue]);
}
- Stmt *getResultDecl() const { return getStoredStmts()[SubStmt::ResultDecl]; }
+ Expr *getReturnValue() const {
+ auto *RS = dyn_cast_or_null<clang::ReturnStmt>(getReturnStmt());
+ return RS ? RS->getRetValue() : nullptr;
+ }
Stmt *getReturnStmt() const { return getStoredStmts()[SubStmt::ReturnStmt]; }
Stmt *getReturnStmtOnAllocFailure() const {
return getStoredStmts()[SubStmt::ReturnStmtOnAllocFailure];
@@ -437,6 +443,17 @@ public:
NumParams);
}
+ child_range childrenExclBody() {
+ return child_range(getStoredStmts() + SubStmt::Body + 1,
+ getStoredStmts() + SubStmt::FirstParamMove + NumParams);
+ }
+
+ const_child_range childrenExclBody() const {
+ return const_child_range(getStoredStmts() + SubStmt::Body + 1,
+ getStoredStmts() + SubStmt::FirstParamMove +
+ NumParams);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CoroutineBodyStmtClass;
}
@@ -495,16 +512,10 @@ public:
}
child_range children() {
- if (!getOperand())
- return child_range(SubStmts + SubStmt::PromiseCall,
- SubStmts + SubStmt::Count);
return child_range(SubStmts, SubStmts + SubStmt::Count);
}
const_child_range children() const {
- if (!getOperand())
- return const_child_range(SubStmts + SubStmt::PromiseCall,
- SubStmts + SubStmt::Count);
return const_child_range(SubStmts, SubStmts + SubStmt::Count);
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h b/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h
index 948ef2421cb9..c46ff4634c82 100644
--- a/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h
+++ b/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h
@@ -162,8 +162,14 @@ public:
};
/// Represents Objective-C's \@try ... \@catch ... \@finally statement.
-class ObjCAtTryStmt : public Stmt {
-private:
+class ObjCAtTryStmt final
+ : public Stmt,
+ private llvm::TrailingObjects<ObjCAtTryStmt, Stmt *> {
+ friend TrailingObjects;
+ size_t numTrailingObjects(OverloadToken<Stmt *>) const {
+ return 1 + NumCatchStmts + HasFinally;
+ }
+
// The location of the @ in the \@try.
SourceLocation AtTryLoc;
@@ -178,10 +184,8 @@ private:
/// The order of the statements in memory follows the order in the source,
/// with the \@try body first, followed by the \@catch statements (if any)
/// and, finally, the \@finally (if it exists).
- Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); }
- const Stmt* const *getStmts() const {
- return reinterpret_cast<const Stmt * const*> (this + 1);
- }
+ Stmt **getStmts() { return getTrailingObjects<Stmt *>(); }
+ Stmt *const *getStmts() const { return getTrailingObjects<Stmt *>(); }
ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
Stmt **CatchStmts, unsigned NumCatchStmts,
@@ -257,13 +261,34 @@ public:
}
child_range children() {
- return child_range(getStmts(),
- getStmts() + 1 + NumCatchStmts + HasFinally);
+ return child_range(
+ getStmts(), getStmts() + numTrailingObjects(OverloadToken<Stmt *>()));
}
const_child_range children() const {
return const_child_range(const_cast<ObjCAtTryStmt *>(this)->children());
}
+
+ using catch_stmt_iterator = CastIterator<ObjCAtCatchStmt>;
+ using const_catch_stmt_iterator = ConstCastIterator<ObjCAtCatchStmt>;
+ using catch_range = llvm::iterator_range<catch_stmt_iterator>;
+ using catch_const_range = llvm::iterator_range<const_catch_stmt_iterator>;
+
+ catch_stmt_iterator catch_stmts_begin() { return getStmts() + 1; }
+ catch_stmt_iterator catch_stmts_end() {
+ return catch_stmts_begin() + NumCatchStmts;
+ }
+ catch_range catch_stmts() {
+ return catch_range(catch_stmts_begin(), catch_stmts_end());
+ }
+
+ const_catch_stmt_iterator catch_stmts_begin() const { return getStmts() + 1; }
+ const_catch_stmt_iterator catch_stmts_end() const {
+ return catch_stmts_begin() + NumCatchStmts;
+ }
+ catch_const_range catch_stmts() const {
+ return catch_const_range(catch_stmts_begin(), catch_stmts_end());
+ }
};
/// Represents Objective-C's \@synchronized statement.
diff --git a/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h b/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h
index 9c85df741f48..621643391535 100644
--- a/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h
+++ b/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h
@@ -277,10 +277,19 @@ class OMPExecutableDirective : public Stmt {
/// Get the clauses storage.
MutableArrayRef<OMPClause *> getClauses() {
if (!Data)
- return llvm::None;
+ return std::nullopt;
return Data->getClauses();
}
+ /// Was this directive mapped from an another directive?
+ /// e.g. 1) omp loop bind(parallel) is mapped to OMPD_for
+ /// 2) omp loop bind(teams) is mapped to OMPD_distribute
+ /// 3) omp loop bind(thread) is mapped to OMPD_simd
+ /// It was necessary to note it down in the Directive because of
+ /// clang::TreeTransform::TransformOMPExecutableDirective() pass in
+ /// the frontend.
+ OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown;
+
protected:
/// Data, associated with the directive.
OMPChildren *Data = nullptr;
@@ -345,6 +354,10 @@ protected:
return Inst;
}
+ void setMappedDirective(OpenMPDirectiveKind MappedDirective) {
+ PrevMappedDirective = MappedDirective;
+ }
+
public:
/// Iterates over expressions/statements used in the construct.
class used_clauses_child_iterator
@@ -399,8 +412,9 @@ public:
static llvm::iterator_range<used_clauses_child_iterator>
used_clauses_children(ArrayRef<OMPClause *> Clauses) {
- return {used_clauses_child_iterator(Clauses),
- used_clauses_child_iterator(llvm::makeArrayRef(Clauses.end(), 0))};
+ return {
+ used_clauses_child_iterator(Clauses),
+ used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))};
}
/// Iterates over a filtered subrange of clauses applied to a
@@ -445,7 +459,7 @@ public:
getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
return {specific_clause_iterator<SpecificClause>(Clauses),
specific_clause_iterator<SpecificClause>(
- llvm::makeArrayRef(Clauses.end(), 0))};
+ llvm::ArrayRef(Clauses.end(), (size_t)0))};
}
template <typename SpecificClause>
@@ -571,7 +585,7 @@ public:
ArrayRef<OMPClause *> clauses() const {
if (!Data)
- return llvm::None;
+ return std::nullopt;
return Data->getClauses();
}
@@ -597,6 +611,8 @@ public:
"Expected directive with the associated statement.");
return Data->getRawStmt();
}
+
+ OpenMPDirectiveKind getMappedDirective() const { return PrevMappedDirective; }
};
/// This represents '#pragma omp parallel' directive.
@@ -889,22 +905,23 @@ public:
/// Calls the specified callback function for all the loops in \p CurStmt,
/// from the outermost to the innermost.
- static bool doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
- unsigned NumLoops,
- llvm::function_ref<bool(unsigned, Stmt *)> Callback,
- llvm::function_ref<void(OMPLoopBasedDirective *)>
- OnTransformationCallback);
+ static bool
+ doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
+ unsigned NumLoops,
+ llvm::function_ref<bool(unsigned, Stmt *)> Callback,
+ llvm::function_ref<void(OMPLoopTransformationDirective *)>
+ OnTransformationCallback);
static bool
doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
unsigned NumLoops,
llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
- llvm::function_ref<void(const OMPLoopBasedDirective *)>
+ llvm::function_ref<void(const OMPLoopTransformationDirective *)>
OnTransformationCallback) {
auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
return Callback(Cnt, CurStmt);
};
auto &&NewTransformCb =
- [OnTransformationCallback](OMPLoopBasedDirective *A) {
+ [OnTransformationCallback](OMPLoopTransformationDirective *A) {
OnTransformationCallback(A);
};
return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
@@ -917,7 +934,7 @@ public:
doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
unsigned NumLoops,
llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
- auto &&TransformCb = [](OMPLoopBasedDirective *) {};
+ auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
TransformCb);
}
@@ -954,6 +971,47 @@ public:
}
};
+/// The base class for all loop transformation directives.
+class OMPLoopTransformationDirective : public OMPLoopBasedDirective {
+ friend class ASTStmtReader;
+
+ /// Number of loops generated by this loop transformation.
+ unsigned NumGeneratedLoops = 0;
+
+protected:
+ explicit OMPLoopTransformationDirective(StmtClass SC,
+ OpenMPDirectiveKind Kind,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned NumAssociatedLoops)
+ : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
+
+ /// Set the number of loops generated by this loop transformation.
+ void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }
+
+public:
+ /// Return the number of associated (consumed) loops.
+ unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
+
+ /// Return the number of loops generated by this loop transformation.
+ unsigned getNumGeneratedLoops() const { return NumGeneratedLoops; }
+
+ /// Get the de-sugared statements after the loop transformation.
+ ///
+ /// Might be nullptr if either the directive generates no loops and is handled
+ /// directly in CodeGen, or resolving a template-dependence context is
+ /// required.
+ Stmt *getTransformedStmt() const;
+
+ /// Return preinits statement.
+ Stmt *getPreInits() const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTileDirectiveClass ||
+ T->getStmtClass() == OMPUnrollDirectiveClass;
+ }
+};
+
/// This is a common base class for loop directives ('omp simd', 'omp
/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
///
@@ -1024,7 +1082,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
MutableArrayRef<Expr *> getCounters() {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind())]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the private counters storage.
@@ -1032,7 +1090,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the updates storage.
@@ -1040,7 +1098,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
2 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the updates storage.
@@ -1048,7 +1106,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
3 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the final counter updates storage.
@@ -1056,7 +1114,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
4 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the dependent counters storage.
@@ -1064,7 +1122,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
5 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the dependent inits storage.
@@ -1072,7 +1130,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
6 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the finals conditions storage.
@@ -1080,7 +1138,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
7 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
protected:
@@ -1102,7 +1160,7 @@ protected:
if (isOpenMPLoopBoundSharingDirective(Kind))
return CombinedDistributeEnd;
if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
- isOpenMPDistributeDirective(Kind))
+ isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind))
return WorksharingEnd;
return DefaultEnd;
}
@@ -1134,6 +1192,7 @@ protected:
}
void setIsLastIterVariable(Expr *IL) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1141,6 +1200,7 @@ protected:
}
void setLowerBoundVariable(Expr *LB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1148,6 +1208,7 @@ protected:
}
void setUpperBoundVariable(Expr *UB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1155,6 +1216,7 @@ protected:
}
void setStrideVariable(Expr *ST) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1162,6 +1224,7 @@ protected:
}
void setEnsureUpperBound(Expr *EUB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1169,6 +1232,7 @@ protected:
}
void setNextLowerBound(Expr *NLB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1176,6 +1240,7 @@ protected:
}
void setNextUpperBound(Expr *NUB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1183,6 +1248,7 @@ protected:
}
void setNumIterations(Expr *NI) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1285,6 +1351,7 @@ public:
Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
Expr *getIsLastIterVariable() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1292,6 +1359,7 @@ public:
}
Expr *getLowerBoundVariable() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1299,6 +1367,7 @@ public:
}
Expr *getUpperBoundVariable() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1306,6 +1375,7 @@ public:
}
Expr *getStrideVariable() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1313,6 +1383,7 @@ public:
}
Expr *getEnsureUpperBound() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1320,6 +1391,7 @@ public:
}
Expr *getNextLowerBound() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1327,6 +1399,7 @@ public:
}
Expr *getNextUpperBound() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1334,6 +1407,7 @@ public:
}
Expr *getNumIterations() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1465,8 +1539,17 @@ public:
T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
T->getStmtClass() == OMPTaskLoopDirectiveClass ||
T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
+ T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
+ T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
+ T->getStmtClass() == OMPGenericLoopDirectiveClass ||
+ T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
+ T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
+ T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
+ T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
+ T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
+ T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
T->getStmtClass() == OMPDistributeDirectiveClass ||
@@ -1536,7 +1619,8 @@ public:
SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt,
- const HelperExprs &Exprs);
+ const HelperExprs &Exprs,
+ OpenMPDirectiveKind ParamPrevMappedDirective);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -1614,7 +1698,8 @@ public:
SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs,
- Expr *TaskRedRef, bool HasCancel);
+ Expr *TaskRedRef, bool HasCancel,
+ OpenMPDirectiveKind ParamPrevMappedDirective);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -1846,6 +1931,57 @@ public:
}
};
+/// This represents '#pragma omp scope' directive.
+/// \code
+/// #pragma omp scope private(a,b) nowait
+/// \endcode
+/// In this example directive '#pragma omp scope' has clauses 'private' with
+/// the variables 'a' and 'b' and nowait.
+///
+class OMPScopeDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPScopeDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope,
+ StartLoc, EndLoc) {}
+
+ /// Build an empty directive.
+ ///
+ explicit OMPScopeDirective()
+ : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope,
+ SourceLocation(), SourceLocation()) {}
+
+public:
+ /// Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPScopeDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt);
+
+ /// Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPScopeDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPScopeDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp single' directive.
///
/// \code
@@ -2241,6 +2377,69 @@ public:
}
};
+/// This represents '#pragma omp parallel masked' directive.
+///
+/// \code
+/// #pragma omp parallel masked filter(tid)
+/// \endcode
+/// In this example directive '#pragma omp parallel masked' has a clause
+/// 'filter' with the variable tid
+///
+class OMPParallelMaskedDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+
+ OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
+ llvm::omp::OMPD_parallel_masked, StartLoc,
+ EndLoc) {}
+
+ explicit OMPParallelMaskedDirective()
+ : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
+ llvm::omp::OMPD_parallel_masked,
+ SourceLocation(), SourceLocation()) {}
+
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
+ ///
+ static OMPParallelMaskedDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
+
+ /// Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelMaskedDirective *
+ CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
+
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() {
+ return cast_or_null<Expr>(Data->getChildren()[0]);
+ }
+ const Expr *getTaskReductionRefExpr() const {
+ return const_cast<OMPParallelMaskedDirective *>(this)
+ ->getTaskReductionRefExpr();
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp parallel sections' directive.
///
/// \code
@@ -2510,15 +2709,20 @@ public:
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
///
- static OMPTaskwaitDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+ static OMPTaskwaitDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses);
/// Creates an empty directive.
///
/// \param C AST context.
+ /// \param NumClauses Number of clauses.
///
- static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+ static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTaskwaitDirectiveClass;
@@ -2738,7 +2942,7 @@ public:
///
/// \param C AST context.
/// \param NumClauses Number of clauses.
- /// \param IsStandalone true, if the the standalone directive is created.
+ /// \param IsStandalone true, if the standalone directive is created.
///
static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses,
@@ -2759,25 +2963,31 @@ public:
class OMPAtomicDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
friend class OMPExecutableDirective;
- /// Used for 'atomic update' or 'atomic capture' constructs. They may
- /// have atomic expressions of forms
- /// \code
- /// x = x binop expr;
- /// x = expr binop x;
- /// \endcode
- /// This field is true for the first form of the expression and false for the
- /// second. Required for correct codegen of non-associative operations (like
- /// << or >>).
- bool IsXLHSInRHSPart = false;
- /// Used for 'atomic update' or 'atomic capture' constructs. They may
- /// have atomic expressions of forms
- /// \code
- /// v = x; <update x>;
- /// <update x>; v = x;
- /// \endcode
- /// This field is true for the first(postfix) form of the expression and false
- /// otherwise.
- bool IsPostfixUpdate = false;
+
+ struct FlagTy {
+ /// Used for 'atomic update' or 'atomic capture' constructs. They may
+ /// have atomic expressions of forms:
+ /// \code
+ /// x = x binop expr;
+ /// x = expr binop x;
+ /// \endcode
+ /// This field is 1 for the first form of the expression and 0 for the
+ /// second. Required for correct codegen of non-associative operations (like
+ /// << or >>).
+ uint8_t IsXLHSInRHSPart : 1;
+ /// Used for 'atomic update' or 'atomic capture' constructs. They may
+ /// have atomic expressions of forms:
+ /// \code
+ /// v = x; <update x>;
+ /// <update x>; v = x;
+ /// \endcode
+ /// This field is 1 for the first(postfix) form of the expression and 0
+ /// otherwise.
+ uint8_t IsPostfixUpdate : 1;
+ /// 1 if 'v' is updated only when the condition is false (compare capture
+ /// only).
+ uint8_t IsFailOnly : 1;
+ } Flags;
/// Build directive with the given start and end location.
///
@@ -2794,18 +3004,62 @@ class OMPAtomicDirective : public OMPExecutableDirective {
: OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
SourceLocation(), SourceLocation()) {}
+ enum DataPositionTy : size_t {
+ POS_X = 0,
+ POS_V,
+ POS_E,
+ POS_UpdateExpr,
+ POS_D,
+ POS_Cond,
+ POS_R,
+ };
+
/// Set 'x' part of the associated expression/statement.
- void setX(Expr *X) { Data->getChildren()[0] = X; }
+ void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
/// Set helper expression of the form
/// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
/// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- void setUpdateExpr(Expr *UE) { Data->getChildren()[1] = UE; }
+ void setUpdateExpr(Expr *UE) {
+ Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
+ }
/// Set 'v' part of the associated expression/statement.
- void setV(Expr *V) { Data->getChildren()[2] = V; }
+ void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
+ /// Set 'r' part of the associated expression/statement.
+ void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
/// Set 'expr' part of the associated expression/statement.
- void setExpr(Expr *E) { Data->getChildren()[3] = E; }
+ void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
+ /// Set 'd' part of the associated expression/statement.
+ void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
+ /// Set conditional expression in `atomic compare`.
+ void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
public:
+ struct Expressions {
+ /// 'x' part of the associated expression/statement.
+ Expr *X = nullptr;
+ /// 'v' part of the associated expression/statement.
+ Expr *V = nullptr;
+ // 'r' part of the associated expression/statement.
+ Expr *R = nullptr;
+ /// 'expr' part of the associated expression/statement.
+ Expr *E = nullptr;
+ /// UE Helper expression of the form:
+ /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
+ /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
+ Expr *UE = nullptr;
+ /// 'd' part of the associated expression/statement.
+ Expr *D = nullptr;
+ /// Conditional expression in `atomic compare` construct.
+ Expr *Cond = nullptr;
+ /// True if UE has the first form and false if the second.
+ bool IsXLHSInRHSPart;
+ /// True if original value of 'x' must be stored in 'v', not an updated one.
+ bool IsPostfixUpdate;
+ /// True if 'v' is updated only when the condition is false (compare capture
+ /// only).
+ bool IsFailOnly;
+ };
+
/// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
/// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
/// detailed description of 'x', 'v' and 'expr').
@@ -2815,20 +3069,12 @@ public:
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
- /// \param X 'x' part of the associated expression/statement.
- /// \param V 'v' part of the associated expression/statement.
- /// \param E 'expr' part of the associated expression/statement.
- /// \param UE Helper expression of the form
- /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
- /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
- /// second.
- /// \param IsPostfixUpdate true if original value of 'x' must be stored in
- /// 'v', not an updated one.
- static OMPAtomicDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
- Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
+ /// \param Exprs Associated expressions or statements.
+ static OMPAtomicDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Expressions Exprs);
/// Creates an empty directive with the place for \a NumClauses
/// clauses.
@@ -2840,33 +3086,67 @@ public:
unsigned NumClauses, EmptyShell);
/// Get 'x' part of the associated expression/statement.
- Expr *getX() { return cast_or_null<Expr>(Data->getChildren()[0]); }
+ Expr *getX() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
+ }
const Expr *getX() const {
- return cast_or_null<Expr>(Data->getChildren()[0]);
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
}
/// Get helper expression of the form
/// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
/// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- Expr *getUpdateExpr() { return cast_or_null<Expr>(Data->getChildren()[1]); }
+ Expr *getUpdateExpr() {
+ return cast_or_null<Expr>(
+ Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
+ }
const Expr *getUpdateExpr() const {
- return cast_or_null<Expr>(Data->getChildren()[1]);
+ return cast_or_null<Expr>(
+ Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
}
/// Return true if helper update expression has form
/// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
/// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
+ bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
/// Return true if 'v' expression must be updated to original value of
/// 'x', false if 'v' must be updated to the new value of 'x'.
- bool isPostfixUpdate() const { return IsPostfixUpdate; }
+ bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
+ /// Return true if 'v' is updated only when the condition is evaluated false
+ /// (compare capture only).
+ bool isFailOnly() const { return Flags.IsFailOnly; }
/// Get 'v' part of the associated expression/statement.
- Expr *getV() { return cast_or_null<Expr>(Data->getChildren()[2]); }
+ Expr *getV() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
+ }
const Expr *getV() const {
- return cast_or_null<Expr>(Data->getChildren()[2]);
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
+ }
+ /// Get 'r' part of the associated expression/statement.
+ Expr *getR() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
+ }
+ const Expr *getR() const {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
}
/// Get 'expr' part of the associated expression/statement.
- Expr *getExpr() { return cast_or_null<Expr>(Data->getChildren()[3]); }
+ Expr *getExpr() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
+ }
const Expr *getExpr() const {
- return cast_or_null<Expr>(Data->getChildren()[3]);
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
+ }
+ /// Get 'd' part of the associated expression/statement.
+ Expr *getD() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
+ }
+ Expr *getD() const {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
+ }
+ /// Get the 'cond' part of the source atomic expression.
+ Expr *getCondExpr() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
+ }
+ Expr *getCondExpr() const {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
}
static bool classof(const Stmt *T) {
@@ -3651,6 +3931,82 @@ public:
}
};
+/// This represents '#pragma omp masked taskloop' directive.
+///
+/// \code
+/// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp masked taskloop' has clauses
+/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
+/// and 'num_tasks' with expression 'num'.
+///
+class OMPMaskedTaskLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel = false;
+
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
+ llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
+ llvm::omp::OMPD_masked_taskloop, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if this directive has inner cancel directive.
+ ///
+ static OMPMaskedTaskLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp master taskloop simd' directive.
///
/// \code
@@ -3716,6 +4072,71 @@ public:
}
};
+/// This represents '#pragma omp masked taskloop simd' directive.
+///
+/// \code
+/// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp masked taskloop simd' has clauses
+/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
+/// and 'num_tasks' with expression 'num'.
+///
+class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
+ llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
+ llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPMaskedTaskLoopSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place for \p NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp parallel master taskloop' directive.
///
/// \code
@@ -3794,6 +4215,84 @@ public:
}
};
+/// This represents '#pragma omp parallel masked taskloop' directive.
+///
+/// \code
+/// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
+/// num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp parallel masked taskloop' has clauses
+/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
+/// and 'num_tasks' with expression 'num'.
+///
+class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel = false;
+
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
+ llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
+ EndLoc, CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
+ llvm::omp::OMPD_parallel_masked_taskloop,
+ SourceLocation(), SourceLocation(), CollapsedNum) {}
+
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if this directive has inner cancel directive.
+ ///
+ static OMPParallelMaskedTaskLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp parallel master taskloop simd' directive.
///
/// \code
@@ -3861,6 +4360,73 @@ public:
}
};
+/// This represents '#pragma omp parallel masked taskloop simd' directive.
+///
+/// \code
+/// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
+/// num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp parallel masked taskloop simd' has
+/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
+/// expression 'val' and 'num_tasks' with expression 'num'.
+///
+class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
+ llvm::omp::OMPD_parallel_masked_taskloop_simd,
+ StartLoc, EndLoc, CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
+ llvm::omp::OMPD_parallel_masked_taskloop_simd,
+ SourceLocation(), SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPParallelMaskedTaskLoopSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelMaskedTaskLoopSimdDirective *
+ CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp distribute' directive.
///
/// \code
@@ -3908,7 +4474,8 @@ public:
static OMPDistributeDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs,
+ OpenMPDirectiveKind ParamPrevMappedDirective);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -4992,7 +5559,7 @@ public:
};
/// This represents the '#pragma omp tile' loop transformation directive.
-class OMPTileDirective final : public OMPLoopBasedDirective {
+class OMPTileDirective final : public OMPLoopTransformationDirective {
friend class ASTStmtReader;
friend class OMPExecutableDirective;
@@ -5004,8 +5571,11 @@ class OMPTileDirective final : public OMPLoopBasedDirective {
explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumLoops)
- : OMPLoopBasedDirective(OMPTileDirectiveClass, llvm::omp::OMPD_tile,
- StartLoc, EndLoc, NumLoops) {}
+ : OMPLoopTransformationDirective(OMPTileDirectiveClass,
+ llvm::omp::OMPD_tile, StartLoc, EndLoc,
+ NumLoops) {
+ setNumGeneratedLoops(3 * NumLoops);
+ }
void setPreInits(Stmt *PreInits) {
Data->getChildren()[PreInitsOffset] = PreInits;
@@ -5042,8 +5612,6 @@ public:
static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
unsigned NumLoops);
- unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
-
/// Gets/sets the associated loops after tiling.
///
/// This is in de-sugared format stored as a CompoundStmt.
@@ -5073,7 +5641,7 @@ public:
/// #pragma omp unroll
/// for (int i = 0; i < 64; ++i)
/// \endcode
-class OMPUnrollDirective final : public OMPLoopBasedDirective {
+class OMPUnrollDirective final : public OMPLoopTransformationDirective {
friend class ASTStmtReader;
friend class OMPExecutableDirective;
@@ -5084,8 +5652,9 @@ class OMPUnrollDirective final : public OMPLoopBasedDirective {
};
explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPLoopBasedDirective(OMPUnrollDirectiveClass, llvm::omp::OMPD_unroll,
- StartLoc, EndLoc, 1) {}
+ : OMPLoopTransformationDirective(OMPUnrollDirectiveClass,
+ llvm::omp::OMPD_unroll, StartLoc, EndLoc,
+ 1) {}
/// Set the pre-init statements.
void setPreInits(Stmt *PreInits) {
@@ -5111,7 +5680,7 @@ public:
static OMPUnrollDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- Stmt *TransformedStmt, Stmt *PreInits);
+ unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits);
/// Build an empty '#pragma omp unroll' AST node for deserialization.
///
@@ -5360,6 +5929,412 @@ public:
}
};
+/// This represents '#pragma omp metadirective' directive.
+///
+/// \code
+/// #pragma omp metadirective when(user={condition(N>10)}: parallel for)
+/// \endcode
+/// In this example directive '#pragma omp metadirective' has clauses 'when'
+/// with a dynamic user condition to check if a variable 'N > 10'
+///
+class OMPMetaDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ Stmt *IfStmt;
+
+ OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(OMPMetaDirectiveClass,
+ llvm::omp::OMPD_metadirective, StartLoc,
+ EndLoc) {}
+ explicit OMPMetaDirective()
+ : OMPExecutableDirective(OMPMetaDirectiveClass,
+ llvm::omp::OMPD_metadirective, SourceLocation(),
+ SourceLocation()) {}
+
+ void setIfStmt(Stmt *S) { IfStmt = S; }
+
+public:
+ static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Stmt *IfStmt);
+ static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+ EmptyShell);
+ Stmt *getIfStmt() const { return IfStmt; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPMetaDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp loop' directive.
+///
+/// \code
+/// #pragma omp loop private(a,b) binding(parallel) order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp loop' has
+/// clauses 'private' with the variables 'a' and 'b', 'binding' with
+/// modifier 'parallel' and 'order(concurrent).
+///
+class OMPGenericLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
+ StartLoc, EndLoc, CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPGenericLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
+ SourceLocation(), SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPGenericLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with a place for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPGenericLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp teams loop' directive.
+///
+/// \code
+/// #pragma omp teams loop private(a,b) order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp teams loop' has
+/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
+///
+class OMPTeamsGenericLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
+ llvm::omp::OMPD_teams_loop, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
+ llvm::omp::OMPD_teams_loop, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTeamsGenericLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp target teams loop' directive.
+///
+/// \code
+/// #pragma omp target teams loop private(a,b) order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp target teams loop' has
+/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
+///
+class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
+ llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
+ llvm::omp::OMPD_target_teams_loop, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTargetTeamsGenericLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp parallel loop' directive.
+///
+/// \code
+/// #pragma omp parallel loop private(a,b) order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp parallel loop' has
+/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
+///
+class OMPParallelGenericLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPParallelGenericLoopDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
+ llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
+ llvm::omp::OMPD_parallel_loop, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPParallelGenericLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp target parallel loop' directive.
+///
+/// \code
+/// #pragma omp target parallel loop private(a,b) order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp target parallel loop' has
+/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
+///
+class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
+ llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
+ llvm::omp::OMPD_target_parallel_loop, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTargetParallelGenericLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTargetParallelGenericLoopDirective *
+ CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp error' directive.
+///
+/// \code
+/// #pragma omp error
+/// \endcode
+class OMPErrorDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
+ StartLoc, EndLoc) {}
+ /// Build an empty directive.
+ ///
+ explicit OMPErrorDirective()
+ : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
+ SourceLocation(), SourceLocation()) {}
+
+public:
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ ///
+ static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses);
+
+ /// Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPErrorDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPErrorDirectiveClass;
+ }
+};
} // end namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/AST/TemplateArgumentVisitor.h b/contrib/llvm-project/clang/include/clang/AST/TemplateArgumentVisitor.h
index 190aa97adf45..cf0d32201580 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TemplateArgumentVisitor.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TemplateArgumentVisitor.h
@@ -37,6 +37,7 @@ public:
DISPATCH(Declaration);
DISPATCH(NullPtr);
DISPATCH(Integral);
+ DISPATCH(StructuralValue);
DISPATCH(Template);
DISPATCH(TemplateExpansion);
DISPATCH(Expression);
@@ -59,6 +60,7 @@ public:
VISIT_METHOD(Declaration);
VISIT_METHOD(NullPtr);
VISIT_METHOD(Integral);
+ VISIT_METHOD(StructuralValue);
VISIT_METHOD(Template);
VISIT_METHOD(TemplateExpansion);
VISIT_METHOD(Expression);
diff --git a/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h b/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h
index fa27a12cfbb9..fea2c8ccfee6 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h
@@ -23,14 +23,13 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
+#include <optional>
namespace llvm {
@@ -51,8 +50,8 @@ template <> struct PointerLikeTypeTraits<clang::Expr *> {
namespace clang {
+class APValue;
class ASTContext;
-class DiagnosticBuilder;
class Expr;
struct PrintingPolicy;
class TypeSourceInfo;
@@ -82,6 +81,13 @@ public:
/// that was provided for an integral non-type template parameter.
Integral,
+ /// The template argument is a non-type template argument that can't be
+ /// represented by the special-case Declaration, NullPtr, or Integral
+ /// forms. These values are only ever produced by constant evaluation,
+ /// so cannot be dependent.
+ /// TODO: merge Declaration, NullPtr and Integral into this?
+ StructuralValue,
+
/// The template argument is a template name that was provided for a
/// template template parameter.
Template,
@@ -105,16 +111,23 @@ private:
/// The kind of template argument we're storing.
struct DA {
- unsigned Kind;
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
void *QT;
ValueDecl *D;
};
struct I {
- unsigned Kind;
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
// We store a decomposed APSInt with the data allocated by ASTContext if
// BitWidth > 64. The memory may be shared between multiple
// TemplateArgument instances.
unsigned BitWidth : 31;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsUnsigned : 1;
union {
/// Used to store the <= 64 bits integer value.
@@ -125,51 +138,77 @@ private:
};
void *Type;
};
+ struct V {
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
+ APValue *Value;
+ void *Type;
+ };
struct A {
- unsigned Kind;
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
unsigned NumArgs;
const TemplateArgument *Args;
};
struct TA {
- unsigned Kind;
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
unsigned NumExpansions;
void *Name;
};
struct TV {
- unsigned Kind;
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
uintptr_t V;
};
union {
struct DA DeclArg;
struct I Integer;
+ struct V Value;
struct A Args;
struct TA TemplateArg;
struct TV TypeOrValue;
};
+ void initFromType(QualType T, bool IsNullPtr, bool IsDefaulted);
+ void initFromDeclaration(ValueDecl *D, QualType QT, bool IsDefaulted);
+ void initFromIntegral(const ASTContext &Ctx, const llvm::APSInt &Value,
+ QualType Type, bool IsDefaulted);
+ void initFromStructural(const ASTContext &Ctx, QualType Type,
+ const APValue &V, bool IsDefaulted);
+
public:
/// Construct an empty, invalid template argument.
- constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
+ constexpr TemplateArgument() : TypeOrValue({Null, 0, /* IsDefaulted */ 0}) {}
/// Construct a template type argument.
- TemplateArgument(QualType T, bool isNullPtr = false) {
- TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
- TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+ TemplateArgument(QualType T, bool isNullPtr = false,
+ bool IsDefaulted = false) {
+ initFromType(T, isNullPtr, IsDefaulted);
}
- /// Construct a template argument that refers to a
- /// declaration, which is either an external declaration or a
- /// template declaration.
- TemplateArgument(ValueDecl *D, QualType QT) {
- assert(D && "Expected decl");
- DeclArg.Kind = Declaration;
- DeclArg.QT = QT.getAsOpaquePtr();
- DeclArg.D = D;
+ /// Construct a template argument that refers to a (non-dependent)
+ /// declaration.
+ TemplateArgument(ValueDecl *D, QualType QT, bool IsDefaulted = false) {
+ initFromDeclaration(D, QT, IsDefaulted);
}
/// Construct an integral constant template argument. The memory to
/// store the value is allocated with Ctx.
- TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
+ TemplateArgument(const ASTContext &Ctx, const llvm::APSInt &Value,
+ QualType Type, bool IsDefaulted = false);
+
+ /// Construct a template argument from an arbitrary constant value.
+ TemplateArgument(const ASTContext &Ctx, QualType Type, const APValue &Value,
+ bool IsDefaulted = false);
/// Construct an integral constant template argument with the same
/// value as Other but a different type.
@@ -186,8 +225,12 @@ public:
/// is taken.
///
/// \param Name The template name.
- TemplateArgument(TemplateName Name) {
+ ///
+ /// \param IsDefaulted If 'true', implies that this TemplateArgument
+ /// corresponds to a default template parameter
+ TemplateArgument(TemplateName Name, bool IsDefaulted = false) {
TemplateArg.Kind = Template;
+ TemplateArg.IsDefaulted = IsDefaulted;
TemplateArg.Name = Name.getAsVoidPointer();
TemplateArg.NumExpansions = 0;
}
@@ -203,8 +246,13 @@ public:
///
/// \param NumExpansions The number of expansions that will be generated by
/// instantiating
- TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
+ ///
+ /// \param IsDefaulted If 'true', implies that this TemplateArgument
+ /// corresponds to a default template parameter
+ TemplateArgument(TemplateName Name, std::optional<unsigned> NumExpansions,
+ bool IsDefaulted = false) {
TemplateArg.Kind = TemplateExpansion;
+ TemplateArg.IsDefaulted = IsDefaulted;
TemplateArg.Name = Name.getAsVoidPointer();
if (NumExpansions)
TemplateArg.NumExpansions = *NumExpansions + 1;
@@ -217,8 +265,9 @@ public:
/// This form of template argument only occurs in template argument
/// lists used for dependent types and for expression; it will not
/// occur in a non-dependent, canonical template argument list.
- TemplateArgument(Expr *E) {
+ TemplateArgument(Expr *E, bool IsDefaulted = false) {
TypeOrValue.Kind = Expression;
+ TypeOrValue.IsDefaulted = IsDefaulted;
TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
}
@@ -228,13 +277,14 @@ public:
/// outlives the TemplateArgument itself.
explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
this->Args.Kind = Pack;
+ this->Args.IsDefaulted = false;
this->Args.Args = Args.data();
this->Args.NumArgs = Args.size();
}
- TemplateArgument(TemplateName, bool) = delete;
-
- static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
+ static TemplateArgument getEmptyPack() {
+ return TemplateArgument(std::nullopt);
+ }
/// Create a new template argument pack by copying the given set of
/// template arguments.
@@ -268,7 +318,7 @@ public:
/// Retrieve the type for a type template argument.
QualType getAsType() const {
assert(getKind() == Type && "Unexpected kind");
- return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
+ return QualType::getFromOpaquePtr(reinterpret_cast<void *>(TypeOrValue.V));
}
/// Retrieve the declaration for a declaration non-type
@@ -286,7 +336,7 @@ public:
/// Retrieve the type for null non-type template argument.
QualType getNullPtrType() const {
assert(getKind() == NullPtr && "Unexpected kind");
- return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
+ return QualType::getFromOpaquePtr(reinterpret_cast<void *>(TypeOrValue.V));
}
/// Retrieve the template name for a template name argument.
@@ -306,7 +356,7 @@ public:
/// Retrieve the number of expansions that a template template argument
/// expansion will produce, if known.
- Optional<unsigned> getNumTemplateExpansions() const;
+ std::optional<unsigned> getNumTemplateExpansions() const;
/// Retrieve the template argument as an integral value.
// FIXME: Provide a way to read the integral data without copying the value.
@@ -319,7 +369,7 @@ public:
return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
- return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
+ return APSInt(APInt(Integer.BitWidth, ArrayRef(Integer.pVal, NumWords)),
Integer.IsUnsigned);
}
@@ -334,6 +384,22 @@ public:
Integer.Type = T.getAsOpaquePtr();
}
+ /// Set to 'true' if this TemplateArgument corresponds to a
+ /// default template parameter.
+ void setIsDefaulted(bool v) { TypeOrValue.IsDefaulted = v; }
+
+ /// If returns 'true', this TemplateArgument corresponds to a
+ /// default template parameter.
+ bool getIsDefaulted() const { return (bool)TypeOrValue.IsDefaulted; }
+
+ /// Get the value of a StructuralValue.
+ const APValue &getAsStructuralValue() const { return *Value.Value; }
+
+ /// Get the type of a StructuralValue.
+ QualType getStructuralValueType() const {
+ return QualType::getFromOpaquePtr(Value.Type);
+ }
+
/// If this is a non-type template argument, get its type. Otherwise,
/// returns a null QualType.
QualType getNonTypeTemplateArgumentType() const;
@@ -364,7 +430,7 @@ public:
/// Iterator range referencing all of the elements of a template
/// argument pack.
ArrayRef<TemplateArgument> pack_elements() const {
- return llvm::makeArrayRef(pack_begin(), pack_end());
+ return llvm::ArrayRef(pack_begin(), pack_end());
}
/// The number of template arguments in the given template argument
@@ -377,7 +443,7 @@ public:
/// Return the array of arguments in this template argument pack.
ArrayRef<TemplateArgument> getPackAsArray() const {
assert(getKind() == Pack);
- return llvm::makeArrayRef(Args.Args, Args.NumArgs);
+ return llvm::ArrayRef(Args.Args, Args.NumArgs);
}
/// Determines whether two template arguments are superficially the
@@ -479,6 +545,7 @@ public:
assert(Argument.getKind() == TemplateArgument::NullPtr ||
Argument.getKind() == TemplateArgument::Integral ||
Argument.getKind() == TemplateArgument::Declaration ||
+ Argument.getKind() == TemplateArgument::StructuralValue ||
Argument.getKind() == TemplateArgument::Expression);
}
@@ -504,13 +571,9 @@ public:
/// - Fetches the full source range of the argument.
SourceRange getSourceRange() const LLVM_READONLY;
- const TemplateArgument &getArgument() const {
- return Argument;
- }
+ const TemplateArgument &getArgument() const { return Argument; }
- TemplateArgumentLocInfo getLocInfo() const {
- return LocInfo;
- }
+ TemplateArgumentLocInfo getLocInfo() const { return LocInfo; }
TypeSourceInfo *getTypeSourceInfo() const {
if (Argument.getKind() != TemplateArgument::Type)
@@ -538,6 +601,11 @@ public:
return LocInfo.getAsExpr();
}
+ Expr *getSourceStructuralValueExpression() const {
+ assert(Argument.getKind() == TemplateArgument::StructuralValue);
+ return LocInfo.getAsExpr();
+ }
+
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
if (Argument.getKind() != TemplateArgument::Template &&
Argument.getKind() != TemplateArgument::TemplateExpansion)
@@ -569,8 +637,7 @@ class TemplateArgumentListInfo {
public:
TemplateArgumentListInfo() = default;
- TemplateArgumentListInfo(SourceLocation LAngleLoc,
- SourceLocation RAngleLoc)
+ TemplateArgumentListInfo(SourceLocation LAngleLoc, SourceLocation RAngleLoc)
: LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
// This can leak if used in an AST node, use ASTTemplateArgumentListInfo
@@ -589,21 +656,15 @@ public:
return Arguments.data();
}
- llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
- return Arguments;
- }
+ llvm::ArrayRef<TemplateArgumentLoc> arguments() const { return Arguments; }
const TemplateArgumentLoc &operator[](unsigned I) const {
return Arguments[I];
}
- TemplateArgumentLoc &operator[](unsigned I) {
- return Arguments[I];
- }
+ TemplateArgumentLoc &operator[](unsigned I) { return Arguments[I]; }
- void addArgument(const TemplateArgumentLoc &Loc) {
- Arguments.push_back(Loc);
- }
+ void addArgument(const TemplateArgumentLoc &Loc) { Arguments.push_back(Loc); }
};
/// Represents an explicit template argument list in C++, e.g.,
@@ -619,6 +680,9 @@ private:
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
+ // FIXME: Is it ever necessary to copy to another context?
+ ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *List);
+
public:
/// The source location of the left angle bracket ('<').
SourceLocation LAngleLoc;
@@ -639,7 +703,7 @@ public:
unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
- return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
+ return llvm::ArrayRef(getTemplateArgs(), getNumTemplateArgs());
}
const TemplateArgumentLoc &operator[](unsigned I) const {
@@ -648,6 +712,10 @@ public:
static const ASTTemplateArgumentListInfo *
Create(const ASTContext &C, const TemplateArgumentListInfo &List);
+
+ // FIXME: Is it ever necessary to copy to another context?
+ static const ASTTemplateArgumentListInfo *
+ Create(const ASTContext &C, const ASTTemplateArgumentListInfo *List);
};
/// Represents an explicit template argument list in C++, e.g.,
@@ -692,33 +760,6 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo {
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const TemplateArgument &Arg);
-inline TemplateSpecializationType::iterator
- TemplateSpecializationType::end() const {
- return getArgs() + getNumArgs();
-}
-
-inline DependentTemplateSpecializationType::iterator
- DependentTemplateSpecializationType::end() const {
- return getArgs() + getNumArgs();
-}
-
-inline const TemplateArgument &
- TemplateSpecializationType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
-inline const TemplateArgument &
- DependentTemplateSpecializationType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
-inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
} // namespace clang
#endif // LLVM_CLANG_AST_TEMPLATEBASE_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/TemplateName.h b/contrib/llvm-project/clang/include/clang/AST/TemplateName.h
index 010b813dc525..b7732e54ba10 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TemplateName.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TemplateName.h
@@ -21,19 +21,19 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
+#include <optional>
namespace clang {
class ASTContext;
+class Decl;
class DependentTemplateName;
-class DiagnosticBuilder;
class IdentifierInfo;
class NamedDecl;
class NestedNameSpecifier;
enum OverloadedOperatorKind : int;
class OverloadedTemplateStorage;
class AssumedTemplateStorage;
-class PartialDiagnostic;
struct PrintingPolicy;
class QualifiedTemplateName;
class SubstTemplateTemplateParmPackStorage;
@@ -41,6 +41,7 @@ class SubstTemplateTemplateParmStorage;
class TemplateArgument;
class TemplateDecl;
class TemplateTemplateParmDecl;
+class UsingShadowDecl;
/// Implementation class used to describe either a set of overloaded
/// template names or an already-substituted template template parameter pack.
@@ -54,12 +55,15 @@ protected:
};
struct BitsTag {
- /// A Kind.
+ LLVM_PREFERRED_TYPE(Kind)
unsigned Kind : 2;
- /// The number of stored templates or template arguments,
- /// depending on which subclass we have.
- unsigned Size : 30;
+ // The template parameter index.
+ unsigned Index : 15;
+
+ /// The pack index, or the number of stored templates
+ /// or template arguments, depending on which subclass we have.
+ unsigned Data : 15;
};
union {
@@ -67,14 +71,13 @@ protected:
void *PointerAlignment;
};
- UncommonTemplateNameStorage(Kind kind, unsigned size) {
- Bits.Kind = kind;
- Bits.Size = size;
+ UncommonTemplateNameStorage(Kind Kind, unsigned Index, unsigned Data) {
+ Bits.Kind = Kind;
+ Bits.Index = Index;
+ Bits.Data = Data;
}
public:
- unsigned size() const { return Bits.Size; }
-
OverloadedTemplateStorage *getAsOverloadedStorage() {
return Bits.Kind == Overloaded
? reinterpret_cast<OverloadedTemplateStorage *>(this)
@@ -106,7 +109,7 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
friend class ASTContext;
OverloadedTemplateStorage(unsigned size)
- : UncommonTemplateNameStorage(Overloaded, size) {}
+ : UncommonTemplateNameStorage(Overloaded, 0, size) {}
NamedDecl **getStorage() {
return reinterpret_cast<NamedDecl **>(this + 1);
@@ -116,13 +119,15 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
}
public:
+ unsigned size() const { return Bits.Data; }
+
using iterator = NamedDecl *const *;
iterator begin() const { return getStorage(); }
- iterator end() const { return getStorage() + size(); }
+ iterator end() const { return getStorage() + Bits.Data; }
llvm::ArrayRef<NamedDecl*> decls() const {
- return llvm::makeArrayRef(begin(), end());
+ return llvm::ArrayRef(begin(), end());
}
};
@@ -132,23 +137,29 @@ public:
/// This kind of template names occurs when the parameter pack has been
/// provided with a template template argument pack in a context where its
/// enclosing pack expansion could not be fully expanded.
-class SubstTemplateTemplateParmPackStorage
- : public UncommonTemplateNameStorage, public llvm::FoldingSetNode
-{
- TemplateTemplateParmDecl *Parameter;
+class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage,
+ public llvm::FoldingSetNode {
const TemplateArgument *Arguments;
+ llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
public:
- SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
- unsigned Size,
- const TemplateArgument *Arguments)
- : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
- Parameter(Parameter), Arguments(Arguments) {}
+ SubstTemplateTemplateParmPackStorage(ArrayRef<TemplateArgument> ArgPack,
+ Decl *AssociatedDecl, unsigned Index,
+ bool Final);
+
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will own a set of template parameters.
+ Decl *getAssociatedDecl() const;
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getParameterPack()->getIndex()`.
+ unsigned getIndex() const { return Bits.Index; }
+
+ // When true the substitution will be 'Final' (subst node won't be placed).
+ bool getFinal() const;
/// Retrieve the template template parameter pack being substituted.
- TemplateTemplateParmDecl *getParameterPack() const {
- return Parameter;
- }
+ TemplateTemplateParmDecl *getParameterPack() const;
/// Retrieve the template template argument pack with which this
/// parameter was substituted.
@@ -156,10 +167,9 @@ public:
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
- static void Profile(llvm::FoldingSetNodeID &ID,
- ASTContext &Context,
- TemplateTemplateParmDecl *Parameter,
- const TemplateArgument &ArgPack);
+ static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+ const TemplateArgument &ArgPack, Decl *AssociatedDecl,
+ unsigned Index, bool Final);
};
/// Represents a C++ template name within the type system.
@@ -190,8 +200,12 @@ public:
/// specifier in the typedef. "apply" is a nested template, and can
/// only be understood in the context of
class TemplateName {
+ // NameDecl is either a TemplateDecl or a UsingShadowDecl depending on the
+ // NameKind.
+ // !! There is no free low bits in 32-bit builds to discriminate more than 4
+ // pointer types in PointerUnion.
using StorageType =
- llvm::PointerUnion<TemplateDecl *, UncommonTemplateNameStorage *,
+ llvm::PointerUnion<Decl *, UncommonTemplateNameStorage *,
QualifiedTemplateName *, DependentTemplateName *>;
StorageType Storage;
@@ -226,7 +240,11 @@ public:
/// A template template parameter pack that has been substituted for
/// a template template argument pack, but has not yet been expanded into
/// individual arguments.
- SubstTemplateTemplateParmPack
+ SubstTemplateTemplateParmPack,
+
+ /// A template name that refers to a template declaration found through a
+ /// specific using shadow declaration.
+ UsingTemplate,
};
TemplateName() = default;
@@ -237,6 +255,7 @@ public:
explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage);
explicit TemplateName(QualifiedTemplateName *Qual);
explicit TemplateName(DependentTemplateName *Dep);
+ explicit TemplateName(UsingShadowDecl *Using);
/// Determine whether this template name is NULL.
bool isNull() const;
@@ -289,6 +308,10 @@ public:
/// structure, if any.
DependentTemplateName *getAsDependentTemplateName() const;
+ /// Retrieve the using shadow declaration through which the underlying
+ /// template declaration is introduced, if any.
+ UsingShadowDecl *getAsUsingShadowDecl() const;
+
TemplateName getUnderlying() const;
/// Get the template name to substitute when this template name is used as a
@@ -309,16 +332,17 @@ public:
/// unexpanded parameter pack (for C++0x variadic templates).
bool containsUnexpandedParameterPack() const;
+ enum class Qualified { None, AsWritten, Fully };
/// Print the template name.
///
/// \param OS the output stream to which the template name will be
/// printed.
///
- /// \param SuppressNNS if true, don't print the
- /// nested-name-specifier that precedes the template name (if it has
- /// one).
+ /// \param Qual print the (Qualified::None) simple name,
+ /// (Qualified::AsWritten) any written (possibly partial) qualifier, or
+ /// (Qualified::Fully) the fully qualified name.
void print(raw_ostream &OS, const PrintingPolicy &Policy,
- bool SuppressNNS = false) const;
+ Qualified Qual = Qualified::AsWritten) const;
/// Debugging aid that dumps the template name.
void dump(raw_ostream &OS) const;
@@ -327,9 +351,7 @@ public:
/// error.
void dump() const;
- void Profile(llvm::FoldingSetNodeID &ID) {
- ID.AddPointer(Storage.getOpaqueValue());
- }
+ void Profile(llvm::FoldingSetNodeID &ID);
/// Retrieve the template name as a void pointer.
void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
@@ -351,23 +373,41 @@ class SubstTemplateTemplateParmStorage
: public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
friend class ASTContext;
- TemplateTemplateParmDecl *Parameter;
TemplateName Replacement;
-
- SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
- TemplateName replacement)
- : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
- Parameter(parameter), Replacement(replacement) {}
+ Decl *AssociatedDecl;
+
+ SubstTemplateTemplateParmStorage(TemplateName Replacement,
+ Decl *AssociatedDecl, unsigned Index,
+ std::optional<unsigned> PackIndex)
+ : UncommonTemplateNameStorage(SubstTemplateTemplateParm, Index,
+ PackIndex ? *PackIndex + 1 : 0),
+ Replacement(Replacement), AssociatedDecl(AssociatedDecl) {
+ assert(AssociatedDecl != nullptr);
+ }
public:
- TemplateTemplateParmDecl *getParameter() const { return Parameter; }
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will own a set of template parameters.
+ Decl *getAssociatedDecl() const { return AssociatedDecl; }
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getParameter()->getIndex()`.
+ unsigned getIndex() const { return Bits.Index; }
+
+ std::optional<unsigned> getPackIndex() const {
+ if (Bits.Data == 0)
+ return std::nullopt;
+ return Bits.Data - 1;
+ }
+
+ TemplateTemplateParmDecl *getParameter() const;
TemplateName getReplacement() const { return Replacement; }
void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- TemplateTemplateParmDecl *parameter,
- TemplateName replacement);
+ static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Replacement,
+ Decl *AssociatedDecl, unsigned Index,
+ std::optional<unsigned> PackIndex);
};
inline TemplateName TemplateName::getUnderlying() const {
@@ -400,13 +440,19 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
/// this name with DependentTemplateName).
llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
- /// The template declaration or set of overloaded function templates
- /// that this qualified name refers to.
- TemplateDecl *Template;
+ /// The underlying template name, it is either
+ /// 1) a Template -- a template declaration that this qualified name refers
+ /// to.
+ /// 2) or a UsingTemplate -- a template declaration introduced by a
+ /// using-shadow declaration.
+ TemplateName UnderlyingTemplate;
QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
- TemplateDecl *Template)
- : Qualifier(NNS, TemplateKeyword? 1 : 0), Template(Template) {}
+ TemplateName Template)
+ : Qualifier(NNS, TemplateKeyword ? 1 : 0), UnderlyingTemplate(Template) {
+ assert(UnderlyingTemplate.getKind() == TemplateName::Template ||
+ UnderlyingTemplate.getKind() == TemplateName::UsingTemplate);
+ }
public:
/// Return the nested name specifier that qualifies this name.
@@ -416,23 +462,18 @@ public:
/// keyword.
bool hasTemplateKeyword() const { return Qualifier.getInt(); }
- /// The template declaration that this qualified name refers
- /// to.
- TemplateDecl *getDecl() const { return Template; }
-
- /// The template declaration to which this qualified name
- /// refers.
- TemplateDecl *getTemplateDecl() const { return Template; }
+ /// Return the underlying template name.
+ TemplateName getUnderlyingTemplate() const { return UnderlyingTemplate; }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
+ Profile(ID, getQualifier(), hasTemplateKeyword(), UnderlyingTemplate);
}
static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- bool TemplateKeyword, TemplateDecl *Template) {
+ bool TemplateKeyword, TemplateName TN) {
ID.AddPointer(NNS);
ID.AddBoolean(TemplateKeyword);
- ID.AddPointer(Template);
+ ID.AddPointer(TN.getAsVoidPointer());
}
};
diff --git a/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h b/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h
index 0eb0031de11f..732749ad305e 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h
@@ -189,6 +189,8 @@ public:
void Visit(const GenericSelectionExpr::ConstAssociation &A);
+ void Visit(const ConceptReference *);
+
void Visit(const concepts::Requirement *R);
void Visit(const APValue &Value, QualType Ty);
@@ -202,6 +204,9 @@ public:
void dumpName(const NamedDecl *ND);
void dumpAccessSpecifier(AccessSpecifier AS);
void dumpCleanupObject(const ExprWithCleanups::CleanupObject &C);
+ void dumpTemplateSpecializationKind(TemplateSpecializationKind TSK);
+ void dumpNestedNameSpecifier(const NestedNameSpecifier *NNS);
+ void dumpConceptReference(const ConceptReference *R);
void dumpDeclRef(const Decl *D, StringRef Label = {});
@@ -246,12 +251,17 @@ public:
void VisitLabelStmt(const LabelStmt *Node);
void VisitGotoStmt(const GotoStmt *Node);
void VisitCaseStmt(const CaseStmt *Node);
+ void VisitReturnStmt(const ReturnStmt *Node);
+ void VisitCoawaitExpr(const CoawaitExpr *Node);
+ void VisitCoreturnStmt(const CoreturnStmt *Node);
+ void VisitCompoundStmt(const CompoundStmt *Node);
void VisitConstantExpr(const ConstantExpr *Node);
void VisitCallExpr(const CallExpr *Node);
void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node);
void VisitCastExpr(const CastExpr *Node);
void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
void VisitDeclRefExpr(const DeclRefExpr *Node);
+ void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *Node);
void VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *Node);
void VisitPredefinedExpr(const PredefinedExpr *Node);
void VisitCharacterLiteral(const CharacterLiteral *Node);
@@ -311,11 +321,17 @@ public:
void VisitFunctionType(const FunctionType *T);
void VisitFunctionProtoType(const FunctionProtoType *T);
void VisitUnresolvedUsingType(const UnresolvedUsingType *T);
+ void VisitUsingType(const UsingType *T);
void VisitTypedefType(const TypedefType *T);
void VisitUnaryTransformType(const UnaryTransformType *T);
void VisitTagType(const TagType *T);
void VisitTemplateTypeParmType(const TemplateTypeParmType *T);
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T);
+ void
+ VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T);
void VisitAutoType(const AutoType *T);
+ void VisitDeducedTemplateSpecializationType(
+ const DeducedTemplateSpecializationType *T);
void VisitTemplateSpecializationType(const TemplateSpecializationType *T);
void VisitInjectedClassNameType(const InjectedClassNameType *T);
void VisitObjCInterfaceType(const ObjCInterfaceType *T);
@@ -376,6 +392,7 @@ public:
void VisitConceptDecl(const ConceptDecl *D);
void
VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D);
+ void VisitHLSLBufferDecl(const HLSLBufferDecl *D);
};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/Type.h b/contrib/llvm-project/clang/include/clang/AST/Type.h
index 9f46d5337897..6384cf9420b8 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Type.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Type.h
@@ -34,10 +34,9 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
@@ -51,12 +50,14 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
+#include <optional>
#include <string>
#include <type_traits>
#include <utility>
namespace clang {
+class BTFTypeTagAttr;
class ExtQuals;
class QualType;
class ConceptDecl;
@@ -129,6 +130,7 @@ class TemplateArgumentLoc;
class TemplateTypeParmDecl;
class TypedefNameDecl;
class UnresolvedUsingTypenameDecl;
+class UsingShadowDecl;
using CanQualType = CanQual<Type>;
@@ -263,16 +265,31 @@ public:
bool hasOnlyConst() const { return Mask == Const; }
void removeConst() { Mask &= ~Const; }
void addConst() { Mask |= Const; }
+ Qualifiers withConst() const {
+ Qualifiers Qs = *this;
+ Qs.addConst();
+ return Qs;
+ }
bool hasVolatile() const { return Mask & Volatile; }
bool hasOnlyVolatile() const { return Mask == Volatile; }
void removeVolatile() { Mask &= ~Volatile; }
void addVolatile() { Mask |= Volatile; }
+ Qualifiers withVolatile() const {
+ Qualifiers Qs = *this;
+ Qs.addVolatile();
+ return Qs;
+ }
bool hasRestrict() const { return Mask & Restrict; }
bool hasOnlyRestrict() const { return Mask == Restrict; }
void removeRestrict() { Mask &= ~Restrict; }
void addRestrict() { Mask |= Restrict; }
+ Qualifiers withRestrict() const {
+ Qualifiers Qs = *this;
+ Qs.addRestrict();
+ return Qs;
+ }
bool hasCVRQualifiers() const { return getCVRQualifiers(); }
unsigned getCVRQualifiers() const { return Mask & CVRMask; }
@@ -495,7 +512,12 @@ public:
(A == LangAS::Default &&
(B == LangAS::sycl_private || B == LangAS::sycl_local ||
B == LangAS::sycl_global || B == LangAS::sycl_global_device ||
- B == LangAS::sycl_global_host));
+ B == LangAS::sycl_global_host)) ||
+ // In HIP device compilation, any cuda address space is allowed
+ // to implicitly cast into the default address space.
+ (A == LangAS::Default &&
+ (B == LangAS::cuda_constant || B == LangAS::cuda_device ||
+ B == LangAS::cuda_shared));
}
/// Returns true if the address space in these qualifiers is equal to or
@@ -602,6 +624,47 @@ private:
static const uint32_t AddressSpaceShift = 9;
};
+class QualifiersAndAtomic {
+ Qualifiers Quals;
+ bool HasAtomic;
+
+public:
+ QualifiersAndAtomic() : HasAtomic(false) {}
+ QualifiersAndAtomic(Qualifiers Quals, bool HasAtomic)
+ : Quals(Quals), HasAtomic(HasAtomic) {}
+
+ operator Qualifiers() const { return Quals; }
+
+ bool hasVolatile() const { return Quals.hasVolatile(); }
+ bool hasConst() const { return Quals.hasConst(); }
+ bool hasRestrict() const { return Quals.hasRestrict(); }
+ bool hasAtomic() const { return HasAtomic; }
+
+ void addVolatile() { Quals.addVolatile(); }
+ void addConst() { Quals.addConst(); }
+ void addRestrict() { Quals.addRestrict(); }
+ void addAtomic() { HasAtomic = true; }
+
+ void removeVolatile() { Quals.removeVolatile(); }
+ void removeConst() { Quals.removeConst(); }
+ void removeRestrict() { Quals.removeRestrict(); }
+ void removeAtomic() { HasAtomic = false; }
+
+ QualifiersAndAtomic withVolatile() {
+ return {Quals.withVolatile(), HasAtomic};
+ }
+ QualifiersAndAtomic withConst() { return {Quals.withConst(), HasAtomic}; }
+ QualifiersAndAtomic withRestrict() {
+ return {Quals.withRestrict(), HasAtomic};
+ }
+ QualifiersAndAtomic withAtomic() { return {Quals, true}; }
+
+ QualifiersAndAtomic &operator+=(Qualifiers RHS) {
+ Quals += RHS;
+ return *this;
+ }
+};
+
/// A std::pair-like structure for storing a qualified type split
/// into its local qualifiers and its locally-unqualified type.
struct SplitQualType {
@@ -651,6 +714,12 @@ enum class ObjCSubstitutionContext {
Superclass,
};
+/// The kind of 'typeof' expression we're after.
+enum class TypeOfKind : uint8_t {
+ Qualified,
+ Unqualified,
+};
+
/// A (possibly-)qualified type.
///
/// For efficiency, we don't store CV-qualified types as nodes on their
@@ -695,6 +764,8 @@ public:
unsigned getLocalFastQualifiers() const { return Value.getInt(); }
void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
+ bool UseExcessPrecision(const ASTContext &Ctx);
+
/// Retrieves a pointer to the underlying (unqualified) type.
///
/// This function requires that the type not be NULL. If the type might be
@@ -734,6 +805,9 @@ public:
return Value.getPointer().isNull();
}
+ // Determines if a type can form `T&`.
+ bool isReferenceable() const;
+
/// Determine whether this particular QualType instance has the
/// "const" qualifier set, without looking through typedefs that may have
/// added "const" at a different level.
@@ -744,6 +818,26 @@ public:
/// Determine whether this type is const-qualified.
bool isConstQualified() const;
+ enum class NonConstantStorageReason {
+ MutableField,
+ NonConstNonReferenceType,
+ NonTrivialCtor,
+ NonTrivialDtor,
+ };
+ /// Determine whether instances of this type can be placed in immutable
+ /// storage.
+ /// If ExcludeCtor is true, the duration when the object's constructor runs
+ /// will not be considered. The caller will need to verify that the object is
+ /// not written to during its construction. ExcludeDtor works similarly.
+ std::optional<NonConstantStorageReason>
+ isNonConstantStorage(const ASTContext &Ctx, bool ExcludeCtor,
+ bool ExcludeDtor);
+
+ bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor,
+ bool ExcludeDtor) {
+ return !isNonConstantStorage(Ctx, ExcludeCtor, ExcludeDtor);
+ }
+
/// Determine whether this particular QualType instance has the
/// "restrict" qualifier set, without looking through typedefs that may have
/// added "restrict" at a different level.
@@ -823,6 +917,14 @@ public:
/// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
bool isTriviallyCopyableType(const ASTContext &Context) const;
+ /// Return true if this is a trivially copyable type
+ bool isTriviallyCopyConstructibleType(const ASTContext &Context) const;
+
+ /// Return true if this is a trivially relocatable type.
+ bool isTriviallyRelocatableType(const ASTContext &Context) const;
+
+ /// Return true if this is a trivially equality comparable type.
+ bool isTriviallyEqualityComparableType(const ASTContext &Context) const;
/// Returns true if it is a class and it might be dynamic.
bool mayBeDynamicClass() const;
@@ -830,6 +932,15 @@ public:
/// Returns true if it is not a class or if the class might not be dynamic.
bool mayBeNotDynamicClass() const;
+ /// Returns true if it is a WebAssembly Reference Type.
+ bool isWebAssemblyReferenceType() const;
+
+ /// Returns true if it is a WebAssembly Externref Type.
+ bool isWebAssemblyExternrefType() const;
+
+ /// Returns true if it is a WebAssembly Funcref Type.
+ bool isWebAssemblyFuncrefType() const;
+
// Don't promise in the API that anything besides 'const' can be
// easily added.
@@ -870,7 +981,6 @@ public:
void removeLocalConst();
void removeLocalVolatile();
void removeLocalRestrict();
- void removeLocalCVRQualifiers(unsigned Mask);
void removeLocalFastQualifiers() { Value.setInt(0); }
void removeLocalFastQualifiers(unsigned Mask) {
@@ -924,6 +1034,10 @@ public:
/// The resulting type might still be qualified if it's sugar for an array
/// type. To strip qualifiers even from within a sugared array type, use
/// ASTContext::getUnqualifiedArrayType.
+ ///
+ /// Note: In C, the _Atomic qualifier is special (see C23 6.2.5p32 for
+ /// details), and it is not stripped by this function. Use
+ /// getAtomicUnqualifiedType() to strip qualifiers including _Atomic.
inline QualType getUnqualifiedType() const;
/// Retrieve the unqualified variant of the given type, removing as little
@@ -1305,6 +1419,8 @@ private:
static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD);
};
+raw_ostream &operator<<(raw_ostream &OS, QualType QT);
+
} // namespace clang
namespace llvm {
@@ -1370,7 +1486,8 @@ class ExtQualsTypeCommonBase {
/// in three low bits on the QualType pointer; a fourth bit records whether
/// the pointer is an ExtQuals node. The extended qualifiers (address spaces,
/// Objective-C GC attributes) are much more rare.
-class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
+class alignas(TypeAlignment) ExtQuals : public ExtQualsTypeCommonBase,
+ public llvm::FoldingSetNode {
// NOTE: changing the fast qualifiers should be straightforward as
// long as you don't make 'const' non-fast.
// 1. Qualifiers:
@@ -1456,6 +1573,10 @@ enum class AutoTypeKeyword {
GNUAutoType
};
+enum class ArraySizeModifier;
+enum class ElaboratedTypeKeyword;
+enum class VectorKind;
+
/// The base class of the type hierarchy.
///
/// A central concept with types is that each type always has a canonical
@@ -1482,7 +1603,7 @@ enum class AutoTypeKeyword {
///
/// Types, once created, are immutable.
///
-class alignas(8) Type : public ExtQualsTypeCommonBase {
+class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
public:
enum TypeClass {
#define TYPE(Class, Base) Class,
@@ -1498,22 +1619,28 @@ private:
template <class T> friend class TypePropertyCache;
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
+ LLVM_PREFERRED_TYPE(TypeClass)
unsigned TC : 8;
/// Store information on the type dependency.
+ LLVM_PREFERRED_TYPE(TypeDependence)
unsigned Dependence : llvm::BitWidth<TypeDependence>;
/// True if the cache (i.e. the bitfields here starting with
/// 'Cache') is valid.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned CacheValid : 1;
/// Linkage of this type.
+ LLVM_PREFERRED_TYPE(Linkage)
mutable unsigned CachedLinkage : 3;
/// Whether this type involves and local or unnamed types.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned CachedLocalOrUnnamed : 1;
/// Whether this type comes from an AST file.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned FromAST : 1;
bool isCacheValid() const {
@@ -1539,34 +1666,41 @@ protected:
class ArrayTypeBitfields {
friend class ArrayType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// CVR qualifiers from declarations like
/// 'int X[static restrict 4]'. For function parameters only.
+ LLVM_PREFERRED_TYPE(Qualifiers)
unsigned IndexTypeQuals : 3;
/// Storage class qualifiers from declarations like
/// 'int X[static restrict 4]'. For function parameters only.
- /// Actually an ArrayType::ArraySizeModifier.
+ LLVM_PREFERRED_TYPE(ArraySizeModifier)
unsigned SizeModifier : 3;
};
+ enum { NumArrayTypeBits = NumTypeBits + 6 };
class ConstantArrayTypeBitfields {
friend class ConstantArrayType;
- unsigned : NumTypeBits + 3 + 3;
+ LLVM_PREFERRED_TYPE(ArrayTypeBitfields)
+ unsigned : NumArrayTypeBits;
/// Whether we have a stored size expression.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasStoredSizeExpr : 1;
};
class BuiltinTypeBitfields {
friend class BuiltinType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// The kind (BuiltinType::Kind) of builtin type this is.
- unsigned Kind : 8;
+ static constexpr unsigned NumOfBuiltinTypeBits = 9;
+ unsigned Kind : NumOfBuiltinTypeBits;
};
/// FunctionTypeBitfields store various bits belonging to FunctionProtoType.
@@ -1576,15 +1710,18 @@ protected:
friend class FunctionProtoType;
friend class FunctionType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// Extra information which affects how the function is called, like
/// regparm and the calling convention.
+ LLVM_PREFERRED_TYPE(CallingConv)
unsigned ExtInfo : 13;
/// The ref-qualifier associated with a \c FunctionProtoType.
///
/// This is a value of type \c RefQualifierKind.
+ LLVM_PREFERRED_TYPE(RefQualifierKind)
unsigned RefQualifier : 2;
/// Used only by FunctionProtoType, put here to pack with the
@@ -1593,8 +1730,10 @@ protected:
///
/// C++ 8.3.5p4: The return type, the parameter type list and the
/// cv-qualifier-seq, [...], are part of the function type.
+ LLVM_PREFERRED_TYPE(Qualifiers)
unsigned FastTypeQuals : Qualifiers::FastWidth;
/// Whether this function has extended Qualifiers.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasExtQuals : 1;
/// The number of parameters this function has, not counting '...'.
@@ -1604,21 +1743,30 @@ protected:
unsigned NumParams : 16;
/// The type of exception specification this function has.
+ LLVM_PREFERRED_TYPE(ExceptionSpecificationType)
unsigned ExceptionSpecType : 4;
/// Whether this function has extended parameter information.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasExtParameterInfos : 1;
+ /// Whether this function has extra bitfields for the prototype.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasExtraBitfields : 1;
+
/// Whether the function is variadic.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Variadic : 1;
/// Whether this function has a trailing return type.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTrailingReturn : 1;
};
class ObjCObjectTypeBitfields {
friend class ObjCObjectType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// The number of type arguments stored directly on this object type.
@@ -1628,12 +1776,14 @@ protected:
unsigned NumProtocols : 6;
/// Whether this is a "kindof" type.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsKindOf : 1;
};
class ReferenceTypeBitfields {
friend class ReferenceType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// True if the type was originally spelled with an lvalue sigil.
@@ -1647,31 +1797,36 @@ protected:
/// ref &&a; // lvalue, inner ref
/// rvref &a; // lvalue, inner ref, spelled lvalue
/// rvref &&a; // rvalue, inner ref
+ LLVM_PREFERRED_TYPE(bool)
unsigned SpelledAsLValue : 1;
/// True if the inner type is a reference type. This only happens
/// in non-canonical forms.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InnerRef : 1;
};
class TypeWithKeywordBitfields {
friend class TypeWithKeyword;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// An ElaboratedTypeKeyword. 8 bits for efficient access.
+ LLVM_PREFERRED_TYPE(ElaboratedTypeKeyword)
unsigned Keyword : 8;
};
- enum { NumTypeWithKeywordBits = 8 };
+ enum { NumTypeWithKeywordBits = NumTypeBits + 8 };
class ElaboratedTypeBitfields {
friend class ElaboratedType;
- unsigned : NumTypeBits;
+ LLVM_PREFERRED_TYPE(TypeWithKeywordBitfields)
unsigned : NumTypeWithKeywordBits;
/// Whether the ElaboratedType has a trailing OwnedTagDecl.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasOwnedTagDecl : 1;
};
@@ -1679,11 +1834,13 @@ protected:
friend class VectorType;
friend class DependentVectorType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// The kind of vector, either a generic vector type or some
/// target-specific vector type such as for AltiVec or Neon.
- unsigned VecKind : 3;
+ LLVM_PREFERRED_TYPE(VectorKind)
+ unsigned VecKind : 4;
/// The number of elements in the vector.
uint32_t NumElements;
};
@@ -1691,19 +1848,22 @@ protected:
class AttributedTypeBitfields {
friend class AttributedType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
- /// An AttributedType::Kind
+ LLVM_PREFERRED_TYPE(attr::Kind)
unsigned AttrKind : 32 - NumTypeBits;
};
class AutoTypeBitfields {
friend class AutoType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// Was this placeholder type spelled as 'auto', 'decltype(auto)',
/// or '__auto_type'? AutoTypeKeyword value.
+ LLVM_PREFERRED_TYPE(AutoTypeKeyword)
unsigned Keyword : 2;
/// The number of template arguments in the type-constraints, which is
@@ -1716,27 +1876,82 @@ protected:
unsigned NumArgs;
};
+ class TypeOfBitfields {
+ friend class TypeOfType;
+ friend class TypeOfExprType;
+
+ LLVM_PREFERRED_TYPE(TypeBitfields)
+ unsigned : NumTypeBits;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsUnqual : 1; // If true: typeof_unqual, else: typeof
+ };
+
+ class UsingBitfields {
+ friend class UsingType;
+
+ LLVM_PREFERRED_TYPE(TypeBitfields)
+ unsigned : NumTypeBits;
+
+ /// True if the underlying type is different from the declared one.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned hasTypeDifferentFromDecl : 1;
+ };
+
+ class TypedefBitfields {
+ friend class TypedefType;
+
+ LLVM_PREFERRED_TYPE(TypeBitfields)
+ unsigned : NumTypeBits;
+
+ /// True if the underlying type is different from the declared one.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned hasTypeDifferentFromDecl : 1;
+ };
+
+ class SubstTemplateTypeParmTypeBitfields {
+ friend class SubstTemplateTypeParmType;
+
+ LLVM_PREFERRED_TYPE(TypeBitfields)
+ unsigned : NumTypeBits;
+
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasNonCanonicalUnderlyingType : 1;
+
+ // The index of the template parameter this substitution represents.
+ unsigned Index : 15;
+
+ /// Represents the index within a pack if this represents a substitution
+ /// from a pack expansion. This index starts at the end of the pack and
+ /// increments towards the beginning.
+ /// Positive non-zero number represents the index + 1.
+ /// Zero means this is not substituted from an expansion.
+ unsigned PackIndex : 16;
+ };
+
class SubstTemplateTypeParmPackTypeBitfields {
friend class SubstTemplateTypeParmPackType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
+ // The index of the template parameter this substitution represents.
+ unsigned Index : 16;
+
/// The number of template arguments in \c Arguments, which is
/// expected to be able to hold at least 1024 according to [implimits].
/// However as this limit is somewhat easy to hit with template
/// metaprogramming we'd prefer to keep it as large as possible.
- /// At the moment it has been left as a non-bitfield since this type
- /// safely fits in 64 bits as an unsigned, so there is no reason to
- /// introduce the performance impact of a bitfield.
- unsigned NumArgs;
+ unsigned NumArgs : 16;
};
class TemplateSpecializationTypeBitfields {
friend class TemplateSpecializationType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// Whether this template specialization type is a substituted type alias.
+ LLVM_PREFERRED_TYPE(bool)
unsigned TypeAlias : 1;
/// The number of template arguments named in this class template
@@ -1752,7 +1967,7 @@ protected:
class DependentTemplateSpecializationTypeBitfields {
friend class DependentTemplateSpecializationType;
- unsigned : NumTypeBits;
+ LLVM_PREFERRED_TYPE(TypeWithKeywordBitfields)
unsigned : NumTypeWithKeywordBits;
/// The number of template arguments named in this class template
@@ -1768,6 +1983,7 @@ protected:
class PackExpansionTypeBitfields {
friend class PackExpansionType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// The number of expansions that this pack expansion will
@@ -1790,6 +2006,9 @@ protected:
ConstantArrayTypeBitfields ConstantArrayTypeBits;
AttributedTypeBitfields AttributedTypeBits;
AutoTypeBitfields AutoTypeBits;
+ TypeOfBitfields TypeOfBits;
+ TypedefBitfields TypedefBits;
+ UsingBitfields UsingBits;
BuiltinTypeBitfields BuiltinTypeBits;
FunctionTypeBitfields FunctionTypeBits;
ObjCObjectTypeBitfields ObjCObjectTypeBits;
@@ -1797,6 +2016,7 @@ protected:
TypeWithKeywordBitfields TypeWithKeywordBits;
ElaboratedTypeBitfields ElaboratedTypeBits;
VectorTypeBitfields VectorTypeBits;
+ SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits;
SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
DependentTemplateSpecializationTypeBitfields
@@ -1818,15 +2038,16 @@ protected:
Type(TypeClass tc, QualType canon, TypeDependence Dependence)
: ExtQualsTypeCommonBase(this,
canon.isNull() ? QualType(this_(), 0) : canon) {
- static_assert(sizeof(*this) <= 8 + sizeof(ExtQualsTypeCommonBase),
+ static_assert(sizeof(*this) <=
+ alignof(decltype(*this)) + sizeof(ExtQualsTypeCommonBase),
"changing bitfields changed sizeof(Type)!");
- static_assert(alignof(decltype(*this)) % sizeof(void *) == 0,
+ static_assert(alignof(decltype(*this)) % TypeAlignment == 0,
"Insufficient alignment!");
TypeBits.TC = tc;
TypeBits.Dependence = static_cast<unsigned>(Dependence);
TypeBits.CacheValid = false;
TypeBits.CachedLocalOrUnnamed = false;
- TypeBits.CachedLinkage = NoLinkage;
+ TypeBits.CachedLinkage = llvm::to_underlying(Linkage::Invalid);
TypeBits.FromAST = false;
}
@@ -1894,16 +2115,43 @@ public:
bool isSizelessType() const;
bool isSizelessBuiltinType() const;
+ /// Returns true for all scalable vector types.
+ bool isSizelessVectorType() const;
+
+ /// Returns true for SVE scalable vector types.
+ bool isSVESizelessBuiltinType() const;
+
+ /// Returns true for RVV scalable vector types.
+ bool isRVVSizelessBuiltinType() const;
+
+ /// Check if this is a WebAssembly Externref Type.
+ bool isWebAssemblyExternrefType() const;
+
+ /// Returns true if this is a WebAssembly table type: either an array of
+ /// reference types, or a pointer to a reference type (which can only be
+ /// created by array to pointer decay).
+ bool isWebAssemblyTableType() const;
+
/// Determines if this is a sizeless type supported by the
/// 'arm_sve_vector_bits' type attribute, which can be applied to a single
/// SVE vector or predicate, excluding tuple types such as svint32x4_t.
- bool isVLSTBuiltinType() const;
+ bool isSveVLSBuiltinType() const;
/// Returns the representative type for the element of an SVE builtin type.
/// This is used to represent fixed-length SVE vectors created with the
/// 'arm_sve_vector_bits' type attribute as VectorType.
QualType getSveEltType(const ASTContext &Ctx) const;
+ /// Determines if this is a sizeless type supported by the
+ /// 'riscv_rvv_vector_bits' type attribute, which can be applied to a single
+ /// RVV vector or mask.
+ bool isRVVVLSBuiltinType() const;
+
+ /// Returns the representative type for the element of an RVV builtin type.
+ /// This is used to represent fixed-length RVV vectors created with the
+ /// 'riscv_rvv_vector_bits' type attribute as VectorType.
+ QualType getRVVEltType(const ASTContext &Ctx) const;
+
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.
@@ -1998,6 +2246,7 @@ public:
bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661
bool isBFloat16Type() const;
bool isFloat128Type() const;
+ bool isIbm128Type() const;
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
bool isVoidType() const; // C99 6.2.5p19
@@ -2039,6 +2288,7 @@ public:
bool isComplexIntegerType() const; // GCC _Complex integer type.
bool isVectorType() const; // GCC vector type.
bool isExtVectorType() const; // Extended vector type.
+ bool isExtVectorBoolType() const; // Extended vector type with bool element.
bool isMatrixType() const; // Matrix type.
bool isConstantMatrixType() const; // Constant matrix type.
bool isDependentAddressSpaceType() const; // value-dependent address space qualifier
@@ -2093,7 +2343,8 @@ public:
bool isObjCARCBridgableType() const;
bool isCARCBridgableType() const;
bool isTemplateTypeParmType() const; // C++ template type parameter
- bool isNullPtrType() const; // C++11 std::nullptr_t
+ bool isNullPtrType() const; // C++11 std::nullptr_t or
+ // C23 nullptr_t
bool isNothrowT() const; // C++ std::nothrow_t
bool isAlignValT() const; // C++17 std::align_val_t
bool isStdByteType() const; // C++17 std::byte
@@ -2122,7 +2373,7 @@ public:
bool isOCLExtOpaqueType() const; // Any OpenCL extension type
bool isPipeType() const; // OpenCL pipe type
- bool isExtIntType() const; // Extended Int Type
+ bool isBitIntType() const; // Bit-precise integer type
bool isOpenCLSpecificType() const; // Any OpenCL specific type
/// Determines if this type, which must satisfy
@@ -2337,9 +2588,6 @@ public:
/// removing any typedefs, typeofs, etc., as well as any qualifiers.
const Type *getUnqualifiedDesugaredType() const;
- /// More type predicates useful for type checking/promotion
- bool isPromotableIntegerType() const; // C99 6.3.1.1p2
-
/// Return true if this is an integer type that is
/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
/// or an enum decl which has a signed representation.
@@ -2415,7 +2663,7 @@ public:
/// Note that nullability is only captured as sugar within the type
/// system, not as part of the canonical type, so nullability will
/// be lost by canonicalization and desugaring.
- Optional<NullabilityKind> getNullability(const ASTContext &context) const;
+ std::optional<NullabilityKind> getNullability() const;
/// Determine whether the given type can have a nullability
/// specifier applied to it, i.e., if it is any kind of pointer type.
@@ -2439,7 +2687,7 @@ public:
/// the type parameters of the given declaration context in any type described
/// within that context, or an empty optional to indicate that no
/// substitution is required.
- Optional<ArrayRef<QualType>>
+ std::optional<ArrayRef<QualType>>
getObjCSubstitutions(const DeclContext *dc) const;
/// Determines if this is an ObjC interface type that may accept type
@@ -2460,6 +2708,7 @@ public:
/// This will check for a TypedefType by removing any existing sugar
/// until it reaches a TypedefType or a non-sugared type.
template <> const TypedefType *Type::getAs() const;
+template <> const UsingType *Type::getAs() const;
/// This will check for a TemplateSpecializationType by removing any
/// existing sugar until it reaches a TemplateSpecializationType or a
@@ -2502,6 +2751,9 @@ public:
// RVV Types
#define RVV_TYPE(Name, Id, SingletonId) Id,
#include "clang/Basic/RISCVVTypes.def"
+// WebAssembly reference types
+#define WASM_TYPE(Name, Id, SingletonId) Id,
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
// All other builtin types
#define BUILTIN_TYPE(Id, SingletonId) Id,
#define LAST_BUILTIN_TYPE(Id) LastKind = Id
@@ -2515,6 +2767,10 @@ private:
: Type(Builtin, QualType(),
K == Dependent ? TypeDependence::DependentInstantiation
: TypeDependence::None) {
+ static_assert(Kind::LastKind <
+ (1 << BuiltinTypeBitfields::NumOfBuiltinTypeBits) &&
+ "Defined builtin type exceeds the allocated space for serial "
+ "numbering");
BuiltinTypeBits.Kind = K;
}
@@ -2545,9 +2801,13 @@ public:
}
bool isFloatingPoint() const {
- return getKind() >= Half && getKind() <= Float128;
+ return getKind() >= Half && getKind() <= Ibm128;
}
+ bool isSVEBool() const { return getKind() == Kind::SveBool; }
+
+ bool isSVECount() const { return getKind() == Kind::SveCount; }
+
/// Determines whether the given kind corresponds to a placeholder type.
static bool isPlaceholderTypeKind(Kind K) {
return K >= Overload;
@@ -2873,17 +3133,14 @@ public:
}
};
+/// Capture whether this is a normal array (e.g. int X[4])
+/// an array with a static size (e.g. int X[static 4]), or an array
+/// with a star size (e.g. int X[*]).
+/// 'static' is only allowed on function parameters.
+enum class ArraySizeModifier { Normal, Static, Star };
+
/// Represents an array type, per C99 6.7.5.2 - Array Declarators.
class ArrayType : public Type, public llvm::FoldingSetNode {
-public:
- /// Capture whether this is a normal array (e.g. int X[4])
- /// an array with a static size (e.g. int X[static 4]), or an array
- /// with a star size (e.g. int X[*]).
- /// 'static' is only allowed on function parameters.
- enum ArraySizeModifier {
- Normal, Static, Star
- };
-
private:
/// The element type of the array.
QualType ElementType;
@@ -2958,6 +3215,8 @@ public:
QualType ElementType,
const llvm::APInt &NumElements);
+ unsigned getNumAddressingBits(const ASTContext &Context) const;
+
/// Determine the maximum number of active bits that an array's size
/// can require, which limits the maximum size of the array.
static unsigned getMaxSizeBits(const ASTContext &Context);
@@ -3005,7 +3264,7 @@ public:
static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
ArraySizeModifier SizeMod, unsigned TypeQuals) {
ID.AddPointer(ET.getAsOpaquePtr());
- ID.AddInteger(SizeMod);
+ ID.AddInteger(llvm::to_underlying(SizeMod));
ID.AddInteger(TypeQuals);
}
};
@@ -3081,8 +3340,6 @@ public:
class DependentSizedArrayType : public ArrayType {
friend class ASTContext; // ASTContext creates these.
- const ASTContext &Context;
-
/// An assignment expression that will instantiate to the
/// size of the array.
///
@@ -3093,8 +3350,8 @@ class DependentSizedArrayType : public ArrayType {
/// The range spanned by the left and right array brackets.
SourceRange Brackets;
- DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can,
- Expr *e, ArraySizeModifier sm, unsigned tq,
+ DependentSizedArrayType(QualType et, QualType can, Expr *e,
+ ArraySizeModifier sm, unsigned tq,
SourceRange brackets);
public:
@@ -3117,7 +3374,7 @@ public:
return T->getTypeClass() == DependentSizedArray;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getElementType(),
getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
}
@@ -3141,14 +3398,12 @@ public:
class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- const ASTContext &Context;
Expr *AddrSpaceExpr;
QualType PointeeType;
SourceLocation loc;
- DependentAddressSpaceType(const ASTContext &Context, QualType PointeeType,
- QualType can, Expr *AddrSpaceExpr,
- SourceLocation loc);
+ DependentAddressSpaceType(QualType PointeeType, QualType can,
+ Expr *AddrSpaceExpr, SourceLocation loc);
public:
Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; }
@@ -3162,7 +3417,7 @@ public:
return T->getTypeClass() == DependentAddressSpace;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getPointeeType(), getAddrSpaceExpr());
}
@@ -3183,7 +3438,6 @@ public:
class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- const ASTContext &Context;
Expr *SizeExpr;
/// The element type of the array.
@@ -3191,8 +3445,8 @@ class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
SourceLocation loc;
- DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType,
- QualType can, Expr *SizeExpr, SourceLocation loc);
+ DependentSizedExtVectorType(QualType ElementType, QualType can,
+ Expr *SizeExpr, SourceLocation loc);
public:
Expr *getSizeExpr() const { return SizeExpr; }
@@ -3206,7 +3460,7 @@ public:
return T->getTypeClass() == DependentSizedExtVector;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getElementType(), getSizeExpr());
}
@@ -3214,40 +3468,44 @@ public:
QualType ElementType, Expr *SizeExpr);
};
+enum class VectorKind {
+ /// not a target-specific vector type
+ Generic,
-/// Represents a GCC generic vector type. This type is created using
-/// __attribute__((vector_size(n)), where "n" specifies the vector size in
-/// bytes; or from an Altivec __vector or vector declaration.
-/// Since the constructor takes the number of vector elements, the
-/// client is responsible for converting the size into the number of elements.
-class VectorType : public Type, public llvm::FoldingSetNode {
-public:
- enum VectorKind {
- /// not a target-specific vector type
- GenericVector,
+ /// is AltiVec vector
+ AltiVecVector,
- /// is AltiVec vector
- AltiVecVector,
+ /// is AltiVec 'vector Pixel'
+ AltiVecPixel,
- /// is AltiVec 'vector Pixel'
- AltiVecPixel,
+ /// is AltiVec 'vector bool ...'
+ AltiVecBool,
- /// is AltiVec 'vector bool ...'
- AltiVecBool,
+ /// is ARM Neon vector
+ Neon,
- /// is ARM Neon vector
- NeonVector,
+ /// is ARM Neon polynomial vector
+ NeonPoly,
- /// is ARM Neon polynomial vector
- NeonPolyVector,
+ /// is AArch64 SVE fixed-length data vector
+ SveFixedLengthData,
- /// is AArch64 SVE fixed-length data vector
- SveFixedLengthDataVector,
+ /// is AArch64 SVE fixed-length predicate vector
+ SveFixedLengthPredicate,
- /// is AArch64 SVE fixed-length predicate vector
- SveFixedLengthPredicateVector
- };
+ /// is RISC-V RVV fixed-length data vector
+ RVVFixedLengthData,
+
+ /// is RISC-V RVV fixed-length mask vector
+ RVVFixedLengthMask,
+};
+/// Represents a GCC generic vector type. This type is created using
+/// __attribute__((vector_size(n)), where "n" specifies the vector size in
+/// bytes; or from an Altivec __vector or vector declaration.
+/// Since the constructor takes the number of vector elements, the
+/// client is responsible for converting the size into the number of elements.
+class VectorType : public Type, public llvm::FoldingSetNode {
protected:
friend class ASTContext; // ASTContext creates these.
@@ -3282,7 +3540,7 @@ public:
ID.AddPointer(ElementType.getAsOpaquePtr());
ID.AddInteger(NumElements);
ID.AddInteger(TypeClass);
- ID.AddInteger(VecKind);
+ ID.AddInteger(llvm::to_underlying(VecKind));
}
static bool classof(const Type *T) {
@@ -3302,21 +3560,19 @@ public:
class DependentVectorType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- const ASTContext &Context;
QualType ElementType;
Expr *SizeExpr;
SourceLocation Loc;
- DependentVectorType(const ASTContext &Context, QualType ElementType,
- QualType CanonType, Expr *SizeExpr,
- SourceLocation Loc, VectorType::VectorKind vecKind);
+ DependentVectorType(QualType ElementType, QualType CanonType, Expr *SizeExpr,
+ SourceLocation Loc, VectorKind vecKind);
public:
Expr *getSizeExpr() const { return SizeExpr; }
QualType getElementType() const { return ElementType; }
SourceLocation getAttributeLoc() const { return Loc; }
- VectorType::VectorKind getVectorKind() const {
- return VectorType::VectorKind(VectorTypeBits.VecKind);
+ VectorKind getVectorKind() const {
+ return VectorKind(VectorTypeBits.VecKind);
}
bool isSugared() const { return false; }
@@ -3326,13 +3582,13 @@ public:
return T->getTypeClass() == DependentVector;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getElementType(), getSizeExpr(), getVectorKind());
}
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
QualType ElementType, const Expr *SizeExpr,
- VectorType::VectorKind VecKind);
+ VectorKind VecKind);
};
/// ExtVectorType - Extended vector type. This type is created using
@@ -3345,7 +3601,8 @@ class ExtVectorType : public VectorType {
friend class ASTContext; // ASTContext creates these.
ExtVectorType(QualType vecType, unsigned nElements, QualType canonType)
- : VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
+ : VectorType(ExtVector, vecType, nElements, canonType,
+ VectorKind::Generic) {}
public:
static int getPointAccessorIdx(char c) {
@@ -3427,7 +3684,7 @@ public:
QualType getElementType() const { return ElementType; }
/// Valid elements types are the following:
- /// * an integer type (as in C2x 6.2.5p19), but excluding enumerated types
+ /// * an integer type (as in C23 6.2.5p22), but excluding enumerated types
/// and _Bool
/// * the standard floating types float or double
/// * a half-precision floating point type, if one is supported on the target
@@ -3450,10 +3707,6 @@ class ConstantMatrixType final : public MatrixType {
protected:
friend class ASTContext;
- /// The element type of the matrix.
- // FIXME: Appears to be unused? There is also MatrixType::ElementType...
- QualType ElementType;
-
/// Number of rows and columns.
unsigned NumRows;
unsigned NumColumns;
@@ -3512,30 +3765,24 @@ public:
class DependentSizedMatrixType final : public MatrixType {
friend class ASTContext;
- const ASTContext &Context;
Expr *RowExpr;
Expr *ColumnExpr;
SourceLocation loc;
- DependentSizedMatrixType(const ASTContext &Context, QualType ElementType,
- QualType CanonicalType, Expr *RowExpr,
- Expr *ColumnExpr, SourceLocation loc);
+ DependentSizedMatrixType(QualType ElementType, QualType CanonicalType,
+ Expr *RowExpr, Expr *ColumnExpr, SourceLocation loc);
public:
- QualType getElementType() const { return ElementType; }
Expr *getRowExpr() const { return RowExpr; }
Expr *getColumnExpr() const { return ColumnExpr; }
SourceLocation getAttributeLoc() const { return loc; }
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
static bool classof(const Type *T) {
return T->getTypeClass() == DependentSizedMatrix;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr());
}
@@ -3787,13 +4034,64 @@ public:
/// A simple holder for various uncommon bits which do not fit in
/// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the
- /// alignment of subsequent objects in TrailingObjects. You must update
- /// hasExtraBitfields in FunctionProtoType after adding extra data here.
+ /// alignment of subsequent objects in TrailingObjects.
struct alignas(void *) FunctionTypeExtraBitfields {
/// The number of types in the exception specification.
/// A whole unsigned is not needed here and according to
/// [implimits] 8 bits would be enough here.
- unsigned NumExceptionType;
+ unsigned NumExceptionType : 10;
+
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasArmTypeAttributes : 1;
+
+ FunctionTypeExtraBitfields()
+ : NumExceptionType(0), HasArmTypeAttributes(false) {}
+ };
+
+ /// The AArch64 SME ACLE (Arm C/C++ Language Extensions) define a number
+ /// of function type attributes that can be set on function types, including
+ /// function pointers.
+ enum AArch64SMETypeAttributes : unsigned {
+ SME_NormalFunction = 0,
+ SME_PStateSMEnabledMask = 1 << 0,
+ SME_PStateSMCompatibleMask = 1 << 1,
+
+ // Describes the value of the state using ArmStateValue.
+ SME_ZAShift = 2,
+ SME_ZAMask = 0b111 << SME_ZAShift,
+ SME_ZT0Shift = 5,
+ SME_ZT0Mask = 0b111 << SME_ZT0Shift,
+
+ SME_AttributeMask =
+ 0b111'111'11 // We can't support more than 8 bits because of
+ // the bitmask in FunctionTypeExtraBitfields.
+ };
+
+ enum ArmStateValue : unsigned {
+ ARM_None = 0,
+ ARM_Preserves = 1,
+ ARM_In = 2,
+ ARM_Out = 3,
+ ARM_InOut = 4,
+ };
+
+ static ArmStateValue getArmZAState(unsigned AttrBits) {
+ return (ArmStateValue)((AttrBits & SME_ZAMask) >> SME_ZAShift);
+ }
+
+ static ArmStateValue getArmZT0State(unsigned AttrBits) {
+ return (ArmStateValue)((AttrBits & SME_ZT0Mask) >> SME_ZT0Shift);
+ }
+
+ /// A holder for Arm type attributes as described in the Arm C/C++
+ /// Language extensions which are not particularly common to all
+ /// types and therefore accounted separately from FunctionTypeBitfields.
+ struct alignas(void *) FunctionTypeArmAttributes {
+ /// Any AArch64 SME ACLE type attributes that need to be propagated
+ /// on declarations and function pointers.
+ unsigned AArch64SMEAttributes : 8;
+
+ FunctionTypeArmAttributes() : AArch64SMEAttributes(SME_NormalFunction) {}
};
protected:
@@ -3804,7 +4102,10 @@ protected:
}
Qualifiers getFastTypeQuals() const {
- return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals);
+ if (isFunctionProtoType())
+ return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals);
+
+ return Qualifiers();
}
public:
@@ -3889,7 +4190,8 @@ class FunctionProtoType final
public llvm::FoldingSetNode,
private llvm::TrailingObjects<
FunctionProtoType, QualType, SourceLocation,
- FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType,
+ FunctionType::FunctionTypeExtraBitfields,
+ FunctionType::FunctionTypeArmAttributes, FunctionType::ExceptionType,
Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> {
friend class ASTContext; // ASTContext creates these.
friend TrailingObjects;
@@ -3962,6 +4264,8 @@ public:
ExceptionSpecInfo() = default;
ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {}
+
+ void instantiate();
};
/// Extra information about a function prototype. ExtProtoInfo is not
@@ -3969,24 +4273,44 @@ public:
/// the various bits of extra information about a function prototype.
struct ExtProtoInfo {
FunctionType::ExtInfo ExtInfo;
- bool Variadic : 1;
- bool HasTrailingReturn : 1;
+ unsigned Variadic : 1;
+ unsigned HasTrailingReturn : 1;
+ unsigned AArch64SMEAttributes : 8;
Qualifiers TypeQuals;
RefQualifierKind RefQualifier = RQ_None;
ExceptionSpecInfo ExceptionSpec;
const ExtParameterInfo *ExtParameterInfos = nullptr;
SourceLocation EllipsisLoc;
- ExtProtoInfo() : Variadic(false), HasTrailingReturn(false) {}
+ ExtProtoInfo()
+ : Variadic(false), HasTrailingReturn(false),
+ AArch64SMEAttributes(SME_NormalFunction) {}
ExtProtoInfo(CallingConv CC)
- : ExtInfo(CC), Variadic(false), HasTrailingReturn(false) {}
+ : ExtInfo(CC), Variadic(false), HasTrailingReturn(false),
+ AArch64SMEAttributes(SME_NormalFunction) {}
ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI) {
ExtProtoInfo Result(*this);
Result.ExceptionSpec = ESI;
return Result;
}
+
+ bool requiresFunctionProtoTypeExtraBitfields() const {
+ return ExceptionSpec.Type == EST_Dynamic ||
+ requiresFunctionProtoTypeArmAttributes();
+ }
+
+ bool requiresFunctionProtoTypeArmAttributes() const {
+ return AArch64SMEAttributes != SME_NormalFunction;
+ }
+
+ void setArmSMEAttribute(AArch64SMETypeAttributes Kind, bool Enable = true) {
+ if (Enable)
+ AArch64SMEAttributes |= Kind;
+ else
+ AArch64SMEAttributes &= ~Kind;
+ }
};
private:
@@ -3998,6 +4322,10 @@ private:
return isVariadic();
}
+ unsigned numTrailingObjects(OverloadToken<FunctionTypeArmAttributes>) const {
+ return hasArmTypeAttributes();
+ }
+
unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const {
return hasExtraBitfields();
}
@@ -4078,15 +4406,18 @@ private:
}
/// Whether the trailing FunctionTypeExtraBitfields is present.
- static bool hasExtraBitfields(ExceptionSpecificationType EST) {
- // If the exception spec type is EST_Dynamic then we have > 0 exception
- // types and the exact number is stored in FunctionTypeExtraBitfields.
- return EST == EST_Dynamic;
+ bool hasExtraBitfields() const {
+ assert((getExceptionSpecType() != EST_Dynamic ||
+ FunctionTypeBits.HasExtraBitfields) &&
+ "ExtraBitfields are required for given ExceptionSpecType");
+ return FunctionTypeBits.HasExtraBitfields;
+
}
- /// Whether the trailing FunctionTypeExtraBitfields is present.
- bool hasExtraBitfields() const {
- return hasExtraBitfields(getExceptionSpecType());
+ bool hasArmTypeAttributes() const {
+ return FunctionTypeBits.HasExtraBitfields &&
+ getTrailingObjects<FunctionTypeExtraBitfields>()
+ ->HasArmTypeAttributes;
}
bool hasExtQualifiers() const {
@@ -4102,7 +4433,7 @@ public:
}
ArrayRef<QualType> getParamTypes() const {
- return llvm::makeArrayRef(param_type_begin(), param_type_end());
+ return llvm::ArrayRef(param_type_begin(), param_type_end());
}
ExtProtoInfo getExtProtoInfo() const {
@@ -4115,6 +4446,7 @@ public:
EPI.TypeQuals = getMethodQuals();
EPI.RefQualifier = getRefQualifier();
EPI.ExtParameterInfos = getExtParameterInfosOrNull();
+ EPI.AArch64SMEAttributes = getAArch64SMEAttributes();
return EPI;
}
@@ -4247,10 +4579,9 @@ public:
}
using param_type_iterator = const QualType *;
- using param_type_range = llvm::iterator_range<param_type_iterator>;
- param_type_range param_types() const {
- return param_type_range(param_type_begin(), param_type_end());
+ ArrayRef<QualType> param_types() const {
+ return llvm::ArrayRef(param_type_begin(), param_type_end());
}
param_type_iterator param_type_begin() const {
@@ -4264,7 +4595,7 @@ public:
using exception_iterator = const QualType *;
ArrayRef<QualType> exceptions() const {
- return llvm::makeArrayRef(exception_begin(), exception_end());
+ return llvm::ArrayRef(exception_begin(), exception_end());
}
exception_iterator exception_begin() const {
@@ -4297,6 +4628,15 @@ public:
return getTrailingObjects<ExtParameterInfo>();
}
+ /// Return a bitmask describing the SME attributes on the function type, see
+ /// AArch64SMETypeAttributes for their values.
+ unsigned getAArch64SMEAttributes() const {
+ if (!hasArmTypeAttributes())
+ return SME_NormalFunction;
+ return getTrailingObjects<FunctionTypeArmAttributes>()
+ ->AArch64SMEAttributes;
+ }
+
ExtParameterInfo getExtParameterInfo(unsigned I) const {
assert(I < getNumParams() && "parameter index out of range");
if (hasExtParameterInfos())
@@ -4370,11 +4710,45 @@ public:
}
};
-class TypedefType : public Type {
- TypedefNameDecl *Decl;
+class UsingType final : public Type,
+ public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<UsingType, QualType> {
+ UsingShadowDecl *Found;
+ friend class ASTContext; // ASTContext creates these.
+ friend TrailingObjects;
-private:
+ UsingType(const UsingShadowDecl *Found, QualType Underlying, QualType Canon);
+
+public:
+ UsingShadowDecl *getFoundDecl() const { return Found; }
+ QualType getUnderlyingType() const;
+
+ bool isSugared() const { return true; }
+
+ // This always has the 'same' type as declared, but not necessarily identical.
+ QualType desugar() const { return getUnderlyingType(); }
+
+ // Internal helper, for debugging purposes.
+ bool typeMatchesDecl() const { return !UsingBits.hasTypeDifferentFromDecl; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Found, typeMatchesDecl() ? QualType() : getUnderlyingType());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, const UsingShadowDecl *Found,
+ QualType Underlying) {
+ ID.AddPointer(Found);
+ if (!Underlying.isNull())
+ Underlying.Profile(ID);
+ }
+ static bool classof(const Type *T) { return T->getTypeClass() == Using; }
+};
+
+class TypedefType final : public Type,
+ public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<TypedefType, QualType> {
+ TypedefNameDecl *Decl;
friend class ASTContext; // ASTContext creates these.
+ friend TrailingObjects;
TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType underlying,
QualType can);
@@ -4383,8 +4757,23 @@ public:
TypedefNameDecl *getDecl() const { return Decl; }
bool isSugared() const { return true; }
+
+ // This always has the 'same' type as declared, but not necessarily identical.
QualType desugar() const;
+ // Internal helper, for debugging purposes.
+ bool typeMatchesDecl() const { return !TypedefBits.hasTypeDifferentFromDecl; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Decl, typeMatchesDecl() ? QualType() : desugar());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, const TypedefNameDecl *Decl,
+ QualType Underlying) {
+ ID.AddPointer(Decl);
+ if (!Underlying.isNull())
+ Underlying.Profile(ID);
+ }
+
static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
};
@@ -4420,18 +4809,25 @@ public:
}
};
-/// Represents a `typeof` (or __typeof__) expression (a GCC extension).
+/// Represents a `typeof` (or __typeof__) expression (a C23 feature and GCC
+/// extension) or a `typeof_unqual` expression (a C23 feature).
class TypeOfExprType : public Type {
Expr *TOExpr;
protected:
friend class ASTContext; // ASTContext creates these.
- TypeOfExprType(Expr *E, QualType can = QualType());
+ TypeOfExprType(Expr *E, TypeOfKind Kind, QualType Can = QualType());
public:
Expr *getUnderlyingExpr() const { return TOExpr; }
+ /// Returns the kind of 'typeof' type this is.
+ TypeOfKind getKind() const {
+ return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified
+ : TypeOfKind::Qualified;
+ }
+
/// Remove a single level of sugar.
QualType desugar() const;
@@ -4447,42 +4843,54 @@ public:
/// This class is used internally by the ASTContext to manage
/// canonical, dependent types, only. Clients will only see instances
/// of this class via TypeOfExprType nodes.
-class DependentTypeOfExprType
- : public TypeOfExprType, public llvm::FoldingSetNode {
- const ASTContext &Context;
-
+class DependentTypeOfExprType : public TypeOfExprType,
+ public llvm::FoldingSetNode {
public:
- DependentTypeOfExprType(const ASTContext &Context, Expr *E)
- : TypeOfExprType(E), Context(Context) {}
+ DependentTypeOfExprType(Expr *E, TypeOfKind Kind) : TypeOfExprType(E, Kind) {}
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Context, getUnderlyingExpr());
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
+ Profile(ID, Context, getUnderlyingExpr(),
+ getKind() == TypeOfKind::Unqualified);
}
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- Expr *E);
+ Expr *E, bool IsUnqual);
};
-/// Represents `typeof(type)`, a GCC extension.
+/// Represents `typeof(type)`, a C23 feature and GCC extension, or
+/// `typeof_unqual(type), a C23 feature.
class TypeOfType : public Type {
friend class ASTContext; // ASTContext creates these.
QualType TOType;
- TypeOfType(QualType T, QualType can)
- : Type(TypeOf, can, T->getDependence()), TOType(T) {
- assert(!isa<TypedefType>(can) && "Invalid canonical type");
+ TypeOfType(QualType T, QualType Can, TypeOfKind Kind)
+ : Type(TypeOf,
+ Kind == TypeOfKind::Unqualified ? Can.getAtomicUnqualifiedType()
+ : Can,
+ T->getDependence()),
+ TOType(T) {
+ TypeOfBits.IsUnqual = Kind == TypeOfKind::Unqualified;
}
public:
- QualType getUnderlyingType() const { return TOType; }
+ QualType getUnmodifiedType() const { return TOType; }
/// Remove a single level of sugar.
- QualType desugar() const { return getUnderlyingType(); }
+ QualType desugar() const {
+ QualType QT = getUnmodifiedType();
+ return TypeOfBits.IsUnqual ? QT.getAtomicUnqualifiedType() : QT;
+ }
/// Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
+ /// Returns the kind of 'typeof' type this is.
+ TypeOfKind getKind() const {
+ return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified
+ : TypeOfKind::Qualified;
+ }
+
static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
};
@@ -4516,12 +4924,10 @@ public:
/// canonical, dependent types, only. Clients will only see instances
/// of this class via DecltypeType nodes.
class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
- const ASTContext &Context;
-
public:
- DependentDecltypeType(const ASTContext &Context, Expr *E);
+ DependentDecltypeType(Expr *E, QualType UnderlyingTpe);
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getUnderlyingExpr());
}
@@ -4533,7 +4939,8 @@ public:
class UnaryTransformType : public Type {
public:
enum UTTKind {
- EnumUnderlyingType
+#define TRANSFORM_TYPE_TRAIT_DEF(Enum, _) Enum,
+#include "clang/Basic/TransformTypeTraits.def"
};
private:
@@ -4714,9 +5121,11 @@ public:
bool isMSTypeSpec() const;
+ bool isWebAssemblyFuncrefSpec() const;
+
bool isCallingConv() const;
- llvm::Optional<NullabilityKind> getImmediateNullability() const;
+ std::optional<NullabilityKind> getImmediateNullability() const;
/// Retrieve the attribute kind corresponding to the given
/// nullability kind.
@@ -4746,7 +5155,7 @@ public:
/// to the underlying modified type.
///
/// \returns the top-level nullability, if present.
- static Optional<NullabilityKind> stripOuterNullability(QualType &T);
+ static std::optional<NullabilityKind> stripOuterNullability(QualType &T);
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
@@ -4764,6 +5173,40 @@ public:
}
};
+class BTFTagAttributedType : public Type, public llvm::FoldingSetNode {
+private:
+ friend class ASTContext; // ASTContext creates these
+
+ QualType WrappedType;
+ const BTFTypeTagAttr *BTFAttr;
+
+ BTFTagAttributedType(QualType Canon, QualType Wrapped,
+ const BTFTypeTagAttr *BTFAttr)
+ : Type(BTFTagAttributed, Canon, Wrapped->getDependence()),
+ WrappedType(Wrapped), BTFAttr(BTFAttr) {}
+
+public:
+ QualType getWrappedType() const { return WrappedType; }
+ const BTFTypeTagAttr *getAttr() const { return BTFAttr; }
+
+ bool isSugared() const { return true; }
+ QualType desugar() const { return getWrappedType(); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, WrappedType, BTFAttr);
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Wrapped,
+ const BTFTypeTagAttr *BTFAttr) {
+ ID.AddPointer(Wrapped.getAsOpaquePtr());
+ ID.AddPointer(BTFAttr);
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == BTFTagAttributed;
+ }
+};
+
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
@@ -4843,40 +5286,60 @@ public:
/// been replaced with these. They are used solely to record that a
/// type was originally written as a template type parameter;
/// therefore they are never canonical.
-class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+class SubstTemplateTypeParmType final
+ : public Type,
+ public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<SubstTemplateTypeParmType, QualType> {
friend class ASTContext;
+ friend class llvm::TrailingObjects<SubstTemplateTypeParmType, QualType>;
- // The original type parameter.
- const TemplateTypeParmType *Replaced;
+ Decl *AssociatedDecl;
- SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
- : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()),
- Replaced(Param) {}
+ SubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
+ unsigned Index, std::optional<unsigned> PackIndex);
public:
- /// Gets the template parameter that was substituted for.
- const TemplateTypeParmType *getReplacedParameter() const {
- return Replaced;
- }
-
/// Gets the type that was substituted for the template
/// parameter.
QualType getReplacementType() const {
- return getCanonicalTypeInternal();
+ return SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType
+ ? *getTrailingObjects<QualType>()
+ : getCanonicalTypeInternal();
+ }
+
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will usually own a set of template parameters, or in some
+ /// cases might even be a template parameter itself.
+ Decl *getAssociatedDecl() const { return AssociatedDecl; }
+
+ /// Gets the template parameter declaration that was substituted for.
+ const TemplateTypeParmDecl *getReplacedParameter() const;
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getReplacedParameter()->getIndex()`.
+ unsigned getIndex() const { return SubstTemplateTypeParmTypeBits.Index; }
+
+ std::optional<unsigned> getPackIndex() const {
+ if (SubstTemplateTypeParmTypeBits.PackIndex == 0)
+ return std::nullopt;
+ return SubstTemplateTypeParmTypeBits.PackIndex - 1;
}
bool isSugared() const { return true; }
QualType desugar() const { return getReplacementType(); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReplacedParameter(), getReplacementType());
+ Profile(ID, getReplacementType(), getAssociatedDecl(), getIndex(),
+ getPackIndex());
}
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
- QualType Replacement) {
- ID.AddPointer(Replaced);
- ID.AddPointer(Replacement.getAsOpaquePtr());
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement,
+ const Decl *AssociatedDecl, unsigned Index,
+ std::optional<unsigned> PackIndex) {
+ Replacement.Profile(ID);
+ ID.AddPointer(AssociatedDecl);
+ ID.AddInteger(Index);
+ ID.AddInteger(PackIndex ? *PackIndex - 1 : 0);
}
static bool classof(const Type *T) {
@@ -4899,24 +5362,33 @@ public:
class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- /// The original type parameter.
- const TemplateTypeParmType *Replaced;
-
/// A pointer to the set of template arguments that this
/// parameter pack is instantiated with.
const TemplateArgument *Arguments;
- SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
- QualType Canon,
+ llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
+
+ SubstTemplateTypeParmPackType(QualType Canon, Decl *AssociatedDecl,
+ unsigned Index, bool Final,
const TemplateArgument &ArgPack);
public:
- IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
+ IdentifierInfo *getIdentifier() const;
- /// Gets the template parameter that was substituted for.
- const TemplateTypeParmType *getReplacedParameter() const {
- return Replaced;
- }
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will usually own a set of template parameters, or in some
+ /// cases might even be a template parameter itself.
+ Decl *getAssociatedDecl() const;
+
+ /// Gets the template parameter declaration that was substituted for.
+ const TemplateTypeParmDecl *getReplacedParameter() const;
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getReplacedParameter()->getIndex()`.
+ unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; }
+
+ // When true the substitution will be 'Final' (subst node won't be placed).
+ bool getFinal() const;
unsigned getNumArgs() const {
return SubstTemplateTypeParmPackTypeBits.NumArgs;
@@ -4928,8 +5400,8 @@ public:
TemplateArgument getArgumentPack() const;
void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
+ static void Profile(llvm::FoldingSetNodeID &ID, const Decl *AssociatedDecl,
+ unsigned Index, bool Final,
const TemplateArgument &ArgPack);
static bool classof(const Type *T) {
@@ -4946,29 +5418,29 @@ public:
/// type-dependent, there is no deduced type and the type is canonical. In
/// the latter case, it is also a dependent type.
class DeducedType : public Type {
+ QualType DeducedAsType;
+
protected:
DeducedType(TypeClass TC, QualType DeducedAsType,
- TypeDependence ExtraDependence)
- : Type(TC,
- // FIXME: Retain the sugared deduced type?
- DeducedAsType.isNull() ? QualType(this, 0)
- : DeducedAsType.getCanonicalType(),
+ TypeDependence ExtraDependence, QualType Canon)
+ : Type(TC, Canon,
ExtraDependence | (DeducedAsType.isNull()
? TypeDependence::None
: DeducedAsType->getDependence() &
- ~TypeDependence::VariablyModified)) {}
+ ~TypeDependence::VariablyModified)),
+ DeducedAsType(DeducedAsType) {}
public:
- bool isSugared() const { return !isCanonicalUnqualified(); }
- QualType desugar() const { return getCanonicalTypeInternal(); }
-
- /// Get the type deduced for this placeholder type, or null if it's
- /// either not been deduced or was deduced to a dependent type.
- QualType getDeducedType() const {
- return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
+ bool isSugared() const { return !DeducedAsType.isNull(); }
+ QualType desugar() const {
+ return isSugared() ? DeducedAsType : QualType(this, 0);
}
+
+ /// Get the type deduced for this placeholder type, or null if it
+ /// has not been deduced.
+ QualType getDeducedType() const { return DeducedAsType; }
bool isDeduced() const {
- return !isCanonicalUnqualified() || isDependentType();
+ return !DeducedAsType.isNull() || isDependentType();
}
static bool classof(const Type *T) {
@@ -4979,38 +5451,19 @@ public:
/// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained
/// by a type-constraint.
-class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode {
+class AutoType : public DeducedType, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
ConceptDecl *TypeConstraintConcept;
AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
- TypeDependence ExtraDependence, ConceptDecl *CD,
+ TypeDependence ExtraDependence, QualType Canon, ConceptDecl *CD,
ArrayRef<TemplateArgument> TypeConstraintArgs);
- const TemplateArgument *getArgBuffer() const {
- return reinterpret_cast<const TemplateArgument*>(this+1);
- }
-
- TemplateArgument *getArgBuffer() {
- return reinterpret_cast<TemplateArgument*>(this+1);
- }
-
public:
- /// Retrieve the template arguments.
- const TemplateArgument *getArgs() const {
- return getArgBuffer();
- }
-
- /// Retrieve the number of template arguments.
- unsigned getNumArgs() const {
- return AutoTypeBits.NumArgs;
- }
-
- const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
ArrayRef<TemplateArgument> getTypeConstraintArguments() const {
- return {getArgs(), getNumArgs()};
+ return {reinterpret_cast<const TemplateArgument *>(this + 1),
+ AutoTypeBits.NumArgs};
}
ConceptDecl *getTypeConstraintConcept() const {
@@ -5025,15 +5478,15 @@ public:
return getKeyword() == AutoTypeKeyword::DecltypeAuto;
}
- AutoTypeKeyword getKeyword() const {
- return (AutoTypeKeyword)AutoTypeBits.Keyword;
+ bool isGNUAutoType() const {
+ return getKeyword() == AutoTypeKeyword::GNUAutoType;
}
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
- Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
- getTypeConstraintConcept(), getTypeConstraintArguments());
+ AutoTypeKeyword getKeyword() const {
+ return (AutoTypeKeyword)AutoTypeBits.Keyword;
}
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context);
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
QualType Deduced, AutoTypeKeyword Keyword,
bool IsDependent, ConceptDecl *CD,
@@ -5059,7 +5512,9 @@ class DeducedTemplateSpecializationType : public DeducedType,
toTypeDependence(Template.getDependence()) |
(IsDeducedAsDependent
? TypeDependence::DependentInstantiation
- : TypeDependence::None)),
+ : TypeDependence::None),
+ DeducedAsType.isNull() ? QualType(this, 0)
+ : DeducedAsType.getCanonicalType()),
Template(Template) {}
public:
@@ -5073,8 +5528,10 @@ public:
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
QualType Deduced, bool IsDependent) {
Template.Profile(ID);
- ID.AddPointer(Deduced.getAsOpaquePtr());
- ID.AddBoolean(IsDependent);
+ QualType CanonicalType =
+ Deduced.isNull() ? Deduced : Deduced.getCanonicalType();
+ ID.AddPointer(CanonicalType.getAsOpaquePtr());
+ ID.AddBoolean(IsDependent || Template.isDependent());
}
static bool classof(const Type *T) {
@@ -5102,9 +5559,7 @@ public:
/// TemplateArguments, followed by a QualType representing the
/// non-canonical aliased type when the template is a type alias
/// template.
-class alignas(8) TemplateSpecializationType
- : public Type,
- public llvm::FoldingSetNode {
+class TemplateSpecializationType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
/// The name of the template being specialized. This is
@@ -5167,35 +5622,14 @@ public:
/// Get the aliased type, if this is a specialization of a type alias
/// template.
- QualType getAliasedType() const {
- assert(isTypeAlias() && "not a type alias template specialization");
- return *reinterpret_cast<const QualType*>(end());
- }
-
- using iterator = const TemplateArgument *;
-
- iterator begin() const { return getArgs(); }
- iterator end() const; // defined inline in TemplateBase.h
+ QualType getAliasedType() const;
/// Retrieve the name of the template that we are specializing.
TemplateName getTemplateName() const { return Template; }
- /// Retrieve the template arguments.
- const TemplateArgument *getArgs() const {
- return reinterpret_cast<const TemplateArgument *>(this + 1);
- }
-
- /// Retrieve the number of template arguments.
- unsigned getNumArgs() const {
- return TemplateSpecializationTypeBits.NumArgs;
- }
-
- /// Retrieve a specific template argument as a type.
- /// \pre \c isArgType(Arg)
- const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
ArrayRef<TemplateArgument> template_arguments() const {
- return {getArgs(), getNumArgs()};
+ return {reinterpret_cast<const TemplateArgument *>(this + 1),
+ TemplateSpecializationTypeBits.NumArgs};
}
bool isSugared() const {
@@ -5206,12 +5640,7 @@ public:
return isTypeAlias() ? getAliasedType() : getCanonicalTypeInternal();
}
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
- Profile(ID, Template, template_arguments(), Ctx);
- if (isTypeAlias())
- getAliasedType().Profile(ID);
- }
-
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
ArrayRef<TemplateArgument> Args,
const ASTContext &Context);
@@ -5238,6 +5667,13 @@ void printTemplateArgumentList(raw_ostream &OS,
const PrintingPolicy &Policy,
const TemplateParameterList *TPL = nullptr);
+/// Make a best-effort determination of whether the type T can be produced by
+/// substituting Args into the default argument of Param.
+bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
+ const NamedDecl *Param,
+ ArrayRef<TemplateArgument> Args,
+ unsigned Depth);
+
/// The injected class name of a C++ class template or class
/// template partial specialization. Used to record that a type was
/// spelled with a bare identifier rather than as a template-id; the
@@ -5306,48 +5742,48 @@ public:
}
};
-/// The kind of a tag type.
-enum TagTypeKind {
- /// The "struct" keyword.
- TTK_Struct,
-
- /// The "__interface" keyword.
- TTK_Interface,
-
- /// The "union" keyword.
- TTK_Union,
-
- /// The "class" keyword.
- TTK_Class,
-
- /// The "enum" keyword.
- TTK_Enum
-};
-
/// The elaboration keyword that precedes a qualified type name or
/// introduces an elaborated-type-specifier.
-enum ElaboratedTypeKeyword {
+enum class ElaboratedTypeKeyword {
/// The "struct" keyword introduces the elaborated-type-specifier.
- ETK_Struct,
+ Struct,
/// The "__interface" keyword introduces the elaborated-type-specifier.
- ETK_Interface,
+ Interface,
/// The "union" keyword introduces the elaborated-type-specifier.
- ETK_Union,
+ Union,
/// The "class" keyword introduces the elaborated-type-specifier.
- ETK_Class,
+ Class,
/// The "enum" keyword introduces the elaborated-type-specifier.
- ETK_Enum,
+ Enum,
/// The "typename" keyword precedes the qualified type name, e.g.,
/// \c typename T::type.
- ETK_Typename,
+ Typename,
/// No keyword precedes the qualified type name.
- ETK_None
+ None
+};
+
+/// The kind of a tag type.
+enum class TagTypeKind {
+ /// The "struct" keyword.
+ Struct,
+
+ /// The "__interface" keyword.
+ Interface,
+
+ /// The "union" keyword.
+ Union,
+
+ /// The "class" keyword.
+ Class,
+
+ /// The "enum" keyword.
+ Enum
};
/// A helper class for Type nodes having an ElaboratedTypeKeyword.
@@ -5359,7 +5795,7 @@ protected:
TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
QualType Canonical, TypeDependence Dependence)
: Type(tc, Canonical, Dependence) {
- TypeWithKeywordBits.Keyword = Keyword;
+ TypeWithKeywordBits.Keyword = llvm::to_underlying(Keyword);
}
public:
@@ -5436,9 +5872,6 @@ class ElaboratedType final
ElaboratedTypeBits.HasOwnedTagDecl = true;
*getTrailingObjects<TagDecl *>() = OwnedTagDecl;
}
- assert(!(Keyword == ETK_None && NNS == nullptr) &&
- "ElaboratedType cannot have elaborated type keyword "
- "and name qualifier both null.");
}
public:
@@ -5468,7 +5901,7 @@ public:
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, QualType NamedType,
TagDecl *OwnedTagDecl) {
- ID.AddInteger(Keyword);
+ ID.AddInteger(llvm::to_underlying(Keyword));
ID.AddPointer(NNS);
NamedType.Profile(ID);
ID.AddPointer(OwnedTagDecl);
@@ -5527,7 +5960,7 @@ public:
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
- ID.AddInteger(Keyword);
+ ID.AddInteger(llvm::to_underlying(Keyword));
ID.AddPointer(NNS);
ID.AddPointer(Name);
}
@@ -5540,9 +5973,8 @@ public:
/// Represents a template specialization type whose template cannot be
/// resolved, e.g.
/// A<T>::template B<T>
-class alignas(8) DependentTemplateSpecializationType
- : public TypeWithKeyword,
- public llvm::FoldingSetNode {
+class DependentTemplateSpecializationType : public TypeWithKeyword,
+ public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
/// The nested name specifier containing the qualifier.
@@ -5557,44 +5989,20 @@ class alignas(8) DependentTemplateSpecializationType
ArrayRef<TemplateArgument> Args,
QualType Canon);
- const TemplateArgument *getArgBuffer() const {
- return reinterpret_cast<const TemplateArgument*>(this+1);
- }
-
- TemplateArgument *getArgBuffer() {
- return reinterpret_cast<TemplateArgument*>(this+1);
- }
-
public:
NestedNameSpecifier *getQualifier() const { return NNS; }
const IdentifierInfo *getIdentifier() const { return Name; }
- /// Retrieve the template arguments.
- const TemplateArgument *getArgs() const {
- return getArgBuffer();
- }
-
- /// Retrieve the number of template arguments.
- unsigned getNumArgs() const {
- return DependentTemplateSpecializationTypeBits.NumArgs;
- }
-
- const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
ArrayRef<TemplateArgument> template_arguments() const {
- return {getArgs(), getNumArgs()};
+ return {reinterpret_cast<const TemplateArgument *>(this + 1),
+ DependentTemplateSpecializationTypeBits.NumArgs};
}
- using iterator = const TemplateArgument *;
-
- iterator begin() const { return getArgs(); }
- iterator end() const; // inline in TemplateBase.h
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
- Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), getNumArgs()});
+ Profile(ID, Context, getKeyword(), NNS, Name, template_arguments());
}
static void Profile(llvm::FoldingSetNodeID &ID,
@@ -5638,7 +6046,7 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
QualType Pattern;
PackExpansionType(QualType Pattern, QualType Canon,
- Optional<unsigned> NumExpansions)
+ std::optional<unsigned> NumExpansions)
: Type(PackExpansion, Canon,
(Pattern->getDependence() | TypeDependence::Dependent |
TypeDependence::Instantiation) &
@@ -5656,10 +6064,10 @@ public:
/// Retrieve the number of expansions that this pack expansion will
/// generate, if known.
- Optional<unsigned> getNumExpansions() const {
+ std::optional<unsigned> getNumExpansions() const {
if (PackExpansionTypeBits.NumExpansions)
return PackExpansionTypeBits.NumExpansions - 1;
- return None;
+ return std::nullopt;
}
bool isSugared() const { return false; }
@@ -5670,9 +6078,9 @@ public:
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
- Optional<unsigned> NumExpansions) {
+ std::optional<unsigned> NumExpansions) {
ID.AddPointer(Pattern.getAsOpaquePtr());
- ID.AddBoolean(NumExpansions.hasValue());
+ ID.AddBoolean(NumExpansions.has_value());
if (NumExpansions)
ID.AddInteger(*NumExpansions);
}
@@ -5927,8 +6335,7 @@ public:
/// Retrieve the type arguments of this object type as they were
/// written.
ArrayRef<QualType> getTypeArgsAsWritten() const {
- return llvm::makeArrayRef(getTypeArgStorage(),
- ObjCObjectTypeBits.NumTypeArgs);
+ return llvm::ArrayRef(getTypeArgStorage(), ObjCObjectTypeBits.NumTypeArgs);
}
/// Whether this is a "__kindof" type as written.
@@ -6018,10 +6425,9 @@ inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() {
class ObjCInterfaceType : public ObjCObjectType {
friend class ASTContext; // ASTContext creates these.
friend class ASTReader;
- friend class ObjCInterfaceDecl;
template <class T> friend class serialization::AbstractTypeReader;
- mutable ObjCInterfaceDecl *Decl;
+ ObjCInterfaceDecl *Decl;
ObjCInterfaceType(const ObjCInterfaceDecl *D)
: ObjCObjectType(Nonce_ObjCInterface),
@@ -6029,7 +6435,7 @@ class ObjCInterfaceType : public ObjCObjectType {
public:
/// Get the declaration of this interface.
- ObjCInterfaceDecl *getDecl() const { return Decl; }
+ ObjCInterfaceDecl *getDecl() const;
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -6306,13 +6712,14 @@ public:
};
/// A fixed int type of a specified bitwidth.
-class ExtIntType final : public Type, public llvm::FoldingSetNode {
+class BitIntType final : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsUnsigned : 1;
unsigned NumBits : 24;
protected:
- ExtIntType(bool isUnsigned, unsigned NumBits);
+ BitIntType(bool isUnsigned, unsigned NumBits);
public:
bool isUnsigned() const { return IsUnsigned; }
@@ -6322,7 +6729,7 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, isUnsigned(), getNumBits());
}
@@ -6332,17 +6739,15 @@ public:
ID.AddInteger(NumBits);
}
- static bool classof(const Type *T) { return T->getTypeClass() == ExtInt; }
+ static bool classof(const Type *T) { return T->getTypeClass() == BitInt; }
};
-class DependentExtIntType final : public Type, public llvm::FoldingSetNode {
+class DependentBitIntType final : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- const ASTContext &Context;
llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned;
protected:
- DependentExtIntType(const ASTContext &Context, bool IsUnsigned,
- Expr *NumBits);
+ DependentBitIntType(bool IsUnsigned, Expr *NumBits);
public:
bool isUnsigned() const;
@@ -6352,14 +6757,14 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, isUnsigned(), getNumBitsExpr());
}
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
bool IsUnsigned, Expr *NumBitsExpr);
static bool classof(const Type *T) {
- return T->getTypeClass() == DependentExtInt;
+ return T->getTypeClass() == DependentBitInt;
}
};
@@ -6402,7 +6807,7 @@ class alignas(8) TypeSourceInfo {
QualType Ty;
- TypeSourceInfo(QualType ty) : Ty(ty) {}
+ TypeSourceInfo(QualType ty, size_t DataSize); // implemented in TypeLoc.h
public:
/// Return the type wrapped by this type source info.
@@ -6432,6 +6837,19 @@ inline const Type *QualType::getTypePtrOrNull() const {
return (isNull() ? nullptr : getCommonPtr()->BaseType);
}
+inline bool QualType::isReferenceable() const {
+ // C++ [defns.referenceable]
+ // type that is either an object type, a function type that does not have
+ // cv-qualifiers or a ref-qualifier, or a reference type.
+ const Type &Self = **this;
+ if (Self.isObjectType() || Self.isReferenceType())
+ return true;
+ if (const auto *F = Self.getAs<FunctionProtoType>())
+ return F->getMethodQuals().empty() && F->getRefQualifier() == RQ_None;
+
+ return false;
+}
+
inline SplitQualType QualType::split() const {
if (!hasLocalNonFastQualifiers())
return SplitQualType(getTypePtrUnsafe(),
@@ -6530,15 +6948,6 @@ inline void QualType::removeLocalVolatile() {
removeLocalFastQualifiers(Qualifiers::Volatile);
}
-inline void QualType::removeLocalCVRQualifiers(unsigned Mask) {
- assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits");
- static_assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask,
- "Fast bits differ from CVR bits!");
-
- // Fast path: we don't need to touch the slow qualifiers.
- removeLocalFastQualifiers(Mask);
-}
-
/// Check if this type has any address space qualifier.
inline bool QualType::hasAddressSpace() const {
return getQualifiers().hasAddressSpace();
@@ -6782,6 +7191,12 @@ inline bool Type::isExtVectorType() const {
return isa<ExtVectorType>(CanonicalType);
}
+inline bool Type::isExtVectorBoolType() const {
+ if (!isExtVectorType())
+ return false;
+ return cast<ExtVectorType>(CanonicalType)->getElementType()->isBooleanType();
+}
+
inline bool Type::isMatrixType() const {
return isa<MatrixType>(CanonicalType);
}
@@ -6890,8 +7305,8 @@ inline bool Type::isPipeType() const {
return isa<PipeType>(CanonicalType);
}
-inline bool Type::isExtIntType() const {
- return isa<ExtIntType>(CanonicalType);
+inline bool Type::isBitIntType() const {
+ return isa<BitIntType>(CanonicalType);
}
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
@@ -6976,6 +7391,10 @@ inline bool Type::isFloat128Type() const {
return isSpecificBuiltinType(BuiltinType::Float128);
}
+inline bool Type::isIbm128Type() const {
+ return isSpecificBuiltinType(BuiltinType::Ibm128);
+}
+
inline bool Type::isNullPtrType() const {
return isSpecificBuiltinType(BuiltinType::NullPtr);
}
@@ -6993,7 +7412,7 @@ inline bool Type::isIntegerType() const {
return IsEnumDeclComplete(ET->getDecl()) &&
!IsEnumDeclScoped(ET->getDecl());
}
- return isExtIntType();
+ return isBitIntType();
}
inline bool Type::isFixedPointType() const {
@@ -7051,7 +7470,7 @@ inline bool Type::isScalarType() const {
isa<MemberPointerType>(CanonicalType) ||
isa<ComplexType>(CanonicalType) ||
isa<ObjCObjectPointerType>(CanonicalType) ||
- isExtIntType();
+ isBitIntType();
}
inline bool Type::isIntegralOrEnumerationType() const {
@@ -7064,7 +7483,7 @@ inline bool Type::isIntegralOrEnumerationType() const {
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
return IsEnumDeclComplete(ET->getDecl());
- return isExtIntType();
+ return isBitIntType();
}
inline bool Type::isBooleanType() const {
@@ -7126,7 +7545,7 @@ inline const Type *Type::getPointeeOrArrayElementType() const {
/// spaces into a diagnostic with <<.
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
LangAS AS) {
- PD.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
+ PD.AddTaggedVal(llvm::to_underlying(AS),
DiagnosticsEngine::ArgumentKind::ak_addrspace);
return PD;
}
@@ -7144,7 +7563,7 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
/// into a diagnostic with <<.
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
QualType T) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
+ PD.AddTaggedVal(reinterpret_cast<uint64_t>(T.getAsOpaquePtr()),
DiagnosticsEngine::ak_qualtype);
return PD;
}
@@ -7191,6 +7610,8 @@ template <typename T> const T *Type::getAsAdjusted() const {
while (Ty) {
if (const auto *A = dyn_cast<AttributedType>(Ty))
Ty = A->getModifiedType().getTypePtr();
+ else if (const auto *A = dyn_cast<BTFTagAttributedType>(Ty))
+ Ty = A->getWrappedType().getTypePtr();
else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
Ty = E->desugar().getTypePtr();
else if (const auto *P = dyn_cast<ParenType>(Ty))
diff --git a/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h b/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h
index 65e95d52c303..471deb14aba5 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_TYPELOC_H
#define LLVM_CLANG_AST_TYPELOC_H
+#include "clang/AST/ASTConcept.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
@@ -240,6 +241,11 @@ private:
static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
};
+inline TypeSourceInfo::TypeSourceInfo(QualType ty, size_t DataSize) : Ty(ty) {
+ // Init data attached to the object. See getTypeLoc.
+ memset(static_cast<void *>(this + 1), 0, DataSize);
+}
+
/// Return the TypeLoc for a type source info.
inline TypeLoc TypeSourceInfo::getTypeLoc() const {
// TODO: is this alignment already sufficient?
@@ -430,7 +436,7 @@ protected:
unsigned size = sizeof(LocalData);
unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
size = llvm::alignTo(size, extraAlign);
- return reinterpret_cast<char*>(Base::Data) + size;
+ return reinterpret_cast<char *>(Base::Data) + size;
}
void *getNonLocalData() const {
@@ -581,10 +587,9 @@ public:
bool needsExtraLocalData() const {
BuiltinType::Kind bk = getTypePtr()->getKind();
- return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
- || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
- || bk == BuiltinType::UChar
- || bk == BuiltinType::SChar;
+ return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) ||
+ (bk >= BuiltinType::Short && bk <= BuiltinType::Ibm128) ||
+ bk == BuiltinType::UChar || bk == BuiltinType::SChar;
}
unsigned getExtraLocalDataSize() const {
@@ -666,6 +671,16 @@ public:
}
};
+/// Wrapper for source info for types used via transparent aliases.
+class UsingTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ UsingTypeLoc, UsingType> {
+public:
+ QualType getUnderlyingType() const {
+ return getTypePtr()->getUnderlyingType();
+ }
+ UsingShadowDecl *getFoundDecl() const { return getTypePtr()->getFoundDecl(); }
+};
+
/// Wrapper for source info for typedefs.
class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TypedefTypeLoc,
@@ -805,7 +820,7 @@ public:
}
ArrayRef<SourceLocation> getProtocolLocs() const {
- return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
+ return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
@@ -892,6 +907,29 @@ public:
}
};
+struct BTFTagAttributedLocInfo {}; // Nothing.
+
+/// Type source information for an btf_tag attributed type.
+class BTFTagAttributedTypeLoc
+ : public ConcreteTypeLoc<UnqualTypeLoc, BTFTagAttributedTypeLoc,
+ BTFTagAttributedType, BTFTagAttributedLocInfo> {
+public:
+ TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); }
+
+ /// The btf_type_tag attribute.
+ const BTFTypeTagAttr *getAttr() const { return getTypePtr()->getAttr(); }
+
+ template <typename T> T *getAttrAs() {
+ return dyn_cast_or_null<T>(getAttr());
+ }
+
+ SourceRange getLocalSourceRange() const;
+
+ void initializeLocal(ASTContext &Context, SourceLocation loc) {}
+
+ QualType getInnerType() const { return getTypePtr()->getWrappedType(); }
+};
+
struct ObjCObjectTypeLocInfo {
SourceLocation TypeArgsLAngleLoc;
SourceLocation TypeArgsRAngleLoc;
@@ -988,7 +1026,7 @@ public:
ArrayRef<SourceLocation> getProtocolLocs() const {
- return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
+ return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols());
}
bool hasBaseTypeAsWritten() const {
@@ -1415,7 +1453,7 @@ public:
}
ArrayRef<ParmVarDecl *> getParams() const {
- return llvm::makeArrayRef(getParmArray(), getNumParams());
+ return llvm::ArrayRef(getParmArray(), getNumParams());
}
// ParmVarDecls* are stored after Info, one for each parameter.
@@ -1602,7 +1640,7 @@ public:
}
unsigned getNumArgs() const {
- return getTypePtr()->getNumArgs();
+ return getTypePtr()->template_arguments().size();
}
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
@@ -1614,7 +1652,8 @@ public:
}
TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+ return TemplateArgumentLoc(getTypePtr()->template_arguments()[i],
+ getArgLocInfo(i));
}
SourceLocation getTemplateNameLoc() const {
@@ -1649,12 +1688,12 @@ public:
setTemplateNameLoc(Loc);
setLAngleLoc(Loc);
setRAngleLoc(Loc);
- initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
+ initializeArgLocs(Context, getTypePtr()->template_arguments(),
getArgInfos(), Loc);
}
- static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
- const TemplateArgument *Args,
+ static void initializeArgLocs(ASTContext &Context,
+ ArrayRef<TemplateArgument> Args,
TemplateArgumentLocInfo *ArgInfos,
SourceLocation Loc);
@@ -1902,7 +1941,7 @@ struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
};
struct TypeOfTypeLocInfo : public TypeofLocInfo {
- TypeSourceInfo* UnderlyingTInfo;
+ TypeSourceInfo *UnmodifiedTInfo;
};
template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
@@ -1970,27 +2009,50 @@ public:
class TypeOfTypeLoc
: public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
public:
- QualType getUnderlyingType() const {
- return this->getTypePtr()->getUnderlyingType();
+ QualType getUnmodifiedType() const {
+ return this->getTypePtr()->getUnmodifiedType();
}
- TypeSourceInfo* getUnderlyingTInfo() const {
- return this->getLocalData()->UnderlyingTInfo;
+ TypeSourceInfo *getUnmodifiedTInfo() const {
+ return this->getLocalData()->UnmodifiedTInfo;
}
- void setUnderlyingTInfo(TypeSourceInfo* TI) const {
- this->getLocalData()->UnderlyingTInfo = TI;
+ void setUnmodifiedTInfo(TypeSourceInfo *TI) const {
+ this->getLocalData()->UnmodifiedTInfo = TI;
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
-// FIXME: location of the 'decltype' and parens.
-class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- DecltypeTypeLoc,
- DecltypeType> {
+// decltype(expression) abc;
+// ~~~~~~~~ DecltypeLoc
+// ~ RParenLoc
+// FIXME: add LParenLoc, it is tricky to support due to the limitation of
+// annotated-decltype token.
+struct DecltypeTypeLocInfo {
+ SourceLocation DecltypeLoc;
+ SourceLocation RParenLoc;
+};
+class DecltypeTypeLoc
+ : public ConcreteTypeLoc<UnqualTypeLoc, DecltypeTypeLoc, DecltypeType,
+ DecltypeTypeLocInfo> {
public:
Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
+
+ SourceLocation getDecltypeLoc() const { return getLocalData()->DecltypeLoc; }
+ void setDecltypeLoc(SourceLocation Loc) { getLocalData()->DecltypeLoc = Loc; }
+
+ SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
+ void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
+
+ SourceRange getLocalSourceRange() const {
+ return SourceRange(getDecltypeLoc(), getRParenLoc());
+ }
+
+ void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+ setDecltypeLoc(Loc);
+ setRParenLoc(Loc);
+ }
};
struct UnaryTransformTypeLocInfo {
@@ -2043,12 +2105,10 @@ class DeducedTypeLoc
DeducedType> {};
struct AutoTypeLocInfo : TypeSpecLocInfo {
- NestedNameSpecifierLoc NestedNameSpec;
- SourceLocation TemplateKWLoc;
- SourceLocation ConceptNameLoc;
- NamedDecl *FoundDecl;
- SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
+ // For decltype(auto).
+ SourceLocation RParenLoc;
+
+ ConceptReference *CR = nullptr;
};
class AutoTypeLoc
@@ -2061,96 +2121,95 @@ public:
return getTypePtr()->getKeyword();
}
+ bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); }
+ SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
+ void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
+
bool isConstrained() const {
return getTypePtr()->isConstrained();
}
- const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
- return getLocalData()->NestedNameSpec;
- }
+ void setConceptReference(ConceptReference *CR) { getLocalData()->CR = CR; }
- void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
- getLocalData()->NestedNameSpec = NNS;
- }
+ ConceptReference *getConceptReference() const { return getLocalData()->CR; }
- SourceLocation getTemplateKWLoc() const {
- return getLocalData()->TemplateKWLoc;
+ // FIXME: Several of the following functions can be removed. Instead the
+ // caller can directly work with the ConceptReference.
+ const NestedNameSpecifierLoc getNestedNameSpecifierLoc() const {
+ if (const auto *CR = getConceptReference())
+ return CR->getNestedNameSpecifierLoc();
+ return NestedNameSpecifierLoc();
}
- void setTemplateKWLoc(SourceLocation Loc) {
- getLocalData()->TemplateKWLoc = Loc;
+ SourceLocation getTemplateKWLoc() const {
+ if (const auto *CR = getConceptReference())
+ return CR->getTemplateKWLoc();
+ return SourceLocation();
}
SourceLocation getConceptNameLoc() const {
- return getLocalData()->ConceptNameLoc;
- }
-
- void setConceptNameLoc(SourceLocation Loc) {
- getLocalData()->ConceptNameLoc = Loc;
+ if (const auto *CR = getConceptReference())
+ return CR->getConceptNameLoc();
+ return SourceLocation();
}
NamedDecl *getFoundDecl() const {
- return getLocalData()->FoundDecl;
- }
-
- void setFoundDecl(NamedDecl *D) {
- getLocalData()->FoundDecl = D;
+ if (const auto *CR = getConceptReference())
+ return CR->getFoundDecl();
+ return nullptr;
}
ConceptDecl *getNamedConcept() const {
- return getTypePtr()->getTypeConstraintConcept();
+ if (const auto *CR = getConceptReference())
+ return CR->getNamedConcept();
+ return nullptr;
}
- DeclarationNameInfo getConceptNameInfo() const;
+ DeclarationNameInfo getConceptNameInfo() const {
+ return getConceptReference()->getConceptNameInfo();
+ }
bool hasExplicitTemplateArgs() const {
- return getLocalData()->LAngleLoc.isValid();
+ return (getConceptReference() &&
+ getConceptReference()->getTemplateArgsAsWritten() &&
+ getConceptReference()
+ ->getTemplateArgsAsWritten()
+ ->getLAngleLoc()
+ .isValid());
}
SourceLocation getLAngleLoc() const {
- return this->getLocalData()->LAngleLoc;
- }
-
- void setLAngleLoc(SourceLocation Loc) {
- this->getLocalData()->LAngleLoc = Loc;
+ if (const auto *CR = getConceptReference())
+ if (const auto *TAAW = CR->getTemplateArgsAsWritten())
+ return TAAW->getLAngleLoc();
+ return SourceLocation();
}
SourceLocation getRAngleLoc() const {
- return this->getLocalData()->RAngleLoc;
- }
-
- void setRAngleLoc(SourceLocation Loc) {
- this->getLocalData()->RAngleLoc = Loc;
+ if (const auto *CR = getConceptReference())
+ if (const auto *TAAW = CR->getTemplateArgsAsWritten())
+ return TAAW->getRAngleLoc();
+ return SourceLocation();
}
unsigned getNumArgs() const {
- return getTypePtr()->getNumArgs();
- }
-
- void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
- getArgInfos()[i] = AI;
- }
-
- TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
- return getArgInfos()[i];
+ return getTypePtr()->getTypeConstraintArguments().size();
}
TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i],
- getArgLocInfo(i));
+ const auto *CR = getConceptReference();
+ assert(CR && "No ConceptReference");
+ return CR->getTemplateArgsAsWritten()->getTemplateArgs()[i];
}
SourceRange getLocalSourceRange() const {
- return{
- isConstrained()
- ? (getNestedNameSpecifierLoc()
- ? getNestedNameSpecifierLoc().getBeginLoc()
- : (getTemplateKWLoc().isValid()
- ? getTemplateKWLoc()
- : getConceptNameLoc()))
- : getNameLoc(),
- getNameLoc()
- };
+ return {isConstrained()
+ ? (getNestedNameSpecifierLoc()
+ ? getNestedNameSpecifierLoc().getBeginLoc()
+ : (getTemplateKWLoc().isValid() ? getTemplateKWLoc()
+ : getConceptNameLoc()))
+ : getNameLoc(),
+ isDecltypeAuto() ? getRParenLoc() : getNameLoc()};
}
void copy(AutoTypeLoc Loc) {
@@ -2160,19 +2219,6 @@ public:
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- unsigned getExtraLocalDataSize() const {
- return getNumArgs() * sizeof(TemplateArgumentLocInfo);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return alignof(TemplateArgumentLocInfo);
- }
-
-private:
- TemplateArgumentLocInfo *getArgInfos() const {
- return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
- }
};
class DeducedTemplateSpecializationTypeLoc
@@ -2202,22 +2248,31 @@ class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ElaboratedLocInfo> {
public:
SourceLocation getElaboratedKeywordLoc() const {
- return this->getLocalData()->ElaboratedKWLoc;
+ return !isEmpty() ? getLocalData()->ElaboratedKWLoc : SourceLocation();
}
void setElaboratedKeywordLoc(SourceLocation Loc) {
- this->getLocalData()->ElaboratedKWLoc = Loc;
+ if (isEmpty()) {
+ assert(Loc.isInvalid());
+ return;
+ }
+ getLocalData()->ElaboratedKWLoc = Loc;
}
NestedNameSpecifierLoc getQualifierLoc() const {
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
+ return !isEmpty() ? NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
+ getLocalData()->QualifierData)
+ : NestedNameSpecifierLoc();
}
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- assert(QualifierLoc.getNestedNameSpecifier()
- == getTypePtr()->getQualifier() &&
+ assert(QualifierLoc.getNestedNameSpecifier() ==
+ getTypePtr()->getQualifier() &&
"Inconsistent nested-name-specifier pointer");
+ if (isEmpty()) {
+ assert(!QualifierLoc.hasQualifier());
+ return;
+ }
getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
@@ -2234,12 +2289,24 @@ public:
void initializeLocal(ASTContext &Context, SourceLocation Loc);
- TypeLoc getNamedTypeLoc() const {
- return getInnerTypeLoc();
+ TypeLoc getNamedTypeLoc() const { return getInnerTypeLoc(); }
+
+ QualType getInnerType() const { return getTypePtr()->getNamedType(); }
+
+ bool isEmpty() const {
+ return getTypePtr()->getKeyword() == ElaboratedTypeKeyword::None &&
+ !getTypePtr()->getQualifier();
}
- QualType getInnerType() const {
- return getTypePtr()->getNamedType();
+ unsigned getLocalDataAlignment() const {
+ // FIXME: We want to return 1 here in the empty case, but
+ // there are bugs in how alignment is handled in TypeLocs
+ // that prevent this from working.
+ return ConcreteTypeLoc::getLocalDataAlignment();
+ }
+
+ unsigned getLocalDataSize() const {
+ return !isEmpty() ? ConcreteTypeLoc::getLocalDataSize() : 0;
}
void copy(ElaboratedTypeLoc Loc) {
@@ -2382,7 +2449,7 @@ public:
}
unsigned getNumArgs() const {
- return getTypePtr()->getNumArgs();
+ return getTypePtr()->template_arguments().size();
}
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
@@ -2394,7 +2461,8 @@ public:
}
TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+ return TemplateArgumentLoc(getTypePtr()->template_arguments()[i],
+ getArgLocInfo(i));
}
SourceRange getLocalSourceRange() const {
@@ -2551,6 +2619,8 @@ inline T TypeLoc::getAsAdjusted() const {
Cur = PTL.getInnerLoc();
else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
Cur = ATL.getModifiedLoc();
+ else if (auto ATL = Cur.getAs<BTFTagAttributedTypeLoc>())
+ Cur = ATL.getWrappedLoc();
else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
Cur = ETL.getNamedTypeLoc();
else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
@@ -2562,12 +2632,28 @@ inline T TypeLoc::getAsAdjusted() const {
}
return Cur.getAs<T>();
}
-class ExtIntTypeLoc final
- : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ExtIntTypeLoc,
- ExtIntType> {};
-class DependentExtIntTypeLoc final
- : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentExtIntTypeLoc,
- DependentExtIntType> {};
+class BitIntTypeLoc final
+ : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, BitIntTypeLoc,
+ BitIntType> {};
+class DependentBitIntTypeLoc final
+ : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentBitIntTypeLoc,
+ DependentBitIntType> {};
+
+class ObjCProtocolLoc {
+ ObjCProtocolDecl *Protocol = nullptr;
+ SourceLocation Loc = SourceLocation();
+
+public:
+ ObjCProtocolLoc(ObjCProtocolDecl *protocol, SourceLocation loc)
+ : Protocol(protocol), Loc(loc) {}
+ ObjCProtocolDecl *getProtocol() const { return Protocol; }
+ SourceLocation getLocation() const { return Loc; }
+
+ /// The source range is just the protocol name.
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return SourceRange(Loc, Loc);
+ }
+};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/TypeOrdering.h b/contrib/llvm-project/clang/include/clang/AST/TypeOrdering.h
index 6630105136f5..8037f98cc965 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TypeOrdering.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TypeOrdering.h
@@ -34,7 +34,6 @@ struct QualTypeOrdering {
}
namespace llvm {
- template<class> struct DenseMapInfo;
template<> struct DenseMapInfo<clang::QualType> {
static inline clang::QualType getEmptyKey() { return clang::QualType(); }
diff --git a/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td b/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td
index 438d5af5a2e2..682c869b0c58 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td
+++ b/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td
@@ -11,7 +11,7 @@ include "clang/Basic/TypeNodes.td"
let Class = ComplexType in {
def : Property<"elementType", QualType> {
- let Read = [{ node->getElementType() }];
+ let Read = [{ node->getElementType() }];
}
def : Creator<[{ return ctx.getComplexType(elementType); }]>;
@@ -323,6 +323,9 @@ let Class = FunctionProtoType in {
? node->getExtParameterInfos()
: llvm::ArrayRef<FunctionProtoType::ExtParameterInfo>() }];
}
+ def : Property<"AArch64SMEAttributes", UInt32> {
+ let Read = [{ node->getAArch64SMEAttributes() }];
+ }
def : Creator<[{
auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm,
@@ -338,6 +341,7 @@ let Class = FunctionProtoType in {
epi.ExceptionSpec = exceptionSpecifier;
epi.ExtParameterInfos =
extParameterInfo.empty() ? nullptr : extParameterInfo.data();
+ epi.AArch64SMEAttributes = AArch64SMEAttributes;
return ctx.getFunctionType(returnType, parameters, epi);
}]>;
}
@@ -358,7 +362,20 @@ let Class = UnresolvedUsingType in {
}
def : Creator<[{
- return ctx.getTypeDeclType(cast<UnresolvedUsingTypenameDecl>(declaration));
+ return ctx.getUnresolvedUsingType(cast<UnresolvedUsingTypenameDecl>(declaration));
+ }]>;
+}
+
+let Class = UsingType in {
+ def : Property<"foundDeclaration", UsingShadowDeclRef> {
+ let Read = [{ node->getFoundDecl() }];
+ }
+ def : Property<"underlyingType", QualType> {
+ let Read = [{ node->getUnderlyingType() }];
+ }
+
+ def : Creator<[{
+ return ctx.getUsingType(foundDeclaration, underlyingType);
}]>;
}
@@ -366,16 +383,12 @@ let Class = TypedefType in {
def : Property<"declaration", DeclRef> {
let Read = [{ node->getDecl() }];
}
- def : Property<"canonicalType", Optional<QualType>> {
- let Read = [{ makeOptionalFromNullable(node->getCanonicalTypeInternal()) }];
+ def : Property<"underlyingType", QualType> {
+ let Read = [{ node->desugar() }];
}
def : Creator<[{
- QualType finalCanonicalType =
- canonicalType ? ctx.getCanonicalType(*canonicalType)
- : QualType();
- return ctx.getTypedefType(cast<TypedefNameDecl>(declaration),
- finalCanonicalType);
+ return ctx.getTypedefType(cast<TypedefNameDecl>(declaration), underlyingType);
}]>;
}
@@ -384,18 +397,26 @@ let Class = TypeOfExprType in {
let Read = [{ node->getUnderlyingExpr() }];
}
+ def : Property<"kind", TypeOfKind> {
+ let Read = [{ node->getKind() }];
+ }
+
def : Creator<[{
- return ctx.getTypeOfExprType(expression);
+ return ctx.getTypeOfExprType(expression, kind);
}]>;
}
let Class = TypeOfType in {
- def : Property<"underlyingType", QualType> {
- let Read = [{ node->getUnderlyingType() }];
+ def : Property<"unmodifiedType", QualType> {
+ let Read = [{ node->getUnmodifiedType() }];
+ }
+
+ def : Property<"kind", TypeOfKind> {
+ let Read = [{ node->getKind() }];
}
def : Creator<[{
- return ctx.getTypeOfType(underlyingType);
+ return ctx.getTypeOfType(unmodifiedType, kind);
}]>;
}
@@ -574,7 +595,7 @@ let Class = ParenType in {
def : Creator<[{
return ctx.getParenType(innerType);
- }]>;
+ }]>;
}
let Class = MacroQualifiedType in {
@@ -606,6 +627,19 @@ let Class = AttributedType in {
}]>;
}
+let Class = BTFTagAttributedType in {
+ def : Property<"attr", BTFTypeTagAttr> {
+ let Read = [{ node->getAttr() }];
+ }
+ def : Property<"wrappedType", QualType> {
+ let Read = [{ node->getWrappedType() }];
+ }
+
+ def : Creator<[{
+ return ctx.getBTFTagAttributedType(attr, wrappedType);
+ }]>;
+}
+
let Class = DependentAddressSpaceType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
@@ -636,16 +670,16 @@ let Class = TemplateSpecializationType in {
def : Property<"underlyingType", Optional<QualType>> {
let Read = [{
node->isTypeAlias()
- ? llvm::Optional<QualType>(node->getAliasedType())
+ ? std::optional<QualType>(node->getAliasedType())
: node->isCanonicalUnqualified()
- ? llvm::None
- : llvm::Optional<QualType>(node->getCanonicalTypeInternal())
+ ? std::nullopt
+ : std::optional<QualType>(node->getCanonicalTypeInternal())
}];
}
def : Creator<[{
QualType result;
- if (!underlyingType.hasValue()) {
+ if (!underlyingType) {
result = ctx.getCanonicalTemplateSpecializationType(templateName,
templateArguments);
} else {
@@ -702,18 +736,23 @@ let Class = TemplateTypeParmType in {
}
let Class = SubstTemplateTypeParmType in {
- def : Property<"replacedParameter", QualType> {
- let Read = [{ QualType(node->getReplacedParameter(), 0) }];
- }
def : Property<"replacementType", QualType> {
let Read = [{ node->getReplacementType() }];
}
+ def : Property<"associatedDecl", DeclRef> {
+ let Read = [{ node->getAssociatedDecl() }];
+ }
+ def : Property<"Index", UInt32> {
+ let Read = [{ node->getIndex() }];
+ }
+ def : Property<"PackIndex", Optional<UInt32>> {
+ let Read = [{ node->getPackIndex() }];
+ }
+ // The call to getCanonicalType here existed in ASTReader.cpp, too.
def : Creator<[{
- // The call to getCanonicalType here existed in ASTReader.cpp, too.
return ctx.getSubstTemplateTypeParmType(
- cast<TemplateTypeParmType>(replacedParameter),
- ctx.getCanonicalType(replacementType));
+ replacementType, associatedDecl, Index, PackIndex);
}]>;
}
@@ -732,8 +771,14 @@ let Class = PackExpansionType in {
}
let Class = SubstTemplateTypeParmPackType in {
- def : Property<"replacedParameter", QualType> {
- let Read = [{ QualType(node->getReplacedParameter(), 0) }];
+ def : Property<"associatedDecl", DeclRef> {
+ let Read = [{ node->getAssociatedDecl() }];
+ }
+ def : Property<"Index", UInt32> {
+ let Read = [{ node->getIndex() }];
+ }
+ def : Property<"Final", Bool> {
+ let Read = [{ node->getFinal() }];
}
def : Property<"replacementPack", TemplateArgument> {
let Read = [{ node->getArgumentPack() }];
@@ -741,8 +786,7 @@ let Class = SubstTemplateTypeParmPackType in {
def : Creator<[{
return ctx.getSubstTemplateTypeParmPackType(
- cast<TemplateTypeParmType>(replacedParameter),
- replacementPack);
+ associatedDecl, Index, Final, replacementPack);
}]>;
}
@@ -773,6 +817,10 @@ let Class = BuiltinType in {
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(NAME, ID, SINGLETON_ID) \
+ case BuiltinType::ID: return ctx.SINGLETON_ID;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+
#define BUILTIN_TYPE(ID, SINGLETON_ID) \
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/AST/BuiltinTypes.def"
@@ -794,8 +842,8 @@ let Class = DependentNameType in {
def : Property<"underlyingType", Optional<QualType>> {
let Read = [{
node->isCanonicalUnqualified()
- ? llvm::None
- : llvm::Optional<QualType>(node->getCanonicalTypeInternal())
+ ? std::nullopt
+ : std::optional<QualType>(node->getCanonicalTypeInternal())
}];
}
@@ -849,7 +897,7 @@ let Class = ObjCInterfaceType in {
let Class = ObjCTypeParamType in {
def : Property<"declaration", ObjCTypeParamDeclRef> {
let Read = [{ node->getDecl() }];
- }
+ }
def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
let Read = [{ node->getProtocols() }];
}
@@ -882,7 +930,7 @@ let Class = PipeType in {
}]>;
}
-let Class = ExtIntType in {
+let Class = BitIntType in {
def : Property<"isUnsigned", Bool> {
let Read = [{ node->isUnsigned() }];
}
@@ -891,11 +939,11 @@ let Class = ExtIntType in {
}
def : Creator<[{
- return ctx.getExtIntType(isUnsigned, numBits);
+ return ctx.getBitIntType(isUnsigned, numBits);
}]>;
}
-let Class = DependentExtIntType in {
+let Class = DependentBitIntType in {
def : Property<"isUnsigned", Bool> {
let Read = [{ node->isUnsigned() }];
}
@@ -903,6 +951,6 @@ let Class = DependentExtIntType in {
let Read = [{ node->getNumBitsExpr() }];
}
def : Creator<[{
- return ctx.getDependentExtIntType(isUnsigned, numBitsExpr);
+ return ctx.getDependentBitIntType(isUnsigned, numBitsExpr);
}]>;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h b/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h
index c75aa0785a63..ee31be969b6e 100644
--- a/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h
+++ b/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h
@@ -114,14 +114,22 @@ public:
I.I->set(New, AS);
}
- void erase(unsigned I) { decls()[I] = decls().pop_back_val(); }
+ void erase(unsigned I) {
+ auto val = decls().pop_back_val();
+ if (I < size())
+ decls()[I] = val;
+ }
- void erase(iterator I) { *I.I = decls().pop_back_val(); }
+ void erase(iterator I) {
+ auto val = decls().pop_back_val();
+ if (I != end())
+ *I.I = val;
+ }
void setAccess(iterator I, AccessSpecifier AS) { I.I->setAccess(AS); }
void clear() { decls().clear(); }
- void set_size(unsigned N) { decls().set_size(N); }
+ void truncate(unsigned N) { decls().truncate(N); }
bool empty() const { return decls().empty(); }
unsigned size() const { return decls().size(); }
diff --git a/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h b/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h
index e451f3f861b7..fbf6c041a1ec 100644
--- a/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h
+++ b/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h
@@ -279,7 +279,7 @@ public:
AddressPointLocation getAddressPoint(BaseSubobject Base) const {
assert(AddressPoints.count(Base) && "Did not find address point!");
- return AddressPoints.find(Base)->second;
+ return AddressPoints.lookup(Base);
}
const AddressPointsMapTy &getAddressPoints() const {
@@ -563,8 +563,6 @@ private:
llvm::DenseMap<const CXXRecordDecl *, std::unique_ptr<VirtualBaseInfo>>
VBaseInfo;
- void enumerateVFPtrs(const CXXRecordDecl *ForClass, VPtrInfoVector &Result);
-
void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
void dumpMethodLocations(const CXXRecordDecl *RD,