Update clang to trunk r290819 and resolve conflicts.
This commit is contained in:
commit
4429064704
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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) {}
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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) {}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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#
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -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(); }
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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() {}
|
||||
|
||||
|
@ -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()),
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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])
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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); }
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
155
contrib/llvm/tools/clang/include/clang/Analysis/Analyses/OSLog.h
Normal file
155
contrib/llvm/tools/clang/include/clang/Analysis/Analyses/OSLog.h
Normal 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
|
@ -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
|
||||
|
@ -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>(); }
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
288
contrib/llvm/tools/clang/include/clang/Analysis/CloneDetection.h
Normal file
288
contrib/llvm/tools/clang/include/clang/Analysis/CloneDetection.h
Normal 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
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
}];
|
||||
}
|
||||
|
@ -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?
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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", "")
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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<
|
||||
|
@ -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'">;
|
||||
|
||||
|
@ -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
|
||||
================
|
||||
}];
|
||||
}
|
||||
|
@ -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">;
|
||||
}
|
||||
|
@ -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>;
|
||||
}
|
||||
}
|
||||
|
@ -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">;
|
||||
|
@ -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">,
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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'">;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user