Update clang to trunk r290819 and resolve conflicts.

This commit is contained in:
Dimitry Andric 2017-01-02 21:29:30 +00:00
commit 4429064704
665 changed files with 66034 additions and 27809 deletions

View File

@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
#define CINDEX_VERSION_MINOR 35
#define CINDEX_VERSION_MINOR 37
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@ -326,7 +326,7 @@ clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file);
*
* \param tu the translation unit
*
* \param file_name the name of the file.
* \param file_name the name of the file.
*
* \returns the file handle for the named file in the translation unit \p tu,
* or a NULL file handle if the file was not a part of this translation unit.
@ -626,6 +626,15 @@ typedef struct {
CINDEX_LINKAGE CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit tu,
CXFile file);
/**
* \brief Retrieve all ranges from all files that were skipped by the
* preprocessor.
*
* The preprocessor will skip lines when they are surrounded by an
* if/ifdef/ifndef directive whose condition does not evaluate to true.
*/
CINDEX_LINKAGE CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit tu);
/**
* \brief Destroy the given \c CXSourceRangeList.
*/
@ -2325,7 +2334,39 @@ enum CXCursorKind {
*/
CXCursor_OMPTargetParallelForSimdDirective = 269,
CXCursor_LastStmt = CXCursor_OMPTargetParallelForSimdDirective,
/** \brief OpenMP target simd directive.
*/
CXCursor_OMPTargetSimdDirective = 270,
/** \brief OpenMP teams distribute directive.
*/
CXCursor_OMPTeamsDistributeDirective = 271,
/** \brief OpenMP teams distribute simd directive.
*/
CXCursor_OMPTeamsDistributeSimdDirective = 272,
/** \brief OpenMP teams distribute parallel for simd directive.
*/
CXCursor_OMPTeamsDistributeParallelForSimdDirective = 273,
/** \brief OpenMP teams distribute parallel for directive.
*/
CXCursor_OMPTeamsDistributeParallelForDirective = 274,
/** \brief OpenMP target teams directive.
*/
CXCursor_OMPTargetTeamsDirective = 275,
/** \brief OpenMP target teams distribute directive.
*/
CXCursor_OMPTargetTeamsDistributeDirective = 276,
/** \brief OpenMP target teams distribute parallel for directive.
*/
CXCursor_OMPTargetTeamsDistributeParallelForDirective = 277,
CXCursor_LastStmt = CXCursor_OMPTargetTeamsDistributeParallelForDirective,
/**
* \brief Cursor that represents the translation unit itself.
@ -2383,8 +2424,12 @@ enum CXCursorKind {
* \brief A static_assert or _Static_assert node
*/
CXCursor_StaticAssert = 602,
/**
* \brief a friend declaration.
*/
CXCursor_FriendDecl = 603,
CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl,
CXCursor_LastExtraDecl = CXCursor_StaticAssert,
CXCursor_LastExtraDecl = CXCursor_FriendDecl,
/**
* \brief A code completion overload candidate.
@ -3001,7 +3046,7 @@ enum CXCallingConv {
CXCallingConv_X86Pascal = 5,
CXCallingConv_AAPCS = 6,
CXCallingConv_AAPCS_VFP = 7,
/* Value 8 was PnaclCall, but it was never used, so it could safely be re-used. */
CXCallingConv_X86RegCall = 8,
CXCallingConv_IntelOclBicc = 9,
CXCallingConv_X86_64Win64 = 10,
CXCallingConv_X86_64SysV = 11,
@ -3491,11 +3536,8 @@ enum CXRefQualifierKind {
};
/**
* \brief Returns the number of template arguments for given class template
* specialization, or -1 if type \c T is not a class template specialization.
*
* Variadic argument packs count as only one argument, and can not be inspected
* further.
* \brief Returns the number of template arguments for given template
* specialization, or -1 if type \c T is not a template specialization.
*/
CINDEX_LINKAGE int clang_Type_getNumTemplateArguments(CXType T);
@ -5239,6 +5281,25 @@ CINDEX_LINKAGE CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E);
*/
CINDEX_LINKAGE int clang_EvalResult_getAsInt(CXEvalResult E);
/**
* \brief Returns the evaluation result as a long long integer if the
* kind is Int. This prevents overflows that may happen if the result is
* returned with clang_EvalResult_getAsInt.
*/
CINDEX_LINKAGE long long clang_EvalResult_getAsLongLong(CXEvalResult E);
/**
* \brief Returns a non-zero value if the kind is Int and the evaluation
* result resulted in an unsigned integer.
*/
CINDEX_LINKAGE unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E);
/**
* \brief Returns the evaluation result as an unsigned integer if
* the kind is Int and clang_EvalResult_isUnsignedInt is non-zero.
*/
CINDEX_LINKAGE unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E);
/**
* \brief Returns the evaluation result as double if the
* kind is double.

View File

@ -135,14 +135,15 @@ class APValue {
}
APValue(const APValue &RHS);
APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex,
bool IsNullPtr = false)
: Kind(Uninitialized) {
MakeLValue(); setLValue(B, O, N, CallIndex);
MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr);
}
APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
bool OnePastTheEnd, unsigned CallIndex)
bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false)
: Kind(Uninitialized) {
MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex);
MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
}
APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
MakeArray(InitElts, Size);
@ -254,6 +255,7 @@ class APValue {
bool hasLValuePath() const;
ArrayRef<LValuePathEntry> getLValuePath() const;
unsigned getLValueCallIndex() const;
bool isNullPointer() const;
APValue &getVectorElt(unsigned I) {
assert(isVector() && "Invalid accessor");
@ -374,10 +376,10 @@ class APValue {
((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
}
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
unsigned CallIndex);
unsigned CallIndex, bool IsNullPtr);
void setLValue(LValueBase B, const CharUnits &O,
ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
unsigned CallIndex);
unsigned CallIndex, bool IsNullPtr);
void setUnion(const FieldDecl *Field, const APValue &Value) {
assert(isUnion() && "Invalid accessor");
((UnionData*)(char*)Data.buffer)->Field = Field;

View File

@ -14,8 +14,6 @@
#ifndef LLVM_CLANG_AST_ASTCONSUMER_H
#define LLVM_CLANG_AST_ASTCONSUMER_H
#include "llvm/ADT/StringRef.h"
namespace clang {
class ASTContext;
class CXXMethodDecl;

View File

@ -19,73 +19,107 @@
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RawCommentList.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Linkage.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SanitizerBlacklist.h"
#include "clang/Basic/VersionTuple.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <memory>
#include <new>
#include <string>
#include <utility>
#include <vector>
namespace llvm {
struct fltSemantics;
}
struct fltSemantics;
} // end namespace llvm
namespace clang {
class FileManager;
class AtomicExpr;
class ASTRecordLayout;
class BlockExpr;
class CharUnits;
class DiagnosticsEngine;
class Expr;
class ASTMutationListener;
class IdentifierTable;
class MaterializeTemporaryExpr;
class SelectorTable;
class TargetInfo;
class CXXABI;
class MangleNumberingContext;
// Decls
class MangleContext;
class ObjCIvarDecl;
class ObjCPropertyDecl;
class UnresolvedSetIterator;
class UsingDecl;
class UsingShadowDecl;
class VTableContextBase;
namespace Builtin { class Context; }
enum BuiltinTemplateKind : int;
class ASTMutationListener;
class ASTRecordLayout;
class AtomicExpr;
class BlockExpr;
class CharUnits;
class CXXABI;
class DiagnosticsEngine;
class Expr;
class MangleNumberingContext;
class MaterializeTemporaryExpr;
class TargetInfo;
// Decls
class MangleContext;
class ObjCIvarDecl;
class ObjCPropertyDecl;
class UnresolvedSetIterator;
class UsingDecl;
class UsingShadowDecl;
class VTableContextBase;
namespace comments {
class FullComment;
}
namespace Builtin {
struct TypeInfo {
uint64_t Width;
unsigned Align;
bool AlignIsRequired : 1;
TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
: Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
};
class Context;
} // end namespace Builtin
enum BuiltinTemplateKind : int;
namespace comments {
class FullComment;
} // end namespace comments
struct TypeInfo {
uint64_t Width;
unsigned Align;
bool AlignIsRequired : 1;
TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
: Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
};
/// \brief Holds long-lived AST nodes (such as types and decls) that can be
/// referred to throughout the semantic analysis of a file.
@ -114,6 +148,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
mutable llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
mutable llvm::FoldingSet<ObjCTypeParamType> ObjCTypeParamTypes;
mutable llvm::FoldingSet<SubstTemplateTypeParmType>
SubstTemplateTypeParmTypes;
mutable llvm::FoldingSet<SubstTemplateTypeParmPackType>
@ -312,13 +347,24 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// definitions of that entity.
llvm::DenseMap<NamedDecl*, llvm::TinyPtrVector<Module*>> MergedDefModules;
/// \brief Initializers for a module, in order. Each Decl will be either
/// something that has a semantic effect on startup (such as a variable with
/// a non-constant initializer), or an ImportDecl (which recursively triggers
/// initialization of another module).
struct PerModuleInitializers {
llvm::SmallVector<Decl*, 4> Initializers;
llvm::SmallVector<uint32_t, 4> LazyInitializers;
void resolve(ASTContext &Ctx);
};
llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers;
public:
/// \brief A type synonym for the TemplateOrInstantiation mapping.
typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
TemplateOrSpecializationInfo;
private:
/// \brief A mapping to contain the template or declaration that
/// a variable declaration describes or was instantiated from,
/// respectively.
@ -352,11 +398,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>
TemplateOrInstantiation;
/// \brief Keeps track of the declaration from which a UsingDecl was
/// \brief Keeps track of the declaration from which a using declaration was
/// created during instantiation.
///
/// The source declaration is always a UsingDecl, an UnresolvedUsingValueDecl,
/// or an UnresolvedUsingTypenameDecl.
/// The source and target declarations are always a UsingDecl, an
/// UnresolvedUsingValueDecl, or an UnresolvedUsingTypenameDecl.
///
/// For example:
/// \code
@ -375,7 +421,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
///
/// This mapping will contain an entry that maps from the UsingDecl in
/// B<int> to the UnresolvedUsingDecl in B<T>.
llvm::DenseMap<UsingDecl *, NamedDecl *> InstantiatedFromUsingDecl;
llvm::DenseMap<NamedDecl *, NamedDecl *> InstantiatedFromUsingDecl;
llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>
InstantiatedFromUsingShadowDecl;
@ -394,7 +440,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Mapping from each declaration context to its corresponding
/// mangling numbering context (used for constructs like lambdas which
/// need to be consistently numbered for the mangler).
llvm::DenseMap<const DeclContext *, MangleNumberingContext *>
llvm::DenseMap<const DeclContext *, std::unique_ptr<MangleNumberingContext>>
MangleNumberingContexts;
/// \brief Side-table of mangling numbers for declarations which rarely
@ -514,6 +560,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
size_t size() const { return end() - begin(); }
bool empty() const { return begin() == end(); }
const DynTypedNode &operator[](size_t N) const {
assert(N < size() && "Out of bounds!");
return *(begin() + N);
@ -569,7 +616,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
return BumpAlloc.Allocate(Size, Align);
}
template <typename T> T *Allocate(size_t Num = 1) const {
return static_cast<T *>(Allocate(Num * sizeof(T), llvm::alignOf<T>()));
return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
}
void Deallocate(void *Ptr) const { }
@ -802,11 +849,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief If the given using decl \p Inst is an instantiation of a
/// (possibly unresolved) using decl from a template instantiation,
/// return it.
NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst);
NamedDecl *getInstantiatedFromUsingDecl(NamedDecl *Inst);
/// \brief Remember that the using decl \p Inst is an instantiation
/// of the using decl \p Pattern of a class template.
void setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern);
void setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern);
void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
UsingShadowDecl *Pattern);
@ -883,6 +930,17 @@ class ASTContext : public RefCountedBase<ASTContext> {
return MergedIt->second;
}
/// Add a declaration to the list of declarations that are initialized
/// for a module. This will typically be a global variable (with internal
/// linkage) that runs module initializers, such as the iostream initializer,
/// or an ImportDecl nominating another module that has initializers.
void addModuleInitializer(Module *M, Decl *Init);
void addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs);
/// Get the initializations to perform when importing a module, if any.
ArrayRef<Decl*> getModuleInitializers(Module *M);
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
ExternCContextDecl *getExternCContextDecl() const;
@ -928,7 +986,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
SelectorTable &sels, Builtin::Context &builtins);
ASTContext(const ASTContext &) = delete;
ASTContext &operator=(const ASTContext &) = delete;
~ASTContext();
/// \brief Attach an external AST source to the AST context.
@ -987,6 +1046,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const;
QualType getPipeType(QualType T, bool ReadOnly) const;
public:
/// \brief Return the uniqued reference to the type for an address space
/// qualified type with the specified type and address space.
@ -996,6 +1057,14 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// replaced.
QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const;
/// \brief Apply Objective-C protocol qualifiers to the given type.
/// \param allowOnPointerType specifies if we can apply protocol
/// qualifiers on ObjCObjectPointerType. It can be set to true when
/// contructing the canonical type of a Objective-C type parameter.
QualType applyObjCProtocolQualifiers(QualType type,
ArrayRef<ObjCProtocolDecl *> protocols, bool &hasError,
bool allowOnPointerType = false) const;
/// \brief Return the uniqued reference to the type for an Objective-C
/// gc-qualified type.
///
@ -1040,6 +1109,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Change the result type of a function type once it is deduced.
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
/// \brief Determine whether two function types are the same, ignoring
/// exception specifications in cases where they're part of the type.
bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U);
/// \brief Change the exception specification on a function once it is
/// delay-parsed, instantiated, or computed.
void adjustExceptionSpec(FunctionDecl *FD,
@ -1088,8 +1161,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// blocks.
QualType getBlockDescriptorType() const;
/// \brief Return pipe type for the specified type.
QualType getPipeType(QualType T) const;
/// \brief Return a read_only pipe type for the specified type.
QualType getReadPipeType(QualType T) const;
/// \brief Return a write_only pipe type for the specified type.
QualType getWritePipeType(QualType T) const;
/// Gets the struct used to keep track of the extended descriptor for
/// pointer to blocks.
@ -1192,8 +1267,17 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Return a normal function type with a typed argument list.
QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args,
const FunctionProtoType::ExtProtoInfo &EPI) const;
const FunctionProtoType::ExtProtoInfo &EPI) const {
return getFunctionTypeInternal(ResultTy, Args, EPI, false);
}
private:
/// \brief Return a normal function type with a typed argument list.
QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
const FunctionProtoType::ExtProtoInfo &EPI,
bool OnlyWantCanonical) const;
public:
/// \brief Return the unique reference to the type for the specified type
/// declaration.
QualType getTypeDeclType(const TypeDecl *Decl,
@ -1271,6 +1355,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;
/// Get a template argument list with one argument per template parameter
/// in a template parameter list, such as for the injected class name of
/// a class template.
void getInjectedTemplateArgs(const TemplateParameterList *Params,
SmallVectorImpl<TemplateArgument> &Args);
QualType getPackExpansionType(QualType Pattern,
Optional<unsigned> NumExpansions);
@ -1286,6 +1376,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
ArrayRef<QualType> typeArgs,
ArrayRef<ObjCProtocolDecl *> protocols,
bool isKindOf) const;
QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
ArrayRef<ObjCProtocolDecl *> protocols,
QualType Canonical = QualType()) const;
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
@ -1440,7 +1534,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
return getObjCSelType();
return ObjCSelRedefinitionType;
}
/// \brief Set the user-written type that redefines 'SEL'.
void setObjCSelRedefinitionType(QualType RedefType) {
@ -1569,16 +1662,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
///
/// \returns true if an error occurred (e.g., because one of the parameter
/// types is incomplete), false otherwise.
bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S);
std::string getObjCEncodingForFunctionDecl(const FunctionDecl *Decl) const;
/// \brief Emit the encoded type for the method declaration \p Decl into
/// \p S.
///
/// \returns true if an error occurred (e.g., because one of the parameter
/// types is incomplete), false otherwise.
bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S,
bool Extended = false)
const;
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
bool Extended = false) const;
/// \brief Return the encoded type for this block declaration.
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const;
@ -1587,9 +1676,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// this method declaration. If non-NULL, Container must be either
/// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
/// only be NULL when getting encodings for protocol properties.
void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
const Decl *Container,
std::string &S) const;
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
const Decl *Container) const;
bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
ObjCProtocolDecl *rProto) const;
@ -1834,6 +1922,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; }
unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).Align; }
/// \brief Return the ABI-specified alignment of a type, in bits, or 0 if
/// the type is incomplete and we cannot determine the alignment (for
/// example, from alignment attributes).
unsigned getTypeAlignIfKnown(QualType T) const;
/// \brief Return the ABI-specified alignment of a (complete) type \p T, in
/// characters.
CharUnits getTypeAlignInChars(QualType T) const;
@ -1860,7 +1953,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief Return the default alignment for __attribute__((aligned)) on
/// this target, to be used if no alignment value is specified.
unsigned getTargetDefaultAlignForAttributeAligned(void) const;
unsigned getTargetDefaultAlignForAttributeAligned() const;
/// \brief Return the alignment in bits that should be given to a
/// global variable with type \p T.
@ -2212,6 +2305,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
return (*AddrSpaceMap)[AS - LangAS::Offset];
}
/// Get target-dependent integer value for null pointer which is used for
/// constant folding.
uint64_t getTargetNullPointerValue(QualType QT) const;
bool addressSpaceMapManglingFor(unsigned AS) const {
return AddrSpaceMapMangling ||
AS < LangAS::Offset ||
@ -2223,7 +2320,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
unsigned getIntegerRank(const Type *T) const;
public:
//===--------------------------------------------------------------------===//
// Type Compatibility Predicates
//===--------------------------------------------------------------------===//
@ -2399,12 +2495,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
CXXConstructorDecl *CD);
void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
unsigned ParmIdx, Expr *DAE);
Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
unsigned ParmIdx);
void addTypedefNameForUnnamedTagDecl(TagDecl *TD, TypedefNameDecl *TND);
TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD);
@ -2423,7 +2513,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// DeclContext.
MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
MangleNumberingContext *createMangleNumberingContext() const;
std::unique_ptr<MangleNumberingContext> createMangleNumberingContext() const;
/// \brief Used by ParmVarDecl to store on the side the
/// index of the parameter when it exceeds the size of the normal bitfield.
@ -2484,10 +2574,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// declarations were built.
static unsigned NumImplicitDestructorsDeclared;
private:
ASTContext(const ASTContext &) = delete;
void operator=(const ASTContext &) = delete;
public:
/// \brief Initialize built-in types.
///
@ -2567,6 +2653,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
friend class DeclContext;
friend class DeclarationNameTable;
void ReleaseDeclContextMaps();
void ReleaseParentMapEntries();
@ -2589,7 +2676,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
DeclaratorDecl *Decl;
SourceLocation PragmaSectionLocation;
int SectionFlags;
SectionInfo() {}
SectionInfo() = default;
SectionInfo(DeclaratorDecl *Decl,
SourceLocation PragmaSectionLocation,
int SectionFlags)
@ -2711,4 +2799,4 @@ typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
return Value;
}
#endif
#endif // LLVM_CLANG_AST_ASTCONTEXT_H

View File

@ -24,6 +24,7 @@
namespace clang {
class ASTContext;
class CXXCtorInitializer;
class CXXBaseSpecifier;
class Decl;
class DeclContext;
class DiagnosticsEngine;
@ -39,7 +40,9 @@ namespace clang {
class ASTImporter {
public:
typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
typedef llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>
ImportedCXXBaseSpecifierMap;
private:
/// \brief The contexts we're importing to and from.
ASTContext &ToContext, &FromContext;
@ -68,7 +71,12 @@ namespace clang {
/// \brief Mapping from the already-imported FileIDs in the "from" source
/// manager to the corresponding FileIDs in the "to" source manager.
llvm::DenseMap<FileID, FileID> ImportedFileIDs;
/// \brief Mapping from the already-imported CXXBasesSpecifier in
/// the "from" source manager to the corresponding CXXBasesSpecifier
/// in the "to" source manager.
ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers;
/// \brief Imported, anonymous tag declarations that are missing their
/// corresponding typedefs.
SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
@ -212,8 +220,13 @@ namespace clang {
/// \returns the equivalent initializer in the "to" context.
CXXCtorInitializer *Import(CXXCtorInitializer *FromInit);
/// \brief Import the given CXXBaseSpecifier from the "from" context into
/// the "to" context.
///
/// \returns the equivalent CXXBaseSpecifier in the source manager of the
/// "to" context.
CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec);
/// \brief Import the definition of the given declaration, including all of
/// the declarations it contains.
///

View File

@ -22,6 +22,7 @@ namespace clang {
class CXXRecordDecl;
class Decl;
class DeclContext;
class FieldDecl;
class FunctionDecl;
class FunctionTemplateDecl;
class Module;
@ -93,6 +94,9 @@ class ASTMutationListener {
/// \brief A default argument was instantiated.
virtual void DefaultArgumentInstantiated(const ParmVarDecl *D) {}
/// \brief A default member initializer was instantiated.
virtual void DefaultMemberInitializerInstantiated(const FieldDecl *D) {}
/// \brief A new objc category class was added for an interface.
virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) {}

View File

@ -121,6 +121,7 @@ class ASTNodeKind {
enum NodeKindId {
NKI_None,
NKI_TemplateArgument,
NKI_TemplateName,
NKI_NestedNameSpecifierLoc,
NKI_QualType,
NKI_TypeLoc,
@ -175,6 +176,7 @@ class ASTNodeKind {
};
KIND_TO_KIND_ID(CXXCtorInitializer)
KIND_TO_KIND_ID(TemplateArgument)
KIND_TO_KIND_ID(TemplateName)
KIND_TO_KIND_ID(NestedNameSpecifier)
KIND_TO_KIND_ID(NestedNameSpecifierLoc)
KIND_TO_KIND_ID(QualType)
@ -470,6 +472,10 @@ template <>
struct DynTypedNode::BaseConverter<
TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
template <>
struct DynTypedNode::BaseConverter<
TemplateName, void> : public ValueConverter<TemplateName> {};
template <>
struct DynTypedNode::BaseConverter<
NestedNameSpecifierLoc,

View File

@ -20,7 +20,6 @@
#include "clang/AST/AttrIterator.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cstring>
@ -381,7 +380,7 @@ void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) {
NewCapacity = MinSize;
// Allocate the memory from the ASTContext.
T *NewElts = new (C, llvm::alignOf<T>()) T[NewCapacity];
T *NewElts = new (C, alignof(T)) T[NewCapacity];
// Copy the elements over.
if (Begin != End) {

View File

@ -24,8 +24,6 @@
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
@ -57,21 +55,20 @@ class Attr {
unsigned IsLateParsed : 1;
unsigned DuplicatesAllowed : 1;
void *operator new(size_t bytes) LLVM_NOEXCEPT {
void *operator new(size_t bytes) noexcept {
llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
}
void operator delete(void *data) LLVM_NOEXCEPT {
void operator delete(void *data) noexcept {
llvm_unreachable("Attrs cannot be released with regular 'delete'.");
}
public:
// Forward so that the regular new and delete do not hide global ones.
void *operator new(size_t Bytes, ASTContext &C,
size_t Alignment = 8) LLVM_NOEXCEPT {
size_t Alignment = 8) noexcept {
return ::operator new(Bytes, C, Alignment);
}
void operator delete(void *Ptr, ASTContext &C,
size_t Alignment) LLVM_NOEXCEPT {
void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
return ::operator delete(Ptr, C, Alignment);
}

View File

@ -39,8 +39,7 @@ void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
namespace clang {
/// AttrVec - A vector of Attr, which is how they are stored on the AST.
typedef SmallVector<Attr*, 2> AttrVec;
typedef SmallVector<const Attr*, 2> ConstAttrVec;
typedef SmallVector<Attr *, 4> AttrVec;
/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
/// providing attributes that are of a specific type.

View File

@ -16,7 +16,6 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
#include "llvm/ADT/MapVector.h"
@ -24,7 +23,6 @@
#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <list>
#include <map>
namespace clang {
@ -174,7 +172,7 @@ class CXXBasePaths {
/// paths for a derived-to-base search.
explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
bool DetectVirtual = true)
: FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
: Origin(), FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
NumDeclsFound(0) {}

View File

@ -630,8 +630,8 @@ CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
template<typename T>
template<typename U>
CanProxy<U> CanQual<T>::getAs() const {
ArrayType_cannot_be_used_with_getAs<U> at;
(void)at;
static_assert(!TypeIsArrayType<T>::value,
"ArrayType cannot be used with getAs!");
if (Stored.isNull())
return CanProxy<U>();
@ -645,8 +645,8 @@ CanProxy<U> CanQual<T>::getAs() const {
template<typename T>
template<typename U>
CanProxy<U> CanQual<T>::castAs() const {
ArrayType_cannot_be_used_with_getAs<U> at;
(void)at;
static_assert(!TypeIsArrayType<U>::value,
"ArrayType cannot be used with castAs!");
assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
return CanQual<U>::CreateUnsafe(Stored);

View File

@ -17,7 +17,6 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/raw_ostream.h"

View File

@ -251,7 +251,7 @@ class NamedDecl : public Decl {
// FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const { return Name.getAsString(); }
void printName(raw_ostream &os) const { os << Name; }
virtual void printName(raw_ostream &os) const;
/// getDeclName - Get the actual, stored name of the declaration,
/// which may be a special name.
@ -789,7 +789,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
protected:
// A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we
// have allocated the auxilliary struct of information there.
// have allocated the auxiliary struct of information there.
//
// TODO: It is a bit unfortunate to use a PointerUnion inside the VarDecl for
// this as *many* VarDecls are ParmVarDecls that don't have default
@ -865,6 +865,11 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
unsigned : NumVarDeclBits;
// FIXME: We need something similar to CXXRecordDecl::DefinitionData.
/// \brief Whether this variable is a definition which was demoted due to
/// module merge.
unsigned IsThisDeclarationADemotedDefinition : 1;
/// \brief Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
unsigned ExceptionVar : 1;
@ -1025,7 +1030,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// void foo() { int x; static int y; extern int z; }
///
bool isLocalVarDecl() const {
if (getKind() != Decl::Var)
if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
return false;
if (const DeclContext *DC = getLexicalDeclContext())
return DC->getRedeclContext()->isFunctionOrMethod();
@ -1040,7 +1045,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but
/// excludes variables declared in blocks.
bool isFunctionOrMethodVarDecl() const {
if (getKind() != Decl::Var)
if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
return false;
const DeclContext *DC = getLexicalDeclContext()->getRedeclContext();
return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
@ -1198,12 +1203,28 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
InitializationStyle getInitStyle() const {
return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
}
/// \brief Whether the initializer is a direct-initializer (list or call).
bool isDirectInit() const {
return getInitStyle() != CInit;
}
/// \brief If this definition should pretend to be a declaration.
bool isThisDeclarationADemotedDefinition() const {
return isa<ParmVarDecl>(this) ? false :
NonParmVarDeclBits.IsThisDeclarationADemotedDefinition;
}
/// \brief This is a definition which should be demoted to a declaration.
///
/// In some cases (mostly module merging) we can end up with two visible
/// definitions one of which needs to be demoted to a declaration to keep
/// the AST invariants.
void demoteThisDefinitionToDeclaration() {
assert (isThisDeclarationADefinition() && "Not a definition!");
assert (!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!");
NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1;
}
/// \brief Determine whether this variable is the exception variable in a
/// C++ catch statememt or an Objective-C \@catch statement.
bool isExceptionVariable() const {
@ -1302,6 +1323,10 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same;
}
/// \brief Retrieve the variable declaration from which this variable could
/// be instantiated, if it is an instantiation (rather than a non-template).
VarDecl *getTemplateInstantiationPattern() const;
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
@ -1576,11 +1601,6 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
/// no formals.
ParmVarDecl **ParamInfo;
/// DeclsInPrototypeScope - Array of pointers to NamedDecls for
/// decls defined in the function prototype that are not parameters. E.g.
/// 'enum Y' in 'void f(enum Y {AA} x) {}'.
ArrayRef<NamedDecl *> DeclsInPrototypeScope;
LazyDeclStmtPtr Body;
// FIXME: This can be packed into the bitfields in DeclContext.
@ -1607,6 +1627,11 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
/// skipped.
unsigned HasSkippedBody : 1;
/// Indicates if the function declaration will have a body, once we're done
/// parsing it. (We don't set it to false when we're done parsing, in the
/// hopes this is simpler.)
unsigned WillHaveBody : 1;
/// \brief End part of this FunctionDecl's source range.
///
/// We could compute the full range in getSourceRange(). However, when we're
@ -1676,25 +1701,21 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
protected:
FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, bool isInlineSpecified,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified,
bool isConstexprSpecified)
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
StartLoc),
DeclContext(DK),
redeclarable_base(C),
ParamInfo(nullptr), Body(),
SClass(S),
IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
IsDefaulted(false), IsExplicitlyDefaulted(false),
HasImplicitReturnZero(false), IsLateTemplateParsed(false),
IsConstexpr(isConstexprSpecified), UsesSEHTry(false),
HasSkippedBody(false), EndRangeLoc(NameInfo.getEndLoc()),
TemplateOrSpecialization(),
DNLoc(NameInfo.getInfo()) {}
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
StartLoc),
DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(),
SClass(S), IsInline(isInlineSpecified),
IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false),
IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true),
IsDeleted(false), IsTrivial(false), IsDefaulted(false),
IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
UsesSEHTry(false), HasSkippedBody(false), WillHaveBody(false),
EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(),
DNLoc(NameInfo.getInfo()) {}
typedef Redeclarable<FunctionDecl> redeclarable_base;
FunctionDecl *getNextRedeclarationImpl() override {
@ -1976,6 +1997,10 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
bool hasSkippedBody() const { return HasSkippedBody; }
void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
/// True if this function will eventually have a body, once it's fully parsed.
bool willHaveBody() const { return WillHaveBody; }
void setWillHaveBody(bool V = true) { WillHaveBody = V; }
void setPreviousDeclaration(FunctionDecl * PrevDecl);
FunctionDecl *getCanonicalDecl() override;
@ -2020,11 +2045,6 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
setParams(getASTContext(), NewParamInfo);
}
ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const {
return DeclsInPrototypeScope;
}
void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls);
/// getMinRequiredArguments - Returns the minimum number of arguments
/// needed to call this function. This may be fewer than the number of
/// function parameters, if some of the parameters have default
@ -3784,6 +3804,55 @@ class ImportDecl final : public Decl,
static bool classofKind(Kind K) { return K == Import; }
};
/// \brief Represents a C++ Modules TS module export declaration.
///
/// For example:
/// \code
/// export void foo();
/// \endcode
class ExportDecl final : public Decl, public DeclContext {
virtual void anchor();
private:
/// \brief The source location for the right brace (if valid).
SourceLocation RBraceLoc;
ExportDecl(DeclContext *DC, SourceLocation ExportLoc)
: Decl(Export, DC, ExportLoc), DeclContext(Export),
RBraceLoc(SourceLocation()) { }
friend class ASTDeclReader;
public:
static ExportDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation ExportLoc);
static ExportDecl *CreateDeserialized(ASTContext &C, unsigned ID);
SourceLocation getExportLoc() const { return getLocation(); }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
SourceLocation getLocEnd() const LLVM_READONLY {
if (RBraceLoc.isValid())
return RBraceLoc;
// No braces: get the end location of the (only) declaration in context
// (if present).
return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
}
SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getLocation(), getLocEnd());
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Export; }
static DeclContext *castToDeclContext(const ExportDecl *D) {
return static_cast<DeclContext *>(const_cast<ExportDecl*>(D));
}
static ExportDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<ExportDecl *>(const_cast<DeclContext*>(DC));
}
};
/// \brief Represents an empty-declaration.
class EmptyDecl : public Decl {
virtual void anchor();

View File

@ -17,6 +17,7 @@
#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
@ -32,6 +33,7 @@ class DeclContext;
class DeclarationName;
class DependentDiagnostic;
class EnumDecl;
class ExportDecl;
class FunctionDecl;
class FunctionType;
enum Linkage : unsigned char;
@ -566,6 +568,10 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
return NextInContextAndBits.getInt() & ModulePrivateFlag;
}
/// \brief Whether this declaration is exported (by virtue of being lexically
/// within an ExportDecl or by being a NamespaceDecl).
bool isExported() const;
/// Return true if this declaration has an attribute which acts as
/// definition of the entity, such as 'alias' or 'ifunc'.
bool hasDefiningAttr() const;
@ -603,7 +609,12 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
/// AR_Available, will be set to a (possibly empty) message
/// describing why the declaration has not been introduced, is
/// deprecated, or is unavailable.
AvailabilityResult getAvailability(std::string *Message = nullptr) const;
///
/// \param EnclosingVersion The version to compare with. If empty, assume the
/// deployment target version.
AvailabilityResult
getAvailability(std::string *Message = nullptr,
VersionTuple EnclosingVersion = VersionTuple()) const;
/// \brief Determine whether this declaration is marked 'deprecated'.
///
@ -1129,6 +1140,7 @@ class DeclContextLookupResult {
/// ObjCMethodDecl
/// ObjCContainerDecl
/// LinkageSpecDecl
/// ExportDecl
/// BlockDecl
/// OMPDeclareReductionDecl
///
@ -1273,7 +1285,8 @@ class DeclContext {
/// \brief Test whether the context supports looking up names.
bool isLookupContext() const {
return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec;
return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec &&
DeclKind != Decl::Export;
}
bool isFileContext() const {
@ -1321,6 +1334,9 @@ class DeclContext {
/// linkage specification context that specifies C linkage.
bool isExternCContext() const;
/// \brief Retrieve the nearest enclosing C linkage specification context.
const LinkageSpecDecl *getExternCContext() const;
/// \brief Determines whether this context or some of its ancestors is a
/// linkage specification context that specifies C++ linkage.
bool isExternCXXContext() const;

View File

@ -139,7 +139,6 @@ class AccessSpecDecl : public Decl {
static bool classofKind(Kind K) { return K == AccessSpec; }
};
/// \brief Represents a base class of a C++ class.
///
/// Each CXXBaseSpecifier represents a single, direct base class (or
@ -536,11 +535,10 @@ class CXXRecordDecl : public RecordDecl {
MethodTyInfo(Info) {
IsLambda = true;
// C++11 [expr.prim.lambda]p3:
// This class type is neither an aggregate nor a literal type.
// C++1z [expr.prim.lambda]p4:
// This class type is not an aggregate type.
Aggregate = false;
PlainOldData = false;
HasNonLiteralTypeFieldsOrBases = true;
}
/// \brief Whether this lambda is known to be dependent, even if its
@ -573,7 +571,7 @@ class CXXRecordDecl : public RecordDecl {
/// actual DeclContext does not suffice. This is used for lambdas that
/// occur within default arguments of function parameters within the class
/// or within a data member initializer.
Decl *ContextDecl;
LazyDeclPtr ContextDecl;
/// \brief The list of captures, both explicit and implicit, for this
/// lambda.
@ -995,7 +993,11 @@ class CXXRecordDecl : public RecordDecl {
!hasUserDeclaredCopyConstructor() &&
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveConstructor() &&
!hasUserDeclaredDestructor();
!hasUserDeclaredDestructor() &&
// C++1z [expr.prim.lambda]p21: "the closure type has a deleted copy
// assignment operator". The intent is that this counts as a user
// declared copy assignment, but we do not model it that way.
!isLambda();
}
/// \brief Determine whether we need to eagerly declare a move assignment
@ -1149,6 +1151,12 @@ class CXXRecordDecl : public RecordDecl {
/// \note This does NOT include a check for union-ness.
bool isEmpty() const { return data().Empty; }
/// \brief Determine whether this class has direct non-static data members.
bool hasDirectFields() const {
auto &D = data();
return D.HasPublicFields || D.HasProtectedFields || D.HasPrivateFields;
}
/// Whether this class is polymorphic (C++ [class.virtual]),
/// which means that the class contains or inherits a virtual function.
bool isPolymorphic() const { return data().Polymorphic; }
@ -1339,11 +1347,15 @@ class CXXRecordDecl : public RecordDecl {
///
/// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
/// treating types with trivial default constructors as literal types.
///
/// Only in C++1z and beyond, are lambdas literal types.
bool isLiteral() const {
return hasTrivialDestructor() &&
(isAggregate() || hasConstexprNonCopyMoveConstructor() ||
hasTrivialDefaultConstructor()) &&
!hasNonLiteralTypeFieldsOrBases();
(!isLambda() || getASTContext().getLangOpts().CPlusPlus1z) &&
!hasNonLiteralTypeFieldsOrBases() &&
(isAggregate() || isLambda() ||
hasConstexprNonCopyMoveConstructor() ||
hasTrivialDefaultConstructor());
}
/// \brief If this record is an instantiation of a member class,
@ -1665,10 +1677,7 @@ class CXXRecordDecl : public RecordDecl {
/// the declaration in which the lambda occurs, e.g., the function parameter
/// or the non-static data member. Otherwise, it returns NULL to imply that
/// the declaration context suffices.
Decl *getLambdaContextDecl() const {
assert(isLambda() && "Not a lambda closure type!");
return getLambdaData().ContextDecl;
}
Decl *getLambdaContextDecl() const;
/// \brief Set the mangling number and context declaration for a lambda
/// class.
@ -1919,8 +1928,7 @@ class CXXMethodDecl : public FunctionDecl {
/// B(A& a) : A(a), f(3.14159) { }
/// };
/// \endcode
class CXXCtorInitializer final
: private llvm::TrailingObjects<CXXCtorInitializer, VarDecl *> {
class CXXCtorInitializer final {
/// \brief Either the base class name/delegating constructor type (stored as
/// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
/// (IndirectFieldDecl*) being initialized.
@ -1958,14 +1966,8 @@ class CXXCtorInitializer final
unsigned IsWritten : 1;
/// If IsWritten is true, then this number keeps track of the textual order
/// of this initializer in the original sources, counting from 0; otherwise,
/// it stores the number of array index variables stored after this object
/// in memory.
unsigned SourceOrderOrNumArrayIndices : 13;
CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
SourceLocation MemberLoc, SourceLocation L, Expr *Init,
SourceLocation R, VarDecl **Indices, unsigned NumIndices);
/// of this initializer in the original sources, counting from 0.
unsigned SourceOrder : 13;
public:
/// \brief Creates a new base-class initializer.
@ -1991,13 +1993,6 @@ class CXXCtorInitializer final
CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
SourceLocation L, Expr *Init, SourceLocation R);
/// \brief Creates a new member initializer that optionally contains
/// array indices used to describe an elementwise initialization.
static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
SourceLocation MemberLoc, SourceLocation L,
Expr *Init, SourceLocation R,
VarDecl **Indices, unsigned NumIndices);
/// \brief Determine whether this initializer is initializing a base class.
bool isBaseInitializer() const {
return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
@ -2102,7 +2097,7 @@ class CXXCtorInitializer final
/// \brief Return the source position of the initializer, counting from 0.
/// If the initializer was implicit, -1 is returned.
int getSourceOrder() const {
return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
return IsWritten ? static_cast<int>(SourceOrder) : -1;
}
/// \brief Set the source order of this initializer.
@ -2112,49 +2107,22 @@ class CXXCtorInitializer final
///
/// This assumes that the initializer was written in the source code, and
/// ensures that isWritten() returns true.
void setSourceOrder(int pos) {
void setSourceOrder(int Pos) {
assert(!IsWritten &&
"setSourceOrder() used on implicit initializer");
assert(SourceOrder == 0 &&
"calling twice setSourceOrder() on the same initializer");
assert(SourceOrderOrNumArrayIndices == 0 &&
"setSourceOrder() used when there are implicit array indices");
assert(pos >= 0 &&
assert(Pos >= 0 &&
"setSourceOrder() used to make an initializer implicit");
IsWritten = true;
SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
SourceOrder = static_cast<unsigned>(Pos);
}
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
/// \brief Determine the number of implicit array indices used while
/// described an array member initialization.
unsigned getNumArrayIndices() const {
return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
}
/// \brief Retrieve a particular array index variable used to
/// describe an array member initialization.
VarDecl *getArrayIndex(unsigned I) {
assert(I < getNumArrayIndices() && "Out of bounds member array index");
return getTrailingObjects<VarDecl *>()[I];
}
const VarDecl *getArrayIndex(unsigned I) const {
assert(I < getNumArrayIndices() && "Out of bounds member array index");
return getTrailingObjects<VarDecl *>()[I];
}
void setArrayIndex(unsigned I, VarDecl *Index) {
assert(I < getNumArrayIndices() && "Out of bounds member array index");
getTrailingObjects<VarDecl *>()[I] = Index;
}
ArrayRef<VarDecl *> getArrayIndices() {
return llvm::makeArrayRef(getTrailingObjects<VarDecl *>(),
getNumArrayIndices());
}
/// \brief Get the initializer.
Expr *getInit() const { return static_cast<Expr*>(Init); }
friend TrailingObjects;
};
/// Description of a constructor that was inherited from a base class.
@ -2952,11 +2920,10 @@ class ConstructorUsingShadowDecl final : public UsingShadowDecl {
dyn_cast<ConstructorUsingShadowDecl>(Target)),
ConstructedBaseClassShadowDecl(NominatedBaseClassShadowDecl),
IsVirtual(TargetInVirtualBase) {
// If we found a constructor for a non-virtual base class, but it chains to
// a constructor for a virtual base, we should directly call the virtual
// base constructor instead.
// If we found a constructor that chains to a constructor for a virtual
// base, we should directly call that virtual base constructor instead.
// FIXME: This logic belongs in Sema.
if (!TargetInVirtualBase && NominatedBaseClassShadowDecl &&
if (NominatedBaseClassShadowDecl &&
NominatedBaseClassShadowDecl->constructsVirtualBase()) {
ConstructedBaseClassShadowDecl =
NominatedBaseClassShadowDecl->ConstructedBaseClassShadowDecl;
@ -2964,7 +2931,9 @@ class ConstructorUsingShadowDecl final : public UsingShadowDecl {
}
}
ConstructorUsingShadowDecl(ASTContext &C, EmptyShell Empty)
: UsingShadowDecl(ConstructorUsingShadow, C, Empty) {}
: UsingShadowDecl(ConstructorUsingShadow, C, Empty),
NominatedBaseClassShadowDecl(), ConstructedBaseClassShadowDecl(),
IsVirtual(false) {}
public:
static ConstructorUsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
@ -3171,6 +3140,77 @@ class UsingDecl : public NamedDecl, public Mergeable<UsingDecl> {
friend class ASTDeclWriter;
};
/// Represents a pack of using declarations that a single
/// using-declarator pack-expanded into.
///
/// \code
/// template<typename ...T> struct X : T... {
/// using T::operator()...;
/// using T::operator T...;
/// };
/// \endcode
///
/// In the second case above, the UsingPackDecl will have the name
/// 'operator T' (which contains an unexpanded pack), but the individual
/// UsingDecls and UsingShadowDecls will have more reasonable names.
class UsingPackDecl final
: public NamedDecl, public Mergeable<UsingPackDecl>,
private llvm::TrailingObjects<UsingPackDecl, NamedDecl *> {
void anchor() override;
/// The UnresolvedUsingValueDecl or UnresolvedUsingTypenameDecl from
/// which this waas instantiated.
NamedDecl *InstantiatedFrom;
/// The number of using-declarations created by this pack expansion.
unsigned NumExpansions;
UsingPackDecl(DeclContext *DC, NamedDecl *InstantiatedFrom,
ArrayRef<NamedDecl *> UsingDecls)
: NamedDecl(UsingPack, DC,
InstantiatedFrom ? InstantiatedFrom->getLocation()
: SourceLocation(),
InstantiatedFrom ? InstantiatedFrom->getDeclName()
: DeclarationName()),
InstantiatedFrom(InstantiatedFrom), NumExpansions(UsingDecls.size()) {
std::uninitialized_copy(UsingDecls.begin(), UsingDecls.end(),
getTrailingObjects<NamedDecl *>());
}
public:
/// Get the using declaration from which this was instantiated. This will
/// always be an UnresolvedUsingValueDecl or an UnresolvedUsingTypenameDecl
/// that is a pack expansion.
NamedDecl *getInstantiatedFromUsingDecl() { return InstantiatedFrom; }
/// Get the set of using declarations that this pack expanded into. Note that
/// some of these may still be unresolved.
ArrayRef<NamedDecl *> expansions() const {
return llvm::makeArrayRef(getTrailingObjects<NamedDecl *>(), NumExpansions);
}
static UsingPackDecl *Create(ASTContext &C, DeclContext *DC,
NamedDecl *InstantiatedFrom,
ArrayRef<NamedDecl *> UsingDecls);
static UsingPackDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumExpansions);
SourceRange getSourceRange() const override LLVM_READONLY {
return InstantiatedFrom->getSourceRange();
}
UsingPackDecl *getCanonicalDecl() override { return getFirstDecl(); }
const UsingPackDecl *getCanonicalDecl() const { return getFirstDecl(); }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UsingPack; }
friend class ASTDeclReader;
friend class ASTDeclWriter;
friend TrailingObjects;
};
/// \brief Represents a dependent using declaration which was not marked with
/// \c typename.
///
@ -3189,6 +3229,9 @@ class UnresolvedUsingValueDecl : public ValueDecl,
/// \brief The source location of the 'using' keyword
SourceLocation UsingLocation;
/// \brief If this is a pack expansion, the location of the '...'.
SourceLocation EllipsisLoc;
/// \brief The nested-name-specifier that precedes the name.
NestedNameSpecifierLoc QualifierLoc;
@ -3199,11 +3242,12 @@ class UnresolvedUsingValueDecl : public ValueDecl,
UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
SourceLocation UsingLoc,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo)
const DeclarationNameInfo &NameInfo,
SourceLocation EllipsisLoc)
: ValueDecl(UnresolvedUsingValue, DC,
NameInfo.getLoc(), NameInfo.getName(), Ty),
UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),
DNLoc(NameInfo.getInfo())
UsingLocation(UsingLoc), EllipsisLoc(EllipsisLoc),
QualifierLoc(QualifierLoc), DNLoc(NameInfo.getInfo())
{ }
public:
@ -3229,10 +3273,20 @@ class UnresolvedUsingValueDecl : public ValueDecl,
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
/// \brief Determine whether this is a pack expansion.
bool isPackExpansion() const {
return EllipsisLoc.isValid();
}
/// \brief Get the location of the ellipsis if this is a pack expansion.
SourceLocation getEllipsisLoc() const {
return EllipsisLoc;
}
static UnresolvedUsingValueDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo);
const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc);
static UnresolvedUsingValueDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
@ -3273,6 +3327,9 @@ class UnresolvedUsingTypenameDecl
/// \brief The source location of the 'typename' keyword
SourceLocation TypenameLocation;
/// \brief If this is a pack expansion, the location of the '...'.
SourceLocation EllipsisLoc;
/// \brief The nested-name-specifier that precedes the name.
NestedNameSpecifierLoc QualifierLoc;
@ -3280,10 +3337,12 @@ class UnresolvedUsingTypenameDecl
SourceLocation TypenameLoc,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TargetNameLoc,
IdentifierInfo *TargetName)
IdentifierInfo *TargetName,
SourceLocation EllipsisLoc)
: TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
UsingLoc),
TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }
TypenameLocation(TypenameLoc), EllipsisLoc(EllipsisLoc),
QualifierLoc(QualifierLoc) { }
friend class ASTDeclReader;
@ -3303,10 +3362,25 @@ class UnresolvedUsingTypenameDecl
return QualifierLoc.getNestedNameSpecifier();
}
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDeclName(), getLocation());
}
/// \brief Determine whether this is a pack expansion.
bool isPackExpansion() const {
return EllipsisLoc.isValid();
}
/// \brief Get the location of the ellipsis if this is a pack expansion.
SourceLocation getEllipsisLoc() const {
return EllipsisLoc;
}
static UnresolvedUsingTypenameDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TargetNameLoc, DeclarationName TargetName);
SourceLocation TargetNameLoc, DeclarationName TargetName,
SourceLocation EllipsisLoc);
static UnresolvedUsingTypenameDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
@ -3364,6 +3438,104 @@ class StaticAssertDecl : public Decl {
friend class ASTDeclReader;
};
/// A binding in a decomposition declaration. For instance, given:
///
/// int n[3];
/// auto &[a, b, c] = n;
///
/// a, b, and c are BindingDecls, whose bindings are the expressions
/// x[0], x[1], and x[2] respectively, where x is the implicit
/// DecompositionDecl of type 'int (&)[3]'.
class BindingDecl : public ValueDecl {
void anchor() override;
/// The binding represented by this declaration. References to this
/// declaration are effectively equivalent to this expression (except
/// that it is only evaluated once at the point of declaration of the
/// binding).
Expr *Binding;
BindingDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id)
: ValueDecl(Decl::Binding, DC, IdLoc, Id, QualType()), Binding(nullptr) {}
public:
static BindingDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc, IdentifierInfo *Id);
static BindingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// Get the expression to which this declaration is bound. This may be null
/// in two different cases: while parsing the initializer for the
/// decomposition declaration, and when the initializer is type-dependent.
Expr *getBinding() const { return Binding; }
/// Get the variable (if any) that holds the value of evaluating the binding.
/// Only present for user-defined bindings for tuple-like types.
VarDecl *getHoldingVar() const;
/// Set the binding for this BindingDecl, along with its declared type (which
/// should be a possibly-cv-qualified form of the type of the binding, or a
/// reference to such a type).
void setBinding(QualType DeclaredType, Expr *Binding) {
setType(DeclaredType);
this->Binding = Binding;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decl::Binding; }
friend class ASTDeclReader;
};
/// A decomposition declaration. For instance, given:
///
/// int n[3];
/// auto &[a, b, c] = n;
///
/// the second line declares a DecompositionDecl of type 'int (&)[3]', and
/// three BindingDecls (named a, b, and c). An instance of this class is always
/// unnamed, but behaves in almost all other respects like a VarDecl.
class DecompositionDecl final
: public VarDecl,
private llvm::TrailingObjects<DecompositionDecl, BindingDecl *> {
void anchor() override;
/// The number of BindingDecl*s following this object.
unsigned NumBindings;
DecompositionDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation LSquareLoc, QualType T,
TypeSourceInfo *TInfo, StorageClass SC,
ArrayRef<BindingDecl *> Bindings)
: VarDecl(Decomposition, C, DC, StartLoc, LSquareLoc, nullptr, T, TInfo,
SC),
NumBindings(Bindings.size()) {
std::uninitialized_copy(Bindings.begin(), Bindings.end(),
getTrailingObjects<BindingDecl *>());
}
public:
static DecompositionDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
SourceLocation LSquareLoc,
QualType T, TypeSourceInfo *TInfo,
StorageClass S,
ArrayRef<BindingDecl *> Bindings);
static DecompositionDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumBindings);
ArrayRef<BindingDecl *> bindings() const {
return llvm::makeArrayRef(getTrailingObjects<BindingDecl *>(), NumBindings);
}
void printName(raw_ostream &os) const override;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decomposition; }
friend TrailingObjects;
friend class ASTDeclReader;
};
/// An instance of this class represents the declaration of a property
/// member. This is a Microsoft extension to C++, first introduced in
/// Visual Studio .NET 2003 as a parallel to similar features in C#

View File

@ -82,6 +82,7 @@ class FriendDecl final
FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
: Decl(Decl::Friend, Empty), NextFriend(),
UnsupportedFriend(false),
NumTPLists(NumFriendTypeTPLists) { }
FriendDecl *getNextFriend() {
@ -166,6 +167,7 @@ class FriendDecl final
friend class ASTDeclReader;
friend class ASTDeclWriter;
friend class ASTNodeImporter;
friend TrailingObjects;
};

View File

@ -84,7 +84,7 @@ class DeclGroupRef {
bool isDeclGroup() const { return getKind() == DeclGroupKind; }
Decl *getSingleDecl() {
assert(isSingleDecl() && "Isn't a declgroup");
assert(isSingleDecl() && "Isn't a single decl");
return D;
}
const Decl *getSingleDecl() const {

View File

@ -394,7 +394,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
/// createImplicitParams - Used to lazily create the self and cmd
/// implict parameters. This must be called prior to using getSelfDecl()
/// or getCmdDecl(). The call is ignored if the implicit paramters
/// or getCmdDecl(). The call is ignored if the implicit parameters
/// have already been created.
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
@ -463,6 +463,9 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
ImplementationControl getImplementationControl() const {
return ImplementationControl(DeclImplementation);
}
bool isOptional() const {
return getImplementationControl() == Optional;
}
/// Returns true if this specific method declaration is marked with the
/// designated initializer attribute.
@ -870,6 +873,9 @@ class ObjCPropertyDecl : public NamedDecl {
PropertyControl getPropertyImplementation() const {
return PropertyControl(PropertyImplementation);
}
bool isOptional() const {
return getPropertyImplementation() == PropertyControl::Optional;
}
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
PropertyIvarDecl = Ivar;

View File

@ -173,18 +173,21 @@ class OMPCapturedExprDecl final : public VarDecl {
void anchor() override;
OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
QualType Type)
: VarDecl(OMPCapturedExpr, C, DC, SourceLocation(), SourceLocation(), Id,
Type, nullptr, SC_None) {
QualType Type, SourceLocation StartLoc)
: VarDecl(OMPCapturedExpr, C, DC, StartLoc, SourceLocation(), Id, Type,
nullptr, SC_None) {
setImplicit();
}
public:
static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id, QualType T);
IdentifierInfo *Id, QualType T,
SourceLocation StartLoc);
static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID);
SourceRange getSourceRange() const override LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == OMPCapturedExpr; }

View File

@ -21,7 +21,6 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
#include <limits>
#include <utility>
namespace clang {
@ -49,7 +48,8 @@ NamedDecl *getAsNamedDecl(TemplateParameter P);
/// \brief Stores a list of template parameters for a TemplateDecl and its
/// derived classes.
class TemplateParameterList final
: private llvm::TrailingObjects<TemplateParameterList, NamedDecl *> {
: private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
Expr *> {
/// The location of the 'template' keyword.
SourceLocation TemplateLoc;
@ -59,26 +59,35 @@ class TemplateParameterList final
/// The number of template parameters in this template
/// parameter list.
unsigned NumParams : 31;
unsigned NumParams : 30;
/// Whether this template parameter list contains an unexpanded parameter
/// pack.
unsigned ContainsUnexpandedParameterPack : 1;
/// Whether this template parameter list has an associated requires-clause
unsigned HasRequiresClause : 1;
protected:
size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
return NumParams;
}
size_t numTrailingObjects(OverloadToken<Expr *>) const {
return HasRequiresClause;
}
TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc);
ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc,
Expr *RequiresClause);
public:
static TemplateParameterList *Create(const ASTContext &C,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ArrayRef<NamedDecl *> Params,
SourceLocation RAngleLoc);
SourceLocation RAngleLoc,
Expr *RequiresClause);
/// \brief Iterates through the template parameters in this list.
typedef NamedDecl** iterator;
@ -130,6 +139,16 @@ class TemplateParameterList final
return ContainsUnexpandedParameterPack;
}
/// \brief The constraint-expression of the associated requires-clause.
Expr *getRequiresClause() {
return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
}
/// \brief The constraint-expression of the associated requires-clause.
const Expr *getRequiresClause() const {
return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
}
SourceLocation getTemplateLoc() const { return TemplateLoc; }
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
@ -139,36 +158,37 @@ class TemplateParameterList final
}
friend TrailingObjects;
template <size_t N> friend class FixedSizeTemplateParameterListStorage;
template <size_t N, bool HasRequiresClause>
friend class FixedSizeTemplateParameterListStorage;
public:
// FIXME: workaround for MSVC 2013; remove when no longer needed
using FixedSizeStorageOwner = TrailingObjects::FixedSizeStorageOwner;
};
/// \brief Stores a list of template parameters for a TemplateDecl and its
/// derived classes. Suitable for creating on the stack.
template <size_t N> class FixedSizeTemplateParameterListStorage {
// This is kinda ugly: TemplateParameterList usually gets allocated
// in a block of memory with NamedDecls appended to it. Here, to get
// it stack allocated, we include the params as a separate
// variable. After allocation, the TemplateParameterList object
// treats them as part of itself.
TemplateParameterList List;
NamedDecl *Params[N];
/// \brief Stores a list of template parameters and the associated
/// requires-clause (if any) for a TemplateDecl and its derived classes.
/// Suitable for creating on the stack.
template <size_t N, bool HasRequiresClause>
class FixedSizeTemplateParameterListStorage
: public TemplateParameterList::FixedSizeStorageOwner {
typename TemplateParameterList::FixedSizeStorage<
NamedDecl *, Expr *>::with_counts<
N, HasRequiresClause ? 1u : 0u
>::type storage;
public:
FixedSizeTemplateParameterListStorage(SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ArrayRef<NamedDecl *> Params,
SourceLocation RAngleLoc)
: List(TemplateLoc, LAngleLoc, Params, RAngleLoc) {
// Because we're doing an evil layout hack above, have some
// asserts, just to double-check everything is laid out like
// expected.
assert(sizeof(*this) ==
TemplateParameterList::totalSizeToAlloc<NamedDecl *>(N) &&
"Object layout not as expected");
assert(this->Params == List.getTrailingObjects<NamedDecl *>() &&
"Object layout not as expected");
}
TemplateParameterList *get() { return &List; }
SourceLocation RAngleLoc,
Expr *RequiresClause)
: FixedSizeStorageOwner(
(assert(N == Params.size()),
assert(HasRequiresClause == static_cast<bool>(RequiresClause)),
new (static_cast<void *>(&storage)) TemplateParameterList(
TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
};
/// \brief A template argument list.
@ -356,6 +376,11 @@ class TemplateDecl : public NamedDecl {
return TemplateParams;
}
/// Get the constraint-expression from the associated requires-clause (if any)
const Expr *getRequiresClause() const {
return TemplateParams ? TemplateParams->getRequiresClause() : nullptr;
}
/// Get the underlying, templated declaration.
NamedDecl *getTemplatedDecl() const { return TemplatedDecl.getPointer(); }

View File

@ -445,6 +445,11 @@ class Expr : public Stmt {
return const_cast<Expr*>(this)->getSourceBitField();
}
Decl *getReferencedDeclOfCallee();
const Decl *getReferencedDeclOfCallee() const {
return const_cast<Expr*>(this)->getReferencedDeclOfCallee();
}
/// \brief If this expression is an l-value for an Objective C
/// property, find the underlying property reference expression.
const ObjCPropertyRefExpr *getObjCProperty() const;
@ -823,12 +828,22 @@ class Expr : public Stmt {
/// behavior if the object isn't dynamically of the derived type.
const CXXRecordDecl *getBestDynamicClassType() const;
/// \brief Get the inner expression that determines the best dynamic class.
/// If this is a prvalue, we guarantee that it is of the most-derived type
/// for the object itself.
const Expr *getBestDynamicClassTypeExpr() const;
/// Walk outwards from an expression we want to bind a reference to and
/// find the expression whose lifetime needs to be extended. Record
/// the LHSs of comma expressions and adjustments needed along the path.
const Expr *skipRValueSubobjectAdjustments(
SmallVectorImpl<const Expr *> &CommaLHS,
SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
const Expr *skipRValueSubobjectAdjustments() const {
SmallVector<const Expr *, 8> CommaLHSs;
SmallVector<SubobjectAdjustment, 8> Adjustments;
return skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
}
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstExprConstant &&
@ -2406,8 +2421,8 @@ class MemberExpr final
/// \brief Retrieve the member declaration to which this expression refers.
///
/// The returned declaration will either be a FieldDecl or (in C++)
/// a CXXMethodDecl.
/// The returned declaration will be a FieldDecl or (in C++) a VarDecl (for
/// static data members), a CXXMethodDecl, or an EnumConstantDecl.
ValueDecl *getMemberDecl() const { return MemberDecl; }
void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
@ -3771,17 +3786,26 @@ class InitListExpr : public Expr {
/// \brief Build an empty initializer list.
explicit InitListExpr(EmptyShell Empty)
: Expr(InitListExprClass, Empty) { }
: Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
unsigned getNumInits() const { return InitExprs.size(); }
/// \brief Retrieve the set of initializers.
Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); }
/// \brief Retrieve the set of initializers.
Expr * const *getInits() const {
return reinterpret_cast<Expr * const *>(InitExprs.data());
}
ArrayRef<Expr *> inits() {
return llvm::makeArrayRef(getInits(), getNumInits());
}
ArrayRef<Expr *> inits() const {
return llvm::makeArrayRef(getInits(), getNumInits());
}
const Expr *getInit(unsigned Init) const {
assert(Init < getNumInits() && "Initializer access out of range!");
return cast_or_null<Expr>(InitExprs[Init]);
@ -3862,7 +3886,7 @@ class InitListExpr : public Expr {
// Explicit InitListExpr's originate from source code (and have valid source
// locations). Implicit InitListExpr's are created by the semantic analyzer.
bool isExplicit() {
bool isExplicit() const {
return LBraceLoc.isValid() && RBraceLoc.isValid();
}
@ -3870,6 +3894,11 @@ class InitListExpr : public Expr {
// literal or an @encode?
bool isStringLiteralInit() const;
/// Is this a transparent initializer list (that is, an InitListExpr that is
/// purely syntactic, and whose semantics are that of the sole contained
/// initializer)?
bool isTransparent() const;
SourceLocation getLBraceLoc() const { return LBraceLoc; }
void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
@ -4304,6 +4333,98 @@ class DesignatedInitUpdateExpr : public Expr {
}
};
/// \brief Represents a loop initializing the elements of an array.
///
/// The need to initialize the elements of an array occurs in a number of
/// contexts:
///
/// * in the implicit copy/move constructor for a class with an array member
/// * when a lambda-expression captures an array by value
/// * when a decomposition declaration decomposes an array
///
/// There are two subexpressions: a common expression (the source array)
/// that is evaluated once up-front, and a per-element initializer that
/// runs once for each array element.
///
/// Within the per-element initializer, the common expression may be referenced
/// via an OpaqueValueExpr, and the current index may be obtained via an
/// ArrayInitIndexExpr.
class ArrayInitLoopExpr : public Expr {
Stmt *SubExprs[2];
explicit ArrayInitLoopExpr(EmptyShell Empty)
: Expr(ArrayInitLoopExprClass, Empty), SubExprs{} {}
public:
explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr *ElementInit)
: Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary, false,
CommonInit->isValueDependent() || ElementInit->isValueDependent(),
T->isInstantiationDependentType(),
CommonInit->containsUnexpandedParameterPack() ||
ElementInit->containsUnexpandedParameterPack()),
SubExprs{CommonInit, ElementInit} {}
/// Get the common subexpression shared by all initializations (the source
/// array).
OpaqueValueExpr *getCommonExpr() const {
return cast<OpaqueValueExpr>(SubExprs[0]);
}
/// Get the initializer to use for each array element.
Expr *getSubExpr() const { return cast<Expr>(SubExprs[1]); }
llvm::APInt getArraySize() const {
return cast<ConstantArrayType>(getType()->castAsArrayTypeUnsafe())
->getSize();
}
static bool classof(const Stmt *S) {
return S->getStmtClass() == ArrayInitLoopExprClass;
}
SourceLocation getLocStart() const LLVM_READONLY {
return getCommonExpr()->getLocStart();
}
SourceLocation getLocEnd() const LLVM_READONLY {
return getCommonExpr()->getLocEnd();
}
child_range children() {
return child_range(SubExprs, SubExprs + 2);
}
friend class ASTReader;
friend class ASTStmtReader;
friend class ASTStmtWriter;
};
/// \brief Represents the index of the current element of an array being
/// initialized by an ArrayInitLoopExpr. This can only appear within the
/// subexpression of an ArrayInitLoopExpr.
class ArrayInitIndexExpr : public Expr {
explicit ArrayInitIndexExpr(EmptyShell Empty)
: Expr(ArrayInitIndexExprClass, Empty) {}
public:
explicit ArrayInitIndexExpr(QualType T)
: Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary,
false, false, false, false) {}
static bool classof(const Stmt *S) {
return S->getStmtClass() == ArrayInitIndexExprClass;
}
SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
child_range children() {
return child_range(child_iterator(), child_iterator());
}
friend class ASTReader;
friend class ASTStmtReader;
};
/// \brief Represents an implicitly-generated value initialization of
/// an object of a given type.
///
@ -4447,11 +4568,19 @@ class GenericSelectionExpr : public Expr {
return cast<Expr>(SubExprs[END_EXPR+i]);
}
Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); }
ArrayRef<Expr *> getAssocExprs() const {
return NumAssocs
? llvm::makeArrayRef(
&reinterpret_cast<Expr **>(SubExprs)[END_EXPR], NumAssocs)
: None;
}
const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
return AssocTypes[i];
}
TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const {
return NumAssocs ? llvm::makeArrayRef(&AssocTypes[0], NumAssocs) : None;
}
QualType getAssocType(unsigned i) const {
if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i))

View File

@ -76,6 +76,19 @@ class CXXOperatorCallExpr : public CallExpr {
/// expression refers to.
OverloadedOperatorKind getOperator() const { return Operator; }
static bool isAssignmentOp(OverloadedOperatorKind Opc) {
return Opc == OO_Equal || Opc == OO_StarEqual ||
Opc == OO_SlashEqual || Opc == OO_PercentEqual ||
Opc == OO_PlusEqual || Opc == OO_MinusEqual ||
Opc == OO_LessLessEqual || Opc == OO_GreaterGreaterEqual ||
Opc == OO_AmpEqual || Opc == OO_CaretEqual ||
Opc == OO_PipeEqual;
}
bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
/// \brief Is this written as an infix binary operator?
bool isInfixBinaryOp() const;
/// \brief Returns the location of the operator symbol in the expression.
///
/// When \c getOperator()==OO_Call, this is the location of the right
@ -1500,9 +1513,8 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr {
/// C++1y introduces a new form of "capture" called an init-capture that
/// includes an initializing expression (rather than capturing a variable),
/// and which can never occur implicitly.
class LambdaExpr final
: public Expr,
private llvm::TrailingObjects<LambdaExpr, Stmt *, unsigned, VarDecl *> {
class LambdaExpr final : public Expr,
private llvm::TrailingObjects<LambdaExpr, Stmt *> {
/// \brief The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
@ -1523,10 +1535,6 @@ class LambdaExpr final
/// \brief Whether this lambda had the result type explicitly specified.
unsigned ExplicitResultType : 1;
/// \brief Whether there are any array index variables stored at the end of
/// this lambda expression.
unsigned HasArrayIndexVars : 1;
/// \brief The location of the closing brace ('}') that completes
/// the lambda.
///
@ -1537,28 +1545,19 @@ class LambdaExpr final
/// module file just to determine the source range.
SourceLocation ClosingBrace;
size_t numTrailingObjects(OverloadToken<Stmt *>) const {
return NumCaptures + 1;
}
size_t numTrailingObjects(OverloadToken<unsigned>) const {
return HasArrayIndexVars ? NumCaptures + 1 : 0;
}
/// \brief Construct a lambda expression.
LambdaExpr(QualType T, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
bool ExplicitParams, bool ExplicitResultType,
ArrayRef<Expr *> CaptureInits, ArrayRef<VarDecl *> ArrayIndexVars,
ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace,
bool ContainsUnexpandedParameterPack);
/// \brief Construct an empty lambda expression.
LambdaExpr(EmptyShell Empty, unsigned NumCaptures, bool HasArrayIndexVars)
LambdaExpr(EmptyShell Empty, unsigned NumCaptures)
: Expr(LambdaExprClass, Empty),
NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
ExplicitResultType(false), HasArrayIndexVars(true) {
ExplicitResultType(false) {
getStoredStmts()[NumCaptures] = nullptr;
}
@ -1566,21 +1565,6 @@ class LambdaExpr final
Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
/// \brief Retrieve the mapping from captures to the first array index
/// variable.
unsigned *getArrayIndexStarts() { return getTrailingObjects<unsigned>(); }
const unsigned *getArrayIndexStarts() const {
return getTrailingObjects<unsigned>();
}
/// \brief Retrieve the complete set of array-index variables.
VarDecl **getArrayIndexVars() { return getTrailingObjects<VarDecl *>(); }
VarDecl *const *getArrayIndexVars() const {
return getTrailingObjects<VarDecl *>();
}
public:
/// \brief Construct a new lambda expression.
static LambdaExpr *
@ -1588,15 +1572,12 @@ class LambdaExpr final
LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
ArrayRef<VarDecl *> ArrayIndexVars,
ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
bool ContainsUnexpandedParameterPack);
SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
/// \brief Construct a new lambda expression that will be deserialized from
/// an external source.
static LambdaExpr *CreateDeserialized(const ASTContext &C,
unsigned NumCaptures,
unsigned NumArrayIndexVars);
unsigned NumCaptures);
/// \brief Determine the default capture kind for this lambda.
LambdaCaptureDefault getCaptureDefault() const {
@ -1695,14 +1676,6 @@ class LambdaExpr final
return capture_init_begin() + NumCaptures;
}
/// \brief Retrieve the set of index variables used in the capture
/// initializer of an array captured by copy.
///
/// \param Iter The iterator that points at the capture initializer for
/// which we are extracting the corresponding index variables.
ArrayRef<VarDecl *>
getCaptureInitIndexVars(const_capture_init_iterator Iter) const;
/// \brief Retrieve the source range covering the lambda introducer,
/// which contains the explicit capture list surrounded by square
/// brackets ([...]).
@ -1828,11 +1801,13 @@ class CXXNewExpr : public Expr {
unsigned GlobalNew : 1;
/// Do we allocate an array? If so, the first SubExpr is the size expression.
unsigned Array : 1;
/// Should the alignment be passed to the allocation function?
unsigned PassAlignment : 1;
/// If this is an array allocation, does the usual deallocation
/// function for the allocated type want to know the allocated size?
unsigned UsualArrayDeleteWantsSize : 1;
/// The number of placement new arguments.
unsigned NumPlacementArgs : 13;
unsigned NumPlacementArgs : 26;
/// What kind of initializer do we have? Could be none, parens, or braces.
/// In storage, we distinguish between "none, and no initializer expr", and
/// "none, but an implicit initializer expr".
@ -1848,8 +1823,8 @@ class CXXNewExpr : public Expr {
};
CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
ArrayRef<Expr*> placementArgs,
FunctionDecl *operatorDelete, bool PassAlignment,
bool usualArrayDeleteWantsSize, ArrayRef<Expr*> placementArgs,
SourceRange typeIdParens, Expr *arraySize,
InitializationStyle initializationStyle, Expr *initializer,
QualType ty, TypeSourceInfo *AllocatedTypeInfo,
@ -1937,10 +1912,16 @@ class CXXNewExpr : public Expr {
}
/// \brief Returns the CXXConstructExpr from this new-expression, or null.
const CXXConstructExpr* getConstructExpr() const {
const CXXConstructExpr *getConstructExpr() const {
return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
}
/// Indicates whether the required alignment should be implicitly passed to
/// the allocation function.
bool passAlignment() const {
return PassAlignment;
}
/// Answers whether the usual array deallocation function for the
/// allocated type expects the size of the allocation as a
/// parameter.
@ -4011,6 +3992,12 @@ class MaterializeTemporaryExpr : public Expr {
// within a default initializer.
if (isa<FieldDecl>(ExtendingDecl))
return SD_Automatic;
// FIXME: This only works because storage class specifiers are not allowed
// on decomposition declarations.
if (isa<BindingDecl>(ExtendingDecl))
return ExtendingDecl->getDeclContext()->isFunctionOrMethod()
? SD_Automatic
: SD_Static;
return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
}

View File

@ -90,7 +90,7 @@ class ObjCBoolLiteralExpr : public Expr {
/// ObjCBoxedExpr - used for generalized expression boxing.
/// as in: @(strdup("hello world")), @(random()) or @(view.frame)
/// Also used for boxing non-parenthesized numeric literals;
/// as in: @42 or \@true (c++/objc++) or \@__yes (c/objc).
/// as in: @42 or \@true (c++/objc++) or \@__objc_yes (c/objc).
class ObjCBoxedExpr : public Expr {
Stmt *SubExpr;
ObjCMethodDecl *BoxingMethod;

View File

@ -14,14 +14,14 @@
#ifndef LLVM_CLANG_AST_MANGLE_H
#define LLVM_CLANG_AST_MANGLE_H
#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
class raw_ostream;
}
namespace clang {
class ASTContext;

View File

@ -16,7 +16,6 @@
#define LLVM_CLANG_AST_MANGLENUMBERINGCONTEXT_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
namespace clang {
@ -30,7 +29,7 @@ class VarDecl;
/// \brief Keeps track of the mangled names of lambda expressions and block
/// literals within a particular context.
class MangleNumberingContext : public RefCountedBase<MangleNumberingContext> {
class MangleNumberingContext {
public:
virtual ~MangleNumberingContext() {}

View File

@ -4228,50 +4228,153 @@ class OMPFromClause final
/// 'use_device_ptr' with the variables 'a' and 'b'.
///
class OMPUseDevicePtrClause final
: public OMPVarListClause<OMPUseDevicePtrClause>,
private llvm::TrailingObjects<OMPUseDevicePtrClause, Expr *> {
: public OMPMappableExprListClause<OMPUseDevicePtrClause>,
private llvm::TrailingObjects<
OMPUseDevicePtrClause, Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent> {
friend TrailingObjects;
friend OMPVarListClause;
friend OMPMappableExprListClause;
friend class OMPClauseReader;
/// Build clause with number of variables \a N.
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
size_t numTrailingObjects(OverloadToken<Expr *>) const {
return 3 * varlist_size();
}
size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
return getUniqueDeclarationsNum();
}
size_t numTrailingObjects(OverloadToken<unsigned>) const {
return getUniqueDeclarationsNum() + getTotalComponentListNum();
}
/// Build clause with number of variables \a NumVars.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param N Number of the variables in the clause.
/// \param NumVars Number of expressions listed in this clause.
/// \param NumUniqueDeclarations Number of unique base declarations in this
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
///
OMPUseDevicePtrClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPUseDevicePtrClause>(OMPC_use_device_ptr, StartLoc,
LParenLoc, EndLoc, N) {}
explicit OMPUseDevicePtrClause(SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
unsigned NumComponents)
: OMPMappableExprListClause(OMPC_use_device_ptr, StartLoc, LParenLoc,
EndLoc, NumVars, NumUniqueDeclarations,
NumComponentLists, NumComponents) {}
/// \brief Build an empty clause.
/// Build an empty clause.
///
/// \param N Number of variables.
/// \param NumVars Number of expressions listed in this clause.
/// \param NumUniqueDeclarations Number of unique base declarations in this
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
///
explicit OMPUseDevicePtrClause(unsigned N)
: OMPVarListClause<OMPUseDevicePtrClause>(
OMPC_use_device_ptr, SourceLocation(), SourceLocation(),
SourceLocation(), N) {}
explicit OMPUseDevicePtrClause(unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
unsigned NumComponents)
: OMPMappableExprListClause(OMPC_use_device_ptr, SourceLocation(),
SourceLocation(), SourceLocation(), NumVars,
NumUniqueDeclarations, NumComponentLists,
NumComponents) {}
/// Sets the list of references to private copies with initializers for new
/// private variables.
/// \param VL List of references.
void setPrivateCopies(ArrayRef<Expr *> VL);
/// Gets the list of references to private copies with initializers for new
/// private variables.
MutableArrayRef<Expr *> getPrivateCopies() {
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateCopies() const {
return llvm::makeArrayRef(varlist_end(), varlist_size());
}
/// Sets the list of references to initializer variables for new private
/// variables.
/// \param VL List of references.
void setInits(ArrayRef<Expr *> VL);
/// Gets the list of references to initializer variables for new private
/// variables.
MutableArrayRef<Expr *> getInits() {
return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
}
ArrayRef<const Expr *> getInits() const {
return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
}
public:
/// Creates clause with a list of variables \a VL.
/// Creates clause with a list of variables \a Vars.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
/// \param Vars The original expression used in the clause.
/// \param PrivateVars Expressions referring to private copies.
/// \param Inits Expressions referring to private copy initializers.
/// \param Declarations Declarations used in the clause.
/// \param ComponentLists Component lists used in the clause.
///
static OMPUseDevicePtrClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL);
/// Creates an empty clause with the place for \a N variables.
SourceLocation EndLoc, ArrayRef<Expr *> Vars,
ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists);
/// Creates an empty clause with the place for \a NumVars variables.
///
/// \param C AST context.
/// \param N The number of variables.
/// \param NumVars Number of expressions listed in the clause.
/// \param NumUniqueDeclarations Number of unique base declarations in this
/// clause.
/// \param NumComponentLists Number of unique base declarations in this
/// clause.
/// \param NumComponents Total number of expression components in the clause.
///
static OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C, unsigned N);
static OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C,
unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
unsigned NumComponents);
typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
typedef llvm::iterator_range<private_copies_const_iterator>
private_copies_const_range;
private_copies_range private_copies() {
return private_copies_range(getPrivateCopies().begin(),
getPrivateCopies().end());
}
private_copies_const_range private_copies() const {
return private_copies_const_range(getPrivateCopies().begin(),
getPrivateCopies().end());
}
typedef MutableArrayRef<Expr *>::iterator inits_iterator;
typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
typedef llvm::iterator_range<inits_iterator> inits_range;
typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
inits_range inits() {
return inits_range(getInits().begin(), getInits().end());
}
inits_const_range inits() const {
return inits_const_range(getInits().begin(), getInits().end());
}
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
@ -4293,50 +4396,94 @@ class OMPUseDevicePtrClause final
/// 'is_device_ptr' with the variables 'a' and 'b'.
///
class OMPIsDevicePtrClause final
: public OMPVarListClause<OMPIsDevicePtrClause>,
private llvm::TrailingObjects<OMPIsDevicePtrClause, Expr *> {
: public OMPMappableExprListClause<OMPIsDevicePtrClause>,
private llvm::TrailingObjects<
OMPIsDevicePtrClause, Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent> {
friend TrailingObjects;
friend OMPVarListClause;
friend OMPMappableExprListClause;
friend class OMPClauseReader;
/// Build clause with number of variables \a N.
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
size_t numTrailingObjects(OverloadToken<Expr *>) const {
return varlist_size();
}
size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
return getUniqueDeclarationsNum();
}
size_t numTrailingObjects(OverloadToken<unsigned>) const {
return getUniqueDeclarationsNum() + getTotalComponentListNum();
}
/// Build clause with number of variables \a NumVars.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param N Number of the variables in the clause.
/// \param NumVars Number of expressions listed in this clause.
/// \param NumUniqueDeclarations Number of unique base declarations in this
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
///
OMPIsDevicePtrClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPIsDevicePtrClause>(OMPC_is_device_ptr, StartLoc,
LParenLoc, EndLoc, N) {}
explicit OMPIsDevicePtrClause(SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc,
unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
unsigned NumComponents)
: OMPMappableExprListClause(OMPC_is_device_ptr, StartLoc, LParenLoc,
EndLoc, NumVars, NumUniqueDeclarations,
NumComponentLists, NumComponents) {}
/// Build an empty clause.
///
/// \param N Number of variables.
/// \param NumVars Number of expressions listed in this clause.
/// \param NumUniqueDeclarations Number of unique base declarations in this
/// clause.
/// \param NumComponentLists Number of component lists in this clause.
/// \param NumComponents Total number of expression components in the clause.
///
explicit OMPIsDevicePtrClause(unsigned N)
: OMPVarListClause<OMPIsDevicePtrClause>(
OMPC_is_device_ptr, SourceLocation(), SourceLocation(),
SourceLocation(), N) {}
explicit OMPIsDevicePtrClause(unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
unsigned NumComponents)
: OMPMappableExprListClause(OMPC_is_device_ptr, SourceLocation(),
SourceLocation(), SourceLocation(), NumVars,
NumUniqueDeclarations, NumComponentLists,
NumComponents) {}
public:
/// Creates clause with a list of variables \a VL.
/// Creates clause with a list of variables \a Vars.
///
/// \param C AST context.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
/// \param Vars The original expression used in the clause.
/// \param Declarations Declarations used in the clause.
/// \param ComponentLists Component lists used in the clause.
///
static OMPIsDevicePtrClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL);
/// Creates an empty clause with the place for \a N variables.
SourceLocation EndLoc, ArrayRef<Expr *> Vars,
ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists);
/// Creates an empty clause with the place for \a NumVars variables.
///
/// \param C AST context.
/// \param N The number of variables.
/// \param NumVars Number of expressions listed in the clause.
/// \param NumUniqueDeclarations Number of unique base declarations in this
/// clause.
/// \param NumComponentLists Number of unique base declarations in this
/// clause.
/// \param NumComponents Total number of expression components in the clause.
///
static OMPIsDevicePtrClause *CreateEmpty(const ASTContext &C, unsigned N);
static OMPIsDevicePtrClause *CreateEmpty(const ASTContext &C,
unsigned NumVars,
unsigned NumUniqueDeclarations,
unsigned NumComponentLists,
unsigned NumComponents);
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),

View File

@ -321,9 +321,14 @@ CAST_OPERATION(BuiltinFnToFnPtr)
// Convert a zero value for OpenCL event_t initialization.
CAST_OPERATION(ZeroToOCLEvent)
// Convert a zero value for OpenCL queue_t initialization.
CAST_OPERATION(ZeroToOCLQueue)
// Convert a pointer to a different address space.
CAST_OPERATION(AddressSpaceConversion)
// Convert an integer initializer to an OpenCL sampler.
CAST_OPERATION(IntToOCLSampler)
//===- Binary Operations -------------------------------------------------===//
// Operators listed in order of precedence.

View File

@ -14,10 +14,10 @@
#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
#include <type_traits>
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
@ -27,7 +27,9 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/LambdaCapture.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
@ -36,6 +38,15 @@
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include <algorithm>
#include <cstddef>
#include <type_traits>
// The following three macros are used for meta programming. The code
// using them is responsible for defining macro OPERATOR().
@ -70,7 +81,7 @@ namespace clang {
do { \
if (!getDerived().CALL_EXPR) \
return false; \
} while (0)
} while (false)
/// \brief A class that does preordor or postorder
/// depth-first traversal on the entire Clang AST and visits each node.
@ -264,10 +275,12 @@ template <typename Derived> class RecursiveASTVisitor {
/// \returns false if the visitation was terminated early, true otherwise.
bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
/// \brief Recursively visit a lambda capture.
/// \brief Recursively visit a lambda capture. \c Init is the expression that
/// will be used to initialize the capture.
///
/// \returns false if the visitation was terminated early, true otherwise.
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
Expr *Init);
/// \brief Recursively visit the body of a lambda expression.
///
@ -327,7 +340,7 @@ template <typename Derived> class RecursiveASTVisitor {
do { \
if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \
return false; \
} while (0)
} while (false)
public:
// Declare Traverse*() for all concrete Stmt classes.
@ -355,7 +368,8 @@ template <typename Derived> class RecursiveASTVisitor {
#define OPERATOR(NAME) \
bool TraverseUnary##NAME(UnaryOperator *S, \
DataRecursionQueue *Queue = nullptr) { \
TRY_TO(WalkUpFromUnary##NAME(S)); \
if (!getDerived().shouldTraversePostOrder()) \
TRY_TO(WalkUpFromUnary##NAME(S)); \
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \
return true; \
} \
@ -480,6 +494,11 @@ template <typename Derived> class RecursiveASTVisitor {
private:
// These are helper methods used by more than one Traverse* method.
bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
// Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
template <typename T>
bool TraverseDeclTemplateParameterLists(T *D);
#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
DEF_TRAVERSE_TMPL_INST(Class)
@ -565,7 +584,6 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
#undef DISPATCH_STMT
template <typename Derived>
bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
switch (S->getStmtClass()) {
@ -754,7 +772,6 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
case DeclarationName::CXXConversionFunctionName:
if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
break;
case DeclarationName::Identifier:
@ -869,25 +886,18 @@ bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
TRY_TO(TraverseStmt(Init->getInit()));
if (getDerived().shouldVisitImplicitCode())
// The braces for this one-line loop are required for MSVC2013. It
// refuses to compile
// for (int i : int_vec)
// do {} while(false);
// without braces on the for loop.
for (VarDecl *VD : Init->getArrayIndices()) {
TRY_TO(TraverseDecl(VD));
}
return true;
}
template <typename Derived>
bool
RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
const LambdaCapture *C) {
const LambdaCapture *C,
Expr *Init) {
if (LE->isInitCapture(C))
TRY_TO(TraverseDecl(C->getCapturedVar()));
else
TRY_TO(TraverseStmt(Init));
return true;
}
@ -1034,6 +1044,8 @@ DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
DEF_TRAVERSE_TYPE(ObjCObjectType, {
@ -1265,6 +1277,8 @@ DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
DEF_TRAVERSE_TYPELOC(PackExpansionType,
{ TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {})
DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
@ -1383,6 +1397,8 @@ DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
DEF_TRAVERSE_DECL(ExportDecl, {})
DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
})
@ -1489,6 +1505,8 @@ DEF_TRAVERSE_DECL(UsingDecl, {
TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
})
DEF_TRAVERSE_DECL(UsingPackDecl, {})
DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
})
@ -1526,6 +1544,16 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
return true;
}
template <typename Derived>
template <typename T>
bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
for (unsigned i = 0; i < D->getNumTemplateParameterLists(); i++) {
TemplateParameterList *TPL = D->getTemplateParameterList(i);
TraverseTemplateParameterListHelper(TPL);
}
return true;
}
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
ClassTemplateDecl *D) {
@ -1687,6 +1715,8 @@ DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
})
DEF_TRAVERSE_DECL(EnumDecl, {
TRY_TO(TraverseDeclTemplateParameterLists(D));
if (D->getTypeForDecl())
TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
@ -1701,6 +1731,7 @@ bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
// We shouldn't traverse D->getTypeForDecl(); it's a result of
// declaring the type, not something that was written in the source.
TRY_TO(TraverseDeclTemplateParameterLists(D));
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
return true;
}
@ -1795,6 +1826,7 @@ DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
TRY_TO(TraverseDeclTemplateParameterLists(D));
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
if (D->getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
@ -1803,6 +1835,18 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
return true;
}
DEF_TRAVERSE_DECL(DecompositionDecl, {
TRY_TO(TraverseVarHelper(D));
for (auto *Binding : D->bindings()) {
TRY_TO(TraverseDecl(Binding));
}
})
DEF_TRAVERSE_DECL(BindingDecl, {
if (getDerived().shouldVisitImplicitCode())
TRY_TO(TraverseStmt(D->getBinding()));
})
DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
DEF_TRAVERSE_DECL(FieldDecl, {
@ -1829,6 +1873,7 @@ DEF_TRAVERSE_DECL(ObjCIvarDecl, {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
TRY_TO(TraverseDeclTemplateParameterLists(D));
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
@ -2041,6 +2086,7 @@ DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
DEF_TRAVERSE_STMT(CXXForRangeStmt, {
if (!getDerived().shouldVisitImplicitCode()) {
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
@ -2050,10 +2096,12 @@ DEF_TRAVERSE_STMT(CXXForRangeStmt, {
ShouldVisitChildren = false;
}
})
DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
})
DEF_TRAVERSE_STMT(ReturnStmt, {})
DEF_TRAVERSE_STMT(SwitchStmt, {})
DEF_TRAVERSE_STMT(WhileStmt, {})
@ -2249,10 +2297,11 @@ DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
// Walk only the visible parts of lambda expressions.
DEF_TRAVERSE_STMT(LambdaExpr, {
for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
CEnd = S->explicit_capture_end();
C != CEnd; ++C) {
TRY_TO(TraverseLambdaCapture(S, C));
for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
const LambdaCapture *C = S->capture_begin() + I;
if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I]));
}
}
TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
@ -2300,23 +2349,31 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
DEF_TRAVERSE_STMT(AddrLabelExpr, {})
DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
DEF_TRAVERSE_STMT(OMPArraySectionExpr, {})
DEF_TRAVERSE_STMT(BlockExpr, {
TRY_TO(TraverseDecl(S->getBlockDecl()));
return true; // no child statements to loop through.
})
DEF_TRAVERSE_STMT(ChooseExpr, {})
DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
})
DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {
if (getDerived().shouldVisitImplicitCode())
TRY_TO(TraverseStmt(S->getExpr()));
})
DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
DEF_TRAVERSE_STMT(ExprWithCleanups, {})
DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {})
DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
@ -2324,6 +2381,7 @@ DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
})
DEF_TRAVERSE_STMT(CXXThisExpr, {})
DEF_TRAVERSE_STMT(CXXThrowExpr, {})
DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
@ -2333,25 +2391,38 @@ DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
DEF_TRAVERSE_STMT(GNUNullExpr, {})
DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
DEF_TRAVERSE_STMT(NoInitExpr, {})
DEF_TRAVERSE_STMT(ArrayInitLoopExpr, {
// FIXME: The source expression of the OVE should be listed as
// a child of the ArrayInitLoopExpr.
if (OpaqueValueExpr *OVE = S->getCommonExpr())
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
})
DEF_TRAVERSE_STMT(ArrayInitIndexExpr, {})
DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
})
DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
DEF_TRAVERSE_STMT(ObjCMessageExpr, {
if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
})
DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
})
DEF_TRAVERSE_STMT(ObjCAvailabilityCheckExpr, {})
DEF_TRAVERSE_STMT(ParenExpr, {})
DEF_TRAVERSE_STMT(ParenListExpr, {})
@ -2574,6 +2645,30 @@ DEF_TRAVERSE_STMT(OMPDistributeSimdDirective,
DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPTargetSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {

View File

@ -15,7 +15,6 @@
#define LLVM_CLANG_AST_REDECLARABLE_H
#include "clang/AST/ExternalASTSource.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Casting.h"
#include <iterator>
@ -280,6 +279,68 @@ class Mergeable {
bool isFirstDecl() const { return getFirstDecl() == this; }
};
}
/// A wrapper class around a pointer that always points to its canonical
/// declaration.
///
/// CanonicalDeclPtr<decl_type> behaves just like decl_type*, except we call
/// decl_type::getCanonicalDecl() on construction.
///
/// This is useful for hashtables that you want to be keyed on a declaration's
/// canonical decl -- if you use CanonicalDeclPtr as the key, you don't need to
/// remember to call getCanonicalDecl() everywhere.
template <typename decl_type> class CanonicalDeclPtr {
public:
CanonicalDeclPtr() : Ptr(nullptr) {}
CanonicalDeclPtr(decl_type *Ptr)
: Ptr(Ptr ? Ptr->getCanonicalDecl() : nullptr) {}
CanonicalDeclPtr(const CanonicalDeclPtr &) = default;
CanonicalDeclPtr &operator=(const CanonicalDeclPtr &) = default;
operator decl_type *() { return Ptr; }
operator const decl_type *() const { return Ptr; }
decl_type *operator->() { return Ptr; }
const decl_type *operator->() const { return Ptr; }
decl_type &operator*() { return *Ptr; }
const decl_type &operator*() const { return *Ptr; }
private:
friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>;
decl_type *Ptr;
};
} // namespace clang
namespace llvm {
template <typename decl_type>
struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
using CanonicalDeclPtr = clang::CanonicalDeclPtr<decl_type>;
using BaseInfo = DenseMapInfo<decl_type *>;
static CanonicalDeclPtr getEmptyKey() {
// Construct our CanonicalDeclPtr this way because the regular constructor
// would dereference P.Ptr, which is not allowed.
CanonicalDeclPtr P;
P.Ptr = BaseInfo::getEmptyKey();
return P;
}
static CanonicalDeclPtr getTombstoneKey() {
CanonicalDeclPtr P;
P.Ptr = BaseInfo::getTombstoneKey();
return P;
}
static unsigned getHashValue(const CanonicalDeclPtr &P) {
return BaseInfo::getHashValue(P);
}
static bool isEqual(const CanonicalDeclPtr &LHS,
const CanonicalDeclPtr &RHS) {
return BaseInfo::isEqual(LHS, RHS);
}
};
} // namespace llvm
#endif

View File

@ -56,7 +56,7 @@ namespace clang {
/// Stmt - This represents one statement.
///
class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt {
class alignas(void *) Stmt {
public:
enum StmtClass {
NoStmtClass = 0,
@ -71,10 +71,10 @@ class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt {
// Make vanilla 'new' and 'delete' illegal for Stmts.
protected:
void *operator new(size_t bytes) LLVM_NOEXCEPT {
void *operator new(size_t bytes) noexcept {
llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
}
void operator delete(void *data) LLVM_NOEXCEPT {
void operator delete(void *data) noexcept {
llvm_unreachable("Stmts cannot be released with regular 'delete'.");
}
@ -284,12 +284,12 @@ class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt {
return operator new(bytes, *C, alignment);
}
void *operator new(size_t bytes, void *mem) LLVM_NOEXCEPT { return mem; }
void *operator new(size_t bytes, void *mem) noexcept { return mem; }
void operator delete(void *, const ASTContext &, unsigned) LLVM_NOEXCEPT {}
void operator delete(void *, const ASTContext *, unsigned) LLVM_NOEXCEPT {}
void operator delete(void *, size_t) LLVM_NOEXCEPT {}
void operator delete(void *, void *) LLVM_NOEXCEPT {}
void operator delete(void *, const ASTContext &, unsigned) noexcept {}
void operator delete(void *, const ASTContext *, unsigned) noexcept {}
void operator delete(void *, size_t) noexcept {}
void operator delete(void *, void *) noexcept {}
public:
/// \brief A placeholder type used to construct an empty shell of a
@ -340,7 +340,7 @@ class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt {
public:
Stmt(StmtClass SC) {
static_assert(sizeof(*this) % llvm::AlignOf<void *>::Alignment == 0,
static_assert(sizeof(*this) % alignof(void *) == 0,
"Insufficient alignment!");
StmtBits.sClass = SC;
if (StatisticsEnabled) Stmt::addStmtClass(SC);
@ -387,6 +387,9 @@ class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt {
/// Skip past any implicit AST nodes which might surround this
/// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
Stmt *IgnoreImplicit();
const Stmt *IgnoreImplicit() const {
return const_cast<Stmt *>(this)->IgnoreImplicit();
}
/// \brief Skip no-op (attributed, compound) container stmts and skip captured
/// stmt at the top, if \a IgnoreCaptured is true.
@ -933,6 +936,8 @@ class IfStmt : public Stmt {
bool isConstexpr() const { return IfStmtBits.IsConstexpr; }
void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; }
bool isObjCAvailabilityCheck() const;
SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; }
SourceLocation getLocEnd() const LLVM_READONLY {
if (SubExprs[ELSE])

View File

@ -304,6 +304,8 @@ class CoroutineBodyStmt : public Stmt {
FinalSuspend, ///< The final suspend statement, run after the body.
OnException, ///< Handler for exceptions thrown in the body.
OnFallthrough, ///< Handler for control flow falling off the body.
Allocate, ///< Coroutine frame memory allocation.
Deallocate, ///< Coroutine frame memory deallocation.
ReturnValue, ///< Return value for thunk function.
FirstParamMove ///< First offset for move construction of parameter copies.
};
@ -313,6 +315,7 @@ class CoroutineBodyStmt : public Stmt {
public:
CoroutineBodyStmt(Stmt *Body, Stmt *Promise, Stmt *InitSuspend,
Stmt *FinalSuspend, Stmt *OnException, Stmt *OnFallthrough,
Expr *Allocate, Stmt *Deallocate,
Expr *ReturnValue, ArrayRef<Expr *> ParamMoves)
: Stmt(CoroutineBodyStmtClass) {
SubStmts[CoroutineBodyStmt::Body] = Body;
@ -321,6 +324,8 @@ class CoroutineBodyStmt : public Stmt {
SubStmts[CoroutineBodyStmt::FinalSuspend] = FinalSuspend;
SubStmts[CoroutineBodyStmt::OnException] = OnException;
SubStmts[CoroutineBodyStmt::OnFallthrough] = OnFallthrough;
SubStmts[CoroutineBodyStmt::Allocate] = Allocate;
SubStmts[CoroutineBodyStmt::Deallocate] = Deallocate;
SubStmts[CoroutineBodyStmt::ReturnValue] = ReturnValue;
// FIXME: Tail-allocate space for parameter move expressions and store them.
assert(ParamMoves.empty() && "not implemented yet");
@ -345,6 +350,9 @@ class CoroutineBodyStmt : public Stmt {
return SubStmts[SubStmt::OnFallthrough];
}
Expr *getAllocate() const { return cast<Expr>(SubStmts[SubStmt::Allocate]); }
Stmt *getDeallocate() const { return SubStmts[SubStmt::Deallocate]; }
Expr *getReturnValueInit() const {
return cast<Expr>(SubStmts[SubStmt::ReturnValue]);
}
@ -405,10 +413,13 @@ class CoreturnStmt : public Stmt {
SourceLocation getLocStart() const LLVM_READONLY { return CoreturnLoc; }
SourceLocation getLocEnd() const LLVM_READONLY {
return getOperand()->getLocEnd();
return getOperand() ? getOperand()->getLocEnd() : getLocStart();
}
child_range children() {
if (!getOperand())
return child_range(SubStmts + SubStmt::PromiseCall,
SubStmts + SubStmt::Count);
return child_range(SubStmts, SubStmts + SubStmt::Count);
}

View File

@ -25,19 +25,18 @@ namespace llvm {
template <> struct GraphTraits<clang::Stmt*> {
typedef clang::Stmt NodeType;
typedef clang::Stmt * NodeRef;
typedef clang::Stmt::child_iterator ChildIteratorType;
typedef llvm::df_iterator<clang::Stmt*> nodes_iterator;
static NodeType* getEntryNode(clang::Stmt* S) { return S; }
static NodeRef getEntryNode(clang::Stmt *S) { return S; }
static inline ChildIteratorType child_begin(NodeType* N) {
static ChildIteratorType child_begin(NodeRef N) {
if (N) return N->child_begin();
else return ChildIteratorType();
}
static inline ChildIteratorType child_end(NodeType* N) {
static ChildIteratorType child_end(NodeRef N) {
if (N) return N->child_end();
else return ChildIteratorType();
}
@ -53,19 +52,18 @@ template <> struct GraphTraits<clang::Stmt*> {
template <> struct GraphTraits<const clang::Stmt*> {
typedef const clang::Stmt NodeType;
typedef const clang::Stmt * NodeRef;
typedef clang::Stmt::const_child_iterator ChildIteratorType;
typedef llvm::df_iterator<const clang::Stmt*> nodes_iterator;
static NodeType* getEntryNode(const clang::Stmt* S) { return S; }
static NodeRef getEntryNode(const clang::Stmt *S) { return S; }
static inline ChildIteratorType child_begin(NodeType* N) {
static ChildIteratorType child_begin(NodeRef N) {
if (N) return N->child_begin();
else return ChildIteratorType();
}
static inline ChildIteratorType child_end(NodeType* N) {
static ChildIteratorType child_end(NodeRef N) {
if (N) return N->child_end();
else return ChildIteratorType();
}

View File

@ -70,7 +70,7 @@ class OMPExecutableDirective : public Stmt {
: Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
NumChildren(NumChildren),
ClausesOffset(llvm::alignTo(sizeof(T), llvm::alignOf<OMPClause *>())) {}
ClausesOffset(llvm::alignTo(sizeof(T), alignof(OMPClause *))) {}
/// \brief Sets the list of variables for this clause.
///
@ -773,7 +773,12 @@ class OMPLoopDirective : public OMPExecutableDirective {
T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
T->getStmtClass() == OMPTargetSimdDirectiveClass ||
T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass ||
T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
}
};
@ -3090,6 +3095,549 @@ class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
}
};
/// This represents '#pragma omp target simd' directive.
///
/// \code
/// #pragma omp target simd private(a) map(b) safelen(c)
/// \endcode
/// In this example directive '#pragma omp target simd' has clauses 'private'
/// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
/// the variable 'c'.
///
class OMPTargetSimdDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPTargetSimdDirectiveClass,
OMPD_target_simd, StartLoc, EndLoc, CollapsedNum,
NumClauses) {}
/// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
explicit OMPTargetSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPTargetSimdDirectiveClass, OMPD_target_simd,
SourceLocation(),SourceLocation(), CollapsedNum,
NumClauses) {}
public:
/// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
///
static OMPTargetSimdDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
/// \param C AST context.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses,
unsigned CollapsedNum,
EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTargetSimdDirectiveClass;
}
};
/// This represents '#pragma omp teams distribute' directive.
///
/// \code
/// #pragma omp teams distribute private(a,b)
/// \endcode
/// In this example directive '#pragma omp teams distribute' has clauses
/// 'private' with the variables 'a' and 'b'
///
class OMPTeamsDistributeDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass,
OMPD_teams_distribute, StartLoc, EndLoc,
CollapsedNum, NumClauses) {}
/// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
explicit OMPTeamsDistributeDirective(unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass,
OMPD_teams_distribute, SourceLocation(),
SourceLocation(), CollapsedNum, NumClauses) {}
public:
/// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
///
static OMPTeamsDistributeDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
/// \param C AST context.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses,
unsigned CollapsedNum,
EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
}
};
/// This represents '#pragma omp teams distribute simd'
/// combined directive.
///
/// \code
/// #pragma omp teams distribute simd private(a,b)
/// \endcode
/// In this example directive '#pragma omp teams distribute simd'
/// has clause 'private' with the variables 'a' and 'b'
///
class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
SourceLocation EndLoc, unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass,
OMPD_teams_distribute_simd, StartLoc, EndLoc,
CollapsedNum, NumClauses) {}
/// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass,
OMPD_teams_distribute_simd, SourceLocation(),
SourceLocation(), CollapsedNum, NumClauses) {}
public:
/// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
///
static OMPTeamsDistributeSimdDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
///
/// \param C AST context.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses,
unsigned CollapsedNum,
EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
}
};
/// This represents '#pragma omp teams distribute parallel for simd' composite
/// directive.
///
/// \code
/// #pragma omp teams distribute parallel for simd private(x)
/// \endcode
/// In this example directive '#pragma omp teams distribute parallel for simd'
/// has clause 'private' with the variables 'x'
///
class OMPTeamsDistributeParallelForSimdDirective final
: public OMPLoopDirective {
friend class ASTStmtReader;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
SourceLocation EndLoc,
unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass,
OMPD_teams_distribute_parallel_for_simd, StartLoc,
EndLoc, CollapsedNum, NumClauses) {}
/// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass,
OMPD_teams_distribute_parallel_for_simd,
SourceLocation(), SourceLocation(), CollapsedNum,
NumClauses) {}
public:
/// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
///
static OMPTeamsDistributeParallelForSimdDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
/// \param C AST context.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
static OMPTeamsDistributeParallelForSimdDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
}
};
/// This represents '#pragma omp teams distribute parallel for' composite
/// directive.
///
/// \code
/// #pragma omp teams distribute parallel for private(x)
/// \endcode
/// In this example directive '#pragma omp teams distribute parallel for'
/// has clause 'private' with the variables 'x'
///
class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
SourceLocation EndLoc,
unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
OMPD_teams_distribute_parallel_for, StartLoc, EndLoc,
CollapsedNum, NumClauses) {}
/// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
OMPD_teams_distribute_parallel_for, SourceLocation(),
SourceLocation(), CollapsedNum, NumClauses) {}
public:
/// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
///
static OMPTeamsDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
/// \param C AST context.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
static OMPTeamsDistributeParallelForDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
}
};
/// This represents '#pragma omp target teams' directive.
///
/// \code
/// #pragma omp target teams if(a>0)
/// \endcode
/// In this example directive '#pragma omp target teams' has clause 'if' with
/// condition 'a>0'.
///
class OMPTargetTeamsDirective final : public OMPExecutableDirective {
friend class ASTStmtReader;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
/// \param NumClauses Number of clauses.
///
OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses)
: OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
OMPD_target_teams, StartLoc, EndLoc, NumClauses,
1) {}
/// Build an empty directive.
///
/// \param NumClauses Number of clauses.
///
explicit OMPTargetTeamsDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
OMPD_target_teams, SourceLocation(),
SourceLocation(), NumClauses, 1) {}
public:
/// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
///
static OMPTargetTeamsDirective *Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
/// \param C AST context.
/// \param NumClauses Number of clauses.
///
static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
}
};
/// This represents '#pragma omp target teams distribute' combined directive.
///
/// \code
/// #pragma omp target teams distribute private(x)
/// \endcode
/// In this example directive '#pragma omp target teams distribute' has clause
/// 'private' with the variables 'x'
///
class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
OMPD_target_teams_distribute, StartLoc, EndLoc,
CollapsedNum, NumClauses) {}
/// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
OMPD_target_teams_distribute, SourceLocation(),
SourceLocation(), CollapsedNum, NumClauses) {}
public:
/// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
///
static OMPTargetTeamsDistributeDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
/// \param C AST context.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
static OMPTargetTeamsDistributeDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
}
};
/// This represents '#pragma omp target teams distribute parallel for' combined
/// directive.
///
/// \code
/// #pragma omp target teams distribute parallel for private(x)
/// \endcode
/// In this example directive '#pragma omp target teams distribute parallel
/// for' has clause 'private' with the variables 'x'
///
class OMPTargetTeamsDistributeParallelForDirective final
: public OMPLoopDirective {
friend class ASTStmtReader;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
SourceLocation EndLoc,
unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(this,
OMPTargetTeamsDistributeParallelForDirectiveClass,
OMPD_target_teams_distribute_parallel_for, StartLoc,
EndLoc, CollapsedNum, NumClauses) {}
/// Build an empty directive.
///
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum,
unsigned NumClauses)
: OMPLoopDirective(
this, OMPTargetTeamsDistributeParallelForDirectiveClass,
OMPD_target_teams_distribute_parallel_for, SourceLocation(),
SourceLocation(), CollapsedNum, NumClauses) {}
public:
/// Creates directive with a list of \a Clauses.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param CollapsedNum Number of collapsed loops.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
///
static OMPTargetTeamsDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
/// Creates an empty directive with the place for \a NumClauses clauses.
///
/// \param C AST context.
/// \param CollapsedNum Number of collapsed nested loops.
/// \param NumClauses Number of clauses.
///
static OMPTargetTeamsDistributeParallelForDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() ==
OMPTargetTeamsDistributeParallelForDirectiveClass;
}
};
} // end namespace clang
#endif

View File

@ -301,6 +301,10 @@ class TemplateArgument {
Integer.Type = T.getAsOpaquePtr();
}
/// \brief If this is a non-type template argument, get its type. Otherwise,
/// returns a null QualType.
QualType getNonTypeTemplateArgumentType() const;
/// \brief Retrieve the template argument as an expression.
Expr *getAsExpr() const {
assert(getKind() == Expression && "Unexpected kind");
@ -326,8 +330,8 @@ class TemplateArgument {
/// \brief Iterator range referencing all of the elements of a template
/// argument pack.
llvm::iterator_range<pack_iterator> pack_elements() const {
return llvm::make_range(pack_begin(), pack_end());
ArrayRef<TemplateArgument> pack_elements() const {
return llvm::makeArrayRef(pack_begin(), pack_end());
}
/// \brief The number of template arguments in the given template argument
@ -592,6 +596,10 @@ struct ASTTemplateArgumentListInfo final
return getTrailingObjects<TemplateArgumentLoc>();
}
llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
return llvm::makeArrayRef(getTemplateArgs(), NumTemplateArgs);
}
const TemplateArgumentLoc &operator[](unsigned I) const {
return getTemplateArgs()[I];
}
@ -607,7 +615,7 @@ struct ASTTemplateArgumentListInfo final
/// as such, doesn't contain the array of TemplateArgumentLoc itself,
/// but expects the containing object to also provide storage for
/// that.
struct LLVM_ALIGNAS(LLVM_PTR_SIZE) ASTTemplateKWAndArgsInfo {
struct alignas(void *) ASTTemplateKWAndArgsInfo {
/// \brief The source location of the left angle bracket ('<').
SourceLocation LAngleLoc;

View File

@ -88,6 +88,7 @@ namespace clang {
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
class ObjCMethodDecl;
class ObjCTypeParamDecl;
class UnresolvedUsingTypenameDecl;
class Expr;
class Stmt;
@ -984,6 +985,7 @@ class QualType {
void dump(const char *s) const;
void dump() const;
void dump(llvm::raw_ostream &OS) const;
void Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddPointer(getAsOpaquePtr());
@ -1377,7 +1379,7 @@ class Type : public ExtQualsTypeCommonBase {
/// Extra information which affects how the function is called, like
/// regparm and the calling convention.
unsigned ExtInfo : 9;
unsigned ExtInfo : 10;
/// Used only by FunctionProtoType, put here to pack with the
/// other bitfields.
@ -1728,7 +1730,8 @@ class Type : public ExtQualsTypeCommonBase {
bool isObjCARCBridgableType() const;
bool isCARCBridgableType() const;
bool isTemplateTypeParmType() const; // C++ template type parameter
bool isNullPtrType() const; // C++0x nullptr_t
bool isNullPtrType() const; // C++11 std::nullptr_t
bool isAlignValT() const; // C++17 std::align_val_t
bool isAtomicType() const; // C11 _Atomic()
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
@ -2003,6 +2006,7 @@ class Type : public ExtQualsTypeCommonBase {
}
CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
void dump() const;
void dump(llvm::raw_ostream &OS) const;
friend class ASTReader;
friend class ASTWriter;
@ -2262,19 +2266,15 @@ class AdjustedType : public Type, public llvm::FoldingSetNode {
/// Represents a pointer type decayed from an array or function type.
class DecayedType : public AdjustedType {
DecayedType(QualType OriginalType, QualType DecayedPtr, QualType CanonicalPtr)
: AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
assert(isa<PointerType>(getAdjustedType()));
}
inline
DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical);
friend class ASTContext; // ASTContext creates these.
public:
QualType getDecayedType() const { return getAdjustedType(); }
QualType getPointeeType() const {
return cast<PointerType>(getDecayedType())->getPointeeType();
}
inline QualType getPointeeType() const;
static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
};
@ -2812,7 +2812,8 @@ class VectorType : public Type, public llvm::FoldingSetNode {
/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
/// class enables syntactic extensions, like Vector Components for accessing
/// points, colors, and textures (modeled after OpenGL Shading Language).
/// points (as .xyzw), colors (as .rgba), and textures (modeled after OpenGL
/// Shading Language).
class ExtVectorType : public VectorType {
ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
@ -2821,10 +2822,10 @@ class ExtVectorType : public VectorType {
static int getPointAccessorIdx(char c) {
switch (c) {
default: return -1;
case 'x': return 0;
case 'y': return 1;
case 'z': return 2;
case 'w': return 3;
case 'x': case 'r': return 0;
case 'y': case 'g': return 1;
case 'z': case 'b': return 2;
case 'w': case 'a': return 3;
}
}
static int getNumericAccessorIdx(char c) {
@ -2855,13 +2856,15 @@ class ExtVectorType : public VectorType {
}
}
static int getAccessorIdx(char c) {
if (int idx = getPointAccessorIdx(c)+1) return idx-1;
return getNumericAccessorIdx(c);
static int getAccessorIdx(char c, bool isNumericAccessor) {
if (isNumericAccessor)
return getNumericAccessorIdx(c);
else
return getPointAccessorIdx(c);
}
bool isAccessorWithinNumElements(char c) const {
if (int idx = getAccessorIdx(c)+1)
bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const {
if (int idx = getAccessorIdx(c, isNumericAccessor)+1)
return unsigned(idx-1) < getNumElements();
return false;
}
@ -2902,19 +2905,19 @@ class FunctionType : public Type {
// * AST read and write
// * Codegen
class ExtInfo {
// Feel free to rearrange or add bits, but if you go over 9,
// Feel free to rearrange or add bits, but if you go over 10,
// you'll need to adjust both the Bits field below and
// Type::FunctionTypeBitfields.
// | CC |noreturn|produces|regparm|
// |0 .. 3| 4 | 5 | 6 .. 8|
// |0 .. 4| 5 | 6 | 7 .. 9|
//
// regparm is either 0 (no regparm attribute) or the regparm value+1.
enum { CallConvMask = 0xF };
enum { NoReturnMask = 0x10 };
enum { ProducesResultMask = 0x20 };
enum { CallConvMask = 0x1F };
enum { NoReturnMask = 0x20 };
enum { ProducesResultMask = 0x40 };
enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask),
RegParmOffset = 6 }; // Assumed to be the last field
RegParmOffset = 7 }; // Assumed to be the last field
uint16_t Bits;
@ -3318,6 +3321,9 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
}
/// Return whether this function has a dependent exception spec.
bool hasDependentExceptionSpec() const;
/// Return whether this function has an instantiation-dependent exception
/// spec.
bool hasInstantiationDependentExceptionSpec() const;
/// Result type of getNoexceptSpec().
enum NoexceptResult {
NR_NoNoexcept, ///< There is no noexcept specifier.
@ -3359,9 +3365,15 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1];
}
/// Determine whether this function type has a non-throwing exception
/// specification.
CanThrowResult canThrow(const ASTContext &Ctx) const;
/// Determine whether this function type has a non-throwing exception
/// specification. If this depends on template arguments, returns
/// \c ResultIfDependent.
bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent = false) const;
bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent = false) const {
return ResultIfDependent ? canThrow(Ctx) != CT_Can
: canThrow(Ctx) == CT_Cannot;
}
bool isVariadic() const { return Variadic; }
@ -3462,7 +3474,8 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
param_type_iterator ArgTys, unsigned NumArgs,
const ExtProtoInfo &EPI, const ASTContext &Context);
const ExtProtoInfo &EPI, const ASTContext &Context,
bool Canonical);
};
/// \brief Represents the dependent type named by a dependently-scoped
@ -3788,6 +3801,7 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
attr_fastcall,
attr_stdcall,
attr_thiscall,
attr_regcall,
attr_pascal,
attr_swiftcall,
attr_vectorcall,
@ -4078,18 +4092,22 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
///
/// These types are usually a placeholder for a deduced type. However, before
/// the initializer is attached, or if the initializer is type-dependent, there
/// is no deduced type and an auto type is canonical. In the latter case, it is
/// also a dependent type.
/// the initializer is attached, or (usually) if the initializer is
/// type-dependent, there is no deduced type and an auto type is canonical. In
/// the latter case, it is also a dependent type.
class AutoType : public Type, public llvm::FoldingSetNode {
AutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent)
: Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
/*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
/*VariablyModified=*/false,
/*ContainsParameterPack=*/DeducedType.isNull()
? false : DeducedType->containsUnexpandedParameterPack()) {
assert((DeducedType.isNull() || !IsDependent) &&
"auto deduced to dependent type");
/*VariablyModified=*/false, /*ContainsParameterPack=*/false) {
if (!DeducedType.isNull()) {
if (DeducedType->isDependentType())
setDependent();
if (DeducedType->isInstantiationDependentType())
setInstantiationDependent();
if (DeducedType->containsUnexpandedParameterPack())
setContainsUnexpandedParameterPack();
}
AutoTypeBits.Keyword = (unsigned)Keyword;
}
@ -4696,6 +4714,102 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
}
};
/// This class wraps the list of protocol qualifiers. For types that can
/// take ObjC protocol qualifers, they can subclass this class.
template <class T>
class ObjCProtocolQualifiers {
protected:
ObjCProtocolQualifiers() {}
ObjCProtocolDecl * const *getProtocolStorage() const {
return const_cast<ObjCProtocolQualifiers*>(this)->getProtocolStorage();
}
ObjCProtocolDecl **getProtocolStorage() {
return static_cast<T*>(this)->getProtocolStorageImpl();
}
void setNumProtocols(unsigned N) {
static_cast<T*>(this)->setNumProtocolsImpl(N);
}
void initialize(ArrayRef<ObjCProtocolDecl *> protocols) {
setNumProtocols(protocols.size());
assert(getNumProtocols() == protocols.size() &&
"bitfield overflow in protocol count");
if (!protocols.empty())
memcpy(getProtocolStorage(), protocols.data(),
protocols.size() * sizeof(ObjCProtocolDecl*));
}
public:
typedef ObjCProtocolDecl * const *qual_iterator;
typedef llvm::iterator_range<qual_iterator> qual_range;
qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
qual_iterator qual_begin() const { return getProtocolStorage(); }
qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
bool qual_empty() const { return getNumProtocols() == 0; }
/// Return the number of qualifying protocols in this type, or 0 if
/// there are none.
unsigned getNumProtocols() const {
return static_cast<const T*>(this)->getNumProtocolsImpl();
}
/// Fetch a protocol by index.
ObjCProtocolDecl *getProtocol(unsigned I) const {
assert(I < getNumProtocols() && "Out-of-range protocol access");
return qual_begin()[I];
}
/// Retrieve all of the protocol qualifiers.
ArrayRef<ObjCProtocolDecl *> getProtocols() const {
return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols());
}
};
/// Represents a type parameter type in Objective C. It can take
/// a list of protocols.
class ObjCTypeParamType : public Type,
public ObjCProtocolQualifiers<ObjCTypeParamType>,
public llvm::FoldingSetNode {
friend class ASTContext;
friend class ObjCProtocolQualifiers<ObjCTypeParamType>;
/// The number of protocols stored on this type.
unsigned NumProtocols : 6;
ObjCTypeParamDecl *OTPDecl;
/// The protocols are stored after the ObjCTypeParamType node. In the
/// canonical type, the list of protocols are sorted alphabetically
/// and uniqued.
ObjCProtocolDecl **getProtocolStorageImpl();
/// Return the number of qualifying protocols in this interface type,
/// or 0 if there are none.
unsigned getNumProtocolsImpl() const {
return NumProtocols;
}
void setNumProtocolsImpl(unsigned N) {
NumProtocols = N;
}
ObjCTypeParamType(const ObjCTypeParamDecl *D,
QualType can,
ArrayRef<ObjCProtocolDecl *> protocols);
public:
bool isSugared() const { return true; }
QualType desugar() const { return getCanonicalTypeInternal(); }
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCTypeParam;
}
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID,
const ObjCTypeParamDecl *OTPDecl,
ArrayRef<ObjCProtocolDecl *> protocols);
ObjCTypeParamDecl *getDecl() const { return OTPDecl; }
};
/// Represents a class type in Objective C.
///
/// Every Objective C type is a combination of a base type, a set of
@ -4724,7 +4838,9 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
/// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType
/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually
/// this should get its own sugar class to better represent the source.
class ObjCObjectType : public Type {
class ObjCObjectType : public Type,
public ObjCProtocolQualifiers<ObjCObjectType> {
friend class ObjCProtocolQualifiers<ObjCObjectType>;
// ObjCObjectType.NumTypeArgs - the number of type arguments stored
// after the ObjCObjectPointerType node.
// ObjCObjectType.NumProtocols - the number of protocols stored
@ -4744,16 +4860,20 @@ class ObjCObjectType : public Type {
mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool>
CachedSuperClassType;
ObjCProtocolDecl * const *getProtocolStorage() const {
return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
}
QualType *getTypeArgStorage();
const QualType *getTypeArgStorage() const {
return const_cast<ObjCObjectType *>(this)->getTypeArgStorage();
}
ObjCProtocolDecl **getProtocolStorage();
ObjCProtocolDecl **getProtocolStorageImpl();
/// Return the number of qualifying protocols in this interface type,
/// or 0 if there are none.
unsigned getNumProtocolsImpl() const {
return ObjCObjectTypeBits.NumProtocols;
}
void setNumProtocolsImpl(unsigned N) {
ObjCObjectTypeBits.NumProtocols = N;
}
protected:
ObjCObjectType(QualType Canonical, QualType Base,
@ -4830,30 +4950,6 @@ class ObjCObjectType : public Type {
ObjCObjectTypeBits.NumTypeArgs);
}
typedef ObjCProtocolDecl * const *qual_iterator;
typedef llvm::iterator_range<qual_iterator> qual_range;
qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
qual_iterator qual_begin() const { return getProtocolStorage(); }
qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
bool qual_empty() const { return getNumProtocols() == 0; }
/// Return the number of qualifying protocols in this interface type,
/// or 0 if there are none.
unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; }
/// Fetch a protocol by index.
ObjCProtocolDecl *getProtocol(unsigned I) const {
assert(I < getNumProtocols() && "Out-of-range protocol access");
return qual_begin()[I];
}
/// Retrieve all of the protocol qualifiers.
ArrayRef<ObjCProtocolDecl *> getProtocols() const {
return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols());
}
/// Whether this is a "__kindof" type as written.
bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; }
@ -4916,11 +5012,16 @@ inline QualType *ObjCObjectType::getTypeArgStorage() {
return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1);
}
inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorageImpl() {
return reinterpret_cast<ObjCProtocolDecl**>(
getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs);
}
inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() {
return reinterpret_cast<ObjCProtocolDecl**>(
static_cast<ObjCTypeParamType*>(this)+1);
}
/// Interfaces are the core concept in Objective-C for object oriented design.
/// They basically correspond to C++ classes. There are two kinds of interface
/// types: normal interfaces like `NSString`, and qualified interfaces, which
@ -5189,17 +5290,17 @@ class AtomicType : public Type, public llvm::FoldingSetNode {
/// PipeType - OpenCL20.
class PipeType : public Type, public llvm::FoldingSetNode {
QualType ElementType;
bool isRead;
PipeType(QualType elemType, QualType CanonicalPtr) :
PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) :
Type(Pipe, CanonicalPtr, elemType->isDependentType(),
elemType->isInstantiationDependentType(),
elemType->isVariablyModifiedType(),
elemType->containsUnexpandedParameterPack()),
ElementType(elemType) {}
ElementType(elemType), isRead(isRead) {}
friend class ASTContext; // ASTContext creates these.
public:
QualType getElementType() const { return ElementType; }
bool isSugared() const { return false; }
@ -5207,18 +5308,19 @@ class PipeType : public Type, public llvm::FoldingSetNode {
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getElementType());
Profile(ID, getElementType(), isReadOnly());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
static void Profile(llvm::FoldingSetNodeID &ID, QualType T, bool isRead) {
ID.AddPointer(T.getAsOpaquePtr());
ID.AddBoolean(isRead);
}
static bool classof(const Type *T) {
return T->getTypeClass() == Pipe;
}
bool isReadOnly() const { return isRead; }
};
/// A qualifier set is used to build a set of qualifiers.
@ -5696,8 +5798,8 @@ inline bool Type::isNullPtrType() const {
return false;
}
extern bool IsEnumDeclComplete(EnumDecl *);
extern bool IsEnumDeclScoped(EnumDecl *);
bool IsEnumDeclComplete(EnumDecl *);
bool IsEnumDeclScoped(EnumDecl *);
inline bool Type::isIntegerType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
@ -5807,17 +5909,15 @@ inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
// Helper class template that is used by Type::getAs to ensure that one does
// not try to look through a qualified type to get to an array type.
template <typename T, bool isArrayType = (std::is_same<T, ArrayType>::value ||
std::is_base_of<ArrayType, T>::value)>
struct ArrayType_cannot_be_used_with_getAs {};
template<typename T>
struct ArrayType_cannot_be_used_with_getAs<T, true>;
template <typename T>
using TypeIsArrayType =
std::integral_constant<bool, std::is_same<T, ArrayType>::value ||
std::is_base_of<ArrayType, T>::value>;
// Member-template getAs<specific type>'.
template <typename T> const T *Type::getAs() const {
ArrayType_cannot_be_used_with_getAs<T> at;
(void)at;
static_assert(!TypeIsArrayType<T>::value,
"ArrayType cannot be used with getAs!");
// If this is directly a T type, return it.
if (const T *Ty = dyn_cast<T>(this))
@ -5847,8 +5947,8 @@ inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
}
template <typename T> const T *Type::castAs() const {
ArrayType_cannot_be_used_with_getAs<T> at;
(void) at;
static_assert(!TypeIsArrayType<T>::value,
"ArrayType cannot be used with castAs!");
if (const T *ty = dyn_cast<T>(this)) return ty;
assert(isa<T>(CanonicalType));
@ -5861,6 +5961,23 @@ inline const ArrayType *Type::castAsArrayTypeUnsafe() const {
return cast<ArrayType>(getUnqualifiedDesugaredType());
}
DecayedType::DecayedType(QualType OriginalType, QualType DecayedPtr,
QualType CanonicalPtr)
: AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
#ifndef NDEBUG
QualType Adjusted = getAdjustedType();
(void)AttributedType::stripOuterNullability(Adjusted);
assert(isa<PointerType>(Adjusted));
#endif
}
QualType DecayedType::getPointeeType() const {
QualType Decayed = getDecayedType();
(void)AttributedType::stripOuterNullability(Decayed);
return cast<PointerType>(Decayed)->getPointeeType();
}
} // end namespace clang
#endif

View File

@ -347,7 +347,7 @@ class ConcreteTypeLoc : public Base {
public:
unsigned getLocalDataAlignment() const {
return std::max(llvm::alignOf<LocalData>(),
return std::max(unsigned(alignof(LocalData)),
asDerived()->getExtraLocalDataAlignment());
}
unsigned getLocalDataSize() const {
@ -487,8 +487,10 @@ class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
Type,
TypeSpecLocInfo> {
public:
enum { LocalDataSize = sizeof(TypeSpecLocInfo),
LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment };
enum {
LocalDataSize = sizeof(TypeSpecLocInfo),
LocalDataAlignment = alignof(TypeSpecLocInfo)
};
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
@ -510,7 +512,7 @@ class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
struct BuiltinLocInfo {
SourceLocation BuiltinLoc;
SourceRange BuiltinRange;
};
/// \brief Wrapper for source info for builtin types.
@ -520,10 +522,19 @@ class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
BuiltinLocInfo> {
public:
SourceLocation getBuiltinLoc() const {
return getLocalData()->BuiltinLoc;
return getLocalData()->BuiltinRange.getBegin();
}
void setBuiltinLoc(SourceLocation Loc) {
getLocalData()->BuiltinLoc = Loc;
getLocalData()->BuiltinRange = Loc;
}
void expandBuiltinRange(SourceRange Range) {
SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
if (!BuiltinRange.getBegin().isValid()) {
BuiltinRange = Range;
} else {
BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
}
}
SourceLocation getNameLoc() const { return getBuiltinLoc(); }
@ -548,11 +559,11 @@ class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
}
unsigned getExtraLocalDataAlignment() const {
return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1;
return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1;
}
SourceRange getLocalSourceRange() const {
return SourceRange(getBuiltinLoc(), getBuiltinLoc());
return getLocalData()->BuiltinRange;
}
TypeSpecifierSign getWrittenSignSpec() const {
@ -693,6 +704,91 @@ class TemplateTypeParmTypeLoc :
TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
struct ObjCTypeParamTypeLocInfo {
SourceLocation NameLoc;
};
/// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for
/// protocol qualifiers are stored after Info.
class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ObjCTypeParamTypeLoc,
ObjCTypeParamType,
ObjCTypeParamTypeLocInfo> {
// SourceLocations are stored after Info, one for each protocol qualifier.
SourceLocation *getProtocolLocArray() const {
return (SourceLocation*)this->getExtraLocalData() + 2;
}
public:
ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); }
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
}
void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
SourceLocation getProtocolLAngleLoc() const {
return getNumProtocols() ?
*((SourceLocation*)this->getExtraLocalData()) :
SourceLocation();
}
void setProtocolLAngleLoc(SourceLocation Loc) {
*((SourceLocation*)this->getExtraLocalData()) = Loc;
}
SourceLocation getProtocolRAngleLoc() const {
return getNumProtocols() ?
*((SourceLocation*)this->getExtraLocalData() + 1) :
SourceLocation();
}
void setProtocolRAngleLoc(SourceLocation Loc) {
*((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
}
unsigned getNumProtocols() const {
return this->getTypePtr()->getNumProtocols();
}
SourceLocation getProtocolLoc(unsigned i) const {
assert(i < getNumProtocols() && "Index is out of bounds!");
return getProtocolLocArray()[i];
}
void setProtocolLoc(unsigned i, SourceLocation Loc) {
assert(i < getNumProtocols() && "Index is out of bounds!");
getProtocolLocArray()[i] = Loc;
}
ObjCProtocolDecl *getProtocol(unsigned i) const {
assert(i < getNumProtocols() && "Index is out of bounds!");
return *(this->getTypePtr()->qual_begin() + i);
}
ArrayRef<SourceLocation> getProtocolLocs() const {
return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
unsigned getExtraLocalDataSize() const {
if (!this->getNumProtocols()) return 0;
// When there are protocol qualifers, we have LAngleLoc and RAngleLoc
// as well.
return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
}
unsigned getExtraLocalDataAlignment() const {
return alignof(SourceLocation);
}
SourceRange getLocalSourceRange() const {
SourceLocation start = getNameLoc();
SourceLocation end = getProtocolRAngleLoc();
if (end.isInvalid()) return SourceRange(start, start);
return SourceRange(start, end);
}
};
/// \brief Wrapper for substituted template type parameters.
class SubstTemplateTypeParmTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
@ -960,10 +1056,9 @@ class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
}
unsigned getExtraLocalDataAlignment() const {
assert(llvm::alignOf<ObjCObjectTypeLoc>()
>= llvm::alignOf<TypeSourceInfo *>() &&
"not enough alignment for tail-allocated data");
return llvm::alignOf<TypeSourceInfo *>();
static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
"not enough alignment for tail-allocated data");
return alignof(TypeSourceInfo *);
}
QualType getInnerType() const {
@ -1329,9 +1424,7 @@ class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
return getNumParams() * sizeof(ParmVarDecl *);
}
unsigned getExtraLocalDataAlignment() const {
return llvm::alignOf<ParmVarDecl*>();
}
unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
QualType getInnerType() const { return getTypePtr()->getReturnType(); }
};
@ -1525,7 +1618,7 @@ class TemplateSpecializationTypeLoc :
}
unsigned getExtraLocalDataAlignment() const {
return llvm::alignOf<TemplateArgumentLocInfo>();
return alignof(TemplateArgumentLocInfo);
}
private:
@ -1935,7 +2028,7 @@ class DependentTemplateSpecializationTypeLoc :
}
unsigned getExtraLocalDataAlignment() const {
return llvm::alignOf<TemplateArgumentLocInfo>();
return alignof(TemplateArgumentLocInfo);
}
private:

View File

@ -101,6 +101,7 @@ DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type)
NON_CANONICAL_TYPE(ObjCTypeParam, Type)
TYPE(ObjCObject, Type)
TYPE(ObjCInterface, ObjCObjectType)
TYPE(ObjCObjectPointer, Type)

View File

@ -17,7 +17,6 @@
#include "clang/AST/DeclAccessPair.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
@ -39,7 +38,9 @@ class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
: iterator_adaptor_base(const_cast<DeclAccessPair *>(Iter)) {}
public:
UnresolvedSetIterator() {}
// Work around a bug in MSVC 2013 where explicitly default constructed
// temporaries with defaulted ctors are not zero initialized.
UnresolvedSetIterator() : iterator_adaptor_base(nullptr) {}
NamedDecl *getDecl() const { return I->getDecl(); }
void setDecl(NamedDecl *ND) const { return I->setDecl(ND); }

View File

@ -20,7 +20,6 @@
#include "clang/AST/GlobalDecl.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/SetVector.h"
#include <utility>
namespace clang {

View File

@ -20,7 +20,6 @@
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
#include <memory>
#include <utility>
@ -219,77 +218,77 @@ class VTableComponent {
class VTableLayout {
public:
typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
typedef const VTableComponent *vtable_component_iterator;
typedef const VTableThunkTy *vtable_thunk_iterator;
typedef llvm::iterator_range<vtable_component_iterator>
vtable_component_range;
typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
struct AddressPointLocation {
unsigned VTableIndex, AddressPointIndex;
};
typedef llvm::DenseMap<BaseSubobject, AddressPointLocation>
AddressPointsMapTy;
private:
uint64_t NumVTableComponents;
std::unique_ptr<VTableComponent[]> VTableComponents;
// Stores the component indices of the first component of each virtual table in
// the virtual table group. To save a little memory in the common case where
// the vtable group contains a single vtable, an empty vector here represents
// the vector {0}.
OwningArrayRef<size_t> VTableIndices;
OwningArrayRef<VTableComponent> VTableComponents;
/// \brief Contains thunks needed by vtables, sorted by indices.
uint64_t NumVTableThunks;
std::unique_ptr<VTableThunkTy[]> VTableThunks;
OwningArrayRef<VTableThunkTy> VTableThunks;
/// \brief Address points for all vtables.
AddressPointsMapTy AddressPoints;
bool IsMicrosoftABI;
public:
VTableLayout(uint64_t NumVTableComponents,
const VTableComponent *VTableComponents,
uint64_t NumVTableThunks,
const VTableThunkTy *VTableThunks,
const AddressPointsMapTy &AddressPoints,
bool IsMicrosoftABI);
VTableLayout(ArrayRef<size_t> VTableIndices,
ArrayRef<VTableComponent> VTableComponents,
ArrayRef<VTableThunkTy> VTableThunks,
const AddressPointsMapTy &AddressPoints);
~VTableLayout();
uint64_t getNumVTableComponents() const {
return NumVTableComponents;
ArrayRef<VTableComponent> vtable_components() const {
return VTableComponents;
}
vtable_component_range vtable_components() const {
return vtable_component_range(vtable_component_begin(),
vtable_component_end());
ArrayRef<VTableThunkTy> vtable_thunks() const {
return VTableThunks;
}
vtable_component_iterator vtable_component_begin() const {
return VTableComponents.get();
}
vtable_component_iterator vtable_component_end() const {
return VTableComponents.get() + NumVTableComponents;
}
uint64_t getNumVTableThunks() const { return NumVTableThunks; }
vtable_thunk_iterator vtable_thunk_begin() const {
return VTableThunks.get();
}
vtable_thunk_iterator vtable_thunk_end() const {
return VTableThunks.get() + NumVTableThunks;
}
uint64_t getAddressPoint(BaseSubobject Base) const {
assert(AddressPoints.count(Base) &&
"Did not find address point!");
uint64_t AddressPoint = AddressPoints.lookup(Base);
assert(AddressPoint != 0 || IsMicrosoftABI);
(void)IsMicrosoftABI;
return AddressPoint;
AddressPointLocation getAddressPoint(BaseSubobject Base) const {
assert(AddressPoints.count(Base) && "Did not find address point!");
return AddressPoints.find(Base)->second;
}
const AddressPointsMapTy &getAddressPoints() const {
return AddressPoints;
}
size_t getNumVTables() const {
if (VTableIndices.empty())
return 1;
return VTableIndices.size();
}
size_t getVTableOffset(size_t i) const {
if (VTableIndices.empty()) {
assert(i == 0);
return 0;
}
return VTableIndices[i];
}
size_t getVTableSize(size_t i) const {
if (VTableIndices.empty()) {
assert(i == 0);
return vtable_components().size();
}
size_t thisIndex = VTableIndices[i];
size_t nextIndex = (i + 1 == VTableIndices.size())
? vtable_components().size()
: VTableIndices[i + 1];
return nextIndex - thisIndex;
}
};
class VTableContextBase {
@ -339,8 +338,9 @@ class ItaniumVTableContext : public VTableContextBase {
typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
MethodVTableIndicesTy MethodVTableIndices;
typedef llvm::DenseMap<const CXXRecordDecl *, const VTableLayout *>
VTableLayoutMapTy;
typedef llvm::DenseMap<const CXXRecordDecl *,
std::unique_ptr<const VTableLayout>>
VTableLayoutMapTy;
VTableLayoutMapTy VTableLayouts;
typedef std::pair<const CXXRecordDecl *,
@ -367,11 +367,9 @@ class ItaniumVTableContext : public VTableContextBase {
return *VTableLayouts[RD];
}
VTableLayout *
createConstructionVTableLayout(const CXXRecordDecl *MostDerivedClass,
CharUnits MostDerivedClassOffset,
bool MostDerivedClassIsVirtual,
const CXXRecordDecl *LayoutClass);
std::unique_ptr<VTableLayout> createConstructionVTableLayout(
const CXXRecordDecl *MostDerivedClass, CharUnits MostDerivedClassOffset,
bool MostDerivedClassIsVirtual, const CXXRecordDecl *LayoutClass);
/// \brief Locate a virtual function in the vtable.
///
@ -399,21 +397,21 @@ struct VPtrInfo {
typedef SmallVector<const CXXRecordDecl *, 1> BasePath;
VPtrInfo(const CXXRecordDecl *RD)
: ReusingBase(RD), BaseWithVPtr(RD), NextBaseToMangle(RD) {}
: ObjectWithVPtr(RD), IntroducingObject(RD), NextBaseToMangle(RD) {}
/// The vtable will hold all of the virtual bases or virtual methods of
/// ReusingBase. This may or may not be the same class as VPtrSubobject.Base.
/// A derived class will reuse the vptr of the first non-virtual base
/// subobject that has one.
const CXXRecordDecl *ReusingBase;
/// This is the most derived class that has this vptr at offset zero. When
/// single inheritance is used, this is always the most derived class. If
/// multiple inheritance is used, it may be any direct or indirect base.
const CXXRecordDecl *ObjectWithVPtr;
/// BaseWithVPtr is at this offset from its containing complete object or
/// This is the class that introduced the vptr by declaring new virtual
/// methods or virtual bases.
const CXXRecordDecl *IntroducingObject;
/// IntroducingObject is at this offset from its containing complete object or
/// virtual base.
CharUnits NonVirtualOffset;
/// The vptr is stored inside this subobject.
const CXXRecordDecl *BaseWithVPtr;
/// The bases from the inheritance path that got used to mangle the vbtable
/// name. This is not really a full path like a CXXBasePath. It holds the
/// subset of records that need to be mangled into the vbtable symbol name in
@ -432,7 +430,7 @@ struct VPtrInfo {
/// This holds the base classes path from the complete type to the first base
/// with the given vfptr offset, in the base-to-derived order. Only used for
/// vftables.
BasePath PathToBaseWithVPtr;
BasePath PathToIntroducingObject;
/// Static offset from the top of the most derived class to this vfptr,
/// including any virtual base offset. Only used for vftables.
@ -444,14 +442,12 @@ struct VPtrInfo {
}
};
typedef SmallVector<VPtrInfo *, 2> VPtrInfoVector;
typedef SmallVector<std::unique_ptr<VPtrInfo>, 2> VPtrInfoVector;
/// All virtual base related information about a given record decl. Includes
/// information on all virtual base tables and the path components that are used
/// to mangle them.
struct VirtualBaseInfo {
~VirtualBaseInfo() { llvm::DeleteContainerPointers(VBPtrPaths); }
/// A map from virtual base to vbtable index for doing a conversion from the
/// the derived class to the a base.
llvm::DenseMap<const CXXRecordDecl *, unsigned> VBTableIndices;
@ -504,15 +500,17 @@ class MicrosoftVTableContext : public VTableContextBase {
MethodVFTableLocationsTy;
MethodVFTableLocationsTy MethodVFTableLocations;
typedef llvm::DenseMap<const CXXRecordDecl *, VPtrInfoVector *>
VFPtrLocationsMapTy;
typedef llvm::DenseMap<const CXXRecordDecl *, VPtrInfoVector>
VFPtrLocationsMapTy;
VFPtrLocationsMapTy VFPtrLocations;
typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
typedef llvm::DenseMap<VFTableIdTy, const VTableLayout *> VFTableLayoutMapTy;
typedef llvm::DenseMap<VFTableIdTy, std::unique_ptr<const VTableLayout>>
VFTableLayoutMapTy;
VFTableLayoutMapTy VFTableLayouts;
llvm::DenseMap<const CXXRecordDecl *, VirtualBaseInfo *> VBaseInfo;
llvm::DenseMap<const CXXRecordDecl *, std::unique_ptr<VirtualBaseInfo>>
VBaseInfo;
void enumerateVFPtrs(const CXXRecordDecl *ForClass, VPtrInfoVector &Result);
@ -522,7 +520,7 @@ class MicrosoftVTableContext : public VTableContextBase {
const MethodVFTableLocationsTy &NewMethods,
raw_ostream &);
const VirtualBaseInfo *
const VirtualBaseInfo &
computeVBTableRelatedInformation(const CXXRecordDecl *RD);
void computeVTablePaths(bool ForVBTables, const CXXRecordDecl *RD,

View File

@ -158,6 +158,8 @@ class MatchFinder {
MatchCallback *Action);
void addMatcher(const TypeLocMatcher &NodeMatch,
MatchCallback *Action);
void addMatcher(const CXXCtorInitializerMatcher &NodeMatch,
MatchCallback *Action);
/// @}
/// \brief Adds a matcher to execute when running over the AST.
@ -208,6 +210,7 @@ class MatchFinder {
std::vector<std::pair<NestedNameSpecifierLocMatcher, MatchCallback *>>
NestedNameSpecifierLoc;
std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc;
std::vector<std::pair<CXXCtorInitializerMatcher, MatchCallback *>> CtorInit;
/// \brief All the callbacks in one container to simplify iteration.
llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks;
};
@ -229,6 +232,10 @@ class MatchFinder {
/// Multiple results occur when using matchers like \c forEachDescendant,
/// which generate a result for each sub-match.
///
/// If you want to find all matches on the sub-tree rooted at \c Node (rather
/// than only the matches on \c Node itself), surround the \c Matcher with a
/// \c findAll().
///
/// \see selectFirst
/// @{
template <typename MatcherT, typename NodeT>

View File

@ -51,7 +51,6 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Regex.h"
#include <iterator>
@ -76,18 +75,6 @@ class BoundNodes {
return MyBoundNodes.getNodeAs<T>(ID);
}
/// \brief Deprecated. Please use \c getNodeAs instead.
/// @{
template <typename T>
const T *getDeclAs(StringRef ID) const {
return getNodeAs<T>(ID);
}
template <typename T>
const T *getStmtAs(StringRef ID) const {
return getNodeAs<T>(ID);
}
/// @}
/// \brief Type of mapping from binding identifiers to bound nodes. This type
/// is an associative container with a key type of \c std::string and a value
/// type of \c clang::ast_type_traits::DynTypedNode
@ -126,6 +113,7 @@ typedef internal::Matcher<QualType> TypeMatcher;
typedef internal::Matcher<TypeLoc> TypeLocMatcher;
typedef internal::Matcher<NestedNameSpecifier> NestedNameSpecifierMatcher;
typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher;
typedef internal::Matcher<CXXCtorInitializer> CXXCtorInitializerMatcher;
/// @}
/// \brief Matches any node.
@ -447,6 +435,17 @@ const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
/// matches 'int' in C<int>.
const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
/// \brief Matches template name.
///
/// Given
/// \code
/// template <typename T> class X { };
/// X<int> xi;
/// \endcode
/// templateName()
/// matches 'X' in X<int>.
const internal::VariadicAllOfMatcher<TemplateName> templateName;
/// \brief Matches non-type template parameter declarations.
///
/// Given
@ -534,7 +533,8 @@ AST_MATCHER(FieldDecl, isBitField) {
return Node.isBitField();
}
/// \brief Matches non-static data members that are bit-fields.
/// \brief Matches non-static data members that are bit-fields of the specified
/// bit width.
///
/// Given
/// \code
@ -544,35 +544,66 @@ AST_MATCHER(FieldDecl, isBitField) {
/// int c : 2;
/// };
/// \endcode
/// fieldDecl(isBitField())
/// fieldDecl(hasBitWidth(2))
/// matches 'int a;' and 'int c;' but not 'int b;'.
AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) {
return Node.isBitField() &&
Node.getBitWidthValue(Finder->getASTContext()) == Width;
}
/// \brief Matches non-static data members that have an in-class initializer.
///
/// Given
/// \code
/// class C {
/// int a = 2;
/// int b = 3;
/// int c;
/// };
/// \endcode
/// fieldDecl(hasInClassInitializer(integerLiteral(equals(2))))
/// matches 'int a;' but not 'int b;'.
/// fieldDecl(hasInClassInitializer(anything()))
/// matches 'int a;' and 'int b;' but not 'int c;'.
AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher<Expr>,
InnerMatcher) {
const Expr *Initializer = Node.getInClassInitializer();
return (Initializer != nullptr &&
InnerMatcher.matches(*Initializer, Finder, Builder));
}
/// \brief Matches a declaration that has been implicitly added
/// by the compiler (eg. implicit default/copy constructors).
AST_MATCHER(Decl, isImplicit) {
return Node.isImplicit();
}
/// \brief Matches classTemplateSpecializations that have at least one
/// TemplateArgument matching the given InnerMatcher.
/// \brief Matches classTemplateSpecializations, templateSpecializationType and
/// functionDecl that have at least one TemplateArgument matching the given
/// InnerMatcher.
///
/// Given
/// \code
/// template<typename T> class A {};
/// template<> class A<double> {};
/// A<int> a;
///
/// template<typename T> f() {};
/// void func() { f<int>(); };
/// \endcode
///
/// \endcode
/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
/// refersToType(asString("int"))))
/// matches the specialization \c A<int>
///
/// functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
/// matches the specialization \c f<int>
AST_POLYMORPHIC_MATCHER_P(
hasAnyTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
TemplateSpecializationType),
TemplateSpecializationType,
FunctionDecl),
internal::Matcher<TemplateArgument>, InnerMatcher) {
ArrayRef<TemplateArgument> List =
internal::getTemplateSpecializationArgs(Node);
@ -699,22 +730,29 @@ AST_MATCHER_P(QualType, ignoringParens,
return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
}
/// \brief Matches classTemplateSpecializations where the n'th TemplateArgument
/// matches the given InnerMatcher.
/// \brief Matches classTemplateSpecializations, templateSpecializationType and
/// functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
///
/// Given
/// \code
/// template<typename T, typename U> class A {};
/// A<bool, int> b;
/// A<int, bool> c;
///
/// template<typename T> f() {};
/// void func() { f<int>(); };
/// \endcode
/// classTemplateSpecializationDecl(hasTemplateArgument(
/// 1, refersToType(asString("int"))))
/// matches the specialization \c A<bool, int>
///
/// functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
/// matches the specialization \c f<int>
AST_POLYMORPHIC_MATCHER_P2(
hasTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
TemplateSpecializationType),
TemplateSpecializationType,
FunctionDecl),
unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
ArrayRef<TemplateArgument> List =
internal::getTemplateSpecializationArgs(Node);
@ -758,6 +796,24 @@ AST_MATCHER_P(TemplateArgument, refersToType,
return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
}
/// \brief Matches a TemplateArgument that refers to a certain template.
///
/// Given
/// \code
/// template<template <typename> class S> class X {};
/// template<typename T> class Y {};"
/// X<Y> xi;
/// \endcode
/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
/// refersToTemplate(templateName())))
/// matches the specialization \c X<Y>
AST_MATCHER_P(TemplateArgument, refersToTemplate,
internal::Matcher<TemplateName>, InnerMatcher) {
if (Node.getKind() != TemplateArgument::Template)
return false;
return InnerMatcher.matches(Node.getAsTemplate(), Finder, Builder);
}
/// \brief Matches a canonical TemplateArgument that refers to a certain
/// declaration.
///
@ -1863,7 +1919,7 @@ const internal::VariadicDynCastAllOfMatcher<
/// \brief Matches a C-style cast expression.
///
/// Example: Matches (int*) 2.2f in
/// Example: Matches (int) 2.2f in
/// \code
/// int i = (int) 2.2f;
/// \endcode
@ -2404,16 +2460,18 @@ const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
/// - for CallExpr, the declaration of the callee
/// - for MemberExpr, the declaration of the referenced member
/// - for CXXConstructExpr, the declaration of the constructor
/// - for CXXNewExpr, the declaration of the operator new
///
/// Also usable as Matcher<T> for any T supporting the getDecl() member
/// function. e.g. various subtypes of clang::Type and various expressions.
///
/// Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
/// Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
/// Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
/// Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
/// Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
/// Matcher<TypedefType>, Matcher<UnresolvedUsingType>
/// Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>,
/// Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>,
/// Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<LabelStmt>,
/// Matcher<MemberExpr>, Matcher<QualType>, Matcher<RecordType>,
/// Matcher<TagType>, Matcher<TemplateSpecializationType>,
/// Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
/// Matcher<UnresolvedUsingType>
inline internal::PolymorphicMatcherWithParam1<
internal::HasDeclarationMatcher, internal::Matcher<Decl>,
void(internal::HasDeclarationSupportedTypes)>
@ -2423,6 +2481,25 @@ hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
void(internal::HasDeclarationSupportedTypes)>(InnerMatcher);
}
/// \brief Matches a \c NamedDecl whose underlying declaration matches the given
/// matcher.
///
/// Given
/// \code
/// namespace N { template<class T> void f(T t); }
/// template <class T> void g() { using N::f; f(T()); }
/// \endcode
/// \c unresolvedLookupExpr(hasAnyDeclaration(
/// namedDecl(hasUnderlyingDecl(hasName("::N::f")))))
/// matches the use of \c f in \c g() .
AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher<NamedDecl>,
InnerMatcher) {
const NamedDecl *UnderlyingDecl = Node.getUnderlyingDecl();
return UnderlyingDecl != nullptr &&
InnerMatcher.matches(*UnderlyingDecl, Finder, Builder);
}
/// \brief Matches on the implicit object argument of a member call expression.
///
/// Example matches y.x()
@ -2671,6 +2748,22 @@ AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>,
.matches(Node, Finder, Builder);
}
/// \brief Matches if the matched type matches the unqualified desugared
/// type of the matched node.
///
/// For example, in:
/// \code
/// class A {};
/// using B = A;
/// \endcode
/// The matcher type(hasUniqualifeidDesugaredType(recordType())) matches
/// both B and A.
AST_MATCHER_P(Type, hasUnqualifiedDesugaredType, internal::Matcher<Type>,
InnerMatcher) {
return InnerMatcher.matches(*Node.getUnqualifiedDesugaredType(), Finder,
Builder);
}
/// \brief Matches if the matched type is a reference type and the referenced
/// type matches the specified matcher.
///
@ -2778,6 +2871,27 @@ AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
return false;
}
/// \brief Matches an \c OverloadExpr if any of the declarations in the set of
/// overloads matches the given matcher.
///
/// Given
/// \code
/// template <typename T> void foo(T);
/// template <typename T> void bar(T);
/// template <typename T> void baz(T t) {
/// foo(t);
/// bar(t);
/// }
/// \endcode
/// unresolvedLookupExpr(hasAnyDeclaration(
/// functionTemplateDecl(hasName("foo"))))
/// matches \c foo in \c foo(t); but not \c bar in \c bar(t);
AST_MATCHER_P(OverloadExpr, hasAnyDeclaration, internal::Matcher<Decl>,
InnerMatcher) {
return matchesFirstInPointerRange(InnerMatcher, Node.decls_begin(),
Node.decls_end(), Finder, Builder);
}
/// \brief Matches the Decl of a DeclStmt which has a single declaration.
///
/// Given
@ -2857,9 +2971,9 @@ AST_MATCHER(VarDecl, hasAutomaticStorageDuration) {
}
/// \brief Matches a variable declaration that has static storage duration.
/// It includes the variable declared at namespace scope and those declared
/// with "static" and "extern" storage class specifiers.
///
/// Example matches y and a, but not x or z.
/// (matcher = varDecl(hasStaticStorageDuration())
/// \code
/// void f() {
/// int x;
@ -2867,6 +2981,10 @@ AST_MATCHER(VarDecl, hasAutomaticStorageDuration) {
/// thread_local int z;
/// }
/// int a;
/// static int b;
/// extern int c;
/// varDecl(hasStaticStorageDuration())
/// matches the function declaration y, a, b and c.
/// \endcode
AST_MATCHER(VarDecl, hasStaticStorageDuration) {
return Node.getStorageDuration() == SD_Static;
@ -3297,10 +3415,31 @@ AST_MATCHER_P(FunctionDecl, returns,
/// \endcode
/// functionDecl(isExternC())
/// matches the declaration of f and g, but not the declaration h
AST_MATCHER(FunctionDecl, isExternC) {
AST_POLYMORPHIC_MATCHER(isExternC, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
VarDecl)) {
return Node.isExternC();
}
/// \brief Matches variable/function declarations that have "static" storage
/// class specifier ("static" keyword) written in the source.
///
/// Given:
/// \code
/// static void f() {}
/// static int i = 0;
/// extern int j;
/// int k;
/// \endcode
/// functionDecl(isStaticStorageClass())
/// matches the function declaration f.
/// varDecl(isStaticStorageClass())
/// matches the variable declaration i.
AST_POLYMORPHIC_MATCHER(isStaticStorageClass,
AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
VarDecl)) {
return Node.getStorageClass() == SC_Static;
}
/// \brief Matches deleted function declarations.
///
/// Given:
@ -4075,7 +4214,7 @@ AST_MATCHER(QualType, isInteger) {
/// void b(unsigned long);
/// void c(double);
/// \endcode
/// functionDecl(hasAnyParameter(hasType(isInteger())))
/// functionDecl(hasAnyParameter(hasType(isUnsignedInteger())))
/// matches "b(unsigned long)", but not "a(int)" and "c(double)".
AST_MATCHER(QualType, isUnsignedInteger) {
return Node->isUnsignedIntegerType();
@ -4089,7 +4228,7 @@ AST_MATCHER(QualType, isUnsignedInteger) {
/// void b(unsigned long);
/// void c(double);
/// \endcode
/// functionDecl(hasAnyParameter(hasType(isInteger())))
/// functionDecl(hasAnyParameter(hasType(isSignedInteger())))
/// matches "a(int)", but not "b(unsigned long)" and "c(double)".
AST_MATCHER(QualType, isSignedInteger) {
return Node->isSignedIntegerType();
@ -4890,6 +5029,22 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
/// \c substTemplateTypeParmType() matches the type of 't' but not '1'
AST_TYPE_MATCHER(SubstTemplateTypeParmType, substTemplateTypeParmType);
/// \brief Matches template type parameter substitutions that have a replacement
/// type that matches the provided matcher.
///
/// Given
/// \code
/// template <typename T>
/// double F(T t);
/// int i;
/// double j = F(i);
/// \endcode
///
/// \c substTemplateTypeParmType(hasReplacementType(type())) matches int
AST_TYPE_TRAVERSE_MATCHER(
hasReplacementType, getReplacementType,
AST_POLYMORPHIC_SUPPORTED_TYPES(SubstTemplateTypeParmType));
/// \brief Matches template type parameter types.
///
/// Example matches T, but not int.
@ -5390,6 +5545,30 @@ AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>,
return false;
}
/// \brief Matches a declaration that has external formal linkage.
///
/// Example matches only z (matcher = varDecl(hasExternalFormalLinkage()))
/// \code
/// void f() {
/// int x;
/// static int y;
/// }
/// int z;
/// \endcode
///
/// Example matches f() because it has external formal linkage despite being
/// unique to the translation unit as though it has internal likage
/// (matcher = functionDecl(hasExternalFormalLinkage()))
///
/// \code
/// namespace {
/// void f() {}
/// }
/// \endcode
AST_MATCHER(NamedDecl, hasExternalFormalLinkage) {
return Node.hasExternalFormalLinkage();
}
} // end namespace ast_matchers
} // end namespace clang

View File

@ -787,6 +787,14 @@ class HasDeclarationMatcher : public WrapperMatcherInterface<T> {
return matchesDecl(Node.getConstructor(), Finder, Builder);
}
/// \brief Extracts the operator new of the new call and returns whether the
/// inner matcher matches on it.
bool matchesSpecialized(const CXXNewExpr &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
return matchesDecl(Node.getOperatorNew(), Finder, Builder);
}
/// \brief Extracts the \c ValueDecl a \c MemberExpr refers to and returns
/// whether the inner matcher matches on it.
bool matchesSpecialized(const MemberExpr &Node,
@ -1007,11 +1015,11 @@ typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
TypeLoc, QualType> AdaptativeDefaultToTypes;
/// \brief All types that are supported by HasDeclarationMatcher above.
typedef TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType,
typedef TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr,
QualType, RecordType, TagType, TemplateSpecializationType,
TemplateTypeParmType, TypedefType,
UnresolvedUsingType> HasDeclarationSupportedTypes;
TemplateTypeParmType, TypedefType, UnresolvedUsingType>
HasDeclarationSupportedTypes;
/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by
/// "adapting" a \c To into a \c T.
@ -1413,18 +1421,18 @@ class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
template <>
inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
const FloatingLiteral &Node) const {
if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
return Node.getValue().convertToFloat() == ExpectedValue;
if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
return Node.getValue().convertToDouble() == ExpectedValue;
return false;
}
template <>
inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
const FloatingLiteral &Node) const {
if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle)
if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
return Node.getValue().convertToFloat() == ExpectedValue;
if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble)
if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
return Node.getValue().convertToDouble() == ExpectedValue;
return false;
}
@ -1638,6 +1646,13 @@ getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
}
inline ArrayRef<TemplateArgument>
getTemplateSpecializationArgs(const FunctionDecl &FD) {
if (const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
return TemplateArgs->asArray();
return ArrayRef<TemplateArgument>();
}
struct NotEqualsBoundNodePredicate {
bool operator()(const internal::BoundNodesMap &Nodes) const {
return Nodes.getNode(ID) != Node;

View File

@ -97,7 +97,7 @@
class matcher_##DefineMatcher##Matcher \
: public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
public: \
explicit matcher_##DefineMatcher##Matcher() {} \
explicit matcher_##DefineMatcher##Matcher() = default; \
bool matches(const Type &Node, \
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
::clang::ast_matchers::internal::BoundNodesTreeBuilder \
@ -401,4 +401,4 @@
ReturnTypesF>::Func MatcherName##Loc; \
AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
#endif
#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H

View File

@ -1,4 +1,4 @@
//===--- Registry.h - Matcher registry -----*- C++ -*-===//
//===--- Registry.h - Matcher registry --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -19,28 +19,36 @@
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include <string>
#include <utility>
#include <vector>
namespace clang {
namespace ast_matchers {
namespace dynamic {
namespace internal {
class MatcherDescriptor;
}
} // end namespace internal
typedef const internal::MatcherDescriptor *MatcherCtor;
struct MatcherCompletion {
MatcherCompletion() {}
MatcherCompletion() = default;
MatcherCompletion(StringRef TypedText, StringRef MatcherDecl,
unsigned Specificity)
: TypedText(TypedText), MatcherDecl(MatcherDecl),
Specificity(Specificity) {}
bool operator==(const MatcherCompletion &Other) const {
return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
}
/// \brief The text to type to select this matcher.
std::string TypedText;
@ -53,14 +61,12 @@ struct MatcherCompletion {
/// matcher that will either always or never match.
/// Such matchers are excluded from code completion results.
unsigned Specificity;
bool operator==(const MatcherCompletion &Other) const {
return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
}
};
class Registry {
public:
Registry() = delete;
/// \brief Look up a matcher in the registry by name,
///
/// \return An opaque value which may be used to refer to the matcher
@ -121,13 +127,10 @@ class Registry {
StringRef BindID,
ArrayRef<ParserValue> Args,
Diagnostics *Error);
private:
Registry() = delete;
};
} // namespace dynamic
} // namespace ast_matchers
} // namespace clang
} // end namespace dynamic
} // end namespace ast_matchers
} // end namespace clang
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H

View File

@ -21,7 +21,6 @@
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/Twine.h"
#include <memory>
#include <vector>
@ -120,9 +119,9 @@ class VariantMatcher {
/// \brief Payload interface to be specialized by each matcher type.
///
/// It follows a similar interface as VariantMatcher itself.
class Payload : public RefCountedBaseVPTR {
class Payload : public RefCountedBase<Payload> {
public:
~Payload() override;
virtual ~Payload();
virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
virtual std::string getTypeAsString() const = 0;
virtual llvm::Optional<DynTypedMatcher>

View File

@ -201,11 +201,6 @@ namespace consumed {
public:
ConsumedBlockInfo() = default;
ConsumedBlockInfo &operator=(ConsumedBlockInfo &&Other) {
StateMapsArray = std::move(Other.StateMapsArray);
VisitOrder = std::move(Other.VisitOrder);
return *this;
}
ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph)
: StateMapsArray(NumBlocks), VisitOrder(NumBlocks, 0) {

View File

@ -167,43 +167,37 @@ class DominatorTree : public ManagedAnalysis {
///
namespace llvm {
template <> struct GraphTraits< ::clang::DomTreeNode* > {
typedef ::clang::DomTreeNode NodeType;
typedef ::clang::DomTreeNode *NodeRef;
typedef NodeType::iterator ChildIteratorType;
typedef ::clang::DomTreeNode::iterator ChildIteratorType;
static NodeType *getEntryNode(NodeType *N) {
return N;
}
static inline ChildIteratorType child_begin(NodeType *N) {
return N->begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
return N->end();
}
static NodeRef getEntryNode(NodeRef N) { return N; }
static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
static ChildIteratorType child_end(NodeRef N) { return N->end(); }
typedef df_iterator< ::clang::DomTreeNode* > nodes_iterator;
typedef llvm::pointer_iterator<df_iterator<::clang::DomTreeNode *>>
nodes_iterator;
static nodes_iterator nodes_begin(::clang::DomTreeNode *N) {
return df_begin(getEntryNode(N));
return nodes_iterator(df_begin(getEntryNode(N)));
}
static nodes_iterator nodes_end(::clang::DomTreeNode *N) {
return df_end(getEntryNode(N));
return nodes_iterator(df_end(getEntryNode(N)));
}
};
template <> struct GraphTraits< ::clang::DominatorTree* >
: public GraphTraits< ::clang::DomTreeNode* > {
static NodeType *getEntryNode(::clang::DominatorTree *DT) {
static NodeRef getEntryNode(::clang::DominatorTree *DT) {
return DT->getRootNode();
}
static nodes_iterator nodes_begin(::clang::DominatorTree *N) {
return df_begin(getEntryNode(N));
return nodes_iterator(df_begin(getEntryNode(N)));
}
static nodes_iterator nodes_end(::clang::DominatorTree *N) {
return df_end(getEntryNode(N));
return nodes_iterator(df_end(getEntryNode(N)));
}
};
} // end namespace llvm

View File

@ -35,7 +35,7 @@ class OptionalFlag {
public:
OptionalFlag(const char *Representation)
: representation(Representation), flag(false) {}
bool isSet() { return flag; }
bool isSet() const { return flag; }
void set() { flag = true; }
void clear() { flag = false; }
void setPosition(const char *position) {
@ -122,12 +122,13 @@ class ConversionSpecifier {
public:
enum Kind {
InvalidSpecifier = 0,
// C99 conversion specifiers.
// C99 conversion specifiers.
cArg,
dArg,
DArg, // Apple extension
iArg,
IntArgBeg = dArg, IntArgEnd = iArg,
IntArgBeg = dArg,
IntArgEnd = iArg,
oArg,
OArg, // Apple extension
@ -135,7 +136,8 @@ class ConversionSpecifier {
UArg, // Apple extension
xArg,
XArg,
UIntArgBeg = oArg, UIntArgEnd = XArg,
UIntArgBeg = oArg,
UIntArgEnd = XArg,
fArg,
FArg,
@ -145,7 +147,8 @@ class ConversionSpecifier {
GArg,
aArg,
AArg,
DoubleArgBeg = fArg, DoubleArgEnd = AArg,
DoubleArgBeg = fArg,
DoubleArgEnd = AArg,
sArg,
pArg,
@ -154,13 +157,19 @@ class ConversionSpecifier {
CArg,
SArg,
// Apple extension: P specifies to os_log that the data being pointed to is
// to be copied by os_log. The precision indicates the number of bytes to
// copy.
PArg,
// ** Printf-specific **
ZArg, // MS extension
// Objective-C specific specifiers.
ObjCObjArg, // '@'
ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg,
ObjCObjArg, // '@'
ObjCBeg = ObjCObjArg,
ObjCEnd = ObjCObjArg,
// FreeBSD kernel specific specifiers.
FreeBSDbArg,
@ -169,13 +178,15 @@ class ConversionSpecifier {
FreeBSDyArg,
// GlibC specific specifiers.
PrintErrno, // 'm'
PrintErrno, // 'm'
PrintfConvBeg = ObjCObjArg, PrintfConvEnd = PrintErrno,
PrintfConvBeg = ObjCObjArg,
PrintfConvEnd = PrintErrno,
// ** Scanf-specific **
ScanListArg, // '['
ScanfConvBeg = ScanListArg, ScanfConvEnd = ScanListArg
ScanfConvBeg = ScanListArg,
ScanfConvEnd = ScanListArg
};
ConversionSpecifier(bool isPrintf = true)
@ -200,6 +211,8 @@ class ConversionSpecifier {
return false;
case PercentArg:
return false;
case InvalidSpecifier:
return false;
default:
return true;
}
@ -437,13 +450,15 @@ class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
OptionalFlag HasAlternativeForm; // '#'
OptionalFlag HasLeadingZeroes; // '0'
OptionalFlag HasObjCTechnicalTerm; // '[tt]'
OptionalFlag IsPrivate; // '{private}'
OptionalFlag IsPublic; // '{public}'
OptionalAmount Precision;
public:
PrintfSpecifier() :
FormatSpecifier(/* isPrintf = */ true),
HasThousandsGrouping("'"), IsLeftJustified("-"), HasPlusPrefix("+"),
HasSpacePrefix(" "), HasAlternativeForm("#"), HasLeadingZeroes("0"),
HasObjCTechnicalTerm("tt") {}
PrintfSpecifier()
: FormatSpecifier(/* isPrintf = */ true), HasThousandsGrouping("'"),
IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "),
HasAlternativeForm("#"), HasLeadingZeroes("0"),
HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public") {}
static PrintfSpecifier Parse(const char *beg, const char *end);
@ -472,6 +487,8 @@ class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
void setHasObjCTechnicalTerm(const char *position) {
HasObjCTechnicalTerm.setPosition(position);
}
void setIsPrivate(const char *position) { IsPrivate.setPosition(position); }
void setIsPublic(const char *position) { IsPublic.setPosition(position); }
void setUsesPositionalArg() { UsesPositionalArg = true; }
// Methods for querying the format specifier.
@ -509,6 +526,8 @@ class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; }
const OptionalFlag &isPrivate() const { return IsPrivate; }
const OptionalFlag &isPublic() const { return IsPublic; }
bool usesPositionalArg() const { return UsesPositionalArg; }
/// Changes the specifier and length according to a QualType, retaining any

View File

@ -16,7 +16,6 @@
#include "clang/AST/Decl.h"
#include "clang/Analysis/AnalysisContext.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ImmutableSet.h"
namespace clang {

View File

@ -0,0 +1,155 @@
//= OSLog.h - Analysis of calls to os_log builtins --*- C++ -*-===============//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines APIs for determining the layout of the data buffer for
// os_log() and os_trace().
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
namespace clang {
namespace analyze_os_log {
/// An OSLogBufferItem represents a single item in the data written by a call
/// to os_log() or os_trace().
class OSLogBufferItem {
public:
enum Kind {
// The item is a scalar (int, float, raw pointer, etc.). No further copying
// is required. This is the only kind allowed by os_trace().
ScalarKind = 0,
// The item is a count, which describes the length of the following item to
// be copied. A count may only be followed by an item of kind StringKind,
// WideStringKind, or PointerKind.
CountKind,
// The item is a pointer to a C string. If preceded by a count 'n',
// os_log() will copy at most 'n' bytes from the pointer.
StringKind,
// The item is a pointer to a block of raw data. This item must be preceded
// by a count 'n'. os_log() will copy exactly 'n' bytes from the pointer.
PointerKind,
// The item is a pointer to an Objective-C object. os_log() may retain the
// object for later processing.
ObjCObjKind,
// The item is a pointer to wide-char string.
WideStringKind,
// The item is corresponding to the '%m' format specifier, no value is
// populated in the buffer and the runtime is loading the errno value.
ErrnoKind
};
enum {
// The item is marked "private" in the format string.
IsPrivate = 0x1,
// The item is marked "public" in the format string.
IsPublic = 0x2
};
private:
Kind TheKind = ScalarKind;
const Expr *TheExpr = nullptr;
CharUnits ConstValue;
CharUnits Size; // size of the data, not including the header bytes
unsigned Flags = 0;
public:
OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags)
: TheKind(kind), TheExpr(expr), Size(size), Flags(flags) {}
OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)
: TheKind(CountKind), ConstValue(value),
Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {}
unsigned char getDescriptorByte() const {
unsigned char result = 0;
if (getIsPrivate())
result |= IsPrivate;
if (getIsPublic())
result |= IsPublic;
result |= ((unsigned)getKind()) << 4;
return result;
}
unsigned char getSizeByte() const { return size().getQuantity(); }
Kind getKind() const { return TheKind; }
bool getIsPrivate() const { return (Flags & IsPrivate) != 0; }
bool getIsPublic() const { return (Flags & IsPublic) != 0; }
const Expr *getExpr() const { return TheExpr; }
CharUnits getConstValue() const { return ConstValue; }
CharUnits size() const { return Size; }
};
class OSLogBufferLayout {
public:
SmallVector<OSLogBufferItem, 4> Items;
enum Flags { HasPrivateItems = 1, HasNonScalarItems = 1 << 1 };
CharUnits size() const {
CharUnits result;
result += CharUnits::fromQuantity(2); // summary byte, num-args byte
for (auto &item : Items) {
// descriptor byte, size byte
result += item.size() + CharUnits::fromQuantity(2);
}
return result;
}
bool hasPrivateItems() const {
return llvm::any_of(
Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); });
}
bool hasPublicItems() const {
return llvm::any_of(
Items, [](const OSLogBufferItem &Item) { return Item.getIsPublic(); });
}
bool hasNonScalar() const {
return llvm::any_of(Items, [](const OSLogBufferItem &Item) {
return Item.getKind() != OSLogBufferItem::ScalarKind;
});
}
unsigned char getSummaryByte() const {
unsigned char result = 0;
if (hasPrivateItems())
result |= HasPrivateItems;
if (hasNonScalar())
result |= HasNonScalarItems;
return result;
}
unsigned char getNumArgsByte() const { return Items.size(); }
};
// Given a call 'E' to one of the builtins __builtin_os_log_format() or
// __builtin_os_log_format_buffer_size(), compute the layout of the buffer that
// the call will write into and store it in 'layout'. Returns 'false' if there
// was some error encountered while computing the layout, and 'true' otherwise.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E,
OSLogBufferLayout &layout);
} // namespace analyze_os_log
} // namespace clang
#endif

View File

@ -415,25 +415,8 @@ class SExprBuilder {
BlockInfo()
: HasBackEdges(false), UnprocessedSuccessors(0),
ProcessedPredecessors(0) {}
BlockInfo(BlockInfo &&RHS)
: ExitMap(std::move(RHS.ExitMap)),
HasBackEdges(RHS.HasBackEdges),
UnprocessedSuccessors(RHS.UnprocessedSuccessors),
ProcessedPredecessors(RHS.ProcessedPredecessors) {}
BlockInfo &operator=(BlockInfo &&RHS) {
if (this != &RHS) {
ExitMap = std::move(RHS.ExitMap);
HasBackEdges = RHS.HasBackEdges;
UnprocessedSuccessors = RHS.UnprocessedSuccessors;
ProcessedPredecessors = RHS.ProcessedPredecessors;
}
return *this;
}
private:
BlockInfo(const BlockInfo &) = delete;
void operator=(const BlockInfo &) = delete;
BlockInfo(BlockInfo &&) = default;
BlockInfo &operator=(BlockInfo &&) = default;
};
// We implement the CFGVisitor API

View File

@ -45,7 +45,7 @@ class MemRegionRef {
MemRegionRef(llvm::BumpPtrAllocator *A) : Allocator(A) {}
void *allocate(size_t Sz) {
return Allocator->Allocate(Sz, llvm::AlignOf<AlignmentType>::Alignment);
return Allocator->Allocate(Sz, alignof(AlignmentType));
}
template <typename T> T *allocateT() { return Allocator->Allocate<T>(); }

View File

@ -406,7 +406,8 @@ class LocationContextManager {
};
class AnalysisDeclContextManager {
typedef llvm::DenseMap<const Decl*, AnalysisDeclContext*> ContextMap;
typedef llvm::DenseMap<const Decl *, std::unique_ptr<AnalysisDeclContext>>
ContextMap;
ContextMap Contexts;
LocationContextManager LocContexts;

View File

@ -22,6 +22,7 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
@ -522,11 +523,15 @@ class CFGBlock {
typedef AdjacentBlocks::const_iterator const_pred_iterator;
typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator;
typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator;
typedef llvm::iterator_range<pred_iterator> pred_range;
typedef llvm::iterator_range<const_pred_iterator> pred_const_range;
typedef AdjacentBlocks::iterator succ_iterator;
typedef AdjacentBlocks::const_iterator const_succ_iterator;
typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator;
typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator;
typedef llvm::iterator_range<succ_iterator> succ_range;
typedef llvm::iterator_range<const_succ_iterator> succ_const_range;
pred_iterator pred_begin() { return Preds.begin(); }
pred_iterator pred_end() { return Preds.end(); }
@ -538,6 +543,13 @@ class CFGBlock {
const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); }
const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
pred_range preds() {
return pred_range(pred_begin(), pred_end());
}
pred_const_range preds() const {
return pred_const_range(pred_begin(), pred_end());
}
succ_iterator succ_begin() { return Succs.begin(); }
succ_iterator succ_end() { return Succs.end(); }
const_succ_iterator succ_begin() const { return Succs.begin(); }
@ -548,6 +560,13 @@ class CFGBlock {
const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); }
const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
succ_range succs() {
return succ_range(succ_begin(), succ_end());
}
succ_const_range succs() const {
return succ_const_range(succ_begin(), succ_end());
}
unsigned succ_size() const { return Succs.size(); }
bool succ_empty() const { return Succs.empty(); }
@ -761,55 +780,6 @@ class CFG {
AddCXXNewAllocator(false), AddCXXDefaultInitExprInCtors(false) {}
};
/// \brief Provides a custom implementation of the iterator class to have the
/// same interface as Function::iterator - iterator returns CFGBlock
/// (not a pointer to CFGBlock).
class graph_iterator {
public:
typedef CFGBlock value_type;
typedef value_type& reference;
typedef value_type* pointer;
typedef BumpVector<CFGBlock*>::iterator ImplTy;
graph_iterator(const ImplTy &i) : I(i) {}
bool operator==(const graph_iterator &X) const { return I == X.I; }
bool operator!=(const graph_iterator &X) const { return I != X.I; }
reference operator*() const { return **I; }
pointer operator->() const { return *I; }
operator CFGBlock* () { return *I; }
graph_iterator &operator++() { ++I; return *this; }
graph_iterator &operator--() { --I; return *this; }
private:
ImplTy I;
};
class const_graph_iterator {
public:
typedef const CFGBlock value_type;
typedef value_type& reference;
typedef value_type* pointer;
typedef BumpVector<CFGBlock*>::const_iterator ImplTy;
const_graph_iterator(const ImplTy &i) : I(i) {}
bool operator==(const const_graph_iterator &X) const { return I == X.I; }
bool operator!=(const const_graph_iterator &X) const { return I != X.I; }
reference operator*() const { return **I; }
pointer operator->() const { return *I; }
operator CFGBlock* () const { return *I; }
const_graph_iterator &operator++() { ++I; return *this; }
const_graph_iterator &operator--() { --I; return *this; }
private:
ImplTy I;
};
/// buildCFG - Builds a CFG from an AST.
static std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
const BuildOptions &BO);
@ -845,14 +815,10 @@ class CFG {
const_iterator begin() const { return Blocks.begin(); }
const_iterator end() const { return Blocks.end(); }
graph_iterator nodes_begin() { return graph_iterator(Blocks.begin()); }
graph_iterator nodes_end() { return graph_iterator(Blocks.end()); }
const_graph_iterator nodes_begin() const {
return const_graph_iterator(Blocks.begin());
}
const_graph_iterator nodes_end() const {
return const_graph_iterator(Blocks.end());
}
iterator nodes_begin() { return iterator(Blocks.begin()); }
iterator nodes_end() { return iterator(Blocks.end()); }
const_iterator nodes_begin() const { return const_iterator(Blocks.begin()); }
const_iterator nodes_end() const { return const_iterator(Blocks.end()); }
reverse_iterator rbegin() { return Blocks.rbegin(); }
reverse_iterator rend() { return Blocks.rend(); }
@ -893,6 +859,7 @@ class CFG {
typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator
synthetic_stmt_iterator;
typedef llvm::iterator_range<synthetic_stmt_iterator> synthetic_stmt_range;
/// Iterates over synthetic DeclStmts in the CFG.
///
@ -908,6 +875,11 @@ class CFG {
return SyntheticDeclStmts.end();
}
/// \sa synthetic_stmt_begin
synthetic_stmt_range synthetic_stmts() const {
return synthetic_stmt_range(synthetic_stmt_begin(), synthetic_stmt_end());
}
//===--------------------------------------------------------------------===//
// Member templates useful for various batch operations over CFGs.
//===--------------------------------------------------------------------===//
@ -998,59 +970,51 @@ template <> struct simplify_type< ::clang::CFGTerminator> {
// Traits for: CFGBlock
template <> struct GraphTraits< ::clang::CFGBlock *> {
typedef ::clang::CFGBlock NodeType;
typedef ::clang::CFGBlock *NodeRef;
typedef ::clang::CFGBlock::succ_iterator ChildIteratorType;
static NodeType* getEntryNode(::clang::CFGBlock *BB)
{ return BB; }
static NodeRef getEntryNode(::clang::CFGBlock *BB) { return BB; }
static inline ChildIteratorType child_begin(NodeType* N)
{ return N->succ_begin(); }
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
static inline ChildIteratorType child_end(NodeType* N)
{ return N->succ_end(); }
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
};
template <> struct GraphTraits< const ::clang::CFGBlock *> {
typedef const ::clang::CFGBlock NodeType;
typedef const ::clang::CFGBlock *NodeRef;
typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType;
static NodeType* getEntryNode(const clang::CFGBlock *BB)
{ return BB; }
static NodeRef getEntryNode(const clang::CFGBlock *BB) { return BB; }
static inline ChildIteratorType child_begin(NodeType* N)
{ return N->succ_begin(); }
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
static inline ChildIteratorType child_end(NodeType* N)
{ return N->succ_end(); }
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
};
template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > {
typedef ::clang::CFGBlock NodeType;
typedef ::clang::CFGBlock *NodeRef;
typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
static NodeType *getEntryNode(Inverse< ::clang::CFGBlock*> G)
{ return G.Graph; }
static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G) {
return G.Graph;
}
static inline ChildIteratorType child_begin(NodeType* N)
{ return N->pred_begin(); }
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
static inline ChildIteratorType child_end(NodeType* N)
{ return N->pred_end(); }
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
};
template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
typedef const ::clang::CFGBlock NodeType;
typedef const ::clang::CFGBlock *NodeRef;
typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
static NodeType *getEntryNode(Inverse<const ::clang::CFGBlock*> G)
{ return G.Graph; }
static NodeRef getEntryNode(Inverse<const ::clang::CFGBlock *> G) {
return G.Graph;
}
static inline ChildIteratorType child_begin(NodeType* N)
{ return N->pred_begin(); }
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
static inline ChildIteratorType child_end(NodeType* N)
{ return N->pred_end(); }
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
};
// Traits for: CFG
@ -1058,9 +1022,9 @@ template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
template <> struct GraphTraits< ::clang::CFG* >
: public GraphTraits< ::clang::CFGBlock *> {
typedef ::clang::CFG::graph_iterator nodes_iterator;
typedef ::clang::CFG::iterator nodes_iterator;
static NodeType *getEntryNode(::clang::CFG* F) { return &F->getEntry(); }
static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); }
static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
static nodes_iterator nodes_end(::clang::CFG* F) { return F->nodes_end(); }
static unsigned size(::clang::CFG* F) { return F->size(); }
@ -1069,11 +1033,9 @@ template <> struct GraphTraits< ::clang::CFG* >
template <> struct GraphTraits<const ::clang::CFG* >
: public GraphTraits<const ::clang::CFGBlock *> {
typedef ::clang::CFG::const_graph_iterator nodes_iterator;
typedef ::clang::CFG::const_iterator nodes_iterator;
static NodeType *getEntryNode( const ::clang::CFG* F) {
return &F->getEntry();
}
static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); }
static nodes_iterator nodes_begin( const ::clang::CFG* F) {
return F->nodes_begin();
}
@ -1088,9 +1050,9 @@ template <> struct GraphTraits<const ::clang::CFG* >
template <> struct GraphTraits<Inverse< ::clang::CFG*> >
: public GraphTraits<Inverse< ::clang::CFGBlock*> > {
typedef ::clang::CFG::graph_iterator nodes_iterator;
typedef ::clang::CFG::iterator nodes_iterator;
static NodeType *getEntryNode( ::clang::CFG* F) { return &F->getExit(); }
static NodeRef getEntryNode(::clang::CFG *F) { return &F->getExit(); }
static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
};
@ -1098,9 +1060,9 @@ template <> struct GraphTraits<Inverse< ::clang::CFG*> >
template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
: public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
typedef ::clang::CFG::const_graph_iterator nodes_iterator;
typedef ::clang::CFG::const_iterator nodes_iterator;
static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); }
static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); }
static nodes_iterator nodes_begin(const ::clang::CFG* F) {
return F->nodes_begin();
}

View File

@ -34,7 +34,8 @@ class CallGraphNode;
class CallGraph : public RecursiveASTVisitor<CallGraph> {
friend class CallGraphNode;
typedef llvm::DenseMap<const Decl *, CallGraphNode *> FunctionMapTy;
typedef llvm::DenseMap<const Decl *, std::unique_ptr<CallGraphNode>>
FunctionMapTy;
/// FunctionMap owns all CallGraphNodes.
FunctionMapTy FunctionMap;
@ -156,7 +157,7 @@ class CallGraphNode {
inline bool empty() const {return CalledFunctions.empty(); }
inline unsigned size() const {return CalledFunctions.size(); }
void addCallee(CallGraphNode *N, CallGraph *CG) {
void addCallee(CallGraphNode *N) {
CalledFunctions.push_back(N);
}
@ -172,25 +173,21 @@ class CallGraphNode {
namespace llvm {
template <> struct GraphTraits<clang::CallGraphNode*> {
typedef clang::CallGraphNode NodeType;
typedef clang::CallGraphNode::CallRecord CallRecordTy;
typedef std::pointer_to_unary_function<CallRecordTy,
clang::CallGraphNode*> CGNDerefFun;
typedef clang::CallGraphNode *NodeRef;
typedef NodeType::iterator ChildIteratorType;
static NodeType *getEntryNode(clang::CallGraphNode *CGN) { return CGN; }
typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
static inline ChildIteratorType child_begin(NodeType *N) {
return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
}
static inline ChildIteratorType child_end (NodeType *N) {
return map_iterator(N->end(), CGNDerefFun(CGNDeref));
}
static clang::CallGraphNode *CGNDeref(CallRecordTy P) {
return P;
return N->begin();
}
static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
};
template <> struct GraphTraits<const clang::CallGraphNode*> {
typedef const clang::CallGraphNode NodeType;
typedef const clang::CallGraphNode *NodeRef;
typedef NodeType::const_iterator ChildIteratorType;
static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; }
static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
@ -202,19 +199,21 @@ template <> struct GraphTraits<clang::CallGraph*>
static NodeType *getEntryNode(clang::CallGraph *CGN) {
return CGN->getRoot(); // Start at the external node!
}
typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
static clang::CallGraphNode *
CGGetValue(clang::CallGraph::const_iterator::value_type &P) {
return P.second.get();
}
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef mapped_iterator<clang::CallGraph::iterator, DerefFun> nodes_iterator;
typedef mapped_iterator<clang::CallGraph::iterator, decltype(&CGGetValue)>
nodes_iterator;
static nodes_iterator nodes_begin(clang::CallGraph *CG) {
return map_iterator(CG->begin(), DerefFun(CGdereference));
return nodes_iterator(CG->begin(), &CGGetValue);
}
static nodes_iterator nodes_end (clang::CallGraph *CG) {
return map_iterator(CG->end(), DerefFun(CGdereference));
}
static clang::CallGraphNode &CGdereference(PairTy P) {
return *(P.second);
return nodes_iterator(CG->end(), &CGGetValue);
}
static unsigned size(clang::CallGraph *CG) {
@ -227,22 +226,23 @@ template <> struct GraphTraits<const clang::CallGraph*> :
static NodeType *getEntryNode(const clang::CallGraph *CGN) {
return CGN->getRoot();
}
typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
static clang::CallGraphNode *
CGGetValue(clang::CallGraph::const_iterator::value_type &P) {
return P.second.get();
}
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef mapped_iterator<clang::CallGraph::const_iterator,
DerefFun> nodes_iterator;
decltype(&CGGetValue)>
nodes_iterator;
static nodes_iterator nodes_begin(const clang::CallGraph *CG) {
return map_iterator(CG->begin(), DerefFun(CGdereference));
return nodes_iterator(CG->begin(), &CGGetValue);
}
static nodes_iterator nodes_end(const clang::CallGraph *CG) {
return map_iterator(CG->end(), DerefFun(CGdereference));
return nodes_iterator(CG->end(), &CGGetValue);
}
static clang::CallGraphNode &CGdereference(PairTy P) {
return *(P.second);
}
static unsigned size(const clang::CallGraph *CG) {
return CG->size();
}

View File

@ -0,0 +1,288 @@
//===--- CloneDetection.h - Finds code clones in an AST ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// /file
/// This file defines classes for searching and anlyzing source code clones.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_CLONEDETECTION_H
#define LLVM_CLANG_AST_CLONEDETECTION_H
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringMap.h"
#include <vector>
namespace clang {
class Stmt;
class Decl;
class VarDecl;
class ASTContext;
class CompoundStmt;
/// \brief Identifies a list of statements.
///
/// Can either identify a single arbitrary Stmt object, a continuous sequence of
/// child statements inside a CompoundStmt or no statements at all.
class StmtSequence {
/// If this object identifies a sequence of statements inside a CompoundStmt,
/// S points to this CompoundStmt. If this object only identifies a single
/// Stmt, then S is a pointer to this Stmt.
const Stmt *S;
/// The related ASTContext for S.
ASTContext *Context;
/// If EndIndex is non-zero, then S is a CompoundStmt and this StmtSequence
/// instance is representing the CompoundStmt children inside the array
/// [StartIndex, EndIndex).
unsigned StartIndex;
unsigned EndIndex;
public:
/// \brief Constructs a StmtSequence holding multiple statements.
///
/// The resulting StmtSequence identifies a continuous sequence of statements
/// in the body of the given CompoundStmt. Which statements of the body should
/// be identified needs to be specified by providing a start and end index
/// that describe a non-empty sub-array in the body of the given CompoundStmt.
///
/// \param Stmt A CompoundStmt that contains all statements in its body.
/// \param Context The ASTContext for the given CompoundStmt.
/// \param StartIndex The inclusive start index in the children array of
/// \p Stmt
/// \param EndIndex The exclusive end index in the children array of \p Stmt.
StmtSequence(const CompoundStmt *Stmt, ASTContext &Context,
unsigned StartIndex, unsigned EndIndex);
/// \brief Constructs a StmtSequence holding a single statement.
///
/// \param Stmt An arbitrary Stmt.
/// \param Context The ASTContext for the given Stmt.
StmtSequence(const Stmt *Stmt, ASTContext &Context);
/// \brief Constructs an empty StmtSequence.
StmtSequence();
typedef const Stmt *const *iterator;
/// Returns an iterator pointing to the first statement in this sequence.
iterator begin() const;
/// Returns an iterator pointing behind the last statement in this sequence.
iterator end() const;
/// Returns the first statement in this sequence.
///
/// This method should only be called on a non-empty StmtSequence object.
const Stmt *front() const {
assert(!empty());
return begin()[0];
}
/// Returns the last statement in this sequence.
///
/// This method should only be called on a non-empty StmtSequence object.
const Stmt *back() const {
assert(!empty());
return begin()[size() - 1];
}
/// Returns the number of statements this object holds.
unsigned size() const {
if (holdsSequence())
return EndIndex - StartIndex;
if (S == nullptr)
return 0;
return 1;
}
/// Returns true if and only if this StmtSequence contains no statements.
bool empty() const { return size() == 0; }
/// Returns the related ASTContext for the stored Stmts.
ASTContext &getASTContext() const {
assert(Context);
return *Context;
}
/// Returns true if this objects holds a list of statements.
bool holdsSequence() const { return EndIndex != 0; }
/// Returns the start sourcelocation of the first statement in this sequence.
///
/// This method should only be called on a non-empty StmtSequence object.
SourceLocation getStartLoc() const;
/// Returns the end sourcelocation of the last statement in this sequence.
///
/// This method should only be called on a non-empty StmtSequence object.
SourceLocation getEndLoc() const;
/// Returns the source range of the whole sequence - from the beginning
/// of the first statement to the end of the last statement.
SourceRange getSourceRange() const;
bool operator==(const StmtSequence &Other) const {
return std::tie(S, StartIndex, EndIndex) ==
std::tie(Other.S, Other.StartIndex, Other.EndIndex);
}
bool operator!=(const StmtSequence &Other) const {
return std::tie(S, StartIndex, EndIndex) !=
std::tie(Other.S, Other.StartIndex, Other.EndIndex);
}
/// Returns true if and only if this sequence covers a source range that
/// contains the source range of the given sequence \p Other.
///
/// This method should only be called on a non-empty StmtSequence object
/// and passed a non-empty StmtSequence object.
bool contains(const StmtSequence &Other) const;
};
/// \brief Searches for clones in source code.
///
/// First, this class needs a translation unit which is passed via
/// \p analyzeTranslationUnit . It will then generate and store search data
/// for all statements inside the given translation unit.
/// Afterwards the generated data can be used to find code clones by calling
/// \p findClones .
///
/// This class only searches for clones in exectuable source code
/// (e.g. function bodies). Other clones (e.g. cloned comments or declarations)
/// are not supported.
class CloneDetector {
public:
typedef unsigned DataPiece;
/// Holds the data about a StmtSequence that is needed during the search for
/// code clones.
struct CloneSignature {
/// \brief The hash code of the StmtSequence.
///
/// The initial clone groups that are formed during the search for clones
/// consist only of Sequences that share the same hash code. This makes this
/// value the central part of this heuristic that is needed to find clones
/// in a performant way. For this to work, the type of this variable
/// always needs to be small and fast to compare.
///
/// Also, StmtSequences that are clones of each others have to share
/// the same hash code. StmtSequences that are not clones of each other
/// shouldn't share the same hash code, but if they do, it will only
/// degrade the performance of the hash search but doesn't influence
/// the correctness of the result.
size_t Hash;
/// \brief The complexity of the StmtSequence.
///
/// This value gives an approximation on how many direct or indirect child
/// statements are contained in the related StmtSequence. In general, the
/// greater this value, the greater the amount of statements. However, this
/// is only an approximation and the actual amount of statements can be
/// higher or lower than this value. Statements that are generated by the
/// compiler (e.g. macro expansions) for example barely influence the
/// complexity value.
///
/// The main purpose of this value is to filter clones that are too small
/// and therefore probably not interesting enough for the user.
unsigned Complexity;
/// \brief Creates an empty CloneSignature without any data.
CloneSignature() : Complexity(1) {}
CloneSignature(llvm::hash_code Hash, unsigned Complexity)
: Hash(Hash), Complexity(Complexity) {}
};
/// Holds group of StmtSequences that are clones of each other and the
/// complexity value (see CloneSignature::Complexity) that all stored
/// StmtSequences have in common.
struct CloneGroup {
std::vector<StmtSequence> Sequences;
CloneSignature Signature;
CloneGroup() {}
CloneGroup(const StmtSequence &Seq, CloneSignature Signature)
: Signature(Signature) {
Sequences.push_back(Seq);
}
/// \brief Returns false if and only if this group should be skipped when
/// searching for clones.
bool isValid() const {
// A clone group with only one member makes no sense, so we skip them.
return Sequences.size() > 1;
}
};
/// \brief Generates and stores search data for all statements in the body of
/// the given Decl.
void analyzeCodeBody(const Decl *D);
/// \brief Stores the CloneSignature to allow future querying.
void add(const StmtSequence &S, const CloneSignature &Signature);
/// \brief Searches the provided statements for clones.
///
/// \param Result Output parameter that is filled with a list of found
/// clone groups. Each group contains multiple StmtSequences
/// that were identified to be clones of each other.
/// \param MinGroupComplexity Only return clones which have at least this
/// complexity value.
/// \param CheckPatterns Returns only clone groups in which the referenced
/// variables follow the same pattern.
void findClones(std::vector<CloneGroup> &Result, unsigned MinGroupComplexity,
bool CheckPatterns = true);
/// \brief Describes two clones that reference their variables in a different
/// pattern which could indicate a programming error.
struct SuspiciousClonePair {
/// \brief Utility class holding the relevant information about a single
/// clone in this pair.
struct SuspiciousCloneInfo {
/// The variable which referencing in this clone was against the pattern.
const VarDecl *Variable;
/// Where the variable was referenced.
const Stmt *Mention;
/// The variable that should have been referenced to follow the pattern.
/// If Suggestion is a nullptr then it's not possible to fix the pattern
/// by referencing a different variable in this clone.
const VarDecl *Suggestion;
SuspiciousCloneInfo(const VarDecl *Variable, const Stmt *Mention,
const VarDecl *Suggestion)
: Variable(Variable), Mention(Mention), Suggestion(Suggestion) {}
SuspiciousCloneInfo() {}
};
/// The first clone in the pair which always has a suggested variable.
SuspiciousCloneInfo FirstCloneInfo;
/// This other clone in the pair which can have a suggested variable.
SuspiciousCloneInfo SecondCloneInfo;
};
/// \brief Searches the provided statements for pairs of clones that don't
/// follow the same pattern when referencing variables.
/// \param Result Output parameter that will contain the clone pairs.
/// \param MinGroupComplexity Only clone pairs in which the clones have at
/// least this complexity value.
void findSuspiciousClones(std::vector<SuspiciousClonePair> &Result,
unsigned MinGroupComplexity);
private:
/// Stores all encountered StmtSequences alongside their CloneSignature.
std::vector<std::pair<CloneSignature, StmtSequence>> Sequences;
};
} // end namespace clang
#endif // LLVM_CLANG_AST_CLONEDETECTION_H

View File

@ -622,8 +622,8 @@ class CallEnter : public ProgramPoint {
class CallExitBegin : public ProgramPoint {
public:
// CallExitBegin uses the callee's location context.
CallExitBegin(const StackFrameContext *L)
: ProgramPoint(nullptr, CallExitBeginKind, L, nullptr) {}
CallExitBegin(const StackFrameContext *L, const ReturnStmt *RS)
: ProgramPoint(RS, CallExitBeginKind, L, nullptr) { }
private:
friend class ProgramPoint;

View File

@ -198,6 +198,7 @@ class Spelling<string name, string variety> {
class GNU<string name> : Spelling<name, "GNU">;
class Declspec<string name> : Spelling<name, "Declspec">;
class Microsoft<string name> : Spelling<name, "Microsoft">;
class CXX11<string namespace, string name, int version = 1>
: Spelling<name, "CXX11"> {
string Namespace = namespace;
@ -241,6 +242,7 @@ def MicrosoftExt : LangOpt<"MicrosoftExt">;
def Borland : LangOpt<"Borland">;
def CUDA : LangOpt<"CUDA">;
def COnly : LangOpt<"CPlusPlus", 1>;
def CPlusPlus : LangOpt<"CPlusPlus">;
def OpenCL : LangOpt<"OpenCL">;
def RenderScript : LangOpt<"RenderScript">;
@ -252,7 +254,7 @@ class TargetArch<list<string> arches> {
list<string> OSes;
list<string> CXXABIs;
}
def TargetARM : TargetArch<["arm", "thumb"]>;
def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
def TargetMips : TargetArch<["mips", "mipsel"]>;
def TargetMSP430 : TargetArch<["msp430"]>;
def TargetX86 : TargetArch<["x86"]>;
@ -380,7 +382,7 @@ def Alias : Attr {
let Spellings = [GCC<"alias">];
let Args = [StringArgument<"Aliasee">];
let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
"ExpectedFunctionGlobalVarMethodOrProperty">;
"ExpectedFunctionOrGlobalVar">;
let Documentation = [Undocumented];
}
@ -778,6 +780,14 @@ def EmptyBases : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
let Documentation = [EmptyBasesDocs];
}
def AllocSize : InheritableAttr {
let Spellings = [GCC<"alloc_size">];
let Subjects = SubjectList<[Function]>;
let Args = [IntArgument<"ElemSizeParam">, IntArgument<"NumElemsParam", 1>];
let TemplateDependent = 1;
let Documentation = [AllocSizeDocs];
}
def EnableIf : InheritableAttr {
let Spellings = [GNU<"enable_if">];
let Subjects = SubjectList<[Function]>;
@ -808,6 +818,11 @@ def FastCall : InheritableAttr {
let Documentation = [FastCallDocs];
}
def RegCall : InheritableAttr {
let Spellings = [GCC<"regcall">, Keyword<"__regcall">];
let Documentation = [RegCallDocs];
}
def Final : InheritableAttr {
let Spellings = [Keyword<"final">, Keyword<"sealed">];
let Accessors = [Accessor<"isSpelledAsSealed", [Keyword<"sealed">]>];
@ -1024,6 +1039,12 @@ def NoDuplicate : InheritableAttr {
let Documentation = [NoDuplicateDocs];
}
def Convergent : InheritableAttr {
let Spellings = [GNU<"convergent">, CXX11<"clang", "convergent">];
let Subjects = SubjectList<[Function]>;
let Documentation = [ConvergentDocs];
}
def NoInline : InheritableAttr {
let Spellings = [GCC<"noinline">, Declspec<"noinline">];
let Subjects = SubjectList<[Function]>;
@ -1048,24 +1069,37 @@ def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
//
// FIXME: This provides a sub-optimal error message if you attempt to
// use this in CUDA, since CUDA does not use the same terminology.
def AMDGPUNumVGPR : InheritableAttr {
let Spellings = [GNU<"amdgpu_num_vgpr">];
let Args = [UnsignedArgument<"NumVGPR">];
let Documentation = [AMDGPUNumVGPRDocs];
// FIXME: This should be for OpenCLKernelFunction, but is not to
//
// FIXME: SubjectList should be for OpenCLKernelFunction, but is not to
// workaround needing to see kernel attribute before others to know if
// this should be rejected on non-kernels.
let Subjects = SubjectList<[Function], ErrorDiag,
"ExpectedKernelFunction">;
def AMDGPUFlatWorkGroupSize : InheritableAttr {
let Spellings = [GNU<"amdgpu_flat_work_group_size">];
let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">];
let Documentation = [AMDGPUFlatWorkGroupSizeDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
}
def AMDGPUWavesPerEU : InheritableAttr {
let Spellings = [GNU<"amdgpu_waves_per_eu">];
let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>];
let Documentation = [AMDGPUWavesPerEUDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
}
def AMDGPUNumSGPR : InheritableAttr {
let Spellings = [GNU<"amdgpu_num_sgpr">];
let Args = [UnsignedArgument<"NumSGPR">];
let Documentation = [AMDGPUNumSGPRDocs];
let Subjects = SubjectList<[Function], ErrorDiag,
"ExpectedKernelFunction">;
let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
}
def AMDGPUNumVGPR : InheritableAttr {
let Spellings = [GNU<"amdgpu_num_vgpr">];
let Args = [UnsignedArgument<"NumVGPR">];
let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
}
def NoSplitStack : InheritableAttr {
@ -1270,6 +1304,12 @@ def ObjCRootClass : InheritableAttr {
let Documentation = [Undocumented];
}
def ObjCSubclassingRestricted : InheritableAttr {
let Spellings = [GNU<"objc_subclassing_restricted">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [ObjCSubclassingRestrictedDocs];
}
def ObjCExplicitProtocolImpl : InheritableAttr {
let Spellings = [GNU<"objc_protocol_requires_explicit_implementation">];
let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
@ -1380,6 +1420,15 @@ def ReqdWorkGroupSize : InheritableAttr {
let Documentation = [Undocumented];
}
def RequireConstantInit : InheritableAttr {
let Spellings = [GNU<"require_constant_initialization">,
CXX11<"clang", "require_constant_initialization">];
let Subjects = SubjectList<[GlobalVar], ErrorDiag,
"ExpectedStaticOrTLSVar">;
let Documentation = [RequireConstantInitDocs];
let LangOpts = [CPlusPlus];
}
def WorkGroupSizeHint : InheritableAttr {
let Spellings = [GNU<"work_group_size_hint">];
let Args = [UnsignedArgument<"XDim">,
@ -1518,7 +1567,8 @@ def Target : InheritableAttr {
def TransparentUnion : InheritableAttr {
let Spellings = [GCC<"transparent_union">];
// let Subjects = SubjectList<[Record, TypedefName]>;
let Documentation = [Undocumented];
let Documentation = [TransparentUnionDocs];
let LangOpts = [COnly];
}
def Unavailable : InheritableAttr {
@ -1574,9 +1624,11 @@ def Used : InheritableAttr {
}
def Uuid : InheritableAttr {
let Spellings = [Declspec<"uuid">];
let Spellings = [Declspec<"uuid">, Microsoft<"uuid">];
let Args = [StringArgument<"Guid">];
// let Subjects = SubjectList<[CXXRecord]>;
let Subjects = SubjectList<[Record, Enum], WarnDiag, "ExpectedEnumOrClass">;
// FIXME: Allow expressing logical AND for LangOpts. Our condition should be:
// CPlusPlus && (MicrosoftExt || Borland)
let LangOpts = [MicrosoftExt, Borland];
let Documentation = [Undocumented];
}
@ -1680,7 +1732,8 @@ def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetX86> {
def NoSanitize : InheritableAttr {
let Spellings = [GNU<"no_sanitize">, CXX11<"clang", "no_sanitize">];
let Args = [VariadicStringArgument<"Sanitizers">];
let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar], ErrorDiag,
"ExpectedFunctionMethodOrGlobalVar">;
let Documentation = [NoSanitizeDocs];
let AdditionalMembers = [{
SanitizerMask getMask() const {
@ -1702,7 +1755,8 @@ def NoSanitizeSpecific : InheritableAttr {
GCC<"no_sanitize_address">,
GCC<"no_sanitize_thread">,
GNU<"no_sanitize_memory">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
"ExpectedFunctionOrGlobalVar">;
let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs,
NoSanitizeMemoryDocs];
let ASTNode = 0;

View File

@ -119,7 +119,7 @@ The ``carries_dependency`` attribute specifies dependency propagation into and
out of functions.
When specified on a function or Objective-C method, the ``carries_dependency``
attribute means that the return value carries a dependency out of the function,
attribute means that the return value carries a dependency out of the function,
so that the implementation need not constrain ordering upon return from that
function. Implementations of the function and its caller may choose to preserve
dependencies instead of emitting memory ordering instructions such as fences.
@ -206,6 +206,44 @@ to enforce the provided alignment assumption.
}];
}
def AllocSizeDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``alloc_size`` attribute can be placed on functions that return pointers in
order to hint to the compiler how many bytes of memory will be available at the
returned poiner. ``alloc_size`` takes one or two arguments.
- ``alloc_size(N)`` implies that argument number N equals the number of
available bytes at the returned pointer.
- ``alloc_size(N, M)`` implies that the product of argument number N and
argument number M equals the number of available bytes at the returned
pointer.
Argument numbers are 1-based.
An example of how to use ``alloc_size``
.. code-block:: c
void *my_malloc(int a) __attribute__((alloc_size(1)));
void *my_calloc(int a, int b) __attribute__((alloc_size(1, 2)));
int main() {
void *const p = my_malloc(100);
assert(__builtin_object_size(p, 0) == 100);
void *const a = my_calloc(20, 5);
assert(__builtin_object_size(a, 0) == 100);
}
.. Note:: This attribute works differently in clang than it does in GCC.
Specifically, clang will only trace ``const`` pointers (as above); we give up
on pointers that are not marked as ``const``. In the vast majority of cases,
this is unimportant, because LLVM has support for the ``alloc_size``
attribute. However, this may cause mildly unintuitive behavior when used with
other attributes, such as ``enable_if``.
}];
}
def EnableIfDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@ -470,6 +508,12 @@ semantics:
* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T``
and ``U`` are compatible types. This conversion is given "conversion" rank.
* If no viable candidates are otherwise available, we allow a conversion from a
pointer of type ``T*`` to a pointer of type ``U*``, where ``T`` and ``U`` are
incompatible. This conversion is ranked below all other types of conversions.
Please note: ``U`` lacking qualifiers that are present on ``T`` is sufficient
for ``T`` and ``U`` to be incompatible.
The declaration of ``overloadable`` functions is restricted to function
declarations and definitions. Most importantly, if any function with a given
name is given the ``overloadable`` attribute, then all function declarations
@ -600,6 +644,33 @@ of the condition.
}];
}
def ConvergentDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``convergent`` attribute can be placed on a function declaration. It is
translated into the LLVM ``convergent`` attribute, which indicates that the call
instructions of a function with this attribute cannot be made control-dependent
on any additional values.
In languages designed for SPMD/SIMT programming model, e.g. OpenCL or CUDA,
the call instructions of a function with this attribute must be executed by
all work items or threads in a work group or sub group.
This attribute is different from ``noduplicate`` because it allows duplicating
function calls if it can be proved that the duplicated function calls are
not made control-dependent on any additional values, e.g., unrolling a loop
executed by all work items.
Sample usage:
.. code-block:: c
void convfunc(void) __attribute__((convergent));
// Setting it as a C++11 attribute is also valid in a C++ program.
// void convfunc(void) [[clang::convergent]];
}];
}
def NoSplitStackDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@ -685,10 +756,10 @@ This attribute specifies that the Objective-C class to which it applies is visib
def ObjCBoxableDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Structs and unions marked with the ``objc_boxable`` attribute can be used
Structs and unions marked with the ``objc_boxable`` attribute can be used
with the Objective-C boxed expression syntax, ``@(...)``.
**Usage**: ``__attribute__((objc_boxable))``. This attribute
**Usage**: ``__attribute__((objc_boxable))``. This attribute
can only be placed on a declaration of a trivially-copyable struct or union:
.. code-block:: objc
@ -829,6 +900,44 @@ When one method overrides another, the overriding method can be more widely avai
}];
}
def RequireConstantInitDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
This attribute specifies that the variable to which it is attached is intended
to have a `constant initializer <http://en.cppreference.com/w/cpp/language/constant_initialization>`_
according to the rules of [basic.start.static]. The variable is required to
have static or thread storage duration. If the initialization of the variable
is not a constant initializer an error will be produced. This attribute may
only be used in C++.
Note that in C++03 strict constant expression checking is not done. Instead
the attribute reports if Clang can emit the variable as a constant, even if it's
not technically a 'constant initializer'. This behavior is non-portable.
Static storage duration variables with constant initializers avoid hard-to-find
bugs caused by the indeterminate order of dynamic initialization. They can also
be safely used during dynamic initialization across translation units.
This attribute acts as a compile time assertion that the requirements
for constant initialization have been met. Since these requirements change
between dialects and have subtle pitfalls it's important to fail fast instead
of silently falling back on dynamic initialization.
.. code-block:: c++
// -std=c++14
#define SAFE_STATIC [[clang::require_constant_initialization]]
struct T {
constexpr T(int) {}
~T(); // non-trivial
};
SAFE_STATIC T x = {42}; // Initialization OK. Doesn't check destructor.
SAFE_STATIC T y = 42; // error: variable does not have a constant initializer
// copy initialization is not a constant expression on a non-literal type.
}];
}
def WarnMaybeUnusedDocs : Documentation {
let Category = DocCatVariable;
let Heading = "maybe_unused, unused, gnu::unused";
@ -845,12 +954,12 @@ variable, a function or method, a function parameter, an enumeration, an
enumerator, a non-static data member, or a label.
.. code-block: c++
#include <cassert>
[[maybe_unused]] void f([[maybe_unused]] bool thing1,
[[maybe_unused]] bool thing2) {
[[maybe_unused]] bool b = thing1 && thing2;
assert(b);
#include <cassert>
[[maybe_unused]] void f([[maybe_unused]] bool thing1,
[[maybe_unused]] bool thing2) {
[[maybe_unused]] bool b = thing1 && thing2;
assert(b);
}
}];
}
@ -867,16 +976,16 @@ potentially-evaluated discarded-value expression that is not explicitly cast to
`void`.
.. code-block: c++
struct [[nodiscard]] error_info { /*...*/ };
error_info enable_missile_safety_mode();
void launch_missiles();
void test_missiles() {
enable_missile_safety_mode(); // diagnoses
launch_missiles();
}
error_info &foo();
void f() { foo(); } // Does not diagnose, error_info is a reference.
struct [[nodiscard]] error_info { /*...*/ };
error_info enable_missile_safety_mode();
void launch_missiles();
void test_missiles() {
enable_missile_safety_mode(); // diagnoses
launch_missiles();
}
error_info &foo();
void f() { foo(); } // Does not diagnose, error_info is a reference.
}];
}
@ -1032,64 +1141,110 @@ the front end.
}];
}
def DocCatAMDGPURegisterAttributes :
DocumentationCategory<"AMD GPU Register Attributes"> {
let Content = [{
Clang supports attributes for controlling register usage on AMD GPU
targets. These attributes may be attached to a kernel function
definition and is an optimization hint to the backend for the maximum
number of registers to use. This is useful in cases where register
limited occupancy is known to be an important factor for the
performance for the kernel.
The semantics are as follows:
- The backend will attempt to limit the number of used registers to
the specified value, but the exact number used is not
guaranteed. The number used may be rounded up to satisfy the
allocation requirements or ABI constraints of the subtarget. For
example, on Southern Islands VGPRs may only be allocated in
increments of 4, so requesting a limit of 39 VGPRs will really
attempt to use up to 40. Requesting more registers than the
subtarget supports will truncate to the maximum allowed. The backend
may also use fewer registers than requested whenever possible.
- 0 implies the default no limit on register usage.
- Ignored on older VLIW subtargets which did not have separate scalar
and vector registers, R600 through Northern Islands.
}];
}
def AMDGPUNumVGPRDocs : Documentation {
let Category = DocCatAMDGPURegisterAttributes;
let Content = [{
Clang supports the
``__attribute__((amdgpu_num_vgpr(<num_registers>)))`` attribute on AMD
Southern Islands GPUs and later for controlling the number of vector
registers. A typical value would be between 4 and 256 in increments
of 4.
}];
}
def AMDGPUNumSGPRDocs : Documentation {
let Category = DocCatAMDGPURegisterAttributes;
def DocCatAMDGPUAttributes : DocumentationCategory<"AMD GPU Attributes">;
def AMDGPUFlatWorkGroupSizeDocs : Documentation {
let Category = DocCatAMDGPUAttributes;
let Content = [{
The flat work-group size is the number of work-items in the work-group size
specified when the kernel is dispatched. It is the product of the sizes of the
x, y, and z dimension of the work-group.
Clang supports the
``__attribute__((amdgpu_num_sgpr(<num_registers>)))`` attribute on AMD
Southern Islands GPUs and later for controlling the number of scalar
registers. A typical value would be between 8 and 104 in increments of
8.
``__attribute__((amdgpu_flat_work_group_size(<min>, <max>)))`` attribute for the
AMDGPU target. This attribute may be attached to a kernel function definition
and is an optimization hint.
Due to common instruction constraints, an additional 2-4 SGPRs are
typically required for internal use depending on features used. This
value is a hint for the total number of SGPRs to use, and not the
number of user SGPRs, so no special consideration needs to be given
for these.
}];
``<min>`` parameter specifies the minimum flat work-group size, and ``<max>``
parameter specifies the maximum flat work-group size (must be greater than
``<min>``) to which all dispatches of the kernel will conform. Passing ``0, 0``
as ``<min>, <max>`` implies the default behavior (``128, 256``).
If specified, the AMDGPU target backend might be able to produce better machine
code for barriers and perform scratch promotion by estimating available group
segment size.
An error will be given if:
- Specified values violate subtarget specifications;
- Specified values are not compatible with values provided through other
attributes.
}];
}
def AMDGPUWavesPerEUDocs : Documentation {
let Category = DocCatAMDGPUAttributes;
let Content = [{
A compute unit (CU) is responsible for executing the wavefronts of a work-group.
It is composed of one or more execution units (EU), which are responsible for
executing the wavefronts. An EU can have enough resources to maintain the state
of more than one executing wavefront. This allows an EU to hide latency by
switching between wavefronts in a similar way to symmetric multithreading on a
CPU. In order to allow the state for multiple wavefronts to fit on an EU, the
resources used by a single wavefront have to be limited. For example, the number
of SGPRs and VGPRs. Limiting such resources can allow greater latency hiding,
but can result in having to spill some register state to memory.
Clang supports the ``__attribute__((amdgpu_waves_per_eu(<min>[, <max>])))``
attribute for the AMDGPU target. This attribute may be attached to a kernel
function definition and is an optimization hint.
``<min>`` parameter specifies the requested minimum number of waves per EU, and
*optional* ``<max>`` parameter specifies the requested maximum number of waves
per EU (must be greater than ``<min>`` if specified). If ``<max>`` is omitted,
then there is no restriction on the maximum number of waves per EU other than
the one dictated by the hardware for which the kernel is compiled. Passing
``0, 0`` as ``<min>, <max>`` implies the default behavior (no limits).
If specified, this attribute allows an advanced developer to tune the number of
wavefronts that are capable of fitting within the resources of an EU. The AMDGPU
target backend can use this information to limit resources, such as number of
SGPRs, number of VGPRs, size of available group and private memory segments, in
such a way that guarantees that at least ``<min>`` wavefronts and at most
``<max>`` wavefronts are able to fit within the resources of an EU. Requesting
more wavefronts can hide memory latency but limits available registers which
can result in spilling. Requesting fewer wavefronts can help reduce cache
thrashing, but can reduce memory latency hiding.
This attribute controls the machine code generated by the AMDGPU target backend
to ensure it is capable of meeting the requested values. However, when the
kernel is executed, there may be other reasons that prevent meeting the request,
for example, there may be wavefronts from other kernels executing on the EU.
An error will be given if:
- Specified values violate subtarget specifications;
- Specified values are not compatible with values provided through other
attributes;
- The AMDGPU target backend is unable to create machine code that can meet the
request.
}];
}
def AMDGPUNumSGPRNumVGPRDocs : Documentation {
let Category = DocCatAMDGPUAttributes;
let Content = [{
Clang supports the ``__attribute__((amdgpu_num_sgpr(<num_sgpr>)))`` and
``__attribute__((amdgpu_num_vgpr(<num_vgpr>)))`` attributes for the AMDGPU
target. These attributes may be attached to a kernel function definition and are
an optimization hint.
If these attributes are specified, then the AMDGPU target backend will attempt
to limit the number of SGPRs and/or VGPRs used to the specified value(s). The
number of used SGPRs and/or VGPRs may further be rounded up to satisfy the
allocation requirements or constraints of the subtarget. Passing ``0`` as
``num_sgpr`` and/or ``num_vgpr`` implies the default behavior (no limits).
These attributes can be used to test the AMDGPU target backend. It is
recommended that the ``amdgpu_waves_per_eu`` attribute be used to control
resources such as SGPRs and VGPRs since it is aware of the limits for different
subtargets.
An error will be given if:
- Specified values violate subtarget specifications;
- Specified values are not compatible with values provided through other
attributes;
- The AMDGPU target backend is unable to create machine code that can meet the
request.
}];
}
def DocCatCallingConvs : DocumentationCategory<"Calling Conventions"> {
@ -1166,6 +1321,18 @@ not require callee-cleanup. See the documentation for `__fastcall`_ on MSDN.
}];
}
def RegCallDocs : Documentation {
let Category = DocCatCallingConvs;
let Content = [{
On x86 targets, this attribute changes the calling convention to
`__regcall`_ convention. This convention aims to pass as many arguments
as possible in registers. It also tries to utilize registers for the
return value whenever it is possible.
.. _`__regcall`: https://software.intel.com/en-us/node/693069
}];
}
def ThisCallDocs : Documentation {
let Category = DocCatCallingConvs;
let Content = [{
@ -1194,7 +1361,7 @@ passed in RCX, RDX, R8, and R9 as is done for the default Windows x64 calling
convention.
On both 32-bit x86 and x86_64 targets, vector and floating point arguments are
passed in XMM0-XMM5. Homogenous vector aggregates of up to four elements are
passed in XMM0-XMM5. Homogeneous vector aggregates of up to four elements are
passed in sequential SSE registers if enough are available. If AVX is enabled,
256 bit vectors are passed in YMM0-YMM5. Any vector or aggregate type that
cannot be passed in registers for any reason is passed by reference, which
@ -1329,7 +1496,7 @@ def NoSanitizeMemoryDocs : Documentation {
.. _langext-memory_sanitizer:
Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
specify that checks for uninitialized memory should not be inserted
specify that checks for uninitialized memory should not be inserted
(e.g. by MemorySanitizer). The function may still be instrumented by the tool
to avoid false positives in other places.
}];
@ -1338,7 +1505,8 @@ to avoid false positives in other places.
def DocCatTypeSafety : DocumentationCategory<"Type Safety Checking"> {
let Content = [{
Clang supports additional attributes to enable checking type safety properties
that can't be enforced by the C type system. Use cases include:
that can't be enforced by the C type system. To see warnings produced by these
checks, ensure that -Wtype-safety is enabled. Use cases include:
* MPI library implementations, where these attributes enable checking that
the buffer type matches the passed ``MPI_Datatype``;
@ -1376,18 +1544,31 @@ def ArgumentWithTypeTagDocs : Documentation {
Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx,
type_tag_idx)))`` on a function declaration to specify that the function
accepts a type tag that determines the type of some other argument.
``arg_kind`` is an identifier that should be used when annotating all
applicable type tags.
This attribute is primarily useful for checking arguments of variadic functions
(``pointer_with_type_tag`` can be used in most non-variadic cases).
In the attribute prototype above:
* ``arg_kind`` is an identifier that should be used when annotating all
applicable type tags.
* ``arg_idx`` provides the position of a function argument. The expected type of
this function argument will be determined by the function argument specified
by ``type_tag_idx``. In the code example below, "3" means that the type of the
function's third argument will be determined by ``type_tag_idx``.
* ``type_tag_idx`` provides the position of a function argument. This function
argument will be a type tag. The type tag will determine the expected type of
the argument specified by ``arg_idx``. In the code example below, "2" means
that the type tag associated with the function's second argument should agree
with the type of the argument specified by ``arg_idx``.
For example:
.. code-block:: c++
int fcntl(int fd, int cmd, ...)
__attribute__(( argument_with_type_tag(fcntl,3,2) ));
// The function's second argument will be a type tag; this type tag will
// determine the expected type of the function's third argument.
}];
}
@ -1399,85 +1580,140 @@ Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))``
on a function declaration to specify that the function accepts a type tag that
determines the pointee type of some other pointer argument.
In the attribute prototype above:
* ``ptr_kind`` is an identifier that should be used when annotating all
applicable type tags.
* ``ptr_idx`` provides the position of a function argument; this function
argument will have a pointer type. The expected pointee type of this pointer
type will be determined by the function argument specified by
``type_tag_idx``. In the code example below, "1" means that the pointee type
of the function's first argument will be determined by ``type_tag_idx``.
* ``type_tag_idx`` provides the position of a function argument; this function
argument will be a type tag. The type tag will determine the expected pointee
type of the pointer argument specified by ``ptr_idx``. In the code example
below, "3" means that the type tag associated with the function's third
argument should agree with the pointee type of the pointer argument specified
by ``ptr_idx``.
For example:
.. code-block:: c++
typedef int MPI_Datatype;
int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
__attribute__(( pointer_with_type_tag(mpi,1,3) ));
// The function's 3rd argument will be a type tag; this type tag will
// determine the expected pointee type of the function's 1st argument.
}];
}
def TypeTagForDatatypeDocs : Documentation {
let Category = DocCatTypeSafety;
let Content = [{
When declaring a variable, use
``__attribute__((type_tag_for_datatype(kind, type)))`` to create a type tag that
is tied to the ``type`` argument given to the attribute.
In the attribute prototype above:
* ``kind`` is an identifier that should be used when annotating all applicable
type tags.
* ``type`` indicates the name of the type.
Clang supports annotating type tags of two forms.
* **Type tag that is an expression containing a reference to some declared
identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a
declaration with that identifier:
* **Type tag that is a reference to a declared identifier.**
Use ``__attribute__((type_tag_for_datatype(kind, type)))`` when declaring that
identifier:
.. code-block:: c++
.. code-block:: c++
extern struct mpi_datatype mpi_datatype_int
__attribute__(( type_tag_for_datatype(mpi,int) ));
#define MPI_INT ((MPI_Datatype) &mpi_datatype_int)
typedef int MPI_Datatype;
extern struct mpi_datatype mpi_datatype_int
__attribute__(( type_tag_for_datatype(mpi,int) ));
#define MPI_INT ((MPI_Datatype) &mpi_datatype_int)
// &mpi_datatype_int is a type tag. It is tied to type "int".
* **Type tag that is an integral literal.** Introduce a ``static const``
variable with a corresponding initializer value and attach
``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration,
for example:
* **Type tag that is an integral literal.**
Declare a ``static const`` variable with an initializer value and attach
``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration:
.. code-block:: c++
.. code-block:: c++
#define MPI_INT ((MPI_Datatype) 42)
static const MPI_Datatype mpi_datatype_int
__attribute__(( type_tag_for_datatype(mpi,int) )) = 42
typedef int MPI_Datatype;
static const MPI_Datatype mpi_datatype_int
__attribute__(( type_tag_for_datatype(mpi,int) )) = 42;
#define MPI_INT ((MPI_Datatype) 42)
// The number 42 is a type tag. It is tied to type "int".
The attribute also accepts an optional third argument that determines how the
expression is compared to the type tag. There are two supported flags:
* ``layout_compatible`` will cause types to be compared according to
layout-compatibility rules (C++11 [class.mem] p 17, 18). This is
implemented to support annotating types like ``MPI_DOUBLE_INT``.
The ``type_tag_for_datatype`` attribute also accepts an optional third argument
that determines how the type of the function argument specified by either
``arg_idx`` or ``ptr_idx`` is compared against the type associated with the type
tag. (Recall that for the ``argument_with_type_tag`` attribute, the type of the
function argument specified by ``arg_idx`` is compared against the type
associated with the type tag. Also recall that for the ``pointer_with_type_tag``
attribute, the pointee type of the function argument specified by ``ptr_idx`` is
compared against the type associated with the type tag.) There are two supported
values for this optional third argument:
For example:
* ``layout_compatible`` will cause types to be compared according to
layout-compatibility rules (In C++11 [class.mem] p 17, 18, see the
layout-compatibility rules for two standard-layout struct types and for two
standard-layout union types). This is useful when creating a type tag
associated with a struct or union type. For example:
.. code-block:: c++
.. code-block:: c++
/* In mpi.h */
struct internal_mpi_double_int { double d; int i; };
extern struct mpi_datatype mpi_datatype_double_int
__attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) ));
/* In mpi.h */
typedef int MPI_Datatype;
struct internal_mpi_double_int { double d; int i; };
extern struct mpi_datatype mpi_datatype_double_int
__attribute__(( type_tag_for_datatype(mpi,
struct internal_mpi_double_int, layout_compatible) ));
#define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)
#define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)
/* In user code */
struct my_pair { double a; int b; };
struct my_pair *buffer;
MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning
int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...)
__attribute__(( pointer_with_type_tag(mpi,1,3) ));
struct my_int_pair { int a; int b; }
struct my_int_pair *buffer2;
MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element
// type 'struct my_int_pair'
// doesn't match specified MPI_Datatype
/* In user code */
struct my_pair { double a; int b; };
struct my_pair *buffer;
MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning because the
// layout of my_pair is
// compatible with that of
// internal_mpi_double_int
* ``must_be_null`` specifies that the expression should be a null pointer
constant, for example:
struct my_int_pair { int a; int b; }
struct my_int_pair *buffer2;
MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning because the
// layout of my_int_pair
// does not match that of
// internal_mpi_double_int
.. code-block:: c++
* ``must_be_null`` specifies that the function argument specified by either
``arg_idx`` (for the ``argument_with_type_tag`` attribute) or ``ptr_idx`` (for
the ``pointer_with_type_tag`` attribute) should be a null pointer constant.
The second argument to the ``type_tag_for_datatype`` attribute is ignored. For
example:
/* In mpi.h */
extern struct mpi_datatype mpi_datatype_null
__attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));
.. code-block:: c++
#define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)
/* In mpi.h */
typedef int MPI_Datatype;
extern struct mpi_datatype mpi_datatype_null
__attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));
/* In user code */
MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL
// was specified but buffer
// is not a null pointer
#define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)
int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...)
__attribute__(( pointer_with_type_tag(mpi,1,3) ));
/* In user code */
struct my_pair { double a; int b; };
struct my_pair *buffer;
MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL
// was specified but buffer
// is not a null pointer
}];
}
@ -1878,7 +2114,7 @@ by Clang.
}
def NullabilityDocs : DocumentationCategory<"Nullability Attributes"> {
let Content = [{
Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``).
Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``).
The nullability (type) qualifiers express whether a value of a given pointer type can be null (the ``_Nullable`` qualifier), doesn't have a defined meaning for null (the ``_Nonnull`` qualifier), or for which the purpose of null is unclear (the ``_Null_unspecified`` qualifier). Because nullability qualifiers are expressed within the type system, they are more general than the ``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for example) a nullable pointer to an array of nonnull pointers. Nullability qualifiers are written to the right of the pointer to which they apply. For example:
@ -2318,7 +2554,7 @@ def SwiftIndirectResultDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
The ``swift_indirect_result`` attribute marks a parameter of a ``swiftcall``
function as having the special indirect-result ABI treatmenet.
function as having the special indirect-result ABI treatment.
This treatment gives the parameter the target's normal indirect-result
ABI treatment, which may involve passing it differently from an ordinary
@ -2490,3 +2726,29 @@ Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_
If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise.
}];
}
def TransparentUnionDocs : Documentation {
let Category = DocCatType;
let Content = [{
This attribute can be applied to a union to change the behaviour of calls to
functions that have an argument with a transparent union type. The compiler
behaviour is changed in the following manner:
- A value whose type is any member of the transparent union can be passed as an
argument without the need to cast that value.
- The argument is passed to the function using the calling convention of the
first member of the transparent union. Consequently, all the members of the
transparent union should have the same calling convention as its first member.
Transparent unions are not supported in C++.
}];
}
def ObjCSubclassingRestrictedDocs : Documentation {
let Category = DocCatType;
let Content = [{
This attribute can be added to an Objective-C ``@interface`` declaration to
ensure that this class cannot be subclassed.
}];
}

View File

@ -22,6 +22,8 @@ enum class AttrSyntax {
GNU,
/// Is the identifier known as a __declspec-style attribute?
Declspec,
/// Is the identifier known as a [] Microsoft-style attribute?
Microsoft,
// Is the identifier known as a C++-style attribute?
CXX,
// Is the identifier known as a pragma attribute?

View File

@ -29,6 +29,7 @@
// f -> float
// d -> double
// z -> size_t
// w -> wchar_t
// F -> constant CFString
// G -> id
// H -> SEL
@ -74,6 +75,7 @@
// f -> this is a libc/libm function without the '__builtin_' prefix. It can
// be followed by ':headername:' to state which header this function
// comes from.
// h -> this function requires a specific header or an explicit declaration.
// i -> this is a runtime library implemented function without the
// '__builtin_' prefix. It will be implemented in compiler-rt or libgcc.
// p:N: -> this is a printf-like function whose Nth argument is the format
@ -366,7 +368,7 @@ BUILTIN(__builtin_islessgreater , "i.", "Fnc")
BUILTIN(__builtin_isunordered , "i.", "Fnc")
// Unary FP classification
BUILTIN(__builtin_fpclassify, "iiiii.", "Fnc")
BUILTIN(__builtin_fpclassify, "iiiiii.", "Fnc")
BUILTIN(__builtin_isfinite, "i.", "Fnc")
BUILTIN(__builtin_isinf, "i.", "Fnc")
BUILTIN(__builtin_isinf_sign, "i.", "Fnc")
@ -455,6 +457,12 @@ BUILTIN(__builtin_strpbrk, "c*cC*cC*", "nF")
BUILTIN(__builtin_strrchr, "c*cC*i", "nF")
BUILTIN(__builtin_strspn, "zcC*cC*", "nF")
BUILTIN(__builtin_strstr, "c*cC*cC*", "nF")
BUILTIN(__builtin_wcschr, "w*wC*w", "nF")
BUILTIN(__builtin_wcscmp, "iwC*wC*", "nF")
BUILTIN(__builtin_wcslen, "zwC*", "nF")
BUILTIN(__builtin_wcsncmp, "iwC*wC*z", "nF")
BUILTIN(__builtin_wmemchr, "w*wC*wz", "nF")
BUILTIN(__builtin_wmemcmp, "iwC*wC*z", "nF")
BUILTIN(__builtin_return_address, "v*IUi", "n")
BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
BUILTIN(__builtin_frame_address, "v*IUi", "n")
@ -511,6 +519,7 @@ BUILTIN(__builtin_unreachable, "v", "nr")
BUILTIN(__builtin_shufflevector, "v." , "nc")
BUILTIN(__builtin_convertvector, "v." , "nct")
BUILTIN(__builtin_alloca, "v*z" , "Fn")
BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn")
BUILTIN(__builtin_call_with_static_chain, "v.", "nt")
// "Overloaded" Atomic operator builtins. These are overloaded to support data
@ -693,7 +702,7 @@ BUILTIN(__atomic_is_lock_free, "izvCD*", "n")
#undef ATOMIC_BUILTIN
// Non-overloaded atomic builtins.
BUILTIN(__sync_synchronize, "v.", "n")
BUILTIN(__sync_synchronize, "v", "n")
// GCC does not support these, they are a Clang extension.
BUILTIN(__sync_fetch_and_min, "iiD*i", "n")
BUILTIN(__sync_fetch_and_max, "iiD*i", "n")
@ -708,6 +717,9 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
// Microsoft builtins. These are only active with -fms-extensions.
LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_ulong, "ULiULi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__exception_code, "ULi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_exception_code, "ULi", "n", ALL_MS_LANGUAGES)
@ -716,15 +728,50 @@ LANGBUILTIN(_exception_info, "v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__abnormal_termination, "i", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_abnormal_termination, "i", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__GetExceptionInfo, "v*.", "ntu", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedAnd8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedAnd16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedAnd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchange8, "ccD*cc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchange16, "ssD*ss", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchange64, "LLiLLiD*LLiLLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedDecrement16, "ssD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchange8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchange16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangeAdd8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangeAdd16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangeSub8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangeSub16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedExchangeSub, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedIncrement16, "ssD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedOr8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedOr16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedOr, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedXor, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__popcnt64, "ULLiULLi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_lrotl, "ULiULii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotl64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotr8, "UcUcUc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotr16, "UsUsUc", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotr, "UiUii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_lrotr, "ULiULii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotr64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
// Microsoft library builtins.
@ -766,7 +813,7 @@ LIBBUILTIN(fprintf, "iP*cC*.", "fp:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(snprintf, "ic*zcC*.", "fp:2:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(sprintf, "ic*cC*.", "fp:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vprintf, "icC*a", "fP:0:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vfprintf, "i.", "fP:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vfprintf, "iP*cC*a", "fP:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(vsprintf, "ic*cC*a", "fP:1:", "stdio.h", ALL_LANGUAGES)
LIBBUILTIN(scanf, "icC*R.", "fs:0:", "stdio.h", ALL_LANGUAGES)
@ -790,6 +837,15 @@ LIBBUILTIN(isupper, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
LIBBUILTIN(isxdigit, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
LIBBUILTIN(tolower, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
LIBBUILTIN(toupper, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
// C99 wchar.h
// FIXME: This list is incomplete. We should cover at least the functions that
// take format strings.
LIBBUILTIN(wcschr, "w*wC*w", "f", "wchar.h", ALL_LANGUAGES)
LIBBUILTIN(wcscmp, "iwC*wC*", "f", "wchar.h", ALL_LANGUAGES)
LIBBUILTIN(wcslen, "zwC*", "f", "wchar.h", ALL_LANGUAGES)
LIBBUILTIN(wcsncmp, "iwC*wC*z", "f", "wchar.h", ALL_LANGUAGES)
LIBBUILTIN(wmemchr, "w*wC*wz", "f", "wchar.h", ALL_LANGUAGES)
LIBBUILTIN(wmemcmp, "iwC*wC*z", "f", "wchar.h", ALL_LANGUAGES)
// C99
// In some systems setjmp is a macro that expands to _setjmp. We undefine
@ -906,6 +962,18 @@ LIBBUILTIN(fabs, "dd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fabsf, "ff", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fabsl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
// Some systems define finitef as alias of _finitef.
#if defined (finitef)
#undef finitef
#endif
LIBBUILTIN(finite, "id", "fnc", "math.h", GNU_LANG)
LIBBUILTIN(finitef, "if", "fnc", "math.h", GNU_LANG)
LIBBUILTIN(finitel, "iLd", "fnc", "math.h", GNU_LANG)
// glibc's math.h generates calls to __finite
LIBBUILTIN(__finite, "id", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(__finitef, "if", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(__finitel, "iLd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fmod, "ddd", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fmodf, "fff", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(fmodl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
@ -1280,6 +1348,22 @@ BUILTIN(__builtin___get_unsafe_stack_ptr, "v*", "Fn")
BUILTIN(__builtin_nontemporal_store, "v.", "t")
BUILTIN(__builtin_nontemporal_load, "v.", "t")
// Coroutine intrinsics.
BUILTIN(__builtin_coro_resume, "vv*", "")
BUILTIN(__builtin_coro_destroy, "vv*", "")
BUILTIN(__builtin_coro_done, "bv*", "n")
BUILTIN(__builtin_coro_promise, "v*v*IiIb", "n")
BUILTIN(__builtin_coro_size, "z", "n")
BUILTIN(__builtin_coro_frame, "v*", "n")
BUILTIN(__builtin_coro_free, "v*v*", "n")
BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n")
BUILTIN(__builtin_coro_alloc, "b", "n")
BUILTIN(__builtin_coro_begin, "v*v*", "n")
BUILTIN(__builtin_coro_end, "vv*Ib", "n")
BUILTIN(__builtin_coro_suspend, "cIb", "n")
BUILTIN(__builtin_coro_param, "bv*v*", "n")
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
// We need the generic prototype, since the packet type could be anything.
LANGBUILTIN(read_pipe, "i.", "tn", OCLC20_LANG)
@ -1317,6 +1401,10 @@ LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG)
LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG)
LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG)
// Builtins for os_log/os_trace
BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut")
BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt")
#undef BUILTIN
#undef LIBBUILTIN
#undef LANGBUILTIN

View File

@ -139,6 +139,13 @@ class Context {
return strchr(getRecord(ID).Attributes, 'f') != nullptr;
}
/// \brief Returns true if this builtin requires appropriate header in other
/// compilers. In Clang it will work even without including it, but we can emit
/// a warning about missing header.
bool isHeaderDependentFunction(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'h') != nullptr;
}
/// \brief Determines whether this builtin is a predefined compiler-rt/libgcc
/// function, such as "__clear_cache", where we know the signature a
/// priori.

View File

@ -36,6 +36,7 @@ BUILTIN(__builtin_amdgcn_workitem_id_z, "Ui", "nc")
// Instruction builtins.
//===----------------------------------------------------------------------===//
BUILTIN(__builtin_amdgcn_s_barrier, "v", "n")
BUILTIN(__builtin_amdgcn_wave_barrier, "v", "n")
BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n")
BUILTIN(__builtin_amdgcn_div_scalef, "fffbb*", "n")
BUILTIN(__builtin_amdgcn_div_fmas, "ddddb", "nc")
@ -70,11 +71,30 @@ BUILTIN(__builtin_amdgcn_cubetc, "ffff", "nc")
BUILTIN(__builtin_amdgcn_cubema, "ffff", "nc")
BUILTIN(__builtin_amdgcn_s_memtime, "LUi", "n")
BUILTIN(__builtin_amdgcn_s_sleep, "vIi", "n")
BUILTIN(__builtin_amdgcn_s_incperflevel, "vIi", "n")
BUILTIN(__builtin_amdgcn_s_decperflevel, "vIi", "n")
BUILTIN(__builtin_amdgcn_uicmp, "LUiUiUiIi", "nc")
BUILTIN(__builtin_amdgcn_uicmpl, "LUiLUiLUiIi", "nc")
BUILTIN(__builtin_amdgcn_sicmp, "LUiiiIi", "nc")
BUILTIN(__builtin_amdgcn_sicmpl, "LUiLiLiIi", "nc")
BUILTIN(__builtin_amdgcn_fcmp, "LUiddIi", "nc")
BUILTIN(__builtin_amdgcn_fcmpf, "LUiffIi", "nc")
BUILTIN(__builtin_amdgcn_ds_swizzle, "iiIi", "nc")
//===----------------------------------------------------------------------===//
// VI+ only builtins.
//===----------------------------------------------------------------------===//
TARGET_BUILTIN(__builtin_amdgcn_div_fixuph, "hhhh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_rcph, "hh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_rsqh, "hh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_sinh, "hh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_cosh, "hh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_ldexph, "hhi", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_frexp_manth, "hh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_frexp_exph, "sh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_fracth, "hh", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_classh, "bhi", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime")
//===----------------------------------------------------------------------===//

View File

@ -18,6 +18,10 @@
# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
#endif
#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN)
# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
// In libgcc
BUILTIN(__clear_cache, "vv*v*", "i")
@ -115,11 +119,34 @@ LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__ldrexd, "WiWiCD*", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveFromCoprocessor, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveFromCoprocessor2, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveToCoprocessor, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveToCoprocessor2, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
#undef BUILTIN
#undef LANGBUILTIN
#undef TARGET_HEADER_BUILTIN

View File

@ -14,6 +14,10 @@
// The format of this database matches clang/Basic/Builtins.def.
#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
// Special Registers
BUILTIN(__nvvm_read_ptx_sreg_tid_x, "i", "nc")
@ -452,18 +456,28 @@ BUILTIN(__builtin_ptx_get_image_channel_orderi_, "ii", "")
BUILTIN(__nvvm_atom_add_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_add_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_add_gen_i, "iiD*i", "n")
TARGET_BUILTIN(__nvvm_atom_cta_add_gen_i, "iiD*i", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_add_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_add_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_add_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_add_gen_l, "LiLiD*Li", "n")
TARGET_BUILTIN(__nvvm_atom_cta_add_gen_l, "LiLiD*Li", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_add_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_add_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_add_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_add_gen_ll, "LLiLLiD*LLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_add_gen_ll, "LLiLLiD*LLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_add_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_add_g_f, "ffD*1f", "n")
BUILTIN(__nvvm_atom_add_s_f, "ffD*3f", "n")
BUILTIN(__nvvm_atom_add_gen_f, "ffD*f", "n")
TARGET_BUILTIN(__nvvm_atom_cta_add_gen_f, "ffD*f", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_add_gen_f, "ffD*f", "n", "satom")
BUILTIN(__nvvm_atom_add_g_d, "ddD*1d", "n")
BUILTIN(__nvvm_atom_add_s_d, "ddD*3d", "n")
BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n")
TARGET_BUILTIN(__nvvm_atom_cta_add_gen_d, "ddD*d", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_add_gen_d, "ddD*d", "n", "satom")
BUILTIN(__nvvm_atom_sub_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_sub_s_i, "iiD*3i", "n")
@ -478,97 +492,155 @@ BUILTIN(__nvvm_atom_sub_gen_ll, "LLiLLiD*LLi", "n")
BUILTIN(__nvvm_atom_xchg_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_xchg_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_xchg_gen_i, "iiD*i", "n")
TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_i, "iiD*i", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_xchg_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_xchg_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_xchg_gen_l, "LiLiD*Li", "n")
TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_l, "LiLiD*Li", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_xchg_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_xchg_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_xchg_gen_ll, "LLiLLiD*LLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_ll, "LLiLLiD*LLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_max_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_max_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_max_gen_i, "iiD*i", "n")
TARGET_BUILTIN(__nvvm_atom_cta_max_gen_i, "iiD*i", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_max_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_max_g_ui, "UiUiD*1Ui", "n")
BUILTIN(__nvvm_atom_max_s_ui, "UiUiD*3Ui", "n")
BUILTIN(__nvvm_atom_max_gen_ui, "UiUiD*Ui", "n")
TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ui, "UiUiD*Ui", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ui, "UiUiD*Ui", "n", "satom")
BUILTIN(__nvvm_atom_max_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_max_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_max_gen_l, "LiLiD*Li", "n")
TARGET_BUILTIN(__nvvm_atom_cta_max_gen_l, "LiLiD*Li", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_max_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_max_g_ul, "ULiULiD*1ULi", "n")
BUILTIN(__nvvm_atom_max_s_ul, "ULiULiD*3ULi", "n")
BUILTIN(__nvvm_atom_max_gen_ul, "ULiULiD*ULi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ul, "ULiULiD*ULi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ul, "ULiULiD*ULi", "n", "satom")
BUILTIN(__nvvm_atom_max_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_max_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_max_gen_ll, "LLiLLiD*LLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ll, "LLiLLiD*LLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_max_g_ull, "ULLiULLiD*1ULLi", "n")
BUILTIN(__nvvm_atom_max_s_ull, "ULLiULLiD*3ULLi", "n")
BUILTIN(__nvvm_atom_max_gen_ull, "ULLiULLiD*ULLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
BUILTIN(__nvvm_atom_min_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_min_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_min_gen_i, "iiD*i", "n")
TARGET_BUILTIN(__nvvm_atom_cta_min_gen_i, "iiD*i", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_min_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_min_g_ui, "UiUiD*1Ui", "n")
BUILTIN(__nvvm_atom_min_s_ui, "UiUiD*3Ui", "n")
BUILTIN(__nvvm_atom_min_gen_ui, "UiUiD*Ui", "n")
TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ui, "UiUiD*Ui", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ui, "UiUiD*Ui", "n", "satom")
BUILTIN(__nvvm_atom_min_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_min_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_min_gen_l, "LiLiD*Li", "n")
TARGET_BUILTIN(__nvvm_atom_cta_min_gen_l, "LiLiD*Li", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_min_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_min_g_ul, "ULiULiD*1ULi", "n")
BUILTIN(__nvvm_atom_min_s_ul, "ULiULiD*3ULi", "n")
BUILTIN(__nvvm_atom_min_gen_ul, "ULiULiD*ULi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ul, "ULiULiD*ULi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ul, "ULiULiD*ULi", "n", "satom")
BUILTIN(__nvvm_atom_min_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_min_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_min_gen_ll, "LLiLLiD*LLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ll, "LLiLLiD*LLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_min_g_ull, "ULLiULLiD*1ULLi", "n")
BUILTIN(__nvvm_atom_min_s_ull, "ULLiULLiD*3ULLi", "n")
BUILTIN(__nvvm_atom_min_gen_ull, "ULLiULLiD*ULLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ull, "ULLiULLiD*ULLi", "n", "satom")
BUILTIN(__nvvm_atom_inc_g_ui, "UiUiD*1Ui", "n")
BUILTIN(__nvvm_atom_inc_s_ui, "UiUiD*3Ui", "n")
BUILTIN(__nvvm_atom_inc_gen_ui, "UiUiD*Ui", "n")
TARGET_BUILTIN(__nvvm_atom_cta_inc_gen_ui, "UiUiD*Ui", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_inc_gen_ui, "UiUiD*Ui", "n", "satom")
BUILTIN(__nvvm_atom_dec_g_ui, "UiUiD*1Ui", "n")
BUILTIN(__nvvm_atom_dec_s_ui, "UiUiD*3Ui", "n")
BUILTIN(__nvvm_atom_dec_gen_ui, "UiUiD*Ui", "n")
TARGET_BUILTIN(__nvvm_atom_cta_dec_gen_ui, "UiUiD*Ui", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_dec_gen_ui, "UiUiD*Ui", "n", "satom")
BUILTIN(__nvvm_atom_and_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_and_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_and_gen_i, "iiD*i", "n")
TARGET_BUILTIN(__nvvm_atom_cta_and_gen_i, "iiD*i", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_and_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_and_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_and_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_and_gen_l, "LiLiD*Li", "n")
TARGET_BUILTIN(__nvvm_atom_cta_and_gen_l, "LiLiD*Li", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_and_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_and_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_and_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_and_gen_ll, "LLiLLiD*LLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_and_gen_ll, "LLiLLiD*LLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_and_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_or_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_or_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_or_gen_i, "iiD*i", "n")
TARGET_BUILTIN(__nvvm_atom_cta_or_gen_i, "iiD*i", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_or_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_or_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_or_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_or_gen_l, "LiLiD*Li", "n")
TARGET_BUILTIN(__nvvm_atom_cta_or_gen_l, "LiLiD*Li", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_or_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_or_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_or_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_or_gen_ll, "LLiLLiD*LLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_or_gen_ll, "LLiLLiD*LLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_or_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_xor_g_i, "iiD*1i", "n")
BUILTIN(__nvvm_atom_xor_s_i, "iiD*3i", "n")
BUILTIN(__nvvm_atom_xor_gen_i, "iiD*i", "n")
TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_i, "iiD*i", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_i, "iiD*i", "n", "satom")
BUILTIN(__nvvm_atom_xor_g_l, "LiLiD*1Li", "n")
BUILTIN(__nvvm_atom_xor_s_l, "LiLiD*3Li", "n")
BUILTIN(__nvvm_atom_xor_gen_l, "LiLiD*Li", "n")
TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_l, "LiLiD*Li", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_l, "LiLiD*Li", "n", "satom")
BUILTIN(__nvvm_atom_xor_g_ll, "LLiLLiD*1LLi", "n")
BUILTIN(__nvvm_atom_xor_s_ll, "LLiLLiD*3LLi", "n")
BUILTIN(__nvvm_atom_xor_gen_ll, "LLiLLiD*LLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_ll, "LLiLLiD*LLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_ll, "LLiLLiD*LLi", "n", "satom")
BUILTIN(__nvvm_atom_cas_g_i, "iiD*1ii", "n")
BUILTIN(__nvvm_atom_cas_s_i, "iiD*3ii", "n")
BUILTIN(__nvvm_atom_cas_gen_i, "iiD*ii", "n")
TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_i, "iiD*ii", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_i, "iiD*ii", "n", "satom")
BUILTIN(__nvvm_atom_cas_g_l, "LiLiD*1LiLi", "n")
BUILTIN(__nvvm_atom_cas_s_l, "LiLiD*3LiLi", "n")
BUILTIN(__nvvm_atom_cas_gen_l, "LiLiD*LiLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_l, "LiLiD*LiLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_l, "LiLiD*LiLi", "n", "satom")
BUILTIN(__nvvm_atom_cas_g_ll, "LLiLLiD*1LLiLLi", "n")
BUILTIN(__nvvm_atom_cas_s_ll, "LLiLLiD*3LLiLLi", "n")
BUILTIN(__nvvm_atom_cas_gen_ll, "LLiLLiD*LLiLLi", "n")
TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_ll, "LLiLLiD*LLiLLi", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_ll, "LLiLLiD*LLiLLi", "n", "satom")
// Compiler Error Warn
BUILTIN(__nvvm_compiler_error, "vcC*4", "n")
@ -611,3 +683,4 @@ BUILTIN(__nvvm_ldg_f4, "E4fE4fC*", "")
BUILTIN(__nvvm_ldg_d2, "E2dE2dC*", "")
#undef BUILTIN
#undef TARGET_BUILTIN

View File

@ -134,6 +134,14 @@ BUILTIN(__builtin_altivec_vcmpequw, "V4iV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpequd, "V2LLiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vcmpeqfp, "V4iV4fV4f", "")
BUILTIN(__builtin_altivec_vcmpneb, "V16cV16cV16c", "")
BUILTIN(__builtin_altivec_vcmpneh, "V8sV8sV8s", "")
BUILTIN(__builtin_altivec_vcmpnew, "V4iV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpnezb, "V16cV16cV16c", "")
BUILTIN(__builtin_altivec_vcmpnezh, "V8sV8sV8s", "")
BUILTIN(__builtin_altivec_vcmpnezw, "V4iV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpgtsb, "V16cV16ScV16Sc", "")
BUILTIN(__builtin_altivec_vcmpgtub, "V16cV16UcV16Uc", "")
BUILTIN(__builtin_altivec_vcmpgtsh, "V8sV8SsV8Ss", "")
@ -223,6 +231,11 @@ BUILTIN(__builtin_altivec_vcmpequw_p, "iiV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpequd_p, "iiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vcmpeqfp_p, "iiV4fV4f", "")
BUILTIN(__builtin_altivec_vcmpneb_p, "iiV16cV16c", "")
BUILTIN(__builtin_altivec_vcmpneh_p, "iiV8sV8s", "")
BUILTIN(__builtin_altivec_vcmpnew_p, "iiV4iV4i", "")
BUILTIN(__builtin_altivec_vcmpned_p, "iiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vcmpgtsb_p, "iiV16ScV16Sc", "")
BUILTIN(__builtin_altivec_vcmpgtub_p, "iiV16UcV16Uc", "")
BUILTIN(__builtin_altivec_vcmpgtsh_p, "iiV8SsV8Ss", "")
@ -254,14 +267,54 @@ BUILTIN(__builtin_altivec_vclzb, "V16UcV16Uc", "")
BUILTIN(__builtin_altivec_vclzh, "V8UsV8Us", "")
BUILTIN(__builtin_altivec_vclzw, "V4UiV4Ui", "")
BUILTIN(__builtin_altivec_vclzd, "V2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vctzb, "V16UcV16Uc", "")
BUILTIN(__builtin_altivec_vctzh, "V8UsV8Us", "")
BUILTIN(__builtin_altivec_vctzw, "V4UiV4Ui", "")
BUILTIN(__builtin_altivec_vctzd, "V2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vclzlsbb, "SiV16Uc", "")
BUILTIN(__builtin_altivec_vctzlsbb, "SiV16Uc", "")
BUILTIN(__builtin_altivec_vprtybw, "V4UiV4Ui", "")
BUILTIN(__builtin_altivec_vprtybd, "V2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vprtybq, "V1ULLLiV1ULLLi", "")
// Vector population count built-ins
BUILTIN(__builtin_altivec_vpopcntb, "V16UcV16Uc", "")
BUILTIN(__builtin_altivec_vpopcnth, "V8UsV8Us", "")
BUILTIN(__builtin_altivec_vpopcntw, "V4UiV4Ui", "")
BUILTIN(__builtin_altivec_vpopcntd, "V2ULLiV2ULLi", "")
// Absolute difference built-ins
BUILTIN(__builtin_altivec_vabsdub, "V16UcV16UcV16Uc", "")
BUILTIN(__builtin_altivec_vabsduh, "V8UsV8UsV8Us", "")
BUILTIN(__builtin_altivec_vabsduw, "V4UiV4UiV4Ui", "")
// P9 Shift built-ins.
BUILTIN(__builtin_altivec_vslv, "V16UcV16UcV16Uc", "")
BUILTIN(__builtin_altivec_vsrv, "V16UcV16UcV16Uc", "")
// P9 Vector rotate built-ins
BUILTIN(__builtin_altivec_vrlwmi, "V4UiV4UiV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vrldmi, "V2ULLiV2ULLiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vrlwnm, "V4UiV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vrldnm, "V2ULLiV2ULLiV2ULLi", "")
// VSX built-ins.
BUILTIN(__builtin_vsx_lxvd2x, "V2divC*", "")
BUILTIN(__builtin_vsx_lxvw4x, "V4iivC*", "")
BUILTIN(__builtin_vsx_lxvd2x_be, "V2dSLLivC*", "")
BUILTIN(__builtin_vsx_lxvw4x_be, "V4iSLLivC*", "")
BUILTIN(__builtin_vsx_stxvd2x, "vV2div*", "")
BUILTIN(__builtin_vsx_stxvw4x, "vV4iiv*", "")
BUILTIN(__builtin_vsx_stxvd2x_be, "vV2dSLLivC*", "")
BUILTIN(__builtin_vsx_stxvw4x_be, "vV4iSLLivC*", "")
BUILTIN(__builtin_vsx_lxvl, "V4ivC*ULLi", "")
BUILTIN(__builtin_vsx_lxvll, "V4ivC*ULLi", "")
BUILTIN(__builtin_vsx_stxvl, "vV4iv*ULLi", "")
BUILTIN(__builtin_vsx_stxvll, "vV4iv*ULLi", "")
BUILTIN(__builtin_vsx_xvmaxdp, "V2dV2dV2d", "")
BUILTIN(__builtin_vsx_xvmaxsp, "V4fV4fV4f", "")
@ -339,6 +392,31 @@ BUILTIN(__builtin_vsx_xvcpsgnsp, "V4fV4fV4f", "")
BUILTIN(__builtin_vsx_xvabssp, "V4fV4f", "")
BUILTIN(__builtin_vsx_xvabsdp, "V2dV2d", "")
// vector Insert/Extract exponent/significand builtins
BUILTIN(__builtin_vsx_xviexpdp, "V2dV2ULLiV2ULLi", "")
BUILTIN(__builtin_vsx_xviexpsp, "V4fV4UiV4Ui", "")
BUILTIN(__builtin_vsx_xvxexpdp, "V2ULLiV2d", "")
BUILTIN(__builtin_vsx_xvxexpsp, "V4UiV4f", "")
BUILTIN(__builtin_vsx_xvxsigdp, "V2ULLiV2d", "")
BUILTIN(__builtin_vsx_xvxsigsp, "V4UiV4f", "")
// Conversion builtins
BUILTIN(__builtin_vsx_xvcvdpsxws, "V4SiV2d", "")
BUILTIN(__builtin_vsx_xvcvdpuxws, "V4UiV2d", "")
BUILTIN(__builtin_vsx_xvcvsxwdp, "V2dV4Si", "")
BUILTIN(__builtin_vsx_xvcvuxwdp, "V2dV4Ui", "")
BUILTIN(__builtin_vsx_xvcvspdp, "V2dV4f", "")
BUILTIN(__builtin_vsx_xvcvsxdsp, "V4fV2SLLi", "")
BUILTIN(__builtin_vsx_xvcvuxdsp, "V4fV2ULLi", "")
BUILTIN(__builtin_vsx_xvcvdpsp, "V4fV2d", "")
BUILTIN(__builtin_vsx_xvcvsphp, "V4fV4f", "")
BUILTIN(__builtin_vsx_xvcvhpsp, "V4fV8Us", "")
// Vector Test Data Class builtins
BUILTIN(__builtin_vsx_xvtstdcdp, "V2ULLiV2dIi", "")
BUILTIN(__builtin_vsx_xvtstdcsp, "V4UiV4fIi", "")
// HTM builtins
BUILTIN(__builtin_tbegin, "UiUIi", "")
BUILTIN(__builtin_tend, "UiUIi", "")

View File

@ -23,6 +23,10 @@
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN)
# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
// FIXME: Are these nothrow/const?
// Miscellaneous builtin for checking x86 cpu features.
@ -44,9 +48,7 @@ TARGET_BUILTIN(__builtin_ia32_undef512, "V8d", "nc", "")
// FLAGS
//
TARGET_BUILTIN(__builtin_ia32_readeflags_u32, "Ui", "n", "")
TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "")
TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "")
TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "")
// 3DNow!
//
@ -301,15 +303,16 @@ TARGET_BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "", "ssse3")
TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "", "ssse3")
TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "", "sse")
TARGET_HEADER_BUILTIN(_mm_setcsr, "vUi", "h","xmmintrin.h", ALL_LANGUAGES, "sse")
TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "", "sse")
TARGET_HEADER_BUILTIN(_mm_getcsr, "Ui", "h", "xmmintrin.h", ALL_LANGUAGES, "sse")
TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_sfence, "v", "", "sse")
TARGET_HEADER_BUILTIN(_mm_sfence, "v", "h", "xmmintrin.h", ALL_LANGUAGES, "sse")
TARGET_BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "", "sse")
@ -331,15 +334,17 @@ TARGET_BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvttsd2si, "iV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvtsd2ss, "V4fV4fV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_clflush, "vvC*", "", "sse2")
TARGET_HEADER_BUILTIN(_mm_clflush, "vvC*", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_lfence, "v", "", "sse2")
TARGET_HEADER_BUILTIN(_mm_lfence, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_mfence, "v", "", "sse2")
TARGET_HEADER_BUILTIN(_mm_mfence, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_pause, "v", "", "sse2")
TARGET_HEADER_BUILTIN(_mm_pause, "v", "h", "emmintrin.h", ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "", "sse2")
@ -413,7 +418,6 @@ TARGET_BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16ciIc","", "sse4.2")
TARGET_BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "", "sse4.2")
TARGET_BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "", "sse4.2")
TARGET_BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "", "sse4.2")
TARGET_BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "", "sse4.2")
// SSE4a
TARGET_BUILTIN(__builtin_ia32_extrqi, "V2LLiV2LLiIcIc", "", "sse4a")
@ -627,65 +631,44 @@ TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "", "rdrnd")
// FSGSBASE
TARGET_BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "", "fsgsbase")
// FXSR
TARGET_BUILTIN(__builtin_ia32_fxrstor, "vv*", "", "fxsr")
TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "", "fxsr")
TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "", "fxsr")
TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "", "fxsr")
// XSAVE
TARGET_BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "", "xsave")
TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "", "xsave")
TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "", "xsave")
TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "", "xsave")
TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "", "xsaveopt")
TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "", "xsaveopt")
TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "", "xsaves")
TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "", "xsaves")
TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "", "xsavec")
TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec")
TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves")
TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves")
//CLFLUSHOPT
TARGET_BUILTIN(__builtin_ia32_clflushopt, "vc*", "", "clflushopt")
// ADX
TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx")
TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx")
TARGET_BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "", "")
TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "")
TARGET_BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "", "")
TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "")
// RDSEED
TARGET_BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "", "rdseed")
TARGET_BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "", "rdseed")
TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "", "rdseed")
// BMI
TARGET_BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "", "bmi")
TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "", "bmi")
// BMI2
TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "", "bmi2")
// TBM
TARGET_BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "", "tbm")
TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "", "tbm")
// SHA
TARGET_BUILTIN(__builtin_ia32_sha1rnds4, "V4iV4iV4iIc", "", "sha")
@ -894,6 +877,7 @@ TARGET_BUILTIN(__builtin_ia32_xtest, "i", "", "rtm")
BUILTIN(__builtin_ia32_rdpmc, "ULLii", "")
BUILTIN(__builtin_ia32_rdtsc, "ULLi", "")
BUILTIN(__rdtsc, "ULLi", "")
BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "")
// PKU
TARGET_BUILTIN(__builtin_ia32_rdpkru, "Ui", "", "pku")
@ -977,8 +961,6 @@ TARGET_BUILTIN(__builtin_ia32_maxps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512
TARGET_BUILTIN(__builtin_ia32_maxpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtdq2pd512_mask, "V8dV8iV8dUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtudq2pd512_mask, "V8dV8iV8dUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "", "avx512f")
@ -992,12 +974,11 @@ TARGET_BUILTIN(__builtin_ia32_pminsd512_mask, "V16iV16iV16iV16iUs", "", "avx512f
TARGET_BUILTIN(__builtin_ia32_pminsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pminud512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pminuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmuldq512_mask, "V8LLiV16iV16iV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmuludq512_mask, "V8LLiV16iV16iV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8LLiV16iV16i", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8LLiV16iV16i", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ptestmd512, "UsV16iV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ptestmq512, "UcV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pbroadcastd512_gpr_mask, "V16iiV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_gpr_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_mem_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "", "avx512f")
@ -1015,27 +996,19 @@ TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_mask, "V16iV16iV16iV16iUs", "", "av
TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_mask, "V16fV16iV16fV16fUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_mask, "V8dV8LLiV8dV8dUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_alignq512_mask, "V8LLiV8LLiV8LLiIiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_alignd512_mask, "V16iV16iV16iIiV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_alignd128_mask, "V4iV4iV4iIiV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_alignd256_mask, "V8iV8iV8iIiV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_alignq128_mask, "V2LLiV2LLiV2LLiIiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_alignq256_mask, "V4LLiV4LLiV4LLiIiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIiV4dUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIiV4fUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V4iV2LLiLLiC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V8iV4LLiLLiC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V4iV2LLiLLiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V8iV4LLiLLiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUci","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUci","","avx512vl")
@ -1093,71 +1066,6 @@ TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_paddq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_psubd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_psubq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_paddd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_paddq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_psubd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_psubq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmuldq256_mask, "V4LLiV8iV8iV4LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmuldq128_mask, "V2LLiV4iV4iV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmuludq256_mask, "V4LLiV8iV8iV4LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmuludq128_mask, "V2LLiV4iV4iV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmulld256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmulld128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_paddb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmullw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmullw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmullw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_psubq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_paddd512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_psubd512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmulld512_mask, "V16iV16iV16iV16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmullq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_xorpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_xorps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_orpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_orps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_andpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_andps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_andnpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_andnps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_pmullq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_pmullq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_andnpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_andnpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_andnps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_andnps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_andpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_andpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_andps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_andps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_xorpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_xorpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_xorps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_xorps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_orpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_orpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_orps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_orps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_pabsb512_mask, "V64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pabsw512_mask, "V32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_packssdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw")
@ -1178,7 +1086,7 @@ TARGET_BUILTIN(__builtin_ia32_pminsb512_mask, "V64cV64cV64cV64cULLi", "", "avx51
TARGET_BUILTIN(__builtin_ia32_pminsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminub512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminuw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pshufb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pshufb512, "V64cV64cV64c", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
@ -1197,57 +1105,6 @@ TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "", "avx5
TARGET_BUILTIN(__builtin_ia32_vplzcntd_512_mask, "V16iV16iV16iUs", "", "avx512cd")
TARGET_BUILTIN(__builtin_ia32_vplzcntq_512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512cd")
TARGET_BUILTIN(__builtin_ia32_pabsb128_mask, "V16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pabsb256_mask, "V32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pabsw128_mask, "V8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pabsw256_mask, "V16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_packssdw128_mask, "V8sV4iV4iV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_packssdw256_mask, "V16sV8iV8iV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_packsswb128_mask, "V16cV8sV8sV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_packsswb256_mask, "V32cV16sV16sV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_packusdw128_mask, "V8sV4iV4iV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_packusdw256_mask, "V16sV8iV8iV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_packuswb128_mask, "V16cV8sV8sV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_packuswb256_mask, "V32cV16sV16sV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddusb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddusb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddusw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddusw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pavgb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pavgb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pavgw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pavgw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxub128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxub256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminub128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminub256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pminuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pshufb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pshufb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubusb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubusb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubusw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_psubusw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_vpermi2varhi128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_vpermi2varhi256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_vpermt2varhi128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
@ -1284,10 +1141,6 @@ TARGET_BUILTIN(__builtin_ia32_subsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f
TARGET_BUILTIN(__builtin_ia32_maxsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_minsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_addpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_addpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_addps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_addps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_compressdf128_mask, "V2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_compressdf256_mask, "V4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_compressdi128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
@ -1304,8 +1157,6 @@ TARGET_BUILTIN(__builtin_ia32_compressstoresf128_mask, "vV4f*V4fUc", "", "avx512
TARGET_BUILTIN(__builtin_ia32_compressstoresf256_mask, "vV8f*V8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_compressstoresi128_mask, "vV4i*V4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_compressstoresi256_mask, "vV8i*V8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtdq2pd128_mask, "V2dV4iV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtdq2pd256_mask, "V4dV4iV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtdq2ps128_mask, "V4fV4iV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtdq2ps256_mask, "V8fV8iV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtpd2dq128_mask, "V4iV2dV4iUc", "", "avx512vl")
@ -1328,14 +1179,8 @@ TARGET_BUILTIN(__builtin_ia32_cvttps2dq128_mask, "V4iV4fV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvttps2dq256_mask, "V8iV8fV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvttps2udq128_mask, "V4iV4fV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvttps2udq256_mask, "V8iV8fV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtudq2pd128_mask, "V2dV4iV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtudq2pd256_mask, "V4dV4iV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtudq2ps128_mask, "V4fV4iV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtudq2ps256_mask, "V8fV8iV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_divpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_divpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_divps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_divps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_expanddf128_mask, "V2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_expanddf256_mask, "V4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_expanddi128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
@ -1356,36 +1201,14 @@ TARGET_BUILTIN(__builtin_ia32_getexppd128_mask, "V2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getexppd256_mask, "V4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getexpps128_mask, "V4fV4fV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getexpps256_mask, "V8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_maxpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_maxpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_maxps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_maxps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_minpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_minpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_minps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_minps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_mulpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_mulpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_mulps_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_mulps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pabsd128_mask, "V4iV4iV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pabsd256_mask, "V8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pabsq128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pabsq256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxsd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxsd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxsq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxsq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxud128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxud256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxuq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmaxuq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminsd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminsd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminsq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminsq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminud128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminud256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminuq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pminuq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_rndscalepd_128_mask, "V2dV2dIiV2dUc", "", "avx512vl")
@ -1414,14 +1237,6 @@ TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vi*UcV4iV4iIi", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vf*UcV8iV8fIi", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vi*UcV8iV8iIi", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_sqrtpd128_mask, "V2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_sqrtpd256_mask, "V4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_sqrtps128_mask, "V4fV4fV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_sqrtps256_mask, "V8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_subpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_subpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_subps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_subps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2vard128_mask, "V4iV4iV4iV4iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2vard256_mask, "V8iV8iV8iV8iUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2varpd128_mask, "V2dV2dV2LLiV2dUc", "", "avx512vl")
@ -1485,22 +1300,12 @@ TARGET_BUILTIN(__builtin_ia32_reduceps128_mask, "V4fV4fIiV4fUc", "", "avx512vl,a
TARGET_BUILTIN(__builtin_ia32_reduceps256_mask, "V8fV8fIiV8fUc", "", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_reducesd_mask, "V2dV2dV2dV2dUcIiIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_reducess_mask, "V4fV4fV4fV4fUcIiIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_pmaddubsw128_mask, "V8sV16cV16cV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaddubsw256_mask, "V16sV32cV32cV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaddwd128_mask, "V4iV8sV8sV4iUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaddwd256_mask, "V8iV16sV16sV8iUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovswb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovswb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovuswb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovuswb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovwb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovwb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmulhrsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmulhrsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmulhuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmulhuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmulhw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmulhw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8LLiV8fV8LLiUcIi", "", "avx512dq")
@ -1517,42 +1322,6 @@ TARGET_BUILTIN(__builtin_ia32_rangepd512_mask, "V8dV8dV8dIiV8dUcIi", "", "avx512
TARGET_BUILTIN(__builtin_ia32_rangeps512_mask, "V16fV16fV16fIiV16fUsIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_reducepd512_mask, "V8dV8dIiV8dUcIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_reduceps512_mask, "V16fV16fIiV16fUsIi", "", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_pmovsxbw512_mask, "V32sV32cV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovsxbd512_mask, "V16iV16cV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovsxbq512_mask, "V8LLiV16cV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovsxdq512_mask, "V8LLiV8iV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovsxwd512_mask, "V16iV16sV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovsxwq512_mask, "V8LLiV8sV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovsxbw128_mask, "V8sV16cV8sUc","","avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovsxbw256_mask, "V16sV16cV16sUs","","avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovsxbd128_mask, "V4iV16cV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsxbd256_mask, "V8iV16cV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsxbq128_mask, "V2LLiV16cV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsxbq256_mask, "V4LLiV16cV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsxdq128_mask, "V2LLiV4iV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsxdq256_mask, "V4LLiV4iV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsxwd128_mask, "V4iV8sV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsxwd256_mask, "V8iV8sV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsxwq128_mask, "V2LLiV8sV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsxwq256_mask, "V4LLiV8sV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovzxbw512_mask, "V32sV32cV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovzxbd512_mask, "V16iV16cV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovzxbq512_mask, "V8LLiV16cV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovzxdq512_mask, "V8LLiV8iV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovzxwd512_mask, "V16iV16sV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovzxwq512_mask, "V8LLiV8sV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovzxbw128_mask, "V8sV16cV8sUc","","avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovzxbw256_mask, "V16sV16cV16sUs","","avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovzxbd128_mask, "V4iV16cV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovzxbd256_mask, "V8iV16cV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovzxbq128_mask, "V2LLiV16cV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovzxbq256_mask, "V4LLiV16cV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovzxdq128_mask, "V2LLiV4iV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovzxdq256_mask, "V4LLiV4iV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovzxwd128_mask, "V4iV8sV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovzxwd256_mask, "V8iV8sV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovzxwq128_mask, "V2LLiV8sV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovzxwq256_mask, "V4LLiV8sV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_prold512_mask, "V16iV16iIiV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_prolq512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_prold128_mask, "V4iV4iIiV4iUc","","avx512vl")
@ -1577,65 +1346,27 @@ TARGET_BUILTIN(__builtin_ia32_prorvd128_mask, "V4iV4iV4iV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorvd256_mask, "V8iV8iV8iV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllv32hi_mask, "V32sV32sV32sV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psllw512_mask, "V32sV32sV8sV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psllwi512_mask, "V32sV32sIiV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psllv16hi_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllv8hi_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllw128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllw256_mask, "V16sV16sV8sV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllwi128_mask, "V8sV8sIiV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllwi256_mask, "V16sV16sIiV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllv2di_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllv4di_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllv4si_mask, "V4iV4iV4iV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllv8si_mask, "V8iV8iV8iV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pslldi512_mask, "V16iV16iIiV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psllqi512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pslld128_mask, "V4iV4iV4iV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pslld256_mask, "V8iV8iV4iV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pslldi128_mask, "V4iV4iIiV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pslldi256_mask, "V8iV8iIiV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllq256_mask, "V4LLiV4LLiV2LLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllqi128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllqi256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlv32hi_mask, "V32sV32sV32sV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrlv16hi_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlv8hi_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlv2di_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlv4di_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlv4si_mask, "V4iV4iV4iV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlv8si_mask, "V8iV8iV8iV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrldi512_mask, "V16iV16iIiV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrlqi512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrld128_mask, "V4iV4iV4iV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrld256_mask, "V8iV8iV4iV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrldi128_mask, "V4iV4iIiV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrldi256_mask, "V8iV8iIiV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlq256_mask, "V4LLiV4LLiV2LLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlqi128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlqi256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrav32hi_mask, "V32sV32sV32sV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrav16hi_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrav8hi_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrav4si_mask, "V4iV4iV4iV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrav8si_mask, "V8iV8iV8iV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psravq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psravq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraw512_mask, "V32sV32sV8sV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrawi512_mask, "V32sV32sIiV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psraw128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraw256_mask, "V16sV16sV8sV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrawi128_mask, "V8sV8sIiV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrawi256_mask, "V16sV16sIiV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlw512_mask, "V32sV32sV8sV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrlwi512_mask, "V32sV32sIiV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrlw128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlw256_mask, "V16sV16sV8sV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlwi128_mask, "V8sV8sIiV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlwi256_mask, "V16sV16sIiV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllv32hi, "V32sV32sV32s","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psllw512, "V32sV32sV8s","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psllwi512, "V32sV32si","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psllv16hi, "V16sV16sV16s","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllv8hi, "V8sV8sV8s","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_pslldi512, "V16iV16ii","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psllqi512, "V8LLiV8LLii","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrlv32hi, "V32sV32sV32s","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrlv16hi, "V16sV16sV16s","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlv8hi, "V8sV8sV8s","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrldi512, "V16iV16ii","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrlqi512, "V8LLiV8LLii","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrav32hi, "V32sV32sV32s","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrav16hi, "V16sV16sV16s","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrav8hi, "V8sV8sV8s","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psravq128, "V2LLiV2LLiV2LLi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psravq256, "V4LLiV4LLiV4LLi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraw512, "V32sV32sV8s","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrawi512, "V32sV32si","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrlw512, "V32sV32sV8s","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_psrlwi512, "V32sV32si","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_movdqa32load128_mask, "V4iV4i*V4iUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_movdqa32load256_mask, "V8iV8i*V8iUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_movdqa32load512_mask, "V16iV16iC*V16iUs","","avx512f")
@ -1653,8 +1384,6 @@ TARGET_BUILTIN(__builtin_ia32_pbroadcastb128_gpr_mask, "V16ccV16cUs","","avx512b
TARGET_BUILTIN(__builtin_ia32_pbroadcastb256_gpr_mask, "V32ccV32cUi","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_pbroadcastd128_gpr_mask, "V4iiV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pbroadcastd256_gpr_mask, "V8iiV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq128_gpr_mask, "V2LLiULLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq256_gpr_mask, "V4LLiULLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
@ -1707,8 +1436,10 @@ TARGET_BUILTIN(__builtin_ia32_fixupimmps128_maskz, "V4fV4fV4fV4iIiUc","","avx512
TARGET_BUILTIN(__builtin_ia32_fixupimmps256_mask, "V8fV8fV8fV8iIiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_fixupimmps256_maskz, "V8fV8fV8fV8iIiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadapd128_mask, "V2dV2d*V2dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadsd128_mask, "V8dV8d*V8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_loadapd256_mask, "V4dV4d*V4dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadaps128_mask, "V4fV4f*V4fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadss128_mask, "V16fV16f*V16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_loadaps256_mask, "V8fV8f*V8fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddqudi128_mask, "V2LLiV2LLi*V2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_loaddqudi256_mask, "V4LLiV4LLi*V4LLiUc","","avx512vl")
@ -1725,8 +1456,10 @@ TARGET_BUILTIN(__builtin_ia32_storedquhi256_mask, "vV16s*V16sUs","","avx512vl,av
TARGET_BUILTIN(__builtin_ia32_storedquqi128_mask, "vV16c*V16cUs","","avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_storedquqi256_mask, "vV32c*V32cUi","","avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_storeapd128_mask, "vV2d*V2dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_storesd128_mask, "vV8d*V8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_storeapd256_mask, "vV4d*V4dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_storeaps128_mask, "vV4f*V4fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_storess128_mask, "vV16f*V16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_storeaps256_mask, "vV8f*V8fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_storedqudi128_mask, "vV2LLi*V2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_storedqudi256_mask, "vV4LLi*V4LLiUc","","avx512vl")
@ -1744,36 +1477,24 @@ TARGET_BUILTIN(__builtin_ia32_vplzcntd_128_mask, "V4iV4iV4iUc","","avx512cd,avx5
TARGET_BUILTIN(__builtin_ia32_vplzcntd_256_mask, "V8iV8iV8iUc","","avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vplzcntq_128_mask, "V2LLiV2LLiV2LLiUc","","avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vplzcntq_256_mask, "V4LLiV4LLiV4LLiUc","","avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "LLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2si32, "iV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi32, "UiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtss2si32, "iV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtss2usi32, "UiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "ULLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttsd2si32, "iV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "LLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi32, "UiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "ULLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttss2si32, "iV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "LLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttss2usi32, "UiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "ULLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermi2vard512_mask, "V16iV16iV16iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512_mask, "V8dV8dV8LLiV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermi2varps512_mask, "V16fV16fV16iV16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermi2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512_mask, "V8dV8dV8LLiV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermilvarps512_mask, "V16fV16fV16iV16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8LLi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermilvarps512, "V16fV16fV16i","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_maskz, "V16iV16iV16iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_maskz, "V8dV8LLiV8dV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_maskz, "V16fV16iV16fV16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermilvarpd_mask, "V2dV2dV2LLiV2dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256_mask, "V4dV4dV4LLiV4dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermilvarps_mask, "V4fV4fV4iV4fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermilvarps256_mask, "V8fV8fV8iV8fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_ptestmb512, "ULLiV64cV64cULLi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_ptestmw512, "UiV32sV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_ptestnmb512, "ULLiV64cV64cULLi","","avx512bw")
@ -1802,28 +1523,24 @@ TARGET_BUILTIN(__builtin_ia32_scalefpd512_mask, "V8dV8dV8dV8dUcIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_scalefps512_mask, "V16fV16fV16fV16fUsIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_scalefsd_round_mask, "V2dV2dV2dV2dUcIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_scalefss_round_mask, "V4fV4fV4fV4fUcIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psradi512_mask, "V16iV16iIiV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psraqi512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrad128_mask, "V4iV4iV4iV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrad256_mask, "V8iV8iV4iV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psradi128_mask, "V4iV4iIiV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psradi256_mask, "V8iV8iIiV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraq256_mask, "V4LLiV4LLiV2LLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraqi128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraqi256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pslld512_mask, "V16iV16iV4iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psllq512_mask, "V8LLiV8LLiV2LLiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psllv16si_mask, "V16iV16iV16iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psllv8di_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrad512_mask, "V16iV16iV4iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psraq512_mask, "V8LLiV8LLiV2LLiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrav16si_mask, "V16iV16iV16iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrav8di_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrld512_mask, "V16iV16iV4iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrlq512_mask, "V8LLiV8LLiV2LLiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrlv16si_mask, "V16iV16iV16iV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrlv8di_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psradi512, "V16iV16ii","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psraqi512, "V8LLiV8LLii","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psraq128, "V2LLiV2LLiV2LLi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraq256, "V4LLiV4LLiV2LLi","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraqi128, "V2LLiV2LLii","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraqi256, "V4LLiV4LLii","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pslld512, "V16iV16iV4i","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psllq512, "V8LLiV8LLiV2LLi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psllv16si, "V16iV16iV16i","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psllv8di, "V8LLiV8LLiV8LLi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrad512, "V16iV16iV4i","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psraq512, "V8LLiV8LLiV2LLi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrav16si, "V16iV16iV16i","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrav8di, "V8LLiV8LLiV8LLi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrld512, "V16iV16iV4i","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrlq512, "V8LLiV8LLiV2LLi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrlv16si, "V16iV16iV16i","","avx512f")
TARGET_BUILTIN(__builtin_ia32_psrlv8di, "V8LLiV8LLiV8LLi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pternlogd512_mask, "V16iV16iV16iV16iIiUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pternlogd512_maskz, "V16iV16iV16iV16iIiUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8LLiV8LLiV8LLiV8LLiIiUc","","avx512f")
@ -1996,28 +1713,6 @@ TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2LLiV8sUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovqw256_mask, "V8sV4LLiV8sUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovqw256mem_mask, "vV8s*V4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_extractf32x8_mask, "V8fV16fIiV8fUc","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_extractf64x2_512_mask, "V2dV8dIiV2dUc","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_extracti32x8_mask, "V8iV16iIiV8iUc","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_extracti64x2_512_mask, "V2LLiV8LLiIiV2LLiUc","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_extracti32x4_mask, "V4iV16iIiV4iUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_extracti64x4_mask, "V4LLiV8LLiIiV4LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_extractf64x2_256_mask, "V2dV4dIiV2dUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_extracti64x2_256_mask, "V2LLiV4LLiIiV2LLiUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_extractf32x4_256_mask, "V4fV8fIiV4fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_extracti32x4_256_mask, "V4iV8iIiV4iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_insertf32x8_mask, "V16fV16fV8fIiV16fUs","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_insertf64x2_512_mask, "V8dV8dV2dIiV8dUc","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_inserti32x8_mask, "V16iV16iV8iIiV16iUs","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_inserti64x2_512_mask, "V8LLiV8LLiV2LLiIiV8LLiUc","","avx512dq")
TARGET_BUILTIN(__builtin_ia32_insertf64x4_mask, "V8dV8dV4dIiV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_inserti64x4_mask, "V8LLiV8LLiV4LLiIiV8LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_insertf64x2_256_mask, "V4dV4dV2dIiV4dUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_inserti64x2_256_mask, "V4LLiV4LLiV2LLiIiV4LLiUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_insertf32x4_256_mask, "V8fV8fV4fIiV8fUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_inserti32x4_256_mask, "V8iV8iV4iIiV8iUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_insertf32x4_mask, "V16fV16fV4fIiV16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_inserti32x4_mask, "V16iV16iV4iIiV16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_getmantpd128_mask, "V2dV2diV2dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_getmantpd256_mask, "V4dV4diV4dUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_getmantps128_mask, "V4fV4fiV4fUc","","avx512vl")
@ -2032,6 +1727,10 @@ TARGET_BUILTIN(__builtin_ia32_vfmaddss3_mask3, "V4fV4fV4fV4fUcIi", "", "avx512f"
TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask, "V2dV2dV2dV2dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_maskz, "V2dV2dV2dV2dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask3, "V2dV2dV2dV2dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfmsubsd3_mask3, "V2dV2dV2dV2dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfmsubss3_mask3, "V4fV4fV4fV4fUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfnmsubsd3_mask3, "V2dV2dV2dV2dUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfnmsubss3_mask3, "V4fV4fV4fV4fUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_permvarhi512_mask, "V32sV32sV32sV32sUi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_permvardf512_mask, "V8dV8dV8LLiV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_permvardi512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f")
@ -2064,8 +1763,6 @@ TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_movntdqa512, "V8LLiV8LLi*","","avx512f")
TARGET_BUILTIN(__builtin_ia32_palignr512_mask, "V64cV64cV64cIiV64cULLi","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_palignr128_mask, "V16cV16cV16cIiV16cUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_palignr256_mask, "V32cV32cV32cIiV32cUi","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw128_mask, "V8sV16cV16cIiV8sUc","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw256_mask, "V16sV32cV32cIiV16sUs","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw512_mask, "V32sV64cV64cIiV32sUi","","avx512bw")
@ -2097,14 +1794,10 @@ TARGET_BUILTIN(__builtin_ia32_cvtw2mask512, "UiV32s","","avx512bw")
TARGET_BUILTIN(__builtin_ia32_cvtw2mask128, "UcV8s","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtw2mask256, "UsV16s","","avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtsd2ss_round_mask, "V4fV4fV2dV4fUcIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dLLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtsi2ss32, "V4fV4fiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fLLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtss2sd_round_mask, "V2dV2dV4fV2dUcIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2sd32, "V2dV2dUi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dULLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2ss32, "V4fV4fUiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fULLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512_mask, "V64cV64cV64cV64cULLi","","avx512vbmi")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128_mask, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256_mask, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl")
@ -2133,5 +1826,21 @@ TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "", "")
TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx")
TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx")
// MSVC
TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_ReadBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_WriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__emul, "LLiii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
#undef BUILTIN
#undef TARGET_BUILTIN
#undef TARGET_HEADER_BUILTIN

View File

@ -0,0 +1,90 @@
//===--- BuiltinsX86_64.def - X86-64 Builtin function database --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the X86-64-specific builtin function database. Users of
// this file must define the BUILTIN macro to make use of this information.
//
//===----------------------------------------------------------------------===//
// The format of this database matches clang/Basic/Builtins.def.
#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN)
# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_umul128, "ULLiULLiULLiULLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "")
TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "")
TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "", "sse")
TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "", "sse4.2")
TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "", "fsgsbase")
TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "", "fxsr")
TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "", "fxsr")
TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "", "xsave")
TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "", "xsave")
TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "", "xsaveopt")
TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "", "xsaves")
TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec")
TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves")
TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx")
TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "")
TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "")
TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "", "rdseed")
TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "", "bmi")
TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "", "bmi2")
TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "", "tbm")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_gpr_mask, "V8LLiLLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq128_gpr_mask, "V2LLiULLiV2LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_pbroadcastq256_gpr_mask, "V4LLiULLiV4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "LLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "ULLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "LLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "ULLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "LLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "ULLiV4fIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dLLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fLLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dULLiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fULLiIi","","avx512f")
#undef BUILTIN
#undef TARGET_BUILTIN
#undef TARGET_HEADER_BUILTIN

View File

@ -37,6 +37,7 @@ def Named : Decl<1>;
def EnumConstant : DDecl<Value>;
def UnresolvedUsingValue : DDecl<Value>;
def IndirectField : DDecl<Value>;
def Binding : DDecl<Value>;
def OMPDeclareReduction : DDecl<Value>, DeclContext;
def Declarator : DDecl<Value, 1>;
def Field : DDecl<Declarator>;
@ -54,6 +55,7 @@ def Named : Decl<1>;
: DDecl<VarTemplateSpecialization>;
def ImplicitParam : DDecl<Var>;
def ParmVar : DDecl<Var>;
def Decomposition : DDecl<Var>;
def OMPCapturedExpr : DDecl<Var>;
def NonTypeTemplateParm : DDecl<Declarator>;
def Template : DDecl<Named, 1>;
@ -65,6 +67,7 @@ def Named : Decl<1>;
def TemplateTemplateParm : DDecl<Template>;
def BuiltinTemplate : DDecl<Template>;
def Using : DDecl<Named>;
def UsingPack : DDecl<Named>;
def UsingShadow : DDecl<Named>;
def ConstructorUsingShadow : DDecl<UsingShadow>;
def ObjCMethod : DDecl<Named>, DeclContext;
@ -78,6 +81,7 @@ def Named : Decl<1>;
def ObjCProperty : DDecl<Named>;
def ObjCCompatibleAlias : DDecl<Named>;
def LinkageSpec : Decl, DeclContext;
def Export : Decl, DeclContext;
def ObjCPropertyImpl : Decl;
def FileScopeAsm : Decl;
def AccessSpec : Decl;

View File

@ -23,22 +23,33 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <list>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
namespace clang {
class DeclContext;
class DiagnosticBuilder;
class DiagnosticConsumer;
class DiagnosticErrorTrap;
class DiagnosticOptions;
class IdentifierInfo;
class LangOptions;
class Preprocessor;
class StoredDiagnostic;
namespace tok {
class DeclContext;
class DiagnosticBuilder;
class DiagnosticConsumer;
class IdentifierInfo;
class LangOptions;
class Preprocessor;
class StoredDiagnostic;
namespace tok {
enum TokenKind : unsigned short;
}
} // end namespace tok
/// \brief Annotates a diagnostic with some code that should be
/// inserted, removed, or replaced to fix the problem.
@ -133,9 +144,6 @@ class FixItHint {
/// the user. DiagnosticsEngine is tied to one translation unit and one
/// SourceManager.
class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
DiagnosticsEngine(const DiagnosticsEngine &) = delete;
void operator=(const DiagnosticsEngine &) = delete;
public:
/// \brief The level of the diagnostic, after it has been through mapping.
enum Level {
@ -344,11 +352,12 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
std::string FlagValue;
public:
explicit DiagnosticsEngine(
const IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
DiagnosticOptions *DiagOpts,
DiagnosticConsumer *client = nullptr,
bool ShouldOwnClient = true);
explicit DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> Diags,
DiagnosticOptions *DiagOpts,
DiagnosticConsumer *client = nullptr,
bool ShouldOwnClient = true);
DiagnosticsEngine(const DiagnosticsEngine &) = delete;
DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
~DiagnosticsEngine();
const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
@ -885,7 +894,6 @@ class DiagnosticBuilder {
/// call to ForceEmit.
mutable bool IsForceEmit = false;
void operator=(const DiagnosticBuilder &) = delete;
friend class DiagnosticsEngine;
DiagnosticBuilder() = default;
@ -950,16 +958,18 @@ class DiagnosticBuilder {
NumArgs = D.NumArgs;
}
/// \brief Retrieve an empty diagnostic builder.
static DiagnosticBuilder getEmpty() {
return DiagnosticBuilder();
}
DiagnosticBuilder &operator=(const DiagnosticBuilder &) = delete;
/// \brief Emits the diagnostic.
~DiagnosticBuilder() {
Emit();
}
/// \brief Retrieve an empty diagnostic builder.
static DiagnosticBuilder getEmpty() {
return DiagnosticBuilder();
}
/// \brief Forces the diagnostic to be emitted.
const DiagnosticBuilder &setForceEmit() const {
IsForceEmit = true;
@ -1144,6 +1154,7 @@ inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
class Diagnostic {
const DiagnosticsEngine *DiagObj;
StringRef StoredDiagMessage;
public:
explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage)
@ -1280,7 +1291,7 @@ class StoredDiagnostic {
ArrayRef<FixItHint> Fixits);
/// \brief Evaluates true when this object stores a diagnostic.
explicit operator bool() const { return Message.size() > 0; }
explicit operator bool() const { return !Message.empty(); }
unsigned getID() const { return ID; }
DiagnosticsEngine::Level getLevel() const { return Level; }
@ -1298,7 +1309,6 @@ class StoredDiagnostic {
return llvm::makeArrayRef(Ranges);
}
typedef std::vector<FixItHint>::const_iterator fixit_iterator;
fixit_iterator fixit_begin() const { return FixIts.begin(); }
fixit_iterator fixit_end() const { return FixIts.end(); }
@ -1313,18 +1323,18 @@ class StoredDiagnostic {
/// formats and prints fully processed diagnostics.
class DiagnosticConsumer {
protected:
unsigned NumWarnings; ///< Number of warnings reported
unsigned NumErrors; ///< Number of errors reported
unsigned NumWarnings = 0; ///< Number of warnings reported
unsigned NumErrors = 0; ///< Number of errors reported
public:
DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { }
DiagnosticConsumer() = default;
virtual ~DiagnosticConsumer();
unsigned getNumErrors() const { return NumErrors; }
unsigned getNumWarnings() const { return NumWarnings; }
virtual void clear() { NumWarnings = NumErrors = 0; }
virtual ~DiagnosticConsumer();
/// \brief Callback to inform the diagnostic client that processing
/// of a source file is beginning.
///
@ -1369,6 +1379,7 @@ class DiagnosticConsumer {
/// \brief A diagnostic client that ignores all diagnostics.
class IgnoringDiagConsumer : public DiagnosticConsumer {
virtual void anchor();
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const Diagnostic &Info) override {
// Just ignore it.
@ -1416,6 +1427,6 @@ void ProcessWarningOptions(DiagnosticsEngine &Diags,
const DiagnosticOptions &Opts,
bool ReportDiags = true);
} // end namespace clang
} // end namespace clang
#endif
#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_H

View File

@ -48,10 +48,13 @@ class DiagGroup<string Name, list<DiagGroup> subgroups = []> {
string GroupName = Name;
list<DiagGroup> SubGroups = subgroups;
string CategoryName = "";
code Documentation = [{}];
}
class InGroup<DiagGroup G> { DiagGroup Group = G; }
//class IsGroup<string Name> { DiagGroup Group = DiagGroup<Name>; }
// This defines documentation for diagnostic groups.
include "DiagnosticDocs.td"
// This defines all of the named diagnostic categories.
include "DiagnosticCategories.td"

View File

@ -158,6 +158,12 @@ def warn_integer_constant_overflow : Warning<
"overflow in expression; result is %0 with type %1">,
InGroup<DiagGroup<"integer-overflow">>;
// This is a temporary diagnostic, and shall be removed once our
// implementation is complete, and like the preceding constexpr notes belongs
// in Sema.
def note_unimplemented_constexpr_lambda_feature_ast : Note<
"unimplemented constexpr lambda feature: %0 (coming soon!)">;
// inline asm related.
let CategoryName = "Inline Assembly Issue" in {
def err_asm_invalid_escape : Error<

View File

@ -94,6 +94,8 @@ def err_module_lock_timeout : Error<
"timed out waiting to acquire lock file for module '%0'">, DefaultFatal;
def err_module_cycle : Error<"cyclic dependency in module '%0': %1">,
DefaultFatal;
def err_module_prebuilt : Error<
"error in loading module '%0' from prebuilt module path">, DefaultFatal;
def note_pragma_entered_here : Note<"#pragma entered here">;
def note_decl_hiding_tag_type : Note<
"%1 %0 is hidden by a non-type declaration of %0 here">;
@ -188,6 +190,8 @@ def err_target_unsupported_fpmath : Error<
"the '%0' unit is not supported with this instruction set">;
def err_target_unsupported_unaligned : Error<
"the %0 sub-architecture does not support unaligned accesses">;
def err_target_unsupported_execute_only : Error<
"execute only is not supported for the %0 sub-architecture">;
def err_opt_not_valid_with_opt : Error<
"option '%0' cannot be specified with '%1'">;

View File

@ -0,0 +1,84 @@
//==--- DiagnosticDocs.td - Diagnostic documentation ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
def GlobalDocumentation {
code Intro =[{..
-------------------------------------------------------------------
NOTE: This file is automatically generated by running clang-tblgen
-gen-diag-docs. Do not edit this file by hand!!
-------------------------------------------------------------------
.. Add custom CSS to output. FIXME: This should be put into <head> rather
than the start of <body>.
.. raw:: html
<style>
table.docutils {
width: 1px;
}
table.docutils td {
border: none;
padding: 0 0 0 0.2em;
vertical-align: middle;
white-space: nowrap;
width: 1px;
font-family: monospace;
}
table.docutils tr + tr {
border-top: 0.2em solid #aaa;
}
.error {
font-family: monospace;
font-weight: bold;
color: #c00;
}
.warning {
font-family: monospace;
font-weight: bold;
color: #80a;
}
.remark {
font-family: monospace;
font-weight: bold;
color: #00c;
}
.diagtext {
font-family: monospace;
font-weight: bold;
}
</style>
.. FIXME: rST doesn't support formatting this, so we format all <td> elements
as monospace font face instead.
.. |nbsp| unicode:: 0xA0
:trim:
.. Roles generated by clang-tblgen.
.. role:: error
.. role:: warning
.. role:: remark
.. role:: diagtext
.. role:: placeholder(emphasis)
=========================
Diagnostic flags in Clang
=========================
.. contents::
:local:
Introduction
============
This page lists the diagnostic flags currently supported by Clang.
Diagnostic flags
================
}];
}

View File

@ -26,10 +26,14 @@ def err_drv_cuda_bad_gpu_arch : Error<"Unsupported CUDA gpu architecture: %0">;
def err_drv_no_cuda_installation : Error<
"cannot find CUDA installation. Provide its path via --cuda-path, or pass "
"-nocudainc to build without CUDA includes.">;
def err_drv_no_cuda_libdevice : Error<
"cannot find libdevice for %0. Provide path to different CUDA installation "
"via --cuda-path, or pass -nocudalib to build without linking with libdevice.">;
def err_drv_cuda_version_too_low : Error<
"GPU arch %1 requires CUDA version at least %3, but installation at %0 is %2. "
"Use --cuda-path to specify a different CUDA install, or pass "
"--no-cuda-version-check.">;
def err_drv_cuda_nvptx_host : Error<"unsupported use of NVPTX for host compilation.">;
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<
@ -83,6 +87,8 @@ def err_drv_clang_unsupported_opt_cxx_darwin_i386 : Error<
"the clang compiler does not support '%0' for C++ on Darwin/i386">;
def err_drv_command_failed : Error<
"%0 command failed with exit code %1 (use -v to see invocation)">;
def err_drv_compilationdatabase : Error<
"compilation database '%0' could not be opened: %1">;
def err_drv_command_signalled : Error<
"%0 command failed due to signal (use -v to see invocation)">;
def err_drv_force_crash : Error<
@ -131,8 +137,6 @@ def err_drv_preamble_format : Error<
"incorrect format for -preamble-bytes=N,END">;
def err_drv_conflicting_deployment_targets : Error<
"conflicting deployment targets, both '%0' and '%1' are present in environment">;
def err_drv_objc_gc_arr : Error<
"cannot specify both '-fobjc-arc' and '%0'">;
def err_arc_unsupported_on_runtime : Error<
"-fobjc-arc is not supported on platforms using the legacy runtime">;
def err_arc_unsupported_on_toolchain : Error< // feel free to generalize this
@ -155,6 +159,11 @@ def err_drv_omp_host_ir_file_not_found : Error<
"The provided host compiler IR file '%0' is required to generate code for OpenMP target regions but cannot be found.">;
def err_drv_omp_host_target_not_supported : Error<
"The target '%0' is not a supported OpenMP host target.">;
def err_drv_expecting_fopenmp_with_fopenmp_targets : Error<
"The option -fopenmp-targets must be used in conjunction with a -fopenmp option compatible with offloading, please use -fopenmp=libomp or -fopenmp=libiomp5.">;
def warn_drv_omp_offload_target_duplicate : Warning<
"The OpenMP offloading target '%0' is similar to target '%1' already specified - will be ignored.">,
InGroup<OpenMPTarget>;
def err_drv_bitcode_unsupported_on_toolchain : Error<
"-fembed-bitcode is not supported on versions of iOS prior to 6.0">;
@ -163,6 +172,9 @@ def warn_drv_optimization_value : Warning<"optimization level '%0' is not suppor
InGroup<InvalidCommandLineArgument>;
def warn_ignored_gcc_optimization : Warning<"optimization flag '%0' is not supported">,
InGroup<IgnoredOptimizationArgument>;
def warn_drv_unsupported_opt_for_target : Warning<
"optimization flag '%0' is not supported for target '%1'">,
InGroup<IgnoredOptimizationArgument>;
def warn_c_kext : Warning<
"ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
def warn_drv_input_file_unused : Warning<
@ -180,6 +192,9 @@ def warn_drv_unused_argument : Warning<
def warn_drv_empty_joined_argument : Warning<
"joined argument expects additional value: '%0'">,
InGroup<UnusedCommandLineArgument>;
def warn_drv_fdiagnostics_show_hotness_requires_pgo : Warning<
"argument '-fdiagnostics-show-hotness' requires profile-guided optimization information">,
InGroup<UnusedCommandLineArgument>;
def warn_drv_clang_unsupported : Warning<
"the clang compiler does not support '%0'">;
def warn_drv_deprecated_arg : Warning<
@ -194,8 +209,6 @@ def warn_drv_overriding_flag_option : Warning<
def warn_drv_treating_input_as_cxx : Warning<
"treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
InGroup<Deprecated>;
def warn_drv_objc_gc_unsupported : Warning<
"Objective-C garbage collection is not supported on this platform, ignoring '%0'">;
def warn_drv_pch_not_first_include : Warning<
"precompiled header '%0' was ignored because '%1' is not first '-include'">;
def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">,
@ -234,6 +247,11 @@ def err_test_module_file_extension_format : Error<
def warn_drv_invoking_fallback : Warning<"falling back to %0">,
InGroup<Fallback>;
def err_drv_ropi_rwpi_incompatible_with_pic : Error<
"embedded and GOT-based position independence are incompatible">;
def err_drv_ropi_incompatible_with_cxx : Error<
"ROPI is not compatible with c++">;
def warn_target_unsupported_nan2008 : Warning<
"ignoring '-mnan=2008' option because the '%0' architecture does not support it">,
InGroup<UnsupportedNan>;
@ -257,4 +275,6 @@ def warn_drv_ps4_sdk_dir : Warning<
InGroup<InvalidOrNonExistentDirectory>;
def err_drv_unsupported_linker : Error<"unsupported value '%0' for -linker option">;
def err_drv_defsym_invalid_format : Error<"defsym must be of the form: sym=value: %0">;
def err_drv_defsym_invalid_symval : Error<"Value is not an integer: %0">;
}

View File

@ -107,10 +107,15 @@ def warn_fe_cc_print_header_failure : Warning<
"unable to open CC_PRINT_HEADERS file: %0 (using stderr)">;
def warn_fe_cc_log_diagnostics_failure : Warning<
"unable to open CC_LOG_DIAGNOSTICS file: %0 (using stderr)">;
def warn_fe_unable_to_open_stats_file : Warning<
"unable to open statistics output file '%0': '%1'">,
InGroup<DiagGroup<"unable-to-open-stats-file">>;
def err_fe_no_pch_in_dir : Error<
"no suitable precompiled header file found in directory '%0'">;
def err_fe_action_not_available : Error<
"action %0 not compiled in">;
def err_fe_invalid_alignment : Error<
"invalid value '%1' in '%0'; alignment must be a power of 2">;
def warn_fe_serialized_diag_merge_failure : Warning<
"unable to merge a subprocess's serialized diagnostics">,
@ -174,6 +179,8 @@ def warn_incompatible_analyzer_plugin_api : Warning<
def note_incompatible_analyzer_plugin_api : Note<
"current API version is '%0', but plugin was compiled with version '%1'">;
def err_module_interface_requires_modules_ts : Error<
"module interface compilation requires '-fmodules-ts'">;
def warn_module_config_mismatch : Warning<
"module file %0 cannot be loaded due to a configuration mismatch with the current "
"compilation">, InGroup<DiagGroup<"module-file-config-mismatch">>, DefaultError;
@ -217,4 +224,4 @@ def err_invalid_vfs_overlay : Error<
def warn_option_invalid_ocl_version : Warning<
"OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>;
}
}

View File

@ -62,7 +62,6 @@ def NullConversion : DiagGroup<"null-conversion">;
def ImplicitConversionFloatingPointToBool :
DiagGroup<"implicit-conversion-floating-point-to-bool">;
def ObjCLiteralConversion : DiagGroup<"objc-literal-conversion">;
def BadArrayNewLength : DiagGroup<"bad-array-new-length">;
def MacroRedefined : DiagGroup<"macro-redefined">;
def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">;
def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
@ -95,8 +94,11 @@ def CXX11CompatDeprecatedWritableStr :
def DeprecatedAttributes : DiagGroup<"deprecated-attributes">;
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
def UnavailableDeclarations : DiagGroup<"unavailable-declarations">;
def PartialAvailability : DiagGroup<"partial-availability">;
def UnguardedAvailability : DiagGroup<"unguarded-availability">;
// partial-availability is an alias of unguarded-availability.
def : DiagGroup<"partial-availability", [UnguardedAvailability]>;
def DeprecatedDynamicExceptionSpec
: DiagGroup<"deprecated-dynamic-exception-spec">;
def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;
def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">;
def DeprecatedRegister : DiagGroup<"deprecated-register">;
@ -105,15 +107,20 @@ def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
// FIXME: Why is DeprecatedImplementations not in this group?
def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes,
DeprecatedDeclarations,
DeprecatedDynamicExceptionSpec,
DeprecatedIncrementBool,
DeprecatedRegister,
DeprecatedWritableStr]>,
DiagCategory<"Deprecations">;
def DynamicExceptionSpec
: DiagGroup<"dynamic-exception-spec", [DeprecatedDynamicExceptionSpec]>;
def LibLTO : DiagGroup<"liblto">;
def : DiagGroup<"disabled-optimization">;
def : DiagGroup<"discard-qual">;
def : DiagGroup<"div-by-zero">;
def DivZero : DiagGroup<"division-by-zero">;
def : DiagGroup<"div-by-zero", [DivZero]>;
def DocumentationHTML : DiagGroup<"documentation-html">;
def DocumentationUnknownCommand : DiagGroup<"documentation-unknown-command">;
@ -200,8 +207,6 @@ def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
def CXX1zCompat : DiagGroup<"c++1z-compat", [DeprecatedRegister,
DeprecatedIncrementBool]>;
def : DiagGroup<"effc++">;
def DivZero : DiagGroup<"division-by-zero">;
def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
@ -225,9 +230,12 @@ def GNUIncludeNext : DiagGroup<"gnu-include-next">;
def IncompatibleMSStruct : DiagGroup<"incompatible-ms-struct">;
def IncompatiblePointerTypesDiscardsQualifiers
: DiagGroup<"incompatible-pointer-types-discards-qualifiers">;
def IncompatibleFunctionPointerTypes
: DiagGroup<"incompatible-function-pointer-types">;
def IncompatiblePointerTypes
: DiagGroup<"incompatible-pointer-types",
[IncompatiblePointerTypesDiscardsQualifiers]>;
[IncompatiblePointerTypesDiscardsQualifiers,
IncompatibleFunctionPointerTypes]>;
def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
def NonModularIncludeInFrameworkModule
: DiagGroup<"non-modular-include-in-framework-module">;
@ -235,6 +243,7 @@ def NonModularIncludeInModule : DiagGroup<"non-modular-include-in-module",
[NonModularIncludeInFrameworkModule]>;
def IncompleteModule : DiagGroup<"incomplete-module",
[IncompleteUmbrella, NonModularIncludeInModule]>;
def PrivateModule : DiagGroup<"private-module">;
def CXX11InlineNamespace : DiagGroup<"c++11-inline-namespace">;
def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
@ -254,6 +263,7 @@ def LoopAnalysis : DiagGroup<"loop-analysis", [ForLoopAnalysis,
def MalformedWarningCheck : DiagGroup<"malformed-warning-check">;
def Main : DiagGroup<"main">;
def MainReturnType : DiagGroup<"main-return-type">;
def MaxUnsignedZero : DiagGroup<"max-unsigned-zero">;
def MissingBraces : DiagGroup<"missing-braces">;
def MissingDeclarations: DiagGroup<"missing-declarations">;
def : DiagGroup<"missing-format-attribute">;
@ -275,8 +285,11 @@ def ModuleFileExtension : DiagGroup<"module-file-extension">;
def NewlineEOF : DiagGroup<"newline-eof">;
def Nullability : DiagGroup<"nullability">;
def NullabilityDeclSpec : DiagGroup<"nullability-declspec">;
def NullabilityInferredOnNestedType : DiagGroup<"nullability-inferred-on-nested-type">;
def NullableToNonNullConversion : DiagGroup<"nullable-to-nonnull-conversion">;
def NullabilityCompleteness : DiagGroup<"nullability-completeness">;
def NullabilityCompletenessOnArrays : DiagGroup<"nullability-completeness-on-arrays">;
def NullabilityCompleteness : DiagGroup<"nullability-completeness",
[NullabilityCompletenessOnArrays]>;
def NullArithmetic : DiagGroup<"null-arithmetic">;
def NullCharacter : DiagGroup<"null-character">;
def NullDereference : DiagGroup<"null-dereference">;
@ -286,6 +299,7 @@ def NonPODVarargs : DiagGroup<"non-pod-varargs">;
def ClassVarargs : DiagGroup<"class-varargs", [NonPODVarargs]>;
def : DiagGroup<"nonportable-cfstrings">;
def NonVirtualDtor : DiagGroup<"non-virtual-dtor">;
def : DiagGroup<"effc++", [NonVirtualDtor]>;
def OveralignedType : DiagGroup<"over-aligned">;
def OldStyleCast : DiagGroup<"old-style-cast">;
def : DiagGroup<"old-style-definition">;
@ -313,6 +327,7 @@ def ObjCRootClass : DiagGroup<"objc-root-class">;
def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-introspection-performSelector">;
def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>;
def ObjCMultipleMethodNames : DiagGroup<"objc-multiple-method-names">;
def OpenCLUnsupportedRGBA: DiagGroup<"opencl-unsupported-rgba">;
def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
def Packed : DiagGroup<"packed">;
@ -343,11 +358,15 @@ def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
def ShadowFieldInConstructorModified : DiagGroup<"shadow-field-in-constructor-modified">;
def ShadowFieldInConstructor : DiagGroup<"shadow-field-in-constructor",
[ShadowFieldInConstructorModified]>;
def ShadowIvar : DiagGroup<"shadow-ivar">;
def ShadowUncapturedLocal : DiagGroup<"shadow-uncaptured-local">;
// -Wshadow-all is a catch-all for all shadowing. -Wshadow is just the
// shadowing that we think is unsafe.
def Shadow : DiagGroup<"shadow", [ShadowFieldInConstructorModified]>;
def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor]>;
def Shadow : DiagGroup<"shadow", [ShadowFieldInConstructorModified,
ShadowIvar]>;
def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor,
ShadowUncapturedLocal]>;
def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
def : DiagGroup<"sign-promo">;
@ -432,8 +451,9 @@ def UninitializedSometimes : DiagGroup<"sometimes-uninitialized">;
def UninitializedStaticSelfInit : DiagGroup<"static-self-init">;
def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes,
UninitializedStaticSelfInit]>;
def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
def IgnoredPragmas : DiagGroup<"ignored-pragmas">;
def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>;
def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>;
def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
@ -491,6 +511,7 @@ def AutomaticReferenceCounting : DiagGroup<"arc",
def ARCRepeatedUseOfWeakMaybe : DiagGroup<"arc-maybe-repeated-use-of-weak">;
def ARCRepeatedUseOfWeak : DiagGroup<"arc-repeated-use-of-weak",
[ARCRepeatedUseOfWeakMaybe]>;
def BlockCaptureAutoReleasing : DiagGroup<"block-capture-autoreleasing">;
def ObjCBridge : DiagGroup<"bridge-cast">;
def DeallocInCategory:DiagGroup<"dealloc-in-category">;
@ -530,6 +551,7 @@ def GCCWriteStrings : DiagGroup<"write-strings" , [WritableStrings]>;
def CharSubscript : DiagGroup<"char-subscripts">;
def LargeByValueCopy : DiagGroup<"large-by-value-copy">;
def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
def SignedEnumBitfield : DiagGroup<"signed-enum-bitfield">;
// Unreachable code warning groups.
//
@ -614,6 +636,8 @@ def Format2 : DiagGroup<"format=2",
def TypeSafety : DiagGroup<"type-safety">;
def IncompatibleExceptionSpec : DiagGroup<"incompatible-exception-spec">;
def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">;
def IntToPointerCast : DiagGroup<"int-to-pointer-cast",
[IntToVoidPointerCast]>;
@ -830,8 +854,9 @@ def ObjCLiteralComparison : DiagGroup<"objc-literal-compare", [
// Inline ASM warnings.
def ASMOperandWidths : DiagGroup<"asm-operand-widths">;
def ASMIgnoredQualifier : DiagGroup<"asm-ignored-qualifier">;
def ASM : DiagGroup<"asm", [
ASMOperandWidths
ASMOperandWidths, ASMIgnoredQualifier
]>;
// OpenMP warnings.
@ -872,3 +897,7 @@ def InvalidOrNonExistentDirectory : DiagGroup<"invalid-or-nonexistent-directory"
def OptionIgnored : DiagGroup<"option-ignored">;
def UnknownArgument : DiagGroup<"unknown-argument">;
// A warning group for warnings about code that clang accepts when
// compiling OpenCL C/C++ but which is not compatible with the SPIR spec.
def SpirCompat : DiagGroup<"spir-compat">;

View File

@ -183,7 +183,7 @@ def ext_hex_constant_invalid : Extension<
def ext_hex_literal_invalid : Extension<
"hexadecimal floating literals are a C++1z feature">, InGroup<CXX1z>;
def warn_cxx1z_hex_literal : Warning<
"hexidecimal floating literals are incompatible with "
"hexadecimal floating literals are incompatible with "
"C++ standards before C++1z">,
InGroup<CXXPre1zCompatPedantic>, DefaultIgnore;
def ext_binary_literal : Extension<
@ -642,6 +642,11 @@ def err_mmap_expected_feature : Error<"expected a feature name">;
def err_mmap_expected_attribute : Error<"expected an attribute name">;
def warn_mmap_unknown_attribute : Warning<"unknown attribute '%0'">,
InGroup<IgnoredAttributes>;
def warn_mmap_mismatched_top_level_private : Warning<
"top-level module '%0' in private module map, expected a submodule of '%1'">,
InGroup<PrivateModule>;
def note_mmap_rename_top_level_private_as_submodule : Note<
"make '%0' a submodule of '%1' to ensure it can be found by name">;
def warn_auto_module_import : Warning<
"treating #%select{include|import|include_next|__include_macros}0 as an "
@ -659,10 +664,10 @@ def warn_use_of_private_header_outside_module : Warning<
def err_undeclared_use_of_module : Error<
"module %0 does not depend on a module exporting '%1'">;
def warn_non_modular_include_in_framework_module : Warning<
"include of non-modular header inside framework module '%0'">,
"include of non-modular header inside framework module '%0': '%1'">,
InGroup<NonModularIncludeInFrameworkModule>, DefaultIgnore;
def warn_non_modular_include_in_module : Warning<
"include of non-modular header inside module '%0'">,
"include of non-modular header inside module '%0': '%1'">,
InGroup<NonModularIncludeInModule>, DefaultIgnore;
def warn_module_conflict : Warning<
"module '%0' conflicts with already-imported module '%1': %2">,

View File

@ -50,6 +50,7 @@ DIAGOPT(Pedantic, 1, 0) /// -pedantic
DIAGOPT(PedanticErrors, 1, 0) /// -pedantic-errors
DIAGOPT(ShowColumn, 1, 1) /// Show column number on diagnostics.
DIAGOPT(ShowLocation, 1, 1) /// Show source location information.
DIAGOPT(AbsolutePath, 1, 0) /// Use absolute paths.
DIAGOPT(ShowCarets, 1, 1) /// Show carets in diagnostics.
DIAGOPT(ShowFixits, 1, 1) /// Show fixit information.
DIAGOPT(ShowSourceRanges, 1, 0) /// Show source ranges in numeric form.

View File

@ -13,10 +13,11 @@
let Component = "Parse" in {
def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">,
CatInlineAsm;
def warn_asm_qualifier_ignored : Warning<
"ignored %0 qualifier on asm">, CatInlineAsm, InGroup<ASMIgnoredQualifier>;
def warn_file_asm_volatile : Warning<
"meaningless 'volatile' on asm outside function">, CatInlineAsm;
"meaningless 'volatile' on asm outside function">, CatInlineAsm,
InGroup<ASMIgnoredQualifier>;
let CategoryName = "Inline Assembly Issue" in {
def err_asm_empty : Error<"__asm used with no assembly instructions">;
@ -63,7 +64,7 @@ def ext_nullability : Extension<
"type nullability specifier %0 is a Clang extension">,
InGroup<DiagGroup<"nullability-extension">>;
def error_empty_enum : Error<"use of empty enum">;
def err_empty_enum : Error<"use of empty enum">;
def ext_ident_list_in_param : Extension<
"type-less parameter names in function declaration">;
@ -346,8 +347,6 @@ def ext_c11_static_assert : Extension<
def warn_cxx98_compat_static_assert : Warning<
"static_assert declarations are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_paren_after_colon_colon : Error<
"unexpected parenthesis after '::'">;
def err_function_definition_not_allowed : Error<
"function definition is not allowed here">;
def err_expected_end_of_enumerator : Error<
@ -355,6 +354,10 @@ def err_expected_end_of_enumerator : Error<
def err_expected_coloncolon_after_super : Error<
"expected '::' after '__super'">;
def ext_decomp_decl_empty : ExtWarn<
"ISO C++1z does not allow a decomposition group to be empty">,
InGroup<DiagGroup<"empty-decomposition">>;
/// Objective-C parser diagnostics
def err_expected_minus_or_plus : Error<
"method type specifier must start with '-' or '+'">;
@ -395,7 +398,7 @@ def err_objc_expected_selector_for_getter_setter : Error<
"expected selector for Objective-C %select{setter|getter}0">;
def err_objc_property_requires_field_name : Error<
"property requires fields to be named">;
def err_objc_property_bitfield : Error<"property name cannot be a bitfield">;
def err_objc_property_bitfield : Error<"property name cannot be a bit-field">;
def err_objc_expected_property_attr : Error<"unknown property attribute %0">;
def err_objc_properties_require_objc2 : Error<
"properties are an Objective-C 2 feature">;
@ -417,13 +420,11 @@ def err_unexpected_protocol_qualifier : Error<
"@implementation declaration cannot be protocol qualified">;
def err_objc_unexpected_atend : Error<
"'@end' appears where closing brace '}' is expected">;
def error_property_ivar_decl : Error<
"property synthesize requires specification of an ivar">;
def err_synthesized_property_name : Error<
"expected a property name in @synthesize">;
def warn_semicolon_before_method_body : Warning<
"semicolon before method body is ignored">,
InGroup<DiagGroup<"semicolon-before-method-body">>, DefaultIgnore;
InGroup<SemiBeforeMethodBody>, DefaultIgnore;
def note_extra_comma_message_arg : Note<
"comma separating Objective-C messaging arguments">;
@ -517,6 +518,12 @@ def ext_constexpr_if : ExtWarn<
def warn_cxx14_compat_constexpr_if : Warning<
"constexpr if is incompatible with C++ standards before C++1z">,
DefaultIgnore, InGroup<CXXPre1zCompat>;
def ext_init_statement : ExtWarn<
"'%select{if|switch}0' initialization statements are a C++1z extension">,
InGroup<CXX1z>;
def warn_cxx14_compat_init_statement : Warning<
"%select{if|switch}0 initialization statements are incompatible with "
"C++ standards before C++1z">, DefaultIgnore, InGroup<CXXPre1zCompat>;
// C++ derived classes
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
@ -719,7 +726,7 @@ def warn_cxx98_compat_nonstatic_member_init : Warning<
"in-class initialization of non-static data members is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_bitfield_member_init: Error<
"bitfield member cannot have an in-class initializer">;
"bit-field member cannot have an in-class initializer">;
def err_incomplete_array_member_init: Error<
"array bound cannot be deduced from an in-class initializer">;
@ -733,6 +740,22 @@ def err_alias_declaration_not_identifier : Error<
"name defined in alias declaration must be an identifier">;
def err_alias_declaration_specialization : Error<
"%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted">;
def err_alias_declaration_pack_expansion : Error<
"alias declaration cannot be a pack expansion">;
// C++1z using-declaration pack expansions
def ext_multi_using_declaration : ExtWarn<
"use of multiple declarators in a single using declaration is "
"a C++1z extension">, InGroup<CXX1z>;
def warn_cxx1z_compat_multi_using_declaration : Warning<
"use of multiple declarators in a single using declaration is "
"incompatible with C++ standards before C++1z">,
InGroup<CXXPre1zCompat>, DefaultIgnore;
def ext_using_declaration_pack : ExtWarn<
"pack expansion of using declaration is a C++1z extension">, InGroup<CXX1z>;
def warn_cxx1z_compat_using_declaration_pack : Warning<
"pack expansion using declaration is incompatible with C++ standards "
"before C++1z">, InGroup<CXXPre1zCompat>, DefaultIgnore;
// C++11 override control
def ext_override_control_keyword : ExtWarn<
@ -780,11 +803,20 @@ def warn_cxx98_compat_lambda : Warning<
InGroup<CXX98Compat>, DefaultIgnore;
def err_lambda_missing_parens : Error<
"lambda requires '()' before %select{'mutable'|return type|"
"attribute specifier}0">;
// C++1z lambda expressions
"attribute specifier|'constexpr'}0">;
def err_lambda_decl_specifier_repeated : Error<
"%select{'mutable'|'constexpr'}0 cannot appear multiple times in a lambda declarator">;
// C++1z lambda expressions
def err_expected_star_this_capture : Error<
"expected 'this' following '*' in lambda capture list">;
// C++1z constexpr lambda expressions
def warn_cxx14_compat_constexpr_on_lambda : Warning<
"constexpr on lambda expressions is incompatible with C++ standards before C++1z">,
InGroup<CXXPre1zCompat>, DefaultIgnore;
def ext_constexpr_on_lambda_cxx1z : ExtWarn<
"'constexpr' on lambda expressions is a C++1z extension">, InGroup<CXX1z>;
// Availability attribute
def err_expected_version : Error<
"expected a version of the form 'major[.minor[.subminor]]'">;
@ -815,8 +847,6 @@ def warn_availability_and_unavailable : Warning<
InGroup<Availability>;
// @available(...)
def err_avail_query_expected_condition : Error<
"expected an availability condition here">;
def err_avail_query_expected_platform_name : Error<
"expected a platform name here">;
@ -900,6 +930,10 @@ def warn_pragma_invalid_action : Warning<
def warn_pragma_pack_malformed : Warning<
"expected integer or identifier in '#pragma pack' - ignored">,
InGroup<IgnoredPragmas>;
// - #pragma intrinsic
def warn_pragma_intrinsic_builtin : Warning<
"%0 is not a recognized builtin%select{|; consider including <intrin.h> to access non-builtin intrinsics}1">,
InGroup<IgnoredPragmaIntrinsic>;
// - #pragma unused
def warn_pragma_unused_expected_var : Warning<
"expected '#pragma unused' argument to be a variable name">,
@ -941,8 +975,10 @@ def err_opencl_unroll_hint_on_non_loop : Error<
// OpenCL EXTENSION pragma (OpenCL 1.1 [9.1])
def warn_pragma_expected_colon : Warning<
"missing ':' after %0 - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_expected_enable_disable : Warning<
"expected 'enable' or 'disable' - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_expected_predicate : Warning<
"expected %select{'enable', 'disable', 'begin' or 'end'|'disable'}0 - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_begin_end_mismatch : Warning<
"OpenCL extension end directive mismatches begin directive - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_unknown_extension : Warning<
"unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_unsupported_extension : Warning<
@ -1007,14 +1043,36 @@ def err_pragma_invalid_keyword : Error<
def warn_pragma_unroll_cuda_value_in_parens : Warning<
"argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
InGroup<CudaCompat>;
def warn_cuda_attr_lambda_position : Warning<
"nvcc does not allow '__%0__' to appear after '()' in lambdas">,
InGroup<CudaCompat>;
def warn_pragma_force_cuda_host_device_bad_arg : Warning<
"incorrect use of #pragma clang force_cuda_host_device begin|end">,
InGroup<IgnoredPragmas>;
def err_pragma_cannot_end_force_cuda_host_device : Error<
"force_cuda_host_device end pragma without matching "
"force_cuda_host_device begin">;
} // end of Parse Issue category.
let CategoryName = "Modules Issue" in {
def err_expected_module_interface_decl : Error<
"expected module declaration at start of module interface">;
def err_unexpected_module_decl : Error<
"module declaration must be the first declaration in the translation unit">;
def err_module_expected_ident : Error<
"expected a module name after module import">;
"expected a module name after module%select{| import}0">;
def err_unexpected_module_kind : Error<
"unexpected module kind %0; expected 'implementation' or 'partition'">;
def err_attribute_not_module_attr : Error<
"%0 attribute cannot be applied to a module">;
def err_attribute_not_import_attr : Error<
"%0 attribute cannot be applied to a module import">;
def err_module_expected_semi : Error<
"expected ';' after module name">;
def err_missing_before_module_end : Error<"expected %0 at end of module">;
def err_export_empty : Error<"export declaration cannot be empty">;
}
let CategoryName = "Generics Issue" in {

View File

@ -21,6 +21,12 @@ def err_fe_pch_malformed_block : Error<
def err_fe_pch_file_modified : Error<
"file '%0' has been modified since the precompiled header '%1' was built">,
DefaultFatal;
def err_fe_module_file_modified : Error<
"file '%0' has been modified since the module file '%1' was built">,
DefaultFatal;
def err_fe_ast_file_modified : Error<
"file '%0' has been modified since the AST file '%1' was built">,
DefaultFatal;
def err_fe_pch_file_overridden : Error<
"file '%0' from the precompiled header has been overridden">;
def note_pch_required_by : Note<"'%0' required by '%1'">;

View File

@ -16,7 +16,6 @@
#define LLVM_CLANG_BASIC_FILEMANAGER_H
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/VirtualFileSystem.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@ -24,25 +23,32 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include <ctime>
#include <memory>
#include <map>
#include <string>
namespace llvm {
class MemoryBuffer;
}
} // end namespace llvm
namespace clang {
class FileManager;
class FileSystemStatCache;
/// \brief Cached information about one directory (either on disk or in
/// the virtual file system).
class DirectoryEntry {
const char *Name; // Name of the directory.
friend class FileManager;
StringRef Name; // Name of the directory.
public:
DirectoryEntry() : Name(nullptr) {}
const char *getName() const { return Name; }
StringRef getName() const { return Name; }
};
/// \brief Cached information about one file (either on disk
@ -51,7 +57,9 @@ class DirectoryEntry {
/// If the 'File' member is valid, then this FileEntry has an open file
/// descriptor for the file.
class FileEntry {
const char *Name; // Name of the file.
friend class FileManager;
StringRef Name; // Name of the file.
std::string RealPathName; // Real path to the file; could be empty.
off_t Size; // File size in bytes.
time_t ModTime; // Modification time of file.
@ -64,25 +72,16 @@ class FileEntry {
/// \brief The open file, if it is owned by the \p FileEntry.
mutable std::unique_ptr<vfs::File> File;
friend class FileManager;
void operator=(const FileEntry &) = delete;
public:
FileEntry()
: UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false)
{}
// FIXME: this is here to allow putting FileEntry in std::map. Once we have
// emplace, we shouldn't need a copy constructor anymore.
/// Intentionally does not copy fields that are not set in an uninitialized
/// \c FileEntry.
FileEntry(const FileEntry &FE) : UniqueID(FE.UniqueID),
IsNamedPipe(FE.IsNamedPipe), InPCH(FE.InPCH), IsValid(FE.IsValid) {
assert(!isValid() && "Cannot copy an initialized FileEntry");
}
FileEntry(const FileEntry &) = delete;
FileEntry &operator=(const FileEntry &) = delete;
const char *getName() const { return Name; }
StringRef getName() const { return Name; }
StringRef tryGetRealPathName() const { return RealPathName; }
bool isValid() const { return IsValid; }
off_t getSize() const { return Size; }
@ -165,7 +164,7 @@ class FileManager : public RefCountedBase<FileManager> {
// Caching.
std::unique_ptr<FileSystemStatCache> StatCache;
bool getStatValue(const char *Path, FileData &Data, bool isFile,
bool getStatValue(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F);
/// Add all ancestors of the given path (pointing to either a file
@ -285,6 +284,6 @@ class FileManager : public RefCountedBase<FileManager> {
void PrintStats() const;
};
} // end namespace clang
} // end namespace clang
#endif
#endif // LLVM_CLANG_BASIC_FILEMANAGER_H

View File

@ -68,7 +68,7 @@ class FileSystemStatCache {
/// success for directories (not files). On a successful file lookup, the
/// implementation can optionally fill in \p F with a valid \p File object and
/// the client guarantees that it will close it.
static bool get(const char *Path, FileData &Data, bool isFile,
static bool get(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
vfs::FileSystem &FS);
@ -92,11 +92,11 @@ class FileSystemStatCache {
// FIXME: The pointer here is a non-owning/optional reference to the
// unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
// Optional needs some work to support references so this isn't possible yet.
virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
virtual LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F,
vfs::FileSystem &FS) = 0;
LookupResult statChained(const char *Path, FileData &Data, bool isFile,
LookupResult statChained(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
if (FileSystemStatCache *Next = getNextStatCache())
return Next->getStat(Path, Data, isFile, F, FS);
@ -121,7 +121,7 @@ class MemorizeStatCalls : public FileSystemStatCache {
iterator begin() const { return StatCalls.begin(); }
iterator end() const { return StatCalls.end(); }
LookupResult getStat(const char *Path, FileData &Data, bool isFile,
LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F,
vfs::FileSystem &FS) override;
};

View File

@ -18,16 +18,26 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/TokenKinds.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <new>
#include <string>
#include <utility>
namespace llvm {
template <typename T> struct DenseMapInfo;
}
} // end namespace llvm
namespace clang {
class LangOptions;
class IdentifierInfo;
class IdentifierTable;
@ -38,13 +48,14 @@ namespace clang {
/// \brief A simple pair of identifier info and location.
typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
/// One of these records is kept for each identifier that
/// is lexed. This contains information about whether the token was \#define'd,
/// is a language keyword, or if it is a front-end token of some sort (e.g. a
/// variable or function name). The preprocessor keeps this information in a
/// set, and all tok::identifier tokens have a pointer to one of these.
class IdentifierInfo {
friend class IdentifierTable;
unsigned TokenID : 9; // Front-end token ID or tok::identifier.
// Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
// First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values
@ -77,21 +88,18 @@ class IdentifierInfo {
void *FETokenInfo; // Managed by the language front-end.
llvm::StringMapEntry<IdentifierInfo*> *Entry;
IdentifierInfo(const IdentifierInfo&) = delete;
void operator=(const IdentifierInfo&) = delete;
friend class IdentifierTable;
public:
IdentifierInfo();
IdentifierInfo(const IdentifierInfo &) = delete;
IdentifierInfo &operator=(const IdentifierInfo &) = delete;
/// \brief Return true if this is the identifier for the specified string.
///
/// This is intended to be used for string literals only: II->isStr("foo").
template <std::size_t StrLen>
bool isStr(const char (&Str)[StrLen]) const {
return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1);
return getLength() == StrLen-1 &&
memcmp(getNameStart(), Str, StrLen-1) == 0;
}
/// \brief Return the beginning of the actual null-terminated string for this
@ -137,7 +145,7 @@ class IdentifierInfo {
HasMacro = Val;
if (Val) {
NeedsHandleIdentifier = 1;
NeedsHandleIdentifier = true;
HadMacro = true;
} else {
RecomputeNeedsHandleIdentifier();
@ -205,8 +213,7 @@ class IdentifierInfo {
/// \brief Return a value indicating whether this is a builtin function.
///
/// 0 is not-built-in. 1 is builtin-for-some-nonprimary-target.
/// 2+ are specific builtin functions.
/// 0 is not-built-in. 1+ are specific builtin functions.
unsigned getBuiltinID() const {
if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
@ -229,7 +236,7 @@ class IdentifierInfo {
void setIsExtensionToken(bool Val) {
IsExtension = Val;
if (Val)
NeedsHandleIdentifier = 1;
NeedsHandleIdentifier = true;
else
RecomputeNeedsHandleIdentifier();
}
@ -243,7 +250,7 @@ class IdentifierInfo {
void setIsFutureCompatKeyword(bool Val) {
IsFutureCompatKeyword = Val;
if (Val)
NeedsHandleIdentifier = 1;
NeedsHandleIdentifier = true;
else
RecomputeNeedsHandleIdentifier();
}
@ -253,7 +260,7 @@ class IdentifierInfo {
void setIsPoisoned(bool Value = true) {
IsPoisoned = Value;
if (Value)
NeedsHandleIdentifier = 1;
NeedsHandleIdentifier = true;
else
RecomputeNeedsHandleIdentifier();
}
@ -266,7 +273,7 @@ class IdentifierInfo {
void setIsCPlusPlusOperatorKeyword(bool Val = true) {
IsCPPOperatorKeyword = Val;
if (Val)
NeedsHandleIdentifier = 1;
NeedsHandleIdentifier = true;
else
RecomputeNeedsHandleIdentifier();
}
@ -371,6 +378,7 @@ class IdentifierInfo {
class PoisonIdentifierRAIIObject {
IdentifierInfo *const II;
const bool OldValue;
public:
PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue)
: II(II), OldValue(II ? II->isPoisoned() : false) {
@ -395,14 +403,13 @@ class PoisonIdentifierRAIIObject {
/// operation. Subclasses of this iterator type will provide the
/// actual functionality.
class IdentifierIterator {
private:
IdentifierIterator(const IdentifierIterator &) = delete;
void operator=(const IdentifierIterator &) = delete;
protected:
IdentifierIterator() { }
IdentifierIterator() = default;
public:
IdentifierIterator(const IdentifierIterator &) = delete;
IdentifierIterator &operator=(const IdentifierIterator &) = delete;
virtual ~IdentifierIterator();
/// \brief Retrieve the next string in the identifier table and
@ -537,7 +544,7 @@ class IdentifierTable {
iterator begin() const { return HashTable.begin(); }
iterator end() const { return HashTable.end(); }
unsigned size() const { return HashTable.size(); }
unsigned size() const { return HashTable.size(); }
/// \brief Print some statistics to stderr that indicate how well the
/// hashing is doing.
@ -654,6 +661,7 @@ class Selector {
return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
return nullptr;
}
MultiKeywordSelector *getMultiKeywordSelector() const {
return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
}
@ -682,6 +690,7 @@ class Selector {
bool operator!=(Selector RHS) const {
return InfoPtr != RHS.InfoPtr;
}
void *getAsOpaquePtr() const {
return reinterpret_cast<void*>(InfoPtr);
}
@ -693,12 +702,13 @@ class Selector {
bool isKeywordSelector() const {
return getIdentifierInfoFlag() != ZeroArg;
}
bool isUnarySelector() const {
return getIdentifierInfoFlag() == ZeroArg;
}
unsigned getNumArgs() const;
/// \brief Retrieve the identifier at a given position in the selector.
///
/// Note that the identifier pointer returned may be NULL. Clients that only
@ -743,6 +753,7 @@ class Selector {
static Selector getEmptyMarker() {
return Selector(uintptr_t(-1));
}
static Selector getTombstoneMarker() {
return Selector(uintptr_t(-2));
}
@ -754,10 +765,11 @@ class Selector {
/// multi-keyword caching.
class SelectorTable {
void *Impl; // Actually a SelectorTableImpl
SelectorTable(const SelectorTable &) = delete;
void operator=(const SelectorTable &) = delete;
public:
SelectorTable();
SelectorTable(const SelectorTable &) = delete;
SelectorTable &operator=(const SelectorTable &) = delete;
~SelectorTable();
/// \brief Can create any sort of selector.
@ -826,6 +838,7 @@ class DeclarationNameExtra {
} // end namespace clang
namespace llvm {
/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
/// DenseSets.
template <>
@ -833,6 +846,7 @@ struct DenseMapInfo<clang::Selector> {
static inline clang::Selector getEmptyKey() {
return clang::Selector::getEmptyMarker();
}
static inline clang::Selector getTombstoneKey() {
return clang::Selector::getTombstoneMarker();
}
@ -855,9 +869,11 @@ class PointerLikeTypeTraits<clang::Selector> {
static inline const void *getAsVoidPointer(clang::Selector P) {
return P.getAsOpaquePtr();
}
static inline clang::Selector getFromVoidPointer(const void *P) {
return clang::Selector(reinterpret_cast<uintptr_t>(P));
}
enum { NumLowBitsAvailable = 0 };
};
@ -869,9 +885,11 @@ class PointerLikeTypeTraits<clang::IdentifierInfo*> {
static inline void *getAsVoidPointer(clang::IdentifierInfo* P) {
return P;
}
static inline clang::IdentifierInfo *getFromVoidPointer(void *P) {
return static_cast<clang::IdentifierInfo*>(P);
}
enum { NumLowBitsAvailable = 1 };
};
@ -881,11 +899,14 @@ class PointerLikeTypeTraits<const clang::IdentifierInfo*> {
static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
return P;
}
static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
return static_cast<const clang::IdentifierInfo*>(P);
}
enum { NumLowBitsAvailable = 1 };
};
} // end namespace llvm
#endif
} // end namespace llvm
#endif // LLVM_CLANG_BASIC_IDENTIFIERTABLE_H

View File

@ -30,6 +30,7 @@ namespace llvm {
class Twine;
template<typename T> class ArrayRef;
template<typename T> class MutableArrayRef;
template<typename T> class OwningArrayRef;
template<unsigned InternalLen> class SmallString;
template<typename T, unsigned N> class SmallVector;
template<typename T> class SmallVectorImpl;
@ -42,7 +43,6 @@ namespace llvm {
template <typename T> class IntrusiveRefCntPtr;
template <typename T> struct IntrusiveRefCntPtrInfo;
template <class Derived> class RefCountedBase;
class RefCountedBaseVPTR;
class raw_ostream;
class raw_pwrite_stream;
@ -65,6 +65,7 @@ namespace clang {
using llvm::Twine;
using llvm::ArrayRef;
using llvm::MutableArrayRef;
using llvm::OwningArrayRef;
using llvm::SmallString;
using llvm::SmallVector;
using llvm::SmallVectorImpl;
@ -74,7 +75,6 @@ namespace clang {
using llvm::IntrusiveRefCntPtr;
using llvm::IntrusiveRefCntPtrInfo;
using llvm::RefCountedBase;
using llvm::RefCountedBaseVPTR;
using llvm::raw_ostream;
using llvm::raw_pwrite_stream;

View File

@ -133,7 +133,8 @@ LANGOPT(Freestanding, 1, 0, "freestanding implementation")
LANGOPT(NoBuiltin , 1, 0, "disable builtin functions")
LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions")
LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly")
LANGOPT(Coroutines , 1, 0, "C++ coroutines")
LANGOPT(CoroutinesTS , 1, 0, "C++ coroutines TS")
LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments")
BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers")
LANGOPT(POSIXThreads , 1, 0, "POSIX thread support")
@ -142,7 +143,9 @@ BENIGN_LANGOPT(EmitAllDecls , 1, 0, "emitting all declarations")
LANGOPT(MathErrno , 1, 1, "errno in math functions")
BENIGN_LANGOPT(HeinousExtensions , 1, 0, "extensions that we really don't like and may be ripped out at any time")
LANGOPT(Modules , 1, 0, "modules extension to C")
BENIGN_LANGOPT(CompilingModule, 1, 0, "compiling a module interface")
COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS")
BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 2, CMK_None,
"compiling a module interface")
COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses")
BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references")
COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules")
@ -193,7 +196,9 @@ LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr function
LANGOPT(CUDADeviceFlushDenormalsToZero, 1, 0, "flushing denormals to zero")
LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions")
LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions")
LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
LANGOPT(NewAlignOverride , 32, 0, "maximum alignment guaranteed by '::operator new(size_t)'")
LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts")
BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records")
@ -234,7 +239,7 @@ ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
BENIGN_LANGOPT(ArrowDepth, 32, 256,
"maximum number of operator->s to follow")
BENIGN_LANGOPT(InstantiationDepth, 32, 256,
BENIGN_LANGOPT(InstantiationDepth, 32, 1024,
"maximum template instantiation depth")
BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
"maximum constexpr call depth")

View File

@ -58,6 +58,12 @@ class LangOptions : public LangOptionsBase {
SOB_Trapping // -ftrapv
};
enum CompilingModuleKind {
CMK_None, ///< Not compiling a module interface at all.
CMK_ModuleMap, ///< Compiling a module from a module map.
CMK_ModuleInterface ///< Compiling a C++ modules TS module interface unit.
};
enum PragmaMSPointersToMembersKind {
PPTMK_BestCase,
PPTMK_FullGeneralitySingleInheritance,
@ -126,6 +132,10 @@ class LangOptions : public LangOptionsBase {
/// host code generation.
std::string OMPHostIRFile;
/// \brief Indicates whether the front-end is explicitly told that the
/// input is a header file (i.e. -x c-header).
bool IsHeaderFile;
LangOptions();
// Define accessors/mutators for language options of enumeration type.
@ -134,7 +144,12 @@ class LangOptions : public LangOptionsBase {
Type get##Name() const { return static_cast<Type>(Name); } \
void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
#include "clang/Basic/LangOptions.def"
/// Are we compiling a module interface (.cppm or module map)?
bool isCompilingModule() const {
return getCompilingModule() != CMK_None;
}
bool isSignedOverflowDefined() const {
return getSignedOverflowBehavior() == SOB_Defined;
}
@ -154,7 +169,7 @@ class LangOptions : public LangOptionsBase {
/// \brief Is this a libc/libm function that is no longer recognized as a
/// builtin because a -fno-builtin-* option has been specified?
bool isNoBuiltinFunc(const char *Name) const;
bool isNoBuiltinFunc(StringRef Name) const;
};
/// \brief Floating point control options

View File

@ -69,6 +69,10 @@ enum GVALinkage {
GVA_StrongODR
};
inline bool isDiscardableGVALinkage(GVALinkage L) {
return L <= GVA_DiscardableODR;
}
inline bool isExternallyVisible(Linkage L) {
return L == ExternalLinkage || L == VisibleNoLinkage;
}

View File

@ -201,6 +201,10 @@ class Module {
/// built.
unsigned ConfigMacrosExhaustive : 1;
/// \brief Whether files in this module can only include non-modular headers
/// and headers from used modules.
unsigned NoUndeclaredIncludes : 1;
/// \brief Describes the visibility of the various names within a
/// particular module.
enum NameVisibilityKind {

View File

@ -312,6 +312,7 @@ class ObjCRuntime {
bool hasARCUnsafeClaimAutoreleasedReturnValue() const {
switch (getKind()) {
case MacOSX:
case FragileMacOSX:
return getVersion() >= VersionTuple(10, 11);
case iOS:
return getVersion() >= VersionTuple(9);

View File

@ -67,6 +67,7 @@ OPENCLEXT_INTERNAL(cl_khr_spir, 120, ~0U)
// OpenCL 2.0.
OPENCLEXT_INTERNAL(cl_khr_egl_event, 200, ~0U)
OPENCLEXT_INTERNAL(cl_khr_egl_image, 200, ~0U)
OPENCLEXT_INTERNAL(cl_khr_mipmap_image, 200, ~0U)
OPENCLEXT_INTERNAL(cl_khr_srgb_image_writes, 200, ~0U)
OPENCLEXT_INTERNAL(cl_khr_subgroups, 200, ~0U)
OPENCLEXT_INTERNAL(cl_khr_terminate_context, 200, ~0U)
@ -74,6 +75,10 @@ OPENCLEXT_INTERNAL(cl_khr_terminate_context, 200, ~0U)
// Clang Extensions.
OPENCLEXT_INTERNAL(cl_clang_storage_class_specifiers, 100, ~0U)
// AMD OpenCL extensions
OPENCLEXT_INTERNAL(cl_amd_media_ops, 100, ~0U)
OPENCLEXT_INTERNAL(cl_amd_media_ops2, 100, ~0U)
#undef OPENCLEXT_INTERNAL
#ifdef OPENCLEXT

View File

@ -7,76 +7,82 @@
//
//===----------------------------------------------------------------------===//
// This file extends builtin types database with OpenCL image singleton types.
// Custom code should define one of those two macros:
// GENERIC_IMAGE_TYPE(Type, Id) - a generic image with its Id without an
// Custom code should define one of those three macros:
// GENERIC_IMAGE_TYPE(Type, Id) - a generic image with its Id without an
// access type
// IMAGE_TYPE(Type, Id, SingletonId, AccessType, CGSuffix) - an image type
// with given ID, singleton ID access type and a codegen suffix
// with given ID, singleton ID access type and a codegen suffix
// GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) - a generic image with its Id and
// required extension without an access type
#ifdef GENERIC_IMAGE_TYPE
#define IMAGE_READ_TYPE(Type, Id) GENERIC_IMAGE_TYPE(Type, Id)
#define IMAGE_WRITE_TYPE(Type, Id)
#define IMAGE_READ_WRITE_TYPE(Type, Id)
#define IMAGE_READ_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE(Type, Id)
#define IMAGE_WRITE_TYPE(Type, Id, Ext)
#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
#elif defined(GENERIC_IMAGE_TYPE_EXT)
#define IMAGE_READ_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE_EXT(Type, Id##ROTy, Ext)
#define IMAGE_WRITE_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE_EXT(Type, Id##WOTy, Ext)
#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext) GENERIC_IMAGE_TYPE_EXT(Type, Id##RWTy, Ext)
#else
#ifndef IMAGE_READ_TYPE
#define IMAGE_READ_TYPE(Type, Id) \
#define IMAGE_READ_TYPE(Type, Id, Ext) \
IMAGE_TYPE(Type, Id##RO, Id##ROTy, read_only, ro)
#endif
#ifndef IMAGE_WRITE_TYPE
#define IMAGE_WRITE_TYPE(Type, Id) \
#define IMAGE_WRITE_TYPE(Type, Id, Ext) \
IMAGE_TYPE(Type, Id##WO, Id##WOTy, write_only, wo)
#endif
#ifndef IMAGE_READ_WRITE_TYPE
#define IMAGE_READ_WRITE_TYPE(Type, Id) \
#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext) \
IMAGE_TYPE(Type, Id##RW, Id##RWTy, read_write, rw)
#endif
#endif
IMAGE_READ_TYPE(image1d, OCLImage1d)
IMAGE_READ_TYPE(image1d_array, OCLImage1dArray)
IMAGE_READ_TYPE(image1d_buffer, OCLImage1dBuffer)
IMAGE_READ_TYPE(image2d, OCLImage2d)
IMAGE_READ_TYPE(image2d_array, OCLImage2dArray)
IMAGE_READ_TYPE(image2d_depth, OCLImage2dDepth)
IMAGE_READ_TYPE(image2d_array_depth, OCLImage2dArrayDepth)
IMAGE_READ_TYPE(image2d_msaa, OCLImage2dMSAA)
IMAGE_READ_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA)
IMAGE_READ_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth)
IMAGE_READ_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth)
IMAGE_READ_TYPE(image3d, OCLImage3d)
IMAGE_READ_TYPE(image1d, OCLImage1d, "")
IMAGE_READ_TYPE(image1d_array, OCLImage1dArray, "")
IMAGE_READ_TYPE(image1d_buffer, OCLImage1dBuffer, "")
IMAGE_READ_TYPE(image2d, OCLImage2d, "")
IMAGE_READ_TYPE(image2d_array, OCLImage2dArray, "")
IMAGE_READ_TYPE(image2d_depth, OCLImage2dDepth, "")
IMAGE_READ_TYPE(image2d_array_depth, OCLImage2dArrayDepth, "")
IMAGE_READ_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
IMAGE_READ_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
IMAGE_READ_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
IMAGE_READ_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
IMAGE_READ_TYPE(image3d, OCLImage3d, "")
IMAGE_WRITE_TYPE(image1d, OCLImage1d)
IMAGE_WRITE_TYPE(image1d_array, OCLImage1dArray)
IMAGE_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer)
IMAGE_WRITE_TYPE(image2d, OCLImage2d)
IMAGE_WRITE_TYPE(image2d_array, OCLImage2dArray)
IMAGE_WRITE_TYPE(image2d_depth, OCLImage2dDepth)
IMAGE_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth)
IMAGE_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA)
IMAGE_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA)
IMAGE_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth)
IMAGE_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth)
IMAGE_WRITE_TYPE(image3d, OCLImage3d)
IMAGE_WRITE_TYPE(image1d, OCLImage1d, "")
IMAGE_WRITE_TYPE(image1d_array, OCLImage1dArray, "")
IMAGE_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer, "")
IMAGE_WRITE_TYPE(image2d, OCLImage2d, "")
IMAGE_WRITE_TYPE(image2d_array, OCLImage2dArray, "")
IMAGE_WRITE_TYPE(image2d_depth, OCLImage2dDepth, "")
IMAGE_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth, "")
IMAGE_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
IMAGE_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
IMAGE_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
IMAGE_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
IMAGE_WRITE_TYPE(image3d, OCLImage3d, "")
IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d)
IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray)
IMAGE_READ_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer)
IMAGE_READ_WRITE_TYPE(image2d, OCLImage2d)
IMAGE_READ_WRITE_TYPE(image2d_array, OCLImage2dArray)
IMAGE_READ_WRITE_TYPE(image2d_depth, OCLImage2dDepth)
IMAGE_READ_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth)
IMAGE_READ_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA)
IMAGE_READ_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA)
IMAGE_READ_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth)
IMAGE_READ_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth)
IMAGE_READ_WRITE_TYPE(image3d, OCLImage3d)
IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d, "")
IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray, "")
IMAGE_READ_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer, "")
IMAGE_READ_WRITE_TYPE(image2d, OCLImage2d, "")
IMAGE_READ_WRITE_TYPE(image2d_array, OCLImage2dArray, "")
IMAGE_READ_WRITE_TYPE(image2d_depth, OCLImage2dDepth, "")
IMAGE_READ_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth, "")
IMAGE_READ_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
IMAGE_READ_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
IMAGE_READ_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
IMAGE_READ_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
IMAGE_READ_WRITE_TYPE(image3d, OCLImage3d, "")
#undef IMAGE_TYPE
#undef GENERIC_IMAGE_TYPE
#undef IMAGE_READ_TYPE
#undef IMAGE_WRITE_TYPE
#undef IMAGE_READ_WRITE_TYPE
#undef IMAGE_READ_WRITE_TYPE

View File

@ -15,52 +15,122 @@
#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H
#define LLVM_CLANG_BASIC_OPENCLOPTIONS_H
#include <string>
#include <vector>
#include "llvm/ADT/StringMap.h"
namespace clang {
/// \brief OpenCL supported extensions and optional core features
class OpenCLOptions {
struct Info {
bool Supported; // Is this option supported
bool Enabled; // Is this option enabled
unsigned Avail; // Option starts to be available in this OpenCL version
unsigned Core; // Option becomes (optional) core feature in this OpenCL
// version
Info(bool S = false, bool E = false, unsigned A = 100, unsigned C = ~0U)
:Supported(S), Enabled(E), Avail(A), Core(C){}
};
llvm::StringMap<Info> OptMap;
public:
#define OPENCLEXT(nm) unsigned nm : 1;
#include "clang/Basic/OpenCLExtensions.def"
OpenCLOptions() {
#define OPENCLEXT(nm) nm = 0;
#include "clang/Basic/OpenCLExtensions.def"
bool isKnown(llvm::StringRef Ext) const {
return OptMap.find(Ext) != OptMap.end();
}
// Enable all options.
void setAll() {
#define OPENCLEXT(nm) nm = 1;
#include "clang/Basic/OpenCLExtensions.def"
bool isEnabled(llvm::StringRef Ext) const {
return OptMap.find(Ext)->second.Enabled;
}
// Is supported with OpenCL version \p OCLVer.
#define OPENCLEXT_INTERNAL(Ext, Avail, ...) \
bool is_##Ext##_supported(unsigned OCLVer) const { \
return Ext && OCLVer >= Avail; \
// Is supported as either an extension or an (optional) core feature for
// OpenCL version \p CLVer.
bool isSupported(llvm::StringRef Ext, unsigned CLVer) const {
auto I = OptMap.find(Ext)->getValue();
return I.Supported && I.Avail <= CLVer;
}
#include "clang/Basic/OpenCLExtensions.def"
// Is supported OpenCL extension with OpenCL version \p OCLVer.
// For supported optional core feature, return false.
#define OPENCLEXT_INTERNAL(Ext, Avail, Core) \
bool is_##Ext##_supported_extension(unsigned CLVer) const { \
return is_##Ext##_supported(CLVer) && (Core == ~0U || CLVer < Core); \
}
#include "clang/Basic/OpenCLExtensions.def"
// Is supported OpenCL core features with OpenCL version \p OCLVer.
// Is supported (optional) OpenCL core features for OpenCL version \p CLVer.
// For supported extension, return false.
#define OPENCLEXT_INTERNAL(Ext, Avail, Core) \
bool is_##Ext##_supported_core(unsigned CLVer) const { \
return is_##Ext##_supported(CLVer) && Core != ~0U && CLVer >= Core; \
bool isSupportedCore(llvm::StringRef Ext, unsigned CLVer) const {
auto I = OptMap.find(Ext)->getValue();
return I.Supported && I.Avail <= CLVer &&
I.Core != ~0U && CLVer >= I.Core;
}
#include "clang/Basic/OpenCLExtensions.def"
// Is supported OpenCL extension for OpenCL version \p CLVer.
// For supported (optional) core feature, return false.
bool isSupportedExtension(llvm::StringRef Ext, unsigned CLVer) const {
auto I = OptMap.find(Ext)->getValue();
return I.Supported && I.Avail <= CLVer &&
(I.Core == ~0U || CLVer < I.Core);
}
void enable(llvm::StringRef Ext, bool V = true) {
OptMap[Ext].Enabled = V;
}
/// \brief Enable or disable support for OpenCL extensions
/// \param Ext name of the extension optionally prefixed with
/// '+' or '-'
/// \param V used when \p Ext is not prefixed by '+' or '-'
void support(llvm::StringRef Ext, bool V = true) {
assert(!Ext.empty() && "Extension is empty.");
switch (Ext[0]) {
case '+':
V = true;
Ext = Ext.drop_front();
break;
case '-':
V = false;
Ext = Ext.drop_front();
break;
}
if (Ext.equals("all")) {
supportAll(V);
return;
}
OptMap[Ext].Supported = V;
}
OpenCLOptions(){
#define OPENCLEXT_INTERNAL(Ext, AvailVer, CoreVer) \
OptMap[#Ext].Avail = AvailVer; \
OptMap[#Ext].Core = CoreVer;
#include "clang/Basic/OpenCLExtensions.def"
}
void addSupport(const OpenCLOptions &Opts) {
for (auto &I:Opts.OptMap)
if (I.second.Supported)
OptMap[I.getKey()].Supported = true;
}
void copy(const OpenCLOptions &Opts) {
OptMap = Opts.OptMap;
}
// Turn on or off support of all options.
void supportAll(bool On = true) {
for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
E = OptMap.end(); I != E; ++I)
I->second.Supported = On;
}
void disableAll() {
for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
E = OptMap.end(); I != E; ++I)
I->second.Enabled = false;
}
void enableSupportedCore(unsigned CLVer) {
for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
E = OptMap.end(); I != E; ++I)
if (isSupportedCore(I->getKey(), CLVer))
I->second.Enabled = true;
}
friend class ASTWriter;
friend class ASTReader;
};
} // end namespace clang

View File

@ -138,6 +138,30 @@
#ifndef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE
#define OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(Name)
#endif
#ifndef OPENMP_TARGET_SIMD_CLAUSE
#define OPENMP_TARGET_SIMD_CLAUSE(Name)
#endif
#ifndef OPENMP_TEAMS_DISTRIBUTE_CLAUSE
#define OPENMP_TEAMS_DISTRIBUTE_CLAUSE(Name)
#endif
#ifndef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE
#define OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name)
#endif
#ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name)
#endif
#ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name)
#endif
#ifndef OPENMP_TARGET_TEAMS_CLAUSE
#define OPENMP_TARGET_TEAMS_CLAUSE(Name)
#endif
#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE
#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name)
#endif
#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name)
#endif
// OpenMP directives.
OPENMP_DIRECTIVE(threadprivate)
@ -182,6 +206,14 @@ OPENMP_DIRECTIVE_EXT(distribute_parallel_for, "distribute parallel for")
OPENMP_DIRECTIVE_EXT(distribute_parallel_for_simd, "distribute parallel for simd")
OPENMP_DIRECTIVE_EXT(distribute_simd, "distribute simd")
OPENMP_DIRECTIVE_EXT(target_parallel_for_simd, "target parallel for simd")
OPENMP_DIRECTIVE_EXT(target_simd, "target simd")
OPENMP_DIRECTIVE_EXT(teams_distribute, "teams distribute")
OPENMP_DIRECTIVE_EXT(teams_distribute_simd, "teams distribute simd")
OPENMP_DIRECTIVE_EXT(teams_distribute_parallel_for_simd, "teams distribute parallel for simd")
OPENMP_DIRECTIVE_EXT(teams_distribute_parallel_for, "teams distribute parallel for")
OPENMP_DIRECTIVE_EXT(target_teams, "target teams")
OPENMP_DIRECTIVE_EXT(target_teams_distribute, "target teams distribute")
OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for, "target teams distribute parallel for")
// OpenMP clauses.
OPENMP_CLAUSE(if, OMPIfClause)
@ -431,7 +463,6 @@ OPENMP_TARGET_EXIT_DATA_CLAUSE(nowait)
OPENMP_TARGET_EXIT_DATA_CLAUSE(depend)
// Clauses allowed for OpenMP directive 'target parallel'.
// TODO: add target clauses 'is_device_ptr'
OPENMP_TARGET_PARALLEL_CLAUSE(if)
OPENMP_TARGET_PARALLEL_CLAUSE(device)
OPENMP_TARGET_PARALLEL_CLAUSE(map)
@ -445,6 +476,7 @@ OPENMP_TARGET_PARALLEL_CLAUSE(default)
OPENMP_TARGET_PARALLEL_CLAUSE(proc_bind)
OPENMP_TARGET_PARALLEL_CLAUSE(shared)
OPENMP_TARGET_PARALLEL_CLAUSE(reduction)
OPENMP_TARGET_PARALLEL_CLAUSE(is_device_ptr)
// Clauses allowed for OpenMP directive 'target parallel for'.
// TODO: add target clauses 'is_device_ptr'
@ -620,6 +652,147 @@ OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned)
// Clauses allowed for OpenMP directive 'target simd'.
OPENMP_TARGET_SIMD_CLAUSE(if)
OPENMP_TARGET_SIMD_CLAUSE(device)
OPENMP_TARGET_SIMD_CLAUSE(map)
OPENMP_TARGET_SIMD_CLAUSE(private)
OPENMP_TARGET_SIMD_CLAUSE(nowait)
OPENMP_TARGET_SIMD_CLAUSE(depend)
OPENMP_TARGET_SIMD_CLAUSE(defaultmap)
OPENMP_TARGET_SIMD_CLAUSE(firstprivate)
OPENMP_TARGET_SIMD_CLAUSE(is_device_ptr)
OPENMP_TARGET_SIMD_CLAUSE(lastprivate)
OPENMP_TARGET_SIMD_CLAUSE(linear)
OPENMP_TARGET_SIMD_CLAUSE(aligned)
OPENMP_TARGET_SIMD_CLAUSE(safelen)
OPENMP_TARGET_SIMD_CLAUSE(simdlen)
OPENMP_TARGET_SIMD_CLAUSE(collapse)
OPENMP_TARGET_SIMD_CLAUSE(reduction)
// Clauses allowed for OpenMP directive 'teams distribute'.
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(default)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(private)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(firstprivate)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(shared)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(reduction)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(num_teams)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(thread_limit)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(lastprivate)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(collapse)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule)
// Clauses allowed for OpenMP directive 'teams distribute simd'
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(default)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(private)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(firstprivate)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(shared)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(reduction)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(num_teams)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(thread_limit)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(lastprivate)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(collapse)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(dist_schedule)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen)
// Clauses allowed for OpenMP directive 'teams distribute parallel for simd'
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit)
// Clauses allowed for OpenMP directive 'teams distribute parallel for'
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(linear)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit)
// Clauses allowed for OpenMP directive 'target teams'.
OPENMP_TARGET_TEAMS_CLAUSE(if)
OPENMP_TARGET_TEAMS_CLAUSE(device)
OPENMP_TARGET_TEAMS_CLAUSE(map)
OPENMP_TARGET_TEAMS_CLAUSE(private)
OPENMP_TARGET_TEAMS_CLAUSE(nowait)
OPENMP_TARGET_TEAMS_CLAUSE(depend)
OPENMP_TARGET_TEAMS_CLAUSE(defaultmap)
OPENMP_TARGET_TEAMS_CLAUSE(firstprivate)
OPENMP_TARGET_TEAMS_CLAUSE(is_device_ptr)
OPENMP_TARGET_TEAMS_CLAUSE(default)
OPENMP_TARGET_TEAMS_CLAUSE(shared)
OPENMP_TARGET_TEAMS_CLAUSE(reduction)
OPENMP_TARGET_TEAMS_CLAUSE(num_teams)
OPENMP_TARGET_TEAMS_CLAUSE(thread_limit)
// Clauses allowed for OpenMP directive 'target teams distribute'.
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(if)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(device)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(map)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(private)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(nowait)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(depend)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(defaultmap)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(firstprivate)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(is_device_ptr)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(default)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(shared)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(reduction)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(num_teams)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(thread_limit)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(lastprivate)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(collapse)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule)
// Clauses allowed for OpenMP directive 'target teams distribute parallel for'.
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(device)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(map)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(nowait)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(depend)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(defaultmap)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(is_device_ptr)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(linear)
#undef OPENMP_TASKLOOP_SIMD_CLAUSE
#undef OPENMP_TASKLOOP_CLAUSE
#undef OPENMP_LINEAR_KIND
@ -662,3 +835,11 @@ OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned)
#undef OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
#undef OPENMP_DISTRIBUTE_SIMD_CLAUSE
#undef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE
#undef OPENMP_TARGET_SIMD_CLAUSE
#undef OPENMP_TEAMS_DISTRIBUTE_CLAUSE
#undef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE
#undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE
#undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE
#undef OPENMP_TARGET_TEAMS_CLAUSE
#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE
#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE

View File

@ -179,10 +179,18 @@ bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind);
/// otherwise - false.
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind);
/// \brief Checks if the specified directive is a teams-kind directive.
/// Checks if the specified composite/combined directive constitutes a teams
/// directive in the outermost nest. For example
/// 'omp teams distribute' or 'omp teams distribute parallel for'.
/// \param DKind Specified directive.
/// \return true - the directive is a teams-like directive like 'omp teams',
/// otherwise - false.
/// \return true - the directive has teams on the outermost nest, otherwise -
/// false.
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind);
/// Checks if the specified directive is a teams-kind directive. For example,
/// 'omp teams distribute' or 'omp target teams'.
/// \param DKind Specified directive.
/// \return true - the directive is a teams-like directive, otherwise - false.
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind);
/// \brief Checks if the specified directive is a simd directive.
@ -198,6 +206,14 @@ bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind);
/// otherwise - false.
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind);
/// Checks if the specified composite/combined directive constitutes a
/// distribute directive in the outermost nest. For example,
/// 'omp distribute parallel for' or 'omp distribute'.
/// \param DKind Specified directive.
/// \return true - the directive has distribute on the outermost nest.
/// otherwise - false.
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind);
/// \brief Checks if the specified clause is one of private clauses like
/// 'private', 'firstprivate', 'reduction' etc..
/// \param Kind Clause kind.

View File

@ -10,7 +10,6 @@
#ifndef LLVM_CLANG_BASIC_PLISTSUPPORT_H
#define LLVM_CLANG_BASIC_PLISTSUPPORT_H
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/raw_ostream.h"

View File

@ -44,30 +44,34 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
namespace clang {
class DiagnosticsEngine;
class SourceManager;
class FileManager;
class FileEntry;
class LineTableInfo;
class ASTWriter;
class ASTReader;
class ASTWriter;
class DiagnosticsEngine;
class LineTableInfo;
class SourceManager;
/// \brief Public enums and private classes that are part of the
/// SourceManager implementation.
///
namespace SrcMgr {
/// \brief Indicates whether a file or directory holds normal user code,
/// system code, or system code which is implicitly 'extern "C"' in C++ mode.
///
@ -146,8 +150,6 @@ namespace SrcMgr {
SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
IsSystemFile(false), IsTransient(false) {}
~ContentCache();
/// The copy ctor does not allow copies where source object has either
/// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
/// is not transferred, so this is a logical error.
@ -164,6 +166,10 @@ namespace SrcMgr {
NumLines = RHS.NumLines;
}
ContentCache &operator=(const ContentCache& RHS) = delete;
~ContentCache();
/// \brief Returns the memory buffer for the associated content.
///
/// \param Diag Object through which diagnostics will be emitted if the
@ -219,15 +225,11 @@ namespace SrcMgr {
bool shouldFreeBuffer() const {
return (Buffer.getInt() & DoNotFreeFlag) == 0;
}
private:
// Disable assignments.
ContentCache &operator=(const ContentCache& RHS) = delete;
};
// Assert that the \c ContentCache objects will always be 8-byte aligned so
// that we can pack 3 bits of integer into pointers to such objects.
static_assert(llvm::AlignOf<ContentCache>::Alignment >= 8,
static_assert(alignof(ContentCache) >= 8,
"ContentCache must be 8-byte aligned.");
/// \brief Information about a FileID, basically just the logical file
@ -259,6 +261,7 @@ namespace SrcMgr {
friend class clang::SourceManager;
friend class clang::ASTWriter;
friend class clang::ASTReader;
public:
/// \brief Return a FileInfo object.
static FileInfo get(SourceLocation IL, const ContentCache *Con,
@ -276,6 +279,7 @@ namespace SrcMgr {
SourceLocation getIncludeLoc() const {
return SourceLocation::getFromRawEncoding(IncludeLoc);
}
const ContentCache* getContentCache() const {
return reinterpret_cast<const ContentCache*>(Data & ~uintptr_t(7));
}
@ -316,9 +320,11 @@ namespace SrcMgr {
SourceLocation getSpellingLoc() const {
return SourceLocation::getFromRawEncoding(SpellingLoc);
}
SourceLocation getExpansionLocStart() const {
return SourceLocation::getFromRawEncoding(ExpansionLocStart);
}
SourceLocation getExpansionLocEnd() const {
SourceLocation EndLoc =
SourceLocation::getFromRawEncoding(ExpansionLocEnd);
@ -399,6 +405,7 @@ namespace SrcMgr {
FileInfo File;
ExpansionInfo Expansion;
};
public:
unsigned getOffset() const { return Offset; }
@ -433,6 +440,7 @@ namespace SrcMgr {
return E;
}
};
} // end SrcMgr namespace.
/// \brief External source of source location entries.
@ -453,7 +461,6 @@ class ExternalSLocEntrySource {
virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) = 0;
};
/// \brief Holds the cache used by isBeforeInTranslationUnit.
///
/// The cache structure is complex enough to be worth breaking out of
@ -479,6 +486,7 @@ class InBeforeInTUCacheEntry {
/// if LQueryFID is a parent of RQueryFID (or vice versa) then these can be a
/// random token in the parent.
unsigned LCommonOffset, RCommonOffset;
public:
/// \brief Return true if the currently cached values match up with
/// the specified LHS/RHS query.
@ -526,13 +534,12 @@ class InBeforeInTUCacheEntry {
LCommonOffset = lCommonOffset;
RCommonOffset = rCommonOffset;
}
};
/// \brief The stack used when building modules on demand, which is used
/// to provide a link between the source managers of the different compiler
/// instances.
typedef ArrayRef<std::pair<std::string, FullSourceLoc> > ModuleBuildStack;
typedef ArrayRef<std::pair<std::string, FullSourceLoc>> ModuleBuildStack;
/// \brief This class handles loading and caching of source files into memory.
///
@ -667,7 +674,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
///
/// Used to cache results from and speed-up \c getDecomposedIncludedLoc
/// function.
mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned> > IncludedLocMap;
mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned>> IncludedLocMap;
/// The key value into the IsBeforeInTUCache table.
typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey;
@ -694,7 +701,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// source location.
typedef std::map<unsigned, SourceLocation> MacroArgsMap;
mutable llvm::DenseMap<FileID, MacroArgsMap *> MacroArgsCacheMap;
mutable llvm::DenseMap<FileID, std::unique_ptr<MacroArgsMap>>
MacroArgsCacheMap;
/// \brief The stack of modules being built, which is used to detect
/// cycles in the module dependency graph as modules are being built, as
@ -705,12 +713,11 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// we can add a cc1-level option to do so.
SmallVector<std::pair<std::string, FullSourceLoc>, 2> StoredModuleBuildStack;
// SourceManager doesn't support copy construction.
explicit SourceManager(const SourceManager&) = delete;
void operator=(const SourceManager&) = delete;
public:
SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr,
bool UserFilesAreVolatile = false);
explicit SourceManager(const SourceManager &) = delete;
SourceManager &operator=(const SourceManager &) = delete;
~SourceManager();
void clearIDTables();
@ -1292,7 +1299,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
///
/// Note that this name does not respect \#line directives. Use
/// getPresumedLoc for normal clients.
const char *getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
StringRef getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
/// \brief Return the file characteristic of the specified source
/// location, indicating whether this is a normal file, a system
@ -1358,7 +1365,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
}
/// \brief Returns whether \p Loc is expanded from a macro in a system header.
bool isInSystemMacro(SourceLocation loc) {
bool isInSystemMacro(SourceLocation loc) const {
return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc));
}
@ -1673,7 +1680,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
std::pair<FileID, unsigned>
getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
unsigned Offset) const;
void computeMacroArgsCache(MacroArgsMap *&MacroArgsCache, FileID FID) const;
void computeMacroArgsCache(MacroArgsMap &MacroArgsCache, FileID FID) const;
void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache,
FileID FID,
SourceLocation SpellLoc,
@ -1713,7 +1720,6 @@ class BeforeThanCompare<SourceRange> {
}
};
} // end namespace clang
} // end namespace clang
#endif
#endif // LLVM_CLANG_BASIC_SOURCEMANAGER_H

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