Merge llvm-project main llvmorg-14-init-17616-g024a1fab5c35

This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-14-init-17616-g024a1fab5c35.

PR:		261742
MFC after:	2 weeks
This commit is contained in:
Dimitry Andric
2022-01-27 23:17:16 +01:00
2699 changed files with 64745 additions and 40299 deletions
+1
View File
@@ -350,6 +350,7 @@ OLD_DIRS+=usr/lib/clang/13.0.0/lib
OLD_DIRS+=usr/lib/clang/13.0.0
# 20220514: new libc++ import which bumps version from 13.0.0 to 14.0.0
OLD_FILES+=usr/include/c++/v1/__function_like.h
OLD_FILES+=usr/include/c++/v1/__memory/pointer_safety.h
OLD_FILES+=usr/include/c++/v1/__utility/__decay_copy.h
@@ -133,7 +133,7 @@ class CommonTypeInfo : public CommonEntityInfo {
llvm::Optional<std::string> NSErrorDomain;
public:
CommonTypeInfo() : CommonEntityInfo() {}
CommonTypeInfo() {}
const llvm::Optional<std::string> &getSwiftBridge() const {
return SwiftBridge;
@@ -208,10 +208,9 @@ class ObjCContextInfo : public CommonTypeInfo {
public:
ObjCContextInfo()
: CommonTypeInfo(), HasDefaultNullability(0), DefaultNullability(0),
HasDesignatedInits(0), SwiftImportAsNonGenericSpecified(false),
SwiftImportAsNonGeneric(false), SwiftObjCMembersSpecified(false),
SwiftObjCMembers(false) {}
: HasDefaultNullability(0), DefaultNullability(0), HasDesignatedInits(0),
SwiftImportAsNonGenericSpecified(false), SwiftImportAsNonGeneric(false),
SwiftObjCMembersSpecified(false), SwiftObjCMembers(false) {}
/// Determine the default nullability for properties and methods of this
/// class.
@@ -309,7 +308,7 @@ class VariableInfo : public CommonEntityInfo {
std::string Type;
public:
VariableInfo() : CommonEntityInfo(), NullabilityAudited(false), Nullable(0) {}
VariableInfo() : NullabilityAudited(false), Nullable(0) {}
llvm::Optional<NullabilityKind> getNullability() const {
return NullabilityAudited ? llvm::Optional<NullabilityKind>(
@@ -358,8 +357,7 @@ class ObjCPropertyInfo : public VariableInfo {
public:
ObjCPropertyInfo()
: VariableInfo(), SwiftImportAsAccessorsSpecified(false),
SwiftImportAsAccessors(false) {}
: SwiftImportAsAccessorsSpecified(false), SwiftImportAsAccessors(false) {}
llvm::Optional<bool> getSwiftImportAsAccessors() const {
return SwiftImportAsAccessorsSpecified
@@ -423,8 +421,7 @@ class ParamInfo : public VariableInfo {
public:
ParamInfo()
: VariableInfo(), NoEscapeSpecified(false), NoEscape(false),
RawRetainCountConvention() {}
: NoEscapeSpecified(false), NoEscape(false), RawRetainCountConvention() {}
llvm::Optional<bool> isNoEscape() const {
if (!NoEscapeSpecified)
@@ -514,7 +511,7 @@ class FunctionInfo : public CommonEntityInfo {
std::vector<ParamInfo> Params;
FunctionInfo()
: CommonEntityInfo(), NullabilityAudited(false), NumAdjustedNullable(0),
: NullabilityAudited(false), NumAdjustedNullable(0),
RawRetainCountConvention() {}
static unsigned getMaxNullabilityIndex() {
@@ -607,8 +604,7 @@ class ObjCMethodInfo : public FunctionInfo {
/// Whether this is a required initializer.
unsigned RequiredInit : 1;
ObjCMethodInfo()
: FunctionInfo(), DesignatedInit(false), RequiredInit(false) {}
ObjCMethodInfo() : DesignatedInit(false), RequiredInit(false) {}
friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &);
@@ -639,19 +635,19 @@ inline bool operator!=(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) {
/// Describes API notes data for a global variable.
class GlobalVariableInfo : public VariableInfo {
public:
GlobalVariableInfo() : VariableInfo() {}
GlobalVariableInfo() {}
};
/// Describes API notes data for a global function.
class GlobalFunctionInfo : public FunctionInfo {
public:
GlobalFunctionInfo() : FunctionInfo() {}
GlobalFunctionInfo() {}
};
/// Describes API notes data for an enumerator.
class EnumConstantInfo : public CommonEntityInfo {
public:
EnumConstantInfo() : CommonEntityInfo() {}
EnumConstantInfo() {}
};
/// Describes API notes data for a tag.
@@ -662,7 +658,7 @@ class TagInfo : public CommonTypeInfo {
public:
llvm::Optional<EnumExtensibilityKind> EnumExtensibility;
TagInfo() : CommonTypeInfo(), HasFlagEnum(0), IsFlagEnum(0) {}
TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {}
llvm::Optional<bool> isFlagEnum() const {
if (HasFlagEnum)
@@ -706,7 +702,7 @@ class TypedefInfo : public CommonTypeInfo {
public:
llvm::Optional<SwiftNewTypeKind> SwiftWrapper;
TypedefInfo() : CommonTypeInfo() {}
TypedefInfo() {}
TypedefInfo &operator|=(const TypedefInfo &RHS) {
static_cast<CommonTypeInfo &>(*this) |= RHS;
@@ -22,7 +22,6 @@
namespace clang {
class ConceptDecl;
class ConceptSpecializationExpr;
/// The result of a constraint satisfaction check, containing the necessary
/// information to diagnose an unsatisfied constraint.
@@ -123,17 +122,16 @@ class ConceptReference {
const ASTTemplateArgumentListInfo *ArgsAsWritten;
public:
ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
ConceptDecl *NamedConcept,
const ASTTemplateArgumentListInfo *ArgsAsWritten) :
NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
const ASTTemplateArgumentListInfo *ArgsAsWritten)
: NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
ConceptReference() : NestedNameSpec(), TemplateKWLoc(), ConceptName(),
FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {}
ConceptReference()
: FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {}
const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
return NestedNameSpec;
@@ -99,15 +99,12 @@ class CXXMethodDecl;
class CXXRecordDecl;
class DiagnosticsEngine;
class ParentMapContext;
class DynTypedNode;
class DynTypedNodeList;
class Expr;
enum class FloatModeKind;
class GlobalDecl;
class ItaniumMangleContext;
class MangleContext;
class MangleNumberingContext;
class MaterializeTemporaryExpr;
class MemberSpecializationInfo;
class Module;
struct MSGuidDeclParts;
@@ -126,7 +123,6 @@ class ObjCTypeParamDecl;
class OMPTraitInfo;
struct ParsedTargetAttr;
class Preprocessor;
class Stmt;
class StoredDeclsMap;
class TargetAttr;
class TargetInfo;
@@ -2626,6 +2622,18 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// template.
bool hasSameTemplateName(TemplateName X, TemplateName Y);
/// Determine whether the two declarations refer to the same entity.
bool isSameEntity(NamedDecl *X, NamedDecl *Y);
/// Determine whether two template parameter lists are similar enough
/// that they may be used in declarations of the same template.
bool isSameTemplateParameterList(TemplateParameterList *X,
TemplateParameterList *Y);
/// Determine whether two template parameters are similar enough
/// that they may be used in declarations of the same template.
bool isSameTemplateParameter(NamedDecl *X, NamedDecl *Y);
/// Retrieve the "canonical" template argument.
///
/// The canonical template argument is the simplest template argument
@@ -2730,13 +2738,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
QualType typeDomain) const;
unsigned getTargetAddressSpace(QualType T) const {
return getTargetAddressSpace(T.getQualifiers());
}
unsigned getTargetAddressSpace(QualType T) const;
unsigned getTargetAddressSpace(Qualifiers Q) const {
return getTargetAddressSpace(Q.getAddressSpace());
}
unsigned getTargetAddressSpace(Qualifiers Q) const;
unsigned getTargetAddressSpace(LangAS AS) const;
@@ -21,7 +21,6 @@
namespace clang {
class ASTContext;
class NamedDecl;
class DeclContext;
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_AST_ABSTRACTBASICREADER_H
#define CLANG_AST_ABSTRACTBASICREADER_H
#ifndef LLVM_CLANG_AST_ABSTRACTBASICREADER_H
#define LLVM_CLANG_AST_ABSTRACTBASICREADER_H
#include "clang/AST/DeclTemplate.h"
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_AST_ABSTRACTBASICWRITER_H
#define CLANG_AST_ABSTRACTBASICWRITER_H
#ifndef LLVM_CLANG_AST_ABSTRACTBASICWRITER_H
#define LLVM_CLANG_AST_ABSTRACTBASICWRITER_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_AST_ABSTRACTTYPEREADER_H
#define CLANG_AST_ABSTRACTTYPEREADER_H
#ifndef LLVM_CLANG_AST_ABSTRACTTYPEREADER_H
#define LLVM_CLANG_AST_ABSTRACTTYPEREADER_H
#include "clang/AST/Type.h"
#include "clang/AST/AbstractBasicReader.h"
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_AST_ABSTRACTTYPEWRITER_H
#define CLANG_AST_ABSTRACTTYPEWRITER_H
#ifndef LLVM_CLANG_AST_ABSTRACTTYPEWRITER_H
#define LLVM_CLANG_AST_ABSTRACTTYPEWRITER_H
#include "clang/AST/Type.h"
#include "clang/AST/AbstractBasicWriter.h"
@@ -34,12 +34,7 @@
namespace clang {
class ASTContext;
class AttributeCommonInfo;
class IdentifierInfo;
class ObjCInterfaceDecl;
class Expr;
class QualType;
class FunctionDecl;
class TypeSourceInfo;
class OMPTraitInfo;
/// Attr - This represents one attribute.
@@ -22,7 +22,6 @@
namespace clang {
class ASTContext;
class Attr;
/// AttrVec - A vector of Attr, which is how they are stored on the AST.
@@ -112,6 +112,9 @@ FIELD(HasVariantMembers, 1, NO_MERGE)
/// True if there no non-field members declared by the user.
FIELD(HasOnlyCMembers, 1, NO_MERGE)
/// True if there is an '__init' method defined by the user.
FIELD(HasInitMethod, 1, NO_MERGE)
/// True if any field has an in-class initializer, including those
/// within anonymous unions or structs.
FIELD(HasInClassInitializer, 1, NO_MERGE)
@@ -424,19 +424,13 @@ class HTMLStartTagComment : public HTMLTagComment {
Attribute() { }
Attribute(SourceLocation NameLocBegin, StringRef Name) :
NameLocBegin(NameLocBegin), Name(Name),
EqualsLoc(SourceLocation()),
ValueRange(SourceRange()), Value(StringRef())
{ }
Attribute(SourceLocation NameLocBegin, StringRef Name)
: NameLocBegin(NameLocBegin), Name(Name), EqualsLoc(SourceLocation()) {}
Attribute(SourceLocation NameLocBegin, StringRef Name,
SourceLocation EqualsLoc,
SourceRange ValueRange, StringRef Value) :
NameLocBegin(NameLocBegin), Name(Name),
EqualsLoc(EqualsLoc),
ValueRange(ValueRange), Value(Value)
{ }
SourceLocation EqualsLoc, SourceRange ValueRange, StringRef Value)
: NameLocBegin(NameLocBegin), Name(Name), EqualsLoc(EqualsLoc),
ValueRange(ValueRange), Value(Value) {}
SourceLocation getNameLocEnd() const {
return NameLocBegin.getLocWithOffset(Name.size());
@@ -320,6 +320,9 @@ class Lexer {
/// Eat string matching regexp \code \s*\* \endcode.
void skipLineStartingDecorations();
/// Skip over pure text.
const char *skipTextToken();
/// Lex comment text, including commands if ParseCommands is set to true.
void lexCommentText(Token &T);
@@ -10,8 +10,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H
#define LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H
#ifndef LLVM_CLANG_AST_COMPUTEDEPENDENCE_H
#define LLVM_CLANG_AST_COMPUTEDEPENDENCE_H
#include "clang/AST/DependenceFlags.h"
#include "clang/Basic/ExceptionSpecificationType.h"
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H
#define LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H
#ifndef LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H
#define LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H
#include <cassert>
@@ -71,4 +71,4 @@ class CurrentSourceLocExprScope::SourceLocExprScopeGuard {
} // end namespace clang
#endif // LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H
#endif // LLVM_CLANG_AST_CURRENTSOURCELOCEXPRSCOPE_H
@@ -53,7 +53,6 @@ namespace clang {
class ASTContext;
struct ASTTemplateArgumentListInfo;
class Attr;
class CompoundStmt;
class DependentFunctionTemplateSpecializationInfo;
class EnumDecl;
@@ -74,7 +73,6 @@ class TemplateArgumentList;
class TemplateArgumentListInfo;
class TemplateParameterList;
class TypeAliasTemplateDecl;
class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;
@@ -52,14 +52,8 @@ enum Linkage : unsigned char;
class LinkageSpecDecl;
class Module;
class NamedDecl;
class ObjCCategoryDecl;
class ObjCCategoryImplDecl;
class ObjCContainerDecl;
class ObjCImplDecl;
class ObjCImplementationDecl;
class ObjCInterfaceDecl;
class ObjCMethodDecl;
class ObjCProtocolDecl;
struct PrintingPolicy;
class RecordDecl;
class SourceManager;
@@ -613,6 +607,20 @@ class alignas(8) Decl {
return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate;
}
/// Whether this declaration was exported in a lexical context.
/// e.g.:
///
/// export namespace A {
/// void f1(); // isInExportDeclContext() == true
/// }
/// void A::f1(); // isInExportDeclContext() == false
///
/// namespace B {
/// void f2(); // isInExportDeclContext() == false
/// }
/// export void B::f2(); // isInExportDeclContext() == true
bool isInExportDeclContext() const;
/// Return true if this declaration has an attribute which acts as
/// definition of the entity, such as 'alias' or 'ifunc'.
bool hasDefiningAttr() const;
@@ -64,7 +64,6 @@ class CXXFinalOverriderMap;
class CXXIndirectPrimaryBaseSet;
class CXXMethodDecl;
class DecompositionDecl;
class DiagnosticBuilder;
class FriendDecl;
class FunctionTemplateDecl;
class IdentifierInfo;
@@ -1140,6 +1139,9 @@ class CXXRecordDecl : public RecordDecl {
/// \note This does NOT include a check for union-ness.
bool isEmpty() const { return data().Empty; }
void setInitMethod(bool Val) { data().HasInitMethod = Val; }
bool hasInitMethod() const { return data().HasInitMethod; }
bool hasPrivateFields() const {
return data().HasPrivateFields;
}
@@ -3291,7 +3293,7 @@ class BaseUsingDecl : public NamedDecl {
protected:
BaseUsingDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
: NamedDecl(DK, DC, L, N), FirstUsingShadow(nullptr, 0) {}
: NamedDecl(DK, DC, L, N), FirstUsingShadow(nullptr, false) {}
private:
void anchor() override;
@@ -90,7 +90,7 @@ class StoredDeclsList {
StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
RHS.Data.setPointer(nullptr);
RHS.Data.setInt(0);
RHS.Data.setInt(false);
}
void MaybeDeallocList() {
@@ -114,7 +114,7 @@ class StoredDeclsList {
Data = RHS.Data;
RHS.Data.setPointer(nullptr);
RHS.Data.setInt(0);
RHS.Data.setInt(false);
return *this;
}
@@ -142,7 +142,7 @@ class StoredDeclsList {
}
void setHasExternalDecls() {
Data.setInt(1);
Data.setInt(true);
}
void remove(NamedDecl *D) {
@@ -155,7 +155,7 @@ class StoredDeclsList {
erase_if([](NamedDecl *ND) { return ND->isFromASTFile(); });
// Don't have any pending external decls any more.
Data.setInt(0);
Data.setInt(false);
}
void replaceExternalDecls(ArrayRef<NamedDecl*> Decls) {
@@ -171,7 +171,7 @@ class StoredDeclsList {
});
// Don't have any pending external decls any more.
Data.setInt(0);
Data.setInt(false);
if (Decls.empty())
return;
@@ -779,17 +779,13 @@ class ObjCPropertyDecl : public NamedDecl {
LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
PropertyAttributes(ObjCPropertyAttribute::kind_noattr),
PropertyAttributesAsWritten(ObjCPropertyAttribute::kind_noattr),
PropertyImplementation(propControl), GetterName(Selector()),
SetterName(Selector()) {}
PropertyImplementation(propControl) {}
public:
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
IdentifierInfo *Id, SourceLocation AtLocation,
SourceLocation LParenLocation,
QualType T,
TypeSourceInfo *TSI,
PropertyControl propControl = None);
static ObjCPropertyDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
SourceLocation AtLocation, SourceLocation LParenLocation, QualType T,
TypeSourceInfo *TSI, PropertyControl propControl = None);
static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -1075,6 +1071,9 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
ObjCPropertyDecl *getProperty(const IdentifierInfo *Id,
bool IsInstance) const;
ObjCPropertyDecl *
FindPropertyDeclaration(const IdentifierInfo *PropertyId,
ObjCPropertyQueryKind QueryKind) const;
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_DECLOBJC_COMMON_H
#define LLVM_CLANG_AST_DECLOBJC_COMMON_H
#ifndef LLVM_CLANG_AST_DECLOBJCCOMMON_H
#define LLVM_CLANG_AST_DECLOBJCCOMMON_H
namespace clang {
@@ -52,4 +52,4 @@ enum {
} // namespace clang
#endif // LLVM_CLANG_AST_DECLOBJC_COMMON_H
#endif // LLVM_CLANG_AST_DECLOBJCCOMMON_H
@@ -498,7 +498,7 @@ class FunctionTemplateSpecializationInfo final
TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
SourceLocation POI, MemberSpecializationInfo *MSInfo)
: Function(FD, MSInfo ? 1 : 0), Template(Template, TSK - 1),
: Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
TemplateArguments(TemplateArgs),
TemplateArgumentsAsWritten(TemplateArgsAsWritten),
PointOfInstantiation(POI) {
@@ -34,11 +34,9 @@ class ASTContext;
template <typename> class CanQual;
class DeclarationName;
class DeclarationNameTable;
class MultiKeywordSelector;
struct PrintingPolicy;
class TemplateDecl;
class TypeSourceInfo;
class UsingDirectiveDecl;
using CanQualType = CanQual<Type>;
@@ -2387,7 +2387,7 @@ class OffsetOfNode {
/// Create an offsetof node that refers into a C++ base class.
explicit OffsetOfNode(const CXXBaseSpecifier *Base)
: Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
: Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
/// Determine what kind of offsetof node this is.
Kind getKind() const { return static_cast<Kind>(Data & Mask); }
@@ -275,12 +275,12 @@ class ExprRequirement : public Requirement {
friend ASTStmtWriter;
/// \brief No return type requirement was specified.
ReturnTypeRequirement() : TypeConstraintInfo(nullptr, 0) {}
ReturnTypeRequirement() : TypeConstraintInfo(nullptr, false) {}
/// \brief A return type requirement was specified but it was a
/// substitution failure.
ReturnTypeRequirement(SubstitutionDiagnostic *SubstDiag) :
TypeConstraintInfo(SubstDiag, 0) {}
TypeConstraintInfo(SubstDiag, false) {}
/// \brief A 'type constraint' style return type requirement.
/// \param TPL an invented template parameter list containing a single
@@ -413,12 +413,12 @@ class NestedRequirement : public Requirement {
friend ASTStmtWriter;
NestedRequirement(SubstitutionDiagnostic *SubstDiag) :
Requirement(RK_Nested, /*Dependent=*/false,
Requirement(RK_Nested, /*IsDependent=*/false,
/*ContainsUnexpandedParameterPack*/false,
/*Satisfied=*/false), Value(SubstDiag) {}
/*IsSatisfied=*/false), Value(SubstDiag) {}
NestedRequirement(Expr *Constraint) :
Requirement(RK_Nested, /*Dependent=*/true,
Requirement(RK_Nested, /*IsDependent=*/true,
Constraint->containsUnexpandedParameterPack()),
Value(Constraint) {
assert(Constraint->isInstantiationDependent() &&
@@ -1706,7 +1706,7 @@ class ObjCAvailabilityCheckExpr : public Expr {
/// This may be '*', in which case this should fold to true.
bool hasVersion() const { return !VersionToCheck.empty(); }
VersionTuple getVersion() { return VersionToCheck; }
VersionTuple getVersion() const { return VersionToCheck; }
child_range children() {
return child_range(child_iterator(), child_iterator());
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
#ifndef LLVM_CLANG_AST_FORMATSTRING_H
#define LLVM_CLANG_AST_FORMATSTRING_H
#include "clang/AST/CanonicalType.h"
@@ -332,11 +332,11 @@ class OptionalAmount {
unsigned amountLength,
bool usesPositionalArg)
: start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
UsesPositionalArg(usesPositionalArg), UsesDotPrefix(false) {}
OptionalAmount(bool valid = true)
: start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
UsesPositionalArg(0), UsesDotPrefix(0) {}
UsesPositionalArg(false), UsesDotPrefix(false) {}
explicit OptionalAmount(unsigned Amount)
: start(nullptr), length(0), hs(Constant), amt(Amount),
@@ -726,7 +726,8 @@ class FormatStringHandler {
virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
unsigned specifierLen) {
unsigned specifierLen,
const TargetInfo &Target) {
return true;
}
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
#define LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
#ifndef LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H
#define LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/LLVM.h"
@@ -160,4 +160,4 @@ class LexicallyOrderedRecursiveASTVisitor
} // end namespace clang
#endif // LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
#endif // LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H
@@ -10,8 +10,8 @@
// source-location information.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SEMA_LOCINFOTYPE_H
#define LLVM_CLANG_SEMA_LOCINFOTYPE_H
#ifndef LLVM_CLANG_AST_LOCINFOTYPE_H
#define LLVM_CLANG_AST_LOCINFOTYPE_H
#include "clang/AST/Type.h"
@@ -54,4 +54,4 @@ class LocInfoType : public Type {
} // end namespace clang
#endif // LLVM_CLANG_SEMA_LOCINFOTYPE_H
#endif // LLVM_CLANG_AST_LOCINFOTYPE_H
@@ -21,9 +21,7 @@ namespace clang {
class BlockDecl;
class CXXMethodDecl;
class IdentifierInfo;
class TagDecl;
class Type;
class VarDecl;
/// Keeps track of the mangled names of lambda expressions and block
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
#define LLVM_CLANG_NON_TRIVIAL_TYPE_VISITOR_H
#ifndef LLVM_CLANG_AST_NONTRIVIALTYPEVISITOR_H
#define LLVM_CLANG_AST_NONTRIVIALTYPEVISITOR_H
#include "clang/AST/Type.h"
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
#ifndef LLVM_CLANG_AST_OSLOG_H
#define LLVM_CLANG_AST_OSLOG_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
@@ -32,6 +32,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Frontend/OpenMP/OMPAssume.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/Frontend/OpenMP/OMPContext.h"
#include "llvm/Support/Casting.h"
@@ -22,7 +22,6 @@ namespace clang {
class ASTContext;
class Decl;
class SourceManager;
/// PrettyDeclStackTraceEntry - If a crash occurs in the parser while
/// parsing something related to a declaration, include that
@@ -20,9 +20,7 @@ namespace clang {
class DeclContext;
class LangOptions;
class SourceManager;
class Stmt;
class TagDecl;
class PrinterHelper {
public:
@@ -75,7 +73,8 @@ struct PrintingPolicy {
MSVCFormatting(false), ConstantsAsWritten(false),
SuppressImplicitBase(false), FullyQualifiedName(false),
PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true),
UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false) {}
UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false),
CleanUglifiedParameters(false) {}
/// Adjust this printing policy for cases where it's known that we're
/// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -282,6 +281,11 @@ struct PrintingPolicy {
/// parameters.
unsigned AlwaysIncludeTypeForTemplateArgument : 1;
/// Whether to strip underscores when printing reserved parameter names.
/// e.g. std::vector<class _Tp> becomes std::vector<class Tp>.
/// This only affects parameter names, and so describes a compatible API.
unsigned CleanUglifiedParameters : 1;
/// Callbacks to use to allow the behavior of printing to be customized.
const PrintingCallbacks *Callbacks = nullptr;
};
@@ -89,4 +89,4 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
bool WithGlobalNsPrefix = false);
} // end namespace TypeName
} // end namespace clang
#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
#endif // LLVM_CLANG_AST_QUALTYPENAMES_H
@@ -52,7 +52,6 @@ template <> struct PointerLikeTypeTraits<clang::Expr *> {
namespace clang {
class ASTContext;
class DiagnosticBuilder;
class Expr;
struct PrintingPolicy;
class TypeSourceInfo;
@@ -26,14 +26,12 @@ namespace clang {
class ASTContext;
class DependentTemplateName;
class DiagnosticBuilder;
class IdentifierInfo;
class NamedDecl;
class NestedNameSpecifier;
enum OverloadedOperatorKind : int;
class OverloadedTemplateStorage;
class AssumedTemplateStorage;
class PartialDiagnostic;
struct PrintingPolicy;
class QualifiedTemplateName;
class SubstTemplateTemplateParmPackStorage;
@@ -1994,12 +1994,35 @@ class TypeOfTypeLoc
void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
// FIXME: location of the 'decltype' and parens.
class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DecltypeTypeLoc,
DecltypeType> {
// decltype(expression) abc;
// ~~~~~~~~ DecltypeLoc
// ~ RParenLoc
// FIXME: add LParenLoc, it is tricky to support due to the limitation of
// annotated-decltype token.
struct DecltypeTypeLocInfo {
SourceLocation DecltypeLoc;
SourceLocation RParenLoc;
};
class DecltypeTypeLoc
: public ConcreteTypeLoc<UnqualTypeLoc, DecltypeTypeLoc, DecltypeType,
DecltypeTypeLocInfo> {
public:
Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
SourceLocation getDecltypeLoc() const { return getLocalData()->DecltypeLoc; }
void setDecltypeLoc(SourceLocation Loc) { getLocalData()->DecltypeLoc = Loc; }
SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
SourceRange getLocalSourceRange() const {
return SourceRange(getDecltypeLoc(), getRParenLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setDecltypeLoc(Loc);
setRParenLoc(Loc);
}
};
struct UnaryTransformTypeLocInfo {
@@ -2058,6 +2081,11 @@ struct AutoTypeLocInfo : TypeSpecLocInfo {
NamedDecl *FoundDecl;
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
// For decltype(auto).
SourceLocation RParenLoc;
// Followed by a TemplateArgumentLocInfo[]
};
class AutoTypeLoc
@@ -2070,6 +2098,10 @@ class AutoTypeLoc
return getTypePtr()->getKeyword();
}
bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); }
SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
bool isConstrained() const {
return getTypePtr()->isConstrained();
}
@@ -2150,16 +2182,13 @@ class AutoTypeLoc
}
SourceRange getLocalSourceRange() const {
return{
isConstrained()
? (getNestedNameSpecifierLoc()
? getNestedNameSpecifierLoc().getBeginLoc()
: (getTemplateKWLoc().isValid()
? getTemplateKWLoc()
: getConceptNameLoc()))
: getNameLoc(),
getNameLoc()
};
return {isConstrained()
? (getNestedNameSpecifierLoc()
? getNestedNameSpecifierLoc().getBeginLoc()
: (getTemplateKWLoc().isValid() ? getTemplateKWLoc()
: getConceptNameLoc()))
: getNameLoc(),
isDecltypeAuto() ? getRParenLoc() : getNameLoc()};
}
void copy(AutoTypeLoc Loc) {
@@ -121,7 +121,7 @@ class UnresolvedSetImpl {
void setAccess(iterator I, AccessSpecifier AS) { I.I->setAccess(AS); }
void clear() { decls().clear(); }
void set_size(unsigned N) { decls().set_size(N); }
void truncate(unsigned N) { decls().truncate(N); }
bool empty() const { return decls().empty(); }
unsigned size() const { return decls().size(); }
@@ -3725,10 +3725,9 @@ AST_MATCHER_P(ObjCMessageExpr, hasReceiver, internal::Matcher<Expr>,
/// \endcode
AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName) {
Selector Sel = Node.getSelector();
return BaseName.compare(Sel.getAsString()) == 0;
return BaseName == Sel.getAsString();
}
/// Matches when at least one of the supplied string equals to the
/// Selector.getAsString()
///
@@ -5171,6 +5170,25 @@ AST_POLYMORPHIC_MATCHER(isNoThrow,
return FnTy->isNothrow();
}
/// Matches consteval function declarations and if consteval/if ! consteval
/// statements.
///
/// Given:
/// \code
/// consteval int a();
/// void b() { if consteval {} }
/// void c() { if ! consteval {} }
/// void d() { if ! consteval {} else {} }
/// \endcode
/// functionDecl(isConsteval())
/// matches the declaration of "int a()".
/// ifStmt(isConsteval())
/// matches the if statement in "void b()", "void c()", "void d()".
AST_POLYMORPHIC_MATCHER(isConsteval,
AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, IfStmt)) {
return Node.isConsteval();
}
/// Matches constexpr variable and function declarations,
/// and if constexpr.
///
@@ -5193,6 +5211,23 @@ AST_POLYMORPHIC_MATCHER(isConstexpr,
return Node.isConstexpr();
}
/// Matches constinit variable declarations.
///
/// Given:
/// \code
/// constinit int foo = 42;
/// constinit const char* bar = "bar";
/// int baz = 42;
/// [[clang::require_constant_initialization]] int xyz = 42;
/// \endcode
/// varDecl(isConstinit())
/// matches the declaration of `foo` and `bar`, but not `baz` and `xyz`.
AST_MATCHER(VarDecl, isConstinit) {
if (const auto *CIA = Node.getAttr<ConstInitAttr>())
return CIA->isConstinit();
return false;
}
/// Matches selection statements with initializer.
///
/// Given:
@@ -40,7 +40,7 @@ struct SourceRange {
/// A VariantValue instance annotated with its parser context.
struct ParserValue {
ParserValue() : Text(), Range(), Value() {}
ParserValue() {}
StringRef Text;
SourceRange Range;
VariantValue Value;
@@ -186,4 +186,4 @@ class Diagnostics {
} // namespace ast_matchers
} // namespace clang
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
#endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
@@ -280,4 +280,4 @@ class Parser {
} // namespace ast_matchers
} // namespace clang
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
#endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
@@ -157,4 +157,4 @@ class Registry {
} // namespace ast_matchers
} // namespace clang
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
#endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
@@ -356,4 +356,4 @@ class VariantValue {
} // end namespace ast_matchers
} // end namespace clang
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
#endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
@@ -20,7 +20,6 @@ class AnalysisDeclContext;
class BlockDecl;
class CFG;
class Decl;
class DeclContext;
class Expr;
class ParmVarDecl;
class Stmt;
@@ -153,8 +153,7 @@ namespace consumed {
public:
ConsumedStateMap() = default;
ConsumedStateMap(const ConsumedStateMap &Other)
: Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap),
TmpMap() {}
: Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap) {}
/// Warn if any of the parameters being tracked are not in the state
/// they were declared to be in upon return from a function.
@@ -517,4 +517,4 @@ void printSCFG(CFGWalker &Walker);
} // namespace threadSafety
} // namespace clang
#endif // LLVM_CLANG_THREAD_SAFETY_COMMON_H
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
@@ -354,4 +354,4 @@ inline std::ostream& operator<<(std::ostream& ss, const StringRef str) {
} // namespace threadSafety
} // namespace clang
#endif // LLVM_CLANG_THREAD_SAFETY_UTIL_H
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYUTIL_H
@@ -10,8 +10,8 @@
//
//===----------------------------------------------------------------------===//
//
#ifndef LLVM_CLANG_ANALYSIS_ANY_CALL_H
#define LLVM_CLANG_ANALYSIS_ANY_CALL_H
#ifndef LLVM_CLANG_ANALYSIS_ANYCALL_H
#define LLVM_CLANG_ANALYSIS_ANYCALL_H
#include "clang/AST/Decl.h"
#include "clang/AST/ExprCXX.h"
@@ -215,4 +215,4 @@ class AnyCall {
}
#endif // LLVM_CLANG_ANALYSIS_ANY_CALL_H
#endif // LLVM_CLANG_ANALYSIS_ANYCALL_H
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H
#define LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H
#ifndef LLVM_CLANG_ANALYSIS_BODYFARM_H
#define LLVM_CLANG_ANALYSIS_BODYFARM_H
#include "clang/AST/DeclBase.h"
#include "clang/Basic/LLVM.h"
@@ -24,7 +24,6 @@ namespace clang {
class ASTContext;
class FunctionDecl;
class ObjCMethodDecl;
class ObjCPropertyDecl;
class Stmt;
class CodeInjector;
@@ -707,7 +707,7 @@ class CFGBlock {
template <bool IsOtherConst>
ElementRefIterator(ElementRefIterator<true, IsOtherConst> E)
: ElementRefIterator(E.Parent, llvm::make_reverse_iterator(E.Pos)) {}
: ElementRefIterator(E.Parent, std::make_reverse_iterator(E.Pos)) {}
bool operator<(ElementRefIterator Other) const {
assert(Parent == Other.Parent);
@@ -11,8 +11,8 @@
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_CLONEDETECTION_H
#define LLVM_CLANG_AST_CLONEDETECTION_H
#ifndef LLVM_CLANG_ANALYSIS_CLONEDETECTION_H
#define LLVM_CLANG_ANALYSIS_CLONEDETECTION_H
#include "clang/AST/StmtVisitor.h"
#include "llvm/Support/Regex.h"
@@ -441,4 +441,4 @@ struct MatchingVariablePatternConstraint {
} // end namespace clang
#endif // LLVM_CLANG_AST_CLONEDETECTION_H
#endif // LLVM_CLANG_ANALYSIS_CLONEDETECTION_H
@@ -0,0 +1,57 @@
//===-- ControlFlowContext.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 a ControlFlowContext class that is used by dataflow
// analyses that run over Control-Flow Graphs (CFGs).
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Stmt.h"
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Error.h"
#include <memory>
#include <utility>
namespace clang {
namespace dataflow {
/// Holds CFG and other derived context that is needed to perform dataflow
/// analysis.
class ControlFlowContext {
public:
/// Builds a ControlFlowContext from an AST node.
static llvm::Expected<ControlFlowContext> build(const Decl *D, Stmt *S,
ASTContext *C);
/// Returns the CFG that is stored in this context.
const CFG &getCFG() const { return *Cfg; }
/// Returns a mapping from statements to basic blocks that contain them.
const llvm::DenseMap<const Stmt *, const CFGBlock *> &getStmtToBlock() const {
return StmtToBlock;
}
private:
ControlFlowContext(std::unique_ptr<CFG> Cfg,
llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock)
: Cfg(std::move(Cfg)), StmtToBlock(std::move(StmtToBlock)) {}
std::unique_ptr<CFG> Cfg;
llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
};
} // namespace dataflow
} // namespace clang
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H
@@ -21,6 +21,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Stmt.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
#include "llvm/ADT/Any.h"
@@ -38,9 +39,13 @@ namespace dataflow {
/// must provide the following public members:
/// * `LatticeT initialElement()` - returns a lattice element that models the
/// initial state of a basic block;
/// * `LatticeT transfer(const Stmt *, const LatticeT &, Environment &)` -
/// applies the analysis transfer function for a given statement and lattice
/// element.
/// * `void transfer(const Stmt *, LatticeT &, Environment &)` - applies the
/// analysis transfer function for a given statement and lattice element.
///
/// `Derived` can optionally override the following members:
/// * `bool merge(QualType, const Value &, const Value &, Value &,
/// Environment &)` - joins distinct values. This could be a strict
/// lattice join or a more general widening operation.
///
/// `LatticeT` is a bounded join-semilattice that is used by `Derived` and must
/// provide the following public members:
@@ -57,6 +62,8 @@ class DataflowAnalysis : public TypeErasedDataflowAnalysis {
using Lattice = LatticeT;
explicit DataflowAnalysis(ASTContext &Context) : Context(Context) {}
explicit DataflowAnalysis(ASTContext &Context, bool ApplyBuiltinTransfer)
: TypeErasedDataflowAnalysis(ApplyBuiltinTransfer), Context(Context) {}
ASTContext &getASTContext() final { return Context; }
@@ -78,11 +85,10 @@ class DataflowAnalysis : public TypeErasedDataflowAnalysis {
return L1 == L2;
}
TypeErasedLattice transferTypeErased(const Stmt *Stmt,
const TypeErasedLattice &E,
Environment &Env) final {
const Lattice &L = llvm::any_cast<const Lattice &>(E.Value);
return {static_cast<Derived *>(this)->transfer(Stmt, L, Env)};
void transferTypeErased(const Stmt *Stmt, TypeErasedLattice &E,
Environment &Env) final {
Lattice &L = llvm::any_cast<Lattice &>(E.Value);
static_cast<Derived *>(this)->transfer(Stmt, L, Env);
}
private:
@@ -101,17 +107,12 @@ template <typename LatticeT> struct DataflowAnalysisState {
/// Performs dataflow analysis and returns a mapping from basic block IDs to
/// dataflow analysis states that model the respective basic blocks. Indices
/// of the returned vector correspond to basic block IDs.
///
/// Requirements:
///
/// `Cfg` must have been built with `CFG::BuildOptions::setAllAlwaysAdd()` to
/// ensure that all sub-expressions in a basic block are evaluated.
template <typename AnalysisT>
std::vector<llvm::Optional<DataflowAnalysisState<typename AnalysisT::Lattice>>>
runDataflowAnalysis(const CFG &Cfg, AnalysisT &Analysis,
runDataflowAnalysis(const ControlFlowContext &CFCtx, AnalysisT &Analysis,
const Environment &InitEnv) {
auto TypeErasedBlockStates =
runTypeErasedDataflowAnalysis(Cfg, Analysis, InitEnv);
runTypeErasedDataflowAnalysis(CFCtx, Analysis, InitEnv);
std::vector<
llvm::Optional<DataflowAnalysisState<typename AnalysisT::Lattice>>>
BlockStates;
@@ -0,0 +1,145 @@
//===-- DataflowAnalysisContext.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 a DataflowAnalysisContext class that owns objects that
// encompass the state of a program and stores context that is used during
// dataflow analysis.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSISCONTEXT_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSISCONTEXT_H
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/DenseMap.h"
#include <cassert>
#include <memory>
#include <type_traits>
#include <utility>
#include <vector>
namespace clang {
namespace dataflow {
/// Owns objects that encompass the state of a program and stores context that
/// is used during dataflow analysis.
class DataflowAnalysisContext {
public:
DataflowAnalysisContext()
: TrueVal(&takeOwnership(std::make_unique<BoolValue>())),
FalseVal(&takeOwnership(std::make_unique<BoolValue>())) {}
/// Takes ownership of `Loc` and returns a reference to it.
///
/// Requirements:
///
/// `Loc` must not be null.
template <typename T>
typename std::enable_if<std::is_base_of<StorageLocation, T>::value, T &>::type
takeOwnership(std::unique_ptr<T> Loc) {
assert(Loc != nullptr);
Locs.push_back(std::move(Loc));
return *cast<T>(Locs.back().get());
}
/// Takes ownership of `Val` and returns a reference to it.
///
/// Requirements:
///
/// `Val` must not be null.
template <typename T>
typename std::enable_if<std::is_base_of<Value, T>::value, T &>::type
takeOwnership(std::unique_ptr<T> Val) {
assert(Val != nullptr);
Vals.push_back(std::move(Val));
return *cast<T>(Vals.back().get());
}
/// Assigns `Loc` as the storage location of `D`.
///
/// Requirements:
///
/// `D` must not be assigned a storage location.
void setStorageLocation(const ValueDecl &D, StorageLocation &Loc) {
assert(DeclToLoc.find(&D) == DeclToLoc.end());
DeclToLoc[&D] = &Loc;
}
/// Returns the storage location assigned to `D` or null if `D` has no
/// assigned storage location.
StorageLocation *getStorageLocation(const ValueDecl &D) const {
auto It = DeclToLoc.find(&D);
return It == DeclToLoc.end() ? nullptr : It->second;
}
/// Assigns `Loc` as the storage location of `E`.
///
/// Requirements:
///
/// `E` must not be assigned a storage location.
void setStorageLocation(const Expr &E, StorageLocation &Loc) {
assert(ExprToLoc.find(&E) == ExprToLoc.end());
ExprToLoc[&E] = &Loc;
}
/// Returns the storage location assigned to `E` or null if `E` has no
/// assigned storage location.
StorageLocation *getStorageLocation(const Expr &E) const {
auto It = ExprToLoc.find(&E);
return It == ExprToLoc.end() ? nullptr : It->second;
}
/// Assigns `Loc` as the storage location of the `this` pointee.
///
/// Requirements:
///
/// The `this` pointee must not be assigned a storage location.
void setThisPointeeStorageLocation(StorageLocation &Loc) {
assert(ThisPointeeLoc == nullptr);
ThisPointeeLoc = &Loc;
}
/// Returns the storage location assigned to the `this` pointee or null if the
/// `this` pointee has no assigned storage location.
StorageLocation *getThisPointeeStorageLocation() const {
return ThisPointeeLoc;
}
/// Returns a symbolic boolean value that models a boolean literal equal to
/// `Value`.
BoolValue &getBoolLiteralValue(bool Value) const {
return Value ? *TrueVal : *FalseVal;
}
private:
// Storage for the state of a program.
std::vector<std::unique_ptr<StorageLocation>> Locs;
std::vector<std::unique_ptr<Value>> Vals;
// Maps from program declarations and statements to storage locations that are
// assigned to them. These assignments are global (aggregated across all basic
// blocks) and are used to produce stable storage locations when the same
// basic blocks are evaluated multiple times. The storage locations that are
// in scope for a particular basic block are stored in `Environment`.
llvm::DenseMap<const ValueDecl *, StorageLocation *> DeclToLoc;
llvm::DenseMap<const Expr *, StorageLocation *> ExprToLoc;
StorageLocation *ThisPointeeLoc = nullptr;
// FIXME: Add support for boolean expressions.
BoolValue *TrueVal;
BoolValue *FalseVal;
};
} // namespace dataflow
} // namespace clang
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSISCONTEXT_H
@@ -15,19 +15,215 @@
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include <memory>
#include <type_traits>
#include <utility>
namespace clang {
namespace dataflow {
/// Indicates what kind of indirections should be skipped past when retrieving
/// storage locations or values.
///
/// FIXME: Consider renaming this or replacing it with a more appropriate model.
/// See the discussion in https://reviews.llvm.org/D116596 for context.
enum class SkipPast {
/// No indirections should be skipped past.
None,
/// An optional reference should be skipped past.
Reference,
/// An optional reference should be skipped past, then an optional pointer
/// should be skipped past.
ReferenceThenPointer,
};
/// Holds the state of the program (store and heap) at a given program point.
class Environment {
public:
bool operator==(const Environment &) const { return true; }
/// Supplements `Environment` with non-standard join operations.
class Merger {
public:
virtual ~Merger() = default;
LatticeJoinEffect join(const Environment &) {
return LatticeJoinEffect::Unchanged;
/// Given distinct `Val1` and `Val2`, modifies `MergedVal` to approximate
/// both `Val1` and `Val2`. This could be a strict lattice join or a more
/// general widening operation. If this function returns true, `MergedVal`
/// will be assigned to a storage location of type `Type` in `Env`.
///
/// Requirements:
///
/// `Val1` and `Val2` must be distinct.
virtual bool merge(QualType Type, const Value &Val1, const Value &Val2,
Value &MergedVal, Environment &Env) {
return false;
}
};
/// Creates an environment that uses `DACtx` to store objects that encompass
/// the state of a program.
explicit Environment(DataflowAnalysisContext &DACtx) : DACtx(&DACtx) {}
/// Creates an environment that uses `DACtx` to store objects that encompass
/// the state of a program.
///
/// If `DeclCtx` is a function, initializes the environment with symbolic
/// representations of the function parameters.
///
/// If `DeclCtx` is a non-static member function, initializes the environment
/// with a symbolic representation of the `this` pointee.
Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx);
bool operator==(const Environment &) const;
LatticeJoinEffect join(const Environment &, Environment::Merger &);
// FIXME: Rename `createOrGetStorageLocation` to `getOrCreateStorageLocation`,
// `getStableStorageLocation`, or something more appropriate.
/// Creates a storage location appropriate for `Type`. Does not assign a value
/// to the returned storage location in the environment.
///
/// Requirements:
///
/// `Type` must not be null.
StorageLocation &createStorageLocation(QualType Type);
/// Creates a storage location for `D`. Does not assign the returned storage
/// location to `D` in the environment. Does not assign a value to the
/// returned storage location in the environment.
StorageLocation &createStorageLocation(const VarDecl &D);
/// Creates a storage location for `E`. Does not assign the returned storage
/// location to `E` in the environment. Does not assign a value to the
/// returned storage location in the environment.
StorageLocation &createStorageLocation(const Expr &E);
/// Assigns `Loc` as the storage location of `D` in the environment.
///
/// Requirements:
///
/// `D` must not be assigned a storage location in the environment.
void setStorageLocation(const ValueDecl &D, StorageLocation &Loc);
/// Returns the storage location assigned to `D` in the environment, applying
/// the `SP` policy for skipping past indirections, or null if `D` isn't
/// assigned a storage location in the environment.
StorageLocation *getStorageLocation(const ValueDecl &D, SkipPast SP) const;
/// Assigns `Loc` as the storage location of `E` in the environment.
///
/// Requirements:
///
/// `E` must not be assigned a storage location in the environment.
void setStorageLocation(const Expr &E, StorageLocation &Loc);
/// Returns the storage location assigned to `E` in the environment, applying
/// the `SP` policy for skipping past indirections, or null if `E` isn't
/// assigned a storage location in the environment.
StorageLocation *getStorageLocation(const Expr &E, SkipPast SP) const;
/// Returns the storage location assigned to the `this` pointee in the
/// environment or null if the `this` pointee has no assigned storage location
/// in the environment.
StorageLocation *getThisPointeeStorageLocation() const;
/// Creates a value appropriate for `Type`, if `Type` is supported, otherwise
/// return null. If `Type` is a pointer or reference type, creates all the
/// necessary storage locations and values for indirections until it finds a
/// non-pointer/non-reference type.
///
/// Requirements:
///
/// `Type` must not be null.
Value *createValue(QualType Type);
/// Assigns `Val` as the value of `Loc` in the environment.
void setValue(const StorageLocation &Loc, Value &Val);
/// Returns the value assigned to `Loc` in the environment or null if `Loc`
/// isn't assigned a value in the environment.
Value *getValue(const StorageLocation &Loc) const;
/// Equivalent to `getValue(getStorageLocation(D, SP), SkipPast::None)` if `D`
/// is assigned a storage location in the environment, otherwise returns null.
Value *getValue(const ValueDecl &D, SkipPast SP) const;
/// Equivalent to `getValue(getStorageLocation(E, SP), SkipPast::None)` if `E`
/// is assigned a storage location in the environment, otherwise returns null.
Value *getValue(const Expr &E, SkipPast SP) const;
/// Transfers ownership of `Loc` to the analysis context and returns a
/// reference to it.
///
/// Requirements:
///
/// `Loc` must not be null.
template <typename T>
typename std::enable_if<std::is_base_of<StorageLocation, T>::value, T &>::type
takeOwnership(std::unique_ptr<T> Loc) {
return DACtx->takeOwnership(std::move(Loc));
}
/// Transfers ownership of `Val` to the analysis context and returns a
/// reference to it.
///
/// Requirements:
///
/// `Val` must not be null.
template <typename T>
typename std::enable_if<std::is_base_of<Value, T>::value, T &>::type
takeOwnership(std::unique_ptr<T> Val) {
return DACtx->takeOwnership(std::move(Val));
}
/// Returns a symbolic boolean value that models a boolean literal equal to
/// `Value`
BoolValue &getBoolLiteralValue(bool Value) const {
return DACtx->getBoolLiteralValue(Value);
}
private:
/// Creates a value appropriate for `Type`, if `Type` is supported, otherwise
/// return null.
///
/// Recursively initializes storage locations and values until it sees a
/// self-referential pointer or reference type. `Visited` is used to track
/// which types appeared in the reference/pointer chain in order to avoid
/// creating a cyclic dependency with self-referential pointers/references.
///
/// Requirements:
///
/// `Type` must not be null.
Value *createValueUnlessSelfReferential(QualType Type,
llvm::DenseSet<QualType> &Visited);
StorageLocation &skip(StorageLocation &Loc, SkipPast SP) const;
const StorageLocation &skip(const StorageLocation &Loc, SkipPast SP) const;
// `DACtx` is not null and not owned by this object.
DataflowAnalysisContext *DACtx;
// Maps from program declarations and statements to storage locations that are
// assigned to them. Unlike the maps in `DataflowAnalysisContext`, these
// include only storage locations that are in scope for a particular basic
// block.
llvm::DenseMap<const ValueDecl *, StorageLocation *> DeclToLoc;
llvm::DenseMap<const Expr *, StorageLocation *> ExprToLoc;
llvm::DenseMap<const StorageLocation *, Value *> LocToVal;
// FIXME: Add flow condition constraints.
};
} // namespace dataflow
@@ -92,4 +92,4 @@ struct BackwardDataflowWorklist
} // namespace clang
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWWORKLIST_H
@@ -0,0 +1,140 @@
//===------------------------ MapLattice.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 a parameterized lattice that maps keys to individual
// lattice elements (of the parameter lattice type). A typical usage is lifting
// a particular lattice to all variables in a lexical scope.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE__MAPLATTICE_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE__MAPLATTICE_H
#include <ostream>
#include <string>
#include <utility>
#include "DataflowAnalysis.h"
#include "clang/AST/Decl.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
namespace clang {
namespace dataflow {
/// A lattice that maps keys to individual lattice elements. When instantiated
/// with an `ElementLattice` that is a bounded semi-lattice, `MapLattice` is
/// itself a bounded semi-lattice, so long as the user limits themselves to a
/// finite number of keys. In that case, `top` is (implicitly), the map
/// containing all valid keys mapped to `top` of `ElementLattice`.
///
/// Requirements on `ElementLattice`:
/// * Provides standard declarations of a bounded semi-lattice.
template <typename Key, typename ElementLattice> class MapLattice {
using Container = llvm::DenseMap<Key, ElementLattice>;
Container C;
public:
using key_type = Key;
using mapped_type = ElementLattice;
using value_type = typename Container::value_type;
using iterator = typename Container::iterator;
using const_iterator = typename Container::const_iterator;
MapLattice() = default;
explicit MapLattice(Container C) { C = std::move(C); }
// The `bottom` element is the empty map.
static MapLattice bottom() { return MapLattice(); }
void insert(const std::pair<const key_type, mapped_type> &P) { C.insert(P); }
void insert(std::pair<const key_type, mapped_type> &&P) {
C.insert(std::move(P));
}
unsigned size() const { return C.size(); }
bool empty() const { return C.empty(); }
iterator begin() { return C.begin(); }
iterator end() { return C.end(); }
const_iterator begin() const { return C.begin(); }
const_iterator end() const { return C.end(); }
// Equality is direct equality of underlying map entries. One implication of
// this definition is that a map with (only) keys that map to bottom is not
// equal to the empty map.
friend bool operator==(const MapLattice &LHS, const MapLattice &RHS) {
return LHS.C == RHS.C;
}
friend bool operator!=(const MapLattice &LHS, const MapLattice &RHS) {
return !(LHS == RHS);
}
bool contains(const key_type &K) const { return C.find(K) != C.end(); }
iterator find(const key_type &K) { return C.find(K); }
const_iterator find(const key_type &K) const { return C.find(K); }
mapped_type &operator[](const key_type &K) { return C[K]; }
/// If an entry exists in one map but not the other, the missing entry is
/// treated as implicitly mapping to `bottom`. So, the joined map contains the
/// entry as it was in the source map.
LatticeJoinEffect join(const MapLattice &Other) {
LatticeJoinEffect Effect = LatticeJoinEffect::Unchanged;
for (const auto &O : Other.C) {
auto It = C.find(O.first);
if (It == C.end()) {
C.insert(O);
Effect = LatticeJoinEffect::Changed;
} else if (It->second.join(O.second) == LatticeJoinEffect::Changed)
Effect = LatticeJoinEffect::Changed;
}
return Effect;
}
};
/// Convenience alias that captures the common use of map lattices to model
/// in-scope variables.
template <typename ElementLattice>
using VarMapLattice = MapLattice<const clang::VarDecl *, ElementLattice>;
template <typename Key, typename ElementLattice>
std::ostream &
operator<<(std::ostream &Os,
const clang::dataflow::MapLattice<Key, ElementLattice> &M) {
std::string Separator = "";
Os << "{";
for (const auto &E : M) {
Os << std::exchange(Separator, ", ") << E.first << " => " << E.second;
}
Os << "}";
return Os;
}
template <typename ElementLattice>
std::ostream &
operator<<(std::ostream &Os,
const clang::dataflow::VarMapLattice<ElementLattice> &M) {
std::string Separator = "";
Os << "{";
for (const auto &E : M) {
Os << std::exchange(Separator, ", ") << E.first->getName().str() << " => "
<< E.second;
}
Os << "}";
return Os;
}
} // namespace dataflow
} // namespace clang
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE__MAPLATTICE_H
@@ -0,0 +1,89 @@
//===-- StorageLocation.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 classes that represent elements of the local variable store
// and of the heap during dataflow analysis.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H
#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/DenseMap.h"
namespace clang {
namespace dataflow {
/// Base class for elements of the local variable store and of the heap.
///
/// Each storage location holds a value. The mapping from storage locations to
/// values is stored in the environment.
class StorageLocation {
public:
enum class Kind { Scalar, Aggregate };
StorageLocation(Kind LocKind, QualType Type) : LocKind(LocKind), Type(Type) {}
virtual ~StorageLocation() = default;
Kind getKind() const { return LocKind; }
QualType getType() const { return Type; }
private:
Kind LocKind;
QualType Type;
};
/// A storage location that is not subdivided further for the purposes of
/// abstract interpretation. For example: `int`, `int*`, `int&`.
class ScalarStorageLocation final : public StorageLocation {
public:
explicit ScalarStorageLocation(QualType Type)
: StorageLocation(Kind::Scalar, Type) {}
static bool classof(const StorageLocation *Loc) {
return Loc->getKind() == Kind::Scalar;
}
};
/// A storage location which is subdivided into smaller storage locations that
/// can be traced independently by abstract interpretation. For example: a
/// struct with public members.
class AggregateStorageLocation final : public StorageLocation {
public:
explicit AggregateStorageLocation(QualType Type)
: AggregateStorageLocation(
Type, llvm::DenseMap<const ValueDecl *, StorageLocation *>()) {}
AggregateStorageLocation(
QualType Type,
llvm::DenseMap<const ValueDecl *, StorageLocation *> Children)
: StorageLocation(Kind::Aggregate, Type), Children(std::move(Children)) {}
static bool classof(const StorageLocation *Loc) {
return Loc->getKind() == Kind::Aggregate;
}
/// Returns the child storage location for `D`.
StorageLocation &getChild(const ValueDecl &D) const {
auto It = Children.find(&D);
assert(It != Children.end());
return *It->second;
}
private:
llvm::DenseMap<const ValueDecl *, StorageLocation *> Children;
};
} // namespace dataflow
} // namespace clang
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H
@@ -0,0 +1,33 @@
//===-- Transfer.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 a transfer function that evaluates a program statement and
// updates an environment accordingly.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TRANSFER_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TRANSFER_H
#include "clang/AST/Stmt.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
namespace clang {
namespace dataflow {
/// Evaluates `S` and updates `Env` accordingly.
///
/// Requirements:
///
/// The type of `S` must not be `ParenExpr`.
void transfer(const Stmt &S, Environment &Env);
} // namespace dataflow
} // namespace clang
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TRANSFER_H
@@ -14,11 +14,13 @@
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H
#include <utility>
#include <vector>
#include "clang/AST/ASTContext.h"
#include "clang/AST/Stmt.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "llvm/ADT/Any.h"
@@ -38,8 +40,18 @@ struct TypeErasedLattice {
};
/// Type-erased base class for dataflow analyses built on a single lattice type.
class TypeErasedDataflowAnalysis {
class TypeErasedDataflowAnalysis : public Environment::Merger {
/// Determines whether to apply the built-in transfer functions.
// FIXME: Remove this option once the framework supports composing analyses
// (at which point the built-in transfer functions can be simply a standalone
// analysis).
bool ApplyBuiltinTransfer;
public:
TypeErasedDataflowAnalysis() : ApplyBuiltinTransfer(true) {}
TypeErasedDataflowAnalysis(bool ApplyBuiltinTransfer)
: ApplyBuiltinTransfer(ApplyBuiltinTransfer) {}
virtual ~TypeErasedDataflowAnalysis() {}
/// Returns the `ASTContext` that is used by the analysis.
@@ -62,9 +74,12 @@ class TypeErasedDataflowAnalysis {
/// Applies the analysis transfer function for a given statement and
/// type-erased lattice element.
virtual TypeErasedLattice transferTypeErased(const Stmt *,
const TypeErasedLattice &,
Environment &) = 0;
virtual void transferTypeErased(const Stmt *, TypeErasedLattice &,
Environment &) = 0;
/// Determines whether to apply the built-in transfer functions, which model
/// the heap and stack in the `Environment`.
bool applyBuiltinTransfer() const { return ApplyBuiltinTransfer; }
};
/// Type-erased model of the program at a given program point.
@@ -74,6 +89,9 @@ struct TypeErasedDataflowAnalysisState {
/// Model of the state of the program (store and heap).
Environment Env;
TypeErasedDataflowAnalysisState(TypeErasedLattice Lattice, Environment Env)
: Lattice(std::move(Lattice)), Env(std::move(Env)) {}
};
/// Transfers the state of a basic block by evaluating each of its statements in
@@ -87,6 +105,7 @@ struct TypeErasedDataflowAnalysisState {
/// already been transferred. States in `BlockStates` that are set to
/// `llvm::None` represent basic blocks that are not evaluated yet.
TypeErasedDataflowAnalysisState transferBlock(
const ControlFlowContext &CFCtx,
std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>> &BlockStates,
const CFGBlock &Block, const Environment &InitEnv,
TypeErasedDataflowAnalysis &Analysis,
@@ -97,13 +116,8 @@ TypeErasedDataflowAnalysisState transferBlock(
/// Performs dataflow analysis and returns a mapping from basic block IDs to
/// dataflow analysis states that model the respective basic blocks. Indices
/// of the returned vector correspond to basic block IDs.
///
/// Requirements:
///
/// `Cfg` must have been built with `CFG::BuildOptions::setAllAlwaysAdd()` to
/// ensure that all sub-expressions in a basic block are evaluated.
std::vector<llvm::Optional<TypeErasedDataflowAnalysisState>>
runTypeErasedDataflowAnalysis(const CFG &Cfg,
runTypeErasedDataflowAnalysis(const ControlFlowContext &CFCtx,
TypeErasedDataflowAnalysis &Analysis,
const Environment &InitEnv);
@@ -0,0 +1,144 @@
//===-- Value.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 classes for values computed by abstract interpretation
// during dataflow analysis.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H
#include "clang/AST/Decl.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <utility>
namespace clang {
namespace dataflow {
/// Base class for all values computed by abstract interpretation.
class Value {
public:
enum class Kind { Bool, Integer, Reference, Pointer, Struct };
explicit Value(Kind ValKind) : ValKind(ValKind) {}
virtual ~Value() = default;
Kind getKind() const { return ValKind; }
private:
Kind ValKind;
};
/// Models a boolean.
class BoolValue : public Value {
public:
explicit BoolValue() : Value(Kind::Bool) {}
static bool classof(const Value *Val) { return Val->getKind() == Kind::Bool; }
};
/// Models an integer.
class IntegerValue : public Value {
public:
explicit IntegerValue() : Value(Kind::Integer) {}
static bool classof(const Value *Val) {
return Val->getKind() == Kind::Integer;
}
};
/// Base class for values that refer to storage locations.
class IndirectionValue : public Value {
public:
/// Constructs a value that refers to `PointeeLoc`.
explicit IndirectionValue(Kind ValueKind, StorageLocation &PointeeLoc)
: Value(ValueKind), PointeeLoc(PointeeLoc) {}
static bool classof(const Value *Val) {
return Val->getKind() == Kind::Reference || Val->getKind() == Kind::Pointer;
}
StorageLocation &getPointeeLoc() const { return PointeeLoc; }
private:
StorageLocation &PointeeLoc;
};
/// Models a dereferenced pointer. For example, a reference in C++ or an lvalue
/// in C.
class ReferenceValue final : public IndirectionValue {
public:
explicit ReferenceValue(StorageLocation &PointeeLoc)
: IndirectionValue(Kind::Reference, PointeeLoc) {}
static bool classof(const Value *Val) {
return Val->getKind() == Kind::Reference;
}
};
/// Models a symbolic pointer. Specifically, any value of type `T*`.
class PointerValue final : public IndirectionValue {
public:
explicit PointerValue(StorageLocation &PointeeLoc)
: IndirectionValue(Kind::Pointer, PointeeLoc) {}
static bool classof(const Value *Val) {
return Val->getKind() == Kind::Pointer;
}
};
/// Models a value of `struct` or `class` type.
class StructValue final : public Value {
public:
StructValue() : StructValue(llvm::DenseMap<const ValueDecl *, Value *>()) {}
explicit StructValue(llvm::DenseMap<const ValueDecl *, Value *> Children)
: Value(Kind::Struct), Children(std::move(Children)) {}
static bool classof(const Value *Val) {
return Val->getKind() == Kind::Struct;
}
/// Returns the child value that is assigned for `D`.
Value &getChild(const ValueDecl &D) const {
auto It = Children.find(&D);
assert(It != Children.end());
return *It->second;
}
/// Assigns `Val` as the child value for `D`.
void setChild(const ValueDecl &D, Value &Val) { Children[&D] = &Val; }
/// Returns the value of the synthetic property with the given `Name` or null
/// if the property isn't assigned a value.
Value *getProperty(llvm::StringRef Name) const {
auto It = Properties.find(Name);
return It == Properties.end() ? nullptr : It->second;
}
/// Assigns `Val` as the value of the synthetic property with the given
/// `Name`.
void setProperty(llvm::StringRef Name, Value &Val) {
Properties.insert_or_assign(Name, &Val);
}
private:
llvm::DenseMap<const ValueDecl *, Value *> Children;
llvm::StringMap<Value *> Properties;
};
} // namespace dataflow
} // namespace clang
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H
@@ -5,8 +5,8 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_STATICANALYZER_CORE_ISSUE_HASH_H
#define LLVM_CLANG_STATICANALYZER_CORE_ISSUE_HASH_H
#ifndef LLVM_CLANG_ANALYSIS_ISSUEHASH_H
#define LLVM_CLANG_ANALYSIS_ISSUEHASH_H
#include "llvm/ADT/SmallString.h"
@@ -10,8 +10,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
#ifndef LLVM_CLANG_ANALYSIS_PATHDIAGNOSTIC_H
#define LLVM_CLANG_ANALYSIS_PATHDIAGNOSTIC_H
#include "clang/AST/Stmt.h"
#include "clang/Analysis/AnalysisDeclContext.h"
@@ -41,10 +41,8 @@ class AnalysisDeclContext;
class BinaryOperator;
class CallEnter;
class CallExitEnd;
class CallExpr;
class ConditionalOperator;
class Decl;
class Expr;
class LocationContext;
class MemberExpr;
class ProgramPoint;
@@ -905,4 +903,4 @@ class PathDiagnostic : public llvm::FoldingSetNode {
} // namespace ento
} // namespace clang
#endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
#endif // LLVM_CLANG_ANALYSIS_PATHDIAGNOSTIC_H
@@ -30,7 +30,6 @@
namespace clang {
class AnalysisDeclContext;
class FunctionDecl;
class LocationContext;
/// ProgramPoints can be "tagged" as representing points specific to a given
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H
#define LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H
#ifndef LLVM_CLANG_ANALYSIS_RETAINSUMMARYMANAGER_H
#define LLVM_CLANG_ANALYSIS_RETAINSUMMARYMANAGER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_ANALYSIS_SELECTOREXTRAS_H
#define LLVM_CLANG_LIB_ANALYSIS_SELECTOREXTRAS_H
#ifndef LLVM_CLANG_ANALYSIS_SELECTOREXTRAS_H
#define LLVM_CLANG_ANALYSIS_SELECTOREXTRAS_H
#include "clang/AST/ASTContext.h"
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
#define LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
#ifndef LLVM_CLANG_BASIC_ALIGNEDALLOCATION_H
#define LLVM_CLANG_BASIC_ALIGNEDALLOCATION_H
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
@@ -42,4 +42,4 @@ inline llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
} // end namespace clang
#endif // LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
#endif // LLVM_CLANG_BASIC_ALIGNEDALLOCATION_H
@@ -1191,6 +1191,13 @@ def SYCLKernel : InheritableAttr {
let Documentation = [SYCLKernelDocs];
}
def SYCLSpecialClass: InheritableAttr {
let Spellings = [Clang<"sycl_special_class">];
let Subjects = SubjectList<[CXXRecord]>;
let LangOpts = [SYCL];
let Documentation = [SYCLSpecialClassDocs];
}
def C11NoReturn : InheritableAttr {
let Spellings = [Keyword<"_Noreturn">];
let Subjects = SubjectList<[Function], ErrorDiag>;
@@ -3686,6 +3693,8 @@ def OMPDeclareTargetDecl : InheritableAttr {
EnumArgument<"DevType", "DevTypeTy",
[ "host", "nohost", "any" ],
[ "DT_Host", "DT_NoHost", "DT_Any" ]>,
ExprArgument<"IndirectExpr">,
BoolArgument<"Indirect">,
UnsignedArgument<"Level">
];
let AdditionalMembers = [{
@@ -409,6 +409,71 @@ The SYCL kernel in the previous code sample meets these expectations.
}];
}
def SYCLSpecialClassDocs : Documentation {
let Category = DocCatStmt;
let Content = [{
SYCL defines some special classes (accessor, sampler, and stream) which require
specific handling during the generation of the SPIR entry point.
The ``__attribute__((sycl_special_class))`` attribute is used in SYCL
headers to indicate that a class or a struct needs a specific handling when
it is passed from host to device.
Special classes will have a mandatory ``__init`` method and an optional
``__finalize`` method (the ``__finalize`` method is used only with the
``stream`` type). Kernel parameters types are extract from the ``__init`` method
parameters. The kernel function arguments list is derived from the
arguments of the ``__init`` method. The arguments of the ``__init`` method are
copied into the kernel function argument list and the ``__init`` and
``__finalize`` methods are called at the beginning and the end of the kernel,
respectively.
The ``__init`` and ``__finalize`` methods must be defined inside the
special class.
Please note that this is an attribute that is used as an internal
implementation detail and not intended to be used by external users.
The syntax of the attribute is as follows:
.. code-block:: c++
class __attribute__((sycl_special_class)) accessor {};
class [[clang::sycl_special_class]] accessor {};
This is a code example that illustrates the use of the attribute:
.. code-block:: c++
class __attribute__((sycl_special_class)) SpecialType {
int F1;
int F2;
void __init(int f1) {
F1 = f1;
F2 = f1;
}
void __finalize() {}
public:
SpecialType() = default;
int getF2() const { return F2; }
};
int main () {
SpecialType T;
cgh.single_task([=] {
T.getF2();
});
}
This would trigger the following kernel entry point in the AST:
.. code-block:: c++
void __sycl_kernel(int f1) {
SpecialType T;
T.__init(f1);
...
T.__finalize()
}
}];
}
def C11NoReturnDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -5987,7 +6052,7 @@ attribute requires a string literal argument to identify the handle being releas
def DiagnoseAsBuiltinDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``diagnose_as_builtin` attribute indicates that Fortify diagnostics are to
The ``diagnose_as_builtin`` attribute indicates that Fortify diagnostics are to
be applied to the declared function as if it were the function specified by the
attribute. The builtin function whose diagnostics are to be mimicked should be
given. In addition, the order in which arguments should be applied must also
@@ -5995,12 +6060,12 @@ be given.
For example, the attribute can be used as follows.
.. code-block:: c
.. code-block:: c
__attribute__((diagnose_as_builtin(__builtin_memset, 3, 2, 1)))
void *mymemset(int n, int c, void *s) {
// ...
}
__attribute__((diagnose_as_builtin(__builtin_memset, 3, 2, 1)))
void *mymemset(int n, int c, void *s) {
// ...
}
This indicates that calls to ``mymemset`` should be diagnosed as if they were
calls to ``__builtin_memset``. The arguments ``3, 2, 1`` indicate by index the
@@ -6015,7 +6080,8 @@ they would to the builtin function, after all normal arguments. For instance,
to diagnose a new function as if it were `sscanf`, we can use the attribute as
follows.
.. code-block:: c
.. code-block:: c
__attribute__((diagnose_as_builtin(sscanf, 1, 2)))
int mysscanf(const char *str, const char *format, ...) {
// ...
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_ATTR_SUBJECT_MATCH_RULES_H
#define LLVM_CLANG_BASIC_ATTR_SUBJECT_MATCH_RULES_H
#ifndef LLVM_CLANG_BASIC_ATTRSUBJECTMATCHRULES_H
#define LLVM_CLANG_BASIC_ATTRSUBJECTMATCHRULES_H
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
@@ -26,6 +26,7 @@
// i -> int
// h -> half (__fp16, OpenCL)
// x -> half (_Float16)
// y -> half (__bf16)
// f -> float
// d -> double
// z -> size_t
@@ -640,16 +641,23 @@ BUILTIN(__builtin_unreachable, "v", "nr")
BUILTIN(__builtin_shufflevector, "v." , "nct")
BUILTIN(__builtin_convertvector, "v." , "nct")
BUILTIN(__builtin_alloca, "v*z" , "Fn")
BUILTIN(__builtin_alloca_uninitialized, "v*z", "Fn")
BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn")
BUILTIN(__builtin_alloca_with_align_uninitialized, "v*zIz", "Fn")
BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
BUILTIN(__builtin_elementwise_abs, "v.", "nct")
BUILTIN(__builtin_elementwise_max, "v.", "nct")
BUILTIN(__builtin_elementwise_min, "v.", "nct")
BUILTIN(__builtin_elementwise_ceil, "v.", "nct")
BUILTIN(__builtin_elementwise_floor, "v.", "nct")
BUILTIN(__builtin_elementwise_roundeven, "v.", "nct")
BUILTIN(__builtin_elementwise_trunc, "v.", "nct")
BUILTIN(__builtin_reduce_max, "v.", "nct")
BUILTIN(__builtin_reduce_min, "v.", "nct")
BUILTIN(__builtin_reduce_xor, "v.", "nct")
BUILTIN(__builtin_reduce_or, "v.", "nct")
BUILTIN(__builtin_reduce_and, "v.", "nct")
BUILTIN(__builtin_matrix_transpose, "v.", "nFt")
BUILTIN(__builtin_matrix_column_major_load, "v.", "nFt")
@@ -402,6 +402,23 @@ BUILTIN(__nvvm_ull2d_rp, "dULLi", "")
BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "")
BUILTIN(__nvvm_f2h_rn, "Usf", "")
TARGET_BUILTIN(__nvvm_ff2bf16x2_rn, "ZUiff", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_ff2bf16x2_rn_relu, "ZUiff", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_ff2bf16x2_rz, "ZUiff", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_ff2bf16x2_rz_relu, "ZUiff", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_ff2f16x2_rn, "V2hff", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_ff2f16x2_rn_relu, "V2hff", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_ff2f16x2_rz, "V2hff", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_ff2f16x2_rz_relu, "V2hff", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_f2bf16_rn, "ZUsf", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_f2bf16_rn_relu, "ZUsf", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_f2bf16_rz, "ZUsf", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_f2bf16_rz_relu, "ZUsf", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_f2tf32_rna, "ZUif", "", AND(SM_80,PTX70))
// Bitcast
BUILTIN(__nvvm_bitcast_f2i, "if", "")
@@ -16,13 +16,13 @@
#endif
// Zbb extension
TARGET_BUILTIN(__builtin_riscv_orc_b_32, "ZiZi", "nc", "experimental-zbb")
TARGET_BUILTIN(__builtin_riscv_orc_b_64, "WiWi", "nc", "experimental-zbb,64bit")
TARGET_BUILTIN(__builtin_riscv_orc_b_32, "ZiZi", "nc", "zbb")
TARGET_BUILTIN(__builtin_riscv_orc_b_64, "WiWi", "nc", "zbb,64bit")
// Zbc extension
TARGET_BUILTIN(__builtin_riscv_clmul, "LiLiLi", "nc", "experimental-zbc")
TARGET_BUILTIN(__builtin_riscv_clmulh, "LiLiLi", "nc", "experimental-zbc")
TARGET_BUILTIN(__builtin_riscv_clmulr, "LiLiLi", "nc", "experimental-zbc")
TARGET_BUILTIN(__builtin_riscv_clmul, "LiLiLi", "nc", "zbc")
TARGET_BUILTIN(__builtin_riscv_clmulh, "LiLiLi", "nc", "zbc")
TARGET_BUILTIN(__builtin_riscv_clmulr, "LiLiLi", "nc", "zbc")
// Zbe extension
TARGET_BUILTIN(__builtin_riscv_bcompress_32, "ZiZiZi", "nc", "experimental-zbe")
@@ -33,6 +33,10 @@ TARGET_BUILTIN(__builtin_riscv_bdecompress_32, "ZiZiZi", "nc",
TARGET_BUILTIN(__builtin_riscv_bdecompress_64, "WiWiWi", "nc",
"experimental-zbe,64bit")
// Zbf extension
TARGET_BUILTIN(__builtin_riscv_bfp_32, "ZiZiZi", "nc", "experimental-zbf")
TARGET_BUILTIN(__builtin_riscv_bfp_64, "WiWiWi", "nc", "experimental-zbf,64bit")
// Zbp extension
TARGET_BUILTIN(__builtin_riscv_grev_32, "ZiZiZi", "nc", "experimental-zbp")
TARGET_BUILTIN(__builtin_riscv_grev_64, "WiWiWi", "nc", "experimental-zbp,64bit")
@@ -54,8 +58,14 @@ TARGET_BUILTIN(__builtin_riscv_crc32_w, "LiLi", "nc", "experimental-zbr")
TARGET_BUILTIN(__builtin_riscv_crc32c_b, "LiLi", "nc", "experimental-zbr")
TARGET_BUILTIN(__builtin_riscv_crc32c_h, "LiLi", "nc", "experimental-zbr")
TARGET_BUILTIN(__builtin_riscv_crc32c_w, "LiLi", "nc", "experimental-zbr")
TARGET_BUILTIN(__builtin_riscv_crc32_d, "LiLi", "nc", "experimental-zbr")
TARGET_BUILTIN(__builtin_riscv_crc32c_d, "LiLi", "nc", "experimental-zbr")
TARGET_BUILTIN(__builtin_riscv_crc32_d, "LiLi", "nc", "experimental-zbr,64bit")
TARGET_BUILTIN(__builtin_riscv_crc32c_d, "LiLi", "nc", "experimental-zbr,64bit")
// Zbt extension
TARGET_BUILTIN(__builtin_riscv_fsl_32, "LiLiLiLi", "nc", "experimental-zbt")
TARGET_BUILTIN(__builtin_riscv_fsr_32, "LiLiLiLi", "nc", "experimental-zbt")
TARGET_BUILTIN(__builtin_riscv_fsl_64, "WiWiWiWi", "nc", "experimental-zbt,64bit")
TARGET_BUILTIN(__builtin_riscv_fsr_64, "WiWiWiWi", "nc", "experimental-zbt,64bit")
#undef BUILTIN
#undef TARGET_BUILTIN
@@ -265,10 +265,6 @@ TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_pminsw128, "V8sV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_packsswb128, "V16cV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_packssdw128, "V8sV4iV4i", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_packuswb128, "V16cV8sV8s", "ncV:128:", "sse2")
@@ -296,9 +292,6 @@ TARGET_BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "ncV:128:", "ssse3")
TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "n", "sse")
TARGET_HEADER_BUILTIN(_mm_setcsr, "vUi", "nh","xmmintrin.h", ALL_LANGUAGES, "sse")
@@ -380,14 +373,6 @@ TARGET_BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_packusdw128, "V8sV4iV4i", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_pmaxsb128, "V16cV16cV16c", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_pmaxsd128, "V4iV4iV4i", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_pmaxud128, "V4iV4iV4i", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_pmaxuw128, "V8sV8sV8s", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_pmuldq128, "V2OiV4iV4i", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_roundps, "V4fV4fIi", "ncV:128:", "sse4.1")
TARGET_BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fIi", "ncV:128:", "sse4.1")
@@ -558,9 +543,6 @@ TARGET_BUILTIN(__builtin_ia32_vec_set_v8si, "V8iV8iiIi", "ncV:256:", "avx")
// AVX2
TARGET_BUILTIN(__builtin_ia32_mpsadbw256, "V32cV32cV32cIc", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pabsb256, "V32cV32c", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pabsw256, "V16sV16s", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pabsd256, "V8iV8i", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_packsswb256, "V32cV16sV16s", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_packssdw256, "V16sV8iV8i", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_packuswb256, "V32cV16sV16s", "ncV:256:", "avx2")
@@ -586,18 +568,6 @@ TARGET_BUILTIN(__builtin_ia32_phsubd256, "V8iV8iV8i", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_phsubsw256, "V16sV16sV16s", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmaddubsw256, "V16sV32cV32c", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmaddwd256, "V8iV16sV16s", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmaxub256, "V32cV32cV32c", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmaxuw256, "V16sV16sV16s", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmaxud256, "V8iV8iV8i", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmaxsb256, "V32cV32cV32c", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmaxsw256, "V16sV16sV16s", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmaxsd256, "V8iV8iV8i", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pminub256, "V32cV32cV32c", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pminuw256, "V16sV16sV16s", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pminud256, "V8iV8iV8i", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pminsb256, "V32cV32cV32c", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pminsw256, "V16sV16sV16s", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pminsd256, "V8iV8iV8i", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmovmskb256, "iV32c", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmuldq256, "V4OiV8iV8i", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pmulhrsw256, "V16sV16sV16s", "ncV:256:", "avx2")
@@ -927,16 +897,6 @@ TARGET_BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "ncV:512:",
TARGET_BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pabsd512, "V16iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pabsq512, "V8OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmaxsd512, "V16iV16iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmaxsq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmaxud512, "V16iV16iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmaxuq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pminsd512, "V16iV16iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pminsq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pminud512, "V16iV16iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pminuq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8OiV16iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8OiV16iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "nV:512:", "avx512f")
@@ -1045,8 +1005,6 @@ TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx5
TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8OiV8OiIiUc", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pabsb512, "V64cV64c", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pabsw512, "V32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packssdw512, "V32sV16iV16i", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packsswb512, "V64cV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packusdw512, "V32sV16iV16i", "ncV:512:", "avx512bw")
@@ -1057,14 +1015,6 @@ TARGET_BUILTIN(__builtin_ia32_paddusb512, "V64cV64cV64c", "ncV:512:", "avx512bw"
TARGET_BUILTIN(__builtin_ia32_paddusw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pavgb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pavgw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxub512, "V64cV64cV64c", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxuw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminub512, "V64cV64cV64c", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminuw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pshufb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
@@ -1198,16 +1148,6 @@ TARGET_BUILTIN(__builtin_ia32_getexppd128_mask, "V2dV2dV2dUc", "ncV:128:", "avx5
TARGET_BUILTIN(__builtin_ia32_getexppd256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getexpps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getexpps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pabsq128, "V2OiV2Oi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pabsq256, "V4OiV4Oi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxsq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxsq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxuq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxuq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminsq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminsq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminuq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminuq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_rndscalepd_128_mask, "V2dV2dIiV2dUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_rndscalepd_256_mask, "V4dV4dIiV4dUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_rndscaleps_128_mask, "V4fV4fIiV4fUc", "ncV:128:", "avx512vl")
@@ -2075,8 +2015,6 @@ TARGET_BUILTIN(__builtin_ia32_selectsd_128, "V2dUcV2dV2d", "ncV:128:", "avx512f"
// generic reduction intrinsics
TARGET_BUILTIN(__builtin_ia32_reduce_add_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_add_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_and_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_and_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_fadd_pd512, "ddV8d", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_fadd_ps512, "ffV16f", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_fadd_ph512, "xxV32x", "ncV:512:", "avx512fp16")
@@ -2099,16 +2037,6 @@ TARGET_BUILTIN(__builtin_ia32_reduce_fmul_ph256, "xxV16x", "ncV:256:", "avx512fp
TARGET_BUILTIN(__builtin_ia32_reduce_fmul_ph128, "xxV8x", "ncV:128:", "avx512fp16,avx512vl")
TARGET_BUILTIN(__builtin_ia32_reduce_mul_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_mul_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_or_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_or_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_smax_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_smax_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_smin_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_smin_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_umax_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_umax_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_umin_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_umin_q512, "OiV8Oi", "ncV:512:", "avx512f")
// MONITORX/MWAITX
TARGET_BUILTIN(__builtin_ia32_monitorx, "vvC*UiUi", "n", "mwaitx")
@@ -64,7 +64,7 @@ CODEGENOPT(DisableLifetimeMarkers, 1, 0) ///< Don't emit any lifetime markers
CODEGENOPT(DisableO0ImplyOptNone , 1, 0) ///< Don't annonate function with optnone at O0
CODEGENOPT(ExperimentalStrictFloatingPoint, 1, 0) ///< Enables the new, experimental
///< strict floating point.
CODEGENOPT(EnableNoundefAttrs, 1, 0) ///< Enable emitting `noundef` attributes on IR call arguments and return values
CODEGENOPT(DisableNoundefAttrs, 1, 0) ///< Disable emitting `noundef` attributes on IR call arguments and return values
CODEGENOPT(LegacyPassManager, 1, 0) ///< Use the legacy pass manager.
CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new
///< pass manager.
@@ -107,6 +107,8 @@ CODEGENOPT(CFProtectionReturn , 1, 0) ///< if -fcf-protection is
///< set to full or return.
CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection is
///< set to full or branch.
CODEGENOPT(IBTSeal, 1, 0) ///< set to optimize CFProtectionBranch.
CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
///< enabled.
CODEGENOPT(StackSizeSection , 1, 0) ///< Set when -fstack-size-section is enabled.
@@ -139,6 +141,9 @@ VALUE_CODEGENOPT(XRaySelectedFunctionGroup, 32, 0)
VALUE_CODEGENOPT(PatchableFunctionEntryCount , 32, 0) ///< Number of NOPs at function entry
VALUE_CODEGENOPT(PatchableFunctionEntryOffset , 32, 0)
CODEGENOPT(HotPatch, 1, 0) ///< Supports the Microsoft /HOTPATCH flag and
///< generates a 'patchable-function' attribute.
CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled.
CODEGENOPT(MNopMCount , 1, 0) ///< Set when -mnop-mcount is enabled.
@@ -231,6 +236,9 @@ CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
ENUM_CODEGENOPT(SanitizeAddressDtor, llvm::AsanDtorKind, 2,
llvm::AsanDtorKind::Global) ///< Set how ASan global
///< destructors are emitted.
CODEGENOPT(SanitizeMemoryParamRetval, 1, 0) ///< Enable detection of uninitialized
///< parameters and return values
///< in MemorySanitizer
CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection
///< in MemorySanitizer
CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI.
@@ -307,7 +307,7 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::shared_ptr<llvm::Regex> Regex;
/// By default, optimization remark is missing.
OptRemark() : Kind(RK_Missing), Pattern(""), Regex(nullptr) {}
OptRemark() : Kind(RK_Missing), Regex(nullptr) {}
/// Returns true iff the optimization remark holds a valid regular
/// expression.
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_DARWIN_SDK_INFO_H
#define LLVM_CLANG_BASIC_DARWIN_SDK_INFO_H
#ifndef LLVM_CLANG_BASIC_DARWINSDKINFO_H
#define LLVM_CLANG_BASIC_DARWINSDKINFO_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
@@ -57,6 +57,20 @@ class DarwinSDKInfo {
llvm::Triple::MacOSX, llvm::Triple::UnknownEnvironment);
}
/// Returns the os-environment mapping pair that's used to represent the
/// iOS -> watchOS version mapping.
static inline constexpr OSEnvPair iOStoWatchOSPair() {
return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
llvm::Triple::WatchOS, llvm::Triple::UnknownEnvironment);
}
/// Returns the os-environment mapping pair that's used to represent the
/// iOS -> tvOS version mapping.
static inline constexpr OSEnvPair iOStoTvOSPair() {
return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
llvm::Triple::TvOS, llvm::Triple::UnknownEnvironment);
}
private:
StorageType Value;
@@ -154,4 +168,4 @@ Expected<Optional<DarwinSDKInfo>> parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS,
} // end namespace clang
#endif // LLVM_CLANG_BASIC_DARWIN_SDK_INFO_H
#endif // LLVM_CLANG_BASIC_DARWINSDKINFO_H
@@ -84,6 +84,7 @@ class Diagnostic<string text, DiagClass DC, Severity defaultmapping> {
bit AccessControl = 0;
bit WarningNoWerror = 0;
bit ShowInSystemHeader = 0;
bit ShowInSystemMacro = 1;
bit Deferrable = 0;
Severity DefaultSeverity = defaultmapping;
DiagGroup Group;
@@ -108,6 +109,14 @@ class SuppressInSystemHeader {
bit ShowInSystemHeader = 0;
}
class ShowInSystemMacro {
bit ShowInSystemMacro = 1;
}
class SuppressInSystemMacro {
bit ShowInSystemMacro = 0;
}
class Deferrable {
bit Deferrable = 1;
}
@@ -159,4 +168,3 @@ include "DiagnosticParseKinds.td"
include "DiagnosticRefactoringKinds.td"
include "DiagnosticSemaKinds.td"
include "DiagnosticSerializationKinds.td"
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define ASTSTART
#include "clang/Basic/DiagnosticASTKinds.inc"
@@ -590,4 +590,9 @@ def warn_padded_struct_size : Warning<
InGroup<Padded>, DefaultIgnore;
def warn_unnecessary_packed : Warning<
"packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore;
// -Wunaligned-access
def warn_unaligned_access : Warning<
"field %1 within %0 is less aligned than %2 and is usually due to %0 being "
"packed, which can lead to unaligned accesses">, InGroup<UnalignedAccess>, DefaultIgnore;
}
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define ANALYSISSTART
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define COMMENTSTART
#include "clang/Basic/DiagnosticCommentKinds.inc"
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define CROSSTUSTART
#include "clang/Basic/DiagnosticCrossTUKinds.inc"
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define DRIVERSTART
#include "clang/Basic/DiagnosticDriverKinds.inc"
@@ -116,10 +116,6 @@ def warn_drv_unsupported_option_for_target : Warning<
"ignoring '%0' option as it is not currently supported for target '%1'">,
InGroup<OptionIgnored>;
def warn_drv_spirv_linking_multiple_inputs_unsupported: Warning<
"Linking multiple input files is not supported for SPIR-V yet">,
InGroup<OptionIgnored>;
def err_drv_invalid_thread_model_for_target : Error<
"invalid thread model '%0' in '%1' for this target">;
def err_drv_invalid_linker_name : Error<
@@ -384,6 +380,9 @@ def warn_drv_deprecated_arg : Warning<
"argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>;
def warn_drv_assuming_mfloat_abi_is : Warning<
"unknown platform, assuming -mfloat-abi=%0">;
def warn_drv_unsupported_float_abi_by_lib : Warning<
"float ABI '%0' is not supported by current library">,
InGroup<DiagGroup<"unsupported-abi">>;
def warn_ignoring_ftabstop_value : Warning<
"ignoring invalid -ftabstop value '%0', using default value %1">;
def warn_drv_overriding_flag_option : Warning<
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
#define LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
#ifndef LLVM_CLANG_BASIC_DIAGNOSTICERROR_H
#define LLVM_CLANG_BASIC_DIAGNOSTICERROR_H
#include "clang/Basic/PartialDiagnostic.h"
#include "llvm/Support/Error.h"
@@ -57,4 +57,4 @@ class DiagnosticError : public llvm::ErrorInfo<DiagnosticError> {
} // end namespace clang
#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
#endif // LLVM_CLANG_BASIC_DIAGNOSTICERROR_H
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define FRONTENDSTART
#include "clang/Basic/DiagnosticFrontendKinds.inc"
@@ -241,6 +241,7 @@ def Documentation : DiagGroup<"documentation",
def EmptyBody : DiagGroup<"empty-body">;
def Exceptions : DiagGroup<"exceptions">;
def DeclarationAfterStatement : DiagGroup<"declaration-after-statement">;
def GNUEmptyInitializer : DiagGroup<"gnu-empty-initializer">;
def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">;
@@ -542,6 +543,7 @@ def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
def OrderedCompareFunctionPointers : DiagGroup<"ordered-compare-function-pointers">;
def Packed : DiagGroup<"packed">;
def Padded : DiagGroup<"padded">;
def UnalignedAccess : DiagGroup<"unaligned-access">;
def PessimizingMove : DiagGroup<"pessimizing-move">;
def ReturnStdMove : DiagGroup<"return-std-move">;
@@ -67,7 +67,7 @@ namespace clang {
// Get typedefs for common diagnostics.
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, CATEGORY, \
NOWERROR, SHOWINSYSHEADER, DEFFERABLE) \
NOWERROR, SHOWINSYSHEADER, SHOWINSYSMACRO, DEFFERABLE) \
ENUM,
#define COMMONSTART
#include "clang/Basic/DiagnosticCommonKinds.inc"
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define LEXSTART
#include "clang/Basic/DiagnosticLexKinds.inc"
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define PARSESTART
#include "clang/Basic/DiagnosticParseKinds.inc"
@@ -1344,15 +1344,17 @@ def warn_omp_unknown_assumption_clause_without_args
def note_omp_assumption_clause_continue_here
: Note<"the ignored tokens spans until here">;
def err_omp_declare_target_unexpected_clause: Error<
"unexpected '%0' clause, only %select{'device_type'|'to' or 'link'|'to', 'link' or 'device_type'}1 clauses expected">;
"unexpected '%0' clause, only %select{'device_type'|'to' or 'link'|'to', 'link' or 'device_type'|'device_type', 'indirect'|'to', 'link', 'device_type' or 'indirect'}1 clauses expected">;
def err_omp_begin_declare_target_unexpected_implicit_to_clause: Error<
"unexpected '(', only 'to', 'link' or 'device_type' clauses expected for 'begin declare target' directive">;
def err_omp_declare_target_unexpected_clause_after_implicit_to: Error<
"unexpected clause after an implicit 'to' clause">;
def err_omp_declare_target_missing_to_or_link_clause: Error<
"expected at least one 'to' or 'link' clause">;
"expected at least one %select{'to' or 'link'|'to', 'link' or 'indirect'}0 clause">;
def err_omp_declare_target_multiple : Error<
"%0 appears multiple times in clauses on the same declare target directive">;
def err_omp_declare_target_indirect_device_type: Error<
"only 'device_type(any)' clause is allowed with indirect clause">;
def err_omp_expected_clause: Error<
"expected at least one clause on '#pragma omp %0' directive">;
def err_omp_mapper_illegal_identifier : Error<
@@ -1374,7 +1376,7 @@ def warn_omp_declare_variant_string_literal_or_identifier
"%select{set|selector|property}0; "
"%select{set|selector|property}0 skipped">,
InGroup<OpenMPClauses>;
def warn_unknown_begin_declare_variant_isa_trait
def warn_unknown_declare_variant_isa_trait
: Warning<"isa trait '%0' is not known to the current target; verify the "
"spelling or consider restricting the context selector with the "
"'arch' selector further">,
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define REFACTORINGSTART
#include "clang/Basic/DiagnosticRefactoringKinds.inc"
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define SEMASTART
#include "clang/Basic/DiagnosticSemaKinds.inc"
@@ -197,7 +197,8 @@ def ext_flexible_array_init : Extension<
// C++20 designated initializers
def ext_cxx_designated_init : Extension<
"designated initializers are a C++20 extension">, InGroup<CXX20Designator>;
"designated initializers are a C++20 extension">, InGroup<CXX20Designator>,
SuppressInSystemMacro;
def warn_cxx17_compat_designated_init : Warning<
"designated initializers are incompatible with C++ standards before C++20">,
InGroup<CXXPre20CompatPedantic>, DefaultIgnore;
@@ -449,7 +450,7 @@ def warn_decl_shadow :
"typedef in %2|"
"type alias in %2|"
"structured binding}1">,
InGroup<Shadow>, DefaultIgnore;
InGroup<Shadow>, DefaultIgnore, SuppressInSystemMacro;
def warn_decl_shadow_uncaptured_local :
Warning<warn_decl_shadow.Text>,
InGroup<ShadowUncapturedLocal>, DefaultIgnore;
@@ -1695,9 +1696,6 @@ def err_missing_exception_specification : Error<
def ext_missing_exception_specification : ExtWarn<
err_missing_exception_specification.Text>,
InGroup<DiagGroup<"missing-exception-spec">>;
def ext_ms_missing_exception_specification : ExtWarn<
err_missing_exception_specification.Text>,
InGroup<MicrosoftExceptionSpec>;
def err_noexcept_needs_constant_expression : Error<
"argument to noexcept specifier must be a constant expression">;
def err_exception_spec_not_parsed : Error<
@@ -3944,7 +3942,8 @@ def warn_cast_align : Warning<
"cast from %0 to %1 increases required alignment from %2 to %3">,
InGroup<CastAlign>, DefaultIgnore;
def warn_old_style_cast : Warning<
"use of old-style cast">, InGroup<OldStyleCast>, DefaultIgnore;
"use of old-style cast">, InGroup<OldStyleCast>, DefaultIgnore,
SuppressInSystemMacro;
// Separate between casts to void* and non-void* pointers.
// Some APIs use (abuse) void* for something like a user context,
@@ -5785,7 +5784,7 @@ def err_typecheck_invalid_restrict_invalid_pointee : Error<
def ext_typecheck_zero_array_size : Extension<
"zero size arrays are an extension">, InGroup<ZeroLengthArray>;
def err_typecheck_zero_array_size : Error<
"zero-length arrays are not permitted in C++">;
"zero-length arrays are not permitted in %select{C++|SYCL device code}0">;
def err_array_size_non_int : Error<"size of array has non-integer type %0">;
def err_init_element_not_constant : Error<
"initializer element is not a compile-time constant">;
@@ -7804,6 +7803,11 @@ def err_expected_class_or_namespace : Error<"%0 is not a class"
"%select{ or namespace|, namespace, or enumeration}1">;
def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here "
"because namespace %1 does not enclose namespace %2">;
def err_export_non_namespace_scope_name : Error<
"cannot export %0 as it is not at namespace scope">;
def err_redeclaration_non_exported : Error <
"cannot export redeclaration %0 here since the previous declaration is not "
"exported">;
def err_invalid_declarator_global_scope : Error<
"definition or redeclaration of %0 cannot name the global scope">;
def err_invalid_declarator_in_function : Error<
@@ -9370,6 +9374,9 @@ def warn_printf_ObjCflags_without_ObjCConversion: Warning<
def warn_printf_invalid_objc_flag: Warning<
"'%0' is not a valid object format flag">,
InGroup<Format>;
def warn_printf_narg_not_supported : Warning<
"'%%n' specifier not supported on this platform">,
InGroup<Format>;
def warn_scanf_scanlist_incomplete : Warning<
"no closing ']' for '%%[' in scanf format string">,
InGroup<Format>;
@@ -9549,7 +9556,8 @@ def err_generic_sel_multi_match : Error<
// Blocks
def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks"
" or %select{pick a deployment target that supports them|for OpenCL 2.0}0">;
" or %select{pick a deployment target that supports them|for OpenCL C 2.0"
" or OpenCL C 3.0 with __opencl_c_device_enqueue feature}0">;
def err_block_returning_array_function : Error<
"block cannot return %select{array|function}0 type %1">;
@@ -9862,8 +9870,11 @@ def err_constant_integer_arg_type : Error<
"argument to %0 must be a constant integer">;
def ext_mixed_decls_code : Extension<
"ISO C90 forbids mixing declarations and code">,
InGroup<DiagGroup<"declaration-after-statement">>;
"mixing declarations and code is a C99 extension">,
InGroup<DeclarationAfterStatement>;
def warn_mixed_decls_code : Warning<
"mixing declarations and code is incompatible with standards before C99">,
InGroup<DeclarationAfterStatement>, DefaultIgnore;
def err_non_local_variable_decl_in_for : Error<
"declaration of non-local variable in 'for' loop">;
@@ -10813,11 +10824,6 @@ def err_omp_non_lvalue_in_map_or_motion_clauses: Error<
"expected addressable lvalue in '%0' clause">;
def err_omp_var_expected : Error<
"expected variable of the '%0' type%select{|, not %2}1">;
def warn_unknown_declare_variant_isa_trait
: Warning<"isa trait '%0' is not known to the current target; verify the "
"spelling or consider restricting the context selector with the "
"'arch' selector further">,
InGroup<SourceUsesOpenMP>;
def err_omp_non_pointer_type_array_shaping_base : Error<
"expected expression with a pointer to a complete type as a base of an array "
"shaping operation">;
@@ -11047,7 +11053,7 @@ def warn_deprecated_coroutine_namespace : Warning<
"use std::%0 instead">,
InGroup<DeprecatedExperimentalCoroutine>;
def err_mixed_use_std_and_experimental_namespace_for_coroutine : Error<
"mixed use of std and std::experimental namespaces for "
"conflicting mixed use of std and std::experimental namespaces for "
"coroutine components">;
def err_implicit_coroutine_std_nothrow_type_not_found : Error<
"std::nothrow was not found; include <new> before defining a coroutine which "
@@ -11443,6 +11449,9 @@ def warn_sycl_kernel_num_of_function_params : Warning<
def warn_sycl_kernel_return_type : Warning<
"function template with 'sycl_kernel' attribute must have a 'void' return type">,
InGroup<IgnoredAttributes>;
def err_sycl_special_type_num_init_method : Error<
"types with 'sycl_special_class' attribute must have one and only one '__init' "
"method defined">;
def err_bit_int_bad_size : Error<"%select{signed|unsigned}0 _BitInt must "
"have a bit size of at least %select{2|1}0">;
@@ -11466,7 +11475,7 @@ def warn_tcb_enforcement_violation : Warning<
// RISC-V builtin required extension warning
def err_riscv_builtin_requires_extension : Error<
"builtin requires '%0' extension support to be enabled">;
"builtin requires at least one of the following extensions support to be enabled : %0">;
def err_riscv_builtin_invalid_lmul : Error<
"LMUL argument must be in the range [0,3] or [5,7]">;
} // end of sema component.
@@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
ENUM,
#define SERIALIZATIONSTART
#include "clang/Basic/DiagnosticSerializationKinds.inc"
@@ -19,6 +19,7 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorOr.h"
namespace clang {

Some files were not shown because too many files have changed in this diff Show More