summaryrefslogtreecommitdiff
path: root/clang/include
diff options
context:
space:
mode:
authorMichael Kruse <llvm-project@meinersbur.de>2025-01-03 10:22:51 +0100
committerMichael Kruse <llvm-project@meinersbur.de>2025-01-03 10:22:51 +0100
commit38500d63e14ce340236840f60d356cdefb56a52c (patch)
tree17edbec446ce9b50d2f215a483b83afb293a635d /clang/include
parent1a3d5daaef7a6a63448a497da3eff7fc9e23df26 (diff)
parent27f30029741ecf023baece7b3dde1ff9011ffefc (diff)
Merge branch 'main' into users/meinersbur/flang_runtime_split-headersusers/meinersbur/flang_runtime_split-headers
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang-c/CXString.h4
-rw-r--r--clang/include/clang-c/Index.h32
-rw-r--r--clang/include/clang/APINotes/Types.h6
-rw-r--r--clang/include/clang/AST/APValue.h6
-rw-r--r--clang/include/clang/AST/ASTContext.h6
-rw-r--r--clang/include/clang/AST/ASTNodeTraverser.h12
-rw-r--r--clang/include/clang/AST/Attr.h1
-rw-r--r--clang/include/clang/AST/Decl.h32
-rw-r--r--clang/include/clang/AST/DeclBase.h14
-rw-r--r--clang/include/clang/AST/DeclCXX.h16
-rw-r--r--clang/include/clang/AST/DeclContextInternals.h10
-rw-r--r--clang/include/clang/AST/DeclTemplate.h50
-rw-r--r--clang/include/clang/AST/ExprCXX.h42
-rw-r--r--clang/include/clang/AST/ExprConcepts.h16
-rw-r--r--clang/include/clang/AST/ExprObjC.h20
-rw-r--r--clang/include/clang/AST/ExternalASTSource.h23
-rw-r--r--clang/include/clang/AST/OpenACCClause.h185
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h24
-rw-r--r--clang/include/clang/AST/Redeclarable.h28
-rw-r--r--clang/include/clang/AST/Stmt.h5
-rw-r--r--clang/include/clang/AST/StmtOpenACC.h388
-rw-r--r--clang/include/clang/AST/TemplateBase.h6
-rw-r--r--clang/include/clang/AST/TextNodeDumper.h7
-rw-r--r--clang/include/clang/AST/Type.h8
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchers.h20
-rw-r--r--clang/include/clang/Analysis/Analyses/ThreadSafety.h36
-rw-r--r--clang/include/clang/Analysis/FlowSensitive/SmartPointerAccessorCaching.h63
-rw-r--r--clang/include/clang/Basic/Attr.td15
-rw-r--r--clang/include/clang/Basic/AttrDocs.td11
-rw-r--r--clang/include/clang/Basic/Builtins.h4
-rw-r--r--clang/include/clang/Basic/Builtins.td14
-rw-r--r--clang/include/clang/Basic/BuiltinsHexagon.def16
-rw-r--r--clang/include/clang/Basic/CodeGenOptions.h6
-rw-r--r--clang/include/clang/Basic/Diagnostic.h5
-rw-r--r--clang/include/clang/Basic/DiagnosticDriverKinds.td2
-rw-r--r--clang/include/clang/Basic/DiagnosticParseKinds.td3
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td81
-rw-r--r--clang/include/clang/Basic/Features.def1
-rw-r--r--clang/include/clang/Basic/FileEntry.h13
-rw-r--r--clang/include/clang/Basic/IdentifierTable.h4
-rw-r--r--clang/include/clang/Basic/OpenACCClauses.def6
-rw-r--r--clang/include/clang/Basic/OpenACCKinds.h8
-rw-r--r--clang/include/clang/Basic/Sanitizers.def3
-rw-r--r--clang/include/clang/Basic/StmtNodes.td7
-rw-r--r--clang/include/clang/Basic/TargetInfo.h10
-rw-r--r--clang/include/clang/Basic/arm_immcheck_incl.td10
-rw-r--r--clang/include/clang/Basic/arm_mve.td10
-rw-r--r--clang/include/clang/Basic/arm_sme.td80
-rw-r--r--clang/include/clang/Basic/arm_sve.td95
-rw-r--r--clang/include/clang/Basic/arm_sve_sme_incl.td4
-rw-r--r--clang/include/clang/CIR/CIRGenerator.h6
-rw-r--r--clang/include/clang/CIR/CMakeLists.txt1
-rw-r--r--clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h44
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRAttrs.h36
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRAttrs.td142
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRDialect.h1
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIROps.td85
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRTypes.h34
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRTypes.td361
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CMakeLists.txt3
-rw-r--r--clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h22
-rw-r--r--clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td56
-rw-r--r--clang/include/clang/CIR/Interfaces/CMakeLists.txt14
-rw-r--r--clang/include/clang/Driver/Driver.h7
-rw-r--r--clang/include/clang/Driver/Options.td63
-rw-r--r--clang/include/clang/Driver/SanitizerArgs.h3
-rw-r--r--clang/include/clang/Format/Format.h53
-rw-r--r--clang/include/clang/Frontend/Utils.h1
-rw-r--r--clang/include/clang/Lex/PreprocessingRecord.h4
-rw-r--r--clang/include/clang/Lex/Preprocessor.h6
-rw-r--r--clang/include/clang/Parse/Parser.h15
-rw-r--r--clang/include/clang/Sema/MultiplexExternalSemaSource.h6
-rw-r--r--clang/include/clang/Sema/ParsedAttr.h10
-rw-r--r--clang/include/clang/Sema/Sema.h7
-rw-r--r--clang/include/clang/Sema/SemaConcept.h39
-rw-r--r--clang/include/clang/Sema/SemaHLSL.h1
-rw-r--r--clang/include/clang/Sema/SemaInternal.h2
-rw-r--r--clang/include/clang/Sema/SemaOpenACC.h57
-rw-r--r--clang/include/clang/Sema/Template.h6
-rw-r--r--clang/include/clang/Serialization/ASTBitCodes.h28
-rw-r--r--clang/include/clang/Serialization/ASTReader.h65
-rw-r--r--clang/include/clang/Serialization/ASTWriter.h41
-rw-r--r--clang/include/clang/StaticAnalyzer/Checkers/Checkers.td4
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def19
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h64
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h60
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h8
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h18
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h2
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h1
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h13
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h7
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h15
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h16
-rw-r--r--clang/include/module.modulemap7
95 files changed, 2509 insertions, 412 deletions
diff --git a/clang/include/clang-c/CXString.h b/clang/include/clang-c/CXString.h
index f117010c71a4..63dce4d140ce 100644
--- a/clang/include/clang-c/CXString.h
+++ b/clang/include/clang-c/CXString.h
@@ -46,6 +46,10 @@ typedef struct {
/**
* Retrieve the character data associated with the given string.
+ *
+ * The returned data is a reference and not owned by the user. This data
+ * is only valid while the `CXString` is valid. This function is similar
+ * to `std::string::c_str()`.
*/
CINDEX_LINKAGE const char *clang_getCString(CXString string);
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 8fc06328f0bc..dfc562da88af 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2166,9 +2166,39 @@ enum CXCursorKind {
*/
CXCursor_OpenACCLoopConstruct = 321,
+ /** OpenACC Combined Constructs.
+ */
CXCursor_OpenACCCombinedConstruct = 322,
- CXCursor_LastStmt = CXCursor_OpenACCCombinedConstruct,
+ /** OpenACC data Construct.
+ */
+ CXCursor_OpenACCDataConstruct = 323,
+
+ /** OpenACC enter data Construct.
+ */
+ CXCursor_OpenACCEnterDataConstruct = 324,
+
+ /** OpenACC exit data Construct.
+ */
+ CXCursor_OpenACCExitDataConstruct = 325,
+
+ /** OpenACC host_data Construct.
+ */
+ CXCursor_OpenACCHostDataConstruct = 326,
+
+ /** OpenACC wait Construct.
+ */
+ CXCursor_OpenACCWaitConstruct = 327,
+
+ /** OpenACC init Construct.
+ */
+ CXCursor_OpenACCInitConstruct = 328,
+
+ /** OpenACC shutdown Construct.
+ */
+ CXCursor_OpenACCShutdownConstruct = 329,
+
+ CXCursor_LastStmt = CXCursor_OpenACCShutdownConstruct,
/**
* Cursor that represents the translation unit itself.
diff --git a/clang/include/clang/APINotes/Types.h b/clang/include/clang/APINotes/Types.h
index ff374ad3ada0..9c01978fd49e 100644
--- a/clang/include/clang/APINotes/Types.h
+++ b/clang/include/clang/APINotes/Types.h
@@ -542,6 +542,9 @@ public:
/// The result type of this function, as a C type.
std::string ResultType;
+ /// Ownership convention for return value
+ std::string SwiftReturnOwnership;
+
/// The function parameters.
std::vector<ParamInfo> Params;
@@ -622,7 +625,8 @@ inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) {
LHS.NumAdjustedNullable == RHS.NumAdjustedNullable &&
LHS.NullabilityPayload == RHS.NullabilityPayload &&
LHS.ResultType == RHS.ResultType && LHS.Params == RHS.Params &&
- LHS.RawRetainCountConvention == RHS.RawRetainCountConvention;
+ LHS.RawRetainCountConvention == RHS.RawRetainCountConvention &&
+ LHS.SwiftReturnOwnership == RHS.SwiftReturnOwnership;
}
inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {
diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h
index 7869ee386689..4401f3a8ff48 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -157,11 +157,9 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const;
- template <class T>
- bool is() const { return Ptr.is<T>(); }
+ template <class T> bool is() const { return isa<T>(Ptr); }
- template <class T>
- T get() const { return Ptr.get<T>(); }
+ template <class T> T get() const { return cast<T>(Ptr); }
template <class T>
T dyn_cast() const { return Ptr.dyn_cast<T>(); }
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 89fcb6789d88..1e89a6805ce9 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -245,7 +245,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
mutable llvm::FoldingSet<DependentUnaryTransformType>
DependentUnaryTransformTypes;
- mutable llvm::ContextualFoldingSet<AutoType, ASTContext&> AutoTypes;
+ // An AutoType can have a dependency on another AutoType via its template
+ // arguments. Since both dependent and dependency are on the same set,
+ // we can end up in an infinite recursion when looking for a node if we used
+ // a `FoldingSet`, since both could end up in the same bucket.
+ mutable llvm::DenseMap<llvm::FoldingSetNodeID, AutoType *> AutoTypes;
mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
DeducedTemplateSpecializationTypes;
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index 3d63d581a9be..f5652b295de1 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -159,7 +159,7 @@ public:
// Some statements have custom mechanisms for dumping their children.
if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S) ||
- isa<RequiresExpr>(S))
+ isa<RequiresExpr>(S) || isa<OpenACCWaitConstruct>(S))
return;
if (Traversal == TK_IgnoreUnlessSpelledInSource &&
@@ -825,6 +825,16 @@ public:
Visit(C);
}
+ void VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *Node) {
+ // Needs custom child checking to put clauses AFTER the children, which are
+ // the expressions in the 'wait' construct. Others likely need this as well,
+ // and might need to do the associated statement after it.
+ for (const Stmt *S : Node->children())
+ Visit(S);
+ for (const auto *C : Node->clauses())
+ Visit(C);
+ }
+
void VisitInitListExpr(const InitListExpr *ILE) {
if (auto *Filler = ILE->getArrayFiller()) {
Visit(Filler, "array_filler");
diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h
index 725498e132fc..3365ebe4d901 100644
--- a/clang/include/clang/AST/Attr.h
+++ b/clang/include/clang/AST/Attr.h
@@ -24,6 +24,7 @@
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Support/Compiler.h"
#include "llvm/Frontend/HLSL/HLSLResource.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 8c39ef3d5a9f..67ee0bb41269 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -747,9 +747,9 @@ class DeclaratorDecl : public ValueDecl {
/// ignoring outer template declarations.
SourceLocation InnerLocStart;
- bool hasExtInfo() const { return DeclInfo.is<ExtInfo*>(); }
- ExtInfo *getExtInfo() { return DeclInfo.get<ExtInfo*>(); }
- const ExtInfo *getExtInfo() const { return DeclInfo.get<ExtInfo*>(); }
+ bool hasExtInfo() const { return isa<ExtInfo *>(DeclInfo); }
+ ExtInfo *getExtInfo() { return cast<ExtInfo *>(DeclInfo); }
+ const ExtInfo *getExtInfo() const { return cast<ExtInfo *>(DeclInfo); }
protected:
DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -762,9 +762,8 @@ public:
friend class ASTDeclWriter;
TypeSourceInfo *getTypeSourceInfo() const {
- return hasExtInfo()
- ? getExtInfo()->TInfo
- : DeclInfo.get<TypeSourceInfo*>();
+ return hasExtInfo() ? getExtInfo()->TInfo
+ : cast<TypeSourceInfo *>(DeclInfo);
}
void setTypeSourceInfo(TypeSourceInfo *TI) {
@@ -3458,18 +3457,17 @@ public:
using redeclarable_base::isFirstDecl;
bool isModed() const {
- return MaybeModedTInfo.getPointer().is<ModedTInfo *>();
+ return isa<ModedTInfo *>(MaybeModedTInfo.getPointer());
}
TypeSourceInfo *getTypeSourceInfo() const {
- return isModed() ? MaybeModedTInfo.getPointer().get<ModedTInfo *>()->first
- : MaybeModedTInfo.getPointer().get<TypeSourceInfo *>();
+ return isModed() ? cast<ModedTInfo *>(MaybeModedTInfo.getPointer())->first
+ : cast<TypeSourceInfo *>(MaybeModedTInfo.getPointer());
}
QualType getUnderlyingType() const {
- return isModed() ? MaybeModedTInfo.getPointer().get<ModedTInfo *>()->second
- : MaybeModedTInfo.getPointer()
- .get<TypeSourceInfo *>()
+ return isModed() ? cast<ModedTInfo *>(MaybeModedTInfo.getPointer())->second
+ : cast<TypeSourceInfo *>(MaybeModedTInfo.getPointer())
->getType();
}
@@ -3587,10 +3585,10 @@ private:
/// otherwise, it is a null (TypedefNameDecl) pointer.
llvm::PointerUnion<TypedefNameDecl *, ExtInfo *> TypedefNameDeclOrQualifier;
- bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo *>(); }
- ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo *>(); }
+ bool hasExtInfo() const { return isa<ExtInfo *>(TypedefNameDeclOrQualifier); }
+ ExtInfo *getExtInfo() { return cast<ExtInfo *>(TypedefNameDeclOrQualifier); }
const ExtInfo *getExtInfo() const {
- return TypedefNameDeclOrQualifier.get<ExtInfo *>();
+ return cast<ExtInfo *>(TypedefNameDeclOrQualifier);
}
protected:
@@ -3793,7 +3791,7 @@ public:
TypedefNameDecl *getTypedefNameForAnonDecl() const {
return hasExtInfo() ? nullptr
- : TypedefNameDeclOrQualifier.get<TypedefNameDecl *>();
+ : cast<TypedefNameDecl *>(TypedefNameDeclOrQualifier);
}
void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
@@ -4011,7 +4009,7 @@ public:
return QualType();
if (const Type *T = IntegerType.dyn_cast<const Type*>())
return QualType(T, 0);
- return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType();
+ return cast<TypeSourceInfo *>(IntegerType)->getType().getUnqualifiedType();
}
/// Set the underlying integer type.
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index a3447d199097..82932e098c86 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -271,16 +271,12 @@ private:
/// // LexicalDC == global namespace
llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
- bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
- bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
+ bool isInSemaDC() const { return isa<DeclContext *>(DeclCtx); }
+ bool isOutOfSemaDC() const { return isa<MultipleDC *>(DeclCtx); }
- MultipleDC *getMultipleDC() const {
- return DeclCtx.get<MultipleDC*>();
- }
+ MultipleDC *getMultipleDC() const { return cast<MultipleDC *>(DeclCtx); }
- DeclContext *getSemanticDC() const {
- return DeclCtx.get<DeclContext*>();
- }
+ DeclContext *getSemanticDC() const { return cast<DeclContext *>(DeclCtx); }
/// Loc - The location of this decl.
SourceLocation Loc;
@@ -1340,7 +1336,7 @@ public:
assert(Ptr && "dereferencing end() iterator");
if (DeclListNode *CurNode = Ptr.dyn_cast<DeclListNode*>())
return CurNode->D;
- return Ptr.get<NamedDecl*>();
+ return cast<NamedDecl *>(Ptr);
}
void operator->() const { } // Unsupported.
bool operator==(const iterator &X) const { return Ptr == X.Ptr; }
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index e389b5cd6df5..c232556edeff 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -2388,19 +2388,19 @@ public:
/// Determine whether this initializer is initializing a base class.
bool isBaseInitializer() const {
- return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
+ return isa<TypeSourceInfo *>(Initializee) && !IsDelegating;
}
/// Determine whether this initializer is initializing a non-static
/// data member.
- bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); }
+ bool isMemberInitializer() const { return isa<FieldDecl *>(Initializee); }
bool isAnyMemberInitializer() const {
return isMemberInitializer() || isIndirectMemberInitializer();
}
bool isIndirectMemberInitializer() const {
- return Initializee.is<IndirectFieldDecl*>();
+ return isa<IndirectFieldDecl *>(Initializee);
}
/// Determine whether this initializer is an implicit initializer
@@ -2416,7 +2416,7 @@ public:
/// Determine whether this initializer is creating a delegating
/// constructor.
bool isDelegatingInitializer() const {
- return Initializee.is<TypeSourceInfo*>() && IsDelegating;
+ return isa<TypeSourceInfo *>(Initializee) && IsDelegating;
}
/// Determine whether this initializer is a pack expansion.
@@ -2457,21 +2457,21 @@ public:
/// non-static data member being initialized. Otherwise, returns null.
FieldDecl *getMember() const {
if (isMemberInitializer())
- return Initializee.get<FieldDecl*>();
+ return cast<FieldDecl *>(Initializee);
return nullptr;
}
FieldDecl *getAnyMember() const {
if (isMemberInitializer())
- return Initializee.get<FieldDecl*>();
+ return cast<FieldDecl *>(Initializee);
if (isIndirectMemberInitializer())
- return Initializee.get<IndirectFieldDecl*>()->getAnonField();
+ return cast<IndirectFieldDecl *>(Initializee)->getAnonField();
return nullptr;
}
IndirectFieldDecl *getIndirectMember() const {
if (isIndirectMemberInitializer())
- return Initializee.get<IndirectFieldDecl*>();
+ return cast<IndirectFieldDecl *>(Initializee);
return nullptr;
}
diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h
index e169c4859219..b17b7627ac90 100644
--- a/clang/include/clang/AST/DeclContextInternals.h
+++ b/clang/include/clang/AST/DeclContextInternals.h
@@ -70,7 +70,7 @@ class StoredDeclsList {
// want to keep (if any) will be of the form DeclListNode(D, <rest>);
// replace it with just D.
if (NewLast) {
- DeclListNode *Node = NewLast->get<DeclListNode*>();
+ DeclListNode *Node = cast<DeclListNode *>(*NewLast);
*NewLast = Node->D;
C.DeallocateDeclListNode(Node);
}
@@ -84,11 +84,11 @@ class StoredDeclsList {
if (!Data.getPointer())
// All declarations are erased.
return nullptr;
- else if (NewHead.is<NamedDecl *>())
+ else if (isa<NamedDecl *>(NewHead))
// The list only contains a declaration, the header itself.
return (DeclListNode::Decls *)&Data;
else {
- assert(NewLast && NewLast->is<NamedDecl *>() && "Not the tail?");
+ assert(NewLast && isa<NamedDecl *>(*NewLast) && "Not the tail?");
return NewLast;
}
}
@@ -207,7 +207,7 @@ public:
}
// Append the Decls.
- DeclListNode *Node = C.AllocateDeclListNode(Tail->get<NamedDecl *>());
+ DeclListNode *Node = C.AllocateDeclListNode(cast<NamedDecl *>(*Tail));
Node->Rest = DeclsAsList;
*Tail = Node;
}
@@ -293,7 +293,7 @@ public:
llvm::errs() << '[' << Node->D << "] -> ";
D = Node->Rest;
} else {
- llvm::errs() << '[' << D.get<NamedDecl*>() << "]\n";
+ llvm::errs() << '[' << cast<NamedDecl *>(D) << "]\n";
return;
}
}
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index e4bf54c3d77b..d3a466a8617b 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -319,8 +319,7 @@ class DefaultArgStorage {
const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
Parm = Prev;
- assert(!Parm->getDefaultArgStorage()
- .ValueOrInherited.template is<ParmDecl *>() &&
+ assert(!isa<ParmDecl *>(Parm->getDefaultArgStorage().ValueOrInherited) &&
"should only be one level of indirection");
return Parm;
}
@@ -333,7 +332,7 @@ public:
/// Determine whether the default argument for this parameter was inherited
/// from a previous declaration of the same entity.
- bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
+ bool isInherited() const { return isa<ParmDecl *>(ValueOrInherited); }
/// Get the default argument's value. This does not consider whether the
/// default argument is visible.
@@ -343,7 +342,7 @@ public:
Storage = &Prev->getDefaultArgStorage();
if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
return C->Value;
- return Storage->ValueOrInherited.template get<ArgType>();
+ return cast<ArgType>(Storage->ValueOrInherited);
}
/// Get the parameter from which we inherit the default argument, if any.
@@ -379,7 +378,7 @@ public:
Inherited->PrevDeclWithDefaultArg = InheritedFrom;
} else
ValueOrInherited = new (allocateDefaultArgStorageChain(C))
- Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
+ Chain{InheritedFrom, cast<ArgType>(ValueOrInherited)};
}
/// Remove the default argument, even if it was inherited.
@@ -735,6 +734,7 @@ class RedeclarableTemplateDecl : public TemplateDecl,
}
void anchor() override;
+
protected:
template <typename EntryType> struct SpecEntryTraits {
using DeclType = EntryType;
@@ -775,13 +775,22 @@ protected:
return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
}
- void loadLazySpecializationsImpl() const;
+ void loadLazySpecializationsImpl(bool OnlyPartial = false) const;
+
+ bool loadLazySpecializationsImpl(llvm::ArrayRef<TemplateArgument> Args,
+ TemplateParameterList *TPL = nullptr) const;
template <class EntryType, typename ...ProfileArguments>
typename SpecEntryTraits<EntryType>::DeclType*
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
void *&InsertPos, ProfileArguments &&...ProfileArgs);
+ template <class EntryType, typename... ProfileArguments>
+ typename SpecEntryTraits<EntryType>::DeclType *
+ findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
+ void *&InsertPos,
+ ProfileArguments &&...ProfileArgs);
+
template <class Derived, class EntryType>
void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
EntryType *Entry, void *InsertPos);
@@ -796,13 +805,6 @@ protected:
/// was explicitly specialized.
llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
InstantiatedFromMember;
-
- /// If non-null, points to an array of specializations (including
- /// partial specializations) known only by their external declaration IDs.
- ///
- /// The first value in the array is the number of specializations/partial
- /// specializations that follow.
- GlobalDeclID *LazySpecializations = nullptr;
};
/// Pointer to the common data shared by all declarations of this
@@ -1962,7 +1964,7 @@ public:
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
return PartialSpec->PartialSpecialization;
- return SpecializedTemplate.get<ClassTemplateDecl*>();
+ return cast<ClassTemplateDecl *>(SpecializedTemplate);
}
/// Retrieve the set of template arguments that should be used
@@ -1989,7 +1991,7 @@ public:
/// template arguments have been deduced.
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
const TemplateArgumentList *TemplateArgs) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
+ assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
"Already set to a class template partial specialization!");
auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
PS->PartialSpecialization = PartialSpec;
@@ -2000,7 +2002,7 @@ public:
/// Note that this class template specialization is an instantiation
/// of the given class template.
void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
+ assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
"Previously set to a class template partial specialization!");
SpecializedTemplate = TemplDecl;
}
@@ -2010,7 +2012,7 @@ public:
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
return Info->TemplateArgsAsWritten;
- return ExplicitInfo.get<const ASTTemplateArgumentListInfo *>();
+ return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
}
/// Set the template argument list as written in the sources.
@@ -2283,7 +2285,7 @@ public:
friend class TemplateDeclInstantiator;
/// Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
+ void LoadLazySpecializations(bool OnlyPartial = false) const;
/// Get the underlying class declarations of the template.
CXXRecordDecl *getTemplatedDecl() const {
@@ -2731,7 +2733,7 @@ public:
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
return PartialSpec->PartialSpecialization;
- return SpecializedTemplate.get<VarTemplateDecl *>();
+ return cast<VarTemplateDecl *>(SpecializedTemplate);
}
/// Retrieve the set of template arguments that should be used
@@ -2758,7 +2760,7 @@ public:
/// template arguments have been deduced.
void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
const TemplateArgumentList *TemplateArgs) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
+ assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
"Already set to a variable template partial specialization!");
auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
PS->PartialSpecialization = PartialSpec;
@@ -2769,7 +2771,7 @@ public:
/// Note that this variable template specialization is an instantiation
/// of the given variable template.
void setInstantiationOf(VarTemplateDecl *TemplDecl) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
+ assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
"Previously set to a variable template partial specialization!");
SpecializedTemplate = TemplDecl;
}
@@ -2779,7 +2781,7 @@ public:
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
return Info->TemplateArgsAsWritten;
- return ExplicitInfo.get<const ASTTemplateArgumentListInfo *>();
+ return cast<const ASTTemplateArgumentListInfo *>(ExplicitInfo);
}
/// Set the template argument list as written in the sources.
@@ -3033,7 +3035,7 @@ public:
friend class ASTDeclWriter;
/// Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
+ void LoadLazySpecializations(bool OnlyPartial = false) const;
/// Get the underlying variable declarations of the template.
VarDecl *getTemplatedDecl() const {
@@ -3306,7 +3308,7 @@ inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
return PD;
if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
return PD;
- return P.get<TemplateTemplateParmDecl *>();
+ return cast<TemplateTemplateParmDecl *>(P);
}
inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 1a24b8857674..4cec89c979f7 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -878,7 +878,7 @@ public:
/// object. This is not a strong guarantee.
bool isMostDerived(const ASTContext &Context) const;
- bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
+ bool isTypeOperand() const { return isa<TypeSourceInfo *>(Operand); }
/// Retrieves the type operand of this typeid() expression after
/// various required adjustments (removing reference types, cv-qualifiers).
@@ -887,11 +887,11 @@ public:
/// Retrieve source information for the type operand.
TypeSourceInfo *getTypeOperandSourceInfo() const {
assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
- return Operand.get<TypeSourceInfo *>();
+ return cast<TypeSourceInfo *>(Operand);
}
Expr *getExprOperand() const {
assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
- return static_cast<Expr*>(Operand.get<Stmt *>());
+ return static_cast<Expr *>(cast<Stmt *>(Operand));
}
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
@@ -1093,7 +1093,7 @@ public:
Operand = (TypeSourceInfo*)nullptr;
}
- bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
+ bool isTypeOperand() const { return isa<TypeSourceInfo *>(Operand); }
/// Retrieves the type operand of this __uuidof() expression after
/// various required adjustments (removing reference types, cv-qualifiers).
@@ -1102,11 +1102,11 @@ public:
/// Retrieve source information for the type operand.
TypeSourceInfo *getTypeOperandSourceInfo() const {
assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
- return Operand.get<TypeSourceInfo *>();
+ return cast<TypeSourceInfo *>(Operand);
}
Expr *getExprOperand() const {
assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
- return static_cast<Expr*>(Operand.get<Stmt *>());
+ return static_cast<Expr *>(cast<Stmt *>(Operand));
}
MSGuidDecl *getGuidDecl() const { return Guid; }
@@ -4750,24 +4750,24 @@ public:
/// be materialized into a glvalue.
Expr *getSubExpr() const {
return cast<Expr>(
- State.is<Stmt *>()
- ? State.get<Stmt *>()
- : State.get<LifetimeExtendedTemporaryDecl *>()->getTemporaryExpr());
+ isa<Stmt *>(State)
+ ? cast<Stmt *>(State)
+ : cast<LifetimeExtendedTemporaryDecl *>(State)->getTemporaryExpr());
}
/// Retrieve the storage duration for the materialized temporary.
StorageDuration getStorageDuration() const {
- return State.is<Stmt *>() ? SD_FullExpression
- : State.get<LifetimeExtendedTemporaryDecl *>()
+ return isa<Stmt *>(State) ? SD_FullExpression
+ : cast<LifetimeExtendedTemporaryDecl *>(State)
->getStorageDuration();
}
/// Get the storage for the constant value of a materialized temporary
/// of static storage duration.
APValue *getOrCreateValue(bool MayCreate) const {
- assert(State.is<LifetimeExtendedTemporaryDecl *>() &&
+ assert(isa<LifetimeExtendedTemporaryDecl *>(State) &&
"the temporary has not been lifetime extended");
- return State.get<LifetimeExtendedTemporaryDecl *>()->getOrCreateValue(
+ return cast<LifetimeExtendedTemporaryDecl *>(State)->getOrCreateValue(
MayCreate);
}
@@ -4782,8 +4782,8 @@ public:
/// Get the declaration which triggered the lifetime-extension of this
/// temporary, if any.
ValueDecl *getExtendingDecl() {
- return State.is<Stmt *>() ? nullptr
- : State.get<LifetimeExtendedTemporaryDecl *>()
+ return isa<Stmt *>(State) ? nullptr
+ : cast<LifetimeExtendedTemporaryDecl *>(State)
->getExtendingDecl();
}
const ValueDecl *getExtendingDecl() const {
@@ -4793,8 +4793,8 @@ public:
void setExtendingDecl(ValueDecl *ExtendedBy, unsigned ManglingNumber);
unsigned getManglingNumber() const {
- return State.is<Stmt *>() ? 0
- : State.get<LifetimeExtendedTemporaryDecl *>()
+ return isa<Stmt *>(State) ? 0
+ : cast<LifetimeExtendedTemporaryDecl *>(State)
->getManglingNumber();
}
@@ -4820,17 +4820,17 @@ public:
// Iterators
child_range children() {
- return State.is<Stmt *>()
+ return isa<Stmt *>(State)
? child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1)
- : State.get<LifetimeExtendedTemporaryDecl *>()->childrenExpr();
+ : cast<LifetimeExtendedTemporaryDecl *>(State)->childrenExpr();
}
const_child_range children() const {
- return State.is<Stmt *>()
+ return isa<Stmt *>(State)
? const_child_range(State.getAddrOfPtr1(),
State.getAddrOfPtr1() + 1)
: const_cast<const LifetimeExtendedTemporaryDecl *>(
- State.get<LifetimeExtendedTemporaryDecl *>())
+ cast<LifetimeExtendedTemporaryDecl *>(State))
->childrenExpr();
}
};
diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h
index f3e32ce39619..f988d40cf73c 100644
--- a/clang/include/clang/AST/ExprConcepts.h
+++ b/clang/include/clang/AST/ExprConcepts.h
@@ -261,13 +261,13 @@ public:
assert(Status == SS_SubstitutionFailure &&
"Attempted to get substitution diagnostic when there has been no "
"substitution failure.");
- return Value.get<SubstitutionDiagnostic *>();
+ return cast<SubstitutionDiagnostic *>(Value);
}
TypeSourceInfo *getType() const {
assert(!isSubstitutionFailure() &&
"Attempted to get type when there has been a substitution failure.");
- return Value.get<TypeSourceInfo *>();
+ return cast<TypeSourceInfo *>(Value);
}
static bool classof(const Requirement *R) {
@@ -329,24 +329,24 @@ public:
bool isSubstitutionFailure() const {
return !isEmpty() &&
- TypeConstraintInfo.getPointer().is<SubstitutionDiagnostic *>();
+ isa<SubstitutionDiagnostic *>(TypeConstraintInfo.getPointer());
}
bool isTypeConstraint() const {
return !isEmpty() &&
- TypeConstraintInfo.getPointer().is<TemplateParameterList *>();
+ isa<TemplateParameterList *>(TypeConstraintInfo.getPointer());
}
SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
assert(isSubstitutionFailure());
- return TypeConstraintInfo.getPointer().get<SubstitutionDiagnostic *>();
+ return cast<SubstitutionDiagnostic *>(TypeConstraintInfo.getPointer());
}
const TypeConstraint *getTypeConstraint() const;
TemplateParameterList *getTypeConstraintTemplateParameterList() const {
assert(isTypeConstraint());
- return TypeConstraintInfo.getPointer().get<TemplateParameterList *>();
+ return cast<TemplateParameterList *>(TypeConstraintInfo.getPointer());
}
};
private:
@@ -409,14 +409,14 @@ public:
assert(isExprSubstitutionFailure() &&
"Attempted to get expression substitution diagnostic when there has "
"been no expression substitution failure");
- return Value.get<SubstitutionDiagnostic *>();
+ return cast<SubstitutionDiagnostic *>(Value);
}
Expr *getExpr() const {
assert(!isExprSubstitutionFailure() &&
"ExprRequirement has no expression because there has been a "
"substitution failure.");
- return Value.get<Expr *>();
+ return cast<Expr *>(Value);
}
static bool classof(const Requirement *R) {
diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h
index f833916c91aa..1fccc2606958 100644
--- a/clang/include/clang/AST/ExprObjC.h
+++ b/clang/include/clang/AST/ExprObjC.h
@@ -752,28 +752,24 @@ public:
setMethodRefFlag(MethodRef_Setter, val);
}
- const Expr *getBase() const {
- return cast<Expr>(Receiver.get<Stmt*>());
- }
- Expr *getBase() {
- return cast<Expr>(Receiver.get<Stmt*>());
- }
+ const Expr *getBase() const { return cast<Expr>(cast<Stmt *>(Receiver)); }
+ Expr *getBase() { return cast<Expr>(cast<Stmt *>(Receiver)); }
SourceLocation getLocation() const { return IdLoc; }
SourceLocation getReceiverLocation() const { return ReceiverLoc; }
QualType getSuperReceiverType() const {
- return QualType(Receiver.get<const Type*>(), 0);
+ return QualType(cast<const Type *>(Receiver), 0);
}
ObjCInterfaceDecl *getClassReceiver() const {
- return Receiver.get<ObjCInterfaceDecl*>();
+ return cast<ObjCInterfaceDecl *>(Receiver);
}
- bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
- bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
- bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
+ bool isObjectReceiver() const { return isa<Stmt *>(Receiver); }
+ bool isSuperReceiver() const { return isa<const Type *>(Receiver); }
+ bool isClassReceiver() const { return isa<ObjCInterfaceDecl *>(Receiver); }
/// Determine the type of the base, regardless of the kind of receiver.
QualType getReceiverType(const ASTContext &ctx) const;
@@ -787,7 +783,7 @@ public:
// Iterators
child_range children() {
- if (Receiver.is<Stmt*>()) {
+ if (isa<Stmt *>(Receiver)) {
Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
return child_range(begin, begin+1);
}
diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h
index 582ed7c65f58..4d7ff822fceb 100644
--- a/clang/include/clang/AST/ExternalASTSource.h
+++ b/clang/include/clang/AST/ExternalASTSource.h
@@ -152,6 +152,21 @@ public:
virtual bool
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
+ /// Load all the external specializations for the Decl \param D if \param
+ /// OnlyPartial is false. Otherwise, load all the external **partial**
+ /// specializations for the \param D.
+ ///
+ /// Return true if any new specializations get loaded. Return false otherwise.
+ virtual bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial);
+
+ /// Load all the specializations for the Decl \param D with the same template
+ /// args specified by \param TemplateArgs.
+ ///
+ /// Return true if any new specializations get loaded. Return false otherwise.
+ virtual bool
+ LoadExternalSpecializations(const Decl *D,
+ ArrayRef<TemplateArgument> TemplateArgs);
+
/// Ensures that the table of all visible declarations inside this
/// context is up to date.
///
@@ -447,9 +462,7 @@ public:
: Value(Value) {}
/// Forcibly set this pointer (which must be lazy) as needing updates.
- void markIncomplete() {
- Value.template get<LazyData *>()->LastGeneration = 0;
- }
+ void markIncomplete() { cast<LazyData *>(Value)->LastGeneration = 0; }
/// Set the value of this pointer, in the current generation.
void set(T NewValue) {
@@ -472,14 +485,14 @@ public:
}
return LazyVal->LastValue;
}
- return Value.template get<T>();
+ return cast<T>(Value);
}
/// Get the most recently computed value of this pointer without updating it.
T getNotUpdated() const {
if (auto *LazyVal = Value.template dyn_cast<LazyData *>())
return LazyVal->LastValue;
- return Value.template get<T>();
+ return cast<T>(Value);
}
void *getOpaqueValue() { return Value.getOpaqueValue(); }
diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h
index 5ad4c336b6c5..b4747c68a1df 100644
--- a/clang/include/clang/AST/OpenACCClause.h
+++ b/clang/include/clang/AST/OpenACCClause.h
@@ -38,7 +38,7 @@ public:
SourceLocation getBeginLoc() const { return Location.getBegin(); }
SourceLocation getEndLoc() const { return Location.getEnd(); }
- static bool classof(const OpenACCClause *) { return false; }
+ static bool classof(const OpenACCClause *) { return true; }
using child_iterator = StmtIterator;
using const_child_iterator = ConstStmtIterator;
@@ -76,6 +76,50 @@ public:
}
};
+// Represents the 'finalize' clause.
+class OpenACCFinalizeClause : public OpenACCClause {
+protected:
+ OpenACCFinalizeClause(SourceLocation BeginLoc, SourceLocation EndLoc)
+ : OpenACCClause(OpenACCClauseKind::Finalize, BeginLoc, EndLoc) {}
+
+public:
+ static bool classof(const OpenACCClause *C) {
+ return C->getClauseKind() == OpenACCClauseKind::Finalize;
+ }
+
+ static OpenACCFinalizeClause *
+ Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
+
+ 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());
+ }
+};
+
+// Represents the 'if_present' clause.
+class OpenACCIfPresentClause : public OpenACCClause {
+protected:
+ OpenACCIfPresentClause(SourceLocation BeginLoc, SourceLocation EndLoc)
+ : OpenACCClause(OpenACCClauseKind::IfPresent, BeginLoc, EndLoc) {}
+
+public:
+ static bool classof(const OpenACCClause *C) {
+ return C->getClauseKind() == OpenACCClauseKind::IfPresent;
+ }
+
+ static OpenACCIfPresentClause *
+ Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);
+
+ 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());
+ }
+};
+
// Represents the 'independent' clause.
class OpenACCIndependentClause : public OpenACCClause {
protected:
@@ -147,8 +191,9 @@ using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
/// an identifier. The 'asterisk' means 'the rest'.
class OpenACCDeviceTypeClause final
: public OpenACCClauseWithParams,
- public llvm::TrailingObjects<OpenACCDeviceTypeClause,
+ private llvm::TrailingObjects<OpenACCDeviceTypeClause,
DeviceTypeArgument> {
+ friend TrailingObjects;
// Data stored in trailing objects as IdentifierInfo* /SourceLocation pairs. A
// nullptr IdentifierInfo* represents an asterisk.
unsigned NumArchs;
@@ -333,7 +378,8 @@ public:
// Represents the 'devnum' and expressions lists for the 'wait' clause.
class OpenACCWaitClause final
: public OpenACCClauseWithExprs,
- public llvm::TrailingObjects<OpenACCWaitClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCWaitClause, Expr *> {
+ friend TrailingObjects;
SourceLocation QueuesLoc;
OpenACCWaitClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
Expr *DevNumExpr, SourceLocation QueuesLoc,
@@ -375,7 +421,8 @@ public:
class OpenACCNumGangsClause final
: public OpenACCClauseWithExprs,
- public llvm::TrailingObjects<OpenACCNumGangsClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCNumGangsClause, Expr *> {
+ friend TrailingObjects;
OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> IntExprs, SourceLocation EndLoc)
@@ -405,7 +452,8 @@ public:
class OpenACCTileClause final
: public OpenACCClauseWithExprs,
- public llvm::TrailingObjects<OpenACCTileClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCTileClause, Expr *> {
+ friend TrailingObjects;
OpenACCTileClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> SizeExprs, SourceLocation EndLoc)
: OpenACCClauseWithExprs(OpenACCClauseKind::Tile, BeginLoc, LParenLoc,
@@ -459,7 +507,8 @@ public:
class OpenACCGangClause final
: public OpenACCClauseWithExprs,
- public llvm::TrailingObjects<OpenACCGangClause, Expr *, OpenACCGangKind> {
+ private llvm::TrailingObjects<OpenACCGangClause, Expr *, OpenACCGangKind> {
+ friend TrailingObjects;
protected:
OpenACCGangClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<OpenACCGangKind> GangKinds,
@@ -483,6 +532,14 @@ public:
return {getGangKind(I), getExprs()[I]};
}
+ bool hasExprOfKind(OpenACCGangKind GK) const {
+ for (unsigned I = 0; I < getNumExprs(); ++I) {
+ if (getGangKind(I) == GK)
+ return true;
+ }
+ return false;
+ }
+
static OpenACCGangClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc,
SourceLocation LParenLoc, ArrayRef<OpenACCGangKind> GangKinds,
@@ -562,6 +619,20 @@ public:
SourceLocation EndLoc);
};
+class OpenACCDeviceNumClause : public OpenACCClauseWithSingleIntExpr {
+ OpenACCDeviceNumClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+ Expr *IntExpr, SourceLocation EndLoc);
+
+public:
+ static bool classof(const OpenACCClause *C) {
+ return C->getClauseKind() == OpenACCClauseKind::DeviceNum;
+ }
+ static OpenACCDeviceNumClause *Create(const ASTContext &C,
+ SourceLocation BeginLoc,
+ SourceLocation LParenLoc, Expr *IntExpr,
+ SourceLocation EndLoc);
+};
+
/// Represents a 'collapse' clause on a 'loop' construct. This clause takes an
/// integer constant expression 'N' that represents how deep to collapse the
/// construct. It also takes an optional 'force' tag that permits intervening
@@ -606,7 +677,8 @@ public:
class OpenACCPrivateClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCPrivateClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCPrivateClause, Expr *> {
+ friend TrailingObjects;
OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
@@ -628,7 +700,8 @@ public:
class OpenACCFirstPrivateClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCFirstPrivateClause, Expr *> {
+ friend TrailingObjects;
OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
@@ -650,7 +723,8 @@ public:
class OpenACCDevicePtrClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCDevicePtrClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCDevicePtrClause, Expr *> {
+ friend TrailingObjects;
OpenACCDevicePtrClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
@@ -672,7 +746,8 @@ public:
class OpenACCAttachClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCAttachClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCAttachClause, Expr *> {
+ friend TrailingObjects;
OpenACCAttachClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
@@ -692,9 +767,79 @@ public:
ArrayRef<Expr *> VarList, SourceLocation EndLoc);
};
+class OpenACCDetachClause final
+ : public OpenACCClauseWithVarList,
+ private llvm::TrailingObjects<OpenACCDetachClause, Expr *> {
+ friend TrailingObjects;
+
+ OpenACCDetachClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc)
+ : OpenACCClauseWithVarList(OpenACCClauseKind::Detach, BeginLoc, LParenLoc,
+ EndLoc) {
+ std::uninitialized_copy(VarList.begin(), VarList.end(),
+ getTrailingObjects<Expr *>());
+ setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
+ }
+
+public:
+ static bool classof(const OpenACCClause *C) {
+ return C->getClauseKind() == OpenACCClauseKind::Detach;
+ }
+ static OpenACCDetachClause *
+ Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc);
+};
+
+class OpenACCDeleteClause final
+ : public OpenACCClauseWithVarList,
+ private llvm::TrailingObjects<OpenACCDeleteClause, Expr *> {
+ friend TrailingObjects;
+
+ OpenACCDeleteClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc)
+ : OpenACCClauseWithVarList(OpenACCClauseKind::Delete, BeginLoc, LParenLoc,
+ EndLoc) {
+ std::uninitialized_copy(VarList.begin(), VarList.end(),
+ getTrailingObjects<Expr *>());
+ setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
+ }
+
+public:
+ static bool classof(const OpenACCClause *C) {
+ return C->getClauseKind() == OpenACCClauseKind::Delete;
+ }
+ static OpenACCDeleteClause *
+ Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc);
+};
+
+class OpenACCUseDeviceClause final
+ : public OpenACCClauseWithVarList,
+ private llvm::TrailingObjects<OpenACCUseDeviceClause, Expr *> {
+ friend TrailingObjects;
+
+ OpenACCUseDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc)
+ : OpenACCClauseWithVarList(OpenACCClauseKind::UseDevice, BeginLoc,
+ LParenLoc, EndLoc) {
+ std::uninitialized_copy(VarList.begin(), VarList.end(),
+ getTrailingObjects<Expr *>());
+ setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), VarList.size()));
+ }
+
+public:
+ static bool classof(const OpenACCClause *C) {
+ return C->getClauseKind() == OpenACCClauseKind::UseDevice;
+ }
+ static OpenACCUseDeviceClause *
+ Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
+ ArrayRef<Expr *> VarList, SourceLocation EndLoc);
+};
+
class OpenACCNoCreateClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCNoCreateClause, Expr *> {
+ friend TrailingObjects;
OpenACCNoCreateClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
@@ -716,7 +861,8 @@ public:
class OpenACCPresentClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCPresentClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCPresentClause, Expr *> {
+ friend TrailingObjects;
OpenACCPresentClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc)
@@ -738,7 +884,8 @@ public:
class OpenACCCopyClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCCopyClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCCopyClause, Expr *> {
+ friend TrailingObjects;
OpenACCCopyClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
SourceLocation LParenLoc, ArrayRef<Expr *> VarList,
@@ -767,7 +914,8 @@ public:
class OpenACCCopyInClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCCopyInClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCCopyInClause, Expr *> {
+ friend TrailingObjects;
bool IsReadOnly;
OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
@@ -799,7 +947,8 @@ public:
class OpenACCCopyOutClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCCopyOutClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCCopyOutClause, Expr *> {
+ friend TrailingObjects;
bool IsZero;
OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
@@ -831,7 +980,8 @@ public:
class OpenACCCreateClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCCreateClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCCreateClause, Expr *> {
+ friend TrailingObjects;
bool IsZero;
OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc,
@@ -863,7 +1013,8 @@ public:
class OpenACCReductionClause final
: public OpenACCClauseWithVarList,
- public llvm::TrailingObjects<OpenACCReductionClause, Expr *> {
+ private llvm::TrailingObjects<OpenACCReductionClause, Expr *> {
+ friend TrailingObjects;
OpenACCReductionOperator Op;
OpenACCReductionClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 76b598a5db23..f5b32ed51698 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2151,8 +2151,11 @@ DEF_TRAVERSE_DECL(DecompositionDecl, {
})
DEF_TRAVERSE_DECL(BindingDecl, {
- if (getDerived().shouldVisitImplicitCode())
+ if (getDerived().shouldVisitImplicitCode()) {
TRY_TO(TraverseStmt(D->getBinding()));
+ if (const auto HoldingVar = D->getHoldingVar())
+ TRY_TO(TraverseDecl(HoldingVar));
+ }
})
DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
@@ -4058,6 +4061,25 @@ DEF_TRAVERSE_STMT(OpenACCLoopConstruct,
{ TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
DEF_TRAVERSE_STMT(OpenACCCombinedConstruct,
{ TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
+DEF_TRAVERSE_STMT(OpenACCDataConstruct,
+ { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
+DEF_TRAVERSE_STMT(OpenACCEnterDataConstruct,
+ { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
+DEF_TRAVERSE_STMT(OpenACCExitDataConstruct,
+ { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
+DEF_TRAVERSE_STMT(OpenACCHostDataConstruct,
+ { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
+DEF_TRAVERSE_STMT(OpenACCWaitConstruct, {
+ if (S->hasDevNumExpr())
+ TRY_TO(TraverseStmt(S->getDevNumExpr()));
+ for (auto *E : S->getQueueIdExprs())
+ TRY_TO(TraverseStmt(E));
+ TRY_TO(VisitOpenACCClauseList(S->clauses()));
+})
+DEF_TRAVERSE_STMT(OpenACCInitConstruct,
+ { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
+DEF_TRAVERSE_STMT(OpenACCShutdownConstruct,
+ { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
// Traverse HLSL: Out argument expression
DEF_TRAVERSE_STMT(HLSLOutArgExpr, {})
diff --git a/clang/include/clang/AST/Redeclarable.h b/clang/include/clang/AST/Redeclarable.h
index 8d320a9ced27..ee21f11e5f70 100644
--- a/clang/include/clang/AST/Redeclarable.h
+++ b/clang/include/clang/AST/Redeclarable.h
@@ -113,25 +113,24 @@ protected:
DeclLink(PreviousTag, decl_type *D) : Link(NotKnownLatest(Previous(D))) {}
bool isFirst() const {
- return Link.is<KnownLatest>() ||
+ return isa<KnownLatest>(Link) ||
// FIXME: 'template' is required on the next line due to an
// apparent clang bug.
- Link.get<NotKnownLatest>().template is<UninitializedLatest>();
+ isa<UninitializedLatest>(cast<NotKnownLatest>(Link));
}
decl_type *getPrevious(const decl_type *D) const {
- if (Link.is<NotKnownLatest>()) {
- NotKnownLatest NKL = Link.get<NotKnownLatest>();
- if (NKL.is<Previous>())
- return static_cast<decl_type*>(NKL.get<Previous>());
+ if (NotKnownLatest NKL = dyn_cast<NotKnownLatest>(Link)) {
+ if (auto *Prev = dyn_cast<Previous>(NKL))
+ return static_cast<decl_type *>(Prev);
// Allocate the generational 'most recent' cache now, if needed.
Link = KnownLatest(*reinterpret_cast<const ASTContext *>(
- NKL.get<UninitializedLatest>()),
+ cast<UninitializedLatest>(NKL)),
const_cast<decl_type *>(D));
}
- return static_cast<decl_type*>(Link.get<KnownLatest>().get(D));
+ return static_cast<decl_type *>(cast<KnownLatest>(Link).get(D));
}
void setPrevious(decl_type *D) {
@@ -141,25 +140,24 @@ protected:
void setLatest(decl_type *D) {
assert(isFirst() && "decl became canonical unexpectedly");
- if (Link.is<NotKnownLatest>()) {
- NotKnownLatest NKL = Link.get<NotKnownLatest>();
+ if (NotKnownLatest NKL = dyn_cast<NotKnownLatest>(Link)) {
Link = KnownLatest(*reinterpret_cast<const ASTContext *>(
- NKL.get<UninitializedLatest>()),
+ cast<UninitializedLatest>(NKL)),
D);
} else {
- auto Latest = Link.get<KnownLatest>();
+ auto Latest = cast<KnownLatest>(Link);
Latest.set(D);
Link = Latest;
}
}
- void markIncomplete() { Link.get<KnownLatest>().markIncomplete(); }
+ void markIncomplete() { cast<KnownLatest>(Link).markIncomplete(); }
Decl *getLatestNotUpdated() const {
assert(isFirst() && "expected a canonical decl");
- if (Link.is<NotKnownLatest>())
+ if (isa<NotKnownLatest>(Link))
return nullptr;
- return Link.get<KnownLatest>().getNotUpdated();
+ return cast<KnownLatest>(Link).getNotUpdated();
}
};
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 83fafbabb1d4..405c6166adb1 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -109,6 +109,8 @@ protected:
//===--- Statement bitfields classes ---===//
+ #define NumStmtBits 9
+
class StmtBitfields {
friend class ASTStmtReader;
friend class ASTStmtWriter;
@@ -116,9 +118,8 @@ protected:
/// The statement class.
LLVM_PREFERRED_TYPE(StmtClass)
- unsigned sClass : 8;
+ unsigned sClass : NumStmtBits;
};
- enum { NumStmtBits = 8 };
class NullStmtBitfields {
friend class ASTStmtReader;
diff --git a/clang/include/clang/AST/StmtOpenACC.h b/clang/include/clang/AST/StmtOpenACC.h
index fa8793e74082..e311eded5599 100644
--- a/clang/include/clang/AST/StmtOpenACC.h
+++ b/clang/include/clang/AST/StmtOpenACC.h
@@ -127,11 +127,12 @@ public:
/// the 'Kind'.
class OpenACCComputeConstruct final
: public OpenACCAssociatedStmtConstruct,
- public llvm::TrailingObjects<OpenACCComputeConstruct,
- const OpenACCClause *> {
+ private llvm::TrailingObjects<OpenACCComputeConstruct,
+ const OpenACCClause *> {
friend class ASTStmtWriter;
friend class ASTStmtReader;
friend class ASTContext;
+ friend TrailingObjects;
OpenACCComputeConstruct(unsigned NumClauses)
: OpenACCAssociatedStmtConstruct(
OpenACCComputeConstructClass, OpenACCDirectiveKind::Invalid,
@@ -189,7 +190,7 @@ public:
/// Construct.
class OpenACCLoopConstruct final
: public OpenACCAssociatedStmtConstruct,
- public llvm::TrailingObjects<OpenACCLoopConstruct,
+ private llvm::TrailingObjects<OpenACCLoopConstruct,
const OpenACCClause *> {
// The compute/combined construct kind this loop is associated with, or
// invalid if this is an orphaned loop construct.
@@ -202,6 +203,7 @@ class OpenACCLoopConstruct final
friend class OpenACCAssociatedStmtConstruct;
friend class OpenACCCombinedConstruct;
friend class OpenACCComputeConstruct;
+ friend TrailingObjects;
OpenACCLoopConstruct(unsigned NumClauses);
@@ -245,8 +247,9 @@ public:
// shared with both loop and compute constructs.
class OpenACCCombinedConstruct final
: public OpenACCAssociatedStmtConstruct,
- public llvm::TrailingObjects<OpenACCCombinedConstruct,
+ private llvm::TrailingObjects<OpenACCCombinedConstruct,
const OpenACCClause *> {
+ friend TrailingObjects;
OpenACCCombinedConstruct(unsigned NumClauses)
: OpenACCAssociatedStmtConstruct(
OpenACCCombinedConstructClass, OpenACCDirectiveKind::Invalid,
@@ -292,5 +295,382 @@ public:
return const_cast<OpenACCCombinedConstruct *>(this)->getLoop();
}
};
+
+// This class represents a 'data' construct, which has an associated statement
+// and clauses, but is otherwise pretty simple.
+class OpenACCDataConstruct final
+ : public OpenACCAssociatedStmtConstruct,
+ private llvm::TrailingObjects<OpenACCDataConstruct,
+ const OpenACCClause *> {
+ friend TrailingObjects;
+ OpenACCDataConstruct(unsigned NumClauses)
+ : OpenACCAssociatedStmtConstruct(
+ OpenACCDataConstructClass, OpenACCDirectiveKind::Data,
+ SourceLocation{}, SourceLocation{}, SourceLocation{},
+ /*AssociatedStmt=*/nullptr) {
+ std::uninitialized_value_construct(
+ getTrailingObjects<const OpenACCClause *>(),
+ getTrailingObjects<const OpenACCClause *>() + NumClauses);
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ NumClauses));
+ }
+
+ OpenACCDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses,
+ Stmt *StructuredBlock)
+ : OpenACCAssociatedStmtConstruct(OpenACCDataConstructClass,
+ OpenACCDirectiveKind::Data, Start,
+ DirectiveLoc, End, StructuredBlock) {
+ std::uninitialized_copy(Clauses.begin(), Clauses.end(),
+ getTrailingObjects<const OpenACCClause *>());
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ Clauses.size()));
+ }
+ void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); }
+
+public:
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OpenACCDataConstructClass;
+ }
+
+ static OpenACCDataConstruct *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses);
+ static OpenACCDataConstruct *Create(const ASTContext &C, SourceLocation Start,
+ SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses,
+ Stmt *StructuredBlock);
+ Stmt *getStructuredBlock() { return getAssociatedStmt(); }
+ const Stmt *getStructuredBlock() const {
+ return const_cast<OpenACCDataConstruct *>(this)->getStructuredBlock();
+ }
+};
+// This class represents a 'enter data' construct, which JUST has clauses.
+class OpenACCEnterDataConstruct final
+ : public OpenACCConstructStmt,
+ private llvm::TrailingObjects<OpenACCEnterDataConstruct,
+ const OpenACCClause *> {
+ friend TrailingObjects;
+ OpenACCEnterDataConstruct(unsigned NumClauses)
+ : OpenACCConstructStmt(OpenACCEnterDataConstructClass,
+ OpenACCDirectiveKind::EnterData, SourceLocation{},
+ SourceLocation{}, SourceLocation{}) {
+ std::uninitialized_value_construct(
+ getTrailingObjects<const OpenACCClause *>(),
+ getTrailingObjects<const OpenACCClause *>() + NumClauses);
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ NumClauses));
+ }
+ OpenACCEnterDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses)
+ : OpenACCConstructStmt(OpenACCEnterDataConstructClass,
+ OpenACCDirectiveKind::EnterData, Start,
+ DirectiveLoc, End) {
+ std::uninitialized_copy(Clauses.begin(), Clauses.end(),
+ getTrailingObjects<const OpenACCClause *>());
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ Clauses.size()));
+ }
+
+public:
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OpenACCEnterDataConstructClass;
+ }
+ static OpenACCEnterDataConstruct *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses);
+ static OpenACCEnterDataConstruct *
+ Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End, ArrayRef<const OpenACCClause *> Clauses);
+};
+// This class represents a 'exit data' construct, which JUST has clauses.
+class OpenACCExitDataConstruct final
+ : public OpenACCConstructStmt,
+ private llvm::TrailingObjects<OpenACCExitDataConstruct,
+ const OpenACCClause *> {
+ friend TrailingObjects;
+ OpenACCExitDataConstruct(unsigned NumClauses)
+ : OpenACCConstructStmt(OpenACCExitDataConstructClass,
+ OpenACCDirectiveKind::ExitData, SourceLocation{},
+ SourceLocation{}, SourceLocation{}) {
+ std::uninitialized_value_construct(
+ getTrailingObjects<const OpenACCClause *>(),
+ getTrailingObjects<const OpenACCClause *>() + NumClauses);
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ NumClauses));
+ }
+ OpenACCExitDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses)
+ : OpenACCConstructStmt(OpenACCExitDataConstructClass,
+ OpenACCDirectiveKind::ExitData, Start,
+ DirectiveLoc, End) {
+ std::uninitialized_copy(Clauses.begin(), Clauses.end(),
+ getTrailingObjects<const OpenACCClause *>());
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ Clauses.size()));
+ }
+
+public:
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OpenACCExitDataConstructClass;
+ }
+ static OpenACCExitDataConstruct *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses);
+ static OpenACCExitDataConstruct *
+ Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End, ArrayRef<const OpenACCClause *> Clauses);
+};
+// This class represents a 'host_data' construct, which has an associated
+// statement and clauses, but is otherwise pretty simple.
+class OpenACCHostDataConstruct final
+ : public OpenACCAssociatedStmtConstruct,
+ private llvm::TrailingObjects<OpenACCHostDataConstruct,
+ const OpenACCClause *> {
+ friend TrailingObjects;
+ OpenACCHostDataConstruct(unsigned NumClauses)
+ : OpenACCAssociatedStmtConstruct(
+ OpenACCHostDataConstructClass, OpenACCDirectiveKind::HostData,
+ SourceLocation{}, SourceLocation{}, SourceLocation{},
+ /*AssociatedStmt=*/nullptr) {
+ std::uninitialized_value_construct(
+ getTrailingObjects<const OpenACCClause *>(),
+ getTrailingObjects<const OpenACCClause *>() + NumClauses);
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ NumClauses));
+ }
+ OpenACCHostDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses,
+ Stmt *StructuredBlock)
+ : OpenACCAssociatedStmtConstruct(OpenACCHostDataConstructClass,
+ OpenACCDirectiveKind::HostData, Start,
+ DirectiveLoc, End, StructuredBlock) {
+ std::uninitialized_copy(Clauses.begin(), Clauses.end(),
+ getTrailingObjects<const OpenACCClause *>());
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ Clauses.size()));
+ }
+ void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); }
+
+public:
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OpenACCHostDataConstructClass;
+ }
+ static OpenACCHostDataConstruct *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses);
+ static OpenACCHostDataConstruct *
+ Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End, ArrayRef<const OpenACCClause *> Clauses,
+ Stmt *StructuredBlock);
+ Stmt *getStructuredBlock() { return getAssociatedStmt(); }
+ const Stmt *getStructuredBlock() const {
+ return const_cast<OpenACCHostDataConstruct *>(this)->getStructuredBlock();
+ }
+};
+
+// This class represents a 'wait' construct, which has some expressions plus a
+// clause list.
+class OpenACCWaitConstruct final
+ : public OpenACCConstructStmt,
+ private llvm::TrailingObjects<OpenACCWaitConstruct, Expr *,
+ OpenACCClause *> {
+ // FIXME: We should be storing a `const OpenACCClause *` to be consistent with
+ // the rest of the constructs, but TrailingObjects doesn't allow for mixing
+ // constness in its implementation of `getTrailingObjects`.
+
+ friend TrailingObjects;
+ friend class ASTStmtWriter;
+ friend class ASTStmtReader;
+ // Locations of the left and right parens of the 'wait-argument'
+ // expression-list.
+ SourceLocation LParenLoc, RParenLoc;
+ // Location of the 'queues' keyword, if present.
+ SourceLocation QueuesLoc;
+
+ // Number of the expressions being represented. Index '0' is always the
+ // 'devnum' expression, even if it not present.
+ unsigned NumExprs = 0;
+
+ OpenACCWaitConstruct(unsigned NumExprs, unsigned NumClauses)
+ : OpenACCConstructStmt(OpenACCWaitConstructClass,
+ OpenACCDirectiveKind::Wait, SourceLocation{},
+ SourceLocation{}, SourceLocation{}),
+ NumExprs(NumExprs) {
+ assert(NumExprs >= 1 &&
+ "NumExprs should always be >= 1 because the 'devnum' "
+ "expr is represented by a null if necessary");
+ std::uninitialized_value_construct(getExprPtr(),
+ getExprPtr() + NumExprs);
+ std::uninitialized_value_construct(getTrailingObjects<OpenACCClause *>(),
+ getTrailingObjects<OpenACCClause *>() +
+ NumClauses);
+ setClauseList(MutableArrayRef(const_cast<const OpenACCClause **>(
+ getTrailingObjects<OpenACCClause *>()),
+ NumClauses));
+ }
+
+ OpenACCWaitConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation LParenLoc, Expr *DevNumExpr,
+ SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
+ SourceLocation RParenLoc, SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses)
+ : OpenACCConstructStmt(OpenACCWaitConstructClass,
+ OpenACCDirectiveKind::Wait, Start, DirectiveLoc,
+ End),
+ LParenLoc(LParenLoc), RParenLoc(RParenLoc), QueuesLoc(QueuesLoc),
+ NumExprs(QueueIdExprs.size() + 1) {
+ assert(NumExprs >= 1 &&
+ "NumExprs should always be >= 1 because the 'devnum' "
+ "expr is represented by a null if necessary");
+
+ std::uninitialized_copy(&DevNumExpr, &DevNumExpr + 1,
+ getExprPtr());
+ std::uninitialized_copy(QueueIdExprs.begin(), QueueIdExprs.end(),
+ getExprPtr() + 1);
+
+ std::uninitialized_copy(const_cast<OpenACCClause **>(Clauses.begin()),
+ const_cast<OpenACCClause **>(Clauses.end()),
+ getTrailingObjects<OpenACCClause *>());
+ setClauseList(MutableArrayRef(const_cast<const OpenACCClause **>(
+ getTrailingObjects<OpenACCClause *>()),
+ Clauses.size()));
+ }
+
+ size_t numTrailingObjects(OverloadToken<Expr *>) const { return NumExprs; }
+ size_t numTrailingObjects(OverloadToken<const OpenACCClause *>) const {
+ return clauses().size();
+ }
+
+ Expr **getExprPtr() const {
+ return const_cast<Expr**>(getTrailingObjects<Expr *>());
+ }
+
+ llvm::ArrayRef<Expr *> getExprs() const {
+ return llvm::ArrayRef<Expr *>(getExprPtr(), NumExprs);
+ }
+
+ llvm::ArrayRef<Expr *> getExprs() {
+ return llvm::ArrayRef<Expr *>(getExprPtr(), NumExprs);
+ }
+
+public:
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OpenACCWaitConstructClass;
+ }
+
+ static OpenACCWaitConstruct *
+ CreateEmpty(const ASTContext &C, unsigned NumExprs, unsigned NumClauses);
+
+ static OpenACCWaitConstruct *
+ Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc,
+ ArrayRef<Expr *> QueueIdExprs, SourceLocation RParenLoc,
+ SourceLocation End, ArrayRef<const OpenACCClause *> Clauses);
+
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ bool hasQueuesTag() const { return !QueuesLoc.isInvalid(); }
+ SourceLocation getQueuesLoc() const { return QueuesLoc; }
+
+ bool hasDevNumExpr() const { return getExprs()[0]; }
+ Expr *getDevNumExpr() const { return getExprs()[0]; }
+ llvm::ArrayRef<Expr *> getQueueIdExprs() { return getExprs().drop_front(); }
+ llvm::ArrayRef<Expr *> getQueueIdExprs() const {
+ return getExprs().drop_front();
+ }
+
+ child_range children() {
+ Stmt **Begin = reinterpret_cast<Stmt **>(getExprPtr());
+ return child_range(Begin, Begin + NumExprs);
+ }
+
+ const_child_range children() const {
+ Stmt *const *Begin =
+ reinterpret_cast<Stmt *const *>(getExprPtr());
+ return const_child_range(Begin, Begin + NumExprs);
+ }
+};
+
+// This class represents an 'init' construct, which has just a clause list.
+class OpenACCInitConstruct final
+ : public OpenACCConstructStmt,
+ private llvm::TrailingObjects<OpenACCInitConstruct,
+ const OpenACCClause *> {
+ friend TrailingObjects;
+ OpenACCInitConstruct(unsigned NumClauses)
+ : OpenACCConstructStmt(OpenACCInitConstructClass,
+ OpenACCDirectiveKind::Init, SourceLocation{},
+ SourceLocation{}, SourceLocation{}) {
+ std::uninitialized_value_construct(
+ getTrailingObjects<const OpenACCClause *>(),
+ getTrailingObjects<const OpenACCClause *>() + NumClauses);
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ NumClauses));
+ }
+ OpenACCInitConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses)
+ : OpenACCConstructStmt(OpenACCInitConstructClass,
+ OpenACCDirectiveKind::Init, Start, DirectiveLoc,
+ End) {
+ std::uninitialized_copy(Clauses.begin(), Clauses.end(),
+ getTrailingObjects<const OpenACCClause *>());
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ Clauses.size()));
+ }
+
+public:
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OpenACCInitConstructClass;
+ }
+ static OpenACCInitConstruct *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses);
+ static OpenACCInitConstruct *Create(const ASTContext &C, SourceLocation Start,
+ SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses);
+};
+
+// This class represents a 'shutdown' construct, which has just a clause list.
+class OpenACCShutdownConstruct final
+ : public OpenACCConstructStmt,
+ private llvm::TrailingObjects<OpenACCShutdownConstruct,
+ const OpenACCClause *> {
+ friend TrailingObjects;
+ OpenACCShutdownConstruct(unsigned NumClauses)
+ : OpenACCConstructStmt(OpenACCShutdownConstructClass,
+ OpenACCDirectiveKind::Shutdown, SourceLocation{},
+ SourceLocation{}, SourceLocation{}) {
+ std::uninitialized_value_construct(
+ getTrailingObjects<const OpenACCClause *>(),
+ getTrailingObjects<const OpenACCClause *>() + NumClauses);
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ NumClauses));
+ }
+ OpenACCShutdownConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses)
+ : OpenACCConstructStmt(OpenACCShutdownConstructClass,
+ OpenACCDirectiveKind::Shutdown, Start,
+ DirectiveLoc, End) {
+ std::uninitialized_copy(Clauses.begin(), Clauses.end(),
+ getTrailingObjects<const OpenACCClause *>());
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ Clauses.size()));
+ }
+
+public:
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OpenACCShutdownConstructClass;
+ }
+ static OpenACCShutdownConstruct *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses);
+ static OpenACCShutdownConstruct *
+ Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End, ArrayRef<const OpenACCClause *> Clauses);
+};
+
} // namespace clang
#endif // LLVM_CLANG_AST_STMTOPENACC_H
diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h
index a8f0263d5505..9d0ee24a4f5e 100644
--- a/clang/include/clang/AST/TemplateBase.h
+++ b/clang/include/clang/AST/TemplateBase.h
@@ -484,7 +484,7 @@ private:
Pointer;
TemplateTemplateArgLocInfo *getTemplate() const {
- return Pointer.get<TemplateTemplateArgLocInfo *>();
+ return cast<TemplateTemplateArgLocInfo *>(Pointer);
}
public:
@@ -499,10 +499,10 @@ public:
SourceLocation EllipsisLoc);
TypeSourceInfo *getAsTypeSourceInfo() const {
- return Pointer.get<TypeSourceInfo *>();
+ return cast<TypeSourceInfo *>(Pointer);
}
- Expr *getAsExpr() const { return Pointer.get<Expr *>(); }
+ Expr *getAsExpr() const { return cast<Expr *>(Pointer); }
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
const auto *Template = getTemplate();
diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h
index 988b142a7672..5383b53fdc49 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -411,6 +411,13 @@ public:
void VisitOpenACCConstructStmt(const OpenACCConstructStmt *S);
void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S);
void VisitOpenACCCombinedConstruct(const OpenACCCombinedConstruct *S);
+ void VisitOpenACCDataConstruct(const OpenACCDataConstruct *S);
+ void VisitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct *S);
+ void VisitOpenACCExitDataConstruct(const OpenACCExitDataConstruct *S);
+ void VisitOpenACCHostDataConstruct(const OpenACCHostDataConstruct *S);
+ void VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *S);
+ void VisitOpenACCInitConstruct(const OpenACCInitConstruct *S);
+ void VisitOpenACCShutdownConstruct(const OpenACCShutdownConstruct *S);
void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *S);
void VisitEmbedExpr(const EmbedExpr *S);
void VisitAtomicExpr(const AtomicExpr *AE);
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 6fd6c73a516f..09c98f642852 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -934,11 +934,11 @@ class QualType {
Qualifiers::FastWidth> Value;
const ExtQuals *getExtQualsUnsafe() const {
- return Value.getPointer().get<const ExtQuals*>();
+ return cast<const ExtQuals *>(Value.getPointer());
}
const Type *getTypePtrUnsafe() const {
- return Value.getPointer().get<const Type*>();
+ return cast<const Type *>(Value.getPointer());
}
const ExtQualsTypeCommonBase *getCommonPtr() const {
@@ -1064,7 +1064,7 @@ public:
/// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
/// instance.
bool hasLocalNonFastQualifiers() const {
- return Value.getPointer().is<const ExtQuals*>();
+ return isa<const ExtQuals *>(Value.getPointer());
}
/// Retrieve the set of qualifiers local to this particular QualType
@@ -6553,7 +6553,7 @@ public:
/// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained
/// by a type-constraint.
-class AutoType : public DeducedType, public llvm::FoldingSetNode {
+class AutoType : public DeducedType {
friend class ASTContext; // ASTContext creates these
ConceptDecl *TypeConstraintConcept;
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 897aa25dc95c..9a046714068a 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2125,6 +2125,16 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr>
declRefExpr;
+/// Matches expressions that refer to dependent scope declarations.
+///
+/// example matches T::v;
+/// \code
+/// template <class T> class X : T { void f() { T::v; } };
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt,
+ DependentScopeDeclRefExpr>
+ dependentScopeDeclRefExpr;
+
/// Matches a reference to an ObjCIvar.
///
/// Example: matches "a" in "init" method:
@@ -7701,6 +7711,16 @@ AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher<QualType>,
return InnerType.matches(Node.getDecayedType(), Finder, Builder);
}
+/// Matches a dependent name type
+///
+/// Example matches T::type
+/// \code
+/// template <typename T> struct declToImport {
+/// typedef typename T::type dependent_name;
+/// };
+/// \endcode
+extern const AstTypeMatcher<DependentNameType> dependentNameType;
+
/// Matches declarations whose declaration context, interpreted as a
/// Decl, matches \c InnerMatcher.
///
diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafety.h b/clang/include/clang/Analysis/Analyses/ThreadSafety.h
index 0866b09bab29..0fcf5bed1285 100644
--- a/clang/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/clang/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -223,6 +223,42 @@ public:
virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
Name LockName, SourceLocation Loc) {}
+ /// Warn when an actual underlying mutex of a scoped lockable does not match
+ /// the expected.
+ /// \param Loc -- The location of the call expression.
+ /// \param DLoc -- The location of the function declaration.
+ /// \param ScopeName -- The name of the scope passed to the function.
+ /// \param Kind -- The kind of the expected mutex.
+ /// \param Expected -- The name of the expected mutex.
+ /// \param Actual -- The name of the actual mutex.
+ virtual void handleUnmatchedUnderlyingMutexes(SourceLocation Loc,
+ SourceLocation DLoc,
+ Name ScopeName, StringRef Kind,
+ Name Expected, Name Actual) {}
+
+ /// Warn when we get fewer underlying mutexes than expected.
+ /// \param Loc -- The location of the call expression.
+ /// \param DLoc -- The location of the function declaration.
+ /// \param ScopeName -- The name of the scope passed to the function.
+ /// \param Kind -- The kind of the expected mutex.
+ /// \param Expected -- The name of the expected mutex.
+ virtual void handleExpectMoreUnderlyingMutexes(SourceLocation Loc,
+ SourceLocation DLoc,
+ Name ScopeName, StringRef Kind,
+ Name Expected) {}
+
+ /// Warn when we get more underlying mutexes than expected.
+ /// \param Loc -- The location of the call expression.
+ /// \param DLoc -- The location of the function declaration.
+ /// \param ScopeName -- The name of the scope passed to the function.
+ /// \param Kind -- The kind of the actual mutex.
+ /// \param Actual -- The name of the actual mutex.
+ virtual void handleExpectFewerUnderlyingMutexes(SourceLocation Loc,
+ SourceLocation DLoc,
+ Name ScopeName,
+ StringRef Kind, Name Actual) {
+ }
+
/// Warn that L1 cannot be acquired before L2.
virtual void handleLockAcquiredBefore(StringRef Kind, Name L1Name,
Name L2Name, SourceLocation Loc) {}
diff --git a/clang/include/clang/Analysis/FlowSensitive/SmartPointerAccessorCaching.h b/clang/include/clang/Analysis/FlowSensitive/SmartPointerAccessorCaching.h
new file mode 100644
index 000000000000..3e4016518eaa
--- /dev/null
+++ b/clang/include/clang/Analysis/FlowSensitive/SmartPointerAccessorCaching.h
@@ -0,0 +1,63 @@
+//===-- SmartPointerAccessorCaching.h ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines utilities to help cache accessors for smart pointer
+// like objects.
+//
+// These should be combined with CachedConstAccessorsLattice.
+// Beyond basic const accessors, smart pointers may have the following two
+// additional issues:
+//
+// 1) There may be multiple accessors for the same underlying object, e.g.
+// `operator->`, `operator*`, and `get`. Users may use a mixture of these
+// accessors, so the cache should unify them.
+//
+// 2) There may be non-const overloads of accessors. They are still safe to
+// cache, as they don't modify the container object.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SMARTPOINTERACCESSORCACHING_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SMARTPOINTERACCESSORCACHING_H
+
+#include <cassert>
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Stmt.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+namespace clang::dataflow {
+
+/// Matchers:
+/// For now, these match on any class with an `operator*` or `operator->`
+/// where the return types have a similar shape as std::unique_ptr
+/// and std::optional.
+///
+/// - `*` returns a reference to a type `T`
+/// - `->` returns a pointer to `T`
+/// - `get` returns a pointer to `T`
+/// - `value` returns a reference `T`
+///
+/// (1) The `T` should all match across the accessors (ignoring qualifiers).
+///
+/// (2) The specific accessor used in a call isn't required to be const,
+/// but the class must have a const overload of each accessor.
+///
+/// For now, we don't have customization to ignore certain classes.
+/// For example, if writing a ClangTidy check for `std::optional`, these
+/// would also match `std::optional`. In order to have special handling
+/// for `std::optional`, we assume the (Matcher, TransferFunction) case
+/// with custom handling is ordered early so that these generic cases
+/// do not trigger.
+ast_matchers::StatementMatcher isSmartPointerLikeOperatorStar();
+ast_matchers::StatementMatcher isSmartPointerLikeOperatorArrow();
+ast_matchers::StatementMatcher isSmartPointerLikeValueMethodCall();
+ast_matchers::StatementMatcher isSmartPointerLikeGetMethodCall();
+
+} // namespace clang::dataflow
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SMARTPOINTERACCESSORCACHING_H
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 17fc36fbe2ac..52ad72eb608c 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3763,7 +3763,7 @@ def AcquireCapability : InheritableAttr {
Clang<"acquire_shared_capability", 0>,
GNU<"exclusive_lock_function">,
GNU<"shared_lock_function">];
- let Subjects = SubjectList<[Function]>;
+ let Subjects = SubjectList<[Function, ParmVar]>;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
@@ -3795,7 +3795,7 @@ def ReleaseCapability : InheritableAttr {
Clang<"release_shared_capability", 0>,
Clang<"release_generic_capability", 0>,
Clang<"unlock_function", 0>];
- let Subjects = SubjectList<[Function]>;
+ let Subjects = SubjectList<[Function, ParmVar]>;
let LateParsed = LateAttrParseStandard;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
@@ -3819,7 +3819,7 @@ def RequiresCapability : InheritableAttr {
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
- let Subjects = SubjectList<[Function]>;
+ let Subjects = SubjectList<[Function, ParmVar]>;
let Accessors = [Accessor<"isShared", [Clang<"requires_shared_capability", 0>,
Clang<"shared_locks_required", 0>]>];
let Documentation = [Undocumented];
@@ -3941,7 +3941,7 @@ def LocksExcluded : InheritableAttr {
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
- let Subjects = SubjectList<[Function]>;
+ let Subjects = SubjectList<[Function, ParmVar]>;
let Documentation = [Undocumented];
}
@@ -4651,6 +4651,13 @@ def HLSLNumThreads: InheritableAttr {
let Documentation = [NumThreadsDocs];
}
+def HLSLSV_GroupThreadID: HLSLAnnotationAttr {
+ let Spellings = [HLSLAnnotation<"SV_GroupThreadID">];
+ let Subjects = SubjectList<[ParmVar, Field]>;
+ let LangOpts = [HLSL];
+ let Documentation = [HLSLSV_GroupThreadIDDocs];
+}
+
def HLSLSV_GroupID: HLSLAnnotationAttr {
let Spellings = [HLSLAnnotation<"SV_GroupID">];
let Subjects = SubjectList<[ParmVar, Field]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 7a82b8fa3205..fdad4c9a3ea1 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7941,6 +7941,17 @@ randomized.
}];
}
+def HLSLSV_GroupThreadIDDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``SV_GroupThreadID`` semantic, when applied to an input parameter, specifies which
+individual thread within a thread group is executing in. This attribute is
+only supported in compute shaders.
+
+The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupthreadid
+ }];
+}
+
def HLSLSV_GroupIDDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index 89f65682ae5b..e27d8ccce736 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -103,9 +103,7 @@ public:
llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
/// Get the type descriptor string for the specified builtin.
- const char *getTypeString(unsigned ID) const {
- return getRecord(ID).Type;
- }
+ const char *getTypeString(unsigned ID) const { return getRecord(ID).Type; }
/// Return true if this function is a target-specific builtin.
bool isTSBuiltin(unsigned ID) const {
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index e2c3d3c53557..b5b47ae27460 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -1450,25 +1450,25 @@ def ElementwiseFma : Builtin {
def ElementwiseAddSat : Builtin {
let Spellings = ["__builtin_elementwise_add_sat"];
- let Attributes = [NoThrow, Const, CustomTypeChecking];
+ let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}
def ElementwiseSubSat : Builtin {
let Spellings = ["__builtin_elementwise_sub_sat"];
- let Attributes = [NoThrow, Const, CustomTypeChecking];
+ let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}
def ReduceMax : Builtin {
let Spellings = ["__builtin_reduce_max"];
- let Attributes = [NoThrow, Const, CustomTypeChecking];
+ let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}
def ReduceMin : Builtin {
let Spellings = ["__builtin_reduce_min"];
- let Attributes = [NoThrow, Const, CustomTypeChecking];
+ let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr];
let Prototype = "void(...)";
}
@@ -4762,6 +4762,12 @@ def HLSLAsDouble : LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}
+def HLSLWaveActiveAllTrue : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_wave_active_all_true"];
+ let Attributes = [NoThrow, Const];
+ let Prototype = "bool(bool)";
+}
+
def HLSLWaveActiveAnyTrue : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_wave_active_any_true"];
let Attributes = [NoThrow, Const];
diff --git a/clang/include/clang/Basic/BuiltinsHexagon.def b/clang/include/clang/Basic/BuiltinsHexagon.def
index 0dc0f4567dd4..adff9f884c04 100644
--- a/clang/include/clang/Basic/BuiltinsHexagon.def
+++ b/clang/include/clang/Basic/BuiltinsHexagon.def
@@ -17,8 +17,12 @@
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
+#pragma push_macro("V79")
+#define V79 "v79"
+#pragma push_macro("V75")
+#define V75 "v75|" V79
#pragma push_macro("V73")
-#define V73 "v73"
+#define V73 "v73|" V75
#pragma push_macro("V71")
#define V71 "v71|" V73
#pragma push_macro("V69")
@@ -40,8 +44,12 @@
#pragma push_macro("V5")
#define V5 "v5|" V55
+#pragma push_macro("HVXV79")
+#define HVXV79 "hvxv79"
+#pragma push_macro("HVXV75")
+#define HVXV75 "hvxv75|" HVXV79
#pragma push_macro("HVXV73")
-#define HVXV73 "hvxv73"
+#define HVXV73 "hvxv73|" HVXV75
#pragma push_macro("HVXV71")
#define HVXV71 "hvxv71|" HVXV73
#pragma push_macro("HVXV69")
@@ -143,6 +151,8 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","", "
#pragma pop_macro("HVXV69")
#pragma pop_macro("HVXV71")
#pragma pop_macro("HVXV73")
+#pragma pop_macro("HVXV75")
+#pragma pop_macro("HVXV79")
#pragma pop_macro("V5")
#pragma pop_macro("V55")
@@ -155,6 +165,8 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","", "
#pragma pop_macro("V69")
#pragma pop_macro("V71")
#pragma pop_macro("V73")
+#pragma pop_macro("V75")
+#pragma pop_macro("V79")
#undef BUILTIN
#undef TARGET_BUILTIN
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 2dcf98b46566..c555fb3b72d6 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -186,7 +186,7 @@ public:
std::string ProfileExcludeFiles;
/// The version string to put into coverage files.
- char CoverageVersion[4];
+ char CoverageVersion[4] = {'0', '0', '0', '0'};
/// Enable additional debugging information.
std::string DebugPass;
@@ -380,6 +380,10 @@ public:
/// Set of sanitizer checks that trap rather than diagnose.
SanitizerSet SanitizeTrap;
+ /// Set of sanitizer checks that can merge handlers (smaller code size at
+ /// the expense of debuggability).
+ SanitizerSet SanitizeMergeHandlers;
+
/// List of backend command-line options for -fembed-bitcode.
std::vector<uint8_t> CmdArgs;
diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
index d271accca3d3..510b782e35d0 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -560,7 +560,8 @@ private:
ArgToStringFnTy ArgToStringFn;
/// Whether the diagnostic should be suppressed in FilePath.
- llvm::unique_function<bool(diag::kind, StringRef /*FilePath*/) const>
+ llvm::unique_function<bool(diag::kind, SourceLocation /*DiagLoc*/,
+ const SourceManager &) const>
DiagSuppressionMapping;
public:
@@ -972,7 +973,7 @@ public:
/// These take presumed locations into account, and can still be overriden by
/// clang-diagnostics pragmas.
void setDiagSuppressionMapping(llvm::MemoryBuffer &Input);
- bool isSuppressedViaMapping(diag::kind DiagId, StringRef FilePath) const;
+ bool isSuppressedViaMapping(diag::kind DiagId, SourceLocation DiagLoc) const;
/// Issue the message to the client.
///
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 5155b23d151c..42c39ac6606c 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -67,7 +67,7 @@ def err_drv_no_cuda_libdevice : Error<
"libdevice">;
def err_drv_no_rocm_device_lib : Error<
- "cannot find ROCm device library%select{| for %1|for ABI version %1}0; provide its path via "
+ "cannot find ROCm device library%select{| for %1| for ABI version %1}0; provide its path via "
"'--rocm-path' or '--rocm-device-lib-path', or pass '-nogpulib' to build "
"without ROCm device library">;
def err_drv_no_hip_runtime : Error<
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 9fa8d5901bd0..86fcae209c40 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -721,6 +721,9 @@ def warn_empty_init_statement : Warning<
"has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore;
def err_keyword_as_parameter : Error <
"invalid parameter name: '%0' is a keyword">;
+def warn_pre_cxx26_ambiguous_pack_indexing_type : Warning<
+ "%0 is no longer a pack expansion but a pack "
+ "indexing type; add a name to specify a pack expansion">, InGroup<CXXPre26Compat>;
// C++ derived classes
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 2137cb713164..330ae045616a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3233,8 +3233,8 @@ def err_attribute_too_few_arguments : Error<
"%0 attribute takes at least %1 argument%s1">;
def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">;
def err_attribute_invalid_bitint_vector_type : Error<
- "'_BitInt' vector element width must be %select{a power of 2|"
- "at least as wide as 'CHAR_BIT'}0">;
+ "'_BitInt' %select{vector|matrix}0 element width must be %select{a power of 2|"
+ "at least as wide as 'CHAR_BIT'}1">;
def err_attribute_invalid_matrix_type : Error<"invalid matrix element type %0">;
def err_attribute_bad_neon_vector_size : Error<
"Neon vector size must be 64 or 128 bits">;
@@ -3423,7 +3423,7 @@ def warn_typecheck_vector_element_sizes_not_equal : Warning<
def err_ext_vector_component_exceeds_length : Error<
"vector component access exceeds type %0">;
def err_ext_vector_component_name_illegal : Error<
- "illegal vector component name '%0'">;
+ "illegal vector component name %0">;
def err_attribute_address_space_negative : Error<
"address space is negative">;
def err_attribute_address_space_too_high : Error<
@@ -3999,6 +3999,10 @@ def warn_thread_attribute_decl_not_lockable : Warning<
def warn_thread_attribute_decl_not_pointer : Warning<
"%0 only applies to pointer types; type here is %1">,
InGroup<ThreadSafetyAttributes>, DefaultIgnore;
+def warn_thread_attribute_not_on_scoped_lockable_param : Warning<
+ "%0 attribute applies to function parameters only if their type is a "
+ "reference to a 'scoped_lockable'-annotated type">,
+ InGroup<ThreadSafetyAttributes>, DefaultIgnore;
def err_attribute_argument_out_of_bounds_extra_info : Error<
"%0 attribute parameter %1 is out of bounds: "
"%plural{0:no parameters to index into|"
@@ -4054,6 +4058,17 @@ def warn_acquired_before : Warning<
def warn_acquired_before_after_cycle : Warning<
"cycle in acquired_before/after dependencies, starting with '%0'">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+def warn_unmatched_underlying_mutexes : Warning<
+ "%0 managed by '%1' is '%3' instead of '%2'">,
+ InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+def warn_expect_more_underlying_mutexes : Warning<
+ "%0 '%2' not managed by '%1'">,
+ InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+def warn_expect_fewer_underlying_mutexes : Warning<
+ "did not expect %0 '%2' to be managed by '%1'">,
+ InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+def note_managed_mismatch_here_for_param : Note<
+ "see attribute on parameter here">;
// Thread safety warnings negative capabilities
@@ -5863,10 +5878,10 @@ def err_pack_expansion_without_parameter_packs : Error<
"pack expansion does not contain any unexpanded parameter packs">;
def err_pack_expansion_length_conflict : Error<
"pack expansion contains parameter packs %0 and %1 that have different "
- "lengths (%2 vs. %3)">;
+ "lengths (%2 vs. %select{|at least }3%4))">;
def err_pack_expansion_length_conflict_multilevel : Error<
"pack expansion contains parameter pack %0 that has a different "
- "length (%1 vs. %2) from outer parameter packs">;
+ "length (%1 vs. %select{|at least }2%3) from outer parameter packs">;
def err_pack_expansion_length_conflict_partial : Error<
"pack expansion contains parameter pack %0 that has a different "
"length (at least %1 vs. %2) from outer parameter packs">;
@@ -10237,16 +10252,16 @@ def warn_dangling_pointer_assignment : Warning<
InGroup<DanglingAssignment>;
def warn_dangling_reference_captured : Warning<
"object whose reference is captured by '%0' will be destroyed at the end of "
- "the full-expression">, InGroup<DanglingCapture>, DefaultIgnore;
+ "the full-expression">, InGroup<DanglingCapture>;
def warn_dangling_reference_captured_by_unknown : Warning<
"object whose reference is captured will be destroyed at the end of "
- "the full-expression">, InGroup<DanglingCapture>, DefaultIgnore;
+ "the full-expression">, InGroup<DanglingCapture>;
// For non-floating point, expressions of the form x == x or x != x
// should result in a warning, since these always evaluate to a constant.
// Array comparisons have similar warnings
def warn_comparison_always : Warning<
- "%select{self-|array }0comparison always evaluates to "
+ "%select{self-|array |pointer }0comparison always evaluates to "
"%select{a constant|true|false|'std::strong_ordering::equal'}1">,
InGroup<TautologicalCompare>;
def warn_comparison_bitwise_always : Warning<
@@ -10274,6 +10289,11 @@ def warn_array_comparison : Warning<
"to compare array addresses, use unary '+' to decay operands to pointers">,
InGroup<DiagGroup<"array-compare">>;
+def warn_array_comparison_cxx26 : Warning<
+ "comparison between two arrays is ill-formed in C++26; "
+ "to compare array addresses, use unary '+' to decay operands to pointers">,
+ InGroup<DiagGroup<"array-compare-cxx26">>, DefaultError;
+
def warn_stringcompare : Warning<
"result of comparison against %select{a string literal|@encode}0 is "
"unspecified (use an explicit string comparison function instead)">,
@@ -12319,6 +12339,8 @@ def warn_noderef_to_dereferenceable_pointer : Warning<
def err_builtin_launder_invalid_arg : Error<
"%select{non-pointer|function pointer|void pointer}0 argument to "
"'__builtin_launder' is not allowed">;
+def err_builtin_assume_aligned_invalid_arg : Error<
+ "non-pointer argument to '__builtin_assume_aligned' is not allowed">;
def err_builtin_is_within_lifetime_invalid_arg : Error<
"%select{non-|function }0pointer argument to '__builtin_is_within_lifetime' "
@@ -12662,8 +12684,8 @@ def err_acc_int_expr_requires_integer
def err_acc_int_expr_incomplete_class_type
: Error<"OpenACC integer expression has incomplete class type %0">;
def err_acc_int_expr_explicit_conversion
- : Error<"OpenACC integer expression type %0 requires explicit conversion "
- "to %1">;
+ : Error<"OpenACC integer expression requires explicit conversion "
+ "from %0 to %1">;
def note_acc_int_expr_conversion
: Note<"conversion to %select{integral|enumeration}0 type %1">;
def err_acc_int_expr_multiple_conversions
@@ -12677,6 +12699,9 @@ def err_acc_not_a_var_ref
: Error<"OpenACC variable is not a valid variable name, sub-array, array "
"element,%select{| member of a composite variable,}0 or composite "
"variable member">;
+def err_acc_not_a_var_ref_use_device
+ : Error<"OpenACC variable in 'use_device' clause is not a valid variable "
+ "name or array name">;
def err_acc_typecheck_subarray_value
: Error<"OpenACC sub-array subscripted value is not an array or pointer">;
def err_acc_subarray_function_type
@@ -12711,9 +12736,9 @@ def err_acc_clause_cannot_combine
: Error<"OpenACC clause '%0' may not appear on the same construct as a "
"'%1' clause on a '%2' construct">;
def err_acc_reduction_num_gangs_conflict
- : Error<
- "OpenACC 'reduction' clause may not appear on a 'parallel' construct "
- "with a 'num_gangs' clause with more than 1 argument, have %0">;
+ : Error<"OpenACC '%1' clause %select{|with more than 1 argument }0may not "
+ "appear on a '%2' construct "
+ "with a '%3' clause%select{ with more than 1 argument|}0">;
def err_acc_reduction_type
: Error<"OpenACC 'reduction' variable must be of scalar type, sub-array, or a "
"composite of scalar types;%select{| sub-array base}1 type is %0">;
@@ -12755,31 +12780,33 @@ def err_acc_gang_multiple_elt
: Error<"OpenACC 'gang' clause may have at most one %select{unnamed or "
"'num'|'dim'|'static'}0 argument">;
def err_acc_int_arg_invalid
- : Error<"'%1' argument on '%0' clause is not permitted on a%select{n "
- "orphaned|||}2 'loop' construct %select{|associated with a "
- "'parallel' compute construct|associated with a 'kernels' compute "
- "construct|associated with a 'serial' compute construct}2">;
+ : Error<"'%0' argument on '%1' clause is not permitted on a%select{|n "
+ "orphaned}2 '%3' construct%select{| associated with a '%5' compute "
+ "construct}4">;
def err_acc_gang_dim_value
: Error<"argument to 'gang' clause dimension must be %select{a constant "
"expression|1, 2, or 3: evaluated to %1}0">;
def err_acc_num_arg_conflict
- : Error<"'num' argument to '%0' clause not allowed on a 'loop' construct "
- "associated with a 'kernels' construct that has a "
- "'%select{num_gangs|num_workers|vector_length}1' "
- "clause">;
+ : Error<"'%0' argument to '%1' clause not allowed on a '%2' "
+ "construct%select{| associated with a '%4' construct}3 that has a "
+ "'%5' clause">;
+def err_acc_num_arg_conflict_reverse
+ : Error<"'%0' clause not allowed on a 'kernels loop' construct that "
+ "has a '%1' clause with a%select{n| 'num'}2 argument">;
def err_acc_clause_in_clause_region
: Error<"loop with a '%0' clause may not exist in the region of a '%1' "
- "clause%select{| on a 'kernels' compute construct}2">;
+ "clause%select{| on a '%3' construct}2">;
def err_acc_gang_reduction_conflict
: Error<"%select{OpenACC 'gang' clause with a 'dim' value greater than "
"1|OpenACC 'reduction' clause}0 cannot "
- "appear on the same 'loop' construct as a %select{'reduction' "
+ "appear on the same '%1' construct as a %select{'reduction' "
"clause|'gang' clause with a 'dim' value greater than 1}0">;
def err_acc_gang_reduction_numgangs_conflict
- : Error<"OpenACC '%0' clause cannot appear on the same 'loop' construct "
- "as a '%1' clause inside a compute construct with a "
+ : Error<"OpenACC '%0' clause cannot appear on the same '%2' construct as a "
+ "'%1' clause %select{inside a compute construct with a|and a}3 "
"'num_gangs' clause with more than one argument">;
-def err_reduction_op_mismatch
+
+ def err_reduction_op_mismatch
: Error<"OpenACC 'reduction' variable must have the same operator in all "
"nested constructs (%0 vs %1)">;
def err_acc_loop_variable_type
@@ -12794,6 +12821,8 @@ def err_acc_loop_terminating_condition
def err_acc_loop_not_monotonic
: Error<"OpenACC '%0' variable must monotonically increase or decrease "
"('++', '--', or compound assignment)">;
+def err_acc_construct_one_clause_of
+ : Error<"OpenACC '%0' construct must have at least one %1 clause">;
// AMDGCN builtins diagnostics
def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">;
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index 15c59c6bcdf2..c82b6d9b5f6c 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -102,6 +102,7 @@ FEATURE(numerical_stability_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Nume
FEATURE(memory_sanitizer,
LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory |
SanitizerKind::KernelMemory))
+FEATURE(type_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Type))
FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
diff --git a/clang/include/clang/Basic/FileEntry.h b/clang/include/clang/Basic/FileEntry.h
index 68d4bf609300..da5ba9097429 100644
--- a/clang/include/clang/Basic/FileEntry.h
+++ b/clang/include/clang/Basic/FileEntry.h
@@ -68,8 +68,13 @@ public:
StringRef getNameAsRequested() const { return ME->first(); }
const FileEntry &getFileEntry() const {
- return *getBaseMapEntry().second->V.get<FileEntry *>();
+ return *cast<FileEntry *>(getBaseMapEntry().second->V);
}
+
+ // This function is used if the buffer size needs to be increased
+ // due to potential z/OS EBCDIC -> UTF-8 conversion
+ inline void updateFileEntryBufferSize(unsigned BufferSize);
+
DirectoryEntryRef getDir() const { return ME->second->Dir; }
inline off_t getSize() const;
@@ -323,6 +328,8 @@ public:
StringRef tryGetRealPathName() const { return RealPathName; }
off_t getSize() const { return Size; }
+ // Size may increase due to potential z/OS EBCDIC -> UTF-8 conversion.
+ void setSize(off_t NewSize) { Size = NewSize; }
unsigned getUID() const { return UID; }
const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
time_t getModificationTime() const { return ModTime; }
@@ -353,6 +360,10 @@ bool FileEntryRef::isNamedPipe() const { return getFileEntry().isNamedPipe(); }
void FileEntryRef::closeFile() const { getFileEntry().closeFile(); }
+void FileEntryRef::updateFileEntryBufferSize(unsigned BufferSize) {
+ cast<FileEntry *>(getBaseMapEntry().second->V)->setSize(BufferSize);
+}
+
} // end namespace clang
#endif // LLVM_CLANG_BASIC_FILEENTRY_H
diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h
index ae9ebd9f5915..33d1cdb46f10 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -1012,7 +1012,7 @@ class Selector {
}
MultiKeywordSelector *getMultiKeywordSelector() const {
- return InfoPtr.getPointer().get<MultiKeywordSelector *>();
+ return cast<MultiKeywordSelector *>(InfoPtr.getPointer());
}
unsigned getIdentifierInfoFlag() const {
@@ -1020,7 +1020,7 @@ class Selector {
// IMPORTANT NOTE: We have to reconstitute this data rather than use the
// value directly from the PointerIntPair. See the comments in `InfoPtr`
// for more details.
- if (InfoPtr.getPointer().is<MultiKeywordSelector *>())
+ if (isa<MultiKeywordSelector *>(InfoPtr.getPointer()))
new_flags |= MultiArg;
return new_flags;
}
diff --git a/clang/include/clang/Basic/OpenACCClauses.def b/clang/include/clang/Basic/OpenACCClauses.def
index c65ebed751cf..1b619bc0dfd4 100644
--- a/clang/include/clang/Basic/OpenACCClauses.def
+++ b/clang/include/clang/Basic/OpenACCClauses.def
@@ -38,12 +38,17 @@ VISIT_CLAUSE(Create)
CLAUSE_ALIAS(PCreate, Create, true)
CLAUSE_ALIAS(PresentOrCreate, Create, true)
VISIT_CLAUSE(Default)
+VISIT_CLAUSE(Delete)
+VISIT_CLAUSE(Detach)
+VISIT_CLAUSE(DeviceNum)
VISIT_CLAUSE(DevicePtr)
VISIT_CLAUSE(DeviceType)
CLAUSE_ALIAS(DType, DeviceType, false)
+VISIT_CLAUSE(Finalize)
VISIT_CLAUSE(FirstPrivate)
VISIT_CLAUSE(Gang)
VISIT_CLAUSE(If)
+VISIT_CLAUSE(IfPresent)
VISIT_CLAUSE(Independent)
VISIT_CLAUSE(NoCreate)
VISIT_CLAUSE(NumGangs)
@@ -54,6 +59,7 @@ VISIT_CLAUSE(Reduction)
VISIT_CLAUSE(Self)
VISIT_CLAUSE(Seq)
VISIT_CLAUSE(Tile)
+VISIT_CLAUSE(UseDevice)
VISIT_CLAUSE(Vector)
VISIT_CLAUSE(VectorLength)
VISIT_CLAUSE(Wait)
diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index ea0bf23468cb..7fb76271826a 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -158,6 +158,14 @@ inline bool isOpenACCCombinedDirectiveKind(OpenACCDirectiveKind K) {
K == OpenACCDirectiveKind::KernelsLoop;
}
+// Tests 'K' to see if it is 'data', 'host_data', 'enter data', or 'exit data'.
+inline bool isOpenACCDataDirectiveKind(OpenACCDirectiveKind K) {
+ return K == OpenACCDirectiveKind::Data ||
+ K == OpenACCDirectiveKind::EnterData ||
+ K == OpenACCDirectiveKind::ExitData ||
+ K == OpenACCDirectiveKind::HostData;
+}
+
enum class OpenACCAtomicKind : uint8_t {
Read,
Write,
diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def
index 9223f62b3639..f234488eaa80 100644
--- a/clang/include/clang/Basic/Sanitizers.def
+++ b/clang/include/clang/Basic/Sanitizers.def
@@ -73,6 +73,9 @@ SANITIZER("fuzzer", Fuzzer)
// libFuzzer-required instrumentation, no linking.
SANITIZER("fuzzer-no-link", FuzzerNoLink)
+// TypeSanitizer
+SANITIZER("type", Type)
+
// ThreadSanitizer
SANITIZER("thread", Thread)
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index 89f5a76eb113..31280df93e4c 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -308,6 +308,13 @@ def OpenACCAssociatedStmtConstruct
def OpenACCComputeConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;
def OpenACCLoopConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;
def OpenACCCombinedConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;
+def OpenACCDataConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;
+def OpenACCEnterDataConstruct : StmtNode<OpenACCConstructStmt>;
+def OpenACCExitDataConstruct : StmtNode<OpenACCConstructStmt>;
+def OpenACCHostDataConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;
+def OpenACCWaitConstruct : StmtNode<OpenACCConstructStmt>;
+def OpenACCInitConstruct : StmtNode<OpenACCConstructStmt>;
+def OpenACCShutdownConstruct : StmtNode<OpenACCConstructStmt>;
// OpenACC Additional Expressions.
def OpenACCAsteriskSizeExpr : StmtNode<Expr>;
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 4420228793e9..f2905f30a7c3 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -358,7 +358,14 @@ public:
// void *__saved_reg_area_end_pointer;
// void *__overflow_area_pointer;
//} va_list;
- HexagonBuiltinVaList
+ HexagonBuiltinVaList,
+
+ // typedef struct __va_list_tag {
+ // int* __va_stk;
+ // int* __va_reg;
+ // int __va_ndx;
+ //} va_list;
+ XtensaABIBuiltinVaList
};
protected:
@@ -1009,7 +1016,6 @@ public:
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const = 0;
-
/// Return information about target-specific builtins for
/// the current primary target, and info about which builtins are non-portable
/// across the current set of primary and secondary targets.
diff --git a/clang/include/clang/Basic/arm_immcheck_incl.td b/clang/include/clang/Basic/arm_immcheck_incl.td
index 9d7f74a35aaa..6892b8299771 100644
--- a/clang/include/clang/Basic/arm_immcheck_incl.td
+++ b/clang/include/clang/Basic/arm_immcheck_incl.td
@@ -2,7 +2,9 @@ class ImmCheckType<int val> {
int Value = val;
}
-// These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h
+
+// For SVE, container_size refers to the width of a vector segment (128b).
+// For NEON, container_size refers to the vector width (64b or 128b).
def ImmCheck0_31 : ImmCheckType<0>; // 0..31 (used for e.g. predicate patterns)
def ImmCheck1_16 : ImmCheckType<1>; // 1..16
def ImmCheckExtract : ImmCheckType<2>; // 0..(2048/sizeinbits(elt) - 1)
@@ -10,10 +12,10 @@ def ImmCheckShiftRight : ImmCheckType<3>; // 1..sizeinbits(elt)
def ImmCheckShiftRightNarrow : ImmCheckType<4>; // 1..sizeinbits(elt)/2
def ImmCheckShiftLeft : ImmCheckType<5>; // 0..(sizeinbits(elt) - 1)
def ImmCheck0_7 : ImmCheckType<6>; // 0..7
-def ImmCheckLaneIndex : ImmCheckType<7>; // 0..(sizeinbits(vec)/(sizeinbits(elt)) - 1)
+def ImmCheckLaneIndex : ImmCheckType<7>; // 0..(container_size/(sizeinbits(elt)) - 1)
def ImmCheckCvt : ImmCheckType<8>; // 1..sizeinbits(elt) (same as ShiftRight)
-def ImmCheckLaneIndexCompRotate : ImmCheckType<9>; // 0..(sizeinbits(vec)/(2*sizeinbits(elt)) - 1)
-def ImmCheckLaneIndexDot : ImmCheckType<10>; // 0..(sizeinbits(vec)/(4*sizeinbits(elt)) - 1)
+def ImmCheckLaneIndexCompRotate : ImmCheckType<9>; // 0..(container_size/(2*sizeinbits(elt)) - 1)
+def ImmCheckLaneIndexDot : ImmCheckType<10>; // 0..(container_size/(4*sizeinbits(elt)) - 1)
def ImmCheckComplexRot90_270 : ImmCheckType<11>; // [90,270]
def ImmCheckComplexRotAll90 : ImmCheckType<12>; // [0, 90, 180,270]
def ImmCheck0_13 : ImmCheckType<13>; // 0..13
diff --git a/clang/include/clang/Basic/arm_mve.td b/clang/include/clang/Basic/arm_mve.td
index 93abbc47c54d..6dd8c52ddfd7 100644
--- a/clang/include/clang/Basic/arm_mve.td
+++ b/clang/include/clang/Basic/arm_mve.td
@@ -1270,13 +1270,13 @@ defm sqrshr: ScalarSaturatingShiftReg<s32, s64>;
def lsll: LongScalarShift<u64, (args s32:$sh), (IRInt<"lsll"> $lo, $hi, $sh)>;
def asrl: LongScalarShift<s64, (args s32:$sh), (IRInt<"asrl"> $lo, $hi, $sh)>;
-multiclass vadcsbc {
+multiclass vadcsbc<dag initial_carry_in> {
def q: Intrinsic<Vector, (args Vector:$a, Vector:$b, Ptr<uint>:$carry),
(seq (IRInt<NAME, [Vector]> $a, $b, (shl (load $carry), 29)):$pair,
(store (and 1, (lshr (xval $pair, 1), 29)), $carry),
(xval $pair, 0))>;
def iq: Intrinsic<Vector, (args Vector:$a, Vector:$b, Ptr<uint>:$carry),
- (seq (IRInt<NAME, [Vector]> $a, $b, 0):$pair,
+ (seq (IRInt<NAME, [Vector]> $a, $b, initial_carry_in):$pair,
(store (and 1, (lshr (xval $pair, 1), 29)), $carry),
(xval $pair, 0))>;
def q_m: Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b,
@@ -1288,13 +1288,13 @@ multiclass vadcsbc {
def iq_m: Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b,
Ptr<uint>:$carry, Predicate:$pred),
(seq (IRInt<NAME # "_predicated", [Vector, Predicate]> $inactive, $a, $b,
- 0, $pred):$pair,
+ initial_carry_in, $pred):$pair,
(store (and 1, (lshr (xval $pair, 1), 29)), $carry),
(xval $pair, 0))>;
}
let params = T.Int32 in {
- defm vadc: vadcsbc;
- defm vsbc: vadcsbc;
+ defm vadc: vadcsbc<(u32 0)>;
+ defm vsbc: vadcsbc<(shl 1, 29)>;
}
let params = T.Int in {
diff --git a/clang/include/clang/Basic/arm_sme.td b/clang/include/clang/Basic/arm_sme.td
index 0f689e82bdb7..6b31dec004a1 100644
--- a/clang/include/clang/Basic/arm_sme.td
+++ b/clang/include/clang/Basic/arm_sme.td
@@ -740,6 +740,38 @@ let SMETargetGuard = "sme2" in {
def SVLUTI4_LANE_ZT_X2 : Inst<"svluti4_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x2", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>;
}
+//
+// SME2 FP8 instructions
+//
+
+// FDOT
+let SMETargetGuard = "sme-f8f32" in {
+ def SVDOT_LANE_FP8_ZA32_VG1x2 : Inst<"svdot_lane_za32[_mf8]_vg1x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVDOT_LANE_FP8_ZA32_VG1x4 : Inst<"svdot_lane_za32[_mf8]_vg1x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>;
+
+ def SVVDOTB_LANE_FP8_ZA32_VG1x4 : Inst<"svvdotb_lane_za32[_mf8]_vg1x4_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdotb_lane_za32_vg1x4", [IsOverloadNone, IsStreaming, IsInOutZA, SetsFPMR], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVVDOTT_LANE_FP8_ZA32_VG1x4 : Inst<"svvdott_lane_za32[_mf8]_vg1x4_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdott_lane_za32_vg1x4", [IsOverloadNone, IsStreaming, IsInOutZA, SetsFPMR], [ImmCheck<3, ImmCheck0_3>]>;
+
+ def SVDOT_SINGLE_FP8_ZA32_VG1x2 : Inst<"svdot[_single]_za32[_mf8]_vg1x2_fpm", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za32_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ def SVDOT_SINGLE_FP8_ZA32_VG1x4 : Inst<"svdot[_single]_za32[_mf8]_vg1x4_fpm", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za32_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+
+ def SVDOT_MULTI_FP8_ZA32_VG1x2 : Inst<"svdot_za32[_mf8]_vg1x2_fpm", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za32_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ def SVDOT_MULTI_FP8_ZA32_VG1x4 : Inst<"svdot_za32[_mf8]_vg1x4_fpm", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za32_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+}
+
+let SMETargetGuard = "sme-f8f16" in {
+ def SVDOT_LANE_FP8_ZA16_VG1x2 : Inst<"svdot_lane_za16[_mf8]_vg1x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za16_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVDOT_LANE_FP8_ZA16_VG1x4 : Inst<"svdot_lane_za16[_mf8]_vg1x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za16_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>;
+
+ def SVVDOT_LANE_FP8_ZA16_VG1x2 : Inst<"svvdot_lane_za16[_mf8]_vg1x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdot_lane_za16_vg1x2", [IsOverloadNone, IsStreaming, IsInOutZA, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>;
+
+ def SVDOT_SINGLE_FP8_ZA16_VG1x2 : Inst<"svdot[_single]_za16[_mf8]_vg1x2_fpm", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za16_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ def SVDOT_SINGLE_FP8_ZA16_VG1x4 : Inst<"svdot[_single]_za16[_mf8]_vg1x4_fpm", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za16_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+
+ def SVDOT_MULTI_FP8_ZA16_VG1x2 : Inst<"svdot_za16[_mf8]_vg1x2_fpm", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za16_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ def SVDOT_MULTI_FP8_ZA16_VG1x4 : Inst<"svdot_za16[_mf8]_vg1x4_fpm", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za16_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+}
+
////////////////////////////////////////////////////////////////////////////////
// SME2p1 - FMOPA, FMOPS (non-widening)
let SMETargetGuard = "sme-b16b16" in {
@@ -824,4 +856,52 @@ let SMETargetGuard = "sme-lutv2" in {
def SVLUTI4_ZT_X4 : SInst<"svluti4_zt_{d}_x4", "4i2.u", "cUc", MergeNone, "aarch64_sme_luti4_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>]>;
}
+let SMETargetGuard = "sme-f8f32" in {
+ def SVMOPA_FP8_ZA32 : Inst<"svmopa_za32[_mf8]_m_fpm", "viPPdd>", "m", MergeNone, "aarch64_sme_fp8_fmopa_za32",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<0, ImmCheck0_3>]>;
+ // FMLALL (indexed)
+ def SVMLA_FP8_LANE_ZA32_VG4x1 : Inst<"svmla_lane_za32[_mf8]_vg4x1_fpm", "vmddi>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x1",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLA_FP8_LANE_ZA32_VG4x2 : Inst<"svmla_lane_za32[_mf8]_vg4x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x2",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLA_FP8_LANE_ZA16_VG4x4 : Inst<"svmla_lane_za32[_mf8]_vg4x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x4",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>;
+ // FMLALL (single)
+ def SVMLA_FP8_SINGLE_ZA32_VG4x1 : Inst<"svmla[_single]_za32[_mf8]_vg4x1_fpm", "vmdd>", "m", MergeNone, "aarch64_sme_fp8_fmlall_single_za32_vg4x1",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ def SVMLA_FP8_SINGLE_ZA32_VG4x2 : Inst<"svmla[_single]_za32[_mf8]_vg4x2_fpm", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fmlall_single_za32_vg4x2",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ def SVMLA_FP8_SINGLE_ZA32_VG4x4 : Inst<"svmla[_single]_za32[_mf8]_vg4x4_fpm", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fmlall_single_za32_vg4x4",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ // FMLALL (multiple)
+ def SVMLA_FP8_MULTI_ZA32_VG4x2 : Inst<"svmla_za32[_mf8]_vg4x2_fpm", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fmlall_multi_za32_vg4x2",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ def SVMLA_FP8_MULTI_ZA32_VG4x4 : Inst<"svmla_za32[_mf8]_vg4x4_fpm", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fmlall_multi_za32_vg4x4",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+}
+
+let SMETargetGuard = "sme-f8f16" in {
+ def SVMOPA_FP8_ZA16 : Inst<"svmopa_za16[_mf8]_m_fpm", "viPPdd>", "m", MergeNone, "aarch64_sme_fp8_fmopa_za16",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<0, ImmCheck0_1>]>;
+ // FMLAL (indexed)
+ def SVMLA_FP8_LANE_ZA16_VG2x1 : Inst<"svmla_lane_za16[_mf8]_vg2x1_fpm", "vmddi>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x1",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLA_FP8_LANE_ZA16_VG2x2 : Inst<"svmla_lane_za16[_mf8]_vg2x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x2",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLA_FP8_LANE_ZA16_VG2x4 : Inst<"svmla_lane_za16[_mf8]_vg2x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x4",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>;
+ // FMLAL (single)
+ def SVMLA_FP8_SINGLE_ZA16_VG2x1 : Inst<"svmla[_single]_za16[_mf8]_vg2x1_fpm", "vmdd>", "m", MergeNone, "aarch64_sme_fp8_fmlal_single_za16_vg2x1",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ def SVMLA_FP8_SINGLE_ZA16_VG2x2 : Inst<"svmla[_single]_za16[_mf8]_vg2x2_fpm", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fmlal_single_za16_vg2x2",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ def SVMLA_FP8_SINGLE_ZA16_VG2x4 : Inst<"svmla[_single]_za16[_mf8]_vg2x4_fpm", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fmlal_single_za16_vg2x4",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ // FMLAL (multiple)
+ def SVMLA_FP8_MULTI_ZA16_VG2x2 : Inst<"svmla_za16[_mf8]_vg2x2_fpm", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fmlal_multi_za16_vg2x2",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+ def SVMLA_FP8_MULTI_ZA16_VG2x4 : Inst<"svmla_za16[_mf8]_vg2x4_fpm", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fmlal_multi_za16_vg2x4",
+ [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>;
+}
+
} // let SVETargetGuard = InvalidMode
diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td
index e551d6e46b8f..1c6bdb8cad2d 100644
--- a/clang/include/clang/Basic/arm_sve.td
+++ b/clang/include/clang/Basic/arm_sve.td
@@ -463,18 +463,19 @@ let SVETargetGuard = "sve,bf16", SMETargetGuard = "sme,bf16" in {
let SVETargetGuard = "sve2p1", SMETargetGuard = InvalidMode in {
// Contiguous truncating store from quadword (single vector).
- def SVST1UWQ : MInst<"svst1wq[_{d}]", "vPcd", "iUif", [IsStore], MemEltTyInt32, "aarch64_sve_st1wq">;
- def SVST1UWQ_VNUM : MInst<"svst1wq_vnum[_{d}]", "vPcld", "iUif", [IsStore], MemEltTyInt32, "aarch64_sve_st1wq">;
+ def SVST1UWQ : MInst<"svst1wq[_{d}]", "vPpd", "iUif", [IsStore], MemEltTyInt32, "aarch64_sve_st1wq">;
+ def SVST1UWQ_VNUM : MInst<"svst1wq_vnum[_{d}]", "vPpld", "iUif", [IsStore], MemEltTyInt32, "aarch64_sve_st1wq">;
- def SVST1UDQ : MInst<"svst1dq[_{d}]", "vPcd", "lUld", [IsStore], MemEltTyInt64, "aarch64_sve_st1dq">;
- def SVST1UDQ_VNUM : MInst<"svst1dq_vnum[_{d}]", "vPcld", "lUld", [IsStore], MemEltTyInt64, "aarch64_sve_st1dq">;
+ def SVST1UDQ : MInst<"svst1dq[_{d}]", "vPpd", "lUld", [IsStore], MemEltTyInt64, "aarch64_sve_st1dq">;
+ def SVST1UDQ_VNUM : MInst<"svst1dq_vnum[_{d}]", "vPpld", "lUld", [IsStore], MemEltTyInt64, "aarch64_sve_st1dq">;
// Store one vector (vector base + scalar offset)
def SVST1Q_SCATTER_U64BASE_OFFSET : MInst<"svst1q_scatter[_{2}base]_offset[_{d}]", "vPgld", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_scalar_offset">;
def SVST1Q_SCATTER_U64BASE : MInst<"svst1q_scatter[_{2}base][_{d}]", "vPgd", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_scalar_offset">;
// Store one vector (scalar base + vector offset)
- def SVST1Q_SCATTER_U64OFFSET : MInst<"svst1q_scatter_[{3}]offset[_{d}]", "vPpgd", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_vector_offset">;
+ def SVST1Q_SCATTER_OFFSETS_U : MInst<"svst1q_scatter_[{3}]offset[_{d}]", "vPpgd", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_vector_offset">;
+ def SVST1Q_SCATTER_OFFSETS_S : MInst<"svst1q_scatter_[{3}]offset[_{d}]", "vPp#d", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_vector_offset">;
// Store N vectors into N-element structure (scalar base)
defm SVST2Q : StructStore<"svst2q[_{d}]", "vPc2", "aarch64_sve_st2q">;
@@ -488,6 +489,7 @@ let SVETargetGuard = "sve2p1", SMETargetGuard = InvalidMode in {
// Scatter store quadwords (scalar base + vector index)
def SVST1Q_SCATTER_INDICES_U : MInst<"svst1q_scatter_[{3}]index[_{d}]", "vPpgd", "sUsiUilUlbhfd", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1q_scatter_index">;
+ def SVST1Q_SCATTER_INDICES_S : MInst<"svst1q_scatter_[{3}]index[_{d}]", "vPp#d", "sUsiUilUlbhfd", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1q_scatter_index">;
// Scatter store quadwords (vector base + scalar index)
def SVST1Q_SCATTER_INDEX_S : MInst<"svst1q_scatter[_{2}base]_index[_{d}]", "vPgld", "sUsiUilUlbhfd", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1q_scatter_scalar_offset">;
@@ -2429,9 +2431,19 @@ let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2,fp8" in {
def FSCALE_X2 : Inst<"svscale[_{d}_x2]", "222.x", "fhd", MergeNone, "aarch64_sme_fp8_scale_x2", [IsStreaming],[]>;
def FSCALE_X4 : Inst<"svscale[_{d}_x4]", "444.x", "fhd", MergeNone, "aarch64_sme_fp8_scale_x4", [IsStreaming],[]>;
+ // Convert from FP8 to half-precision/BFloat16 multi-vector
+ def SVF1CVT_X2 : Inst<"svcvt1_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvt1_x2", [IsStreaming, SetsFPMR], []>;
+ def SVF2CVT_X2 : Inst<"svcvt2_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvt2_x2", [IsStreaming, SetsFPMR], []>;
+
// Convert from FP8 to deinterleaved half-precision/BFloat16 multi-vector
- def SVF1CVTL : Inst<"svcvtl1_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl1_x2", [IsStreaming, SetsFPMR], []>;
- def SVF2CVTL : Inst<"svcvtl2_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl2_x2", [IsStreaming, SetsFPMR], []>;
+ def SVF1CVTL_X2 : Inst<"svcvtl1_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl1_x2", [IsStreaming, SetsFPMR], []>;
+ def SVF2CVTL_X2 : Inst<"svcvtl2_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl2_x2", [IsStreaming, SetsFPMR], []>;
+
+ // Convert from single/half/bfloat multivector to FP8
+ def SVFCVT_X2 : Inst<"svcvt_mf8[_{d}_x2]_fpm", "~2>", "bh", MergeNone, "aarch64_sve_fp8_cvt_x2", [IsStreaming, SetsFPMR], []>;
+ def SVFCVT_X4 : Inst<"svcvt_mf8[_{d}_x4]_fpm", "~4>", "f", MergeNone, "aarch64_sve_fp8_cvt_x4", [IsOverloadNone, IsStreaming, SetsFPMR], []>;
+ // interleaved
+ def SVFCVTN_X4 : Inst<"svcvtn_mf8[_{d}_x4]_fpm", "~4>", "f", MergeNone, "aarch64_sve_fp8_cvtn_x4", [IsOverloadNone, IsStreaming, SetsFPMR], []>;
}
let SVETargetGuard = "sve2p1", SMETargetGuard = "sme2" in {
@@ -2447,3 +2459,72 @@ let SVETargetGuard = "sve2,faminmax", SMETargetGuard = "sme2,faminmax" in {
defm SVAMIN : SInstZPZZ<"svamin", "hfd", "aarch64_sve_famin", "aarch64_sve_famin_u">;
defm SVAMAX : SInstZPZZ<"svamax", "hfd", "aarch64_sve_famax", "aarch64_sve_famax_u">;
}
+
+let SVETargetGuard = "sve2,fp8", SMETargetGuard = "sme2,fp8" in {
+ // SVE FP8 widening conversions
+
+ // 8-bit floating-point convert to BFloat16/Float16
+ def SVF1CVT : SInst<"svcvt1_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvt1", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVF2CVT : SInst<"svcvt2_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvt2", [VerifyRuntimeMode, SetsFPMR]>;
+
+ // 8-bit floating-point convert to BFloat16/Float16 (top)
+ def SVF1CVTLT : SInst<"svcvtlt1_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvtlt1", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVF2CVTLT : SInst<"svcvtlt2_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvtlt2", [VerifyRuntimeMode, SetsFPMR]>;
+
+ // BFloat16/Float16 convert, narrow and interleave to 8-bit floating-point
+ def SVFCVTN : SInst<"svcvtn_mf8[_{d}_x2]_fpm", "~2>", "bh", MergeNone, "aarch64_sve_fp8_cvtn", [VerifyRuntimeMode, SetsFPMR]>;
+
+ // Single-precision convert, narrow and interleave to 8-bit floating-point (top and bottom)
+ def SVFCVTNB : SInst<"svcvtnb_mf8[_f32_x2]_fpm", "~2>", "f", MergeNone, "aarch64_sve_fp8_cvtnb", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFCVTNT : SInst<"svcvtnt_mf8[_f32_x2]_fpm", "~~2>", "f", MergeNone, "aarch64_sve_fp8_cvtnt", [VerifyRuntimeMode, SetsFPMR]>;
+}
+
+let SVETargetGuard = "sve2,fp8dot2", SMETargetGuard ="sme,ssve-fp8dot2" in {
+ // 8-bit floating-point dot product to half-precision (vectors)
+ def SVFDOT_2WAY : SInst<"svdot[_f16_mf8]_fpm", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFDOT_N_2WAY : SInst<"svdot[_n_f16_mf8]_fpm", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>;
+
+ // 8-bit floating-point dot product to half-precision (indexed)
+ def SVFDOT_LANE_2WAY : SInst<"svdot_lane[_f16_mf8]_fpm", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fdot_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>;
+}
+
+let SVETargetGuard = "sve2,fp8dot4", SMETargetGuard ="sme,ssve-fp8dot4" in {
+ // 8-bit floating-point dot product to single-precision (vectors)
+ def SVFDOT_4WAY : SInst<"svdot[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFDOT_N_4WAY : SInst<"svdot[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>;
+
+ // 8-bit floating-point dot product to single-precision (indexed)
+ def SVFDOT_LANE_4WAY : SInst<"svdot_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fdot_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_3>]>;
+}
+
+let SVETargetGuard = "sve2,fp8fma", SMETargetGuard = "sme,ssve-fp8fma" in {
+ // 8-bit floating-point multiply-add long to half-precision (bottom)
+ def SVFMLALB : SInst<"svmlalb[_f16_mf8]_fpm", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fmlalb", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFMLALB_N : SInst<"svmlalb[_n_f16_mf8]_fpm", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fmlalb", [VerifyRuntimeMode, SetsFPMR]>;
+
+ // 8-bit floating-point multiply-add long to ha_fpmlf-precision (bottom, indexed)
+ def SVFMLALB_LANE : SInst<"svmlalb_lane[_f16_mf8]_fpm", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fmlalb_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_15>]>;
+
+ // 8-bit floating-point multiply-add long to half-precision (top)
+ def SVFMLALT : SInst<"svmlalt[_f16_mf8]_fpm", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fmlalt", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFMLALT_N : SInst<"svmlalt[_n_f16_mf8]_fpm", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fmlalt", [VerifyRuntimeMode, SetsFPMR]>;
+
+ // 8-bit floating-point multiply-add long to half-precision (top, indexed)
+ def SVFMLALT_LANE : SInst<"svmlalt_lane[_f16_mf8]_fpm", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fmlalt_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_15>]>;
+
+ // 8-bit floating-point multiply-add long long to single-precision (all top/bottom variants)
+ def SVFMLALLBB : SInst<"svmlallbb[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFMLALLBB_N : SInst<"svmlallbb[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFMLALLBT : SInst<"svmlallbt[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFMLALLBT_N : SInst<"svmlallbt[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFMLALLTB : SInst<"svmlalltb[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFMLALLTB_N : SInst<"svmlalltb[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFMLALLTT : SInst<"svmlalltt[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt", [VerifyRuntimeMode, SetsFPMR]>;
+ def SVFMLALLTT_N : SInst<"svmlalltt[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt", [VerifyRuntimeMode, SetsFPMR]>;
+
+ // 8-bit floating-point multiply-add long long to single-precision (indexed, all top/bottom variants)
+ def SVFMLALLBB_LANE : SInst<"svmlallbb_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVFMLALLBT_LANE : SInst<"svmlallbt_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVFMLALLTB_LANE : SInst<"svmlalltb_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVFMLALLTT_LANE : SInst<"svmlalltt_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>;
+}
diff --git a/clang/include/clang/Basic/arm_sve_sme_incl.td b/clang/include/clang/Basic/arm_sve_sme_incl.td
index de10be7bdce0..13e7cf45471c 100644
--- a/clang/include/clang/Basic/arm_sve_sme_incl.td
+++ b/clang/include/clang/Basic/arm_sve_sme_incl.td
@@ -52,6 +52,7 @@ include "arm_immcheck_incl.td"
// h: half-float
// d: double
// b: bfloat
+// m: mfloat8
// Typespec modifiers
// ------------------
@@ -69,6 +70,7 @@ include "arm_immcheck_incl.td"
// x: vector of signed integers
// u: vector of unsigned integers
// d: default
+// p: pointer type
// c: const pointer type
// P: predicate type
// s: scalar of element type
@@ -88,6 +90,7 @@ include "arm_immcheck_incl.td"
// j: element type promoted to 64bits (splat to vector type)
// K: element type bitcast to a signed integer (splat to vector type)
// L: element type bitcast to an unsigned integer (splat to vector type)
+// !: mfloat8_t (splat to svmfloat8_t)
//
// i: constant uint64_t
// k: int32_t
@@ -99,6 +102,7 @@ include "arm_immcheck_incl.td"
// [: svuint8_t
// t: svint32_t
// z: svuint32_t
+// #: svint64_t
// g: svuint64_t
// O: svfloat16_t
// M: svfloat32_t
diff --git a/clang/include/clang/CIR/CIRGenerator.h b/clang/include/clang/CIR/CIRGenerator.h
index c8ca7e4bfa72..414eba80b88b 100644
--- a/clang/include/clang/CIR/CIRGenerator.h
+++ b/clang/include/clang/CIR/CIRGenerator.h
@@ -37,14 +37,14 @@ namespace cir {
class CIRGenerator : public clang::ASTConsumer {
virtual void anchor();
clang::DiagnosticsEngine &diags;
- clang::ASTContext *astCtx;
+ clang::ASTContext *astContext;
// Only used for debug info.
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs;
const clang::CodeGenOptions &codeGenOpts;
protected:
- std::unique_ptr<mlir::MLIRContext> mlirCtx;
+ std::unique_ptr<mlir::MLIRContext> mlirContext;
std::unique_ptr<clang::CIRGen::CIRGenModule> cgm;
public:
@@ -52,7 +52,7 @@ public:
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs,
const clang::CodeGenOptions &cgo);
~CIRGenerator() override;
- void Initialize(clang::ASTContext &astCtx) override;
+ void Initialize(clang::ASTContext &astContext) override;
bool HandleTopLevelDecl(clang::DeclGroupRef group) override;
mlir::ModuleOp getModule() const;
};
diff --git a/clang/include/clang/CIR/CMakeLists.txt b/clang/include/clang/CIR/CMakeLists.txt
index f8d6f407a03d..e20c896171c9 100644
--- a/clang/include/clang/CIR/CMakeLists.txt
+++ b/clang/include/clang/CIR/CMakeLists.txt
@@ -4,3 +4,4 @@ include_directories(${MLIR_INCLUDE_DIR})
include_directories(${MLIR_TABLEGEN_OUTPUT_DIR})
add_subdirectory(Dialect)
+add_subdirectory(Interfaces)
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
new file mode 100644
index 000000000000..b4a961de224a
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
+#define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
+
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/Types.h"
+
+namespace cir {
+
+class CIRBaseBuilderTy : public mlir::OpBuilder {
+
+public:
+ CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
+ : mlir::OpBuilder(&mlirContext) {}
+
+ cir::PointerType getPointerTo(mlir::Type ty) {
+ return cir::PointerType::get(getContext(), ty);
+ }
+
+ cir::PointerType getVoidPtrTy() {
+ return getPointerTo(cir::VoidType::get(getContext()));
+ }
+
+ mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value) {
+ auto valueAttr = mlir::IntegerAttr::get(
+ mlir::IntegerType::get(type.getContext(), 64), value);
+ return cir::ConstPtrAttr::get(
+ getContext(), mlir::cast<cir::PointerType>(type), valueAttr);
+ }
+};
+
+} // namespace cir
+
+#endif
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
new file mode 100644
index 000000000000..438fb7d09608
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 declares the attributes in the CIR dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H
+#define LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H
+
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
+
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/BuiltinAttributeInterfaces.h"
+
+#include "llvm/ADT/SmallVector.h"
+
+//===----------------------------------------------------------------------===//
+// CIR Dialect Attrs
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+class FunctionDecl;
+class VarDecl;
+class RecordDecl;
+} // namespace clang
+
+#define GET_ATTRDEF_CLASSES
+#include "clang/CIR/Dialect/IR/CIROpsAttributes.h.inc"
+
+#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
new file mode 100644
index 000000000000..bd1665e1ac1a
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -0,0 +1,142 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 declares the CIR dialect attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_TD
+#define LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_TD
+
+include "mlir/IR/BuiltinAttributeInterfaces.td"
+include "mlir/IR/EnumAttr.td"
+
+include "clang/CIR/Dialect/IR/CIRDialect.td"
+
+//===----------------------------------------------------------------------===//
+// CIR Attrs
+//===----------------------------------------------------------------------===//
+
+class CIR_Attr<string name, string attrMnemonic, list<Trait> traits = []>
+ : AttrDef<CIR_Dialect, name, traits> {
+ let mnemonic = attrMnemonic;
+}
+
+class CIRUnitAttr<string name, string attrMnemonic, list<Trait> traits = []>
+ : CIR_Attr<name, attrMnemonic, traits> {
+ let returnType = "bool";
+ let defaultValue = "false";
+ let valueType = NoneType;
+ let isOptional = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// IntegerAttr
+//===----------------------------------------------------------------------===//
+
+def IntAttr : CIR_Attr<"Int", "int", [TypedAttrInterface]> {
+ let summary = "An attribute containing an integer value";
+ let description = [{
+ An integer attribute is a literal attribute that represents an integral
+ value of the specified integer type.
+ }];
+ let parameters = (ins AttributeSelfTypeParameter<"">:$type,
+ "llvm::APInt":$value);
+ let builders = [
+ AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
+ "const llvm::APInt &":$value), [{
+ return $_get(type.getContext(), type, value);
+ }]>,
+ AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
+ "int64_t":$value), [{
+ IntType intType = mlir::cast<IntType>(type);
+ mlir::APInt apValue(intType.getWidth(), value, intType.isSigned());
+ return $_get(intType.getContext(), intType, apValue);
+ }]>,
+ ];
+ let extraClassDeclaration = [{
+ int64_t getSInt() const { return getValue().getSExtValue(); }
+ uint64_t getUInt() const { return getValue().getZExtValue(); }
+ bool isNullValue() const { return getValue() == 0; }
+ uint64_t getBitWidth() const {
+ return mlir::cast<IntType>(getType()).getWidth();
+ }
+ }];
+ let genVerifyDecl = 1;
+ let hasCustomAssemblyFormat = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// FPAttr
+//===----------------------------------------------------------------------===//
+
+def FPAttr : CIR_Attr<"FP", "fp", [TypedAttrInterface]> {
+ let summary = "An attribute containing a floating-point value";
+ let description = [{
+ An fp attribute is a literal attribute that represents a floating-point
+ value of the specified floating-point type. Supporting only CIR FP types.
+ }];
+ let parameters = (ins
+ AttributeSelfTypeParameter<"", "::cir::CIRFPTypeInterface">:$type,
+ APFloatParameter<"">:$value
+ );
+ let builders = [
+ AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
+ "const llvm::APFloat &":$value), [{
+ return $_get(type.getContext(), mlir::cast<CIRFPTypeInterface>(type),
+ value);
+ }]>,
+ AttrBuilder<(ins "mlir::Type":$type,
+ "const llvm::APFloat &":$value), [{
+ return $_get($_ctxt, mlir::cast<CIRFPTypeInterface>(type), value);
+ }]>,
+ ];
+ let extraClassDeclaration = [{
+ static FPAttr getZero(mlir::Type type);
+ }];
+ let genVerifyDecl = 1;
+
+ let assemblyFormat = [{
+ `<` custom<FloatLiteral>($value, ref($type)) `>`
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// ConstPtrAttr
+//===----------------------------------------------------------------------===//
+
+def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> {
+ let summary = "Holds a constant pointer value";
+ let parameters = (ins
+ AttributeSelfTypeParameter<"", "::cir::PointerType">:$type,
+ "mlir::IntegerAttr":$value);
+ let description = [{
+ A pointer attribute is a literal attribute that represents an integral
+ value of a pointer type.
+ }];
+ let builders = [
+ AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
+ "mlir::IntegerAttr":$value), [{
+ return $_get(type.getContext(), mlir::cast<cir::PointerType>(type),
+ value);
+ }]>,
+ AttrBuilder<(ins "mlir::Type":$type,
+ "mlir::IntegerAttr":$value), [{
+ return $_get($_ctxt, mlir::cast<cir::PointerType>(type), value);
+ }]>,
+ ];
+ let extraClassDeclaration = [{
+ bool isNullValue() const { return getValue().getInt() == 0; }
+ }];
+
+ let assemblyFormat = [{
+ `<` custom<ConstPtr>($value) `>`
+ }];
+}
+
+#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_TD
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h
index 0b71bdad29a3..683176b139ca 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h
@@ -26,6 +26,7 @@
#include "mlir/Interfaces/MemorySlotInterfaces.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
#include "clang/CIR/Dialect/IR/CIROpsDialect.h.inc"
// TableGen'erated files for MLIR dialects require that a macro be defined when
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 4462eb6fc00b..b15e0415360e 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -15,6 +15,8 @@
#define LLVM_CLANG_CIR_DIALECT_IR_CIROPS
include "clang/CIR/Dialect/IR/CIRDialect.td"
+include "clang/CIR/Dialect/IR/CIRTypes.td"
+include "clang/CIR/Dialect/IR/CIRAttrs.td"
include "mlir/IR/BuiltinAttributeInterfaces.td"
include "mlir/IR/EnumAttr.td"
@@ -75,6 +77,84 @@ class CIR_Op<string mnemonic, list<Trait> traits = []> :
Op<CIR_Dialect, mnemonic, traits>, LLVMLoweringInfo;
//===----------------------------------------------------------------------===//
+// ConstantOp
+//===----------------------------------------------------------------------===//
+
+def ConstantOp : CIR_Op<"const",
+ [ConstantLike, Pure, AllTypesMatch<["value", "res"]>]> {
+ let summary = "Defines a CIR constant";
+ let description = [{
+ The `cir.const` operation turns a literal into an SSA value. The data is
+ attached to the operation as an attribute.
+
+ ```mlir
+ %0 = cir.const 42 : i32
+ %1 = cir.const 4.2 : f32
+ %2 = cir.const nullptr : !cir.ptr<i32>
+ ```
+ }];
+
+ // The constant operation takes an attribute as the only input.
+ let arguments = (ins TypedAttrInterface:$value);
+
+ // The constant operation returns a single value of CIR_AnyType.
+ let results = (outs CIR_AnyType:$res);
+
+ let assemblyFormat = "attr-dict $value";
+
+ let hasVerifier = 1;
+
+ let extraClassDeclaration = [{
+ bool isNullPtr() {
+ if (const auto ptrAttr = mlir::dyn_cast<cir::ConstPtrAttr>(getValue()))
+ return ptrAttr.isNullValue();
+ return false;
+ }
+ }];
+
+ let hasFolder = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// GlobalOp
+//===----------------------------------------------------------------------===//
+
+// TODO(CIR): For starters, cir.global has only name and type. The other
+// properties of a global variable will be added over time as more of ClangIR
+// is upstreamed.
+
+def GlobalOp : CIR_Op<"global"> {
+ let summary = "Declare or define a global variable";
+ let description = [{
+ The `cir.global` operation declares or defines a named global variable.
+
+ The backing memory for the variable is allocated statically and is
+ described by the type of the variable.
+ }];
+
+ let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type,
+ OptionalAttr<AnyAttr>:$initial_value);
+
+ let assemblyFormat = [{
+ $sym_name
+ custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value)
+ attr-dict
+ }];
+
+ let extraClassDeclaration = [{
+ bool isDeclaration() { return !getInitialValue(); }
+ bool hasInitializer() { return !isDeclaration(); }
+ }];
+
+ let skipDefaultBuilders = 1;
+
+ let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name,
+ "mlir::Type":$sym_type)>];
+
+ let hasVerifier = 1;
+}
+
+//===----------------------------------------------------------------------===//
// FuncOp
//===----------------------------------------------------------------------===//
@@ -85,14 +165,15 @@ class CIR_Op<string mnemonic, list<Trait> traits = []> :
def FuncOp : CIR_Op<"func"> {
let summary = "Declare or define a function";
let description = [{
- ... lots of text to be added later ...
+ The `cir.func` operation defines a function, similar to the `mlir::FuncOp`
+ built-in.
}];
let arguments = (ins SymbolNameAttr:$sym_name);
let skipDefaultBuilders = 1;
- let builders = [OpBuilder<(ins "llvm::StringRef":$name)>];
+ let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name)>];
let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
new file mode 100644
index 000000000000..5d1eb17e146d
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 declares the types in the CIR dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_CIR_IR_CIRTYPES_H_
+#define MLIR_DIALECT_CIR_IR_CIRTYPES_H_
+
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/Types.h"
+#include "mlir/Interfaces/DataLayoutInterfaces.h"
+#include "clang/CIR/Interfaces/CIRFPTypeInterface.h"
+
+namespace cir {
+
+bool isAnyFloatingPointType(mlir::Type t);
+
+} // namespace cir
+
+//===----------------------------------------------------------------------===//
+// CIR Dialect Tablegen'd Types
+//===----------------------------------------------------------------------===//
+
+#define GET_TYPEDEF_CLASSES
+#include "clang/CIR/Dialect/IR/CIROpsTypes.h.inc"
+
+#endif // MLIR_DIALECT_CIR_IR_CIRTYPES_H_
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
new file mode 100644
index 000000000000..a32fb3c80111
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -0,0 +1,361 @@
+//===- CIRTypes.td - CIR dialect types ---------------------*- tablegen -*-===//
+//
+// 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 declares the CIR dialect types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_CIR_DIALECT_CIR_TYPES
+#define MLIR_CIR_DIALECT_CIR_TYPES
+
+include "clang/CIR/Dialect/IR/CIRDialect.td"
+include "clang/CIR/Interfaces/CIRFPTypeInterface.td"
+include "mlir/Interfaces/DataLayoutInterfaces.td"
+include "mlir/IR/AttrTypeBase.td"
+
+//===----------------------------------------------------------------------===//
+// CIR Types
+//===----------------------------------------------------------------------===//
+
+class CIR_Type<string name, string typeMnemonic, list<Trait> traits = [],
+ string baseCppClass = "::mlir::Type">
+ : TypeDef<CIR_Dialect, name, traits, baseCppClass> {
+ let mnemonic = typeMnemonic;
+}
+
+//===----------------------------------------------------------------------===//
+// IntType
+//===----------------------------------------------------------------------===//
+
+def CIR_IntType : CIR_Type<"Int", "int",
+ [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
+ let summary = "Integer type with arbitrary precision up to a fixed limit";
+ let description = [{
+ CIR type that represents integer types with arbitrary precision, including
+ standard integral types such as `int` and `long`, extended integral types
+ such as `__int128`, and arbitrary width types such as `_BitInt(n)`.
+
+ Those integer types that are directly available in C/C++ standard are called
+ primitive integer types. Said types are: `signed char`, `short`, `int`,
+ `long`, `long long`, and their unsigned variations.
+ }];
+ let parameters = (ins "unsigned":$width, "bool":$isSigned);
+ let hasCustomAssemblyFormat = 1;
+ let extraClassDeclaration = [{
+ /// Return true if this is a signed integer type.
+ bool isSigned() const { return getIsSigned(); }
+ /// Return true if this is an unsigned integer type.
+ bool isUnsigned() const { return !getIsSigned(); }
+ /// Return type alias.
+ std::string getAlias() const {
+ return (isSigned() ? 's' : 'u') + std::to_string(getWidth()) + 'i';
+ }
+ /// Return true if this is a primitive integer type (i.e. signed or unsigned
+ /// integer types whose bit width is 8, 16, 32, or 64).
+ bool isPrimitive() const {
+ return isValidPrimitiveIntBitwidth(getWidth());
+ }
+ bool isSignedPrimitive() const {
+ return isPrimitive() && isSigned();
+ }
+
+ /// Returns a minimum bitwidth of cir::IntType
+ static unsigned minBitwidth() { return 1; }
+ /// Returns a maximum bitwidth of cir::IntType
+ static unsigned maxBitwidth() { return 128; }
+
+ /// Returns true if cir::IntType that represents a primitive integer type
+ /// can be constructed from the provided bitwidth.
+ static bool isValidPrimitiveIntBitwidth(unsigned width) {
+ return width == 8 || width == 16 || width == 32 || width == 64;
+ }
+ }];
+ let genVerifyDecl = 1;
+}
+
+// Constraints
+
+// Unsigned integer type of a specific width.
+class UInt<int width>
+ : Type<And<[
+ CPred<"::mlir::isa<::cir::IntType>($_self)">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).isUnsigned()">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width>
+ ]>, width # "-bit unsigned integer", "::cir::IntType">,
+ BuildableType<
+ "cir::IntType::get($_builder.getContext(), "
+ # width # ", /*isSigned=*/false)"> {
+ int bitwidth = width;
+}
+
+def UInt1 : UInt<1>;
+def UInt8 : UInt<8>;
+def UInt16 : UInt<16>;
+def UInt32 : UInt<32>;
+def UInt64 : UInt<64>;
+
+// Signed integer type of a specific width.
+class SInt<int width>
+ : Type<And<[
+ CPred<"::mlir::isa<::cir::IntType>($_self)">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).isSigned()">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width>
+ ]>, width # "-bit signed integer", "::cir::IntType">,
+ BuildableType<
+ "cir::IntType::get($_builder.getContext(), "
+ # width # ", /*isSigned=*/true)"> {
+ int bitwidth = width;
+}
+
+def SInt1 : SInt<1>;
+def SInt8 : SInt<8>;
+def SInt16 : SInt<16>;
+def SInt32 : SInt<32>;
+def SInt64 : SInt<64>;
+
+def PrimitiveUInt
+ : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64], "primitive unsigned int",
+ "::cir::IntType">;
+
+def PrimitiveSInt
+ : AnyTypeOf<[SInt8, SInt16, SInt32, SInt64], "primitive signed int",
+ "::cir::IntType">;
+
+def PrimitiveInt
+ : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64],
+ "primitive int", "::cir::IntType">;
+
+//===----------------------------------------------------------------------===//
+// FloatType
+//===----------------------------------------------------------------------===//
+
+class CIR_FloatType<string name, string mnemonic>
+ : CIR_Type<name, mnemonic,
+ [
+ DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
+ DeclareTypeInterfaceMethods<CIRFPTypeInterface>,
+ ]> {}
+
+def CIR_Single : CIR_FloatType<"Single", "float"> {
+ let summary = "CIR single-precision 32-bit float type";
+ let description = [{
+ A 32-bit floating-point type whose format is IEEE-754 `binary32`. It
+ represents the types `float`, `_Float32`, and `std::float32_t` in C and C++.
+ }];
+}
+
+def CIR_Double : CIR_FloatType<"Double", "double"> {
+ let summary = "CIR double-precision 64-bit float type";
+ let description = [{
+ A 64-bit floating-point type whose format is IEEE-754 `binary64`. It
+ represents the types `double', '_Float64`, `std::float64_t`, and `_Float32x`
+ in C and C++. This is the underlying type for `long double` on some
+ platforms, including Windows.
+ }];
+}
+
+def CIR_FP16 : CIR_FloatType<"FP16", "f16"> {
+ let summary = "CIR half-precision 16-bit float type";
+ let description = [{
+ A 16-bit floating-point type whose format is IEEE-754 `binary16`. It
+ represents the types '_Float16` and `std::float16_t` in C and C++.
+ }];
+}
+
+def CIR_BFloat16 : CIR_FloatType<"BF16", "bf16"> {
+ let summary = "CIR bfloat16 16-bit float type";
+ let description = [{
+ A 16-bit floating-point type in the bfloat16 format, which is the same as
+ IEEE `binary32` except that the lower 16 bits of the mantissa are missing.
+ It represents the type `std::bfloat16_t` in C++, also spelled `__bf16` in
+ some implementations.
+ }];
+}
+
+def CIR_FP80 : CIR_FloatType<"FP80", "f80"> {
+ let summary = "CIR x87 80-bit float type";
+ let description = [{
+ An 80-bit floating-point type in the x87 extended precision format. The
+ size and alignment of the type are both 128 bits, even though only 80 of
+ those bits are used. This is the underlying type for `long double` on Linux
+ x86 platforms, and it is available as an extension in some implementations.
+ }];
+}
+
+def CIR_FP128 : CIR_FloatType<"FP128", "f128"> {
+ let summary = "CIR quad-precision 128-bit float type";
+ let description = [{
+ A 128-bit floating-point type whose format is IEEE-754 `binary128`. It
+ represents the types `_Float128` and `std::float128_t` in C and C++, and the
+ extension `__float128` in some implementations. This is the underlying type
+ for `long double` on some platforms including Linux Arm.
+ }];
+}
+
+def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {
+ let summary = "CIR float type for `long double`";
+ let description = [{
+ A floating-point type that represents the `long double` type in C and C++.
+
+ The underlying floating-point format of a `long double` value depends on the
+ target platform and the implementation. The `underlying` parameter specifies
+ the CIR floating-point type that corresponds to this format. Underlying
+ types of IEEE 64-bit, IEEE 128-bit, x87 80-bit, and IBM's double-double
+ format are all in use.
+ }];
+
+ let parameters = (ins "mlir::Type":$underlying);
+
+ let assemblyFormat = [{
+ `<` $underlying `>`
+ }];
+
+ let genVerifyDecl = 1;
+}
+
+// Constraints
+
+def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_FP80, CIR_FP128,
+ CIR_LongDouble, CIR_FP16, CIR_BFloat16]>;
+def CIR_AnyIntOrFloat: AnyTypeOf<[CIR_AnyFloat, CIR_IntType]>;
+
+//===----------------------------------------------------------------------===//
+// PointerType
+//===----------------------------------------------------------------------===//
+
+def CIR_PointerType : CIR_Type<"Pointer", "ptr",
+ [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
+
+ let summary = "CIR pointer type";
+ let description = [{
+ The `cir.ptr` type represents C and C++ pointer types and C++ reference
+ types, other than pointers-to-members. The `pointee` type is the type
+ pointed to.
+
+ TODO(CIR): The address space attribute is not yet implemented.
+ }];
+
+ let parameters = (ins "mlir::Type":$pointee);
+
+ let builders = [
+ TypeBuilderWithInferredContext<(ins "mlir::Type":$pointee), [{
+ return $_get(pointee.getContext(), pointee);
+ }]>,
+ TypeBuilder<(ins "mlir::Type":$pointee), [{
+ return $_get($_ctxt, pointee);
+ }]>
+ ];
+
+ let assemblyFormat = [{
+ `<` $pointee `>`
+ }];
+
+ let genVerifyDecl = 1;
+
+ let skipDefaultBuilders = 1;
+
+ let extraClassDeclaration = [{
+ bool isVoidPtr() const {
+ return mlir::isa<cir::VoidType>(getPointee());
+ }
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// FuncType
+//===----------------------------------------------------------------------===//
+
+def CIR_FuncType : CIR_Type<"Func", "func"> {
+ let summary = "CIR function type";
+ let description = [{
+ The `!cir.func` is a function type. It consists of a single return type, a
+ list of parameter types and can optionally be variadic.
+
+ Example:
+
+ ```mlir
+ !cir.func<!bool ()>
+ !cir.func<!s32i (!s8i, !s8i)>
+ !cir.func<!s32i (!s32i, ...)>
+ ```
+ }];
+
+ let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs,
+ "mlir::Type":$returnType, "bool":$varArg);
+ let assemblyFormat = [{
+ `<` $returnType ` ` `(` custom<FuncTypeArgs>($inputs, $varArg) `>`
+ }];
+
+ let builders = [
+ TypeBuilderWithInferredContext<(ins
+ "llvm::ArrayRef<mlir::Type>":$inputs, "mlir::Type":$returnType,
+ CArg<"bool", "false">:$isVarArg), [{
+ return $_get(returnType.getContext(), inputs, returnType, isVarArg);
+ }]>
+ ];
+
+ let extraClassDeclaration = [{
+ /// Returns whether the function is variadic.
+ bool isVarArg() const { return getVarArg(); }
+
+ /// Returns the `i`th input operand type. Asserts if out of bounds.
+ mlir::Type getInput(unsigned i) const { return getInputs()[i]; }
+
+ /// Returns the number of arguments to the function.
+ unsigned getNumInputs() const { return getInputs().size(); }
+
+ /// Returns the result type of the function as an ArrayRef, enabling better
+ /// integration with generic MLIR utilities.
+ llvm::ArrayRef<mlir::Type> getReturnTypes() const;
+
+ /// Returns whether the function is returns void.
+ bool isVoid() const;
+
+ /// Returns a clone of this function type with the given argument
+ /// and result types.
+ FuncType clone(mlir::TypeRange inputs, mlir::TypeRange results) const;
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// Void type
+//===----------------------------------------------------------------------===//
+
+def CIR_VoidType : CIR_Type<"Void", "void"> {
+ let summary = "CIR void type";
+ let description = [{
+ The `!cir.void` type represents the C and C++ `void` type.
+ }];
+ let extraClassDeclaration = [{
+ std::string getAlias() const { return "void"; };
+ }];
+}
+
+// Constraints
+
+// Pointer to void
+def VoidPtr : Type<
+ And<[
+ CPred<"::mlir::isa<::cir::PointerType>($_self)">,
+ CPred<"::mlir::isa<::cir::VoidType>("
+ "::mlir::cast<::cir::PointerType>($_self).getPointee())">,
+ ]>, "void*">,
+ BuildableType<
+ "cir::PointerType::get($_builder.getContext(),"
+ "cir::VoidType::get($_builder.getContext()))"> {
+}
+
+//===----------------------------------------------------------------------===//
+// Global type constraints
+//===----------------------------------------------------------------------===//
+
+def CIR_AnyType : AnyTypeOf<[
+ CIR_VoidType, CIR_IntType, CIR_AnyFloat, CIR_PointerType, CIR_FuncType
+]>;
+
+#endif // MLIR_CIR_DIALECT_CIR_TYPES
diff --git a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
index 28ae30dab8df..1fdbc24ba6b4 100644
--- a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
+++ b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
@@ -14,3 +14,6 @@ mlir_tablegen(CIROpsDialect.cpp.inc -gen-dialect-defs)
add_public_tablegen_target(MLIRCIROpsIncGen)
add_dependencies(mlir-headers MLIRCIROpsIncGen)
+mlir_tablegen(CIROpsAttributes.h.inc -gen-attrdef-decls)
+mlir_tablegen(CIROpsAttributes.cpp.inc -gen-attrdef-defs)
+add_public_tablegen_target(MLIRCIRAttrsEnumsGen)
diff --git a/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h
new file mode 100644
index 000000000000..40b85ef6cfb6
--- /dev/null
+++ b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h
@@ -0,0 +1,22 @@
+//===---------------------------------------------------------------------===//
+//
+// 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
+//
+//===---------------------------------------------------------------------===//
+//
+// Defines the interface to generically handle CIR floating-point types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_H
+#define LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_H
+
+#include "mlir/IR/Types.h"
+#include "llvm/ADT/APFloat.h"
+
+/// Include the tablegen'd interface declarations.
+#include "clang/CIR/Interfaces/CIRFPTypeInterface.h.inc"
+
+#endif // LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_H
diff --git a/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td
new file mode 100644
index 000000000000..973851b61444
--- /dev/null
+++ b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the interface to generically handle CIR floating-point types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_TD
+#define LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_TD
+
+include "mlir/IR/OpBase.td"
+
+def CIRFPTypeInterface : TypeInterface<"CIRFPTypeInterface"> {
+ let description = [{
+ Contains helper functions to query properties about a floating-point type.
+ }];
+ let cppNamespace = "::cir";
+
+ let methods = [
+ InterfaceMethod<[{
+ Returns the bit width of this floating-point type.
+ }],
+ /*retTy=*/"unsigned",
+ /*methodName=*/"getWidth",
+ /*args=*/(ins),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ return llvm::APFloat::semanticsSizeInBits($_type.getFloatSemantics());
+ }]
+ >,
+ InterfaceMethod<[{
+ Return the mantissa width.
+ }],
+ /*retTy=*/"unsigned",
+ /*methodName=*/"getFPMantissaWidth",
+ /*args=*/(ins),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ return llvm::APFloat::semanticsPrecision($_type.getFloatSemantics());
+ }]
+ >,
+ InterfaceMethod<[{
+ Return the float semantics of this floating-point type.
+ }],
+ /*retTy=*/"const llvm::fltSemantics &",
+ /*methodName=*/"getFloatSemantics"
+ >,
+ ];
+}
+
+#endif // LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_TD
diff --git a/clang/include/clang/CIR/Interfaces/CMakeLists.txt b/clang/include/clang/CIR/Interfaces/CMakeLists.txt
new file mode 100644
index 000000000000..1c90b6b5a23c
--- /dev/null
+++ b/clang/include/clang/CIR/Interfaces/CMakeLists.txt
@@ -0,0 +1,14 @@
+# This replicates part of the add_mlir_interface cmake function from MLIR that
+# cannot be used here. This happens because it expects to be run inside MLIR
+# directory which is not the case for CIR (and also FIR, both have similar
+# workarounds).
+
+function(add_clang_mlir_type_interface interface)
+ set(LLVM_TARGET_DEFINITIONS ${interface}.td)
+ mlir_tablegen(${interface}.h.inc -gen-type-interface-decls)
+ mlir_tablegen(${interface}.cpp.inc -gen-type-interface-defs)
+ add_public_tablegen_target(MLIR${interface}IncGen)
+ add_dependencies(mlir-generic-headers MLIR${interface}IncGen)
+endfunction()
+
+add_clang_mlir_type_interface(CIRFPTypeInterface)
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index 9177d56718ee..c23d037e725b 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -297,8 +297,11 @@ private:
/// Object that stores strings read from configuration file.
llvm::StringSaver Saver;
- /// Arguments originated from configuration file.
- std::unique_ptr<llvm::opt::InputArgList> CfgOptions;
+ /// Arguments originated from configuration file (head part).
+ std::unique_ptr<llvm::opt::InputArgList> CfgOptionsHead;
+
+ /// Arguments originated from configuration file (tail part).
+ std::unique_ptr<llvm::opt::InputArgList> CfgOptionsTail;
/// Arguments originated from command line.
std::unique_ptr<llvm::opt::InputArgList> CLOptions;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index a89a4e8f8ec9..523761f5e0d8 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -240,7 +240,8 @@ def m_riscv_Features_Group : OptionGroup<"<riscv features group>">,
def m_ve_Features_Group : OptionGroup<"<ve features group>">,
Group<m_Group>, DocName<"VE">;
def m_loongarch_Features_Group : OptionGroup<"<loongarch features group>">,
- Group<m_Group>, DocName<"LoongArch">;
+ Group<m_Group>, DocName<"LoongArch">,
+ Visibility<[ClangOption, CLOption, FlangOption]>;
def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_mips_Features_Group>,
Flags<[HelpHidden]>;
@@ -1055,11 +1056,11 @@ def z : Separate<["-"], "z">, Flags<[LinkerInput]>,
def offload_link : Flag<["--"], "offload-link">, Group<Link_Group>,
HelpText<"Use the new offloading linker to perform the link job.">;
def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
- Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>,
+ Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">,
Group<Link_Group>;
def Xoffload_linker : JoinedAndSeparate<["-"], "Xoffload-linker">,
- Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>,
+ Visibility<[ClangOption, FlangOption]>,
HelpText<"Pass <arg> to the offload linkers or the ones identified by -<triple>">,
MetaVarName<"<triple> <arg>">, Group<Link_Group>;
def Xpreprocessor : Separate<["-"], "Xpreprocessor">, Group<Preprocessor_Group>,
@@ -1175,7 +1176,7 @@ def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
def config : Joined<["--"], "config=">, Flags<[NoXarchOption]>,
Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, MetaVarName<"<file>">,
HelpText<"Specify configuration file">;
-def : Separate<["--"], "config">, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, Alias<config>;
+def : Separate<["--"], "config">, Visibility<[ClangOption, FlangOption]>, Alias<config>;
def no_default_config : Flag<["--"], "no-default-config">,
Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
HelpText<"Disable loading default configuration files">;
@@ -1492,6 +1493,8 @@ def libomptarget_amdgcn_bc_path_EQ : Joined<["--"], "libomptarget-amdgcn-bc-path
HelpText<"Path to libomptarget-amdgcn bitcode library">, Alias<libomptarget_amdgpu_bc_path_EQ>;
def libomptarget_nvptx_bc_path_EQ : Joined<["--"], "libomptarget-nvptx-bc-path=">, Group<i_Group>,
HelpText<"Path to libomptarget-nvptx bitcode library">;
+def libomptarget_spirv_bc_path_EQ : Joined<["--"], "libomptarget-spirv-bc-path=">, Group<i_Group>,
+ HelpText<"Path to libomptarget-spirv bitcode library">;
def dD : Flag<["-"], "dD">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Print macro definitions in -E mode in addition to normal output">;
def dI : Flag<["-"], "dI">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>,
@@ -2015,10 +2018,10 @@ argument are escaped with backslashes. This format differs from the format of
the equivalent section produced by GCC with the -frecord-gcc-switches flag.
This option is currently only supported on ELF targets.}]>,
Group<f_Group>,
- Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>;
+ Visibility<[ClangOption, FlangOption]>;
def fno_record_command_line : Flag<["-"], "fno-record-command-line">,
Group<f_Group>,
- Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>;
+ Visibility<[ClangOption, FlangOption]>;
def : Flag<["-"], "frecord-gcc-switches">, Alias<frecord_command_line>;
def : Flag<["-"], "fno-record-gcc-switches">, Alias<fno_record_command_line>;
def fcommon : Flag<["-"], "fcommon">, Group<f_Group>,
@@ -2554,6 +2557,21 @@ def fno_sanitize_trap : Flag<["-"], "fno-sanitize-trap">, Group<f_clang_Group>,
Alias<fno_sanitize_trap_EQ>, AliasArgs<["all"]>,
Visibility<[ClangOption, CLOption]>,
HelpText<"Disable trapping for all sanitizers">;
+def fsanitize_merge_handlers_EQ
+ : CommaJoined<["-"], "fsanitize-merge=">,
+ Group<f_clang_Group>,
+ HelpText<"Allow compiler to merge handlers for specified sanitizers">;
+def fno_sanitize_merge_handlers_EQ
+ : CommaJoined<["-"], "fno-sanitize-merge=">,
+ Group<f_clang_Group>,
+ HelpText<"Do not allow compiler to merge handlers for specified sanitizers">;
+def fsanitize_merge_handlers : Flag<["-"], "fsanitize-merge">, Group<f_clang_Group>,
+ Alias<fsanitize_merge_handlers_EQ>, AliasArgs<["all"]>,
+ HelpText<"Allow compiler to merge handlers for all sanitizers">;
+def fno_sanitize_merge_handlers : Flag<["-"], "fno-sanitize-merge">, Group<f_clang_Group>,
+ Alias<fno_sanitize_merge_handlers_EQ>, AliasArgs<["all"]>,
+ Visibility<[ClangOption, CLOption]>,
+ HelpText<"Do not allow compiler to merge handlers for any sanitizers">;
def fsanitize_undefined_trap_on_error
: Flag<["-"], "fsanitize-undefined-trap-on-error">, Group<f_clang_Group>,
Alias<fsanitize_trap_EQ>, AliasArgs<["undefined"]>;
@@ -3194,11 +3212,14 @@ defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf",
"Perform ODR checks for decls in the global module fragment.">>,
Group<f_Group>;
-def modules_reduced_bmi : Flag<["-"], "fexperimental-modules-reduced-bmi">,
+def modules_reduced_bmi : Flag<["-"], "fmodules-reduced-bmi">,
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Generate the reduced BMI">,
MarshallingInfoFlag<FrontendOpts<"GenReducedBMI">>;
+def experimental_modules_reduced_bmi : Flag<["-"], "fexperimental-modules-reduced-bmi">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>, Alias<modules_reduced_bmi>;
+
def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">,
Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Embed the contents of all files read by this compilation into "
@@ -3459,6 +3480,9 @@ defm diagnostics_show_line_numbers : BoolFOption<"diagnostics-show-line-numbers"
NegFlag<SetFalse, [], [ClangOption, CC1Option],
"Show line numbers in diagnostic code snippets">,
PosFlag<SetTrue>>;
+def fno_realloc_lhs : Flag<["-"], "fno-realloc-lhs">, Group<f_Group>,
+ HelpText<"An allocatable left-hand side of an intrinsic assignment is assumed to be allocated and match the shape/type of the right-hand side">,
+ Visibility<[FlangOption, FC1Option]>;
def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>,
HelpText<"Disable the use of stack protectors">;
def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>,
@@ -4292,6 +4316,9 @@ defm stack_size_section : BoolFOption<"stack-size-section",
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Emit section containing metadata on function stack sizes">,
NegFlag<SetFalse>>;
+def frealloc_lhs : Flag<["-"], "frealloc-lhs">, Group<f_Group>,
+ Visibility<[FlangOption, FC1Option]>,
+ HelpText<"If an allocatable left-hand side of an intrinsic assignment is unallocated or its shape/type does not match the right-hand side, then it is automatically (re)allocated">;
def fstack_usage : Flag<["-"], "fstack-usage">, Group<f_Group>,
HelpText<"Emit .su file containing information on function stack sizes">;
def stack_usage_file : Separate<["-"], "stack-usage-file">,
@@ -5644,7 +5671,7 @@ def gpulibc : Flag<["-"], "gpulibc">, Visibility<[ClangOption, CC1Option, FlangO
HelpText<"Link the LLVM C Library for GPUs">;
def nogpulibc : Flag<["-"], "nogpulibc">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
def nodefaultlibs : Flag<["-"], "nodefaultlibs">,
- Visibility<[ClangOption, FlangOption, CLOption, DXCOption]>;
+ Visibility<[ClangOption, FlangOption]>;
def nodriverkitlib : Flag<["-"], "nodriverkitlib">;
def nofixprebinding : Flag<["-"], "nofixprebinding">;
def nolibc : Flag<["-"], "nolibc">;
@@ -5666,10 +5693,10 @@ def nostdincxx : Flag<["-"], "nostdinc++">, Visibility<[ClangOption, CC1Option]>
HelpText<"Disable standard #include directories for the C++ standard library">,
MarshallingInfoNegativeFlag<HeaderSearchOpts<"UseStandardCXXIncludes">>;
def nostdlib : Flag<["-"], "nostdlib">,
- Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>,
+ Visibility<[ClangOption, FlangOption]>,
Group<Link_Group>;
def stdlib : Flag<["-"], "stdlib">,
- Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>,
+ Visibility<[ClangOption, FlangOption]>,
Group<Link_Group>;
def nostdlibxx : Flag<["-"], "nostdlib++">;
def object : Flag<["-"], "object">;
@@ -5783,7 +5810,7 @@ def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[NoXarchOption]>,
Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
Alias<resource_dir>;
def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>, Group<Link_Group>,
- Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>;
+ Visibility<[ClangOption, FlangOption]>;
def rtlib_EQ : Joined<["-", "--"], "rtlib=">, Visibility<[ClangOption, CLOption, FlangOption]>,
HelpText<"Compiler runtime library to use">;
def frtlib_add_rpath: Flag<["-"], "frtlib-add-rpath">, Flags<[NoArgumentUnused]>,
@@ -5847,7 +5874,7 @@ def segs__read__write__addr : Separate<["-"], "segs_read_write_addr">;
def segs__read__ : Joined<["-"], "segs_read_">;
def shared_libgcc : Flag<["-"], "shared-libgcc">;
def shared : Flag<["-", "--"], "shared">, Group<Link_Group>,
- Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>;
+ Visibility<[ClangOption, FlangOption]>;
def single__module : Flag<["-"], "single_module">;
def specs_EQ : Joined<["-", "--"], "specs=">, Group<Link_Group>;
def specs : Separate<["-", "--"], "specs">, Flags<[Unsupported]>;
@@ -5857,7 +5884,7 @@ def start_no_unused_arguments : Flag<["--"], "start-no-unused-arguments">,
def static_libgcc : Flag<["-"], "static-libgcc">;
def static_libstdcxx : Flag<["-"], "static-libstdc++">;
def static : Flag<["-", "--"], "static">, Group<Link_Group>,
- Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
+ Visibility<[ClangOption, FlangOption]>,
Flags<[NoArgumentUnused]>;
def std_default_EQ : Joined<["-"], "std-default=">;
def std_EQ : Joined<["-", "--"], "std=">,
@@ -6199,6 +6226,10 @@ def mv71t : Flag<["-"], "mv71t">, Group<m_hexagon_Features_Group>,
Alias<mcpu_EQ>, AliasArgs<["hexagonv71t"]>;
def mv73 : Flag<["-"], "mv73">, Group<m_hexagon_Features_Group>,
Alias<mcpu_EQ>, AliasArgs<["hexagonv73"]>;
+def mv75 : Flag<["-"], "mv75">, Group<m_hexagon_Features_Group>,
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv75"]>;
+def mv79 : Flag<["-"], "mv79">, Group<m_hexagon_Features_Group>,
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv79"]>;
def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_HVX_Group>,
HelpText<"Enable Hexagon Vector eXtensions">;
def mhexagon_hvx_EQ : Joined<["-"], "mhvx=">,
@@ -6771,7 +6802,6 @@ defm real_4_real_8 : BooleanFFlag<"real-4-real-8">, Group<gfortran_Group>;
defm real_8_real_10 : BooleanFFlag<"real-8-real-10">, Group<gfortran_Group>;
defm real_8_real_16 : BooleanFFlag<"real-8-real-16">, Group<gfortran_Group>;
defm real_8_real_4 : BooleanFFlag<"real-8-real-4">, Group<gfortran_Group>;
-defm realloc_lhs : BooleanFFlag<"realloc-lhs">, Group<gfortran_Group>;
defm recursive : BooleanFFlag<"recursive">, Group<gfortran_Group>;
defm repack_arrays : BooleanFFlag<"repack-arrays">, Group<gfortran_Group>;
defm second_underscore : BooleanFFlag<"second-underscore">, Group<gfortran_Group>;
@@ -6836,10 +6866,6 @@ def flang_deprecated_no_hlfir : Flag<["-"], "flang-deprecated-no-hlfir">,
Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>,
HelpText<"Do not use HLFIR lowering (deprecated)">;
-def flang_experimental_integer_overflow : Flag<["-"], "flang-experimental-integer-overflow">,
- Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>,
- HelpText<"Add nsw flag to internal operations such as do-variable increment (experimental)">;
-
//===----------------------------------------------------------------------===//
// FLangOption + CoreOption + NoXarchOption
//===----------------------------------------------------------------------===//
@@ -6908,6 +6934,7 @@ defm underscoring : OptInFC1FFlag<"underscoring", "Appends one trailing undersco
defm ppc_native_vec_elem_order: BoolOptionWithoutMarshalling<"f", "ppc-native-vector-element-order",
PosFlag<SetTrue, [], [ClangOption], "Specifies PowerPC native vector element order (default)">,
NegFlag<SetFalse, [], [ClangOption], "Specifies PowerPC non-native vector element order">>;
+defm unsigned : OptInFC1FFlag<"unsigned", "Enables UNSIGNED type">;
def fno_automatic : Flag<["-"], "fno-automatic">, Group<f_Group>,
HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">;
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index 0c6f3869549e..3b275092bbbe 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -25,6 +25,7 @@ class SanitizerArgs {
SanitizerSet Sanitizers;
SanitizerSet RecoverableSanitizers;
SanitizerSet TrapSanitizers;
+ SanitizerSet MergeHandlers;
std::vector<std::string> UserIgnorelistFiles;
std::vector<std::string> SystemIgnorelistFiles;
@@ -87,6 +88,7 @@ public:
bool needsHwasanAliasesRt() const {
return needsHwasanRt() && HwasanUseAliases;
}
+ bool needsTysanRt() const { return Sanitizers.has(SanitizerKind::Type); }
bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); }
bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); }
bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); }
@@ -97,6 +99,7 @@ public:
}
bool needsFuzzerInterceptors() const;
bool needsUbsanRt() const;
+ bool needsUbsanCXXRt() const;
bool requiresMinimalRuntime() const { return MinimalRuntime; }
bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
bool needsSafeStackRt() const { return SafeStackRuntime; }
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 6383934afa2c..9b7a633e0a14 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -988,6 +988,10 @@ struct FormatStyle {
/// \version 3.7
bool AllowShortLoopsOnASingleLine;
+ /// If ``true``, ``namespace a { class b; }`` can be put on a single line.
+ /// \version 20
+ bool AllowShortNamespacesOnASingleLine;
+
/// Different ways to break after the function definition return type.
/// This option is **deprecated** and is retained for backwards compatibility.
enum DefinitionReturnTypeBreakingStyle : int8_t {
@@ -5099,6 +5103,15 @@ struct FormatStyle {
/// \version 3.7
UseTabStyle UseTab;
+ /// A vector of non-keyword identifiers that should be interpreted as variable
+ /// template names.
+ ///
+ /// A ``)`` after a variable template instantiation is **not** annotated as
+ /// the closing parenthesis of C-style cast operator.
+ ///
+ /// \version 20
+ std::vector<std::string> VariableTemplates;
+
/// For Verilog, put each port on its own line in module instantiations.
/// \code
/// true:
@@ -5130,6 +5143,39 @@ struct FormatStyle {
/// \version 11
std::vector<std::string> WhitespaceSensitiveMacros;
+ /// Different styles for wrapping namespace body with empty lines.
+ enum WrapNamespaceBodyWithEmptyLinesStyle : int8_t {
+ /// Remove all empty lines at the beginning and the end of namespace body.
+ /// \code
+ /// namespace N1 {
+ /// namespace N2
+ /// function();
+ /// }
+ /// }
+ /// \endcode
+ WNBWELS_Never,
+ /// Always have at least one empty line at the beginning and the end of
+ /// namespace body except that the number of empty lines between consecutive
+ /// nested namespace definitions is not increased.
+ /// \code
+ /// namespace N1 {
+ /// namespace N2 {
+ ///
+ /// function();
+ ///
+ /// }
+ /// }
+ /// \endcode
+ WNBWELS_Always,
+ /// Keep existing newlines at the beginning and the end of namespace body.
+ /// ``MaxEmptyLinesToKeep`` still applies.
+ WNBWELS_Leave
+ };
+
+ /// Wrap namespace body with empty lines.
+ /// \version 20
+ WrapNamespaceBodyWithEmptyLinesStyle WrapNamespaceBodyWithEmptyLines;
+
bool operator==(const FormatStyle &R) const {
return AccessModifierOffset == R.AccessModifierOffset &&
AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
@@ -5168,6 +5214,8 @@ struct FormatStyle {
R.AllowShortIfStatementsOnASingleLine &&
AllowShortLambdasOnASingleLine == R.AllowShortLambdasOnASingleLine &&
AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
+ AllowShortNamespacesOnASingleLine ==
+ R.AllowShortNamespacesOnASingleLine &&
AlwaysBreakBeforeMultilineStrings ==
R.AlwaysBreakBeforeMultilineStrings &&
AttributeMacros == R.AttributeMacros &&
@@ -5308,10 +5356,11 @@ struct FormatStyle {
TableGenBreakInsideDAGArg == R.TableGenBreakInsideDAGArg &&
TabWidth == R.TabWidth && TemplateNames == R.TemplateNames &&
TypeNames == R.TypeNames && TypenameMacros == R.TypenameMacros &&
- UseTab == R.UseTab &&
+ UseTab == R.UseTab && VariableTemplates == R.VariableTemplates &&
VerilogBreakBetweenInstancePorts ==
R.VerilogBreakBetweenInstancePorts &&
- WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros;
+ WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros &&
+ WrapNamespaceBodyWithEmptyLines == R.WrapNamespaceBodyWithEmptyLines;
}
std::optional<FormatStyle> GetLanguageStyle(LanguageKind Language) const;
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index 604e42067a3f..8ed17179c982 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -120,6 +120,7 @@ protected:
private:
void outputDependencyFile(DiagnosticsEngine &Diags);
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
std::string OutputFile;
std::vector<std::string> Targets;
bool IncludeSystemHeaders;
diff --git a/clang/include/clang/Lex/PreprocessingRecord.h b/clang/include/clang/Lex/PreprocessingRecord.h
index 437d8e4cc174..7886aef7f0c7 100644
--- a/clang/include/clang/Lex/PreprocessingRecord.h
+++ b/clang/include/clang/Lex/PreprocessingRecord.h
@@ -180,13 +180,13 @@ class Token;
}
/// True if it is a builtin macro.
- bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); }
+ bool isBuiltinMacro() const { return isa<IdentifierInfo *>(NameOrDef); }
/// The name of the macro being expanded.
const IdentifierInfo *getName() const {
if (MacroDefinitionRecord *Def = getDefinition())
return Def->getName();
- return NameOrDef.get<IdentifierInfo *>();
+ return cast<IdentifierInfo *>(NameOrDef);
}
/// The definition of the macro being expanded. May return null if
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 3312d4ed1d79..3d223c345ea1 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -859,7 +859,7 @@ private:
auto *Info = State.dyn_cast<ModuleMacroInfo*>();
if (!Info) {
Info = new (PP.getPreprocessorAllocator())
- ModuleMacroInfo(State.get<MacroDirective *>());
+ ModuleMacroInfo(cast<MacroDirective *>(State));
State = Info;
}
@@ -892,7 +892,7 @@ private:
MacroDirective *getLatest() const {
if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
return Info->MD;
- return State.get<MacroDirective*>();
+ return cast<MacroDirective *>(State);
}
void setLatest(MacroDirective *MD) {
@@ -945,7 +945,7 @@ private:
if (Overrides.empty())
return;
Info = new (PP.getPreprocessorAllocator())
- ModuleMacroInfo(State.get<MacroDirective *>());
+ ModuleMacroInfo(cast<MacroDirective *>(State));
State = Info;
}
Info->OverriddenMacros.clear();
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index d3838a4cc841..e99d2cf2eaa4 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3706,10 +3706,14 @@ private:
OpenACCDirectiveKind DirKind;
SourceLocation StartLoc;
SourceLocation DirLoc;
+ SourceLocation LParenLoc;
+ SourceLocation RParenLoc;
SourceLocation EndLoc;
+ SourceLocation MiscLoc;
+ SmallVector<Expr *> Exprs;
SmallVector<OpenACCClause *> Clauses;
- // TODO OpenACC: As we implement support for the Atomic, Routine, Cache, and
- // Wait constructs, we likely want to put that information in here as well.
+ // TODO OpenACC: As we implement support for the Atomic, Routine, and Cache
+ // constructs, we likely want to put that information in here as well.
};
struct OpenACCWaitParseInfo {
@@ -3717,6 +3721,13 @@ private:
Expr *DevNumExpr = nullptr;
SourceLocation QueuesLoc;
SmallVector<Expr *> QueueIdExprs;
+
+ SmallVector<Expr *> getAllExprs() {
+ SmallVector<Expr *> Out;
+ Out.push_back(DevNumExpr);
+ Out.insert(Out.end(), QueueIdExprs.begin(), QueueIdExprs.end());
+ return Out;
+ }
};
/// Represents the 'error' state of parsing an OpenACC Clause, and stores
diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h
index 3d1906d86992..0c92c52854c9 100644
--- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -97,6 +97,12 @@ public:
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;
+ bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
+
+ bool
+ LoadExternalSpecializations(const Decl *D,
+ ArrayRef<TemplateArgument> TemplateArgs) override;
+
/// Ensures that the table of all visible declarations inside this
/// context is up to date.
void completeVisibleDeclsMap(const DeclContext *DC) override;
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index 22cbd0d90ee4..4fa5fbdb5a7f 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -392,19 +392,17 @@ public:
}
bool isArgExpr(unsigned Arg) const {
- return Arg < NumArgs && getArg(Arg).is<Expr*>();
+ return Arg < NumArgs && isa<Expr *>(getArg(Arg));
}
- Expr *getArgAsExpr(unsigned Arg) const {
- return getArg(Arg).get<Expr*>();
- }
+ Expr *getArgAsExpr(unsigned Arg) const { return cast<Expr *>(getArg(Arg)); }
bool isArgIdent(unsigned Arg) const {
- return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
+ return Arg < NumArgs && isa<IdentifierLoc *>(getArg(Arg));
}
IdentifierLoc *getArgAsIdent(unsigned Arg) const {
- return getArg(Arg).get<IdentifierLoc*>();
+ return cast<IdentifierLoc *>(getArg(Arg));
}
const AvailabilityChange &getAvailabilityIntroduced() const {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b8684d11460e..5ee7ea48cc98 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5314,7 +5314,7 @@ public:
/// is complete.
void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl,
SourceLocation EqualLoc,
- Expr *Init);
+ ExprResult Init);
/// Handle a C++ member initializer using parentheses syntax.
MemInitResult
@@ -10659,6 +10659,11 @@ public:
SourceLocation EndLoc);
void ActOnForEachDeclStmt(DeclGroupPtrTy Decl);
+ /// DiagnoseDiscardedExprMarkedNodiscard - Given an expression that is
+ /// semantically a discarded-value expression, diagnose if any [[nodiscard]]
+ /// value has been discarded.
+ void DiagnoseDiscardedExprMarkedNodiscard(const Expr *E);
+
/// DiagnoseUnusedExprResult - If the statement passed in is an expression
/// whose result is unused, warn.
void DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID);
diff --git a/clang/include/clang/Sema/SemaConcept.h b/clang/include/clang/Sema/SemaConcept.h
index 4b1abccb7741..5c599a70532f 100644
--- a/clang/include/clang/Sema/SemaConcept.h
+++ b/clang/include/clang/Sema/SemaConcept.h
@@ -135,31 +135,20 @@ struct NormalizedConstraint {
return *this;
}
- bool isAtomic() const { return Constraint.is<AtomicConstraint *>(); }
+ bool isAtomic() const { return llvm::isa<AtomicConstraint *>(Constraint); }
bool isFoldExpanded() const {
- return Constraint.is<FoldExpandedConstraint *>();
+ return llvm::isa<FoldExpandedConstraint *>(Constraint);
}
- bool isCompound() const { return Constraint.is<CompoundConstraint>(); }
+ bool isCompound() const { return llvm::isa<CompoundConstraint>(Constraint); }
- CompoundConstraintKind getCompoundKind() const {
- assert(isCompound() && "getCompoundKind on a non-compound constraint..");
- return Constraint.get<CompoundConstraint>().getInt();
- }
+ CompoundConstraintKind getCompoundKind() const;
NormalizedConstraint &getLHS() const;
NormalizedConstraint &getRHS() const;
- AtomicConstraint *getAtomicConstraint() const {
- assert(isAtomic() &&
- "getAtomicConstraint called on non-atomic constraint.");
- return Constraint.get<AtomicConstraint *>();
- }
+ AtomicConstraint *getAtomicConstraint() const;
- FoldExpandedConstraint *getFoldExpandedConstraint() const {
- assert(isFoldExpanded() &&
- "getFoldExpandedConstraint called on non-fold-expanded constraint.");
- return Constraint.get<FoldExpandedConstraint *>();
- }
+ FoldExpandedConstraint *getFoldExpandedConstraint() const;
private:
static std::optional<NormalizedConstraint>
@@ -210,17 +199,17 @@ bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF,
bool Found = false;
for (NormalFormConstraint Pia : Pi) {
for (NormalFormConstraint Qjb : Qj) {
- if (Pia.is<FoldExpandedConstraint *>() &&
- Qjb.is<FoldExpandedConstraint *>()) {
- if (Pia.get<FoldExpandedConstraint *>()->subsumes(
- *Qjb.get<FoldExpandedConstraint *>(), E)) {
+ if (isa<FoldExpandedConstraint *>(Pia) &&
+ isa<FoldExpandedConstraint *>(Qjb)) {
+ if (cast<FoldExpandedConstraint *>(Pia)->subsumes(
+ *cast<FoldExpandedConstraint *>(Qjb), E)) {
Found = true;
break;
}
- } else if (Pia.is<AtomicConstraint *>() &&
- Qjb.is<AtomicConstraint *>()) {
- if (E(*Pia.get<AtomicConstraint *>(),
- *Qjb.get<AtomicConstraint *>())) {
+ } else if (isa<AtomicConstraint *>(Pia) &&
+ isa<AtomicConstraint *>(Qjb)) {
+ if (E(*cast<AtomicConstraint *>(Pia),
+ *cast<AtomicConstraint *>(Qjb))) {
Found = true;
break;
}
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index ee685d95c961..f4cd11f423a8 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -119,6 +119,7 @@ public:
void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL);
void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL);
void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL);
+ void handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL);
void handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL);
void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL);
void handleShaderAttr(Decl *D, const ParsedAttr &AL);
diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h
index 41d05b2bfb07..27cda7198972 100644
--- a/clang/include/clang/Sema/SemaInternal.h
+++ b/clang/include/clang/Sema/SemaInternal.h
@@ -75,7 +75,7 @@ getDepthAndIndex(UnexpandedParameterPack UPP) {
if (const auto *TTP = UPP.first.dyn_cast<const TemplateTypeParmType *>())
return std::make_pair(TTP->getDepth(), TTP->getIndex());
- return getDepthAndIndex(UPP.first.get<NamedDecl *>());
+ return getDepthAndIndex(cast<NamedDecl *>(UPP.first));
}
class TypoCorrectionConsumer : public VisibleDeclConsumer {
diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h
index d720cf3c74d8..addc33bf3c76 100644
--- a/clang/include/clang/Sema/SemaOpenACC.h
+++ b/clang/include/clang/Sema/SemaOpenACC.h
@@ -164,9 +164,14 @@ public:
}
/// If there is a current 'active' loop construct with a 'gang' clause on a
- /// 'kernel' construct, this will have the source location for it. This
- /// permits us to implement the restriction of no further 'gang' clauses.
- SourceLocation LoopGangClauseOnKernelLoc;
+ /// 'kernel' construct, this will have the source location for it, and the
+ /// 'kernel kind'. This permits us to implement the restriction of no further
+ /// 'gang' clauses.
+ struct LoopGangOnKernelTy {
+ SourceLocation Loc;
+ OpenACCDirectiveKind DirKind = OpenACCDirectiveKind::Invalid;
+ } LoopGangClauseOnKernel;
+
/// If there is a current 'active' loop construct with a 'worker' clause on it
/// (on any sort of construct), this has the source location for it. This
/// permits us to implement the restriction of no further 'gang' or 'worker'
@@ -291,13 +296,15 @@ public:
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
+ ClauseKind == OpenACCClauseKind::DeviceNum ||
ClauseKind == OpenACCClauseKind::Tile ||
ClauseKind == OpenACCClauseKind::Worker ||
ClauseKind == OpenACCClauseKind::Vector ||
ClauseKind == OpenACCClauseKind::VectorLength) &&
"Parsed clause kind does not have a int exprs");
- // 'async' and 'wait' have an optional IntExpr, so be tolerant of that.
+ // 'async', 'worker', 'vector', and 'wait' have an optional IntExpr, so be
+ // tolerant of that.
if ((ClauseKind == OpenACCClauseKind::Async ||
ClauseKind == OpenACCClauseKind::Worker ||
ClauseKind == OpenACCClauseKind::Vector ||
@@ -341,6 +348,7 @@ public:
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
+ ClauseKind == OpenACCClauseKind::DeviceNum ||
ClauseKind == OpenACCClauseKind::Tile ||
ClauseKind == OpenACCClauseKind::Gang ||
ClauseKind == OpenACCClauseKind::Worker ||
@@ -394,6 +402,9 @@ public:
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
ClauseKind == OpenACCClauseKind::Attach ||
+ ClauseKind == OpenACCClauseKind::Delete ||
+ ClauseKind == OpenACCClauseKind::UseDevice ||
+ ClauseKind == OpenACCClauseKind::Detach ||
ClauseKind == OpenACCClauseKind::DevicePtr ||
ClauseKind == OpenACCClauseKind::Reduction ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
@@ -474,6 +485,7 @@ public:
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
+ ClauseKind == OpenACCClauseKind::DeviceNum ||
ClauseKind == OpenACCClauseKind::Tile ||
ClauseKind == OpenACCClauseKind::Worker ||
ClauseKind == OpenACCClauseKind::Vector ||
@@ -485,6 +497,7 @@ public:
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
+ ClauseKind == OpenACCClauseKind::DeviceNum ||
ClauseKind == OpenACCClauseKind::Tile ||
ClauseKind == OpenACCClauseKind::Worker ||
ClauseKind == OpenACCClauseKind::Vector ||
@@ -530,6 +543,9 @@ public:
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
ClauseKind == OpenACCClauseKind::Attach ||
+ ClauseKind == OpenACCClauseKind::Delete ||
+ ClauseKind == OpenACCClauseKind::UseDevice ||
+ ClauseKind == OpenACCClauseKind::Detach ||
ClauseKind == OpenACCClauseKind::DevicePtr ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
"Parsed clause kind does not have a var-list");
@@ -566,6 +582,9 @@ public:
ClauseKind == OpenACCClauseKind::PCreate ||
ClauseKind == OpenACCClauseKind::PresentOrCreate ||
ClauseKind == OpenACCClauseKind::Attach ||
+ ClauseKind == OpenACCClauseKind::Delete ||
+ ClauseKind == OpenACCClauseKind::UseDevice ||
+ ClauseKind == OpenACCClauseKind::Detach ||
ClauseKind == OpenACCClauseKind::DevicePtr ||
ClauseKind == OpenACCClauseKind::FirstPrivate) &&
"Parsed clause kind does not have a var-list");
@@ -648,7 +667,8 @@ public:
/// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
/// happen before any associated declarations or statements have been parsed.
/// This function is only called when we are parsing a 'statement' context.
- bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc);
+ bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
+ ArrayRef<const OpenACCClause *> Clauses);
/// Called after the directive, including its clauses, have been parsed and
/// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
@@ -664,12 +684,18 @@ public:
/// Called after the directive has been completely parsed, including the
/// declaration group or associated statement.
- StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K,
- SourceLocation StartLoc,
- SourceLocation DirLoc,
- SourceLocation EndLoc,
- ArrayRef<OpenACCClause *> Clauses,
- StmtResult AssocStmt);
+ /// LParenLoc: Location of the left paren, if it exists (not on all
+ /// constructs).
+ /// MiscLoc: First misc location, if necessary (not all constructs).
+ /// Exprs: List of expressions on the construct itself, if necessary (not all
+ /// constructs).
+ /// RParenLoc: Location of the right paren, if it exists (not on all
+ /// constructs).
+ StmtResult ActOnEndStmtDirective(
+ OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc,
+ SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc, SourceLocation EndLoc,
+ ArrayRef<OpenACCClause *> Clauses, StmtResult AssocStmt);
/// Called after the directive has been completely parsed, including the
/// declaration group or associated statement.
@@ -705,12 +731,15 @@ public:
ExprResult CheckTileSizeExpr(Expr *SizeExpr);
// Check a single expression on a gang clause.
- ExprResult CheckGangExpr(OpenACCGangKind GK, Expr *E);
+ ExprResult CheckGangExpr(ArrayRef<const OpenACCClause *> ExistingClauses,
+ OpenACCDirectiveKind DK, OpenACCGangKind GK,
+ Expr *E);
// Does the checking for a 'gang' clause that needs to be done in dependent
// and not dependent cases.
OpenACCClause *
- CheckGangClause(ArrayRef<const OpenACCClause *> ExistingClauses,
+ CheckGangClause(OpenACCDirectiveKind DirKind,
+ ArrayRef<const OpenACCClause *> ExistingClauses,
SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<OpenACCGangKind> GangKinds,
ArrayRef<Expr *> IntExprs, SourceLocation EndLoc);
@@ -771,7 +800,7 @@ public:
SemaOpenACC &SemaRef;
ComputeConstructInfo OldActiveComputeConstructInfo;
OpenACCDirectiveKind DirKind;
- SourceLocation OldLoopGangClauseOnKernelLoc;
+ LoopGangOnKernelTy OldLoopGangClauseOnKernel;
SourceLocation OldLoopWorkerClauseLoc;
SourceLocation OldLoopVectorClauseLoc;
LoopWithoutSeqCheckingInfo OldLoopWithoutSeqInfo;
diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h
index 6872d04cc4df..9800f75f676a 100644
--- a/clang/include/clang/Sema/Template.h
+++ b/clang/include/clang/Sema/Template.h
@@ -486,10 +486,10 @@ enum class TemplateSubstitutionKind : char {
const Decl *D = I->first;
llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
newScope->LocalDecls[D];
- if (I->second.is<Decl *>()) {
- Stored = I->second.get<Decl *>();
+ if (auto *D2 = dyn_cast<Decl *>(I->second)) {
+ Stored = D2;
} else {
- DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>();
+ DeclArgumentPack *OldPack = cast<DeclArgumentPack *>(I->second);
DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
Stored = NewPack;
newScope->ArgumentPacks.push_back(NewPack);
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index fd834c14ce79..dfd82afad400 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -724,15 +724,20 @@ enum ASTRecordTypes {
/// Record code for vtables to emit.
VTABLES_TO_EMIT = 70,
- /// Record code for the FunctionDecl to lambdas mapping. These lambdas have to
- /// be loaded right after the function they belong to. It is required to have
- /// canonical declaration for the lambda class from the same module as
- /// enclosing function.
- FUNCTION_DECL_TO_LAMBDAS_MAP = 71,
+ /// Record code for related declarations that have to be deserialized together
+ /// from the same module.
+ RELATED_DECLS_MAP = 71,
/// Record code for Sema's vector of functions/blocks with effects to
/// be verified.
DECLS_WITH_EFFECTS_TO_VERIFY = 72,
+
+ /// Record code for updated specialization
+ UPDATE_SPECIALIZATION = 73,
+
+ CXX_ADDED_TEMPLATE_SPECIALIZATION = 74,
+
+ CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION = 75,
};
/// Record types used within a source manager block.
@@ -1502,6 +1507,12 @@ enum DeclCode {
/// An ImplicitConceptSpecializationDecl record.
DECL_IMPLICIT_CONCEPT_SPECIALIZATION,
+ // A decls specilization record.
+ DECL_SPECIALIZATIONS,
+
+ // A decls specilization record.
+ DECL_PARTIAL_SPECIALIZATIONS,
+
DECL_LAST = DECL_IMPLICIT_CONCEPT_SPECIALIZATION
};
@@ -2006,6 +2017,13 @@ enum StmtCode {
STMT_OPENACC_LOOP_CONSTRUCT,
STMT_OPENACC_COMBINED_CONSTRUCT,
EXPR_OPENACC_ASTERISK_SIZE,
+ STMT_OPENACC_DATA_CONSTRUCT,
+ STMT_OPENACC_ENTER_DATA_CONSTRUCT,
+ STMT_OPENACC_EXIT_DATA_CONSTRUCT,
+ STMT_OPENACC_HOST_DATA_CONSTRUCT,
+ STMT_OPENACC_WAIT_CONSTRUCT,
+ STMT_OPENACC_INIT_CONSTRUCT,
+ STMT_OPENACC_SHUTDOWN_CONSTRUCT,
// HLSL Constructs
EXPR_HLSL_OUT_ARG,
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index f739fe688c11..9f978762a6fb 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -354,6 +354,9 @@ class ASTIdentifierLookupTrait;
/// The on-disk hash table(s) used for DeclContext name lookup.
struct DeclContextLookupTable;
+/// The on-disk hash table(s) used for specialization decls.
+struct LazySpecializationInfoLookupTable;
+
} // namespace reader
} // namespace serialization
@@ -534,17 +537,14 @@ private:
/// namespace as if it is not delayed.
DelayedNamespaceOffsetMapTy DelayedNamespaceOffsetMap;
- /// Mapping from FunctionDecl IDs to the corresponding lambda IDs.
+ /// Mapping from main decl ID to the related decls IDs.
///
- /// These lambdas have to be loaded right after the function they belong to.
- /// It is required to have canonical declaration for lambda class from the
- /// same module as enclosing function. This is required to correctly resolve
- /// captured variables in the lambda. Without this, due to lazy
- /// deserialization, canonical declarations for the function and lambdas can
- /// be selected from different modules and DeclRefExprs may refer to the AST
- /// nodes that don't exist in the function.
- llvm::DenseMap<GlobalDeclID, SmallVector<GlobalDeclID, 4>>
- FunctionToLambdasMap;
+ /// These related decls have to be loaded right after the main decl.
+ /// It is required to have canonical declaration for related decls from the
+ /// same module as the enclosing main decl. Without this, due to lazy
+ /// deserialization, canonical declarations for the main decl and related can
+ /// be selected from different modules.
+ llvm::DenseMap<GlobalDeclID, SmallVector<GlobalDeclID, 4>> RelatedDeclsMap;
struct PendingUpdateRecord {
Decl *D;
@@ -632,20 +632,40 @@ private:
llvm::DenseMap<const DeclContext *,
serialization::reader::DeclContextLookupTable> Lookups;
+ using SpecLookupTableTy =
+ llvm::DenseMap<const Decl *,
+ serialization::reader::LazySpecializationInfoLookupTable>;
+ /// Map from decls to specialized decls.
+ SpecLookupTableTy SpecializationsLookups;
+ /// Split partial specialization from specialization to speed up lookups.
+ SpecLookupTableTy PartialSpecializationsLookups;
+
+ bool LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups,
+ const Decl *D);
+ bool LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups,
+ const Decl *D,
+ ArrayRef<TemplateArgument> TemplateArgs);
+
// Updates for visible decls can occur for other contexts than just the
// TU, and when we read those update records, the actual context may not
// be available yet, so have this pending map using the ID as a key. It
- // will be realized when the context is actually loaded.
- struct PendingVisibleUpdate {
+ // will be realized when the data is actually loaded.
+ struct UpdateData {
ModuleFile *Mod;
const unsigned char *Data;
};
- using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>;
+ using DeclContextVisibleUpdates = SmallVector<UpdateData, 1>;
/// Updates to the visible declarations of declaration contexts that
/// haven't been loaded yet.
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> PendingVisibleUpdates;
+ using SpecializationsUpdate = SmallVector<UpdateData, 1>;
+ using SpecializationsUpdateMap =
+ llvm::DenseMap<GlobalDeclID, SpecializationsUpdate>;
+ SpecializationsUpdateMap PendingSpecializationsUpdates;
+ SpecializationsUpdateMap PendingPartialSpecializationsUpdates;
+
/// The set of C++ or Objective-C classes that have forward
/// declarations that have not yet been linked to their definitions.
llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
@@ -678,6 +698,11 @@ private:
llvm::BitstreamCursor &Cursor,
uint64_t Offset, GlobalDeclID ID);
+ bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
+ uint64_t Offset, Decl *D, bool IsPartial);
+ void AddSpecializations(const Decl *D, const unsigned char *Data,
+ ModuleFile &M, bool IsPartial);
+
/// A vector containing identifiers that have already been
/// loaded.
///
@@ -1419,6 +1444,14 @@ public:
const serialization::reader::DeclContextLookupTable *
getLoadedLookupTables(DeclContext *Primary) const;
+ /// Get the loaded specializations lookup tables for \p D,
+ /// if any.
+ serialization::reader::LazySpecializationInfoLookupTable *
+ getLoadedSpecializationsLookupTables(const Decl *D, bool IsPartial);
+
+ /// If we have any unloaded specialization for \p D
+ bool haveUnloadedSpecializations(const Decl *D) const;
+
private:
struct ImportedModule {
ModuleFile *Mod;
@@ -2076,6 +2109,12 @@ public:
unsigned BlockID,
uint64_t *StartOfBlockOffset = nullptr);
+ bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;
+
+ bool
+ LoadExternalSpecializations(const Decl *D,
+ ArrayRef<TemplateArgument> TemplateArgs) override;
+
/// Finds all the visible declarations with a given name.
/// The current implementation of this method just loads the entire
/// lookup table as unmaterialized references.
diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h
index e418fdea44a0..adb7cce522a8 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -230,13 +230,12 @@ private:
/// instead of comparing the result of `getDeclID()` or `GetDeclRef()`.
llvm::SmallPtrSet<const Decl *, 32> PredefinedDecls;
- /// Mapping from FunctionDecl ID to the list of lambda IDs inside the
- /// function.
+ /// Mapping from the main decl to related decls inside the main decls.
///
- /// These lambdas have to be loaded right after the function they belong to.
- /// In order to have canonical declaration for lambda class from the same
- /// module as enclosing function during deserialization.
- llvm::DenseMap<LocalDeclID, SmallVector<LocalDeclID, 4>> FunctionToLambdasMap;
+ /// These related decls have to be loaded right after the main decl they
+ /// belong to. In order to have canonical declaration for related decls from
+ /// the same module as the main decl during deserialization.
+ llvm::DenseMap<LocalDeclID, SmallVector<LocalDeclID, 4>> RelatedDeclsMap;
/// Offset of each declaration in the bitstream, indexed by
/// the declaration's ID.
@@ -423,6 +422,13 @@ private:
/// Only meaningful for reduced BMI.
DeclUpdateMap DeclUpdatesFromGMF;
+ /// Mapping from decl templates and its new specialization in the
+ /// current TU.
+ using SpecializationUpdateMap =
+ llvm::MapVector<const NamedDecl *, SmallVector<const Decl *>>;
+ SpecializationUpdateMap SpecializationsUpdates;
+ SpecializationUpdateMap PartialSpecializationsUpdates;
+
using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;
/// Map of first declarations from a chained PCH that point to the
@@ -575,6 +581,12 @@ private:
bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
+ void GenerateSpecializationInfoLookupTable(
+ const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
+ llvm::SmallVectorImpl<char> &LookupTable, bool IsPartial);
+ uint64_t WriteSpecializationInfoLookupTable(
+ const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
+ bool IsPartial);
void GenerateNameLookupTable(ASTContext &Context, const DeclContext *DC,
llvm::SmallVectorImpl<char> &LookupTable);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context,
@@ -590,6 +602,7 @@ private:
void WriteDeclAndTypes(ASTContext &Context);
void PrepareWritingSpecialDecls(Sema &SemaRef);
void WriteSpecialDeclRecords(Sema &SemaRef);
+ void WriteSpecializationsUpdates(bool IsPartial);
void WriteDeclUpdatesBlocks(ASTContext &Context,
RecordDataImpl &OffsetsRecord);
void WriteDeclContextVisibleUpdate(ASTContext &Context,
@@ -619,6 +632,9 @@ private:
unsigned DeclEnumAbbrev = 0;
unsigned DeclObjCIvarAbbrev = 0;
unsigned DeclCXXMethodAbbrev = 0;
+ unsigned DeclSpecializationsAbbrev = 0;
+ unsigned DeclPartialSpecializationsAbbrev = 0;
+
unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
unsigned DeclTemplateCXXMethodAbbrev = 0;
unsigned DeclMemberSpecializedCXXMethodAbbrev = 0;
@@ -981,13 +997,15 @@ protected:
virtual Module *getEmittingModule(ASTContext &Ctx) override;
CXX20ModulesGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
- StringRef OutputFile, bool GeneratingReducedBMI);
+ StringRef OutputFile, bool GeneratingReducedBMI,
+ bool AllowASTWithErrors);
public:
CXX20ModulesGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
- StringRef OutputFile)
+ StringRef OutputFile, bool AllowASTWithErrors = false)
: CXX20ModulesGenerator(PP, ModuleCache, OutputFile,
- /*GeneratingReducedBMI=*/false) {}
+ /*GeneratingReducedBMI=*/false,
+ AllowASTWithErrors) {}
void HandleTranslationUnit(ASTContext &Ctx) override;
};
@@ -997,9 +1015,10 @@ class ReducedBMIGenerator : public CXX20ModulesGenerator {
public:
ReducedBMIGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
- StringRef OutputFile)
+ StringRef OutputFile, bool AllowASTWithErrors = false)
: CXX20ModulesGenerator(PP, ModuleCache, OutputFile,
- /*GeneratingReducedBMI=*/true) {}
+ /*GeneratingReducedBMI=*/true,
+ AllowASTWithErrors) {}
};
/// If we can elide the definition of \param D in reduced BMI.
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 9be82622f264..b34e940682fc 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -1749,6 +1749,10 @@ def UncountedLambdaCapturesChecker : Checker<"UncountedLambdaCapturesChecker">,
let ParentPackage = WebKitAlpha in {
+def MemoryUnsafeCastChecker : Checker<"MemoryUnsafeCastChecker">,
+ HelpText<"Check for memory unsafe casts from base type to derived type.">,
+ Documentation<HasDocumentation>;
+
def NoUncheckedPtrMemberChecker : Checker<"NoUncheckedPtrMemberChecker">,
HelpText<"Check for no unchecked member variables.">,
Documentation<HasDocumentation>;
diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
index ad2dbffe8832..d8a7c755c959 100644
--- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
+++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
@@ -189,20 +189,29 @@ ANALYZER_OPTION(
"crosscheck-with-z3-eqclass-timeout-threshold",
"Set a timeout for bug report equivalence classes in milliseconds. "
"If we exhaust this threshold, we will drop the bug report eqclass "
- "instead of doing more Z3 queries. Set 0 for no timeout.", 700)
+ "instead of doing more Z3 queries. Setting this to 700 ms in conjunction "
+ "with \"crosscheck-with-z3-timeout-threshold\" of 300 ms, would nicely "
+ "guarantee that no bug report equivalence class can take longer than "
+ "1 second, effectively mitigating Z3 hangs during refutation. "
+ "Set 0 for no timeout.", 0)
ANALYZER_OPTION(
unsigned, Z3CrosscheckTimeoutThreshold,
"crosscheck-with-z3-timeout-threshold",
"Set a timeout for individual Z3 queries in milliseconds. "
- "Set 0 for no timeout.", 300)
+ "On fast machines, 300 worked well in some cases. "
+ "The lower it is, the higher the chances of having flaky issues. "
+ "Having no timeout may hang the analyzer indefinitely. "
+ "Set 0 for no timeout.", 15'000)
ANALYZER_OPTION(
unsigned, Z3CrosscheckRLimitThreshold,
"crosscheck-with-z3-rlimit-threshold",
- "Set the Z3 resource limit threshold. This sets a deterministic cutoff "
- "point for Z3 queries, as longer queries usually consume more resources. "
- "Set 0 for unlimited.", 400'000)
+ "Set the Z3 resource limit threshold. This sets a supposedly deterministic "
+ "cutoff point for Z3 queries, as longer queries usually consume more "
+ "resources. "
+ "400'000 should on average make Z3 queries run for up to 100ms on modern "
+ "hardware. Set 0 for unlimited.", 0)
ANALYZER_OPTION(bool, ShouldReportIssuesInMainSourceFile,
"report-in-main-source-file",
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h
new file mode 100644
index 000000000000..84a6bf1406ac
--- /dev/null
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h
@@ -0,0 +1,64 @@
+//== APSIntPtr.h - Wrapper for APSInt objects owned separately -*- 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_STATICANALYZER_CORE_PATHSENSITIVE_APSIntPtr_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSIntPtr_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang::ento {
+
+/// A safe wrapper around APSInt objects allocated and owned by
+/// \c BasicValueFactory. This just wraps a common llvm::APSInt.
+class APSIntPtr {
+ using APSInt = llvm::APSInt;
+
+public:
+ APSIntPtr() = delete;
+ APSIntPtr(const APSIntPtr &) = default;
+ APSIntPtr &operator=(const APSIntPtr &) & = default;
+ ~APSIntPtr() = default;
+
+ /// You should not use this API.
+ /// If do, ensure that the \p Ptr not going to dangle.
+ /// Prefer using \c BasicValueFactory::getValue() to get an APSIntPtr object.
+ static APSIntPtr unsafeConstructor(const APSInt *Ptr) {
+ return APSIntPtr(Ptr);
+ }
+
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
+ const APSInt *get() const { return Ptr; }
+ /*implicit*/ operator const APSInt &() const { return *get(); }
+
+ APSInt operator-() const { return -*Ptr; }
+ APSInt operator~() const { return ~*Ptr; }
+
+#define DEFINE_OPERATOR(OP) \
+ bool operator OP(APSIntPtr Other) const { return (*Ptr)OP(*Other.Ptr); }
+ DEFINE_OPERATOR(>)
+ DEFINE_OPERATOR(>=)
+ DEFINE_OPERATOR(<)
+ DEFINE_OPERATOR(<=)
+ DEFINE_OPERATOR(==)
+ DEFINE_OPERATOR(!=)
+#undef DEFINE_OPERATOR
+
+ const APSInt &operator*() const { return *Ptr; }
+ const APSInt *operator->() const { return Ptr; }
+
+private:
+ explicit APSIntPtr(const APSInt *Ptr) : Ptr(Ptr) {}
+
+ /// Owned by \c BasicValueFactory.
+ const APSInt *Ptr;
+};
+
+} // namespace clang::ento
+
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSIntPtr_H
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index ec503b41b381..ef04f9c485e8 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -18,10 +18,11 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableList.h"
@@ -129,7 +130,7 @@ class BasicValueFactory {
// This is private because external clients should use the factory
// method that takes a QualType.
- const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
+ APSIntPtr getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
public:
BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
@@ -140,9 +141,9 @@ public:
ASTContext &getContext() const { return Ctx; }
- const llvm::APSInt& getValue(const llvm::APSInt& X);
- const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned);
- const llvm::APSInt& getValue(uint64_t X, QualType T);
+ APSIntPtr getValue(const llvm::APSInt &X);
+ APSIntPtr getValue(const llvm::APInt &X, bool isUnsigned);
+ APSIntPtr getValue(uint64_t X, QualType T);
/// Returns the type of the APSInt used to store values of the given QualType.
APSIntType getAPSIntType(QualType T) const {
@@ -165,79 +166,70 @@ public:
/// Convert - Create a new persistent APSInt with the same value as 'From'
/// but with the bitwidth and signedness of 'To'.
- const llvm::APSInt &Convert(const llvm::APSInt& To,
- const llvm::APSInt& From) {
+ APSIntPtr Convert(const llvm::APSInt &To, const llvm::APSInt &From) {
APSIntType TargetType(To);
if (TargetType == APSIntType(From))
- return From;
+ return getValue(From);
return getValue(TargetType.convert(From));
}
- const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) {
+ APSIntPtr Convert(QualType T, const llvm::APSInt &From) {
APSIntType TargetType = getAPSIntType(T);
return Convert(TargetType, From);
}
- const llvm::APSInt &Convert(APSIntType TargetType, const llvm::APSInt &From) {
+ APSIntPtr Convert(APSIntType TargetType, const llvm::APSInt &From) {
if (TargetType == APSIntType(From))
- return From;
+ return getValue(From);
return getValue(TargetType.convert(From));
}
- const llvm::APSInt &getIntValue(uint64_t X, bool isUnsigned) {
+ APSIntPtr getIntValue(uint64_t X, bool isUnsigned) {
QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy;
return getValue(X, T);
}
- const llvm::APSInt &getMaxValue(const llvm::APSInt &v) {
+ APSIntPtr getMaxValue(const llvm::APSInt &v) {
return getValue(APSIntType(v).getMaxValue());
}
- const llvm::APSInt &getMinValue(const llvm::APSInt &v) {
+ APSIntPtr getMinValue(const llvm::APSInt &v) {
return getValue(APSIntType(v).getMinValue());
}
- const llvm::APSInt &getMaxValue(QualType T) {
- return getMaxValue(getAPSIntType(T));
- }
+ APSIntPtr getMaxValue(QualType T) { return getMaxValue(getAPSIntType(T)); }
- const llvm::APSInt &getMinValue(QualType T) {
- return getMinValue(getAPSIntType(T));
- }
+ APSIntPtr getMinValue(QualType T) { return getMinValue(getAPSIntType(T)); }
- const llvm::APSInt &getMaxValue(APSIntType T) {
- return getValue(T.getMaxValue());
- }
+ APSIntPtr getMaxValue(APSIntType T) { return getValue(T.getMaxValue()); }
- const llvm::APSInt &getMinValue(APSIntType T) {
- return getValue(T.getMinValue());
- }
+ APSIntPtr getMinValue(APSIntType T) { return getValue(T.getMinValue()); }
- const llvm::APSInt &Add1(const llvm::APSInt &V) {
+ APSIntPtr Add1(const llvm::APSInt &V) {
llvm::APSInt X = V;
++X;
return getValue(X);
}
- const llvm::APSInt &Sub1(const llvm::APSInt &V) {
+ APSIntPtr Sub1(const llvm::APSInt &V) {
llvm::APSInt X = V;
--X;
return getValue(X);
}
- const llvm::APSInt &getZeroWithTypeSize(QualType T) {
+ APSIntPtr getZeroWithTypeSize(QualType T) {
assert(T->isScalarType());
return getValue(0, Ctx.getTypeSize(T), true);
}
- const llvm::APSInt &getTruthValue(bool b, QualType T) {
+ APSIntPtr getTruthValue(bool b, QualType T) {
return getValue(b ? 1 : 0, Ctx.getIntWidth(T),
T->isUnsignedIntegerOrEnumerationType());
}
- const llvm::APSInt &getTruthValue(bool b) {
+ APSIntPtr getTruthValue(bool b) {
return getTruthValue(b, Ctx.getLogicalOperationType());
}
@@ -273,9 +265,9 @@ public:
accumCXXBase(llvm::iterator_range<CastExpr::path_const_iterator> PathRange,
const nonloc::PointerToMember &PTM, const clang::CastKind &kind);
- const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op,
- const llvm::APSInt& V1,
- const llvm::APSInt& V2);
+ std::optional<APSIntPtr> evalAPSInt(BinaryOperator::Opcode Op,
+ const llvm::APSInt &V1,
+ const llvm::APSInt &V2);
const std::pair<SVal, uintptr_t>&
getPersistentSValWithData(const SVal& V, uintptr_t Data);
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index a6d05a3ac67b..80b79fd4e928 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -126,6 +126,14 @@ private:
ExplodedNode *generateCallExitBeginNode(ExplodedNode *N,
const ReturnStmt *RS);
+ /// Helper function called by `HandleBranch()`. If the currently handled
+ /// branch corresponds to a loop, this returns the number of already
+ /// completed iterations in that loop, otherwise the return value is
+ /// `std::nullopt`. Note that this counts _all_ earlier iterations, including
+ /// ones that were performed within an earlier iteration of an outer loop.
+ std::optional<unsigned> getCompletedIterationCount(const CFGBlock *B,
+ ExplodedNode *Pred) const;
+
public:
/// Construct a CoreEngine object to analyze the provided CFG.
CoreEngine(ExprEngine &exprengine,
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 8c7493e27fca..20c446e33ef9 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -321,14 +321,14 @@ public:
NodeBuilderWithSinks &nodeBuilder,
ExplodedNode *Pred);
- /// ProcessBranch - Called by CoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a branch condition.
- void processBranch(const Stmt *Condition,
- NodeBuilderContext& BuilderCtx,
- ExplodedNode *Pred,
- ExplodedNodeSet &Dst,
- const CFGBlock *DstT,
- const CFGBlock *DstF);
+ /// ProcessBranch - Called by CoreEngine. Used to generate successor nodes by
+ /// processing the 'effects' of a branch condition. If the branch condition
+ /// is a loop condition, IterationsCompletedInLoop is the number of completed
+ /// iterations (otherwise it's std::nullopt).
+ void processBranch(const Stmt *Condition, NodeBuilderContext &BuilderCtx,
+ ExplodedNode *Pred, ExplodedNodeSet &Dst,
+ const CFGBlock *DstT, const CFGBlock *DstF,
+ std::optional<unsigned> IterationsCompletedInLoop);
/// Called by CoreEngine.
/// Used to generate successor nodes for temporary destructors depending
@@ -588,6 +588,8 @@ public:
void evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
const Expr *Ex);
+ bool didEagerlyAssumeBifurcateAt(ProgramStateRef State, const Expr *Ex) const;
+
static std::pair<const ProgramPointTag *, const ProgramPointTag *>
getEagerlyAssumeBifurcationTags();
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 0d9566285f5d..f88bf70d7239 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -1206,7 +1206,7 @@ class ElementRegion : public TypedValueRegion {
: TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
Index(Idx) {
assert((!isa<nonloc::ConcreteInt>(Idx) ||
- Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
+ Idx.castAs<nonloc::ConcreteInt>().getValue()->isSigned()) &&
"The index must be signed");
assert(!elementType.isNull() && !elementType->isVoidType() &&
"Invalid region type!");
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 29f534eba2a2..a20516b003c7 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -70,7 +70,6 @@ template <typename T> struct ProgramStateTrait {
/// values will never change.
class ProgramState : public llvm::FoldingSetNode {
public:
- typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
typedef llvm::ImmutableMap<void*, void*> GenericDataMap;
private:
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
index 5766af1fc78a..7cfb24e5e649 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
@@ -16,6 +16,7 @@
#include "clang/Basic/JsonSupport.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h"
#include <optional>
@@ -154,7 +155,7 @@ public:
return nullptr;
// This is the only solution, store it
- return &BVF.getValue(Value);
+ return BVF.getValue(Value).get();
}
if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
@@ -167,16 +168,16 @@ public:
const llvm::APSInt *Value;
if (!(Value = getSymVal(State, CastSym)))
return nullptr;
- return &BVF.Convert(SC->getType(), *Value);
+ return BVF.Convert(SC->getType(), *Value).get();
}
if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
const llvm::APSInt *LHS, *RHS;
if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
LHS = getSymVal(State, SIE->getLHS());
- RHS = &SIE->getRHS();
+ RHS = SIE->getRHS().get();
} else if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
- LHS = &ISE->getLHS();
+ LHS = ISE->getLHS().get();
RHS = getSymVal(State, ISE->getRHS());
} else if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
// Early termination to avoid expensive call
@@ -195,7 +196,9 @@ public:
std::tie(ConvertedRHS, RTy) = SMTConv::fixAPSInt(Ctx, *RHS);
SMTConv::doIntTypeConversion<llvm::APSInt, &SMTConv::castAPSInt>(
Solver, Ctx, ConvertedLHS, LTy, ConvertedRHS, RTy);
- return BVF.evalAPSInt(BSE->getOpcode(), ConvertedLHS, ConvertedRHS);
+ std::optional<APSIntPtr> Res =
+ BVF.evalAPSInt(BSE->getOpcode(), ConvertedLHS, ConvertedRHS);
+ return Res ? Res.value().get() : nullptr;
}
llvm_unreachable("Unsupported expression to get symbol value!");
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index ec2b2b245694..54430d426a82 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -329,11 +329,10 @@ public:
}
nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt &rhs, QualType type);
+ APSIntPtr rhs, QualType type);
- nonloc::SymbolVal makeNonLoc(const llvm::APSInt &rhs,
- BinaryOperator::Opcode op, const SymExpr *lhs,
- QualType type);
+ nonloc::SymbolVal makeNonLoc(APSIntPtr rhs, BinaryOperator::Opcode op,
+ const SymExpr *lhs, QualType type);
nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
const SymExpr *rhs, QualType type);
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index a054a819a15a..aeb57b28077c 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -17,6 +17,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
@@ -298,9 +299,12 @@ public:
/// Value representing integer constant.
class ConcreteInt : public NonLoc {
public:
- explicit ConcreteInt(const llvm::APSInt &V) : NonLoc(ConcreteIntKind, &V) {}
+ explicit ConcreteInt(APSIntPtr V) : NonLoc(ConcreteIntKind, V.get()) {}
- const llvm::APSInt &getValue() const { return *castDataAs<llvm::APSInt>(); }
+ APSIntPtr getValue() const {
+ // This is safe because in the ctor we take a safe APSIntPtr.
+ return APSIntPtr::unsafeConstructor(castDataAs<llvm::APSInt>());
+ }
static bool classof(SVal V) { return V.getKind() == ConcreteIntKind; }
};
@@ -510,9 +514,12 @@ public:
class ConcreteInt : public Loc {
public:
- explicit ConcreteInt(const llvm::APSInt &V) : Loc(ConcreteIntKind, &V) {}
+ explicit ConcreteInt(APSIntPtr V) : Loc(ConcreteIntKind, V.get()) {}
- const llvm::APSInt &getValue() const { return *castDataAs<llvm::APSInt>(); }
+ APSIntPtr getValue() const {
+ // This is safe because in the ctor we take a safe APSIntPtr.
+ return APSIntPtr::unsafeConstructor(castDataAs<llvm::APSInt>());
+ }
static bool classof(SVal V) { return V.getKind() == ConcreteIntKind; }
};
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 3b64d38ee2b2..73732d532f63 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -18,6 +18,7 @@
#include "clang/AST/Type.h"
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
@@ -410,9 +411,7 @@ protected:
return 1;
}
- static const llvm::APSInt *getPointer(const llvm::APSInt &Value) {
- return &Value;
- }
+ static const llvm::APSInt *getPointer(APSIntPtr Value) { return Value.get(); }
static const SymExpr *getPointer(const SymExpr *Value) { return Value; }
static void dumpToStreamImpl(raw_ostream &os, const SymExpr *Value);
@@ -468,11 +467,11 @@ public:
};
/// Represents a symbolic expression like 'x' + 3.
-using SymIntExpr = BinarySymExprImpl<const SymExpr *, const llvm::APSInt &,
+using SymIntExpr = BinarySymExprImpl<const SymExpr *, APSIntPtr,
SymExpr::Kind::SymIntExprKind>;
/// Represents a symbolic expression like 3 - 'x'.
-using IntSymExpr = BinarySymExprImpl<const llvm::APSInt &, const SymExpr *,
+using IntSymExpr = BinarySymExprImpl<APSIntPtr, const SymExpr *,
SymExpr::Kind::IntSymExprKind>;
/// Represents a symbolic expression like 'x' + 'y'.
@@ -537,15 +536,14 @@ public:
QualType From, QualType To);
const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType t);
+ APSIntPtr rhs, QualType t);
const SymIntExpr *getSymIntExpr(const SymExpr &lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType t) {
+ APSIntPtr rhs, QualType t) {
return getSymIntExpr(&lhs, op, rhs, t);
}
- const IntSymExpr *getIntSymExpr(const llvm::APSInt& lhs,
- BinaryOperator::Opcode op,
+ const IntSymExpr *getIntSymExpr(APSIntPtr lhs, BinaryOperator::Opcode op,
const SymExpr *rhs, QualType t);
const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
diff --git a/clang/include/module.modulemap b/clang/include/module.modulemap
index b399f0beee59..5bb9f6b7a91f 100644
--- a/clang/include/module.modulemap
+++ b/clang/include/module.modulemap
@@ -115,7 +115,7 @@ module Clang_Diagnostics {
module Driver { header "clang/Driver/DriverDiagnostic.h" export * }
module Frontend { header "clang/Frontend/FrontendDiagnostic.h" export * }
module Lex { header "clang/Lex/LexDiagnostic.h" export * }
- module Parse { header "clang/Parse/ParseDiagnostic.h" export * }
+ module Parse { header "clang/Basic/DiagnosticParse.h" export * }
module Serialization { header "clang/Serialization/SerializationDiagnostic.h" export * }
module Refactoring { header "clang/Tooling/Refactoring/RefactoringDiagnostic.h" export * }
}
@@ -183,9 +183,14 @@ module Clang_StaticAnalyzer_Frontend {
module * { export * }
}
+module Clang_Support { requires cplusplus umbrella "clang/Support" module * { export * } }
+
module Clang_Testing {
requires cplusplus
umbrella "clang/Testing"
+
+ textual header "clang/Testing/TestLanguage.def"
+
module * { export * }
}