Merge clang trunk r321017 to contrib/llvm/tools/clang.
This commit is contained in:
commit
aad9e6bafb
@ -32,7 +32,7 @@
|
||||
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
|
||||
*/
|
||||
#define CINDEX_VERSION_MAJOR 0
|
||||
#define CINDEX_VERSION_MINOR 43
|
||||
#define CINDEX_VERSION_MINOR 45
|
||||
|
||||
#define CINDEX_VERSION_ENCODE(major, minor) ( \
|
||||
((major) * 10000) \
|
||||
@ -333,6 +333,16 @@ CINDEX_LINKAGE void clang_CXIndex_setGlobalOptions(CXIndex, unsigned options);
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_CXIndex_getGlobalOptions(CXIndex);
|
||||
|
||||
/**
|
||||
* \brief Sets the invocation emission path option in a CXIndex.
|
||||
*
|
||||
* The invocation emission path specifies a path which will contain log
|
||||
* files for certain libclang invocations. A null value (default) implies that
|
||||
* libclang invocations are not logged..
|
||||
*/
|
||||
CINDEX_LINKAGE void
|
||||
clang_CXIndex_setInvocationEmissionPathOption(CXIndex, const char *Path);
|
||||
|
||||
/**
|
||||
* \defgroup CINDEX_FILES File manipulation routines
|
||||
*
|
||||
@ -393,6 +403,21 @@ clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file);
|
||||
CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu,
|
||||
const char *file_name);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the buffer associated with the given file.
|
||||
*
|
||||
* \param tu the translation unit
|
||||
*
|
||||
* \param file the file for which to retrieve the buffer.
|
||||
*
|
||||
* \param size [out] if non-NULL, will be set to the size of the buffer.
|
||||
*
|
||||
* \returns a pointer to the buffer in memory that holds the contents of
|
||||
* \p file, or a NULL pointer when the file is not loaded.
|
||||
*/
|
||||
CINDEX_LINKAGE const char *clang_getFileContents(CXTranslationUnit tu,
|
||||
CXFile file, size_t *size);
|
||||
|
||||
/**
|
||||
* \brief Returns non-zero if the \c file1 and \c file2 point to the same file,
|
||||
* or they are both NULL.
|
||||
@ -2836,6 +2861,22 @@ enum CXLanguageKind {
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor);
|
||||
|
||||
/**
|
||||
* \brief Describe the "thread-local storage (TLS) kind" of the declaration
|
||||
* referred to by a cursor.
|
||||
*/
|
||||
enum CXTLSKind {
|
||||
CXTLS_None = 0,
|
||||
CXTLS_Dynamic,
|
||||
CXTLS_Static
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Determine the "thread-local storage (TLS) kind" of the declaration
|
||||
* referred to by a cursor.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXTLSKind clang_getCursorTLSKind(CXCursor cursor);
|
||||
|
||||
/**
|
||||
* \brief Returns the translation unit that a cursor originated from.
|
||||
*/
|
||||
@ -3115,8 +3156,9 @@ enum CXTypeKind {
|
||||
CXType_ObjCSel = 29,
|
||||
CXType_Float128 = 30,
|
||||
CXType_Half = 31,
|
||||
CXType_Float16 = 32,
|
||||
CXType_FirstBuiltin = CXType_Void,
|
||||
CXType_LastBuiltin = CXType_Half,
|
||||
CXType_LastBuiltin = CXType_Float16,
|
||||
|
||||
CXType_Complex = 100,
|
||||
CXType_Pointer = 101,
|
||||
@ -4275,6 +4317,12 @@ CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor);
|
||||
*/
|
||||
CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the CXStrings representing the mangled symbols of the ObjC
|
||||
* class interface or implementation at the cursor.
|
||||
*/
|
||||
CINDEX_LINKAGE CXStringSet *clang_Cursor_getObjCManglings(CXCursor);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@ -4418,6 +4466,12 @@ CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine if a C++ record is abstract, i.e. whether a class or struct
|
||||
* has a pure virtual member function.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_CXXRecord_isAbstract(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Determine if an enum declaration refers to a scoped enum.
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- C++ -*-===//
|
||||
//===- ASTContext.h - Context to hold long-lived AST nodes ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -6,10 +6,10 @@
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
//
|
||||
/// \file
|
||||
/// \brief Defines the clang::ASTContext interface.
|
||||
///
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
|
||||
@ -19,8 +19,8 @@
|
||||
#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/DeclarationName.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/AST/PrettyPrinter.h"
|
||||
@ -30,32 +30,32 @@
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/AddressSpaces.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "clang/Basic/LLVM.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/SourceLocation.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Basic/XRayLists.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/ADT/TinyPtrVector.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Support/AlignOf.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
@ -65,7 +65,6 @@
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@ -75,50 +74,72 @@ namespace llvm {
|
||||
|
||||
struct fltSemantics;
|
||||
|
||||
} // end namespace llvm
|
||||
} // namespace llvm
|
||||
|
||||
namespace clang {
|
||||
|
||||
class APValue;
|
||||
class ASTMutationListener;
|
||||
class ASTRecordLayout;
|
||||
class AtomicExpr;
|
||||
class BlockExpr;
|
||||
class BuiltinTemplateDecl;
|
||||
class CharUnits;
|
||||
class CXXABI;
|
||||
class CXXConstructorDecl;
|
||||
class CXXMethodDecl;
|
||||
class CXXRecordDecl;
|
||||
class DiagnosticsEngine;
|
||||
class Expr;
|
||||
class MangleContext;
|
||||
class MangleNumberingContext;
|
||||
class MaterializeTemporaryExpr;
|
||||
class TargetInfo;
|
||||
// Decls
|
||||
class MangleContext;
|
||||
class MemberSpecializationInfo;
|
||||
class Module;
|
||||
class ObjCCategoryDecl;
|
||||
class ObjCCategoryImplDecl;
|
||||
class ObjCContainerDecl;
|
||||
class ObjCImplDecl;
|
||||
class ObjCImplementationDecl;
|
||||
class ObjCInterfaceDecl;
|
||||
class ObjCIvarDecl;
|
||||
class ObjCMethodDecl;
|
||||
class ObjCPropertyDecl;
|
||||
class ObjCPropertyImplDecl;
|
||||
class ObjCProtocolDecl;
|
||||
class ObjCTypeParamDecl;
|
||||
class Preprocessor;
|
||||
class Stmt;
|
||||
class StoredDeclsMap;
|
||||
class TemplateDecl;
|
||||
class TemplateParameterList;
|
||||
class TemplateTemplateParmDecl;
|
||||
class TemplateTypeParmDecl;
|
||||
class UnresolvedSetIterator;
|
||||
class UsingDecl;
|
||||
class UsingShadowDecl;
|
||||
class VarTemplateDecl;
|
||||
class VTableContextBase;
|
||||
|
||||
namespace Builtin {
|
||||
|
||||
class Context;
|
||||
class Context;
|
||||
|
||||
} // end namespace Builtin
|
||||
} // namespace Builtin
|
||||
|
||||
enum BuiltinTemplateKind : int;
|
||||
|
||||
namespace comments {
|
||||
|
||||
class FullComment;
|
||||
class FullComment;
|
||||
|
||||
} // end namespace comments
|
||||
} // namespace comments
|
||||
|
||||
struct TypeInfo {
|
||||
uint64_t Width;
|
||||
unsigned Align;
|
||||
uint64_t Width = 0;
|
||||
unsigned Align = 0;
|
||||
bool AlignIsRequired : 1;
|
||||
|
||||
TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
|
||||
TypeInfo() : AlignIsRequired(false) {}
|
||||
TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
|
||||
: Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
|
||||
};
|
||||
@ -126,7 +147,7 @@ struct TypeInfo {
|
||||
/// \brief Holds long-lived AST nodes (such as types and decls) that can be
|
||||
/// referred to throughout the semantic analysis of a file.
|
||||
class ASTContext : public RefCountedBase<ASTContext> {
|
||||
ASTContext &this_() { return *this; }
|
||||
friend class NestedNameSpecifier;
|
||||
|
||||
mutable SmallVector<Type *, 0> Types;
|
||||
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
|
||||
@ -143,6 +164,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
|
||||
mutable llvm::FoldingSet<DependentSizedExtVectorType>
|
||||
DependentSizedExtVectorTypes;
|
||||
mutable llvm::FoldingSet<DependentAddressSpaceType>
|
||||
DependentAddressSpaceTypes;
|
||||
mutable llvm::FoldingSet<VectorType> VectorTypes;
|
||||
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
|
||||
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
|
||||
@ -187,8 +210,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
///
|
||||
/// This set is managed by the NestedNameSpecifier class.
|
||||
mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
|
||||
mutable NestedNameSpecifier *GlobalNestedNameSpecifier;
|
||||
friend class NestedNameSpecifier;
|
||||
mutable NestedNameSpecifier *GlobalNestedNameSpecifier = nullptr;
|
||||
|
||||
/// \brief A cache mapping from RecordDecls to ASTRecordLayouts.
|
||||
///
|
||||
@ -199,7 +221,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
ObjCLayouts;
|
||||
|
||||
/// \brief A cache from types to size and alignment information.
|
||||
typedef llvm::DenseMap<const Type *, struct TypeInfo> TypeInfoMap;
|
||||
using TypeInfoMap = llvm::DenseMap<const Type *, struct TypeInfo>;
|
||||
mutable TypeInfoMap MemoizedTypeInfo;
|
||||
|
||||
/// \brief A cache mapping from CXXRecordDecls to key functions.
|
||||
@ -233,7 +255,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
public:
|
||||
CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
|
||||
: Parm(Parm) { }
|
||||
: Parm(Parm) {}
|
||||
|
||||
TemplateTemplateParmDecl *getParam() const { return Parm; }
|
||||
|
||||
@ -249,32 +271,32 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
|
||||
|
||||
/// \brief The typedef for the __int128_t type.
|
||||
mutable TypedefDecl *Int128Decl;
|
||||
mutable TypedefDecl *Int128Decl = nullptr;
|
||||
|
||||
/// \brief The typedef for the __uint128_t type.
|
||||
mutable TypedefDecl *UInt128Decl;
|
||||
mutable TypedefDecl *UInt128Decl = nullptr;
|
||||
|
||||
/// \brief The typedef for the target specific predefined
|
||||
/// __builtin_va_list type.
|
||||
mutable TypedefDecl *BuiltinVaListDecl;
|
||||
mutable TypedefDecl *BuiltinVaListDecl = nullptr;
|
||||
|
||||
/// The typedef for the predefined \c __builtin_ms_va_list type.
|
||||
mutable TypedefDecl *BuiltinMSVaListDecl;
|
||||
mutable TypedefDecl *BuiltinMSVaListDecl = nullptr;
|
||||
|
||||
/// \brief The typedef for the predefined \c id type.
|
||||
mutable TypedefDecl *ObjCIdDecl;
|
||||
mutable TypedefDecl *ObjCIdDecl = nullptr;
|
||||
|
||||
/// \brief The typedef for the predefined \c SEL type.
|
||||
mutable TypedefDecl *ObjCSelDecl;
|
||||
mutable TypedefDecl *ObjCSelDecl = nullptr;
|
||||
|
||||
/// \brief The typedef for the predefined \c Class type.
|
||||
mutable TypedefDecl *ObjCClassDecl;
|
||||
mutable TypedefDecl *ObjCClassDecl = nullptr;
|
||||
|
||||
/// \brief The typedef for the predefined \c Protocol class in Objective-C.
|
||||
mutable ObjCInterfaceDecl *ObjCProtocolClassDecl;
|
||||
mutable ObjCInterfaceDecl *ObjCProtocolClassDecl = nullptr;
|
||||
|
||||
/// \brief The typedef for the predefined 'BOOL' type.
|
||||
mutable TypedefDecl *BOOLDecl;
|
||||
mutable TypedefDecl *BOOLDecl = nullptr;
|
||||
|
||||
// Typedefs which may be provided defining the structure of Objective-C
|
||||
// pseudo-builtins
|
||||
@ -298,42 +320,42 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
mutable IdentifierInfo *TypePackElementName = nullptr;
|
||||
|
||||
QualType ObjCConstantStringType;
|
||||
mutable RecordDecl *CFConstantStringTagDecl;
|
||||
mutable TypedefDecl *CFConstantStringTypeDecl;
|
||||
mutable RecordDecl *CFConstantStringTagDecl = nullptr;
|
||||
mutable TypedefDecl *CFConstantStringTypeDecl = nullptr;
|
||||
|
||||
mutable QualType ObjCSuperType;
|
||||
|
||||
QualType ObjCNSStringType;
|
||||
|
||||
/// \brief The typedef declaration for the Objective-C "instancetype" type.
|
||||
TypedefDecl *ObjCInstanceTypeDecl;
|
||||
TypedefDecl *ObjCInstanceTypeDecl = nullptr;
|
||||
|
||||
/// \brief The type for the C FILE type.
|
||||
TypeDecl *FILEDecl;
|
||||
TypeDecl *FILEDecl = nullptr;
|
||||
|
||||
/// \brief The type for the C jmp_buf type.
|
||||
TypeDecl *jmp_bufDecl;
|
||||
TypeDecl *jmp_bufDecl = nullptr;
|
||||
|
||||
/// \brief The type for the C sigjmp_buf type.
|
||||
TypeDecl *sigjmp_bufDecl;
|
||||
TypeDecl *sigjmp_bufDecl = nullptr;
|
||||
|
||||
/// \brief The type for the C ucontext_t type.
|
||||
TypeDecl *ucontext_tDecl;
|
||||
TypeDecl *ucontext_tDecl = nullptr;
|
||||
|
||||
/// \brief Type for the Block descriptor for Blocks CodeGen.
|
||||
///
|
||||
/// Since this is only used for generation of debug info, it is not
|
||||
/// serialized.
|
||||
mutable RecordDecl *BlockDescriptorType;
|
||||
mutable RecordDecl *BlockDescriptorType = nullptr;
|
||||
|
||||
/// \brief Type for the Block descriptor for Blocks CodeGen.
|
||||
///
|
||||
/// Since this is only used for generation of debug info, it is not
|
||||
/// serialized.
|
||||
mutable RecordDecl *BlockDescriptorExtendedType;
|
||||
mutable RecordDecl *BlockDescriptorExtendedType = nullptr;
|
||||
|
||||
/// \brief Declaration for the CUDA cudaConfigureCall function.
|
||||
FunctionDecl *cudaConfigureCallDecl;
|
||||
FunctionDecl *cudaConfigureCallDecl = nullptr;
|
||||
|
||||
/// \brief Keeps track of all declaration attributes.
|
||||
///
|
||||
@ -363,12 +385,19 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
};
|
||||
llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers;
|
||||
|
||||
ASTContext &this_() { return *this; }
|
||||
|
||||
public:
|
||||
/// \brief A type synonym for the TemplateOrInstantiation mapping.
|
||||
typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
|
||||
TemplateOrSpecializationInfo;
|
||||
using TemplateOrSpecializationInfo =
|
||||
llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>;
|
||||
|
||||
private:
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTReader;
|
||||
friend class ASTWriter;
|
||||
friend class CXXRecordDecl;
|
||||
|
||||
/// \brief A mapping to contain the template or declaration that
|
||||
/// a variable declaration describes or was instantiated from,
|
||||
/// respectively.
|
||||
@ -438,7 +467,7 @@ private:
|
||||
/// Since most C++ member functions aren't virtual and therefore
|
||||
/// don't override anything, we store the overridden functions in
|
||||
/// this map on the side rather than within the CXXMethodDecl structure.
|
||||
typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;
|
||||
using CXXMethodVector = llvm::TinyPtrVector<const CXXMethodDecl *>;
|
||||
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
|
||||
|
||||
/// \brief Mapping from each declaration context to its corresponding
|
||||
@ -454,18 +483,18 @@ private:
|
||||
|
||||
/// \brief Mapping that stores parameterIndex values for ParmVarDecls when
|
||||
/// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
|
||||
typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable;
|
||||
using ParameterIndexTable = llvm::DenseMap<const VarDecl *, unsigned>;
|
||||
ParameterIndexTable ParamIndices;
|
||||
|
||||
ImportDecl *FirstLocalImport;
|
||||
ImportDecl *LastLocalImport;
|
||||
ImportDecl *FirstLocalImport = nullptr;
|
||||
ImportDecl *LastLocalImport = nullptr;
|
||||
|
||||
TranslationUnitDecl *TUDecl;
|
||||
mutable ExternCContextDecl *ExternCContext;
|
||||
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl;
|
||||
mutable BuiltinTemplateDecl *TypePackElementDecl;
|
||||
mutable ExternCContextDecl *ExternCContext = nullptr;
|
||||
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr;
|
||||
mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr;
|
||||
|
||||
/// \brief The associated SourceManager object.a
|
||||
/// \brief The associated SourceManager object.
|
||||
SourceManager &SourceMgr;
|
||||
|
||||
/// \brief The language options used to create the AST associated with
|
||||
@ -494,19 +523,14 @@ private:
|
||||
CXXABI *createCXXABI(const TargetInfo &T);
|
||||
|
||||
/// \brief The logical -> physical address space map.
|
||||
const LangAS::Map *AddrSpaceMap;
|
||||
const LangASMap *AddrSpaceMap = nullptr;
|
||||
|
||||
/// \brief Address space map mangling must be used with language specific
|
||||
/// address spaces (e.g. OpenCL/CUDA)
|
||||
bool AddrSpaceMapMangling;
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTReader;
|
||||
friend class ASTWriter;
|
||||
friend class CXXRecordDecl;
|
||||
|
||||
const TargetInfo *Target;
|
||||
const TargetInfo *AuxTarget;
|
||||
const TargetInfo *Target = nullptr;
|
||||
const TargetInfo *AuxTarget = nullptr;
|
||||
clang::PrintingPolicy PrintingPolicy;
|
||||
|
||||
public:
|
||||
@ -515,31 +539,33 @@ public:
|
||||
Builtin::Context &BuiltinInfo;
|
||||
mutable DeclarationNameTable DeclarationNames;
|
||||
IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
|
||||
ASTMutationListener *Listener;
|
||||
ASTMutationListener *Listener = nullptr;
|
||||
|
||||
/// \brief Contains parents of a node.
|
||||
typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> ParentVector;
|
||||
using ParentVector = llvm::SmallVector<ast_type_traits::DynTypedNode, 2>;
|
||||
|
||||
/// \brief Maps from a node to its parents. This is used for nodes that have
|
||||
/// pointer identity only, which are more common and we can save space by
|
||||
/// only storing a unique pointer to them.
|
||||
typedef llvm::DenseMap<const void *,
|
||||
llvm::PointerUnion4<const Decl *, const Stmt *,
|
||||
ast_type_traits::DynTypedNode *,
|
||||
ParentVector *>> ParentMapPointers;
|
||||
using ParentMapPointers =
|
||||
llvm::DenseMap<const void *,
|
||||
llvm::PointerUnion4<const Decl *, const Stmt *,
|
||||
ast_type_traits::DynTypedNode *,
|
||||
ParentVector *>>;
|
||||
|
||||
/// Parent map for nodes without pointer identity. We store a full
|
||||
/// DynTypedNode for all keys.
|
||||
typedef llvm::DenseMap<
|
||||
ast_type_traits::DynTypedNode,
|
||||
llvm::PointerUnion4<const Decl *, const Stmt *,
|
||||
ast_type_traits::DynTypedNode *, ParentVector *>>
|
||||
ParentMapOtherNodes;
|
||||
using ParentMapOtherNodes =
|
||||
llvm::DenseMap<ast_type_traits::DynTypedNode,
|
||||
llvm::PointerUnion4<const Decl *, const Stmt *,
|
||||
ast_type_traits::DynTypedNode *,
|
||||
ParentVector *>>;
|
||||
|
||||
/// Container for either a single DynTypedNode or for an ArrayRef to
|
||||
/// DynTypedNode. For use with ParentMap.
|
||||
class DynTypedNodeList {
|
||||
typedef ast_type_traits::DynTypedNode DynTypedNode;
|
||||
using DynTypedNode = ast_type_traits::DynTypedNode;
|
||||
|
||||
llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode,
|
||||
ArrayRef<DynTypedNode>> Storage;
|
||||
bool IsSingleNode;
|
||||
@ -548,6 +574,7 @@ public:
|
||||
DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
|
||||
new (Storage.buffer) DynTypedNode(N);
|
||||
}
|
||||
|
||||
DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
|
||||
new (Storage.buffer) ArrayRef<DynTypedNode>(A);
|
||||
}
|
||||
@ -626,13 +653,14 @@ public:
|
||||
template <typename T> T *Allocate(size_t Num = 1) const {
|
||||
return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
|
||||
}
|
||||
void Deallocate(void *Ptr) const { }
|
||||
void Deallocate(void *Ptr) const {}
|
||||
|
||||
/// Return the total amount of physical memory allocated for representing
|
||||
/// AST nodes and type information.
|
||||
size_t getASTAllocatedMemory() const {
|
||||
return BumpAlloc.getTotalMemory();
|
||||
}
|
||||
|
||||
/// Return the total memory used for various side tables.
|
||||
size_t getSideTableAllocatedMemory() const;
|
||||
|
||||
@ -649,6 +677,7 @@ public:
|
||||
/// Returns empty type if there is no appropriate target types.
|
||||
QualType getIntTypeForBitwidth(unsigned DestWidth,
|
||||
unsigned Signed) const;
|
||||
|
||||
/// getRealTypeForBitwidth -
|
||||
/// sets floating point QualTy according to specified bitwidth.
|
||||
/// Returns empty type if there is no appropriate target types.
|
||||
@ -676,7 +705,7 @@ public:
|
||||
RawCommentList Comments;
|
||||
|
||||
/// \brief True if comments are already loaded from ExternalASTSource.
|
||||
mutable bool CommentsLoaded;
|
||||
mutable bool CommentsLoaded = false;
|
||||
|
||||
class RawCommentAndCacheFlags {
|
||||
public:
|
||||
@ -759,24 +788,24 @@ public:
|
||||
}
|
||||
|
||||
/// \brief Return the documentation comment attached to a given declaration.
|
||||
/// Returns NULL if no comment is attached.
|
||||
/// Returns nullptr if no comment is attached.
|
||||
///
|
||||
/// \param OriginalDecl if not NULL, is set to declaration AST node that had
|
||||
/// the comment, if the comment we found comes from a redeclaration.
|
||||
/// \param OriginalDecl if not nullptr, is set to declaration AST node that
|
||||
/// had the comment, if the comment we found comes from a redeclaration.
|
||||
const RawComment *
|
||||
getRawCommentForAnyRedecl(const Decl *D,
|
||||
const Decl **OriginalDecl = nullptr) const;
|
||||
|
||||
/// Return parsed documentation comment attached to a given declaration.
|
||||
/// Returns NULL if no comment is attached.
|
||||
/// Returns nullptr if no comment is attached.
|
||||
///
|
||||
/// \param PP the Preprocessor used with this TU. Could be NULL if
|
||||
/// \param PP the Preprocessor used with this TU. Could be nullptr if
|
||||
/// preprocessor is not available.
|
||||
comments::FullComment *getCommentForDecl(const Decl *D,
|
||||
const Preprocessor *PP) const;
|
||||
|
||||
/// Return parsed documentation comment attached to a given declaration.
|
||||
/// Returns NULL if no comment is attached. Does not look at any
|
||||
/// Returns nullptr if no comment is attached. Does not look at any
|
||||
/// redeclarations of the declaration.
|
||||
comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const;
|
||||
|
||||
@ -788,16 +817,16 @@ private:
|
||||
|
||||
/// \brief Iterator that visits import declarations.
|
||||
class import_iterator {
|
||||
ImportDecl *Import;
|
||||
ImportDecl *Import = nullptr;
|
||||
|
||||
public:
|
||||
typedef ImportDecl *value_type;
|
||||
typedef ImportDecl *reference;
|
||||
typedef ImportDecl *pointer;
|
||||
typedef int difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
using value_type = ImportDecl *;
|
||||
using reference = ImportDecl *;
|
||||
using pointer = ImportDecl *;
|
||||
using difference_type = int;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
import_iterator() : Import() {}
|
||||
import_iterator() = default;
|
||||
explicit import_iterator(ImportDecl *Import) : Import(Import) {}
|
||||
|
||||
reference operator*() const { return Import; }
|
||||
@ -876,7 +905,7 @@ public:
|
||||
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
|
||||
|
||||
// Access to the set of methods overridden by the given C++ method.
|
||||
typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator;
|
||||
using overridden_cxx_method_iterator = CXXMethodVector::const_iterator;
|
||||
overridden_cxx_method_iterator
|
||||
overridden_methods_begin(const CXXMethodDecl *Method) const;
|
||||
|
||||
@ -884,8 +913,10 @@ public:
|
||||
overridden_methods_end(const CXXMethodDecl *Method) const;
|
||||
|
||||
unsigned overridden_methods_size(const CXXMethodDecl *Method) const;
|
||||
typedef llvm::iterator_range<overridden_cxx_method_iterator>
|
||||
overridden_method_range;
|
||||
|
||||
using overridden_method_range =
|
||||
llvm::iterator_range<overridden_cxx_method_iterator>;
|
||||
|
||||
overridden_method_range overridden_methods(const CXXMethodDecl *Method) const;
|
||||
|
||||
/// \brief Note that the given C++ \p Method overrides the given \p
|
||||
@ -912,7 +943,8 @@ public:
|
||||
return Import->NextLocalImport;
|
||||
}
|
||||
|
||||
typedef llvm::iterator_range<import_iterator> import_range;
|
||||
using import_range = llvm::iterator_range<import_iterator>;
|
||||
|
||||
import_range local_imports() const {
|
||||
return import_range(import_iterator(FirstLocalImport), import_iterator());
|
||||
}
|
||||
@ -929,6 +961,7 @@ public:
|
||||
/// and should be visible whenever \p M is visible.
|
||||
void mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
|
||||
bool NotifyListeners = true);
|
||||
|
||||
/// \brief Clean up the merged definition list. Call this if you might have
|
||||
/// added duplicates into the list.
|
||||
void deduplicateMergedDefinitonsFor(NamedDecl *ND);
|
||||
@ -973,6 +1006,7 @@ public:
|
||||
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
|
||||
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
|
||||
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
|
||||
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
|
||||
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
|
||||
CanQualType Float128ComplexTy;
|
||||
CanQualType VoidPtrTy, NullPtrTy;
|
||||
@ -1067,7 +1101,14 @@ public:
|
||||
/// The resulting type has a union of the qualifiers from T and the address
|
||||
/// space. If T already has an address space specifier, it is silently
|
||||
/// replaced.
|
||||
QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const;
|
||||
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const;
|
||||
|
||||
/// \brief Remove any existing address space on the type and returns the type
|
||||
/// with qualifiers intact (or that's the idea anyway)
|
||||
///
|
||||
/// The return type should be T with all prior qualifiers minus the address
|
||||
/// space.
|
||||
QualType removeAddrSpaceQualType(QualType T) const;
|
||||
|
||||
/// \brief Apply Objective-C protocol qualifiers to the given type.
|
||||
/// \param allowOnPointerType specifies if we can apply protocol
|
||||
@ -1175,6 +1216,7 @@ public:
|
||||
|
||||
/// \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;
|
||||
|
||||
@ -1182,9 +1224,16 @@ public:
|
||||
/// pointer to blocks.
|
||||
QualType getBlockDescriptorExtendedType() const;
|
||||
|
||||
/// Map an AST Type to an OpenCLTypeKind enum value.
|
||||
TargetInfo::OpenCLTypeKind getOpenCLTypeKind(const Type *T) const;
|
||||
|
||||
/// Get address space for OpenCL type.
|
||||
LangAS getOpenCLTypeAddrSpace(const Type *T) const;
|
||||
|
||||
void setcudaConfigureCallDecl(FunctionDecl *FD) {
|
||||
cudaConfigureCallDecl = FD;
|
||||
}
|
||||
|
||||
FunctionDecl *getcudaConfigureCallDecl() {
|
||||
return cudaConfigureCallDecl;
|
||||
}
|
||||
@ -1192,7 +1241,6 @@ public:
|
||||
/// Returns true iff we need copy/dispose helpers for the given type.
|
||||
bool BlockRequiresCopying(QualType Ty, const VarDecl *D);
|
||||
|
||||
|
||||
/// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set
|
||||
/// to false in this case. If HasByrefExtendedLayout returns true, byref variable
|
||||
/// has extended lifetime.
|
||||
@ -1269,6 +1317,10 @@ public:
|
||||
Expr *SizeExpr,
|
||||
SourceLocation AttrLoc) const;
|
||||
|
||||
QualType getDependentAddressSpaceType(QualType PointeeType,
|
||||
Expr *AddrSpaceExpr,
|
||||
SourceLocation AttrLoc) const;
|
||||
|
||||
/// \brief Return a K&R style C function type like 'int()'.
|
||||
QualType getFunctionNoProtoType(QualType ResultTy,
|
||||
const FunctionType::ExtInfo &Info) const;
|
||||
@ -1396,6 +1448,7 @@ public:
|
||||
QualType Canonical = QualType()) const;
|
||||
|
||||
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
|
||||
|
||||
/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
|
||||
/// QT's qualified-id protocol list adopt all protocols in IDecl's list
|
||||
/// of protocols.
|
||||
@ -1426,7 +1479,7 @@ public:
|
||||
/// \brief C++11 deduction pattern for 'auto &&' type.
|
||||
QualType getAutoRRefDeductType() const;
|
||||
|
||||
/// \brief C++1z deduced class template specialization type.
|
||||
/// \brief C++17 deduced class template specialization type.
|
||||
QualType getDeducedTemplateSpecializationType(TemplateName Template,
|
||||
QualType DeducedType,
|
||||
bool IsDependent) const;
|
||||
@ -1488,6 +1541,11 @@ public:
|
||||
/// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
|
||||
QualType getPointerDiffType() const;
|
||||
|
||||
/// \brief Return the unique unsigned counterpart of "ptrdiff_t"
|
||||
/// integer type. The standard (C11 7.21.6.1p7) refers to this type
|
||||
/// in the definition of %tu format specifier.
|
||||
QualType getUnsignedPointerDiffType() const;
|
||||
|
||||
/// \brief Return the unique type for "pid_t" defined in
|
||||
/// <sys/types.h>. We need this to compute the correct type for vfork().
|
||||
QualType getProcessIDType() const;
|
||||
@ -1581,6 +1639,24 @@ public:
|
||||
return NSCopyingName;
|
||||
}
|
||||
|
||||
CanQualType getNSUIntegerType() const {
|
||||
assert(Target && "Expected target to be initialized");
|
||||
const llvm::Triple &T = Target->getTriple();
|
||||
// Windows is LLP64 rather than LP64
|
||||
if (T.isOSWindows() && T.isArch64Bit())
|
||||
return UnsignedLongLongTy;
|
||||
return UnsignedLongTy;
|
||||
}
|
||||
|
||||
CanQualType getNSIntegerType() const {
|
||||
assert(Target && "Expected target to be initialized");
|
||||
const llvm::Triple &T = Target->getTriple();
|
||||
// Windows is LLP64 rather than LP64
|
||||
if (T.isOSWindows() && T.isArch64Bit())
|
||||
return LongLongTy;
|
||||
return LongTy;
|
||||
}
|
||||
|
||||
/// Retrieve the identifier 'bool'.
|
||||
IdentifierInfo *getBoolName() const {
|
||||
if (!BoolName)
|
||||
@ -1865,10 +1941,17 @@ public:
|
||||
const TemplateArgument &ArgPack) const;
|
||||
|
||||
enum GetBuiltinTypeError {
|
||||
GE_None, ///< No error
|
||||
GE_Missing_stdio, ///< Missing a type from <stdio.h>
|
||||
GE_Missing_setjmp, ///< Missing a type from <setjmp.h>
|
||||
GE_Missing_ucontext ///< Missing a type from <ucontext.h>
|
||||
/// No error
|
||||
GE_None,
|
||||
|
||||
/// Missing a type from <stdio.h>
|
||||
GE_Missing_stdio,
|
||||
|
||||
/// Missing a type from <setjmp.h>
|
||||
GE_Missing_setjmp,
|
||||
|
||||
/// Missing a type from <ucontext.h>
|
||||
GE_Missing_ucontext
|
||||
};
|
||||
|
||||
/// \brief Return the type for the specified builtin.
|
||||
@ -2019,7 +2102,7 @@ public:
|
||||
getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const;
|
||||
|
||||
/// \brief Get our current best idea for the key function of the
|
||||
/// given record decl, or NULL if there isn't one.
|
||||
/// given record decl, or nullptr if there isn't one.
|
||||
///
|
||||
/// The key function is, according to the Itanium C++ ABI section 5.2.3:
|
||||
/// ...the first non-pure virtual function that is not inline at the
|
||||
@ -2072,6 +2155,10 @@ public:
|
||||
void CollectInheritedProtocols(const Decl *CDecl,
|
||||
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
|
||||
|
||||
/// \brief Return true if the specified type has unique object representations
|
||||
/// according to (C++17 [meta.unary.prop]p9)
|
||||
bool hasUniqueObjectRepresentations(QualType Ty) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Type Operators
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -2103,7 +2190,6 @@ public:
|
||||
bool hasSameType(QualType T1, QualType T2) const {
|
||||
return getCanonicalType(T1) == getCanonicalType(T2);
|
||||
}
|
||||
|
||||
bool hasSameType(const Type *T1, const Type *T2) const {
|
||||
return getCanonicalType(T1) == getCanonicalType(T2);
|
||||
}
|
||||
@ -2192,7 +2278,7 @@ public:
|
||||
getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
|
||||
|
||||
/// \brief Retrieves the default calling convention for the current target.
|
||||
CallingConv getDefaultCallingConvention(bool isVariadic,
|
||||
CallingConv getDefaultCallingConvention(bool IsVariadic,
|
||||
bool IsCXXMethod) const;
|
||||
|
||||
/// \brief Retrieves the "canonical" template name that refers to a
|
||||
@ -2326,14 +2412,14 @@ public:
|
||||
return getTargetAddressSpace(Q.getAddressSpace());
|
||||
}
|
||||
|
||||
unsigned getTargetAddressSpace(unsigned AS) const;
|
||||
unsigned getTargetAddressSpace(LangAS AS) const;
|
||||
|
||||
/// 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::FirstTargetAddressSpace;
|
||||
bool addressSpaceMapManglingFor(LangAS AS) const {
|
||||
return AddrSpaceMapMangling || isTargetAddressSpace(AS);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2355,12 +2441,15 @@ public:
|
||||
bool isObjCIdType(QualType T) const {
|
||||
return T == getObjCIdType();
|
||||
}
|
||||
|
||||
bool isObjCClassType(QualType T) const {
|
||||
return T == getObjCClassType();
|
||||
}
|
||||
|
||||
bool isObjCSelType(QualType T) const {
|
||||
return T == getObjCSelType();
|
||||
}
|
||||
|
||||
bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
|
||||
bool ForCompare);
|
||||
|
||||
@ -2394,9 +2483,30 @@ public:
|
||||
|
||||
QualType mergeObjCGCQualifiers(QualType, QualType);
|
||||
|
||||
bool doFunctionTypesMatchOnExtParameterInfos(
|
||||
const FunctionProtoType *FromFunctionType,
|
||||
const FunctionProtoType *ToFunctionType);
|
||||
/// This function merges the ExtParameterInfo lists of two functions. It
|
||||
/// returns true if the lists are compatible. The merged list is returned in
|
||||
/// NewParamInfos.
|
||||
///
|
||||
/// \param FirstFnType The type of the first function.
|
||||
///
|
||||
/// \param SecondFnType The type of the second function.
|
||||
///
|
||||
/// \param CanUseFirst This flag is set to true if the first function's
|
||||
/// ExtParameterInfo list can be used as the composite list of
|
||||
/// ExtParameterInfo.
|
||||
///
|
||||
/// \param CanUseSecond This flag is set to true if the second function's
|
||||
/// ExtParameterInfo list can be used as the composite list of
|
||||
/// ExtParameterInfo.
|
||||
///
|
||||
/// \param NewParamInfos The composite list of ExtParameterInfo. The list is
|
||||
/// empty if none of the flags are set.
|
||||
///
|
||||
bool mergeExtParameterInfo(
|
||||
const FunctionProtoType *FirstFnType,
|
||||
const FunctionProtoType *SecondFnType,
|
||||
bool &CanUseFirst, bool &CanUseSecond,
|
||||
SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &NewParamInfos);
|
||||
|
||||
void ResetObjCLayout(const ObjCContainerDecl *CD);
|
||||
|
||||
@ -2432,12 +2542,13 @@ public:
|
||||
|
||||
bool isSentinelNullExpr(const Expr *E);
|
||||
|
||||
/// \brief Get the implementation of the ObjCInterfaceDecl \p D, or NULL if
|
||||
/// \brief Get the implementation of the ObjCInterfaceDecl \p D, or nullptr if
|
||||
/// none exists.
|
||||
ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);
|
||||
/// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if
|
||||
|
||||
/// \brief Get the implementation of the ObjCCategoryDecl \p D, or nullptr if
|
||||
/// none exists.
|
||||
ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
|
||||
ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
|
||||
|
||||
/// \brief Return true if there is at least one \@implementation in the TU.
|
||||
bool AnyObjCImplementation() {
|
||||
@ -2447,6 +2558,7 @@ public:
|
||||
/// \brief Set the implementation of ObjCInterfaceDecl.
|
||||
void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
|
||||
ObjCImplementationDecl *ImplD);
|
||||
|
||||
/// \brief Set the implementation of ObjCCategoryDecl.
|
||||
void setObjCImplementation(ObjCCategoryDecl *CatD,
|
||||
ObjCCategoryImplDecl *ImplD);
|
||||
@ -2466,8 +2578,9 @@ public:
|
||||
|
||||
/// \brief Set the copy inialization expression of a block var decl.
|
||||
void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
|
||||
|
||||
/// \brief Get the copy initialization expression of the VarDecl \p VD, or
|
||||
/// NULL if none exists.
|
||||
/// nullptr if none exists.
|
||||
Expr *getBlockVarCopyInits(const VarDecl* VD);
|
||||
|
||||
/// \brief Allocate an uninitialized TypeSourceInfo.
|
||||
@ -2636,6 +2749,7 @@ private:
|
||||
const FieldDecl *Field,
|
||||
bool includeVBases = true,
|
||||
QualType *NotEncodedT=nullptr) const;
|
||||
|
||||
public:
|
||||
// Adds the encoding of a method parameter or return type.
|
||||
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
|
||||
@ -2647,11 +2761,19 @@ public:
|
||||
bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
|
||||
|
||||
enum class InlineVariableDefinitionKind {
|
||||
None, ///< Not an inline variable.
|
||||
Weak, ///< Weak definition of inline variable.
|
||||
WeakUnknown, ///< Weak for now, might become strong later in this TU.
|
||||
Strong ///< Strong definition.
|
||||
/// Not an inline variable.
|
||||
None,
|
||||
|
||||
/// Weak definition of inline variable.
|
||||
Weak,
|
||||
|
||||
/// Weak for now, might become strong later in this TU.
|
||||
WeakUnknown,
|
||||
|
||||
/// Strong definition.
|
||||
Strong
|
||||
};
|
||||
|
||||
/// \brief Determine whether a definition of this inline variable should
|
||||
/// be treated as a weak or strong definition. For compatibility with
|
||||
/// C++14 and before, for a constexpr static data member, if there is an
|
||||
@ -2661,6 +2783,9 @@ public:
|
||||
getInlineVariableDefinitionKind(const VarDecl *VD) const;
|
||||
|
||||
private:
|
||||
friend class DeclarationNameTable;
|
||||
friend class DeclContext;
|
||||
|
||||
const ASTRecordLayout &
|
||||
getObjCLayout(const ObjCInterfaceDecl *D,
|
||||
const ObjCImplementationDecl *Impl) const;
|
||||
@ -2673,26 +2798,23 @@ private:
|
||||
// into the datastructures which avoids this mess during deallocation but is
|
||||
// wasteful of memory, and here we require a lot of error prone book keeping
|
||||
// in order to track and run destructors while we're tearing things down.
|
||||
typedef llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>
|
||||
DeallocationFunctionsAndArguments;
|
||||
using DeallocationFunctionsAndArguments =
|
||||
llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>;
|
||||
DeallocationFunctionsAndArguments Deallocations;
|
||||
|
||||
// FIXME: This currently contains the set of StoredDeclMaps used
|
||||
// by DeclContext objects. This probably should not be in ASTContext,
|
||||
// but we include it here so that ASTContext can quickly deallocate them.
|
||||
llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM;
|
||||
|
||||
friend class DeclContext;
|
||||
friend class DeclarationNameTable;
|
||||
|
||||
void ReleaseDeclContextMaps();
|
||||
void ReleaseParentMapEntries();
|
||||
llvm::PointerIntPair<StoredDeclsMap *, 1> LastSDM;
|
||||
|
||||
std::unique_ptr<ParentMapPointers> PointerParents;
|
||||
std::unique_ptr<ParentMapOtherNodes> OtherParents;
|
||||
|
||||
std::unique_ptr<VTableContextBase> VTContext;
|
||||
|
||||
void ReleaseDeclContextMaps();
|
||||
void ReleaseParentMapEntries();
|
||||
|
||||
public:
|
||||
enum PragmaSectionFlag : unsigned {
|
||||
PSF_None = 0,
|
||||
@ -2712,27 +2834,26 @@ public:
|
||||
SectionInfo(DeclaratorDecl *Decl,
|
||||
SourceLocation PragmaSectionLocation,
|
||||
int SectionFlags)
|
||||
: Decl(Decl),
|
||||
PragmaSectionLocation(PragmaSectionLocation),
|
||||
SectionFlags(SectionFlags) {}
|
||||
: Decl(Decl), PragmaSectionLocation(PragmaSectionLocation),
|
||||
SectionFlags(SectionFlags) {}
|
||||
};
|
||||
|
||||
llvm::StringMap<SectionInfo> SectionInfos;
|
||||
};
|
||||
|
||||
/// \brief Utility function for constructing a nullary selector.
|
||||
static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) {
|
||||
inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) {
|
||||
IdentifierInfo* II = &Ctx.Idents.get(name);
|
||||
return Ctx.Selectors.getSelector(0, &II);
|
||||
}
|
||||
|
||||
/// \brief Utility function for constructing an unary selector.
|
||||
static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
|
||||
inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
|
||||
IdentifierInfo* II = &Ctx.Idents.get(name);
|
||||
return Ctx.Selectors.getSelector(1, &II);
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
// operator new and delete aren't allowed inside namespaces.
|
||||
|
||||
@ -2763,11 +2884,12 @@ static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
|
||||
/// @param C The ASTContext that provides the allocator.
|
||||
/// @param Alignment The alignment of the allocated memory (if the underlying
|
||||
/// allocator supports it).
|
||||
/// @return The allocated memory. Could be NULL.
|
||||
/// @return The allocated memory. Could be nullptr.
|
||||
inline void *operator new(size_t Bytes, const clang::ASTContext &C,
|
||||
size_t Alignment) {
|
||||
return C.Allocate(Bytes, Alignment);
|
||||
}
|
||||
|
||||
/// @brief Placement delete companion to the new above.
|
||||
///
|
||||
/// This operator is just a companion to the new above. There is no way of
|
||||
@ -2800,7 +2922,7 @@ inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
|
||||
/// @param C The ASTContext that provides the allocator.
|
||||
/// @param Alignment The alignment of the allocated memory (if the underlying
|
||||
/// allocator supports it).
|
||||
/// @return The allocated memory. Could be NULL.
|
||||
/// @return The allocated memory. Could be nullptr.
|
||||
inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
|
||||
size_t Alignment = 8) {
|
||||
return C.Allocate(Bytes, Alignment);
|
||||
|
@ -22,6 +22,7 @@ namespace clang {
|
||||
class CXXRecordDecl;
|
||||
class Decl;
|
||||
class DeclContext;
|
||||
class Expr;
|
||||
class FieldDecl;
|
||||
class FunctionDecl;
|
||||
class FunctionTemplateDecl;
|
||||
@ -35,6 +36,7 @@ namespace clang {
|
||||
class QualType;
|
||||
class RecordDecl;
|
||||
class TagDecl;
|
||||
class ValueDecl;
|
||||
class VarDecl;
|
||||
class VarTemplateDecl;
|
||||
class VarTemplateSpecializationDecl;
|
||||
@ -80,13 +82,19 @@ public:
|
||||
|
||||
/// \brief A virtual destructor's operator delete has been resolved.
|
||||
virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
|
||||
const FunctionDecl *Delete) {}
|
||||
const FunctionDecl *Delete,
|
||||
Expr *ThisArg) {}
|
||||
|
||||
/// \brief An implicit member got a definition.
|
||||
virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
|
||||
|
||||
/// \brief A static data member was implicitly instantiated.
|
||||
virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
|
||||
/// \brief The instantiation of a templated function or variable was
|
||||
/// requested. In particular, the point of instantiation and template
|
||||
/// specialization kind of \p D may have changed.
|
||||
virtual void InstantiationRequested(const ValueDecl *D) {}
|
||||
|
||||
/// \brief A templated variable's definition was implicitly instantiated.
|
||||
virtual void VariableDefinitionInstantiated(const VarDecl *D) {}
|
||||
|
||||
/// \brief A function template's definition was instantiated.
|
||||
virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- ASTUnresolvedSet.h - Unresolved sets of declarations ---*- C++ -*-===//
|
||||
//===- ASTUnresolvedSet.h - Unresolved sets of declarations -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -16,14 +16,22 @@
|
||||
#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
|
||||
|
||||
#include "clang/AST/ASTVector.h"
|
||||
#include "clang/AST/DeclAccessPair.h"
|
||||
#include "clang/AST/UnresolvedSet.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class NamedDecl;
|
||||
|
||||
/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
|
||||
class ASTUnresolvedSet {
|
||||
friend class LazyASTUnresolvedSet;
|
||||
|
||||
struct DeclsTy : ASTVector<DeclAccessPair> {
|
||||
DeclsTy() {}
|
||||
DeclsTy() = default;
|
||||
DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {}
|
||||
|
||||
bool isLazy() const { return getTag(); }
|
||||
@ -32,14 +40,12 @@ class ASTUnresolvedSet {
|
||||
|
||||
DeclsTy Decls;
|
||||
|
||||
friend class LazyASTUnresolvedSet;
|
||||
|
||||
public:
|
||||
ASTUnresolvedSet() {}
|
||||
ASTUnresolvedSet() = default;
|
||||
ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
|
||||
|
||||
typedef UnresolvedSetIterator iterator;
|
||||
typedef UnresolvedSetIterator const_iterator;
|
||||
using iterator = UnresolvedSetIterator;
|
||||
using const_iterator = UnresolvedSetIterator;
|
||||
|
||||
iterator begin() { return iterator(Decls.begin()); }
|
||||
iterator end() { return iterator(Decls.end()); }
|
||||
@ -98,13 +104,14 @@ public:
|
||||
}
|
||||
|
||||
void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); }
|
||||
|
||||
void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) {
|
||||
assert(Impl.empty() || Impl.Decls.isLazy());
|
||||
Impl.Decls.setLazy(true);
|
||||
Impl.addDecl(C, reinterpret_cast<NamedDecl*>(ID << 2), AS);
|
||||
Impl.addDecl(C, reinterpret_cast<NamedDecl *>(ID << 2), AS);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===- ASTVector.h - Vector that uses ASTContext for allocation --*- C++ -*-=//
|
||||
//===- ASTVector.h - Vector that uses ASTContext for allocation ---*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -18,22 +18,26 @@
|
||||
#ifndef LLVM_CLANG_AST_ASTVECTOR_H
|
||||
#define LLVM_CLANG_AST_ASTVECTOR_H
|
||||
|
||||
#include "clang/AST/AttrIterator.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
|
||||
class ASTContext;
|
||||
|
||||
template<typename T>
|
||||
class ASTVector {
|
||||
private:
|
||||
T *Begin, *End;
|
||||
llvm::PointerIntPair<T*, 1, bool> Capacity;
|
||||
T *Begin = nullptr;
|
||||
T *End = nullptr;
|
||||
llvm::PointerIntPair<T *, 1, bool> Capacity;
|
||||
|
||||
void setEnd(T *P) { this->End = P; }
|
||||
|
||||
@ -45,7 +49,7 @@ protected:
|
||||
|
||||
public:
|
||||
// Default ctor - Initialize to empty.
|
||||
ASTVector() : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {}
|
||||
ASTVector() : Capacity(nullptr, false) {}
|
||||
|
||||
ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) {
|
||||
O.Begin = O.End = nullptr;
|
||||
@ -53,14 +57,15 @@ public:
|
||||
O.Capacity.setInt(false);
|
||||
}
|
||||
|
||||
ASTVector(const ASTContext &C, unsigned N)
|
||||
: Begin(nullptr), End(nullptr), Capacity(nullptr, false) {
|
||||
ASTVector(const ASTContext &C, unsigned N) : Capacity(nullptr, false) {
|
||||
reserve(C, N);
|
||||
}
|
||||
|
||||
ASTVector &operator=(ASTVector &&RHS) {
|
||||
ASTVector O(std::move(RHS));
|
||||
|
||||
using std::swap;
|
||||
|
||||
swap(Begin, O.Begin);
|
||||
swap(End, O.End);
|
||||
swap(Capacity, O.Capacity);
|
||||
@ -74,19 +79,19 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T value_type;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using value_type = T;
|
||||
using iterator = T *;
|
||||
using const_iterator = const T *;
|
||||
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
using reference = T &;
|
||||
using const_reference = const T &;
|
||||
using pointer = T *;
|
||||
using const_pointer = const T *;
|
||||
|
||||
// forward iterator creation methods.
|
||||
iterator begin() { return Begin; }
|
||||
@ -175,7 +180,6 @@ public:
|
||||
size_t capacity() const { return this->capacity_ptr() - Begin; }
|
||||
|
||||
/// append - Add the specified range to the end of the SmallVector.
|
||||
///
|
||||
template<typename in_iter>
|
||||
void append(const ASTContext &C, in_iter in_start, in_iter in_end) {
|
||||
size_type NumInputs = std::distance(in_start, in_end);
|
||||
@ -195,7 +199,6 @@ public:
|
||||
}
|
||||
|
||||
/// append - Add the specified range to the end of the SmallVector.
|
||||
///
|
||||
void append(const ASTContext &C, size_type NumInputs, const T &Elt) {
|
||||
// Grow allocated space if needed.
|
||||
if (NumInputs > size_type(this->capacity_ptr()-this->end()))
|
||||
@ -368,6 +371,7 @@ protected:
|
||||
const_iterator capacity_ptr() const {
|
||||
return (iterator) Capacity.getPointer();
|
||||
}
|
||||
|
||||
iterator capacity_ptr() { return (iterator)Capacity.getPointer(); }
|
||||
};
|
||||
|
||||
@ -401,5 +405,6 @@ void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) {
|
||||
Capacity.setPointer(Begin+NewCapacity);
|
||||
}
|
||||
|
||||
} // end: clang namespace
|
||||
#endif
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_ASTVECTOR_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- AttrIterator.h - Classes for attribute iteration -------*- C++ -*-===//
|
||||
//===- AttrIterator.h - Classes for attribute iteration ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -15,16 +15,23 @@
|
||||
#define LLVM_CLANG_AST_ATTRITERATOR_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class Attr;
|
||||
}
|
||||
|
||||
class ASTContext;
|
||||
class Attr;
|
||||
|
||||
} // namespace clang
|
||||
|
||||
// Defined in ASTContext.h
|
||||
void *operator new(size_t Bytes, const clang::ASTContext &C,
|
||||
size_t Alignment = 8);
|
||||
|
||||
// FIXME: Being forced to not have a default argument here due to redeclaration
|
||||
// rules on default arguments sucks
|
||||
void *operator new[](size_t Bytes, const clang::ASTContext &C,
|
||||
@ -39,13 +46,13 @@ 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 *, 4> AttrVec;
|
||||
using AttrVec = SmallVector<Attr *, 4>;
|
||||
|
||||
/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
|
||||
/// providing attributes that are of a specific type.
|
||||
template <typename SpecificAttr, typename Container = AttrVec>
|
||||
class specific_attr_iterator {
|
||||
typedef typename Container::const_iterator Iterator;
|
||||
using Iterator = typename Container::const_iterator;
|
||||
|
||||
/// Current - The current, underlying iterator.
|
||||
/// In order to ensure we don't dereference an invalid iterator unless
|
||||
@ -67,14 +74,14 @@ class specific_attr_iterator {
|
||||
}
|
||||
|
||||
public:
|
||||
typedef SpecificAttr* value_type;
|
||||
typedef SpecificAttr* reference;
|
||||
typedef SpecificAttr* pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
using value_type = SpecificAttr *;
|
||||
using reference = SpecificAttr *;
|
||||
using pointer = SpecificAttr *;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
specific_attr_iterator() : Current() { }
|
||||
explicit specific_attr_iterator(Iterator i) : Current(i) { }
|
||||
specific_attr_iterator() = default;
|
||||
explicit specific_attr_iterator(Iterator i) : Current(i) {}
|
||||
|
||||
reference operator*() const {
|
||||
AdvanceToNext();
|
||||
@ -136,6 +143,6 @@ inline SpecificAttr *getSpecificAttr(const Container& container) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_ATTRITERATOR_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- BaseSubobject.h - BaseSubobject class ----------------------------===//
|
||||
//===- BaseSubobject.h - BaseSubobject class --------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -15,12 +15,15 @@
|
||||
#define LLVM_CLANG_AST_BASESUBOBJECT_H
|
||||
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CXXRecordDecl;
|
||||
|
||||
// BaseSubobject - Uniquely identifies a direct or indirect base class.
|
||||
// Stores both the base class decl and the offset from the most derived class to
|
||||
// the base class. Used for vtable and VTT generation.
|
||||
@ -32,9 +35,9 @@ class BaseSubobject {
|
||||
CharUnits BaseOffset;
|
||||
|
||||
public:
|
||||
BaseSubobject() { }
|
||||
BaseSubobject() = default;
|
||||
BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
|
||||
: Base(Base), BaseOffset(BaseOffset) { }
|
||||
: Base(Base), BaseOffset(BaseOffset) {}
|
||||
|
||||
/// getBase - Returns the base class declaration.
|
||||
const CXXRecordDecl *getBase() const { return Base; }
|
||||
@ -47,7 +50,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -65,7 +68,8 @@ template<> struct DenseMapInfo<clang::BaseSubobject> {
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const clang::BaseSubobject &Base) {
|
||||
typedef std::pair<const clang::CXXRecordDecl *, clang::CharUnits> PairTy;
|
||||
using PairTy = std::pair<const clang::CXXRecordDecl *, clang::CharUnits>;
|
||||
|
||||
return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(),
|
||||
Base.getBaseOffset()));
|
||||
}
|
||||
@ -81,6 +85,6 @@ template <> struct isPodLike<clang::BaseSubobject> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_BASESUBOBJECT_H
|
||||
|
@ -133,6 +133,9 @@ FLOATING_TYPE(Double, DoubleTy)
|
||||
// 'long double'
|
||||
FLOATING_TYPE(LongDouble, LongDoubleTy)
|
||||
|
||||
// '_Float16'
|
||||
FLOATING_TYPE(Float16, HalfTy)
|
||||
|
||||
// '__float128'
|
||||
FLOATING_TYPE(Float128, Float128Ty)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===------ CXXInheritance.h - C++ Inheritance ------------------*- C++ -*-===//
|
||||
//===- CXXInheritance.h - C++ Inheritance -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -16,19 +16,23 @@
|
||||
|
||||
#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 "clang/Basic/Specifiers.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <cassert>
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CXXBaseSpecifier;
|
||||
class CXXMethodDecl;
|
||||
class CXXRecordDecl;
|
||||
|
||||
class ASTContext;
|
||||
class NamedDecl;
|
||||
|
||||
/// \brief Represents an element in a path from a derived class to a
|
||||
@ -66,12 +70,12 @@ struct CXXBasePathElement {
|
||||
/// subobject is being used.
|
||||
class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
|
||||
public:
|
||||
CXXBasePath() : Access(AS_public) {}
|
||||
|
||||
/// \brief The access along this inheritance path. This is only
|
||||
/// calculated when recording paths. AS_none is a special value
|
||||
/// used to indicate a path which permits no legal access.
|
||||
AccessSpecifier Access;
|
||||
AccessSpecifier Access = AS_public;
|
||||
|
||||
CXXBasePath() = default;
|
||||
|
||||
/// \brief The set of declarations found inside this base class
|
||||
/// subobject.
|
||||
@ -113,8 +117,10 @@ public:
|
||||
/// refer to the same base class subobject of type A (the virtual
|
||||
/// one), there is no ambiguity.
|
||||
class CXXBasePaths {
|
||||
friend class CXXRecordDecl;
|
||||
|
||||
/// \brief The type from which this search originated.
|
||||
CXXRecordDecl *Origin;
|
||||
CXXRecordDecl *Origin = nullptr;
|
||||
|
||||
/// Paths - The actual set of paths that can be taken from the
|
||||
/// derived class to the same base class.
|
||||
@ -152,15 +158,13 @@ class CXXBasePaths {
|
||||
CXXBasePath ScratchPath;
|
||||
|
||||
/// DetectedVirtual - The base class that is virtual.
|
||||
const RecordType *DetectedVirtual;
|
||||
const RecordType *DetectedVirtual = nullptr;
|
||||
|
||||
/// \brief Array of the declarations that have been found. This
|
||||
/// array is constructed only if needed, e.g., to iterate over the
|
||||
/// results within LookupResult.
|
||||
std::unique_ptr<NamedDecl *[]> DeclsFound;
|
||||
unsigned NumDeclsFound;
|
||||
|
||||
friend class CXXRecordDecl;
|
||||
unsigned NumDeclsFound = 0;
|
||||
|
||||
void ComputeDeclsFound();
|
||||
|
||||
@ -169,17 +173,16 @@ class CXXBasePaths {
|
||||
bool LookupInDependent = false);
|
||||
|
||||
public:
|
||||
typedef std::list<CXXBasePath>::iterator paths_iterator;
|
||||
typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
|
||||
typedef NamedDecl **decl_iterator;
|
||||
using paths_iterator = std::list<CXXBasePath>::iterator;
|
||||
using const_paths_iterator = std::list<CXXBasePath>::const_iterator;
|
||||
using decl_iterator = NamedDecl **;
|
||||
|
||||
/// BasePaths - Construct a new BasePaths structure to record the
|
||||
/// paths for a derived-to-base search.
|
||||
explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
|
||||
bool DetectVirtual = true)
|
||||
: Origin(), FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
|
||||
DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
|
||||
NumDeclsFound(0) {}
|
||||
: FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
|
||||
DetectVirtual(DetectVirtual) {}
|
||||
|
||||
paths_iterator begin() { return Paths.begin(); }
|
||||
paths_iterator end() { return Paths.end(); }
|
||||
@ -189,7 +192,8 @@ public:
|
||||
CXXBasePath& front() { return Paths.front(); }
|
||||
const CXXBasePath& front() const { return Paths.front(); }
|
||||
|
||||
typedef llvm::iterator_range<decl_iterator> decl_range;
|
||||
using decl_range = llvm::iterator_range<decl_iterator>;
|
||||
|
||||
decl_range found_decls();
|
||||
|
||||
/// \brief Determine whether the path from the most-derived type to the
|
||||
@ -231,25 +235,24 @@ public:
|
||||
/// \brief Uniquely identifies a virtual method within a class
|
||||
/// hierarchy by the method itself and a class subobject number.
|
||||
struct UniqueVirtualMethod {
|
||||
UniqueVirtualMethod()
|
||||
: Method(nullptr), Subobject(0), InVirtualSubobject(nullptr) { }
|
||||
|
||||
UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
|
||||
const CXXRecordDecl *InVirtualSubobject)
|
||||
: Method(Method), Subobject(Subobject),
|
||||
InVirtualSubobject(InVirtualSubobject) { }
|
||||
|
||||
/// \brief The overriding virtual method.
|
||||
CXXMethodDecl *Method;
|
||||
CXXMethodDecl *Method = nullptr;
|
||||
|
||||
/// \brief The subobject in which the overriding virtual method
|
||||
/// resides.
|
||||
unsigned Subobject;
|
||||
unsigned Subobject = 0;
|
||||
|
||||
/// \brief The virtual base class subobject of which this overridden
|
||||
/// virtual method is a part. Note that this records the closest
|
||||
/// derived virtual base class subobject.
|
||||
const CXXRecordDecl *InVirtualSubobject;
|
||||
const CXXRecordDecl *InVirtualSubobject = nullptr;
|
||||
|
||||
UniqueVirtualMethod() = default;
|
||||
|
||||
UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
|
||||
const CXXRecordDecl *InVirtualSubobject)
|
||||
: Method(Method), Subobject(Subobject),
|
||||
InVirtualSubobject(InVirtualSubobject) {}
|
||||
|
||||
friend bool operator==(const UniqueVirtualMethod &X,
|
||||
const UniqueVirtualMethod &Y) {
|
||||
@ -271,14 +274,16 @@ struct UniqueVirtualMethod {
|
||||
/// pair is the virtual method that overrides it (including the
|
||||
/// subobject in which that virtual function occurs).
|
||||
class OverridingMethods {
|
||||
typedef SmallVector<UniqueVirtualMethod, 4> ValuesT;
|
||||
typedef llvm::MapVector<unsigned, ValuesT> MapType;
|
||||
using ValuesT = SmallVector<UniqueVirtualMethod, 4>;
|
||||
using MapType = llvm::MapVector<unsigned, ValuesT>;
|
||||
|
||||
MapType Overrides;
|
||||
|
||||
public:
|
||||
// Iterate over the set of subobjects that have overriding methods.
|
||||
typedef MapType::iterator iterator;
|
||||
typedef MapType::const_iterator const_iterator;
|
||||
using iterator = MapType::iterator;
|
||||
using const_iterator = MapType::const_iterator;
|
||||
|
||||
iterator begin() { return Overrides.begin(); }
|
||||
const_iterator begin() const { return Overrides.begin(); }
|
||||
iterator end() { return Overrides.end(); }
|
||||
@ -287,10 +292,10 @@ public:
|
||||
|
||||
// Iterate over the set of overriding virtual methods in a given
|
||||
// subobject.
|
||||
typedef SmallVectorImpl<UniqueVirtualMethod>::iterator
|
||||
overriding_iterator;
|
||||
typedef SmallVectorImpl<UniqueVirtualMethod>::const_iterator
|
||||
overriding_const_iterator;
|
||||
using overriding_iterator =
|
||||
SmallVectorImpl<UniqueVirtualMethod>::iterator;
|
||||
using overriding_const_iterator =
|
||||
SmallVectorImpl<UniqueVirtualMethod>::const_iterator;
|
||||
|
||||
// Add a new overriding method for a particular subobject.
|
||||
void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
|
||||
@ -357,12 +362,12 @@ public:
|
||||
/// subobject numbers greater than 0 refer to non-virtual base class
|
||||
/// subobjects of that type.
|
||||
class CXXFinalOverriderMap
|
||||
: public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> { };
|
||||
: public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> {};
|
||||
|
||||
/// \brief A set of all the primary bases for a class.
|
||||
class CXXIndirectPrimaryBaseSet
|
||||
: public llvm::SmallSet<const CXXRecordDecl*, 32> { };
|
||||
: public llvm::SmallSet<const CXXRecordDecl*, 32> {};
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_CXXINHERITANCE_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===//
|
||||
//===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -16,13 +16,29 @@
|
||||
#define LLVM_CLANG_AST_CANONICALTYPE_H
|
||||
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/iterator.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/PointerLikeTypeTraits.h"
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace clang {
|
||||
|
||||
template<typename T> class CanProxy;
|
||||
template<typename T> struct CanProxyAdaptor;
|
||||
class CXXRecordDecl;
|
||||
class EnumDecl;
|
||||
class Expr;
|
||||
class IdentifierInfo;
|
||||
class ObjCInterfaceDecl;
|
||||
class RecordDecl;
|
||||
class TagDecl;
|
||||
class TemplateTypeParmDecl;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Canonical, qualified type template
|
||||
@ -46,8 +62,6 @@ template<typename T> struct CanProxyAdaptor;
|
||||
/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
|
||||
/// be implicitly converted to a QualType, but the reverse operation requires
|
||||
/// a call to ASTContext::getCanonicalType().
|
||||
///
|
||||
///
|
||||
template<typename T = Type>
|
||||
class CanQual {
|
||||
/// \brief The actual, canonical type.
|
||||
@ -55,7 +69,7 @@ class CanQual {
|
||||
|
||||
public:
|
||||
/// \brief Constructs a NULL canonical type.
|
||||
CanQual() : Stored() { }
|
||||
CanQual() = default;
|
||||
|
||||
/// \brief Converting constructor that permits implicit upcasting of
|
||||
/// canonical type pointers.
|
||||
@ -66,12 +80,11 @@ public:
|
||||
/// \brief Retrieve the underlying type pointer, which refers to a
|
||||
/// canonical type.
|
||||
///
|
||||
/// The underlying pointer must not be NULL.
|
||||
/// The underlying pointer must not be nullptr.
|
||||
const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
|
||||
|
||||
/// \brief Retrieve the underlying type pointer, which refers to a
|
||||
/// canonical type, or NULL.
|
||||
///
|
||||
/// canonical type, or nullptr.
|
||||
const T *getTypePtrOrNull() const {
|
||||
return cast_or_null<T>(Stored.getTypePtrOrNull());
|
||||
}
|
||||
@ -125,9 +138,11 @@ public:
|
||||
bool isConstQualified() const {
|
||||
return Stored.isLocalConstQualified();
|
||||
}
|
||||
|
||||
bool isVolatileQualified() const {
|
||||
return Stored.isLocalVolatileQualified();
|
||||
}
|
||||
|
||||
bool isRestrictQualified() const {
|
||||
return Stored.isLocalRestrictQualified();
|
||||
}
|
||||
@ -195,7 +210,7 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) {
|
||||
}
|
||||
|
||||
/// \brief Represents a canonical, potentially-qualified type.
|
||||
typedef CanQual<Type> CanQualType;
|
||||
using CanQualType = CanQual<Type>;
|
||||
|
||||
inline CanQualType Type::getCanonicalTypeUnqualified() const {
|
||||
return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
|
||||
@ -320,7 +335,7 @@ public:
|
||||
/// than the more typical @c QualType, to propagate the notion of "canonical"
|
||||
/// through the system.
|
||||
template<typename T>
|
||||
struct CanProxyAdaptor : CanProxyBase<T> { };
|
||||
struct CanProxyAdaptor : CanProxyBase<T> {};
|
||||
|
||||
/// \brief Canonical proxy type returned when retrieving the members of a
|
||||
/// canonical type or as the result of the @c CanQual<T>::getAs member
|
||||
@ -333,7 +348,7 @@ template<typename T>
|
||||
class CanProxy : public CanProxyAdaptor<T> {
|
||||
public:
|
||||
/// \brief Build a NULL proxy.
|
||||
CanProxy() { }
|
||||
CanProxy() = default;
|
||||
|
||||
/// \brief Build a proxy to the given canonical type.
|
||||
CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
|
||||
@ -342,7 +357,7 @@ public:
|
||||
operator CanQual<T>() const { return this->Stored; }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -350,8 +365,9 @@ namespace llvm {
|
||||
/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
|
||||
/// to return smart pointer (proxies?).
|
||||
template<typename T>
|
||||
struct simplify_type< ::clang::CanQual<T> > {
|
||||
typedef const T *SimpleType;
|
||||
struct simplify_type< ::clang::CanQual<T>> {
|
||||
using SimpleType = const T *;
|
||||
|
||||
static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
|
||||
return Val.getTypePtr();
|
||||
}
|
||||
@ -359,19 +375,20 @@ struct simplify_type< ::clang::CanQual<T> > {
|
||||
|
||||
// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
|
||||
template<typename T>
|
||||
class PointerLikeTypeTraits<clang::CanQual<T> > {
|
||||
public:
|
||||
static inline void *getAsVoidPointer(clang::CanQual<T> P) {
|
||||
struct PointerLikeTypeTraits<clang::CanQual<T>> {
|
||||
static void *getAsVoidPointer(clang::CanQual<T> P) {
|
||||
return P.getAsOpaquePtr();
|
||||
}
|
||||
static inline clang::CanQual<T> getFromVoidPointer(void *P) {
|
||||
|
||||
static clang::CanQual<T> getFromVoidPointer(void *P) {
|
||||
return clang::CanQual<T>::getFromOpaquePtr(P);
|
||||
}
|
||||
|
||||
// qualifier information is encoded in the low bits.
|
||||
enum { NumLowBitsAvailable = 0 };
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
} // namespace llvm
|
||||
|
||||
namespace clang {
|
||||
|
||||
@ -389,7 +406,7 @@ struct CanTypeIterator
|
||||
CanQualType,
|
||||
typename std::iterator_traits<InputIterator>::difference_type,
|
||||
CanProxy<Type>, CanQualType> {
|
||||
CanTypeIterator() {}
|
||||
CanTypeIterator() = default;
|
||||
explicit CanTypeIterator(InputIterator Iter)
|
||||
: CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {}
|
||||
|
||||
@ -487,6 +504,7 @@ struct CanProxyAdaptor<FunctionProtoType>
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(
|
||||
ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos)
|
||||
|
||||
CanQualType getParamType(unsigned i) const {
|
||||
return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
|
||||
}
|
||||
@ -494,8 +512,8 @@ struct CanProxyAdaptor<FunctionProtoType>
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
|
||||
|
||||
typedef CanTypeIterator<FunctionProtoType::param_type_iterator>
|
||||
param_type_iterator;
|
||||
using param_type_iterator =
|
||||
CanTypeIterator<FunctionProtoType::param_type_iterator>;
|
||||
|
||||
param_type_iterator param_type_begin() const {
|
||||
return param_type_iterator(this->getTypePtr()->param_type_begin());
|
||||
@ -567,7 +585,8 @@ struct CanProxyAdaptor<ObjCObjectType>
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
|
||||
|
||||
typedef ObjCObjectPointerType::qual_iterator qual_iterator;
|
||||
using qual_iterator = ObjCObjectPointerType::qual_iterator;
|
||||
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
|
||||
@ -585,7 +604,8 @@ struct CanProxyAdaptor<ObjCObjectPointerType>
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
|
||||
|
||||
typedef ObjCObjectPointerType::qual_iterator qual_iterator;
|
||||
using qual_iterator = ObjCObjectPointerType::qual_iterator;
|
||||
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
|
||||
@ -662,7 +682,6 @@ CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const {
|
||||
return CanProxy<Type>(*this);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace clang
|
||||
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_CANONICALTYPE_H
|
||||
|
@ -40,14 +40,14 @@ namespace clang {
|
||||
typedef int64_t QuantityType;
|
||||
|
||||
private:
|
||||
QuantityType Quantity;
|
||||
QuantityType Quantity = 0;
|
||||
|
||||
explicit CharUnits(QuantityType C) : Quantity(C) {}
|
||||
|
||||
public:
|
||||
|
||||
/// CharUnits - A default constructor.
|
||||
CharUnits() : Quantity(0) {}
|
||||
CharUnits() = default;
|
||||
|
||||
/// Zero - Construct a CharUnits quantity of zero.
|
||||
static CharUnits Zero() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- CommentVisitor.h - Visitor for Comment subclasses ------*- C++ -*-===//
|
||||
//===- CommentVisitor.h - Visitor for Comment subclasses --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -16,8 +16,8 @@
|
||||
namespace clang {
|
||||
namespace comments {
|
||||
|
||||
template <typename T> struct make_ptr { typedef T *type; };
|
||||
template <typename T> struct make_const_ptr { typedef const T *type; };
|
||||
template <typename T> struct make_ptr { using type = T *; };
|
||||
template <typename T> struct make_const_ptr { using type = const T *; };
|
||||
|
||||
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
|
||||
class CommentVisitorBase {
|
||||
@ -64,7 +64,7 @@ template<typename ImplClass, typename RetTy=void>
|
||||
class ConstCommentVisitor :
|
||||
public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
|
||||
|
||||
} // end namespace comments
|
||||
} // end namespace clang
|
||||
} // namespace comments
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_COMMENTVISITOR_H
|
||||
|
65
contrib/llvm/tools/clang/include/clang/AST/DataCollection.h
Normal file
65
contrib/llvm/tools/clang/include/clang/AST/DataCollection.h
Normal file
@ -0,0 +1,65 @@
|
||||
//===--- DatatCollection.h --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \file
|
||||
/// \brief This file declares helper methods for collecting data from AST nodes.
|
||||
///
|
||||
/// To collect data from Stmt nodes, subclass ConstStmtVisitor and include
|
||||
/// StmtDataCollectors.inc after defining the macros that you need. This
|
||||
/// provides data collection implementations for most Stmt kinds. Note
|
||||
/// that that code requires some conditions to be met:
|
||||
///
|
||||
/// - There must be a method addData(const T &Data) that accepts strings,
|
||||
/// integral types as well as QualType. All data is forwarded using
|
||||
/// to this method.
|
||||
/// - The ASTContext of the Stmt must be accessible by the name Context.
|
||||
///
|
||||
/// It is also possible to override individual visit methods. Have a look at
|
||||
/// the DataCollector in lib/Analysis/CloneDetection.cpp for a usage example.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_DATACOLLECTION_H
|
||||
#define LLVM_CLANG_AST_DATACOLLECTION_H
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
|
||||
namespace clang {
|
||||
namespace data_collection {
|
||||
|
||||
/// Returns a string that represents all macro expansions that expanded into the
|
||||
/// given SourceLocation.
|
||||
///
|
||||
/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
|
||||
/// A and B are expanded from the same macros in the same order.
|
||||
std::string getMacroStack(SourceLocation Loc, ASTContext &Context);
|
||||
|
||||
/// Utility functions for implementing addData() for a consumer that has a
|
||||
/// method update(StringRef)
|
||||
template <class T>
|
||||
void addDataToConsumer(T &DataConsumer, llvm::StringRef Str) {
|
||||
DataConsumer.update(Str);
|
||||
}
|
||||
|
||||
template <class T> void addDataToConsumer(T &DataConsumer, const QualType &QT) {
|
||||
addDataToConsumer(DataConsumer, QT.getAsString());
|
||||
}
|
||||
|
||||
template <class T, class Type>
|
||||
typename std::enable_if<
|
||||
std::is_integral<Type>::value || std::is_enum<Type>::value ||
|
||||
std::is_convertible<Type, size_t>::value // for llvm::hash_code
|
||||
>::type
|
||||
addDataToConsumer(T &DataConsumer, Type Data) {
|
||||
DataConsumer.update(StringRef(reinterpret_cast<char *>(&Data), sizeof(Data)));
|
||||
}
|
||||
|
||||
} // end namespace data_collection
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_DATACOLLECTION_H
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
//===-- DeclBase.h - Base Classes for representing declarations -*- C++ -*-===//
|
||||
//===- DeclBase.h - Base Classes for representing declarations --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -16,33 +16,40 @@
|
||||
|
||||
#include "clang/AST/AttrIterator.h"
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include "clang/Basic/VersionTuple.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/iterator.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class ASTMutationListener;
|
||||
class BlockDecl;
|
||||
class CXXRecordDecl;
|
||||
class CompoundStmt;
|
||||
class Attr;
|
||||
class DeclContext;
|
||||
class DeclarationName;
|
||||
class DependentDiagnostic;
|
||||
class EnumDecl;
|
||||
class ExportDecl;
|
||||
class ExternalSourceSymbolAttr;
|
||||
class FunctionDecl;
|
||||
class FunctionType;
|
||||
class IdentifierInfo;
|
||||
enum Linkage : unsigned char;
|
||||
class LinkageComputer;
|
||||
class LinkageSpecDecl;
|
||||
class Module;
|
||||
class NamedDecl;
|
||||
class NamespaceDecl;
|
||||
class ObjCCategoryDecl;
|
||||
class ObjCCategoryImplDecl;
|
||||
class ObjCContainerDecl;
|
||||
@ -53,23 +60,21 @@ class ObjCMethodDecl;
|
||||
class ObjCProtocolDecl;
|
||||
struct PrintingPolicy;
|
||||
class RecordDecl;
|
||||
class SourceManager;
|
||||
class Stmt;
|
||||
class StoredDeclsMap;
|
||||
class TemplateDecl;
|
||||
class TranslationUnitDecl;
|
||||
class UsingDirectiveDecl;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// \brief Captures the result of checking the availability of a
|
||||
/// declaration.
|
||||
enum AvailabilityResult {
|
||||
AR_Available = 0,
|
||||
AR_NotYetIntroduced,
|
||||
AR_Deprecated,
|
||||
AR_Unavailable
|
||||
};
|
||||
/// \brief Captures the result of checking the availability of a
|
||||
/// declaration.
|
||||
enum AvailabilityResult {
|
||||
AR_Available = 0,
|
||||
AR_NotYetIntroduced,
|
||||
AR_Deprecated,
|
||||
AR_Unavailable
|
||||
};
|
||||
|
||||
/// Decl - This represents one declaration (or definition), e.g. a variable,
|
||||
/// typedef, function, struct, etc.
|
||||
@ -94,7 +99,7 @@ public:
|
||||
/// \brief A placeholder type used to construct an empty shell of a
|
||||
/// decl-derived type that will be filled in later (e.g., by some
|
||||
/// deserialization method).
|
||||
struct EmptyShell { };
|
||||
struct EmptyShell {};
|
||||
|
||||
/// IdentifierNamespace - The different namespaces in which
|
||||
/// declarations may appear. According to C99 6.2.3, there are
|
||||
@ -208,15 +213,18 @@ public:
|
||||
enum class ModuleOwnershipKind : unsigned {
|
||||
/// This declaration is not owned by a module.
|
||||
Unowned,
|
||||
|
||||
/// This declaration has an owning module, but is globally visible
|
||||
/// (typically because its owning module is visible and we know that
|
||||
/// modules cannot later become hidden in this compilation).
|
||||
/// After serialization and deserialization, this will be converted
|
||||
/// to VisibleWhenImported.
|
||||
Visible,
|
||||
|
||||
/// This declaration has an owning module, and is visible when that
|
||||
/// module is imported.
|
||||
VisibleWhenImported,
|
||||
|
||||
/// This declaration has an owning module, but is only visible to
|
||||
/// lookups that occur within that module.
|
||||
ModulePrivate
|
||||
@ -238,7 +246,6 @@ private:
|
||||
DeclContext *LexicalDC;
|
||||
};
|
||||
|
||||
|
||||
/// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
|
||||
/// For declarations that don't contain C++ scope specifiers, it contains
|
||||
/// the DeclContext where the Decl was declared.
|
||||
@ -254,12 +261,14 @@ private:
|
||||
/// // LexicalDC == global namespace
|
||||
llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
|
||||
|
||||
inline bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
|
||||
inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
|
||||
inline MultipleDC *getMultipleDC() const {
|
||||
bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
|
||||
bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
|
||||
|
||||
MultipleDC *getMultipleDC() const {
|
||||
return DeclCtx.get<MultipleDC*>();
|
||||
}
|
||||
inline DeclContext *getSemanticDC() const {
|
||||
|
||||
DeclContext *getSemanticDC() const {
|
||||
return DeclCtx.get<DeclContext*>();
|
||||
}
|
||||
|
||||
@ -298,10 +307,16 @@ private:
|
||||
static bool StatisticsEnabled;
|
||||
|
||||
protected:
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
friend class ASTReader;
|
||||
friend class CXXClassMemberWrapper;
|
||||
friend class LinkageComputer;
|
||||
template<typename decl_type> friend class Redeclarable;
|
||||
|
||||
/// Access - Used by C++ decls for the access specifier.
|
||||
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
|
||||
unsigned Access : 2;
|
||||
friend class CXXClassMemberWrapper;
|
||||
|
||||
/// \brief Whether this declaration was loaded from an AST file.
|
||||
unsigned FromASTFile : 1;
|
||||
@ -313,13 +328,6 @@ protected:
|
||||
/// Otherwise, it is the linkage + 1.
|
||||
mutable unsigned CacheValidAndLinkage : 3;
|
||||
|
||||
friend class ASTDeclWriter;
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTReader;
|
||||
friend class LinkageComputer;
|
||||
|
||||
template<typename decl_type> friend class Redeclarable;
|
||||
|
||||
/// \brief Allocate memory for a deserialized declaration.
|
||||
///
|
||||
/// This routine must be used to allocate memory for any declaration that is
|
||||
@ -357,7 +365,7 @@ private:
|
||||
protected:
|
||||
Decl(Kind DK, DeclContext *DC, SourceLocation L)
|
||||
: NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)),
|
||||
DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(0), HasAttrs(false),
|
||||
DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false),
|
||||
Implicit(false), Used(false), Referenced(false),
|
||||
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
|
||||
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
|
||||
@ -366,9 +374,9 @@ protected:
|
||||
}
|
||||
|
||||
Decl(Kind DK, EmptyShell Empty)
|
||||
: NextInContextAndBits(), DeclKind(DK), InvalidDecl(0), HasAttrs(false),
|
||||
Implicit(false), Used(false), Referenced(false),
|
||||
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
|
||||
: DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false),
|
||||
Used(false), Referenced(false), TopLevelDeclInObjCContainer(false),
|
||||
Access(AS_none), FromASTFile(0),
|
||||
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
|
||||
CacheValidAndLinkage(0) {
|
||||
if (StatisticsEnabled) add(DK);
|
||||
@ -392,14 +400,15 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Source range that this declaration covers.
|
||||
virtual SourceRange getSourceRange() const LLVM_READONLY {
|
||||
return SourceRange(getLocation(), getLocation());
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY {
|
||||
return getSourceRange().getBegin();
|
||||
}
|
||||
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return getSourceRange().getEnd();
|
||||
}
|
||||
@ -460,12 +469,15 @@ public:
|
||||
}
|
||||
|
||||
bool hasAttrs() const { return HasAttrs; }
|
||||
|
||||
void setAttrs(const AttrVec& Attrs) {
|
||||
return setAttrsImpl(Attrs, getASTContext());
|
||||
}
|
||||
|
||||
AttrVec &getAttrs() {
|
||||
return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
|
||||
}
|
||||
|
||||
const AttrVec &getAttrs() const;
|
||||
void dropAttrs();
|
||||
|
||||
@ -476,8 +488,8 @@ public:
|
||||
setAttrs(AttrVec(1, A));
|
||||
}
|
||||
|
||||
typedef AttrVec::const_iterator attr_iterator;
|
||||
typedef llvm::iterator_range<attr_iterator> attr_range;
|
||||
using attr_iterator = AttrVec::const_iterator;
|
||||
using attr_range = llvm::iterator_range<attr_iterator>;
|
||||
|
||||
attr_range attrs() const {
|
||||
return attr_range(attr_begin(), attr_end());
|
||||
@ -510,6 +522,7 @@ public:
|
||||
specific_attr_iterator<T> specific_attr_begin() const {
|
||||
return specific_attr_iterator<T>(attr_begin());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
specific_attr_iterator<T> specific_attr_end() const {
|
||||
return specific_attr_iterator<T>(attr_end());
|
||||
@ -518,6 +531,7 @@ public:
|
||||
template<typename T> T *getAttr() const {
|
||||
return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr;
|
||||
}
|
||||
|
||||
template<typename T> bool hasAttr() const {
|
||||
return hasAttrs() && hasSpecificAttr<T>(getAttrs());
|
||||
}
|
||||
@ -616,7 +630,6 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Determine the availability of the given declaration.
|
||||
///
|
||||
/// This routine will determine the most restrictive availability of
|
||||
@ -698,6 +711,7 @@ public:
|
||||
|
||||
private:
|
||||
Module *getOwningModuleSlow() const;
|
||||
|
||||
protected:
|
||||
bool hasLocalOwningModuleStorage() const;
|
||||
|
||||
@ -733,11 +747,18 @@ public:
|
||||
return getModuleOwnershipKind() != ModuleOwnershipKind::Unowned;
|
||||
}
|
||||
|
||||
/// Get the module that owns this declaration.
|
||||
/// Get the module that owns this declaration (for visibility purposes).
|
||||
Module *getOwningModule() const {
|
||||
return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule();
|
||||
}
|
||||
|
||||
/// Get the module that owns this declaration for linkage purposes.
|
||||
/// There only ever is such a module under the C++ Modules TS.
|
||||
///
|
||||
/// \param IgnoreLinkage Ignore the linkage of the entity; assume that
|
||||
/// all declarations in a global module fragment are unowned.
|
||||
Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const;
|
||||
|
||||
/// \brief Determine whether this declaration might be hidden from name
|
||||
/// lookup. Note that the declaration might be visible even if this returns
|
||||
/// \c false, if the owning module is visible within the query context.
|
||||
@ -770,14 +791,17 @@ public:
|
||||
unsigned getIdentifierNamespace() const {
|
||||
return IdentifierNamespace;
|
||||
}
|
||||
|
||||
bool isInIdentifierNamespace(unsigned NS) const {
|
||||
return getIdentifierNamespace() & NS;
|
||||
}
|
||||
|
||||
static unsigned getIdentifierNamespaceForKind(Kind DK);
|
||||
|
||||
bool hasTagIdentifierNamespace() const {
|
||||
return isTagIdentifierNamespace(getIdentifierNamespace());
|
||||
}
|
||||
|
||||
static bool isTagIdentifierNamespace(unsigned NS) {
|
||||
// TagDecls have Tag and Type set and may also have TagFriend.
|
||||
return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type);
|
||||
@ -865,18 +889,18 @@ public:
|
||||
/// \brief Iterates through all the redeclarations of the same decl.
|
||||
class redecl_iterator {
|
||||
/// Current - The current declaration.
|
||||
Decl *Current;
|
||||
Decl *Current = nullptr;
|
||||
Decl *Starter;
|
||||
|
||||
public:
|
||||
typedef Decl *value_type;
|
||||
typedef const value_type &reference;
|
||||
typedef const value_type *pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
using value_type = Decl *;
|
||||
using reference = const value_type &;
|
||||
using pointer = const value_type *;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
redecl_iterator() : Current(nullptr) { }
|
||||
explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
|
||||
redecl_iterator() = default;
|
||||
explicit redecl_iterator(Decl *C) : Current(C), Starter(C) {}
|
||||
|
||||
reference operator*() const { return Current; }
|
||||
value_type operator->() const { return Current; }
|
||||
@ -899,12 +923,13 @@ public:
|
||||
friend bool operator==(redecl_iterator x, redecl_iterator y) {
|
||||
return x.Current == y.Current;
|
||||
}
|
||||
|
||||
friend bool operator!=(redecl_iterator x, redecl_iterator y) {
|
||||
return x.Current != y.Current;
|
||||
}
|
||||
};
|
||||
|
||||
typedef llvm::iterator_range<redecl_iterator> redecl_range;
|
||||
using redecl_range = llvm::iterator_range<redecl_iterator>;
|
||||
|
||||
/// \brief Returns an iterator range for all the redeclarations of the same
|
||||
/// decl. It will iterate at least once (when this decl is the only one).
|
||||
@ -915,6 +940,7 @@ public:
|
||||
redecl_iterator redecls_begin() const {
|
||||
return redecl_iterator(const_cast<Decl *>(this));
|
||||
}
|
||||
|
||||
redecl_iterator redecls_end() const { return redecl_iterator(); }
|
||||
|
||||
/// \brief Retrieve the previous declaration that declares the same entity
|
||||
@ -1002,13 +1028,15 @@ public:
|
||||
/// declaration, but in the semantic context of the enclosing namespace
|
||||
/// scope.
|
||||
void setLocalExternDecl() {
|
||||
assert((IdentifierNamespace == IDNS_Ordinary ||
|
||||
IdentifierNamespace == IDNS_OrdinaryFriend) &&
|
||||
"namespace is not ordinary");
|
||||
|
||||
Decl *Prev = getPreviousDecl();
|
||||
IdentifierNamespace &= ~IDNS_Ordinary;
|
||||
|
||||
// It's OK for the declaration to still have the "invisible friend" flag or
|
||||
// the "conflicts with tag declarations in this scope" flag for the outer
|
||||
// scope.
|
||||
assert((IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 &&
|
||||
"namespace is not ordinary");
|
||||
|
||||
IdentifierNamespace |= IDNS_LocalExtern;
|
||||
if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)
|
||||
IdentifierNamespace |= IDNS_Ordinary;
|
||||
@ -1094,10 +1122,13 @@ public:
|
||||
static void printGroup(Decl** Begin, unsigned NumDecls,
|
||||
raw_ostream &Out, const PrintingPolicy &Policy,
|
||||
unsigned Indentation = 0);
|
||||
|
||||
// Debuggers don't usually respect default arguments.
|
||||
void dump() const;
|
||||
|
||||
// Same as dump(), but forces color printing.
|
||||
void dumpColor() const;
|
||||
|
||||
void dump(raw_ostream &Out, bool Deserialize = false) const;
|
||||
|
||||
/// \brief Looks through the Decl's underlying type to extract a FunctionType
|
||||
@ -1132,10 +1163,11 @@ class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
|
||||
SourceLocation Loc;
|
||||
SourceManager &SM;
|
||||
const char *Message;
|
||||
|
||||
public:
|
||||
PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
|
||||
SourceManager &sm, const char *Msg)
|
||||
: TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
|
||||
: TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
|
||||
|
||||
void print(raw_ostream &OS) const override;
|
||||
};
|
||||
@ -1144,30 +1176,35 @@ public:
|
||||
/// single result (with no stable storage) or a collection of results (with
|
||||
/// stable storage provided by the lookup table).
|
||||
class DeclContextLookupResult {
|
||||
typedef ArrayRef<NamedDecl *> ResultTy;
|
||||
using ResultTy = ArrayRef<NamedDecl *>;
|
||||
|
||||
ResultTy Result;
|
||||
|
||||
// If there is only one lookup result, it would be invalidated by
|
||||
// reallocations of the name table, so store it separately.
|
||||
NamedDecl *Single;
|
||||
NamedDecl *Single = nullptr;
|
||||
|
||||
static NamedDecl *const SingleElementDummyList;
|
||||
|
||||
public:
|
||||
DeclContextLookupResult() : Result(), Single() {}
|
||||
DeclContextLookupResult() = default;
|
||||
DeclContextLookupResult(ArrayRef<NamedDecl *> Result)
|
||||
: Result(Result), Single() {}
|
||||
: Result(Result) {}
|
||||
DeclContextLookupResult(NamedDecl *Single)
|
||||
: Result(SingleElementDummyList), Single(Single) {}
|
||||
|
||||
class iterator;
|
||||
typedef llvm::iterator_adaptor_base<iterator, ResultTy::iterator,
|
||||
std::random_access_iterator_tag,
|
||||
NamedDecl *const> IteratorBase;
|
||||
|
||||
using IteratorBase =
|
||||
llvm::iterator_adaptor_base<iterator, ResultTy::iterator,
|
||||
std::random_access_iterator_tag,
|
||||
NamedDecl *const>;
|
||||
|
||||
class iterator : public IteratorBase {
|
||||
value_type SingleElement;
|
||||
|
||||
public:
|
||||
iterator() : IteratorBase(), SingleElement() {}
|
||||
iterator() = default;
|
||||
explicit iterator(pointer Pos, value_type Single = nullptr)
|
||||
: IteratorBase(Pos), SingleElement(Single) {}
|
||||
|
||||
@ -1175,9 +1212,10 @@ public:
|
||||
return SingleElement ? SingleElement : IteratorBase::operator*();
|
||||
}
|
||||
};
|
||||
typedef iterator const_iterator;
|
||||
typedef iterator::pointer pointer;
|
||||
typedef iterator::reference reference;
|
||||
|
||||
using const_iterator = iterator;
|
||||
using pointer = iterator::pointer;
|
||||
using reference = iterator::reference;
|
||||
|
||||
iterator begin() const { return iterator(Result.begin(), Single); }
|
||||
iterator end() const { return iterator(Result.end(), Single); }
|
||||
@ -1211,7 +1249,6 @@ public:
|
||||
/// ExportDecl
|
||||
/// BlockDecl
|
||||
/// OMPDeclareReductionDecl
|
||||
///
|
||||
class DeclContext {
|
||||
/// DeclKind - This indicates which class this is.
|
||||
unsigned DeclKind : 8;
|
||||
@ -1251,22 +1288,22 @@ class DeclContext {
|
||||
/// contains an entry for a DeclarationName (and we haven't lazily
|
||||
/// omitted anything), then it contains all relevant entries for that
|
||||
/// name (modulo the hasExternalDecls() flag).
|
||||
mutable StoredDeclsMap *LookupPtr;
|
||||
mutable StoredDeclsMap *LookupPtr = nullptr;
|
||||
|
||||
protected:
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTWriter;
|
||||
friend class ExternalASTSource;
|
||||
|
||||
/// FirstDecl - The first declaration stored within this declaration
|
||||
/// context.
|
||||
mutable Decl *FirstDecl;
|
||||
mutable Decl *FirstDecl = nullptr;
|
||||
|
||||
/// LastDecl - The last declaration stored within this declaration
|
||||
/// context. FIXME: We could probably cache this value somewhere
|
||||
/// outside of the DeclContext, to reduce the size of DeclContext by
|
||||
/// another pointer.
|
||||
mutable Decl *LastDecl;
|
||||
|
||||
friend class ExternalASTSource;
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTWriter;
|
||||
mutable Decl *LastDecl = nullptr;
|
||||
|
||||
/// \brief Build up a chain of declarations.
|
||||
///
|
||||
@ -1279,8 +1316,7 @@ protected:
|
||||
ExternalVisibleStorage(false),
|
||||
NeedToReconcileExternalVisibleStorage(false),
|
||||
HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false),
|
||||
UseQualifiedLookup(false),
|
||||
LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {}
|
||||
UseQualifiedLookup(false) {}
|
||||
|
||||
public:
|
||||
~DeclContext();
|
||||
@ -1288,6 +1324,7 @@ public:
|
||||
Decl::Kind getDeclKind() const {
|
||||
return static_cast<Decl::Kind>(DeclKind);
|
||||
}
|
||||
|
||||
const char *getDeclKindName() const;
|
||||
|
||||
/// getParent - Returns the containing DeclContext.
|
||||
@ -1495,19 +1532,20 @@ public:
|
||||
/// within this context.
|
||||
class decl_iterator {
|
||||
/// Current - The current declaration.
|
||||
Decl *Current;
|
||||
Decl *Current = nullptr;
|
||||
|
||||
public:
|
||||
typedef Decl *value_type;
|
||||
typedef const value_type &reference;
|
||||
typedef const value_type *pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
using value_type = Decl *;
|
||||
using reference = const value_type &;
|
||||
using pointer = const value_type *;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
decl_iterator() : Current(nullptr) { }
|
||||
explicit decl_iterator(Decl *C) : Current(C) { }
|
||||
decl_iterator() = default;
|
||||
explicit decl_iterator(Decl *C) : Current(C) {}
|
||||
|
||||
reference operator*() const { return Current; }
|
||||
|
||||
// This doesn't meet the iterator requirements, but it's convenient
|
||||
value_type operator->() const { return Current; }
|
||||
|
||||
@ -1525,12 +1563,13 @@ public:
|
||||
friend bool operator==(decl_iterator x, decl_iterator y) {
|
||||
return x.Current == y.Current;
|
||||
}
|
||||
|
||||
friend bool operator!=(decl_iterator x, decl_iterator y) {
|
||||
return x.Current != y.Current;
|
||||
}
|
||||
};
|
||||
|
||||
typedef llvm::iterator_range<decl_iterator> decl_range;
|
||||
using decl_range = llvm::iterator_range<decl_iterator>;
|
||||
|
||||
/// decls_begin/decls_end - Iterate over the declarations stored in
|
||||
/// this context.
|
||||
@ -1569,16 +1608,16 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
typedef SpecificDecl *value_type;
|
||||
// TODO: Add reference and pointer typedefs (with some appropriate proxy
|
||||
// type) if we ever have a need for them.
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
|
||||
difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
using value_type = SpecificDecl *;
|
||||
// TODO: Add reference and pointer types (with some appropriate proxy type)
|
||||
// if we ever have a need for them.
|
||||
using reference = void;
|
||||
using pointer = void;
|
||||
using difference_type =
|
||||
std::iterator_traits<DeclContext::decl_iterator>::difference_type;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
specific_decl_iterator() : Current() { }
|
||||
specific_decl_iterator() = default;
|
||||
|
||||
/// specific_decl_iterator - Construct a new iterator over a
|
||||
/// subset of the declarations the range [C,
|
||||
@ -1593,6 +1632,7 @@ public:
|
||||
}
|
||||
|
||||
value_type operator*() const { return cast<SpecificDecl>(*Current); }
|
||||
|
||||
// This doesn't meet the iterator requirements, but it's convenient
|
||||
value_type operator->() const { return **this; }
|
||||
|
||||
@ -1646,16 +1686,16 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
typedef SpecificDecl *value_type;
|
||||
// TODO: Add reference and pointer typedefs (with some appropriate proxy
|
||||
// type) if we ever have a need for them.
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
|
||||
difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
using value_type = SpecificDecl *;
|
||||
// TODO: Add reference and pointer types (with some appropriate proxy type)
|
||||
// if we ever have a need for them.
|
||||
using reference = void;
|
||||
using pointer = void;
|
||||
using difference_type =
|
||||
std::iterator_traits<DeclContext::decl_iterator>::difference_type;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
filtered_decl_iterator() : Current() { }
|
||||
filtered_decl_iterator() = default;
|
||||
|
||||
/// filtered_decl_iterator - Construct a new iterator over a
|
||||
/// subset of the declarations the range [C,
|
||||
@ -1733,8 +1773,8 @@ public:
|
||||
/// @brief Checks whether a declaration is in this context.
|
||||
bool containsDecl(Decl *D) const;
|
||||
|
||||
typedef DeclContextLookupResult lookup_result;
|
||||
typedef lookup_result::iterator lookup_iterator;
|
||||
using lookup_result = DeclContextLookupResult;
|
||||
using lookup_iterator = lookup_result::iterator;
|
||||
|
||||
/// lookup - Find the declarations (if any) with the given Name in
|
||||
/// this context. Returns a range of iterators that contains all of
|
||||
@ -1780,7 +1820,7 @@ public:
|
||||
/// of looking up every possible name.
|
||||
class all_lookups_iterator;
|
||||
|
||||
typedef llvm::iterator_range<all_lookups_iterator> lookups_range;
|
||||
using lookups_range = llvm::iterator_range<all_lookups_iterator>;
|
||||
|
||||
lookups_range lookups() const;
|
||||
lookups_range noload_lookups() const;
|
||||
@ -1796,21 +1836,26 @@ public:
|
||||
all_lookups_iterator noload_lookups_end() const;
|
||||
|
||||
struct udir_iterator;
|
||||
typedef llvm::iterator_adaptor_base<udir_iterator, lookup_iterator,
|
||||
std::random_access_iterator_tag,
|
||||
UsingDirectiveDecl *> udir_iterator_base;
|
||||
|
||||
using udir_iterator_base =
|
||||
llvm::iterator_adaptor_base<udir_iterator, lookup_iterator,
|
||||
std::random_access_iterator_tag,
|
||||
UsingDirectiveDecl *>;
|
||||
|
||||
struct udir_iterator : udir_iterator_base {
|
||||
udir_iterator(lookup_iterator I) : udir_iterator_base(I) {}
|
||||
|
||||
UsingDirectiveDecl *operator*() const;
|
||||
};
|
||||
|
||||
typedef llvm::iterator_range<udir_iterator> udir_range;
|
||||
using udir_range = llvm::iterator_range<udir_iterator>;
|
||||
|
||||
udir_range using_directives() const;
|
||||
|
||||
// These are all defined in DependentDiagnostic.h.
|
||||
class ddiag_iterator;
|
||||
typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range;
|
||||
|
||||
using ddiag_range = llvm::iterator_range<DeclContext::ddiag_iterator>;
|
||||
|
||||
inline ddiag_range ddiags() const;
|
||||
|
||||
@ -1883,6 +1928,8 @@ public:
|
||||
bool Deserialize = false) const;
|
||||
|
||||
private:
|
||||
friend class DependentDiagnostic;
|
||||
|
||||
void reconcileExternalVisibleStorage() const;
|
||||
bool LoadLexicalDeclsFromExternalStorage() const;
|
||||
|
||||
@ -1894,7 +1941,6 @@ private:
|
||||
/// use of addDeclInternal().
|
||||
void makeDeclVisibleInContextInternal(NamedDecl *D);
|
||||
|
||||
friend class DependentDiagnostic;
|
||||
StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
|
||||
|
||||
void buildLookupImpl(DeclContext *DCtx, bool Internal);
|
||||
@ -1933,8 +1979,7 @@ struct cast_convert_decl_context<ToTy, true> {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // end clang.
|
||||
} // namespace clang
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -1954,12 +1999,14 @@ struct cast_convert_val<ToTy,
|
||||
return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ToTy>
|
||||
struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
|
||||
static ToTy &doit(::clang::DeclContext &Val) {
|
||||
return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ToTy>
|
||||
struct cast_convert_val<ToTy,
|
||||
const ::clang::DeclContext*, const ::clang::DeclContext*> {
|
||||
@ -1967,6 +2014,7 @@ struct cast_convert_val<ToTy,
|
||||
return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ToTy>
|
||||
struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
|
||||
static ToTy *doit(::clang::DeclContext *Val) {
|
||||
@ -2003,6 +2051,6 @@ struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_DECLBASE_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
//===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===//
|
||||
//===- DeclContextInternals.h - DeclContext Representation ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -11,10 +11,12 @@
|
||||
// of DeclContext.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
|
||||
#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
@ -22,6 +24,7 @@
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
namespace clang {
|
||||
|
||||
@ -30,21 +33,20 @@ class DependentDiagnostic;
|
||||
/// \brief An array of decls optimized for the common case of only containing
|
||||
/// one entry.
|
||||
struct StoredDeclsList {
|
||||
|
||||
/// \brief When in vector form, this is what the Data pointer points to.
|
||||
typedef SmallVector<NamedDecl *, 4> DeclsTy;
|
||||
using DeclsTy = SmallVector<NamedDecl *, 4>;
|
||||
|
||||
/// \brief A collection of declarations, with a flag to indicate if we have
|
||||
/// further external declarations.
|
||||
typedef llvm::PointerIntPair<DeclsTy *, 1, bool> DeclsAndHasExternalTy;
|
||||
using DeclsAndHasExternalTy = llvm::PointerIntPair<DeclsTy *, 1, bool>;
|
||||
|
||||
/// \brief The stored data, which will be either a pointer to a NamedDecl,
|
||||
/// or a pointer to a vector with a flag to indicate if there are further
|
||||
/// external declarations.
|
||||
llvm::PointerUnion<NamedDecl*, DeclsAndHasExternalTy> Data;
|
||||
llvm::PointerUnion<NamedDecl *, DeclsAndHasExternalTy> Data;
|
||||
|
||||
public:
|
||||
StoredDeclsList() {}
|
||||
StoredDeclsList() = default;
|
||||
|
||||
StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
|
||||
RHS.Data = (NamedDecl *)nullptr;
|
||||
@ -186,7 +188,6 @@ public:
|
||||
|
||||
/// AddSubsequentDecl - This is called on the second and later decl when it is
|
||||
/// not a redeclaration to merge it into the appropriate place in our list.
|
||||
///
|
||||
void AddSubsequentDecl(NamedDecl *D) {
|
||||
assert(!isNull() && "don't AddSubsequentDecl when we have no decls");
|
||||
|
||||
@ -237,28 +238,28 @@ public:
|
||||
};
|
||||
|
||||
class StoredDeclsMap
|
||||
: public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
|
||||
|
||||
: public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
|
||||
public:
|
||||
static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
|
||||
|
||||
private:
|
||||
friend class ASTContext; // walks the chain deleting these
|
||||
friend class DeclContext;
|
||||
|
||||
llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
|
||||
};
|
||||
|
||||
class DependentStoredDeclsMap : public StoredDeclsMap {
|
||||
public:
|
||||
DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {}
|
||||
DependentStoredDeclsMap() = default;
|
||||
|
||||
private:
|
||||
friend class DependentDiagnostic;
|
||||
friend class DeclContext; // iterates over diagnostics
|
||||
friend class DependentDiagnostic;
|
||||
|
||||
DependentDiagnostic *FirstDiagnostic;
|
||||
DependentDiagnostic *FirstDiagnostic = nullptr;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- DeclFriend.h - Classes for C++ friend declarations -*- C++ -*------===//
|
||||
//===- DeclFriend.h - Classes for C++ friend declarations -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -15,16 +15,30 @@
|
||||
#ifndef LLVM_CLANG_AST_DECLFRIEND_H
|
||||
#define LLVM_CLANG_AST_DECLFRIEND_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/TrailingObjects.h"
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
|
||||
/// FriendDecl - Represents the declaration of a friend entity,
|
||||
/// which can be a function, a type, or a templated function or type.
|
||||
// For example:
|
||||
/// For example:
|
||||
///
|
||||
/// @code
|
||||
/// template <typename T> class A {
|
||||
@ -41,10 +55,14 @@ class FriendDecl final
|
||||
: public Decl,
|
||||
private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> {
|
||||
virtual void anchor();
|
||||
|
||||
public:
|
||||
typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
|
||||
using FriendUnion = llvm::PointerUnion<NamedDecl *, TypeSourceInfo *>;
|
||||
|
||||
private:
|
||||
friend class CXXRecordDecl;
|
||||
friend class CXXRecordDecl::friend_iterator;
|
||||
|
||||
// The declaration that's a friend of this class.
|
||||
FriendUnion Friend;
|
||||
|
||||
@ -64,35 +82,33 @@ private:
|
||||
// template <class T> friend class A<T>::B;
|
||||
unsigned NumTPLists : 31;
|
||||
|
||||
friend class CXXRecordDecl::friend_iterator;
|
||||
friend class CXXRecordDecl;
|
||||
|
||||
FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
|
||||
SourceLocation FriendL,
|
||||
ArrayRef<TemplateParameterList*> FriendTypeTPLists)
|
||||
: Decl(Decl::Friend, DC, L),
|
||||
Friend(Friend),
|
||||
NextFriend(),
|
||||
FriendLoc(FriendL),
|
||||
UnsupportedFriend(false),
|
||||
NumTPLists(FriendTypeTPLists.size()) {
|
||||
ArrayRef<TemplateParameterList *> FriendTypeTPLists)
|
||||
: Decl(Decl::Friend, DC, L), Friend(Friend), FriendLoc(FriendL),
|
||||
UnsupportedFriend(false), NumTPLists(FriendTypeTPLists.size()) {
|
||||
for (unsigned i = 0; i < NumTPLists; ++i)
|
||||
getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i];
|
||||
}
|
||||
|
||||
FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
|
||||
: Decl(Decl::Friend, Empty), NextFriend(),
|
||||
UnsupportedFriend(false),
|
||||
NumTPLists(NumFriendTypeTPLists) { }
|
||||
: Decl(Decl::Friend, Empty), UnsupportedFriend(false),
|
||||
NumTPLists(NumFriendTypeTPLists) {}
|
||||
|
||||
FriendDecl *getNextFriend() {
|
||||
if (!NextFriend.isOffset())
|
||||
return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
|
||||
return getNextFriendSlowCase();
|
||||
}
|
||||
|
||||
FriendDecl *getNextFriendSlowCase();
|
||||
|
||||
public:
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
friend class ASTNodeImporter;
|
||||
friend TrailingObjects;
|
||||
|
||||
static FriendDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L, FriendUnion Friend_,
|
||||
SourceLocation FriendL,
|
||||
@ -108,9 +124,11 @@ public:
|
||||
TypeSourceInfo *getFriendType() const {
|
||||
return Friend.dyn_cast<TypeSourceInfo*>();
|
||||
}
|
||||
|
||||
unsigned getFriendTypeNumTemplateParameterLists() const {
|
||||
return NumTPLists;
|
||||
}
|
||||
|
||||
TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
|
||||
assert(N < NumTPLists);
|
||||
return getTrailingObjects<TemplateParameterList *>()[N];
|
||||
@ -119,7 +137,7 @@ public:
|
||||
/// If this friend declaration doesn't name a type, return the inner
|
||||
/// declaration.
|
||||
NamedDecl *getFriendDecl() const {
|
||||
return Friend.dyn_cast<NamedDecl*>();
|
||||
return Friend.dyn_cast<NamedDecl *>();
|
||||
}
|
||||
|
||||
/// Retrieves the location of the 'friend' keyword.
|
||||
@ -164,27 +182,24 @@ public:
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == Decl::Friend; }
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
friend class ASTNodeImporter;
|
||||
friend TrailingObjects;
|
||||
};
|
||||
|
||||
/// An iterator over the friend declarations of a class.
|
||||
class CXXRecordDecl::friend_iterator {
|
||||
friend class CXXRecordDecl;
|
||||
|
||||
FriendDecl *Ptr;
|
||||
|
||||
friend class CXXRecordDecl;
|
||||
explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {}
|
||||
public:
|
||||
friend_iterator() {}
|
||||
|
||||
typedef FriendDecl *value_type;
|
||||
typedef FriendDecl *reference;
|
||||
typedef FriendDecl *pointer;
|
||||
typedef int difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
public:
|
||||
friend_iterator() = default;
|
||||
|
||||
using value_type = FriendDecl *;
|
||||
using reference = FriendDecl *;
|
||||
using pointer = FriendDecl *;
|
||||
using difference_type = int;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
reference operator*() const { return Ptr; }
|
||||
|
||||
@ -240,6 +255,6 @@ inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
|
||||
data().FirstFriend = FD;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_DECLFRIEND_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===//
|
||||
//===- DeclGroup.h - Classes for representing groups of Decls ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -14,26 +14,26 @@
|
||||
#ifndef LLVM_CLANG_AST_DECLGROUP_H
|
||||
#define LLVM_CLANG_AST_DECLGROUP_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/TrailingObjects.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class Decl;
|
||||
class DeclGroup;
|
||||
class DeclGroupIterator;
|
||||
|
||||
class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> {
|
||||
// FIXME: Include a TypeSpecifier object.
|
||||
unsigned NumDecls;
|
||||
unsigned NumDecls = 0;
|
||||
|
||||
private:
|
||||
DeclGroup() : NumDecls(0) {}
|
||||
DeclGroup() = default;
|
||||
DeclGroup(unsigned numdecls, Decl** decls);
|
||||
|
||||
public:
|
||||
friend TrailingObjects;
|
||||
|
||||
static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
|
||||
|
||||
unsigned size() const { return NumDecls; }
|
||||
@ -47,23 +47,21 @@ public:
|
||||
assert (i < NumDecls && "Out-of-bounds access.");
|
||||
return getTrailingObjects<Decl *>()[i];
|
||||
}
|
||||
|
||||
friend TrailingObjects;
|
||||
};
|
||||
|
||||
class DeclGroupRef {
|
||||
// Note this is not a PointerIntPair because we need the address of the
|
||||
// non-group case to be valid as a Decl** for iteration.
|
||||
enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
|
||||
Decl* D;
|
||||
|
||||
Decl* D = nullptr;
|
||||
|
||||
Kind getKind() const {
|
||||
return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
|
||||
}
|
||||
|
||||
public:
|
||||
DeclGroupRef() : D(nullptr) {}
|
||||
|
||||
DeclGroupRef() = default;
|
||||
explicit DeclGroupRef(Decl* d) : D(d) {}
|
||||
explicit DeclGroupRef(DeclGroup* dg)
|
||||
: D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
|
||||
@ -76,8 +74,8 @@ public:
|
||||
return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
|
||||
}
|
||||
|
||||
typedef Decl** iterator;
|
||||
typedef Decl* const * const_iterator;
|
||||
using iterator = Decl **;
|
||||
using const_iterator = Decl * const *;
|
||||
|
||||
bool isNull() const { return D == nullptr; }
|
||||
bool isSingleDecl() const { return getKind() == SingleDeclKind; }
|
||||
@ -133,22 +131,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // end clang namespace
|
||||
} // namespace clang
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
|
||||
template <typename T>
|
||||
class PointerLikeTypeTraits;
|
||||
struct PointerLikeTypeTraits;
|
||||
template <>
|
||||
class PointerLikeTypeTraits<clang::DeclGroupRef> {
|
||||
public:
|
||||
struct PointerLikeTypeTraits<clang::DeclGroupRef> {
|
||||
static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
|
||||
return P.getAsOpaquePtr();
|
||||
}
|
||||
|
||||
static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
|
||||
return clang::DeclGroupRef::getFromOpaquePtr(P);
|
||||
}
|
||||
|
||||
enum { NumLowBitsAvailable = 0 };
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_CLANG_AST_DECLGROUP_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- DeclLookups.h - Low-level interface to all names in a DC-*- C++ -*-===//
|
||||
//===- DeclLookups.h - Low-level interface to all names in a DC -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -18,6 +18,9 @@
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclContextInternals.h"
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
namespace clang {
|
||||
|
||||
@ -25,14 +28,15 @@ namespace clang {
|
||||
/// of looking up every possible name.
|
||||
class DeclContext::all_lookups_iterator {
|
||||
StoredDeclsMap::iterator It, End;
|
||||
public:
|
||||
typedef lookup_result value_type;
|
||||
typedef lookup_result reference;
|
||||
typedef lookup_result pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
all_lookups_iterator() {}
|
||||
public:
|
||||
using value_type = lookup_result;
|
||||
using reference = lookup_result;
|
||||
using pointer = lookup_result;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
all_lookups_iterator() = default;
|
||||
all_lookups_iterator(StoredDeclsMap::iterator It,
|
||||
StoredDeclsMap::iterator End)
|
||||
: It(It), End(End) {}
|
||||
@ -63,6 +67,7 @@ public:
|
||||
friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) {
|
||||
return x.It == y.It;
|
||||
}
|
||||
|
||||
friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) {
|
||||
return x.It != y.It;
|
||||
}
|
||||
@ -110,6 +115,6 @@ DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
|
||||
return noload_lookups().end();
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_DECLLOOKUPS_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -100,12 +100,22 @@ public:
|
||||
///
|
||||
/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
|
||||
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
|
||||
public:
|
||||
enum InitKind {
|
||||
CallInit, // Initialized by function call.
|
||||
DirectInit, // omp_priv(<expr>)
|
||||
CopyInit // omp_priv = <expr>
|
||||
};
|
||||
|
||||
private:
|
||||
friend class ASTDeclReader;
|
||||
/// \brief Combiner for declare reduction construct.
|
||||
Expr *Combiner;
|
||||
/// \brief Initializer for declare reduction construct.
|
||||
Expr *Initializer;
|
||||
/// Kind of initializer - function call or omp_priv<init_expr> initializtion.
|
||||
InitKind InitializerKind = CallInit;
|
||||
|
||||
/// \brief Reference to the previous declare reduction construct in the same
|
||||
/// scope with the same name. Required for proper templates instantiation if
|
||||
/// the declare reduction construct is declared inside compound statement.
|
||||
@ -117,7 +127,8 @@ private:
|
||||
DeclarationName Name, QualType Ty,
|
||||
OMPDeclareReductionDecl *PrevDeclInScope)
|
||||
: ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
|
||||
Initializer(nullptr), PrevDeclInScope(PrevDeclInScope) {}
|
||||
Initializer(nullptr), InitializerKind(CallInit),
|
||||
PrevDeclInScope(PrevDeclInScope) {}
|
||||
|
||||
void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
|
||||
PrevDeclInScope = Prev;
|
||||
@ -142,8 +153,13 @@ public:
|
||||
/// construct.
|
||||
Expr *getInitializer() { return Initializer; }
|
||||
const Expr *getInitializer() const { return Initializer; }
|
||||
/// Get initializer kind.
|
||||
InitKind getInitializerKind() const { return InitializerKind; }
|
||||
/// \brief Set initializer expression for the declare reduction construct.
|
||||
void setInitializer(Expr *E) { Initializer = E; }
|
||||
void setInitializer(Expr *E, InitKind IK) {
|
||||
Initializer = E;
|
||||
InitializerKind = IK;
|
||||
}
|
||||
|
||||
/// \brief Get reference to previous declare reduction construct in the same
|
||||
/// scope with the same name.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
//===--- DeclVisitor.h - Visitor for Decl subclasses ------------*- C++ -*-===//
|
||||
//===- DeclVisitor.h - Visitor for Decl subclasses --------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -10,27 +10,30 @@
|
||||
// This file defines the DeclVisitor interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_DECLVISITOR_H
|
||||
#define LLVM_CLANG_AST_DECLVISITOR_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclFriend.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclOpenMP.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace declvisitor {
|
||||
|
||||
template <typename T> struct make_ptr { typedef T *type; };
|
||||
template <typename T> struct make_const_ptr { typedef const T *type; };
|
||||
template <typename T> struct make_ptr { using type = T *; };
|
||||
template <typename T> struct make_const_ptr { using type = const T *; };
|
||||
|
||||
/// \brief A simple visitor class that helps create declaration visitors.
|
||||
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
|
||||
class Base {
|
||||
public:
|
||||
|
||||
#define PTR(CLASS) typename Ptr<CLASS>::type
|
||||
#define DISPATCH(NAME, CLASS) \
|
||||
return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D))
|
||||
@ -57,23 +60,23 @@ public:
|
||||
#undef DISPATCH
|
||||
};
|
||||
|
||||
} // end namespace declvisitor
|
||||
} // namespace declvisitor
|
||||
|
||||
/// \brief A simple visitor class that helps create declaration visitors.
|
||||
///
|
||||
/// This class does not preserve constness of Decl pointers (see also
|
||||
/// ConstDeclVisitor).
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
template<typename ImplClass, typename RetTy = void>
|
||||
class DeclVisitor
|
||||
: public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {};
|
||||
|
||||
/// \brief A simple visitor class that helps create declaration visitors.
|
||||
///
|
||||
/// This class preserves constness of Decl pointers (see also DeclVisitor).
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
template<typename ImplClass, typename RetTy = void>
|
||||
class ConstDeclVisitor
|
||||
: public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {};
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_DECLVISITOR_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- DeclarationName.h - Representation of declaration names -*- C++ -*-===//
|
||||
//===- DeclarationName.h - Representation of declaration names --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -10,36 +10,42 @@
|
||||
// This file declares the DeclarationName and DeclarationNameTable classes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
|
||||
#define LLVM_CLANG_AST_DECLARATIONNAME_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
||||
namespace llvm {
|
||||
template <typename T> struct DenseMapInfo;
|
||||
}
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class CXXDeductionGuideNameExtra;
|
||||
class CXXLiteralOperatorIdName;
|
||||
class CXXOperatorIdName;
|
||||
class CXXSpecialName;
|
||||
class DeclarationNameExtra;
|
||||
class IdentifierInfo;
|
||||
class MultiKeywordSelector;
|
||||
enum OverloadedOperatorKind : int;
|
||||
struct PrintingPolicy;
|
||||
class QualType;
|
||||
class TemplateDecl;
|
||||
class Type;
|
||||
class TypeSourceInfo;
|
||||
class UsingDirectiveDecl;
|
||||
|
||||
template <typename> class CanQual;
|
||||
typedef CanQual<Type> CanQualType;
|
||||
class ASTContext;
|
||||
template <typename> class CanQual;
|
||||
class CXXDeductionGuideNameExtra;
|
||||
class CXXLiteralOperatorIdName;
|
||||
class CXXOperatorIdName;
|
||||
class CXXSpecialName;
|
||||
class DeclarationNameExtra;
|
||||
class IdentifierInfo;
|
||||
class MultiKeywordSelector;
|
||||
enum OverloadedOperatorKind : int;
|
||||
struct PrintingPolicy;
|
||||
class QualType;
|
||||
class TemplateDecl;
|
||||
class Type;
|
||||
class TypeSourceInfo;
|
||||
class UsingDirectiveDecl;
|
||||
|
||||
using CanQualType = CanQual<Type>;
|
||||
|
||||
/// DeclarationName - The name of a declaration. In the common case,
|
||||
/// this just stores an IdentifierInfo pointer to a normal
|
||||
@ -63,9 +69,13 @@ public:
|
||||
CXXLiteralOperatorName,
|
||||
CXXUsingDirective
|
||||
};
|
||||
|
||||
static const unsigned NumNameKinds = CXXUsingDirective + 1;
|
||||
|
||||
private:
|
||||
friend class DeclarationNameTable;
|
||||
friend class NamedDecl;
|
||||
|
||||
/// StoredNameKind - The kind of name that is actually stored in the
|
||||
/// upper bits of the Ptr field. This is only used internally.
|
||||
///
|
||||
@ -99,7 +109,18 @@ private:
|
||||
/// DeclarationNameExtra structure, whose first value will tell us
|
||||
/// whether this is an Objective-C selector, C++ operator-id name,
|
||||
/// or special C++ name.
|
||||
uintptr_t Ptr;
|
||||
uintptr_t Ptr = 0;
|
||||
|
||||
// Construct a declaration name from the name of a C++ constructor,
|
||||
// destructor, or conversion function.
|
||||
DeclarationName(DeclarationNameExtra *Name)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned DeclarationNameExtra");
|
||||
Ptr |= StoredDeclarationNameExtra;
|
||||
}
|
||||
|
||||
/// Construct a declaration name from a raw pointer.
|
||||
DeclarationName(uintptr_t Ptr) : Ptr(Ptr) {}
|
||||
|
||||
/// getStoredNameKind - Return the kind of object that is stored in
|
||||
/// Ptr.
|
||||
@ -146,36 +167,22 @@ private:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Construct a declaration name from the name of a C++ constructor,
|
||||
// destructor, or conversion function.
|
||||
DeclarationName(DeclarationNameExtra *Name)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned DeclarationNameExtra");
|
||||
Ptr |= StoredDeclarationNameExtra;
|
||||
}
|
||||
|
||||
/// Construct a declaration name from a raw pointer.
|
||||
DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
|
||||
|
||||
friend class DeclarationNameTable;
|
||||
friend class NamedDecl;
|
||||
|
||||
/// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
|
||||
/// for this name as a void pointer if it's not an identifier.
|
||||
void *getFETokenInfoAsVoidSlow() const;
|
||||
|
||||
public:
|
||||
/// DeclarationName - Used to create an empty selector.
|
||||
DeclarationName() : Ptr(0) { }
|
||||
DeclarationName() = default;
|
||||
|
||||
// Construct a declaration name from an IdentifierInfo *.
|
||||
DeclarationName(const IdentifierInfo *II)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(II)) {
|
||||
: Ptr(reinterpret_cast<uintptr_t>(II)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
|
||||
}
|
||||
|
||||
// Construct a declaration name from an Objective-C selector.
|
||||
DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) { }
|
||||
DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
|
||||
|
||||
/// getUsingDirectiveName - Return name for all using-directives.
|
||||
static DeclarationName getUsingDirectiveName();
|
||||
@ -344,16 +351,24 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
|
||||
/// getCXXConstructorName).
|
||||
class DeclarationNameTable {
|
||||
const ASTContext &Ctx;
|
||||
void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
|
||||
CXXOperatorIdName *CXXOperatorNames; // Operator names
|
||||
void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
|
||||
void *CXXDeductionGuideNames; // FoldingSet<CXXDeductionGuideNameExtra> *
|
||||
|
||||
DeclarationNameTable(const DeclarationNameTable&) = delete;
|
||||
void operator=(const DeclarationNameTable&) = delete;
|
||||
// Actually a FoldingSet<CXXSpecialName> *
|
||||
void *CXXSpecialNamesImpl;
|
||||
|
||||
// Operator names
|
||||
CXXOperatorIdName *CXXOperatorNames;
|
||||
|
||||
// Actually a CXXOperatorIdName*
|
||||
void *CXXLiteralOperatorNames;
|
||||
|
||||
// FoldingSet<CXXDeductionGuideNameExtra> *
|
||||
void *CXXDeductionGuideNames;
|
||||
|
||||
public:
|
||||
DeclarationNameTable(const ASTContext &C);
|
||||
DeclarationNameTable(const DeclarationNameTable &) = delete;
|
||||
DeclarationNameTable &operator=(const DeclarationNameTable &) = delete;
|
||||
|
||||
~DeclarationNameTable();
|
||||
|
||||
/// getIdentifier - Create a declaration name that is a simple
|
||||
@ -428,10 +443,10 @@ struct DeclarationNameLoc {
|
||||
};
|
||||
|
||||
DeclarationNameLoc(DeclarationName Name);
|
||||
|
||||
// FIXME: this should go away once all DNLocs are properly initialized.
|
||||
DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
|
||||
}; // struct DeclarationNameLoc
|
||||
|
||||
};
|
||||
|
||||
/// DeclarationNameInfo - A collector data type for bundling together
|
||||
/// a DeclarationName and the correspnding source/type location info.
|
||||
@ -439,29 +454,33 @@ struct DeclarationNameInfo {
|
||||
private:
|
||||
/// Name - The declaration name, also encoding name kind.
|
||||
DeclarationName Name;
|
||||
|
||||
/// Loc - The main source location for the declaration name.
|
||||
SourceLocation NameLoc;
|
||||
|
||||
/// Info - Further source/type location info for special kinds of names.
|
||||
DeclarationNameLoc LocInfo;
|
||||
|
||||
public:
|
||||
// FIXME: remove it.
|
||||
DeclarationNameInfo() {}
|
||||
DeclarationNameInfo() = default;
|
||||
|
||||
DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
|
||||
: Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
|
||||
: Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
|
||||
|
||||
DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
|
||||
DeclarationNameLoc LocInfo)
|
||||
: Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
|
||||
: Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
|
||||
|
||||
/// getName - Returns the embedded declaration name.
|
||||
DeclarationName getName() const { return Name; }
|
||||
|
||||
/// setName - Sets the embedded declaration name.
|
||||
void setName(DeclarationName N) { Name = N; }
|
||||
|
||||
/// getLoc - Returns the main location of the declaration name.
|
||||
SourceLocation getLoc() const { return NameLoc; }
|
||||
|
||||
/// setLoc - Sets the main location of the declaration name.
|
||||
void setLoc(SourceLocation L) { NameLoc = L; }
|
||||
|
||||
@ -477,6 +496,7 @@ public:
|
||||
Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
|
||||
return LocInfo.NamedType.TInfo;
|
||||
}
|
||||
|
||||
/// setNamedTypeInfo - Sets the source type info associated to
|
||||
/// the name. Assumes it is a constructor, destructor or conversion.
|
||||
void setNamedTypeInfo(TypeSourceInfo *TInfo) {
|
||||
@ -495,6 +515,7 @@ public:
|
||||
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
|
||||
);
|
||||
}
|
||||
|
||||
/// setCXXOperatorNameRange - Sets the range of the operator name
|
||||
/// (without the operator keyword). Assumes it is a C++ operator.
|
||||
void setCXXOperatorNameRange(SourceRange R) {
|
||||
@ -511,6 +532,7 @@ public:
|
||||
return SourceLocation::
|
||||
getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
|
||||
}
|
||||
|
||||
/// setCXXLiteralOperatorNameLoc - Sets the location of the literal
|
||||
/// operator name (not the operator keyword).
|
||||
/// Assumes it is a literal operator.
|
||||
@ -534,15 +556,19 @@ public:
|
||||
|
||||
/// getBeginLoc - Retrieve the location of the first token.
|
||||
SourceLocation getBeginLoc() const { return NameLoc; }
|
||||
|
||||
/// getEndLoc - Retrieve the location of the last token.
|
||||
SourceLocation getEndLoc() const;
|
||||
|
||||
/// getSourceRange - The range of the declaration name.
|
||||
SourceRange getSourceRange() const LLVM_READONLY {
|
||||
return SourceRange(getLocStart(), getLocEnd());
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY {
|
||||
return getBeginLoc();
|
||||
}
|
||||
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
SourceLocation EndLoc = getEndLoc();
|
||||
return EndLoc.isValid() ? EndLoc : getLocStart();
|
||||
@ -573,9 +599,10 @@ inline raw_ostream &operator<<(raw_ostream &OS,
|
||||
return OS;
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// Define DenseMapInfo so that DeclarationNames can be used as keys
|
||||
/// in DenseMap and DenseSets.
|
||||
template<>
|
||||
@ -601,6 +628,6 @@ struct DenseMapInfo<clang::DeclarationName> {
|
||||
template <>
|
||||
struct isPodLike<clang::DeclarationName> { static const bool value = true; };
|
||||
|
||||
} // end namespace llvm
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_DECLARATIONNAME_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- C++ -*-=//
|
||||
//==- DependentDiagnostic.h - Dependently-generated diagnostics --*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -23,6 +23,9 @@
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
|
||||
namespace clang {
|
||||
|
||||
@ -94,6 +97,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
friend class DeclContext::ddiag_iterator;
|
||||
friend class DependentStoredDeclsMap;
|
||||
|
||||
DependentDiagnostic(const PartialDiagnostic &PDiag,
|
||||
PartialDiagnostic::Storage *Storage)
|
||||
: Diag(PDiag, Storage) {}
|
||||
@ -102,8 +108,6 @@ private:
|
||||
DeclContext *Parent,
|
||||
const PartialDiagnostic &PDiag);
|
||||
|
||||
friend class DependentStoredDeclsMap;
|
||||
friend class DeclContext::ddiag_iterator;
|
||||
DependentDiagnostic *NextDiagnostic;
|
||||
|
||||
PartialDiagnostic Diag;
|
||||
@ -118,19 +122,17 @@ private:
|
||||
} AccessData;
|
||||
};
|
||||
|
||||
///
|
||||
|
||||
/// An iterator over the dependent diagnostics in a dependent context.
|
||||
class DeclContext::ddiag_iterator {
|
||||
public:
|
||||
ddiag_iterator() : Ptr(nullptr) {}
|
||||
ddiag_iterator() = default;
|
||||
explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
|
||||
|
||||
typedef DependentDiagnostic *value_type;
|
||||
typedef DependentDiagnostic *reference;
|
||||
typedef DependentDiagnostic *pointer;
|
||||
typedef int difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
using value_type = DependentDiagnostic *;
|
||||
using reference = DependentDiagnostic *;
|
||||
using pointer = DependentDiagnostic *;
|
||||
using difference_type = int;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
reference operator*() const { return Ptr; }
|
||||
|
||||
@ -168,7 +170,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
DependentDiagnostic *Ptr;
|
||||
DependentDiagnostic *Ptr = nullptr;
|
||||
};
|
||||
|
||||
inline DeclContext::ddiag_range DeclContext::ddiags() const {
|
||||
@ -184,6 +186,6 @@ inline DeclContext::ddiag_range DeclContext::ddiags() const {
|
||||
return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/CharInfo.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Basic/SyncScope.h"
|
||||
#include "clang/Basic/TypeTraits.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
@ -274,6 +275,7 @@ public:
|
||||
MLV_LValueCast, // Specialized form of MLV_InvalidExpression.
|
||||
MLV_IncompleteType,
|
||||
MLV_ConstQualified,
|
||||
MLV_ConstQualifiedField,
|
||||
MLV_ConstAddrSpace,
|
||||
MLV_ArrayType,
|
||||
MLV_NoSetterProperty,
|
||||
@ -323,6 +325,7 @@ public:
|
||||
CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
|
||||
CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
|
||||
CM_ConstQualified,
|
||||
CM_ConstQualifiedField,
|
||||
CM_ConstAddrSpace,
|
||||
CM_ArrayType,
|
||||
CM_IncompleteType
|
||||
@ -2345,6 +2348,12 @@ public:
|
||||
SourceLocation getLocStart() const LLVM_READONLY;
|
||||
SourceLocation getLocEnd() const LLVM_READONLY;
|
||||
|
||||
bool isCallToStdMove() const {
|
||||
const FunctionDecl* FD = getDirectCallee();
|
||||
return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
|
||||
FD->getIdentifier() && FD->getIdentifier()->isStr("move");
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() >= firstCallExprConstant &&
|
||||
T->getStmtClass() <= lastCallExprConstant;
|
||||
@ -2733,7 +2742,6 @@ protected:
|
||||
ty->containsUnexpandedParameterPack()) ||
|
||||
(op && op->containsUnexpandedParameterPack()))),
|
||||
Op(op) {
|
||||
assert(kind != CK_Invalid && "creating cast with invalid cast kind");
|
||||
CastExprBits.Kind = kind;
|
||||
setBasePathSize(BasePathSize);
|
||||
assert(CastConsistency());
|
||||
@ -2771,6 +2779,16 @@ public:
|
||||
path_const_iterator path_begin() const { return path_buffer(); }
|
||||
path_const_iterator path_end() const { return path_buffer() + path_size(); }
|
||||
|
||||
const FieldDecl *getTargetUnionField() const {
|
||||
assert(getCastKind() == CK_ToUnion);
|
||||
return getTargetFieldForToUnionCast(getType(), getSubExpr()->getType());
|
||||
}
|
||||
|
||||
static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType,
|
||||
QualType opType);
|
||||
static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD,
|
||||
QualType opType);
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() >= firstCastExprConstant &&
|
||||
T->getStmtClass() <= lastCastExprConstant;
|
||||
@ -3054,7 +3072,7 @@ public:
|
||||
static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; }
|
||||
bool isEqualityOp() const { return isEqualityOp(getOpcode()); }
|
||||
|
||||
static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; }
|
||||
static bool isComparisonOp(Opcode Opc) { return Opc >= BO_Cmp && Opc<=BO_NE; }
|
||||
bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
|
||||
|
||||
static Opcode negateComparisonOp(Opcode Opc) {
|
||||
@ -3113,6 +3131,12 @@ public:
|
||||
return isShiftAssignOp(getOpcode());
|
||||
}
|
||||
|
||||
// Return true if a binary operator using the specified opcode and operands
|
||||
// would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized
|
||||
// integer to a pointer.
|
||||
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc,
|
||||
Expr *LHS, Expr *RHS);
|
||||
|
||||
static bool classof(const Stmt *S) {
|
||||
return S->getStmtClass() >= firstBinaryOperatorConstant &&
|
||||
S->getStmtClass() <= lastBinaryOperatorConstant;
|
||||
@ -3986,6 +4010,10 @@ public:
|
||||
/// initializer)?
|
||||
bool isTransparent() const;
|
||||
|
||||
/// Is this the zero initializer {0} in a language which considers it
|
||||
/// idiomatic?
|
||||
bool isIdiomaticZeroInitializer(const LangOptions &LangOpts) const;
|
||||
|
||||
SourceLocation getLBraceLoc() const { return LBraceLoc; }
|
||||
void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
|
||||
SourceLocation getRBraceLoc() const { return RBraceLoc; }
|
||||
@ -3995,6 +4023,9 @@ public:
|
||||
InitListExpr *getSemanticForm() const {
|
||||
return isSemanticForm() ? nullptr : AltForm.getPointer();
|
||||
}
|
||||
bool isSyntacticForm() const {
|
||||
return !AltForm.getInt() || !AltForm.getPointer();
|
||||
}
|
||||
InitListExpr *getSyntacticForm() const {
|
||||
return isSemanticForm() ? AltForm.getPointer() : nullptr;
|
||||
}
|
||||
@ -5064,9 +5095,11 @@ public:
|
||||
|
||||
/// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*,
|
||||
/// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the
|
||||
/// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>.
|
||||
/// All of these instructions take one primary pointer and at least one memory
|
||||
/// order.
|
||||
/// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>,
|
||||
/// and corresponding __opencl_atomic_* for OpenCL 2.0.
|
||||
/// All of these instructions take one primary pointer, at least one memory
|
||||
/// order. The instructions for which getScopeModel returns non-null value
|
||||
/// take one synch scope.
|
||||
class AtomicExpr : public Expr {
|
||||
public:
|
||||
enum AtomicOp {
|
||||
@ -5078,14 +5111,16 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
/// \brief Location of sub-expressions.
|
||||
/// The location of Scope sub-expression is NumSubExprs - 1, which is
|
||||
/// not fixed, therefore is not defined in enum.
|
||||
enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
|
||||
Stmt* SubExprs[END_EXPR];
|
||||
Stmt *SubExprs[END_EXPR + 1];
|
||||
unsigned NumSubExprs;
|
||||
SourceLocation BuiltinLoc, RParenLoc;
|
||||
AtomicOp Op;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
|
||||
public:
|
||||
AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t,
|
||||
AtomicOp op, SourceLocation RP);
|
||||
@ -5103,8 +5138,12 @@ public:
|
||||
Expr *getOrder() const {
|
||||
return cast<Expr>(SubExprs[ORDER]);
|
||||
}
|
||||
Expr *getScope() const {
|
||||
assert(getScopeModel() && "No scope");
|
||||
return cast<Expr>(SubExprs[NumSubExprs - 1]);
|
||||
}
|
||||
Expr *getVal1() const {
|
||||
if (Op == AO__c11_atomic_init)
|
||||
if (Op == AO__c11_atomic_init || Op == AO__opencl_atomic_init)
|
||||
return cast<Expr>(SubExprs[ORDER]);
|
||||
assert(NumSubExprs > VAL1);
|
||||
return cast<Expr>(SubExprs[VAL1]);
|
||||
@ -5123,6 +5162,7 @@ public:
|
||||
assert(NumSubExprs > WEAK);
|
||||
return cast<Expr>(SubExprs[WEAK]);
|
||||
}
|
||||
QualType getValueType() const;
|
||||
|
||||
AtomicOp getOp() const { return Op; }
|
||||
unsigned getNumSubExprs() const { return NumSubExprs; }
|
||||
@ -5139,10 +5179,17 @@ public:
|
||||
bool isCmpXChg() const {
|
||||
return getOp() == AO__c11_atomic_compare_exchange_strong ||
|
||||
getOp() == AO__c11_atomic_compare_exchange_weak ||
|
||||
getOp() == AO__opencl_atomic_compare_exchange_strong ||
|
||||
getOp() == AO__opencl_atomic_compare_exchange_weak ||
|
||||
getOp() == AO__atomic_compare_exchange ||
|
||||
getOp() == AO__atomic_compare_exchange_n;
|
||||
}
|
||||
|
||||
bool isOpenCL() const {
|
||||
return getOp() >= AO__opencl_atomic_init &&
|
||||
getOp() <= AO__opencl_atomic_fetch_max;
|
||||
}
|
||||
|
||||
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
|
||||
@ -5160,6 +5207,24 @@ public:
|
||||
const_child_range children() const {
|
||||
return const_child_range(SubExprs, SubExprs + NumSubExprs);
|
||||
}
|
||||
|
||||
/// \brief Get atomic scope model for the atomic op code.
|
||||
/// \return empty atomic scope model if the atomic op code does not have
|
||||
/// scope operand.
|
||||
static std::unique_ptr<AtomicScopeModel> getScopeModel(AtomicOp Op) {
|
||||
auto Kind =
|
||||
(Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max)
|
||||
? AtomicScopeModelKind::OpenCL
|
||||
: AtomicScopeModelKind::None;
|
||||
return AtomicScopeModel::create(Kind);
|
||||
}
|
||||
|
||||
/// \brief Get atomic scope model.
|
||||
/// \return empty atomic scope model if this atomic expression does not have
|
||||
/// scope operand.
|
||||
std::unique_ptr<AtomicScopeModel> getScopeModel() const {
|
||||
return getScopeModel(getOp());
|
||||
}
|
||||
};
|
||||
|
||||
/// TypoExpr - Internal placeholder for expressions where typo correction
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -16,34 +16,159 @@
|
||||
|
||||
#include "clang/AST/ASTImporter.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// ExternalASTSource implementation that merges information from several
|
||||
/// ASTContexts.
|
||||
///
|
||||
/// ExtermalASTMerger maintains a vector of ASTImporters that it uses to import
|
||||
/// (potentially incomplete) Decls and DeclContexts from the source ASTContexts
|
||||
/// in response to ExternalASTSource API calls.
|
||||
///
|
||||
/// When lookup occurs in the resulting imported DeclContexts, the original
|
||||
/// DeclContexts need to be queried. Roughly, there are three cases here:
|
||||
///
|
||||
/// - The DeclContext of origin can be found by simple name lookup. In this
|
||||
/// case, no additional state is required.
|
||||
///
|
||||
/// - The DeclContext of origin is different from what would be found by name
|
||||
/// lookup. In this case, Origins contains an entry overriding lookup and
|
||||
/// specifying the correct pair of DeclContext/ASTContext.
|
||||
///
|
||||
/// - The DeclContext of origin was determined by another ExterenalASTMerger.
|
||||
/// (This is possible when the source ASTContext for one of the Importers has
|
||||
/// its own ExternalASTMerger). The origin must be properly forwarded in this
|
||||
/// case.
|
||||
///
|
||||
/// ExternalASTMerger's job is to maintain the data structures necessary to
|
||||
/// allow this. The data structures themselves can be extracted (read-only) and
|
||||
/// copied for re-use.
|
||||
class ExternalASTMerger : public ExternalASTSource {
|
||||
public:
|
||||
struct ImporterPair {
|
||||
std::unique_ptr<ASTImporter> Forward;
|
||||
std::unique_ptr<ASTImporter> Reverse;
|
||||
/// A single origin for a DeclContext. Unlike Decls, DeclContexts do
|
||||
/// not allow their containing ASTContext to be determined in all cases.
|
||||
struct DCOrigin {
|
||||
DeclContext *DC;
|
||||
ASTContext *AST;
|
||||
};
|
||||
|
||||
typedef std::map<const DeclContext *, DCOrigin> OriginMap;
|
||||
typedef std::vector<std::unique_ptr<ASTImporter>> ImporterVector;
|
||||
private:
|
||||
std::vector<ImporterPair> Importers;
|
||||
/// One importer exists for each source.
|
||||
ImporterVector Importers;
|
||||
/// Overrides in case name lookup would return nothing or would return
|
||||
/// the wrong thing.
|
||||
OriginMap Origins;
|
||||
/// The installed log stream.
|
||||
llvm::raw_ostream *LogStream;
|
||||
|
||||
public:
|
||||
struct ImporterEndpoint {
|
||||
/// The target for an ExternalASTMerger.
|
||||
///
|
||||
/// ASTImporters require both ASTContext and FileManager to be able to
|
||||
/// import SourceLocations properly.
|
||||
struct ImporterTarget {
|
||||
ASTContext &AST;
|
||||
FileManager &FM;
|
||||
};
|
||||
ExternalASTMerger(const ImporterEndpoint &Target,
|
||||
llvm::ArrayRef<ImporterEndpoint> Sources);
|
||||
/// A source for an ExternalASTMerger.
|
||||
///
|
||||
/// ASTImporters require both ASTContext and FileManager to be able to
|
||||
/// import SourceLocations properly. Additionally, when import occurs for
|
||||
/// a DeclContext whose origin has been overridden, then this
|
||||
/// ExternalASTMerger must be able to determine that.
|
||||
struct ImporterSource {
|
||||
ASTContext &AST;
|
||||
FileManager &FM;
|
||||
const OriginMap &OM;
|
||||
};
|
||||
|
||||
private:
|
||||
/// The target for this ExtenralASTMerger.
|
||||
ImporterTarget Target;
|
||||
|
||||
public:
|
||||
ExternalASTMerger(const ImporterTarget &Target,
|
||||
llvm::ArrayRef<ImporterSource> Sources);
|
||||
|
||||
/// Add a set of ASTContexts as possible origins.
|
||||
///
|
||||
/// Usually the set will be initialized in the constructor, but long-lived
|
||||
/// ExternalASTMergers may neeed to import from new sources (for example,
|
||||
/// newly-parsed source files).
|
||||
///
|
||||
/// Ensures that Importers does not gain duplicate entries as a result.
|
||||
void AddSources(llvm::ArrayRef<ImporterSource> Sources);
|
||||
|
||||
/// Remove a set of ASTContexts as possible origins.
|
||||
///
|
||||
/// Sometimes an origin goes away (for example, if a source file gets
|
||||
/// superseded by a newer version).
|
||||
///
|
||||
/// The caller is responsible for ensuring that this doesn't leave
|
||||
/// DeclContexts that can't be completed.
|
||||
void RemoveSources(llvm::ArrayRef<ImporterSource> Sources);
|
||||
|
||||
/// Implementation of the ExternalASTSource API.
|
||||
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
|
||||
DeclarationName Name) override;
|
||||
|
||||
/// Implementation of the ExternalASTSource API.
|
||||
void
|
||||
FindExternalLexicalDecls(const DeclContext *DC,
|
||||
llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
|
||||
SmallVectorImpl<Decl *> &Result) override;
|
||||
|
||||
/// Implementation of the ExternalASTSource API.
|
||||
void CompleteType(TagDecl *Tag) override;
|
||||
|
||||
/// Implementation of the ExternalASTSource API.
|
||||
void CompleteType(ObjCInterfaceDecl *Interface) override;
|
||||
|
||||
/// Returns true if DC can be found in any source AST context.
|
||||
bool CanComplete(DeclContext *DC);
|
||||
|
||||
/// Records an origin in Origins only if name lookup would find
|
||||
/// something different or nothing at all.
|
||||
void MaybeRecordOrigin(const DeclContext *ToDC, DCOrigin Origin);
|
||||
|
||||
/// Regardless of any checks, override the Origin for a DeclContext.
|
||||
void ForceRecordOrigin(const DeclContext *ToDC, DCOrigin Origin);
|
||||
|
||||
/// Get a read-only view of the Origins map, for use in constructing
|
||||
/// an ImporterSource for another ExternalASTMerger.
|
||||
const OriginMap &GetOrigins() { return Origins; }
|
||||
|
||||
/// Returns true if Importers contains an ASTImporter whose source is
|
||||
/// OriginContext.
|
||||
bool HasImporterForOrigin(ASTContext &OriginContext);
|
||||
|
||||
/// Returns a reference to the ASTRImporter from Importers whose origin
|
||||
/// is OriginContext. This allows manual import of ASTs while preserving the
|
||||
/// OriginMap correctly.
|
||||
ASTImporter &ImporterForOrigin(ASTContext &OriginContext);
|
||||
|
||||
/// Sets the current log stream.
|
||||
void SetLogStream(llvm::raw_string_ostream &Stream) { LogStream = &Stream; }
|
||||
private:
|
||||
/// Records and origin in Origins.
|
||||
void RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origin,
|
||||
ASTImporter &importer);
|
||||
|
||||
/// Performs an action for every DeclContext that is identified as
|
||||
/// corresponding (either by forced origin or by name lookup) to DC.
|
||||
template <typename CallbackType>
|
||||
void ForEachMatchingDC(const DeclContext *DC, CallbackType Callback);
|
||||
|
||||
public:
|
||||
/// Log something if there is a logging callback installed.
|
||||
llvm::raw_ostream &logs() { return *LogStream; }
|
||||
|
||||
/// True if the log stream is not llvm::nulls();
|
||||
bool LoggingEnabled() { return LogStream != &llvm::nulls(); }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- ExternalASTSource.h - Abstract External AST Interface --*- C++ -*-===//
|
||||
//===- ExternalASTSource.h - Abstract External AST Interface ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -11,24 +11,44 @@
|
||||
// construction of AST nodes from some external source.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
|
||||
#define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
|
||||
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/Module.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/iterator.h"
|
||||
#include "llvm/Support/PointerLikeTypeTraits.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTConsumer;
|
||||
class ASTContext;
|
||||
class CXXBaseSpecifier;
|
||||
class CXXCtorInitializer;
|
||||
class CXXRecordDecl;
|
||||
class DeclarationName;
|
||||
class ExternalSemaSource; // layering violation required for downcasting
|
||||
class FieldDecl;
|
||||
class Module;
|
||||
class IdentifierInfo;
|
||||
class NamedDecl;
|
||||
class ObjCInterfaceDecl;
|
||||
class RecordDecl;
|
||||
class Selector;
|
||||
class Stmt;
|
||||
@ -42,30 +62,31 @@ class TagDecl;
|
||||
/// actual type and declaration nodes, and read parts of declaration
|
||||
/// contexts.
|
||||
class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
|
||||
friend class ExternalSemaSource;
|
||||
|
||||
/// Generation number for this external AST source. Must be increased
|
||||
/// whenever we might have added new redeclarations for existing decls.
|
||||
uint32_t CurrentGeneration;
|
||||
uint32_t CurrentGeneration = 0;
|
||||
|
||||
/// \brief Whether this AST source also provides information for
|
||||
/// semantic analysis.
|
||||
bool SemaSource;
|
||||
|
||||
friend class ExternalSemaSource;
|
||||
bool SemaSource = false;
|
||||
|
||||
public:
|
||||
ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { }
|
||||
|
||||
ExternalASTSource() = default;
|
||||
virtual ~ExternalASTSource();
|
||||
|
||||
/// \brief RAII class for safely pairing a StartedDeserializing call
|
||||
/// with FinishedDeserializing.
|
||||
class Deserializing {
|
||||
ExternalASTSource *Source;
|
||||
|
||||
public:
|
||||
explicit Deserializing(ExternalASTSource *source) : Source(source) {
|
||||
assert(Source);
|
||||
Source->StartedDeserializing();
|
||||
}
|
||||
|
||||
~Deserializing() {
|
||||
Source->FinishedDeserializing();
|
||||
}
|
||||
@ -122,7 +143,7 @@ public:
|
||||
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
|
||||
|
||||
/// \brief Update an out-of-date identifier.
|
||||
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { }
|
||||
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) {}
|
||||
|
||||
/// \brief Find all declarations with the given name in the given context,
|
||||
/// and add them to the context by calling SetExternalVisibleDeclsForName
|
||||
@ -154,12 +175,13 @@ public:
|
||||
const Module *ClangModule = nullptr;
|
||||
|
||||
public:
|
||||
ASTSourceDescriptor(){};
|
||||
ASTSourceDescriptor() = default;
|
||||
ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
|
||||
ASTFileSignature Signature)
|
||||
: PCHModuleName(std::move(Name)), Path(std::move(Path)),
|
||||
ASTFile(std::move(ASTFile)), Signature(Signature){};
|
||||
ASTFile(std::move(ASTFile)), Signature(Signature) {}
|
||||
ASTSourceDescriptor(const Module &M);
|
||||
|
||||
std::string getModuleName() const;
|
||||
StringRef getPath() const { return Path; }
|
||||
StringRef getASTFile() const { return ASTFile; }
|
||||
@ -246,7 +268,6 @@ public:
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual void PrintStats();
|
||||
|
||||
|
||||
/// \brief Perform layout on the given record.
|
||||
///
|
||||
/// This routine allows the external AST source to provide an specific
|
||||
@ -289,7 +310,7 @@ public:
|
||||
size_t mmap_bytes;
|
||||
|
||||
MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
|
||||
: malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
|
||||
: malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
|
||||
};
|
||||
|
||||
/// Return the amount of memory used by memory buffers, breaking down
|
||||
@ -329,12 +350,12 @@ struct LazyOffsetPtr {
|
||||
///
|
||||
/// If the low bit is clear, a pointer to the AST node. If the low
|
||||
/// bit is set, the upper 63 bits are the offset.
|
||||
mutable uint64_t Ptr;
|
||||
mutable uint64_t Ptr = 0;
|
||||
|
||||
public:
|
||||
LazyOffsetPtr() : Ptr(0) { }
|
||||
LazyOffsetPtr() = default;
|
||||
explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {}
|
||||
|
||||
explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
|
||||
explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
|
||||
assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
|
||||
if (Offset == 0)
|
||||
@ -392,15 +413,16 @@ struct LazyGenerationalUpdatePtr {
|
||||
/// A cache of the value of this pointer, in the most recent generation in
|
||||
/// which we queried it.
|
||||
struct LazyData {
|
||||
LazyData(ExternalASTSource *Source, T Value)
|
||||
: ExternalSource(Source), LastGeneration(0), LastValue(Value) {}
|
||||
ExternalASTSource *ExternalSource;
|
||||
uint32_t LastGeneration;
|
||||
uint32_t LastGeneration = 0;
|
||||
T LastValue;
|
||||
|
||||
LazyData(ExternalASTSource *Source, T Value)
|
||||
: ExternalSource(Source), LastValue(Value) {}
|
||||
};
|
||||
|
||||
// Our value is represented as simply T if there is no external AST source.
|
||||
typedef llvm::PointerUnion<T, LazyData*> ValueType;
|
||||
using ValueType = llvm::PointerUnion<T, LazyData*>;
|
||||
ValueType Value;
|
||||
|
||||
LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
|
||||
@ -459,25 +481,31 @@ public:
|
||||
return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
|
||||
}
|
||||
};
|
||||
} // end namespace clang
|
||||
|
||||
} // namespace clang
|
||||
|
||||
/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
|
||||
/// placed into a PointerUnion.
|
||||
namespace llvm {
|
||||
|
||||
template<typename Owner, typename T,
|
||||
void (clang::ExternalASTSource::*Update)(Owner)>
|
||||
struct PointerLikeTypeTraits<
|
||||
clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
|
||||
typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr;
|
||||
using Ptr = clang::LazyGenerationalUpdatePtr<Owner, T, Update>;
|
||||
|
||||
static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
|
||||
static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
|
||||
|
||||
enum {
|
||||
NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// \brief Represents a lazily-loaded vector of data.
|
||||
///
|
||||
/// The lazily-loaded vector of data contains data that is partially loaded
|
||||
@ -511,13 +539,14 @@ public:
|
||||
class iterator
|
||||
: public llvm::iterator_adaptor_base<
|
||||
iterator, int, std::random_access_iterator_tag, T, int, T *, T &> {
|
||||
friend class LazyVector;
|
||||
|
||||
LazyVector *Self;
|
||||
|
||||
iterator(LazyVector *Self, int Position)
|
||||
: iterator::iterator_adaptor_base(Position), Self(Self) {}
|
||||
|
||||
bool isLoaded() const { return this->I < 0; }
|
||||
friend class LazyVector;
|
||||
|
||||
public:
|
||||
iterator() : iterator(nullptr, 0) {}
|
||||
@ -562,23 +591,23 @@ public:
|
||||
};
|
||||
|
||||
/// \brief A lazy pointer to a statement.
|
||||
typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
|
||||
LazyDeclStmtPtr;
|
||||
using LazyDeclStmtPtr =
|
||||
LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>;
|
||||
|
||||
/// \brief A lazy pointer to a declaration.
|
||||
typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
|
||||
LazyDeclPtr;
|
||||
using LazyDeclPtr =
|
||||
LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>;
|
||||
|
||||
/// \brief A lazy pointer to a set of CXXCtorInitializers.
|
||||
typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t,
|
||||
&ExternalASTSource::GetExternalCXXCtorInitializers>
|
||||
LazyCXXCtorInitializersPtr;
|
||||
using LazyCXXCtorInitializersPtr =
|
||||
LazyOffsetPtr<CXXCtorInitializer *, uint64_t,
|
||||
&ExternalASTSource::GetExternalCXXCtorInitializers>;
|
||||
|
||||
/// \brief A lazy pointer to a set of CXXBaseSpecifiers.
|
||||
typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
|
||||
&ExternalASTSource::GetExternalCXXBaseSpecifiers>
|
||||
LazyCXXBaseSpecifiersPtr;
|
||||
using LazyCXXBaseSpecifiersPtr =
|
||||
LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
|
||||
&ExternalASTSource::GetExternalCXXBaseSpecifiers>;
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_EXTERNALASTSOURCE_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===//
|
||||
//===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -19,6 +19,12 @@
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclOpenMP.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace clang {
|
||||
|
||||
@ -27,7 +33,7 @@ namespace clang {
|
||||
/// a CXXDestructorDecl and the destructor type (Base, Complete) or
|
||||
/// a VarDecl, a FunctionDecl or a BlockDecl.
|
||||
class GlobalDecl {
|
||||
llvm::PointerIntPair<const Decl*, 2> Value;
|
||||
llvm::PointerIntPair<const Decl *, 2> Value;
|
||||
|
||||
void Init(const Decl *D) {
|
||||
assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
|
||||
@ -37,19 +43,15 @@ class GlobalDecl {
|
||||
}
|
||||
|
||||
public:
|
||||
GlobalDecl() {}
|
||||
|
||||
GlobalDecl() = default;
|
||||
GlobalDecl(const VarDecl *D) { Init(D);}
|
||||
GlobalDecl(const FunctionDecl *D) { Init(D); }
|
||||
GlobalDecl(const BlockDecl *D) { Init(D); }
|
||||
GlobalDecl(const CapturedDecl *D) { Init(D); }
|
||||
GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
|
||||
GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
|
||||
|
||||
GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
|
||||
: Value(D, Type) {}
|
||||
GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
|
||||
: Value(D, Type) {}
|
||||
GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
|
||||
GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
|
||||
|
||||
GlobalDecl getCanonicalDecl() const {
|
||||
GlobalDecl CanonGD;
|
||||
@ -90,10 +92,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
namespace llvm {
|
||||
template<class> struct DenseMapInfo;
|
||||
|
||||
template<> struct DenseMapInfo<clang::GlobalDecl> {
|
||||
static inline clang::GlobalDecl getEmptyKey() {
|
||||
@ -113,7 +114,6 @@ namespace llvm {
|
||||
clang::GlobalDecl RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// GlobalDecl isn't *technically* a POD type. However, its copy constructor,
|
||||
@ -122,6 +122,7 @@ namespace llvm {
|
||||
struct isPodLike<clang::GlobalDecl> {
|
||||
static const bool value = true;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_CLANG_AST_GLOBALDECL_H
|
||||
|
@ -0,0 +1,164 @@
|
||||
//===--- LexicallyOrderedRecursiveASTVisitor.h - ----------------*- 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 LexicallyOrderedRecursiveASTVisitor interface, which
|
||||
// recursively traverses the entire AST in a lexical order.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
|
||||
#define LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
|
||||
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/Support/SaveAndRestore.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// A RecursiveASTVisitor subclass that guarantees that AST traversal is
|
||||
/// performed in a lexical order (i.e. the order in which declarations are
|
||||
/// written in the source).
|
||||
///
|
||||
/// RecursiveASTVisitor doesn't guarantee lexical ordering because there are
|
||||
/// some declarations, like Objective-C @implementation declarations
|
||||
/// that might be represented in the AST differently to how they were written
|
||||
/// in the source.
|
||||
/// In particular, Objective-C @implementation declarations may contain
|
||||
/// non-Objective-C declarations, like functions:
|
||||
///
|
||||
/// @implementation MyClass
|
||||
///
|
||||
/// - (void) method { }
|
||||
/// void normalFunction() { }
|
||||
///
|
||||
/// @end
|
||||
///
|
||||
/// Clang's AST stores these declarations outside of the @implementation
|
||||
/// declaration, so the example above would be represented using the following
|
||||
/// AST:
|
||||
/// |-ObjCImplementationDecl ... MyClass
|
||||
/// | `-ObjCMethodDecl ... method
|
||||
/// | ...
|
||||
/// `-FunctionDecl ... normalFunction
|
||||
/// ...
|
||||
///
|
||||
/// This class ensures that these declarations are traversed before the
|
||||
/// corresponding TraverseDecl for the @implementation returns. This ensures
|
||||
/// that the lexical parent relationship between these declarations and the
|
||||
/// @implementation is preserved while traversing the AST. Note that the
|
||||
/// current implementation doesn't mix these declarations with the declarations
|
||||
/// contained in the @implementation, so the traversal of all of the
|
||||
/// declarations in the @implementation still doesn't follow the lexical order.
|
||||
template <typename Derived>
|
||||
class LexicallyOrderedRecursiveASTVisitor
|
||||
: public RecursiveASTVisitor<Derived> {
|
||||
using BaseType = RecursiveASTVisitor<Derived>;
|
||||
|
||||
public:
|
||||
LexicallyOrderedRecursiveASTVisitor(const SourceManager &SM) : SM(SM) {}
|
||||
|
||||
bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) {
|
||||
// Objective-C @implementation declarations should not trigger early exit
|
||||
// until the additional decls are traversed as their children are not
|
||||
// lexically ordered.
|
||||
bool Result = BaseType::TraverseObjCImplementationDecl(D);
|
||||
return TraverseAdditionalLexicallyNestedDeclarations() ? Result : false;
|
||||
}
|
||||
|
||||
bool TraverseObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
|
||||
bool Result = BaseType::TraverseObjCCategoryImplDecl(D);
|
||||
return TraverseAdditionalLexicallyNestedDeclarations() ? Result : false;
|
||||
}
|
||||
|
||||
bool TraverseDeclContextHelper(DeclContext *DC) {
|
||||
if (!DC)
|
||||
return true;
|
||||
|
||||
for (auto I = DC->decls_begin(), E = DC->decls_end(); I != E;) {
|
||||
Decl *Child = *I;
|
||||
if (BaseType::canIgnoreChildDeclWhileTraversingDeclContext(Child)) {
|
||||
++I;
|
||||
continue;
|
||||
}
|
||||
if (!isa<ObjCImplementationDecl>(Child) &&
|
||||
!isa<ObjCCategoryImplDecl>(Child)) {
|
||||
if (!BaseType::getDerived().TraverseDecl(Child))
|
||||
return false;
|
||||
++I;
|
||||
continue;
|
||||
}
|
||||
// Gather declarations that follow the Objective-C implementation
|
||||
// declarations but are lexically contained in the implementation.
|
||||
LexicallyNestedDeclarations.clear();
|
||||
for (++I; I != E; ++I) {
|
||||
Decl *Sibling = *I;
|
||||
if (!SM.isBeforeInTranslationUnit(Sibling->getLocStart(),
|
||||
Child->getLocEnd()))
|
||||
break;
|
||||
if (!BaseType::canIgnoreChildDeclWhileTraversingDeclContext(Sibling))
|
||||
LexicallyNestedDeclarations.push_back(Sibling);
|
||||
}
|
||||
if (!BaseType::getDerived().TraverseDecl(Child))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
|
||||
|
||||
SmallVector<Stmt *, 8> getStmtChildren(CXXOperatorCallExpr *CE) {
|
||||
SmallVector<Stmt *, 8> Children(CE->children());
|
||||
bool Swap;
|
||||
// Switch the operator and the first operand for all infix and postfix
|
||||
// operations.
|
||||
switch (CE->getOperator()) {
|
||||
case OO_Arrow:
|
||||
case OO_Call:
|
||||
case OO_Subscript:
|
||||
Swap = true;
|
||||
break;
|
||||
case OO_PlusPlus:
|
||||
case OO_MinusMinus:
|
||||
// These are postfix unless there is exactly one argument.
|
||||
Swap = Children.size() != 2;
|
||||
break;
|
||||
default:
|
||||
Swap = CE->isInfixBinaryOp();
|
||||
break;
|
||||
}
|
||||
if (Swap && Children.size() > 1)
|
||||
std::swap(Children[0], Children[1]);
|
||||
return Children;
|
||||
}
|
||||
|
||||
private:
|
||||
bool TraverseAdditionalLexicallyNestedDeclarations() {
|
||||
// FIXME: Ideally the gathered declarations and the declarations in the
|
||||
// @implementation should be mixed and sorted to get a true lexical order,
|
||||
// but right now we only care about getting the correct lexical parent, so
|
||||
// we can traverse the gathered nested declarations after the declarations
|
||||
// in the decl context.
|
||||
assert(!BaseType::getDerived().shouldTraversePostOrder() &&
|
||||
"post-order traversal is not supported for lexically ordered "
|
||||
"recursive ast visitor");
|
||||
for (Decl *D : LexicallyNestedDeclarations) {
|
||||
if (!BaseType::getDerived().TraverseDecl(D))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const SourceManager &SM;
|
||||
llvm::SmallVector<Decl *, 8> LexicallyNestedDeclarations;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H
|
@ -1,4 +1,4 @@
|
||||
//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===//
|
||||
//===- NestedNameSpecifier.h - C++ nested name specifiers -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -11,38 +11,42 @@
|
||||
// a C++ nested-name-specifier.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
|
||||
#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class CXXRecordDecl;
|
||||
class IdentifierInfo;
|
||||
class LangOptions;
|
||||
class NamespaceAliasDecl;
|
||||
class NamespaceDecl;
|
||||
class IdentifierInfo;
|
||||
struct PrintingPolicy;
|
||||
class Type;
|
||||
class TypeLoc;
|
||||
class LangOptions;
|
||||
|
||||
/// \brief Represents a C++ nested name specifier, such as
|
||||
/// "\::std::vector<int>::".
|
||||
///
|
||||
/// C++ nested name specifiers are the prefixes to qualified
|
||||
/// namespaces. For example, "foo::" in "foo::x" is a nested name
|
||||
/// names. For example, "foo::" in "foo::x" is a nested name
|
||||
/// specifier. Nested name specifiers are made up of a sequence of
|
||||
/// specifiers, each of which can be a namespace, type, identifier
|
||||
/// (for dependent names), decltype specifier, or the global specifier ('::').
|
||||
/// The last two specifiers can only appear at the start of a
|
||||
/// nested-namespace-specifier.
|
||||
class NestedNameSpecifier : public llvm::FoldingSetNode {
|
||||
|
||||
/// \brief Enumeration describing
|
||||
enum StoredSpecifierKind {
|
||||
StoredIdentifier = 0,
|
||||
@ -66,7 +70,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
|
||||
/// specifier '::'. Otherwise, the pointer is one of
|
||||
/// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
|
||||
/// specifier as encoded within the prefix.
|
||||
void* Specifier;
|
||||
void* Specifier = nullptr;
|
||||
|
||||
public:
|
||||
/// \brief The kind of specifier that completes this nested name
|
||||
@ -74,17 +78,23 @@ public:
|
||||
enum SpecifierKind {
|
||||
/// \brief An identifier, stored as an IdentifierInfo*.
|
||||
Identifier,
|
||||
|
||||
/// \brief A namespace, stored as a NamespaceDecl*.
|
||||
Namespace,
|
||||
|
||||
/// \brief A namespace alias, stored as a NamespaceAliasDecl*.
|
||||
NamespaceAlias,
|
||||
|
||||
/// \brief A type, stored as a Type*.
|
||||
TypeSpec,
|
||||
|
||||
/// \brief A type that was preceded by the 'template' keyword,
|
||||
/// stored as a Type*.
|
||||
TypeSpecWithTemplate,
|
||||
|
||||
/// \brief The global specifier '::'. There is no stored value.
|
||||
Global,
|
||||
|
||||
/// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
|
||||
/// the class it appeared in.
|
||||
Super
|
||||
@ -92,17 +102,11 @@ public:
|
||||
|
||||
private:
|
||||
/// \brief Builds the global specifier.
|
||||
NestedNameSpecifier()
|
||||
: Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
|
||||
NestedNameSpecifier() : Prefix(nullptr, StoredIdentifier) {}
|
||||
|
||||
/// \brief Copy constructor used internally to clone nested name
|
||||
/// specifiers.
|
||||
NestedNameSpecifier(const NestedNameSpecifier &Other)
|
||||
: llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
|
||||
Specifier(Other.Specifier) {
|
||||
}
|
||||
|
||||
void operator=(const NestedNameSpecifier &) = delete;
|
||||
NestedNameSpecifier(const NestedNameSpecifier &Other) = default;
|
||||
|
||||
/// \brief Either find or insert the given nested name specifier
|
||||
/// mockup in the given context.
|
||||
@ -110,6 +114,8 @@ private:
|
||||
const NestedNameSpecifier &Mockup);
|
||||
|
||||
public:
|
||||
NestedNameSpecifier &operator=(const NestedNameSpecifier &) = delete;
|
||||
|
||||
/// \brief Builds a specifier combining a prefix and an identifier.
|
||||
///
|
||||
/// The prefix must be dependent, since nested name specifiers
|
||||
@ -224,8 +230,8 @@ public:
|
||||
/// \brief A C++ nested-name-specifier augmented with source location
|
||||
/// information.
|
||||
class NestedNameSpecifierLoc {
|
||||
NestedNameSpecifier *Qualifier;
|
||||
void *Data;
|
||||
NestedNameSpecifier *Qualifier = nullptr;
|
||||
void *Data = nullptr;
|
||||
|
||||
/// \brief Determines the data length for the last component in the
|
||||
/// given nested-name-specifier.
|
||||
@ -237,12 +243,12 @@ class NestedNameSpecifierLoc {
|
||||
|
||||
public:
|
||||
/// \brief Construct an empty nested-name-specifier.
|
||||
NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
|
||||
NestedNameSpecifierLoc() = default;
|
||||
|
||||
/// \brief Construct a nested-name-specifier with source location information
|
||||
/// from
|
||||
NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
|
||||
: Qualifier(Qualifier), Data(Data) { }
|
||||
: Qualifier(Qualifier), Data(Data) {}
|
||||
|
||||
/// \brief Evalutes true when this nested-name-specifier location is
|
||||
/// non-empty.
|
||||
@ -339,7 +345,7 @@ public:
|
||||
class NestedNameSpecifierLocBuilder {
|
||||
/// \brief The current representation of the nested-name-specifier we're
|
||||
/// building.
|
||||
NestedNameSpecifier *Representation;
|
||||
NestedNameSpecifier *Representation = nullptr;
|
||||
|
||||
/// \brief Buffer used to store source-location information for the
|
||||
/// nested-name-specifier.
|
||||
@ -347,21 +353,18 @@ class NestedNameSpecifierLocBuilder {
|
||||
/// Note that we explicitly manage the buffer (rather than using a
|
||||
/// SmallVector) because \c Declarator expects it to be possible to memcpy()
|
||||
/// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
|
||||
char *Buffer;
|
||||
char *Buffer = nullptr;
|
||||
|
||||
/// \brief The size of the buffer used to store source-location information
|
||||
/// for the nested-name-specifier.
|
||||
unsigned BufferSize;
|
||||
unsigned BufferSize = 0;
|
||||
|
||||
/// \brief The capacity of the buffer used to store source-location
|
||||
/// information for the nested-name-specifier.
|
||||
unsigned BufferCapacity;
|
||||
unsigned BufferCapacity = 0;
|
||||
|
||||
public:
|
||||
NestedNameSpecifierLocBuilder()
|
||||
: Representation(nullptr), Buffer(nullptr), BufferSize(0),
|
||||
BufferCapacity(0) {}
|
||||
|
||||
NestedNameSpecifierLocBuilder() = default;
|
||||
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
|
||||
|
||||
NestedNameSpecifierLocBuilder &
|
||||
@ -451,6 +454,7 @@ public:
|
||||
/// \param ColonColonLoc The location of the trailing '::'.
|
||||
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
|
||||
SourceLocation SuperLoc, SourceLocation ColonColonLoc);
|
||||
|
||||
/// \brief Make a new nested-name-specifier from incomplete source-location
|
||||
/// information.
|
||||
///
|
||||
@ -511,6 +515,6 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
return DB;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -327,12 +327,13 @@ CAST_OPERATION(ZeroToOCLQueue)
|
||||
// Convert a pointer to a different address space.
|
||||
CAST_OPERATION(AddressSpaceConversion)
|
||||
|
||||
// Convert an integer initializer to an OpenCL sampler.
|
||||
// Convert an integer initializer to an OpenCL sampler.
|
||||
CAST_OPERATION(IntToOCLSampler)
|
||||
|
||||
//===- Binary Operations -------------------------------------------------===//
|
||||
// Operators listed in order of precedence.
|
||||
// Note that additions to this should also update the StmtVisitor class.
|
||||
// Note that additions to this should also update the StmtVisitor class and
|
||||
// BinaryOperator::getOverloadedOperator.
|
||||
|
||||
// [C++ 5.5] Pointer-to-member operators.
|
||||
BINARY_OPERATION(PtrMemD, ".*")
|
||||
@ -347,6 +348,8 @@ BINARY_OPERATION(Sub, "-")
|
||||
// [C99 6.5.7] Bitwise shift operators.
|
||||
BINARY_OPERATION(Shl, "<<")
|
||||
BINARY_OPERATION(Shr, ">>")
|
||||
// C++20 [expr.spaceship] Three-way comparison operator.
|
||||
BINARY_OPERATION(Cmp, "<=>")
|
||||
// [C99 6.5.8] Relational operators.
|
||||
BINARY_OPERATION(LT, "<")
|
||||
BINARY_OPERATION(GT, ">")
|
||||
@ -382,7 +385,8 @@ BINARY_OPERATION(Comma, ",")
|
||||
|
||||
|
||||
//===- Unary Operations ---------------------------------------------------===//
|
||||
// Note that additions to this should also update the StmtVisitor class.
|
||||
// Note that additions to this should also update the StmtVisitor class and
|
||||
// UnaryOperator::getOverloadedOperator.
|
||||
|
||||
// [C99 6.5.2.4] Postfix increment and decrement
|
||||
UNARY_OPERATION(PostInc, "++")
|
||||
|
@ -23,8 +23,6 @@ enum CastKind {
|
||||
#include "clang/AST/OperationKinds.def"
|
||||
};
|
||||
|
||||
static const CastKind CK_Invalid = static_cast<CastKind>(-1);
|
||||
|
||||
enum BinaryOperatorKind {
|
||||
#define BINARY_OPERATION(Name, Spelling) BO_##Name,
|
||||
#include "clang/AST/OperationKinds.def"
|
||||
|
@ -30,8 +30,8 @@ public:
|
||||
virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0;
|
||||
};
|
||||
|
||||
/// \brief Describes how types, statements, expressions, and
|
||||
/// declarations should be printed.
|
||||
/// Describes how types, statements, expressions, and declarations should be
|
||||
/// printed.
|
||||
///
|
||||
/// This type is intended to be small and suitable for passing by value.
|
||||
/// It is very frequently copied.
|
||||
@ -50,22 +50,24 @@ struct PrintingPolicy {
|
||||
UseVoidForZeroParams(!LO.CPlusPlus),
|
||||
TerseOutput(false), PolishForDeclaration(false),
|
||||
Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
|
||||
IncludeNewlines(true), MSVCFormatting(false) { }
|
||||
IncludeNewlines(true), MSVCFormatting(false),
|
||||
ConstantsAsWritten(false), SuppressImplicitBase(false),
|
||||
FullyQualifiedName(false) { }
|
||||
|
||||
/// \brief Adjust this printing policy for cases where it's known that
|
||||
/// we're printing C++ code (for instance, if AST dumping reaches a
|
||||
/// C++-only construct). This should not be used if a real LangOptions
|
||||
/// object is available.
|
||||
/// Adjust this printing policy for cases where it's known that we're
|
||||
/// printing C++ code (for instance, if AST dumping reaches a C++-only
|
||||
/// construct). This should not be used if a real LangOptions object is
|
||||
/// available.
|
||||
void adjustForCPlusPlus() {
|
||||
SuppressTagKeyword = true;
|
||||
Bool = true;
|
||||
UseVoidForZeroParams = false;
|
||||
}
|
||||
|
||||
/// \brief The number of spaces to use to indent each line.
|
||||
/// The number of spaces to use to indent each line.
|
||||
unsigned Indentation : 8;
|
||||
|
||||
/// \brief Whether we should suppress printing of the actual specifiers for
|
||||
/// Whether we should suppress printing of the actual specifiers for
|
||||
/// the given type or declaration.
|
||||
///
|
||||
/// This flag is only used when we are printing declarators beyond
|
||||
@ -81,7 +83,7 @@ struct PrintingPolicy {
|
||||
/// "const int" type specifier and instead only print the "*y".
|
||||
bool SuppressSpecifiers : 1;
|
||||
|
||||
/// \brief Whether type printing should skip printing the tag keyword.
|
||||
/// Whether type printing should skip printing the tag keyword.
|
||||
///
|
||||
/// This is used when printing the inner type of elaborated types,
|
||||
/// (as the tag keyword is part of the elaborated type):
|
||||
@ -91,7 +93,7 @@ struct PrintingPolicy {
|
||||
/// \endcode
|
||||
bool SuppressTagKeyword : 1;
|
||||
|
||||
/// \brief When true, include the body of a tag definition.
|
||||
/// When true, include the body of a tag definition.
|
||||
///
|
||||
/// This is used to place the definition of a struct
|
||||
/// in the middle of another declaration as with:
|
||||
@ -101,14 +103,14 @@ struct PrintingPolicy {
|
||||
/// \endcode
|
||||
bool IncludeTagDefinition : 1;
|
||||
|
||||
/// \brief Suppresses printing of scope specifiers.
|
||||
/// Suppresses printing of scope specifiers.
|
||||
bool SuppressScope : 1;
|
||||
|
||||
/// \brief Suppress printing parts of scope specifiers that don't need
|
||||
/// Suppress printing parts of scope specifiers that don't need
|
||||
/// to be written, e.g., for inline or anonymous namespaces.
|
||||
bool SuppressUnwrittenScope : 1;
|
||||
|
||||
/// \brief Suppress printing of variable initializers.
|
||||
/// Suppress printing of variable initializers.
|
||||
///
|
||||
/// This flag is used when printing the loop variable in a for-range
|
||||
/// statement. For example, given:
|
||||
@ -121,8 +123,8 @@ struct PrintingPolicy {
|
||||
/// internal initializer constructed for x will not be printed.
|
||||
bool SuppressInitializers : 1;
|
||||
|
||||
/// \brief Whether we should print the sizes of constant array expressions
|
||||
/// as written in the sources.
|
||||
/// Whether we should print the sizes of constant array expressions as written
|
||||
/// in the sources.
|
||||
///
|
||||
/// This flag determines whether array types declared as
|
||||
///
|
||||
@ -139,67 +141,90 @@ struct PrintingPolicy {
|
||||
/// \endcode
|
||||
bool ConstantArraySizeAsWritten : 1;
|
||||
|
||||
/// \brief When printing an anonymous tag name, also print the location of
|
||||
/// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just
|
||||
/// prints "(anonymous)" for the name.
|
||||
/// When printing an anonymous tag name, also print the location of that
|
||||
/// entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just prints
|
||||
/// "(anonymous)" for the name.
|
||||
bool AnonymousTagLocations : 1;
|
||||
|
||||
/// \brief When true, suppress printing of the __strong lifetime qualifier in
|
||||
/// ARC.
|
||||
/// When true, suppress printing of the __strong lifetime qualifier in ARC.
|
||||
unsigned SuppressStrongLifetime : 1;
|
||||
|
||||
/// \brief When true, suppress printing of lifetime qualifier in
|
||||
/// ARC.
|
||||
/// When true, suppress printing of lifetime qualifier in ARC.
|
||||
unsigned SuppressLifetimeQualifiers : 1;
|
||||
|
||||
/// When true, suppresses printing template arguments in names of C++
|
||||
/// constructors.
|
||||
unsigned SuppressTemplateArgsInCXXConstructors : 1;
|
||||
|
||||
/// \brief Whether we can use 'bool' rather than '_Bool' (even if the language
|
||||
/// Whether we can use 'bool' rather than '_Bool' (even if the language
|
||||
/// doesn't actually have 'bool', because, e.g., it is defined as a macro).
|
||||
unsigned Bool : 1;
|
||||
|
||||
/// \brief Whether we can use 'restrict' rather than '__restrict'.
|
||||
/// Whether we can use 'restrict' rather than '__restrict'.
|
||||
unsigned Restrict : 1;
|
||||
|
||||
/// \brief Whether we can use 'alignof' rather than '__alignof'.
|
||||
/// Whether we can use 'alignof' rather than '__alignof'.
|
||||
unsigned Alignof : 1;
|
||||
|
||||
/// \brief Whether we can use '_Alignof' rather than '__alignof'.
|
||||
/// Whether we can use '_Alignof' rather than '__alignof'.
|
||||
unsigned UnderscoreAlignof : 1;
|
||||
|
||||
/// \brief Whether we should use '(void)' rather than '()' for a function
|
||||
/// prototype with zero parameters.
|
||||
/// Whether we should use '(void)' rather than '()' for a function prototype
|
||||
/// with zero parameters.
|
||||
unsigned UseVoidForZeroParams : 1;
|
||||
|
||||
/// \brief Provide a 'terse' output.
|
||||
/// Provide a 'terse' output.
|
||||
///
|
||||
/// For example, in this mode we don't print function bodies, class members,
|
||||
/// declarations inside namespaces etc. Effectively, this should print
|
||||
/// only the requested declaration.
|
||||
unsigned TerseOutput : 1;
|
||||
|
||||
/// \brief When true, do certain refinement needed for producing proper
|
||||
/// declaration tag; such as, do not print attributes attached to the declaration.
|
||||
/// When true, do certain refinement needed for producing proper declaration
|
||||
/// tag; such as, do not print attributes attached to the declaration.
|
||||
///
|
||||
unsigned PolishForDeclaration : 1;
|
||||
|
||||
/// \brief When true, print the half-precision floating-point type as 'half'
|
||||
/// When true, print the half-precision floating-point type as 'half'
|
||||
/// instead of '__fp16'
|
||||
unsigned Half : 1;
|
||||
|
||||
/// \brief When true, print the built-in wchar_t type as __wchar_t. For use in
|
||||
/// When true, print the built-in wchar_t type as __wchar_t. For use in
|
||||
/// Microsoft mode when wchar_t is not available.
|
||||
unsigned MSWChar : 1;
|
||||
|
||||
/// \brief When true, include newlines after statements like "break", etc.
|
||||
/// When true, include newlines after statements like "break", etc.
|
||||
unsigned IncludeNewlines : 1;
|
||||
|
||||
/// \brief Use whitespace and punctuation like MSVC does. In particular, this
|
||||
/// prints anonymous namespaces as `anonymous namespace' and does not insert
|
||||
/// spaces after template arguments.
|
||||
/// Use whitespace and punctuation like MSVC does. In particular, this prints
|
||||
/// anonymous namespaces as `anonymous namespace' and does not insert spaces
|
||||
/// after template arguments.
|
||||
bool MSVCFormatting : 1;
|
||||
|
||||
/// Whether we should print the constant expressions as written in the
|
||||
/// sources.
|
||||
///
|
||||
/// This flag determines whether constants expressions like
|
||||
///
|
||||
/// \code
|
||||
/// 0x10
|
||||
/// 2.5e3
|
||||
/// \endcode
|
||||
///
|
||||
/// will be printed as written or as follows:
|
||||
///
|
||||
/// \code
|
||||
/// 0x10
|
||||
/// 2.5e3
|
||||
/// \endcode
|
||||
bool ConstantsAsWritten : 1;
|
||||
|
||||
/// When true, don't print the implicit 'self' or 'this' expressions.
|
||||
bool SuppressImplicitBase : 1;
|
||||
|
||||
/// When true, print the fully qualified name of function declarations.
|
||||
/// This is the opposite of SuppressScope and thus overrules it.
|
||||
bool FullyQualifiedName : 1;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
@ -56,8 +56,8 @@
|
||||
//
|
||||
// ===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
|
||||
#define LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
|
||||
#ifndef LLVM_CLANG_AST_QUALTYPENAMES_H
|
||||
#define LLVM_CLANG_AST_QUALTYPENAMES_H
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
|
||||
@ -71,9 +71,20 @@ namespace TypeName {
|
||||
/// \param[in] Ctx - the ASTContext to be used.
|
||||
/// \param[in] WithGlobalNsPrefix - If true, then the global namespace
|
||||
/// specifier "::" will be prepended to the fully qualified name.
|
||||
std::string getFullyQualifiedName(QualType QT,
|
||||
const ASTContext &Ctx,
|
||||
std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx,
|
||||
bool WithGlobalNsPrefix = false);
|
||||
} // end namespace TypeName
|
||||
} // end namespace clang
|
||||
#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
|
||||
|
||||
/// \brief Generates a QualType that can be used to name the same type
|
||||
/// if used at the end of the current translation unit. This ignores
|
||||
/// issues such as type shadowing.
|
||||
///
|
||||
/// \param[in] QT - the type for which the fully qualified type will be
|
||||
/// returned.
|
||||
/// \param[in] Ctx - the ASTContext to be used.
|
||||
/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
|
||||
/// specifier "::" should be prepended or not.
|
||||
QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
|
||||
bool WithGlobalNsPrefix = false);
|
||||
} // end namespace TypeName
|
||||
} // end namespace clang
|
||||
#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
|
@ -1,4 +1,4 @@
|
||||
//===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===//
|
||||
//===- RecordLayout.h - Layout information for a struct/union ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -14,15 +14,20 @@
|
||||
#ifndef LLVM_CLANG_AST_RECORDLAYOUT_H
|
||||
#define LLVM_CLANG_AST_RECORDLAYOUT_H
|
||||
|
||||
#include "clang/AST/ASTVector.h"
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class FieldDecl;
|
||||
class RecordDecl;
|
||||
class CXXRecordDecl;
|
||||
|
||||
class ASTContext;
|
||||
class CXXRecordDecl;
|
||||
|
||||
/// ASTRecordLayout -
|
||||
/// This class contains layout information for one RecordDecl,
|
||||
@ -42,21 +47,21 @@ public:
|
||||
/// Whether this virtual base requires a vtordisp field in the
|
||||
/// Microsoft ABI. These fields are required for certain operations
|
||||
/// in constructors and destructors.
|
||||
bool HasVtorDisp;
|
||||
bool HasVtorDisp = false;
|
||||
|
||||
public:
|
||||
VBaseInfo() = default;
|
||||
VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp)
|
||||
: VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
|
||||
|
||||
bool hasVtorDisp() const { return HasVtorDisp; }
|
||||
|
||||
VBaseInfo() : HasVtorDisp(false) {}
|
||||
|
||||
VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) :
|
||||
VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
|
||||
};
|
||||
|
||||
typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>
|
||||
VBaseOffsetsMapTy;
|
||||
using VBaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>;
|
||||
|
||||
private:
|
||||
friend class ASTContext;
|
||||
|
||||
/// Size - Size of record in characters.
|
||||
CharUnits Size;
|
||||
|
||||
@ -117,7 +122,7 @@ private:
|
||||
const CXXRecordDecl *BaseSharingVBPtr;
|
||||
|
||||
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
|
||||
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
|
||||
using BaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, CharUnits>;
|
||||
|
||||
/// BaseOffsets - Contains a map from base classes to their offset.
|
||||
BaseOffsetsMapTy BaseOffsets;
|
||||
@ -128,16 +133,15 @@ private:
|
||||
|
||||
/// CXXInfo - If the record layout is for a C++ record, this will have
|
||||
/// C++ specific information about the record.
|
||||
CXXRecordLayoutInfo *CXXInfo;
|
||||
|
||||
friend class ASTContext;
|
||||
CXXRecordLayoutInfo *CXXInfo = nullptr;
|
||||
|
||||
ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
|
||||
CharUnits requiredAlignment, CharUnits datasize,
|
||||
ArrayRef<uint64_t> fieldoffsets);
|
||||
|
||||
using BaseOffsetsMapTy = CXXRecordLayoutInfo::BaseOffsetsMapTy;
|
||||
|
||||
// Constructor for C++ records.
|
||||
typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
|
||||
ASTRecordLayout(const ASTContext &Ctx,
|
||||
CharUnits size, CharUnits alignment,
|
||||
CharUnits requiredAlignment,
|
||||
@ -159,9 +163,9 @@ private:
|
||||
|
||||
void Destroy(ASTContext &Ctx);
|
||||
|
||||
ASTRecordLayout(const ASTRecordLayout &) = delete;
|
||||
void operator=(const ASTRecordLayout &) = delete;
|
||||
public:
|
||||
ASTRecordLayout(const ASTRecordLayout &) = delete;
|
||||
ASTRecordLayout &operator=(const ASTRecordLayout &) = delete;
|
||||
|
||||
/// getAlignment - Get the record alignment in characters.
|
||||
CharUnits getAlignment() const { return Alignment; }
|
||||
@ -305,6 +309,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_RECORDLAYOUT_H
|
||||
|
@ -63,8 +63,8 @@
|
||||
OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \
|
||||
OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \
|
||||
OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
|
||||
OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \
|
||||
OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
|
||||
OPERATOR(NE) OPERATOR(Cmp) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \
|
||||
OPERATOR(LAnd) OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
|
||||
|
||||
// All compound assign operators.
|
||||
#define CAO_LIST() \
|
||||
@ -83,7 +83,7 @@ namespace clang {
|
||||
return false; \
|
||||
} while (false)
|
||||
|
||||
/// \brief A class that does preordor or postorder
|
||||
/// \brief A class that does preorder or postorder
|
||||
/// depth-first traversal on the entire Clang AST and visits each node.
|
||||
///
|
||||
/// This class performs three distinct tasks:
|
||||
@ -267,6 +267,12 @@ public:
|
||||
bool TraverseTemplateArguments(const TemplateArgument *Args,
|
||||
unsigned NumArgs);
|
||||
|
||||
/// \brief Recursively visit a base specifier. This can be overridden by a
|
||||
/// subclass.
|
||||
///
|
||||
/// \returns false if the visitation was terminated early, true otherwise.
|
||||
bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base);
|
||||
|
||||
/// \brief Recursively visit a constructor initializer. This
|
||||
/// automatically dispatches to another visitor for the initializer
|
||||
/// expression, but not for the name of the initializer, so may
|
||||
@ -309,6 +315,8 @@ public:
|
||||
|
||||
// ---- Methods on Stmts ----
|
||||
|
||||
Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
|
||||
|
||||
private:
|
||||
template<typename T, typename U>
|
||||
struct has_same_member_pointer_type : std::false_type {};
|
||||
@ -491,6 +499,8 @@ public:
|
||||
bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
|
||||
#include "clang/AST/DeclNodes.inc"
|
||||
|
||||
bool canIgnoreChildDeclWhileTraversingDeclContext(const Decl *Child);
|
||||
|
||||
private:
|
||||
// These are helper methods used by more than one Traverse* method.
|
||||
bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
|
||||
@ -978,6 +988,11 @@ DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
|
||||
TRY_TO(TraverseStmt(T->getSizeExpr()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
|
||||
TRY_TO(TraverseStmt(T->getAddrSpaceExpr()));
|
||||
TRY_TO(TraverseType(T->getPointeeType()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
|
||||
if (T->getSizeExpr())
|
||||
TRY_TO(TraverseStmt(T->getSizeExpr()));
|
||||
@ -1188,6 +1203,11 @@ DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
|
||||
return TraverseArrayTypeLocHelper(TL);
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, {
|
||||
TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr()));
|
||||
TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType()));
|
||||
})
|
||||
|
||||
// FIXME: order? why not size expr first?
|
||||
// FIXME: base VectorTypeLoc is unfinished
|
||||
DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
|
||||
@ -1338,15 +1358,21 @@ DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
|
||||
// Therefore each Traverse* only needs to worry about children other
|
||||
// than those.
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::canIgnoreChildDeclWhileTraversingDeclContext(
|
||||
const Decl *Child) {
|
||||
// BlockDecls and CapturedDecls are traversed through BlockExprs and
|
||||
// CapturedStmts respectively.
|
||||
return isa<BlockDecl>(Child) || isa<CapturedDecl>(Child);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
|
||||
if (!DC)
|
||||
return true;
|
||||
|
||||
for (auto *Child : DC->decls()) {
|
||||
// BlockDecls and CapturedDecls are traversed through BlockExprs and
|
||||
// CapturedStmts respectively.
|
||||
if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
|
||||
if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
|
||||
TRY_TO(TraverseDecl(Child));
|
||||
}
|
||||
|
||||
@ -1674,8 +1700,8 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
|
||||
// template declarations.
|
||||
#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
|
||||
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
|
||||
TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
|
||||
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
|
||||
TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
|
||||
\
|
||||
/* By default, we do not traverse the instantiations of \
|
||||
class templates since they do not appear in the user code. The \
|
||||
@ -1768,13 +1794,20 @@ bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::TraverseCXXBaseSpecifier(
|
||||
const CXXBaseSpecifier &Base) {
|
||||
TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
|
||||
if (!TraverseRecordHelper(D))
|
||||
return false;
|
||||
if (D->isCompleteDefinition()) {
|
||||
for (const auto &I : D->bases()) {
|
||||
TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
|
||||
TRY_TO(TraverseCXXBaseSpecifier(I));
|
||||
}
|
||||
// We don't traverse the friends or the conversions, as they are
|
||||
// already in decls_begin()/decls_end().
|
||||
@ -2057,7 +2090,7 @@ DEF_TRAVERSE_DECL(ParmVarDecl, {
|
||||
TRY_TO(WalkUpFrom##STMT(S)); \
|
||||
{ CODE; } \
|
||||
if (ShouldVisitChildren) { \
|
||||
for (Stmt *SubStmt : S->children()) { \
|
||||
for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
|
||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
|
||||
} \
|
||||
} \
|
||||
@ -3038,6 +3071,30 @@ bool RecursiveASTVisitor<Derived>::VisitOMPTaskReductionClause(
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPInReductionClause(
|
||||
OMPInReductionClause *C) {
|
||||
TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
|
||||
TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
|
||||
TRY_TO(VisitOMPClauseList(C));
|
||||
TRY_TO(VisitOMPClauseWithPostUpdate(C));
|
||||
for (auto *E : C->privates()) {
|
||||
TRY_TO(TraverseStmt(E));
|
||||
}
|
||||
for (auto *E : C->lhs_exprs()) {
|
||||
TRY_TO(TraverseStmt(E));
|
||||
}
|
||||
for (auto *E : C->rhs_exprs()) {
|
||||
TRY_TO(TraverseStmt(E));
|
||||
}
|
||||
for (auto *E : C->reduction_ops()) {
|
||||
TRY_TO(TraverseStmt(E));
|
||||
}
|
||||
for (auto *E : C->taskgroup_descriptors())
|
||||
TRY_TO(TraverseStmt(E));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
|
||||
TRY_TO(VisitOMPClauseList(C));
|
||||
@ -3052,6 +3109,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) {
|
||||
TRY_TO(VisitOMPClauseWithPreInit(C));
|
||||
TRY_TO(TraverseStmt(C->getDevice()));
|
||||
return true;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- Redeclarable.h - Base for Decls that can be redeclared -*- C++ -*-====//
|
||||
//===- Redeclarable.h - Base for Decls that can be redeclared --*- C++ -*-====//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -15,11 +15,18 @@
|
||||
#define LLVM_CLANG_AST_REDECLARABLE_H
|
||||
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class Decl;
|
||||
|
||||
// Some notes on redeclarables:
|
||||
//
|
||||
@ -82,21 +89,21 @@ protected:
|
||||
class DeclLink {
|
||||
/// A pointer to a known latest declaration, either statically known or
|
||||
/// generationally updated as decls are added by an external source.
|
||||
typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
|
||||
&ExternalASTSource::CompleteRedeclChain>
|
||||
KnownLatest;
|
||||
using KnownLatest =
|
||||
LazyGenerationalUpdatePtr<const Decl *, Decl *,
|
||||
&ExternalASTSource::CompleteRedeclChain>;
|
||||
|
||||
/// We store a pointer to the ASTContext in the UninitializedLatest
|
||||
/// pointer, but to avoid circular type dependencies when we steal the low
|
||||
/// bits of this pointer, we use a raw void* here.
|
||||
typedef const void *UninitializedLatest;
|
||||
using UninitializedLatest = const void *;
|
||||
|
||||
typedef Decl *Previous;
|
||||
using Previous = Decl *;
|
||||
|
||||
/// A pointer to either an uninitialized latest declaration (where either
|
||||
/// we've not yet set the previous decl or there isn't one), or to a known
|
||||
/// previous declaration.
|
||||
typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
|
||||
using NotKnownLatest = llvm::PointerUnion<Previous, UninitializedLatest>;
|
||||
|
||||
mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
|
||||
|
||||
@ -106,8 +113,7 @@ protected:
|
||||
|
||||
DeclLink(LatestTag, const ASTContext &Ctx)
|
||||
: Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
|
||||
DeclLink(PreviousTag, decl_type *D)
|
||||
: Next(NotKnownLatest(Previous(D))) {}
|
||||
DeclLink(PreviousTag, decl_type *D) : Next(NotKnownLatest(Previous(D))) {}
|
||||
|
||||
bool NextIsPrevious() const {
|
||||
return Next.is<NotKnownLatest>() &&
|
||||
@ -182,6 +188,7 @@ protected:
|
||||
///
|
||||
/// If there is only one declaration, it is <pointer to self, true>
|
||||
DeclLink RedeclLink;
|
||||
|
||||
decl_type *First;
|
||||
|
||||
decl_type *getNextRedeclaration() const {
|
||||
@ -189,8 +196,12 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
Redeclarable(const ASTContext &Ctx)
|
||||
: RedeclLink(LatestDeclLink(Ctx)), First(static_cast<decl_type *>(this)) {}
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
|
||||
Redeclarable(const ASTContext &Ctx)
|
||||
: RedeclLink(LatestDeclLink(Ctx)),
|
||||
First(static_cast<decl_type *>(this)) {}
|
||||
|
||||
/// \brief Return the previous declaration of this declaration or NULL if this
|
||||
/// is the first declaration.
|
||||
@ -232,20 +243,19 @@ public:
|
||||
/// \brief Iterates through all the redeclarations of the same decl.
|
||||
class redecl_iterator {
|
||||
/// Current - The current declaration.
|
||||
decl_type *Current;
|
||||
decl_type *Current = nullptr;
|
||||
decl_type *Starter;
|
||||
bool PassedFirst;
|
||||
bool PassedFirst = false;
|
||||
|
||||
public:
|
||||
typedef decl_type* value_type;
|
||||
typedef decl_type* reference;
|
||||
typedef decl_type* pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
using value_type = decl_type *;
|
||||
using reference = decl_type *;
|
||||
using pointer = decl_type *;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
redecl_iterator() : Current(nullptr) { }
|
||||
explicit redecl_iterator(decl_type *C)
|
||||
: Current(C), Starter(C), PassedFirst(false) { }
|
||||
redecl_iterator() = default;
|
||||
explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) {}
|
||||
|
||||
reference operator*() const { return Current; }
|
||||
pointer operator->() const { return Current; }
|
||||
@ -282,7 +292,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef llvm::iterator_range<redecl_iterator> redecl_range;
|
||||
using redecl_range = llvm::iterator_range<redecl_iterator>;
|
||||
|
||||
/// \brief Returns an iterator range for all the redeclarations of the same
|
||||
/// decl. It will iterate at least once (when this decl is the only one).
|
||||
@ -294,9 +304,6 @@ public:
|
||||
|
||||
redecl_iterator redecls_begin() const { return redecls().begin(); }
|
||||
redecl_iterator redecls_end() const { return redecls().end(); }
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
};
|
||||
|
||||
/// \brief Get the primary declaration for a declaration from an AST file. That
|
||||
@ -309,7 +316,7 @@ Decl *getPrimaryMergedDecl(Decl *D);
|
||||
template<typename decl_type>
|
||||
class Mergeable {
|
||||
public:
|
||||
Mergeable() {}
|
||||
Mergeable() = default;
|
||||
|
||||
/// \brief Return the first declaration of this declaration or itself if this
|
||||
/// is the only declaration.
|
||||
@ -344,7 +351,7 @@ public:
|
||||
/// remember to call getCanonicalDecl() everywhere.
|
||||
template <typename decl_type> class CanonicalDeclPtr {
|
||||
public:
|
||||
CanonicalDeclPtr() : Ptr(nullptr) {}
|
||||
CanonicalDeclPtr() = default;
|
||||
CanonicalDeclPtr(decl_type *Ptr)
|
||||
: Ptr(Ptr ? Ptr->getCanonicalDecl() : nullptr) {}
|
||||
CanonicalDeclPtr(const CanonicalDeclPtr &) = default;
|
||||
@ -362,11 +369,13 @@ public:
|
||||
private:
|
||||
friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>;
|
||||
|
||||
decl_type *Ptr;
|
||||
decl_type *Ptr = nullptr;
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <typename decl_type>
|
||||
struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
|
||||
using CanonicalDeclPtr = clang::CanonicalDeclPtr<decl_type>;
|
||||
@ -395,6 +404,7 @@ struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
|
||||
return BaseInfo::isEqual(LHS, RHS);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_REDECLARABLE_H
|
||||
|
File diff suppressed because it is too large
Load Diff
242
contrib/llvm/tools/clang/include/clang/AST/StmtDataCollectors.td
Normal file
242
contrib/llvm/tools/clang/include/clang/AST/StmtDataCollectors.td
Normal file
@ -0,0 +1,242 @@
|
||||
class Stmt {
|
||||
code Code = [{
|
||||
addData(S->getStmtClass());
|
||||
// This ensures that non-macro-generated code isn't identical to
|
||||
// macro-generated code.
|
||||
addData(data_collection::getMacroStack(S->getLocStart(), Context));
|
||||
addData(data_collection::getMacroStack(S->getLocEnd(), Context));
|
||||
}];
|
||||
}
|
||||
|
||||
class Expr {
|
||||
code Code = [{
|
||||
addData(S->getType());
|
||||
}];
|
||||
}
|
||||
|
||||
//--- Builtin functionality ----------------------------------------------//
|
||||
class ArrayTypeTraitExpr {
|
||||
code Code = [{
|
||||
addData(S->getTrait());
|
||||
}];
|
||||
}
|
||||
class ExpressionTraitExpr {
|
||||
code Code = [{
|
||||
addData(S->getTrait());
|
||||
}];
|
||||
}
|
||||
class PredefinedExpr {
|
||||
code Code = [{
|
||||
addData(S->getIdentType());
|
||||
}];
|
||||
}
|
||||
class TypeTraitExpr {
|
||||
code Code = [{
|
||||
addData(S->getTrait());
|
||||
for (unsigned i = 0; i < S->getNumArgs(); ++i)
|
||||
addData(S->getArg(i)->getType());
|
||||
}];
|
||||
}
|
||||
|
||||
//--- Calls --------------------------------------------------------------//
|
||||
class CallExpr {
|
||||
code Code = [{
|
||||
// Function pointers don't have a callee and we just skip hashing it.
|
||||
if (const FunctionDecl *D = S->getDirectCallee()) {
|
||||
// If the function is a template specialization, we also need to handle
|
||||
// the template arguments as they are not included in the qualified name.
|
||||
if (auto Args = D->getTemplateSpecializationArgs()) {
|
||||
std::string ArgString;
|
||||
|
||||
// Print all template arguments into ArgString
|
||||
llvm::raw_string_ostream OS(ArgString);
|
||||
for (unsigned i = 0; i < Args->size(); ++i) {
|
||||
Args->get(i).print(Context.getLangOpts(), OS);
|
||||
// Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
|
||||
OS << '\n';
|
||||
}
|
||||
OS.flush();
|
||||
|
||||
addData(ArgString);
|
||||
}
|
||||
addData(D->getQualifiedNameAsString());
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
//--- Value references ---------------------------------------------------//
|
||||
class DeclRefExpr {
|
||||
code Code = [{
|
||||
addData(S->getDecl()->getQualifiedNameAsString());
|
||||
}];
|
||||
}
|
||||
class MemberExpr {
|
||||
code Code = [{
|
||||
addData(S->getMemberDecl()->getName());
|
||||
}];
|
||||
}
|
||||
|
||||
//--- Literals -----------------------------------------------------------//
|
||||
class IntegerLiteral {
|
||||
code Code = [{
|
||||
addData(llvm::hash_value(S->getValue()));
|
||||
}];
|
||||
}
|
||||
class FloatingLiteral {
|
||||
code Code = [{
|
||||
addData(llvm::hash_value(S->getValue()));
|
||||
}];
|
||||
}
|
||||
class StringLiteral {
|
||||
code Code = [{
|
||||
addData(S->getString());
|
||||
}];
|
||||
}
|
||||
class CXXBoolLiteralExpr {
|
||||
code Code = [{
|
||||
addData(S->getValue());
|
||||
}];
|
||||
}
|
||||
class CharacterLiteral {
|
||||
code Code = [{
|
||||
addData(S->getValue());
|
||||
}];
|
||||
}
|
||||
|
||||
//--- Exceptions ---------------------------------------------------------//
|
||||
class CXXCatchStmt {
|
||||
code Code = [{
|
||||
addData(S->getCaughtType());
|
||||
}];
|
||||
}
|
||||
|
||||
//--- C++ OOP Stmts ------------------------------------------------------//
|
||||
class CXXDeleteExpr {
|
||||
code Code = [{
|
||||
addData(S->isArrayFormAsWritten()); addData(S->isGlobalDelete());
|
||||
}];
|
||||
}
|
||||
|
||||
//--- Casts --------------------------------------------------------------//
|
||||
class ObjCBridgedCastExpr {
|
||||
code Code = [{
|
||||
addData(S->getBridgeKind());
|
||||
}];
|
||||
}
|
||||
|
||||
//--- Miscellaneous Exprs ------------------------------------------------//
|
||||
class BinaryOperator {
|
||||
code Code = [{
|
||||
addData(S->getOpcode());
|
||||
}];
|
||||
}
|
||||
class UnaryOperator {
|
||||
code Code = [{
|
||||
addData(S->getOpcode());
|
||||
}];
|
||||
}
|
||||
|
||||
//--- Control flow -------------------------------------------------------//
|
||||
class GotoStmt {
|
||||
code Code = [{
|
||||
addData(S->getLabel()->getName());
|
||||
}];
|
||||
}
|
||||
class IndirectGotoStmt {
|
||||
code Code = [{
|
||||
if (S->getConstantTarget())
|
||||
addData(S->getConstantTarget()->getName());
|
||||
}];
|
||||
}
|
||||
class LabelStmt {
|
||||
code Code = [{
|
||||
addData(S->getDecl()->getName());
|
||||
}];
|
||||
}
|
||||
class MSDependentExistsStmt {
|
||||
code Code = [{
|
||||
addData(S->isIfExists());
|
||||
}];
|
||||
}
|
||||
class AddrLabelExpr {
|
||||
code Code = [{
|
||||
addData(S->getLabel()->getName());
|
||||
}];
|
||||
}
|
||||
|
||||
//--- Objective-C --------------------------------------------------------//
|
||||
class ObjCIndirectCopyRestoreExpr {
|
||||
code Code = [{
|
||||
addData(S->shouldCopy());
|
||||
}];
|
||||
}
|
||||
class ObjCPropertyRefExpr {
|
||||
code Code = [{
|
||||
addData(S->isSuperReceiver()); addData(S->isImplicitProperty());
|
||||
}];
|
||||
}
|
||||
class ObjCAtCatchStmt {
|
||||
code Code = [{
|
||||
addData(S->hasEllipsis());
|
||||
}];
|
||||
}
|
||||
|
||||
//--- Miscellaneous Stmts ------------------------------------------------//
|
||||
class CXXFoldExpr {
|
||||
code Code = [{
|
||||
addData(S->isRightFold()); addData(S->getOperator());
|
||||
}];
|
||||
}
|
||||
class GenericSelectionExpr {
|
||||
code Code = [{
|
||||
for (unsigned i = 0; i < S->getNumAssocs(); ++i) {
|
||||
addData(S->getAssocType(i));
|
||||
}
|
||||
}];
|
||||
}
|
||||
class LambdaExpr {
|
||||
code Code = [{
|
||||
for (const LambdaCapture &C : S->captures()) {
|
||||
addData(C.isPackExpansion());
|
||||
addData(C.getCaptureKind());
|
||||
if (C.capturesVariable())
|
||||
addData(C.getCapturedVar()->getType());
|
||||
}
|
||||
addData(S->isGenericLambda());
|
||||
addData(S->isMutable());
|
||||
}];
|
||||
}
|
||||
class DeclStmt {
|
||||
code Code = [{
|
||||
auto numDecls = std::distance(S->decl_begin(), S->decl_end());
|
||||
addData(static_cast<unsigned>(numDecls));
|
||||
for (const Decl *D : S->decls()) {
|
||||
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
||||
addData(VD->getType());
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
class AsmStmt {
|
||||
code Code = [{
|
||||
addData(S->isSimple());
|
||||
addData(S->isVolatile());
|
||||
addData(S->generateAsmString(Context));
|
||||
for (unsigned i = 0; i < S->getNumInputs(); ++i) {
|
||||
addData(S->getInputConstraint(i));
|
||||
}
|
||||
for (unsigned i = 0; i < S->getNumOutputs(); ++i) {
|
||||
addData(S->getOutputConstraint(i));
|
||||
}
|
||||
for (unsigned i = 0; i < S->getNumClobbers(); ++i) {
|
||||
addData(S->getClobber(i));
|
||||
}
|
||||
}];
|
||||
}
|
||||
class AttributedStmt {
|
||||
code Code = [{
|
||||
for (const Attr *A : S->getAttrs()) {
|
||||
addData(std::string(A->getSpelling()));
|
||||
}
|
||||
}];
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
//===--- StmtGraphTraits.h - Graph Traits for the class Stmt ----*- C++ -*-===//
|
||||
//===- StmtGraphTraits.h - Graph Traits for the class Stmt ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -21,13 +21,10 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
//template <typename T> struct GraphTraits;
|
||||
|
||||
|
||||
template <> struct GraphTraits<clang::Stmt*> {
|
||||
typedef clang::Stmt * NodeRef;
|
||||
typedef clang::Stmt::child_iterator ChildIteratorType;
|
||||
typedef llvm::df_iterator<clang::Stmt*> nodes_iterator;
|
||||
template <> struct GraphTraits<clang::Stmt *> {
|
||||
using NodeRef = clang::Stmt *;
|
||||
using ChildIteratorType = clang::Stmt::child_iterator;
|
||||
using nodes_iterator = llvm::df_iterator<clang::Stmt *>;
|
||||
|
||||
static NodeRef getEntryNode(clang::Stmt *S) { return S; }
|
||||
|
||||
@ -50,11 +47,10 @@ template <> struct GraphTraits<clang::Stmt*> {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <> struct GraphTraits<const clang::Stmt*> {
|
||||
typedef const clang::Stmt * NodeRef;
|
||||
typedef clang::Stmt::const_child_iterator ChildIteratorType;
|
||||
typedef llvm::df_iterator<const clang::Stmt*> nodes_iterator;
|
||||
template <> struct GraphTraits<const clang::Stmt *> {
|
||||
using NodeRef = const clang::Stmt *;
|
||||
using ChildIteratorType = clang::Stmt::const_child_iterator;
|
||||
using nodes_iterator = llvm::df_iterator<const clang::Stmt *>;
|
||||
|
||||
static NodeRef getEntryNode(const clang::Stmt *S) { return S; }
|
||||
|
||||
@ -77,7 +73,6 @@ template <> struct GraphTraits<const clang::Stmt*> {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_STMTGRAPHTRAITS_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- StmtIterator.h - Iterators for Statements --------------*- C++ -*-===//
|
||||
//===- StmtIterator.h - Iterators for Statements ----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -14,31 +14,38 @@
|
||||
#ifndef LLVM_CLANG_AST_STMTITERATOR_H
|
||||
#define LLVM_CLANG_AST_STMTITERATOR_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class Stmt;
|
||||
class Decl;
|
||||
class Stmt;
|
||||
class VariableArrayType;
|
||||
|
||||
class StmtIteratorBase {
|
||||
protected:
|
||||
enum { StmtMode = 0x0, SizeOfTypeVAMode = 0x1, DeclGroupMode = 0x2,
|
||||
Flags = 0x3 };
|
||||
enum {
|
||||
StmtMode = 0x0,
|
||||
SizeOfTypeVAMode = 0x1,
|
||||
DeclGroupMode = 0x2,
|
||||
Flags = 0x3
|
||||
};
|
||||
|
||||
union {
|
||||
Stmt **stmt;
|
||||
Decl **DGI;
|
||||
};
|
||||
uintptr_t RawVAPtr;
|
||||
uintptr_t RawVAPtr = 0;
|
||||
Decl **DGE;
|
||||
|
||||
StmtIteratorBase(Stmt **s) : stmt(s) {}
|
||||
StmtIteratorBase(const VariableArrayType *t);
|
||||
StmtIteratorBase(Decl **dgi, Decl **dge);
|
||||
StmtIteratorBase() : stmt(nullptr) {}
|
||||
|
||||
bool inDeclGroup() const {
|
||||
return (RawVAPtr & Flags) == DeclGroupMode;
|
||||
}
|
||||
@ -56,7 +63,7 @@ protected:
|
||||
}
|
||||
|
||||
void setVAPtr(const VariableArrayType *P) {
|
||||
assert (inDeclGroup() || inSizeOfTypeVA());
|
||||
assert(inDeclGroup() || inSizeOfTypeVA());
|
||||
RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
|
||||
}
|
||||
|
||||
@ -65,14 +72,8 @@ protected:
|
||||
void NextVA();
|
||||
|
||||
Stmt*& GetDeclExpr() const;
|
||||
|
||||
StmtIteratorBase(Stmt **s) : stmt(s), RawVAPtr(0) {}
|
||||
StmtIteratorBase(const VariableArrayType *t);
|
||||
StmtIteratorBase(Decl **dgi, Decl **dge);
|
||||
StmtIteratorBase() : stmt(nullptr), RawVAPtr(0) {}
|
||||
};
|
||||
|
||||
|
||||
template <typename DERIVED, typename REFERENCE>
|
||||
class StmtIteratorImpl : public StmtIteratorBase,
|
||||
public std::iterator<std::forward_iterator_tag,
|
||||
@ -80,8 +81,9 @@ class StmtIteratorImpl : public StmtIteratorBase,
|
||||
REFERENCE, REFERENCE> {
|
||||
protected:
|
||||
StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
|
||||
|
||||
public:
|
||||
StmtIteratorImpl() {}
|
||||
StmtIteratorImpl() = default;
|
||||
StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
|
||||
StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
|
||||
StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
|
||||
@ -120,16 +122,13 @@ public:
|
||||
|
||||
struct ConstStmtIterator;
|
||||
|
||||
struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
|
||||
explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
|
||||
|
||||
StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
|
||||
|
||||
struct StmtIterator : public StmtIteratorImpl<StmtIterator, Stmt*&> {
|
||||
explicit StmtIterator() = default;
|
||||
StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator, Stmt*&>(S) {}
|
||||
StmtIterator(Decl** dgi, Decl** dge)
|
||||
: StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
|
||||
|
||||
: StmtIteratorImpl<StmtIterator, Stmt*&>(dgi, dge) {}
|
||||
StmtIterator(const VariableArrayType *t)
|
||||
: StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
|
||||
: StmtIteratorImpl<StmtIterator, Stmt*&>(t) {}
|
||||
|
||||
private:
|
||||
StmtIterator(const StmtIteratorBase &RHS)
|
||||
@ -141,11 +140,9 @@ private:
|
||||
|
||||
struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
|
||||
const Stmt*> {
|
||||
explicit ConstStmtIterator() :
|
||||
StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
|
||||
|
||||
ConstStmtIterator(const StmtIterator& RHS) :
|
||||
StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
|
||||
explicit ConstStmtIterator() = default;
|
||||
ConstStmtIterator(const StmtIterator& RHS)
|
||||
: StmtIteratorImpl<ConstStmtIterator, const Stmt*>(RHS) {}
|
||||
|
||||
ConstStmtIterator(Stmt * const *S)
|
||||
: StmtIteratorImpl<ConstStmtIterator, const Stmt *>(
|
||||
@ -155,6 +152,7 @@ struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
|
||||
inline StmtIterator cast_away_const(const ConstStmtIterator &RHS) {
|
||||
return RHS;
|
||||
}
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_STMTITERATOR_H
|
||||
|
@ -899,7 +899,9 @@ public:
|
||||
}
|
||||
const Stmt *getBody() const {
|
||||
// This relies on the loop form is already checked by Sema.
|
||||
Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
|
||||
const Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
|
||||
while(const auto *CS = dyn_cast<CapturedStmt>(Body))
|
||||
Body = CS->getCapturedStmt();
|
||||
Body = cast<ForStmt>(Body)->getBody();
|
||||
for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
|
||||
Body = Body->IgnoreContainers();
|
||||
@ -955,8 +957,15 @@ public:
|
||||
T->getStmtClass() == OMPTargetSimdDirectiveClass ||
|
||||
T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
|
||||
T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
|
||||
T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass ||
|
||||
T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
|
||||
T->getStmtClass() ==
|
||||
OMPTeamsDistributeParallelForSimdDirectiveClass ||
|
||||
T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
|
||||
T->getStmtClass() ==
|
||||
OMPTargetTeamsDistributeParallelForDirectiveClass ||
|
||||
T->getStmtClass() ==
|
||||
OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
|
||||
T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
|
||||
T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1912,7 +1921,7 @@ class OMPTaskgroupDirective : public OMPExecutableDirective {
|
||||
OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc,
|
||||
unsigned NumClauses)
|
||||
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
|
||||
StartLoc, EndLoc, NumClauses, 1) {}
|
||||
StartLoc, EndLoc, NumClauses, 2) {}
|
||||
|
||||
/// Build an empty directive.
|
||||
/// \param NumClauses Number of clauses.
|
||||
@ -1920,7 +1929,12 @@ class OMPTaskgroupDirective : public OMPExecutableDirective {
|
||||
explicit OMPTaskgroupDirective(unsigned NumClauses)
|
||||
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
|
||||
SourceLocation(), SourceLocation(), NumClauses,
|
||||
1) {}
|
||||
2) {}
|
||||
|
||||
/// Sets the task_reduction return variable.
|
||||
void setReductionRef(Expr *RR) {
|
||||
*std::next(child_begin(), 1) = RR;
|
||||
}
|
||||
|
||||
public:
|
||||
/// Creates directive.
|
||||
@ -1930,10 +1944,12 @@ public:
|
||||
/// \param EndLoc Ending Location of the directive.
|
||||
/// \param Clauses List of clauses.
|
||||
/// \param AssociatedStmt Statement, associated with the directive.
|
||||
/// \param ReductionRef Reference to the task_reduction return variable.
|
||||
///
|
||||
static OMPTaskgroupDirective *
|
||||
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
|
||||
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
|
||||
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
|
||||
Expr *ReductionRef);
|
||||
|
||||
/// Creates an empty directive.
|
||||
///
|
||||
@ -1943,6 +1959,15 @@ public:
|
||||
static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
|
||||
unsigned NumClauses, EmptyShell);
|
||||
|
||||
|
||||
/// Returns reference to the task_reduction return variable.
|
||||
const Expr *getReductionRef() const {
|
||||
return static_cast<const Expr *>(*std::next(child_begin(), 1));
|
||||
}
|
||||
Expr *getReductionRef() {
|
||||
return static_cast<Expr *>(*std::next(child_begin(), 1));
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == OMPTaskgroupDirectiveClass;
|
||||
}
|
||||
@ -2330,7 +2355,7 @@ class OMPTargetEnterDataDirective : public OMPExecutableDirective {
|
||||
unsigned NumClauses)
|
||||
: OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
|
||||
OMPD_target_enter_data, StartLoc, EndLoc,
|
||||
NumClauses, /*NumChildren=*/0) {}
|
||||
NumClauses, /*NumChildren=*/1) {}
|
||||
|
||||
/// \brief Build an empty directive.
|
||||
///
|
||||
@ -2340,7 +2365,7 @@ class OMPTargetEnterDataDirective : public OMPExecutableDirective {
|
||||
: OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
|
||||
OMPD_target_enter_data, SourceLocation(),
|
||||
SourceLocation(), NumClauses,
|
||||
/*NumChildren=*/0) {}
|
||||
/*NumChildren=*/1) {}
|
||||
|
||||
public:
|
||||
/// \brief Creates directive with a list of \a Clauses.
|
||||
@ -2349,11 +2374,11 @@ public:
|
||||
/// \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 OMPTargetEnterDataDirective *Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
ArrayRef<OMPClause *> Clauses);
|
||||
static OMPTargetEnterDataDirective *
|
||||
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
|
||||
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
|
||||
|
||||
/// \brief Creates an empty directive with the place for \a N clauses.
|
||||
///
|
||||
@ -2389,7 +2414,7 @@ class OMPTargetExitDataDirective : public OMPExecutableDirective {
|
||||
unsigned NumClauses)
|
||||
: OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
|
||||
OMPD_target_exit_data, StartLoc, EndLoc,
|
||||
NumClauses, /*NumChildren=*/0) {}
|
||||
NumClauses, /*NumChildren=*/1) {}
|
||||
|
||||
/// \brief Build an empty directive.
|
||||
///
|
||||
@ -2399,7 +2424,7 @@ class OMPTargetExitDataDirective : public OMPExecutableDirective {
|
||||
: OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
|
||||
OMPD_target_exit_data, SourceLocation(),
|
||||
SourceLocation(), NumClauses,
|
||||
/*NumChildren=*/0) {}
|
||||
/*NumChildren=*/1) {}
|
||||
|
||||
public:
|
||||
/// \brief Creates directive with a list of \a Clauses.
|
||||
@ -2408,11 +2433,11 @@ public:
|
||||
/// \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 OMPTargetExitDataDirective *Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
ArrayRef<OMPClause *> Clauses);
|
||||
static OMPTargetExitDataDirective *
|
||||
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
|
||||
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
|
||||
|
||||
/// \brief Creates an empty directive with the place for \a N clauses.
|
||||
///
|
||||
@ -2966,7 +2991,7 @@ class OMPTargetUpdateDirective : public OMPExecutableDirective {
|
||||
unsigned NumClauses)
|
||||
: OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
|
||||
OMPD_target_update, StartLoc, EndLoc, NumClauses,
|
||||
0) {}
|
||||
1) {}
|
||||
|
||||
/// \brief Build an empty directive.
|
||||
///
|
||||
@ -2975,7 +3000,7 @@ class OMPTargetUpdateDirective : public OMPExecutableDirective {
|
||||
explicit OMPTargetUpdateDirective(unsigned NumClauses)
|
||||
: OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
|
||||
OMPD_target_update, SourceLocation(),
|
||||
SourceLocation(), NumClauses, 0) {}
|
||||
SourceLocation(), NumClauses, 1) {}
|
||||
|
||||
public:
|
||||
/// \brief Creates directive with a list of \a Clauses.
|
||||
@ -2984,11 +3009,11 @@ public:
|
||||
/// \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 OMPTargetUpdateDirective *Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
ArrayRef<OMPClause *> Clauses);
|
||||
static OMPTargetUpdateDirective *
|
||||
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
|
||||
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
|
||||
|
||||
/// \brief Creates an empty directive with the place for \a NumClauses
|
||||
/// clauses.
|
||||
@ -3015,6 +3040,8 @@ public:
|
||||
///
|
||||
class OMPDistributeParallelForDirective : public OMPLoopDirective {
|
||||
friend class ASTStmtReader;
|
||||
/// true if the construct has inner cancel directive.
|
||||
bool HasCancel = false;
|
||||
|
||||
/// \brief Build directive with the given start and end location.
|
||||
///
|
||||
@ -3028,7 +3055,7 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective {
|
||||
unsigned CollapsedNum, unsigned NumClauses)
|
||||
: OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
|
||||
OMPD_distribute_parallel_for, StartLoc, EndLoc,
|
||||
CollapsedNum, NumClauses) {}
|
||||
CollapsedNum, NumClauses), HasCancel(false) {}
|
||||
|
||||
/// \brief Build an empty directive.
|
||||
///
|
||||
@ -3039,7 +3066,11 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective {
|
||||
unsigned NumClauses)
|
||||
: OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
|
||||
OMPD_distribute_parallel_for, SourceLocation(),
|
||||
SourceLocation(), CollapsedNum, NumClauses) {}
|
||||
SourceLocation(), CollapsedNum, NumClauses),
|
||||
HasCancel(false) {}
|
||||
|
||||
/// Set cancel state.
|
||||
void setHasCancel(bool Has) { HasCancel = Has; }
|
||||
|
||||
public:
|
||||
/// \brief Creates directive with a list of \a Clauses.
|
||||
@ -3051,11 +3082,12 @@ public:
|
||||
/// \param Clauses List of clauses.
|
||||
/// \param AssociatedStmt Statement, associated with the directive.
|
||||
/// \param Exprs Helper expressions for CodeGen.
|
||||
/// \param HasCancel true if this directive has inner cancel directive.
|
||||
///
|
||||
static OMPDistributeParallelForDirective *
|
||||
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
|
||||
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
|
||||
Stmt *AssociatedStmt, const HelperExprs &Exprs);
|
||||
Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
|
||||
|
||||
/// \brief Creates an empty directive with the place
|
||||
/// for \a NumClauses clauses.
|
||||
@ -3069,6 +3101,9 @@ public:
|
||||
unsigned CollapsedNum,
|
||||
EmptyShell);
|
||||
|
||||
/// Return true if current directive has inner cancel directive.
|
||||
bool hasCancel() const { return HasCancel; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
|
||||
}
|
||||
@ -3565,6 +3600,8 @@ public:
|
||||
///
|
||||
class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
|
||||
friend class ASTStmtReader;
|
||||
/// true if the construct has inner cancel directive.
|
||||
bool HasCancel = false;
|
||||
|
||||
/// Build directive with the given start and end location.
|
||||
///
|
||||
@ -3579,7 +3616,7 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
|
||||
unsigned NumClauses)
|
||||
: OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
|
||||
OMPD_teams_distribute_parallel_for, StartLoc, EndLoc,
|
||||
CollapsedNum, NumClauses) {}
|
||||
CollapsedNum, NumClauses), HasCancel(false) {}
|
||||
|
||||
/// Build an empty directive.
|
||||
///
|
||||
@ -3590,7 +3627,11 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
|
||||
unsigned NumClauses)
|
||||
: OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
|
||||
OMPD_teams_distribute_parallel_for, SourceLocation(),
|
||||
SourceLocation(), CollapsedNum, NumClauses) {}
|
||||
SourceLocation(), CollapsedNum, NumClauses),
|
||||
HasCancel(false) {}
|
||||
|
||||
/// Set cancel state.
|
||||
void setHasCancel(bool Has) { HasCancel = Has; }
|
||||
|
||||
public:
|
||||
/// Creates directive with a list of \a Clauses.
|
||||
@ -3602,11 +3643,12 @@ public:
|
||||
/// \param Clauses List of clauses.
|
||||
/// \param AssociatedStmt Statement, associated with the directive.
|
||||
/// \param Exprs Helper expressions for CodeGen.
|
||||
/// \param HasCancel true if this directive has inner cancel directive.
|
||||
///
|
||||
static OMPTeamsDistributeParallelForDirective *
|
||||
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
|
||||
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
|
||||
Stmt *AssociatedStmt, const HelperExprs &Exprs);
|
||||
Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
|
||||
|
||||
/// Creates an empty directive with the place for \a NumClauses clauses.
|
||||
///
|
||||
@ -3618,6 +3660,9 @@ public:
|
||||
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
|
||||
EmptyShell);
|
||||
|
||||
/// Return true if current directive has inner cancel directive.
|
||||
bool hasCancel() const { return HasCancel; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
|
||||
}
|
||||
@ -3761,6 +3806,8 @@ public:
|
||||
class OMPTargetTeamsDistributeParallelForDirective final
|
||||
: public OMPLoopDirective {
|
||||
friend class ASTStmtReader;
|
||||
/// true if the construct has inner cancel directive.
|
||||
bool HasCancel = false;
|
||||
|
||||
/// Build directive with the given start and end location.
|
||||
///
|
||||
@ -3776,7 +3823,8 @@ class OMPTargetTeamsDistributeParallelForDirective final
|
||||
: OMPLoopDirective(this,
|
||||
OMPTargetTeamsDistributeParallelForDirectiveClass,
|
||||
OMPD_target_teams_distribute_parallel_for, StartLoc,
|
||||
EndLoc, CollapsedNum, NumClauses) {}
|
||||
EndLoc, CollapsedNum, NumClauses),
|
||||
HasCancel(false) {}
|
||||
|
||||
/// Build an empty directive.
|
||||
///
|
||||
@ -3788,7 +3836,11 @@ class OMPTargetTeamsDistributeParallelForDirective final
|
||||
: OMPLoopDirective(
|
||||
this, OMPTargetTeamsDistributeParallelForDirectiveClass,
|
||||
OMPD_target_teams_distribute_parallel_for, SourceLocation(),
|
||||
SourceLocation(), CollapsedNum, NumClauses) {}
|
||||
SourceLocation(), CollapsedNum, NumClauses),
|
||||
HasCancel(false) {}
|
||||
|
||||
/// Set cancel state.
|
||||
void setHasCancel(bool Has) { HasCancel = Has; }
|
||||
|
||||
public:
|
||||
/// Creates directive with a list of \a Clauses.
|
||||
@ -3800,11 +3852,12 @@ public:
|
||||
/// \param Clauses List of clauses.
|
||||
/// \param AssociatedStmt Statement, associated with the directive.
|
||||
/// \param Exprs Helper expressions for CodeGen.
|
||||
/// \param HasCancel true if this directive has inner cancel directive.
|
||||
///
|
||||
static OMPTargetTeamsDistributeParallelForDirective *
|
||||
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
|
||||
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
|
||||
Stmt *AssociatedStmt, const HelperExprs &Exprs);
|
||||
Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
|
||||
|
||||
/// Creates an empty directive with the place for \a NumClauses clauses.
|
||||
///
|
||||
@ -3816,6 +3869,9 @@ public:
|
||||
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
|
||||
EmptyShell);
|
||||
|
||||
/// Return true if current directive has inner cancel directive.
|
||||
bool hasCancel() const { return HasCancel; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() ==
|
||||
OMPTargetTeamsDistributeParallelForDirectiveClass;
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
|
||||
//===- StmtVisitor.h - Visitor for Stmt subclasses --------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -17,28 +17,33 @@
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/ExprObjC.h"
|
||||
#include "clang/AST/ExprOpenMP.h"
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "clang/AST/StmtCXX.h"
|
||||
#include "clang/AST/StmtObjC.h"
|
||||
#include "clang/AST/StmtOpenMP.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
template <typename T> struct make_ptr { typedef T *type; };
|
||||
template <typename T> struct make_const_ptr { typedef const T *type; };
|
||||
template <typename T> struct make_ptr { using type = T *; };
|
||||
template <typename T> struct make_const_ptr { using type = const T *; };
|
||||
|
||||
/// StmtVisitorBase - This class implements a simple visitor for Stmt
|
||||
/// subclasses. Since Expr derives from Stmt, this also includes support for
|
||||
/// visiting Exprs.
|
||||
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
|
||||
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void,
|
||||
class... ParamTys>
|
||||
class StmtVisitorBase {
|
||||
public:
|
||||
|
||||
#define PTR(CLASS) typename Ptr<CLASS>::type
|
||||
#define DISPATCH(NAME, CLASS) \
|
||||
return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S))
|
||||
|
||||
RetTy Visit(PTR(Stmt) S) {
|
||||
return static_cast<ImplClass*>(this)->Visit ## NAME( \
|
||||
static_cast<PTR(CLASS)>(S), std::forward<ParamTys>(P)...)
|
||||
|
||||
RetTy Visit(PTR(Stmt) S, ParamTys... P) {
|
||||
// If we have a binary expr, dispatch to the subcode of the binop. A smart
|
||||
// optimizer (e.g. LLVM) will fold this comparison into the switch stmt
|
||||
// below.
|
||||
@ -60,6 +65,7 @@ public:
|
||||
case BO_GE: DISPATCH(BinGE, BinaryOperator);
|
||||
case BO_EQ: DISPATCH(BinEQ, BinaryOperator);
|
||||
case BO_NE: DISPATCH(BinNE, BinaryOperator);
|
||||
case BO_Cmp: DISPATCH(BinCmp, BinaryOperator);
|
||||
|
||||
case BO_And: DISPATCH(BinAnd, BinaryOperator);
|
||||
case BO_Xor: DISPATCH(BinXor, BinaryOperator);
|
||||
@ -111,13 +117,13 @@ public:
|
||||
// If the implementation chooses not to implement a certain visit method, fall
|
||||
// back on VisitExpr or whatever else is the superclass.
|
||||
#define STMT(CLASS, PARENT) \
|
||||
RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); }
|
||||
RetTy Visit ## CLASS(PTR(CLASS) S, ParamTys... P) { DISPATCH(PARENT, PARENT); }
|
||||
#include "clang/AST/StmtNodes.inc"
|
||||
|
||||
// If the implementation doesn't implement binary operator methods, fall back
|
||||
// on VisitBinaryOperator.
|
||||
#define BINOP_FALLBACK(NAME) \
|
||||
RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \
|
||||
RetTy VisitBin ## NAME(PTR(BinaryOperator) S, ParamTys... P) { \
|
||||
DISPATCH(BinaryOperator, BinaryOperator); \
|
||||
}
|
||||
BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI)
|
||||
@ -127,6 +133,8 @@ public:
|
||||
|
||||
BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE)
|
||||
BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE)
|
||||
BINOP_FALLBACK(Cmp)
|
||||
|
||||
BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or)
|
||||
BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr)
|
||||
|
||||
@ -137,7 +145,7 @@ public:
|
||||
// If the implementation doesn't implement compound assignment operator
|
||||
// methods, fall back on VisitCompoundAssignOperator.
|
||||
#define CAO_FALLBACK(NAME) \
|
||||
RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \
|
||||
RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S, ParamTys... P) { \
|
||||
DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
|
||||
}
|
||||
CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
|
||||
@ -149,7 +157,7 @@ public:
|
||||
// If the implementation doesn't implement unary operator methods, fall back
|
||||
// on VisitUnaryOperator.
|
||||
#define UNARYOP_FALLBACK(NAME) \
|
||||
RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \
|
||||
RetTy VisitUnary ## NAME(PTR(UnaryOperator) S, ParamTys... P) { \
|
||||
DISPATCH(UnaryOperator, UnaryOperator); \
|
||||
}
|
||||
UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
|
||||
@ -163,7 +171,7 @@ public:
|
||||
#undef UNARYOP_FALLBACK
|
||||
|
||||
// Base case, ignore it. :)
|
||||
RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); }
|
||||
RetTy VisitStmt(PTR(Stmt) Node, ParamTys... P) { return RetTy(); }
|
||||
|
||||
#undef PTR
|
||||
#undef DISPATCH
|
||||
@ -174,18 +182,18 @@ public:
|
||||
///
|
||||
/// This class does not preserve constness of Stmt pointers (see also
|
||||
/// ConstStmtVisitor).
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
template<typename ImplClass, typename RetTy=void, typename... ParamTys>
|
||||
class StmtVisitor
|
||||
: public StmtVisitorBase<make_ptr, ImplClass, RetTy> {};
|
||||
: public StmtVisitorBase<make_ptr, ImplClass, RetTy, ParamTys...> {};
|
||||
|
||||
/// ConstStmtVisitor - This class implements a simple visitor for Stmt
|
||||
/// subclasses. Since Expr derives from Stmt, this also includes support for
|
||||
/// visiting Exprs.
|
||||
///
|
||||
/// This class preserves constness of Stmt pointers (see also StmtVisitor).
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
template<typename ImplClass, typename RetTy=void, typename... ParamTys>
|
||||
class ConstStmtVisitor
|
||||
: public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {};
|
||||
: public StmtVisitorBase<make_const_ptr, ImplClass, RetTy, ParamTys...> {};
|
||||
|
||||
/// \brief This class implements a simple visitor for OMPClause
|
||||
/// subclasses.
|
||||
@ -222,6 +230,6 @@ template<class ImplClass, typename RetTy = void>
|
||||
class ConstOMPClauseVisitor :
|
||||
public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {};
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_STMTVISITOR_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
|
||||
//===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -15,21 +15,32 @@
|
||||
#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
|
||||
#define LLVM_CLANG_AST_TEMPLATEBASE_H
|
||||
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/AST/TemplateName.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/TrailingObjects.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace llvm {
|
||||
class FoldingSetNodeID;
|
||||
}
|
||||
|
||||
class FoldingSetNodeID;
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class DiagnosticBuilder;
|
||||
class Expr;
|
||||
struct PrintingPolicy;
|
||||
@ -44,29 +55,37 @@ public:
|
||||
/// \brief Represents an empty template argument, e.g., one that has not
|
||||
/// been deduced.
|
||||
Null = 0,
|
||||
|
||||
/// The template argument is a type.
|
||||
Type,
|
||||
|
||||
/// The template argument is a declaration that was provided for a pointer,
|
||||
/// reference, or pointer to member non-type template parameter.
|
||||
Declaration,
|
||||
|
||||
/// The template argument is a null pointer or null pointer to member that
|
||||
/// was provided for a non-type template parameter.
|
||||
NullPtr,
|
||||
|
||||
/// The template argument is an integral value stored in an llvm::APSInt
|
||||
/// that was provided for an integral non-type template parameter.
|
||||
Integral,
|
||||
|
||||
/// The template argument is a template name that was provided for a
|
||||
/// template template parameter.
|
||||
Template,
|
||||
|
||||
/// The template argument is a pack expansion of a template name that was
|
||||
/// provided for a template template parameter.
|
||||
TemplateExpansion,
|
||||
|
||||
/// The template argument is an expression, and we've not resolved it to one
|
||||
/// of the other forms yet, either because it's dependent or because we're
|
||||
/// representing a non-canonical template argument (for instance, in a
|
||||
/// TemplateSpecializationType). Also used to represent a non-dependent
|
||||
/// __uuidof expression (a Microsoft extension).
|
||||
Expression,
|
||||
|
||||
/// The template argument is actually a parameter pack. Arguments are stored
|
||||
/// in the Args struct.
|
||||
Pack
|
||||
@ -88,8 +107,11 @@ private:
|
||||
unsigned BitWidth : 31;
|
||||
unsigned IsUnsigned : 1;
|
||||
union {
|
||||
uint64_t VAL; ///< Used to store the <= 64 bits integer value.
|
||||
const uint64_t *pVal; ///< Used to store the >64 bits integer value.
|
||||
/// Used to store the <= 64 bits integer value.
|
||||
uint64_t VAL;
|
||||
|
||||
/// Used to store the >64 bits integer value.
|
||||
const uint64_t *pVal;
|
||||
};
|
||||
void *Type;
|
||||
};
|
||||
@ -115,8 +137,6 @@ private:
|
||||
struct TV TypeOrValue;
|
||||
};
|
||||
|
||||
TemplateArgument(TemplateName, bool) = delete;
|
||||
|
||||
public:
|
||||
/// \brief Construct an empty, invalid template argument.
|
||||
constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
|
||||
@ -202,6 +222,8 @@ public:
|
||||
this->Args.NumArgs = Args.size();
|
||||
}
|
||||
|
||||
TemplateArgument(TemplateName, bool) = delete;
|
||||
|
||||
static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
|
||||
|
||||
/// \brief Create a new template argument pack by copying the given set of
|
||||
@ -278,7 +300,9 @@ public:
|
||||
// FIXME: Provide a way to read the integral data without copying the value.
|
||||
llvm::APSInt getAsIntegral() const {
|
||||
assert(getKind() == Integral && "Unexpected kind");
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
if (Integer.BitWidth <= 64)
|
||||
return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
|
||||
|
||||
@ -309,7 +333,7 @@ public:
|
||||
}
|
||||
|
||||
/// \brief Iterator that traverses the elements of a template argument pack.
|
||||
typedef const TemplateArgument * pack_iterator;
|
||||
using pack_iterator = const TemplateArgument *;
|
||||
|
||||
/// \brief Iterator referencing the first argument of a template argument
|
||||
/// pack.
|
||||
@ -368,7 +392,6 @@ public:
|
||||
/// Location information for a TemplateArgument.
|
||||
struct TemplateArgumentLocInfo {
|
||||
private:
|
||||
|
||||
struct T {
|
||||
// FIXME: We'd like to just use the qualifier in the TemplateName,
|
||||
// but template arguments get canonicalized too quickly.
|
||||
@ -393,8 +416,7 @@ public:
|
||||
|
||||
TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation EllipsisLoc)
|
||||
{
|
||||
SourceLocation EllipsisLoc) {
|
||||
Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
|
||||
Template.QualifierLocData = QualifierLoc.getOpaqueData();
|
||||
Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
|
||||
@ -434,16 +456,15 @@ public:
|
||||
|
||||
TemplateArgumentLoc(const TemplateArgument &Argument,
|
||||
TemplateArgumentLocInfo Opaque)
|
||||
: Argument(Argument), LocInfo(Opaque) {
|
||||
}
|
||||
: Argument(Argument), LocInfo(Opaque) {}
|
||||
|
||||
TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
|
||||
: Argument(Argument), LocInfo(TInfo) {
|
||||
: Argument(Argument), LocInfo(TInfo) {
|
||||
assert(Argument.getKind() == TemplateArgument::Type);
|
||||
}
|
||||
|
||||
TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
|
||||
: Argument(Argument), LocInfo(E) {
|
||||
: Argument(Argument), LocInfo(E) {
|
||||
assert(Argument.getKind() == TemplateArgument::Expression);
|
||||
}
|
||||
|
||||
@ -451,7 +472,8 @@ public:
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation EllipsisLoc = SourceLocation())
|
||||
: Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
|
||||
: Argument(Argument),
|
||||
LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
|
||||
assert(Argument.getKind() == TemplateArgument::Template ||
|
||||
Argument.getKind() == TemplateArgument::TemplateExpansion);
|
||||
}
|
||||
@ -526,16 +548,16 @@ class TemplateArgumentListInfo {
|
||||
SourceLocation LAngleLoc;
|
||||
SourceLocation RAngleLoc;
|
||||
|
||||
// This can leak if used in an AST node, use ASTTemplateArgumentListInfo
|
||||
// instead.
|
||||
void *operator new(size_t bytes, ASTContext &C) = delete;
|
||||
|
||||
public:
|
||||
TemplateArgumentListInfo() {}
|
||||
TemplateArgumentListInfo() = default;
|
||||
|
||||
TemplateArgumentListInfo(SourceLocation LAngleLoc,
|
||||
SourceLocation RAngleLoc)
|
||||
: LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
|
||||
: LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
|
||||
|
||||
// This can leak if used in an AST node, use ASTTemplateArgumentListInfo
|
||||
// instead.
|
||||
void *operator new(size_t bytes, ASTContext &C) = delete;
|
||||
|
||||
SourceLocation getLAngleLoc() const { return LAngleLoc; }
|
||||
SourceLocation getRAngleLoc() const { return RAngleLoc; }
|
||||
@ -574,8 +596,8 @@ struct ASTTemplateArgumentListInfo final
|
||||
: private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
|
||||
TemplateArgumentLoc> {
|
||||
private:
|
||||
friend TrailingObjects;
|
||||
friend class ASTNodeImporter;
|
||||
friend TrailingObjects;
|
||||
|
||||
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
|
||||
|
||||
@ -668,6 +690,6 @@ inline const TemplateArgument &
|
||||
return getArgs()[Idx];
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_TEMPLATEBASE_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
|
||||
//===- TemplateName.h - C++ Template Name Representation --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -14,10 +14,12 @@
|
||||
#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
|
||||
#define LLVM_CLANG_AST_TEMPLATENAME_H
|
||||
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/Support/PointerLikeTypeTraits.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace clang {
|
||||
|
||||
@ -94,7 +96,7 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
|
||||
friend class ASTContext;
|
||||
|
||||
OverloadedTemplateStorage(unsigned size)
|
||||
: UncommonTemplateNameStorage(Overloaded, size) { }
|
||||
: UncommonTemplateNameStorage(Overloaded, size) {}
|
||||
|
||||
NamedDecl **getStorage() {
|
||||
return reinterpret_cast<NamedDecl **>(this + 1);
|
||||
@ -104,7 +106,7 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
|
||||
}
|
||||
|
||||
public:
|
||||
typedef NamedDecl *const *iterator;
|
||||
using iterator = NamedDecl *const *;
|
||||
|
||||
iterator begin() const { return getStorage(); }
|
||||
iterator end() const { return getStorage() + size(); }
|
||||
@ -126,8 +128,8 @@ public:
|
||||
SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
|
||||
unsigned Size,
|
||||
const TemplateArgument *Arguments)
|
||||
: UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
|
||||
Parameter(Parameter), Arguments(Arguments) { }
|
||||
: UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
|
||||
Parameter(Parameter), Arguments(Arguments) {}
|
||||
|
||||
/// \brief Retrieve the template template parameter pack being substituted.
|
||||
TemplateTemplateParmDecl *getParameterPack() const {
|
||||
@ -174,10 +176,9 @@ public:
|
||||
/// specifier in the typedef. "apply" is a nested template, and can
|
||||
/// only be understood in the context of
|
||||
class TemplateName {
|
||||
typedef llvm::PointerUnion4<TemplateDecl *,
|
||||
UncommonTemplateNameStorage *,
|
||||
QualifiedTemplateName *,
|
||||
DependentTemplateName *> StorageType;
|
||||
using StorageType =
|
||||
llvm::PointerUnion4<TemplateDecl *, UncommonTemplateNameStorage *,
|
||||
QualifiedTemplateName *, DependentTemplateName *>;
|
||||
|
||||
StorageType Storage;
|
||||
|
||||
@ -188,24 +189,29 @@ public:
|
||||
enum NameKind {
|
||||
/// \brief A single template declaration.
|
||||
Template,
|
||||
|
||||
/// \brief A set of overloaded template declarations.
|
||||
OverloadedTemplate,
|
||||
|
||||
/// \brief A qualified template name, where the qualification is kept
|
||||
/// to describe the source code as written.
|
||||
QualifiedTemplate,
|
||||
|
||||
/// \brief A dependent template name that has not been resolved to a
|
||||
/// template (or set of templates).
|
||||
DependentTemplate,
|
||||
|
||||
/// \brief A template template parameter that has been substituted
|
||||
/// for some other template name.
|
||||
SubstTemplateTemplateParm,
|
||||
|
||||
/// \brief A template template parameter pack that has been substituted for
|
||||
/// a template template argument pack, but has not yet been expanded into
|
||||
/// individual arguments.
|
||||
SubstTemplateTemplateParmPack
|
||||
};
|
||||
|
||||
TemplateName() : Storage() { }
|
||||
TemplateName() = default;
|
||||
explicit TemplateName(TemplateDecl *Template);
|
||||
explicit TemplateName(OverloadedTemplateStorage *Storage);
|
||||
explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
|
||||
@ -262,6 +268,11 @@ public:
|
||||
|
||||
TemplateName getUnderlying() const;
|
||||
|
||||
/// Get the template name to substitute when this template name is used as a
|
||||
/// template template argument. This refers to the most recent declaration of
|
||||
/// the template, including any default template arguments.
|
||||
TemplateName getNameToSubstitute() const;
|
||||
|
||||
/// \brief Determines whether this is a dependent template name.
|
||||
bool isDependent() const;
|
||||
|
||||
@ -320,8 +331,8 @@ class SubstTemplateTemplateParmStorage
|
||||
|
||||
SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
|
||||
TemplateName replacement)
|
||||
: UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
|
||||
Parameter(parameter), Replacement(replacement) {}
|
||||
: UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
|
||||
Parameter(parameter), Replacement(replacement) {}
|
||||
|
||||
public:
|
||||
TemplateTemplateParmDecl *getParameter() const { return Parameter; }
|
||||
@ -353,6 +364,8 @@ inline TemplateName TemplateName::getUnderlying() const {
|
||||
/// manner, it is to TemplateName what ElaboratedType is to Type,
|
||||
/// providing extra syntactic sugar for downstream clients.
|
||||
class QualifiedTemplateName : public llvm::FoldingSetNode {
|
||||
friend class ASTContext;
|
||||
|
||||
/// \brief The nested name specifier that qualifies the template name.
|
||||
///
|
||||
/// The bit is used to indicate whether the "template" keyword was
|
||||
@ -366,12 +379,9 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
|
||||
/// that this qualified name refers to.
|
||||
TemplateDecl *Template;
|
||||
|
||||
friend class ASTContext;
|
||||
|
||||
QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
|
||||
TemplateDecl *Template)
|
||||
: Qualifier(NNS, TemplateKeyword? 1 : 0),
|
||||
Template(Template) { }
|
||||
: Qualifier(NNS, TemplateKeyword? 1 : 0), Template(Template) {}
|
||||
|
||||
public:
|
||||
/// \brief Return the nested name specifier that qualifies this name.
|
||||
@ -410,6 +420,8 @@ public:
|
||||
/// where "MetaFun::" is the nested name specifier and "apply" is the
|
||||
/// template name referenced. The "template" keyword is implied.
|
||||
class DependentTemplateName : public llvm::FoldingSetNode {
|
||||
friend class ASTContext;
|
||||
|
||||
/// \brief The nested name specifier that qualifies the template
|
||||
/// name.
|
||||
///
|
||||
@ -439,29 +451,27 @@ class DependentTemplateName : public llvm::FoldingSetNode {
|
||||
/// canonical.
|
||||
TemplateName CanonicalTemplateName;
|
||||
|
||||
friend class ASTContext;
|
||||
|
||||
DependentTemplateName(NestedNameSpecifier *Qualifier,
|
||||
const IdentifierInfo *Identifier)
|
||||
: Qualifier(Qualifier, false), Identifier(Identifier),
|
||||
CanonicalTemplateName(this) { }
|
||||
: Qualifier(Qualifier, false), Identifier(Identifier),
|
||||
CanonicalTemplateName(this) {}
|
||||
|
||||
DependentTemplateName(NestedNameSpecifier *Qualifier,
|
||||
const IdentifierInfo *Identifier,
|
||||
TemplateName Canon)
|
||||
: Qualifier(Qualifier, false), Identifier(Identifier),
|
||||
CanonicalTemplateName(Canon) { }
|
||||
: Qualifier(Qualifier, false), Identifier(Identifier),
|
||||
CanonicalTemplateName(Canon) {}
|
||||
|
||||
DependentTemplateName(NestedNameSpecifier *Qualifier,
|
||||
OverloadedOperatorKind Operator)
|
||||
: Qualifier(Qualifier, true), Operator(Operator),
|
||||
CanonicalTemplateName(this) { }
|
||||
: Qualifier(Qualifier, true), Operator(Operator),
|
||||
CanonicalTemplateName(this) {}
|
||||
|
||||
DependentTemplateName(NestedNameSpecifier *Qualifier,
|
||||
OverloadedOperatorKind Operator,
|
||||
TemplateName Canon)
|
||||
: Qualifier(Qualifier, true), Operator(Operator),
|
||||
CanonicalTemplateName(Canon) { }
|
||||
: Qualifier(Qualifier, true), Operator(Operator),
|
||||
CanonicalTemplateName(Canon) {}
|
||||
|
||||
public:
|
||||
/// \brief Return the nested name specifier that qualifies this name.
|
||||
@ -509,14 +519,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang.
|
||||
} // namespace clang.
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// \brief The clang::TemplateName class is effectively a pointer.
|
||||
template<>
|
||||
class PointerLikeTypeTraits<clang::TemplateName> {
|
||||
public:
|
||||
struct PointerLikeTypeTraits<clang::TemplateName> {
|
||||
static inline void *getAsVoidPointer(clang::TemplateName TN) {
|
||||
return TN.getAsVoidPointer();
|
||||
}
|
||||
@ -529,6 +538,6 @@ public:
|
||||
enum { NumLowBitsAvailable = 0 };
|
||||
};
|
||||
|
||||
} // end namespace llvm.
|
||||
} // namespace llvm.
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_TEMPLATENAME_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
|
||||
//===- TypeLoc.h - Type Source Info Wrapper ---------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -6,26 +6,42 @@
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
//
|
||||
/// \file
|
||||
/// \brief Defines the clang::TypeLoc interface and its subclasses.
|
||||
///
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_TYPELOC_H
|
||||
#define LLVM_CLANG_AST_TYPELOC_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/AST/TemplateBase.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class ParmVarDecl;
|
||||
class TypeSourceInfo;
|
||||
class UnqualTypeLoc;
|
||||
|
||||
class ASTContext;
|
||||
class CXXRecordDecl;
|
||||
class Expr;
|
||||
class ObjCInterfaceDecl;
|
||||
class ObjCProtocolDecl;
|
||||
class ObjCTypeParamDecl;
|
||||
class TemplateTypeParmDecl;
|
||||
class UnqualTypeLoc;
|
||||
class UnresolvedUsingTypenameDecl;
|
||||
|
||||
// Predeclare all the type nodes.
|
||||
#define ABSTRACT_TYPELOC(Class, Base)
|
||||
@ -41,10 +57,16 @@ class TypeLoc {
|
||||
protected:
|
||||
// The correctness of this relies on the property that, for Type *Ty,
|
||||
// QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
|
||||
const void *Ty;
|
||||
void *Data;
|
||||
const void *Ty = nullptr;
|
||||
void *Data = nullptr;
|
||||
|
||||
public:
|
||||
TypeLoc() = default;
|
||||
TypeLoc(QualType ty, void *opaqueData)
|
||||
: Ty(ty.getAsOpaquePtr()), Data(opaqueData) {}
|
||||
TypeLoc(const Type *ty, void *opaqueData)
|
||||
: Ty(ty), Data(opaqueData) {}
|
||||
|
||||
/// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
|
||||
/// is of the desired type.
|
||||
///
|
||||
@ -88,12 +110,6 @@ public:
|
||||
Qualified
|
||||
};
|
||||
|
||||
TypeLoc() : Ty(nullptr), Data(nullptr) { }
|
||||
TypeLoc(QualType ty, void *opaqueData)
|
||||
: Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
|
||||
TypeLoc(const Type *ty, void *opaqueData)
|
||||
: Ty(ty), Data(opaqueData) { }
|
||||
|
||||
TypeLocClass getTypeLocClass() const {
|
||||
if (getType().hasLocalQualifiers()) return Qualified;
|
||||
return (TypeLocClass) getType()->getTypeClass();
|
||||
@ -134,6 +150,7 @@ public:
|
||||
SourceRange getSourceRange() const LLVM_READONLY {
|
||||
return SourceRange(getBeginLoc(), getEndLoc());
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
|
||||
@ -228,7 +245,7 @@ inline TypeLoc TypeSourceInfo::getTypeLoc() const {
|
||||
/// no direct qualifiers.
|
||||
class UnqualTypeLoc : public TypeLoc {
|
||||
public:
|
||||
UnqualTypeLoc() {}
|
||||
UnqualTypeLoc() = default;
|
||||
UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
|
||||
|
||||
const Type *getTypePtr() const {
|
||||
@ -241,6 +258,7 @@ public:
|
||||
|
||||
private:
|
||||
friend class TypeLoc;
|
||||
|
||||
static bool isKind(const TypeLoc &TL) {
|
||||
return !TL.getType().hasLocalQualifiers();
|
||||
}
|
||||
@ -253,9 +271,7 @@ private:
|
||||
/// type qualifiers.
|
||||
class QualifiedTypeLoc : public TypeLoc {
|
||||
public:
|
||||
SourceRange getLocalSourceRange() const {
|
||||
return SourceRange();
|
||||
}
|
||||
SourceRange getLocalSourceRange() const { return {}; }
|
||||
|
||||
UnqualTypeLoc getUnqualifiedLoc() const {
|
||||
unsigned align =
|
||||
@ -296,6 +312,7 @@ public:
|
||||
|
||||
private:
|
||||
friend class TypeLoc;
|
||||
|
||||
static bool isKind(const TypeLoc &TL) {
|
||||
return TL.getType().hasLocalQualifiers();
|
||||
}
|
||||
@ -337,12 +354,12 @@ inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
|
||||
/// InheritingConcreteTypeLoc instead.
|
||||
template <class Base, class Derived, class TypeClass, class LocalData>
|
||||
class ConcreteTypeLoc : public Base {
|
||||
friend class TypeLoc;
|
||||
|
||||
const Derived *asDerived() const {
|
||||
return static_cast<const Derived*>(this);
|
||||
}
|
||||
|
||||
friend class TypeLoc;
|
||||
static bool isKind(const TypeLoc &TL) {
|
||||
return !TL.getType().hasLocalQualifiers() &&
|
||||
Derived::classofType(TL.getTypePtr());
|
||||
@ -357,6 +374,7 @@ public:
|
||||
return std::max(unsigned(alignof(LocalData)),
|
||||
asDerived()->getExtraLocalDataAlignment());
|
||||
}
|
||||
|
||||
unsigned getLocalDataSize() const {
|
||||
unsigned size = sizeof(LocalData);
|
||||
unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
|
||||
@ -449,9 +467,7 @@ private:
|
||||
return TypeLoc::getLocalAlignmentForType(T);
|
||||
}
|
||||
|
||||
TypeLoc getNextTypeLoc(HasNoInnerType _) const {
|
||||
return TypeLoc();
|
||||
}
|
||||
TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; }
|
||||
|
||||
TypeLoc getNextTypeLoc(QualType T) const {
|
||||
return TypeLoc(T, getNonLocalData());
|
||||
@ -464,6 +480,7 @@ private:
|
||||
template <class Base, class Derived, class TypeClass>
|
||||
class InheritingConcreteTypeLoc : public Base {
|
||||
friend class TypeLoc;
|
||||
|
||||
static bool classofType(const Type *Ty) {
|
||||
return TypeClass::classof(Ty);
|
||||
}
|
||||
@ -482,7 +499,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct TypeSpecLocInfo {
|
||||
SourceLocation NameLoc;
|
||||
};
|
||||
@ -502,22 +518,25 @@ public:
|
||||
SourceLocation getNameLoc() const {
|
||||
return this->getLocalData()->NameLoc;
|
||||
}
|
||||
|
||||
void setNameLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->NameLoc = Loc;
|
||||
}
|
||||
|
||||
SourceRange getLocalSourceRange() const {
|
||||
return SourceRange(getNameLoc(), getNameLoc());
|
||||
}
|
||||
|
||||
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
|
||||
setNameLoc(Loc);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class TypeLoc;
|
||||
|
||||
static bool isKind(const TypeLoc &TL);
|
||||
};
|
||||
|
||||
|
||||
struct BuiltinLocInfo {
|
||||
SourceRange BuiltinRange;
|
||||
};
|
||||
@ -531,9 +550,11 @@ public:
|
||||
SourceLocation getBuiltinLoc() const {
|
||||
return getLocalData()->BuiltinRange.getBegin();
|
||||
}
|
||||
|
||||
void setBuiltinLoc(SourceLocation Loc) {
|
||||
getLocalData()->BuiltinRange = Loc;
|
||||
}
|
||||
|
||||
void expandBuiltinRange(SourceRange Range) {
|
||||
SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
|
||||
if (!BuiltinRange.getBegin().isValid()) {
|
||||
@ -579,9 +600,11 @@ public:
|
||||
else
|
||||
return TSS_unspecified;
|
||||
}
|
||||
|
||||
bool hasWrittenSignSpec() const {
|
||||
return getWrittenSignSpec() != TSS_unspecified;
|
||||
}
|
||||
|
||||
void setWrittenSignSpec(TypeSpecifierSign written) {
|
||||
if (needsExtraLocalData())
|
||||
getWrittenBuiltinSpecs().Sign = written;
|
||||
@ -593,18 +616,22 @@ public:
|
||||
else
|
||||
return TSW_unspecified;
|
||||
}
|
||||
|
||||
bool hasWrittenWidthSpec() const {
|
||||
return getWrittenWidthSpec() != TSW_unspecified;
|
||||
}
|
||||
|
||||
void setWrittenWidthSpec(TypeSpecifierWidth written) {
|
||||
if (needsExtraLocalData())
|
||||
getWrittenBuiltinSpecs().Width = written;
|
||||
}
|
||||
|
||||
TypeSpecifierType getWrittenTypeSpec() const;
|
||||
|
||||
bool hasWrittenTypeSpec() const {
|
||||
return getWrittenTypeSpec() != TST_unspecified;
|
||||
}
|
||||
|
||||
void setWrittenTypeSpec(TypeSpecifierType written) {
|
||||
if (needsExtraLocalData())
|
||||
getWrittenBuiltinSpecs().Type = written;
|
||||
@ -616,6 +643,7 @@ public:
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void setModeAttr(bool written) {
|
||||
if (needsExtraLocalData())
|
||||
getWrittenBuiltinSpecs().ModeAttr = written;
|
||||
@ -633,7 +661,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Wrapper for source info for typedefs.
|
||||
class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
|
||||
TypedefTypeLoc,
|
||||
@ -742,6 +769,7 @@ public:
|
||||
*((SourceLocation*)this->getExtraLocalData()) :
|
||||
SourceLocation();
|
||||
}
|
||||
|
||||
void setProtocolLAngleLoc(SourceLocation Loc) {
|
||||
*((SourceLocation*)this->getExtraLocalData()) = Loc;
|
||||
}
|
||||
@ -751,6 +779,7 @@ public:
|
||||
*((SourceLocation*)this->getExtraLocalData() + 1) :
|
||||
SourceLocation();
|
||||
}
|
||||
|
||||
void setProtocolRAngleLoc(SourceLocation Loc) {
|
||||
*((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
|
||||
}
|
||||
@ -763,6 +792,7 @@ public:
|
||||
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;
|
||||
@ -785,9 +815,11 @@ public:
|
||||
// as well.
|
||||
return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
|
||||
}
|
||||
|
||||
unsigned getExtraLocalDataAlignment() const {
|
||||
return alignof(SourceLocation);
|
||||
}
|
||||
|
||||
SourceRange getLocalSourceRange() const {
|
||||
SourceLocation start = getNameLoc();
|
||||
SourceLocation end = getProtocolRAngleLoc();
|
||||
@ -938,7 +970,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct ObjCObjectTypeLocInfo {
|
||||
SourceLocation TypeArgsLAngleLoc;
|
||||
SourceLocation TypeArgsRAngleLoc;
|
||||
@ -971,6 +1002,7 @@ public:
|
||||
SourceLocation getTypeArgsLAngleLoc() const {
|
||||
return this->getLocalData()->TypeArgsLAngleLoc;
|
||||
}
|
||||
|
||||
void setTypeArgsLAngleLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->TypeArgsLAngleLoc = Loc;
|
||||
}
|
||||
@ -978,6 +1010,7 @@ public:
|
||||
SourceLocation getTypeArgsRAngleLoc() const {
|
||||
return this->getLocalData()->TypeArgsRAngleLoc;
|
||||
}
|
||||
|
||||
void setTypeArgsRAngleLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->TypeArgsRAngleLoc = Loc;
|
||||
}
|
||||
@ -999,6 +1032,7 @@ public:
|
||||
SourceLocation getProtocolLAngleLoc() const {
|
||||
return this->getLocalData()->ProtocolLAngleLoc;
|
||||
}
|
||||
|
||||
void setProtocolLAngleLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->ProtocolLAngleLoc = Loc;
|
||||
}
|
||||
@ -1006,6 +1040,7 @@ public:
|
||||
SourceLocation getProtocolRAngleLoc() const {
|
||||
return this->getLocalData()->ProtocolRAngleLoc;
|
||||
}
|
||||
|
||||
void setProtocolRAngleLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->ProtocolRAngleLoc = Loc;
|
||||
}
|
||||
@ -1018,6 +1053,7 @@ public:
|
||||
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;
|
||||
@ -1073,7 +1109,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct ObjCInterfaceLocInfo {
|
||||
SourceLocation NameLoc;
|
||||
SourceLocation NameEndLoc;
|
||||
@ -1127,12 +1162,15 @@ public:
|
||||
SourceLocation getLParenLoc() const {
|
||||
return this->getLocalData()->LParenLoc;
|
||||
}
|
||||
|
||||
SourceLocation getRParenLoc() const {
|
||||
return this->getLocalData()->RParenLoc;
|
||||
}
|
||||
|
||||
void setLParenLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->LParenLoc = Loc;
|
||||
}
|
||||
|
||||
void setRParenLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->RParenLoc = Loc;
|
||||
}
|
||||
@ -1161,8 +1199,7 @@ inline TypeLoc TypeLoc::IgnoreParens() const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
struct AdjustedLocInfo { }; // Nothing.
|
||||
struct AdjustedLocInfo {}; // Nothing.
|
||||
|
||||
class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
|
||||
AdjustedType, AdjustedLocInfo> {
|
||||
@ -1181,9 +1218,7 @@ public:
|
||||
return getTypePtr()->getOriginalType();
|
||||
}
|
||||
|
||||
SourceRange getLocalSourceRange() const {
|
||||
return SourceRange();
|
||||
}
|
||||
SourceRange getLocalSourceRange() const { return {}; }
|
||||
|
||||
unsigned getLocalDataSize() const {
|
||||
// sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
|
||||
@ -1210,6 +1245,7 @@ public:
|
||||
SourceLocation getSigilLoc() const {
|
||||
return this->getLocalData()->StarLoc;
|
||||
}
|
||||
|
||||
void setSigilLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->StarLoc = Loc;
|
||||
}
|
||||
@ -1231,7 +1267,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Wrapper for source info for pointers.
|
||||
class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
|
||||
PointerType> {
|
||||
@ -1239,12 +1274,12 @@ public:
|
||||
SourceLocation getStarLoc() const {
|
||||
return getSigilLoc();
|
||||
}
|
||||
|
||||
void setStarLoc(SourceLocation Loc) {
|
||||
setSigilLoc(Loc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Wrapper for source info for block pointers.
|
||||
class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
|
||||
BlockPointerType> {
|
||||
@ -1252,6 +1287,7 @@ public:
|
||||
SourceLocation getCaretLoc() const {
|
||||
return getSigilLoc();
|
||||
}
|
||||
|
||||
void setCaretLoc(SourceLocation Loc) {
|
||||
setSigilLoc(Loc);
|
||||
}
|
||||
@ -1269,6 +1305,7 @@ public:
|
||||
SourceLocation getStarLoc() const {
|
||||
return getSigilLoc();
|
||||
}
|
||||
|
||||
void setStarLoc(SourceLocation Loc) {
|
||||
setSigilLoc(Loc);
|
||||
}
|
||||
@ -1276,9 +1313,11 @@ public:
|
||||
const Type *getClass() const {
|
||||
return getTypePtr()->getClass();
|
||||
}
|
||||
|
||||
TypeSourceInfo *getClassTInfo() const {
|
||||
return getLocalData()->ClassTInfo;
|
||||
}
|
||||
|
||||
void setClassTInfo(TypeSourceInfo* TI) {
|
||||
getLocalData()->ClassTInfo = TI;
|
||||
}
|
||||
@ -1310,7 +1349,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
|
||||
ReferenceType> {
|
||||
public:
|
||||
@ -1327,6 +1365,7 @@ public:
|
||||
SourceLocation getAmpLoc() const {
|
||||
return getSigilLoc();
|
||||
}
|
||||
|
||||
void setAmpLoc(SourceLocation Loc) {
|
||||
setSigilLoc(Loc);
|
||||
}
|
||||
@ -1340,12 +1379,12 @@ public:
|
||||
SourceLocation getAmpAmpLoc() const {
|
||||
return getSigilLoc();
|
||||
}
|
||||
|
||||
void setAmpAmpLoc(SourceLocation Loc) {
|
||||
setSigilLoc(Loc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct FunctionLocInfo {
|
||||
SourceLocation LocalRangeBegin;
|
||||
SourceLocation LParenLoc;
|
||||
@ -1371,10 +1410,12 @@ class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
|
||||
// exception specification information.
|
||||
return (SourceRange *)(getParmArray() + getNumParams());
|
||||
}
|
||||
|
||||
public:
|
||||
SourceLocation getLocalRangeBegin() const {
|
||||
return getLocalData()->LocalRangeBegin;
|
||||
}
|
||||
|
||||
void setLocalRangeBegin(SourceLocation L) {
|
||||
getLocalData()->LocalRangeBegin = L;
|
||||
}
|
||||
@ -1382,6 +1423,7 @@ public:
|
||||
SourceLocation getLocalRangeEnd() const {
|
||||
return getLocalData()->LocalRangeEnd;
|
||||
}
|
||||
|
||||
void setLocalRangeEnd(SourceLocation L) {
|
||||
getLocalData()->LocalRangeEnd = L;
|
||||
}
|
||||
@ -1389,6 +1431,7 @@ public:
|
||||
SourceLocation getLParenLoc() const {
|
||||
return this->getLocalData()->LParenLoc;
|
||||
}
|
||||
|
||||
void setLParenLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->LParenLoc = Loc;
|
||||
}
|
||||
@ -1396,6 +1439,7 @@ public:
|
||||
SourceLocation getRParenLoc() const {
|
||||
return this->getLocalData()->RParenLoc;
|
||||
}
|
||||
|
||||
void setRParenLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->RParenLoc = Loc;
|
||||
}
|
||||
@ -1407,8 +1451,9 @@ public:
|
||||
SourceRange getExceptionSpecRange() const {
|
||||
if (hasExceptionSpec())
|
||||
return *getExceptionSpecRangePtr();
|
||||
return SourceRange();
|
||||
return {};
|
||||
}
|
||||
|
||||
void setExceptionSpecRange(SourceRange R) {
|
||||
if (hasExceptionSpec())
|
||||
*getExceptionSpecRangePtr() = R;
|
||||
@ -1428,6 +1473,7 @@ public:
|
||||
return 0;
|
||||
return cast<FunctionProtoType>(getTypePtr())->getNumParams();
|
||||
}
|
||||
|
||||
ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
|
||||
void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
|
||||
|
||||
@ -1474,7 +1520,6 @@ class FunctionNoProtoTypeLoc :
|
||||
FunctionNoProtoType> {
|
||||
};
|
||||
|
||||
|
||||
struct ArrayLocInfo {
|
||||
SourceLocation LBracketLoc, RBracketLoc;
|
||||
Expr *Size;
|
||||
@ -1489,6 +1534,7 @@ public:
|
||||
SourceLocation getLBracketLoc() const {
|
||||
return getLocalData()->LBracketLoc;
|
||||
}
|
||||
|
||||
void setLBracketLoc(SourceLocation Loc) {
|
||||
getLocalData()->LBracketLoc = Loc;
|
||||
}
|
||||
@ -1496,6 +1542,7 @@ public:
|
||||
SourceLocation getRBracketLoc() const {
|
||||
return getLocalData()->RBracketLoc;
|
||||
}
|
||||
|
||||
void setRBracketLoc(SourceLocation Loc) {
|
||||
getLocalData()->RBracketLoc = Loc;
|
||||
}
|
||||
@ -1507,6 +1554,7 @@ public:
|
||||
Expr *getSizeExpr() const {
|
||||
return getLocalData()->Size;
|
||||
}
|
||||
|
||||
void setSizeExpr(Expr *Size) {
|
||||
getLocalData()->Size = Size;
|
||||
}
|
||||
@ -1557,7 +1605,6 @@ class VariableArrayTypeLoc :
|
||||
VariableArrayType> {
|
||||
};
|
||||
|
||||
|
||||
// Location information for a TemplateName. Rudimentary for now.
|
||||
struct TemplateNameLocInfo {
|
||||
SourceLocation NameLoc;
|
||||
@ -1578,6 +1625,7 @@ public:
|
||||
SourceLocation getTemplateKeywordLoc() const {
|
||||
return getLocalData()->TemplateKWLoc;
|
||||
}
|
||||
|
||||
void setTemplateKeywordLoc(SourceLocation Loc) {
|
||||
getLocalData()->TemplateKWLoc = Loc;
|
||||
}
|
||||
@ -1585,6 +1633,7 @@ public:
|
||||
SourceLocation getLAngleLoc() const {
|
||||
return getLocalData()->LAngleLoc;
|
||||
}
|
||||
|
||||
void setLAngleLoc(SourceLocation Loc) {
|
||||
getLocalData()->LAngleLoc = Loc;
|
||||
}
|
||||
@ -1592,6 +1641,7 @@ public:
|
||||
SourceLocation getRAngleLoc() const {
|
||||
return getLocalData()->RAngleLoc;
|
||||
}
|
||||
|
||||
void setRAngleLoc(SourceLocation Loc) {
|
||||
getLocalData()->RAngleLoc = Loc;
|
||||
}
|
||||
@ -1599,9 +1649,11 @@ public:
|
||||
unsigned getNumArgs() const {
|
||||
return getTypePtr()->getNumArgs();
|
||||
}
|
||||
|
||||
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
|
||||
getArgInfos()[i] = AI;
|
||||
}
|
||||
|
||||
TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
|
||||
return getArgInfos()[i];
|
||||
}
|
||||
@ -1613,6 +1665,7 @@ public:
|
||||
SourceLocation getTemplateNameLoc() const {
|
||||
return getLocalData()->NameLoc;
|
||||
}
|
||||
|
||||
void setTemplateNameLoc(SourceLocation Loc) {
|
||||
getLocalData()->NameLoc = Loc;
|
||||
}
|
||||
@ -1664,6 +1717,74 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
struct DependentAddressSpaceLocInfo {
|
||||
Expr *ExprOperand;
|
||||
SourceRange OperandParens;
|
||||
SourceLocation AttrLoc;
|
||||
};
|
||||
|
||||
class DependentAddressSpaceTypeLoc
|
||||
: public ConcreteTypeLoc<UnqualTypeLoc,
|
||||
DependentAddressSpaceTypeLoc,
|
||||
DependentAddressSpaceType,
|
||||
DependentAddressSpaceLocInfo> {
|
||||
public:
|
||||
/// The location of the attribute name, i.e.
|
||||
/// int * __attribute__((address_space(11)))
|
||||
/// ^~~~~~~~~~~~~
|
||||
SourceLocation getAttrNameLoc() const {
|
||||
return getLocalData()->AttrLoc;
|
||||
}
|
||||
void setAttrNameLoc(SourceLocation loc) {
|
||||
getLocalData()->AttrLoc = loc;
|
||||
}
|
||||
|
||||
/// The attribute's expression operand, if it has one.
|
||||
/// int * __attribute__((address_space(11)))
|
||||
/// ^~
|
||||
Expr *getAttrExprOperand() const {
|
||||
return getLocalData()->ExprOperand;
|
||||
}
|
||||
void setAttrExprOperand(Expr *e) {
|
||||
getLocalData()->ExprOperand = e;
|
||||
}
|
||||
|
||||
/// The location of the parentheses around the operand, if there is
|
||||
/// an operand.
|
||||
/// int * __attribute__((address_space(11)))
|
||||
/// ^ ^
|
||||
SourceRange getAttrOperandParensRange() const {
|
||||
return getLocalData()->OperandParens;
|
||||
}
|
||||
void setAttrOperandParensRange(SourceRange range) {
|
||||
getLocalData()->OperandParens = range;
|
||||
}
|
||||
|
||||
SourceRange getLocalSourceRange() const {
|
||||
SourceRange range(getAttrNameLoc());
|
||||
range.setEnd(getAttrOperandParensRange().getEnd());
|
||||
return range;
|
||||
}
|
||||
|
||||
/// Returns the type before the address space attribute application
|
||||
/// area.
|
||||
/// int * __attribute__((address_space(11))) *
|
||||
/// ^ ^
|
||||
QualType getInnerType() const {
|
||||
return this->getTypePtr()->getPointeeType();
|
||||
}
|
||||
|
||||
TypeLoc getPointeeTypeLoc() const {
|
||||
return this->getInnerTypeLoc();
|
||||
}
|
||||
|
||||
void initializeLocal(ASTContext &Context, SourceLocation loc) {
|
||||
setAttrNameLoc(loc);
|
||||
setAttrOperandParensRange(SourceRange(loc));
|
||||
setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// All of these need proper implementations.
|
||||
@ -1717,6 +1838,7 @@ public:
|
||||
SourceLocation getTypeofLoc() const {
|
||||
return this->getLocalData()->TypeofLoc;
|
||||
}
|
||||
|
||||
void setTypeofLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->TypeofLoc = Loc;
|
||||
}
|
||||
@ -1724,6 +1846,7 @@ public:
|
||||
SourceLocation getLParenLoc() const {
|
||||
return this->getLocalData()->LParenLoc;
|
||||
}
|
||||
|
||||
void setLParenLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->LParenLoc = Loc;
|
||||
}
|
||||
@ -1731,6 +1854,7 @@ public:
|
||||
SourceLocation getRParenLoc() const {
|
||||
return this->getLocalData()->RParenLoc;
|
||||
}
|
||||
|
||||
void setRParenLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->RParenLoc = Loc;
|
||||
}
|
||||
@ -1738,6 +1862,7 @@ public:
|
||||
SourceRange getParensRange() const {
|
||||
return SourceRange(getLParenLoc(), getRParenLoc());
|
||||
}
|
||||
|
||||
void setParensRange(SourceRange range) {
|
||||
setLParenLoc(range.getBegin());
|
||||
setRParenLoc(range.getEnd());
|
||||
@ -1761,6 +1886,7 @@ public:
|
||||
Expr* getUnderlyingExpr() const {
|
||||
return getTypePtr()->getUnderlyingExpr();
|
||||
}
|
||||
|
||||
// Reimplemented to account for GNU/C++ extension
|
||||
// typeof unary-expression
|
||||
// where there are no parentheses.
|
||||
@ -1773,9 +1899,11 @@ public:
|
||||
QualType getUnderlyingType() const {
|
||||
return this->getTypePtr()->getUnderlyingType();
|
||||
}
|
||||
|
||||
TypeSourceInfo* getUnderlyingTInfo() const {
|
||||
return this->getLocalData()->UnderlyingTInfo;
|
||||
}
|
||||
|
||||
void setUnderlyingTInfo(TypeSourceInfo* TI) const {
|
||||
this->getLocalData()->UnderlyingTInfo = TI;
|
||||
}
|
||||
@ -1815,6 +1943,7 @@ public:
|
||||
TypeSourceInfo* getUnderlyingTInfo() const {
|
||||
return getLocalData()->UnderlyingTInfo;
|
||||
}
|
||||
|
||||
void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
|
||||
getLocalData()->UnderlyingTInfo = TInfo;
|
||||
}
|
||||
@ -1826,16 +1955,13 @@ public:
|
||||
SourceRange getParensRange() const {
|
||||
return SourceRange(getLParenLoc(), getRParenLoc());
|
||||
}
|
||||
|
||||
void setParensRange(SourceRange Range) {
|
||||
setLParenLoc(Range.getBegin());
|
||||
setRParenLoc(Range.getEnd());
|
||||
}
|
||||
|
||||
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
|
||||
setKWLoc(Loc);
|
||||
setRParenLoc(Loc);
|
||||
setLParenLoc(Loc);
|
||||
}
|
||||
void initializeLocal(ASTContext &Context, SourceLocation Loc);
|
||||
};
|
||||
|
||||
class DeducedTypeLoc
|
||||
@ -1854,6 +1980,7 @@ public:
|
||||
SourceLocation getTemplateNameLoc() const {
|
||||
return getNameLoc();
|
||||
}
|
||||
|
||||
void setTemplateNameLoc(SourceLocation Loc) {
|
||||
setNameLoc(Loc);
|
||||
}
|
||||
@ -1861,6 +1988,7 @@ public:
|
||||
|
||||
struct ElaboratedLocInfo {
|
||||
SourceLocation ElaboratedKWLoc;
|
||||
|
||||
/// \brief Data associated with the nested-name-specifier location.
|
||||
void *QualifierData;
|
||||
};
|
||||
@ -1873,6 +2001,7 @@ public:
|
||||
SourceLocation getElaboratedKeywordLoc() const {
|
||||
return this->getLocalData()->ElaboratedKWLoc;
|
||||
}
|
||||
|
||||
void setElaboratedKeywordLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->ElaboratedKWLoc = Loc;
|
||||
}
|
||||
@ -1931,6 +2060,7 @@ public:
|
||||
SourceLocation getElaboratedKeywordLoc() const {
|
||||
return this->getLocalData()->ElaboratedKWLoc;
|
||||
}
|
||||
|
||||
void setElaboratedKeywordLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->ElaboratedKWLoc = Loc;
|
||||
}
|
||||
@ -1950,6 +2080,7 @@ public:
|
||||
SourceLocation getNameLoc() const {
|
||||
return this->getLocalData()->NameLoc;
|
||||
}
|
||||
|
||||
void setNameLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->NameLoc = Loc;
|
||||
}
|
||||
@ -1986,6 +2117,7 @@ public:
|
||||
SourceLocation getElaboratedKeywordLoc() const {
|
||||
return this->getLocalData()->ElaboratedKWLoc;
|
||||
}
|
||||
|
||||
void setElaboratedKeywordLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->ElaboratedKWLoc = Loc;
|
||||
}
|
||||
@ -2017,6 +2149,7 @@ public:
|
||||
SourceLocation getTemplateKeywordLoc() const {
|
||||
return getLocalData()->TemplateKWLoc;
|
||||
}
|
||||
|
||||
void setTemplateKeywordLoc(SourceLocation Loc) {
|
||||
getLocalData()->TemplateKWLoc = Loc;
|
||||
}
|
||||
@ -2024,6 +2157,7 @@ public:
|
||||
SourceLocation getTemplateNameLoc() const {
|
||||
return this->getLocalData()->NameLoc;
|
||||
}
|
||||
|
||||
void setTemplateNameLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->NameLoc = Loc;
|
||||
}
|
||||
@ -2031,6 +2165,7 @@ public:
|
||||
SourceLocation getLAngleLoc() const {
|
||||
return this->getLocalData()->LAngleLoc;
|
||||
}
|
||||
|
||||
void setLAngleLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->LAngleLoc = Loc;
|
||||
}
|
||||
@ -2038,6 +2173,7 @@ public:
|
||||
SourceLocation getRAngleLoc() const {
|
||||
return this->getLocalData()->RAngleLoc;
|
||||
}
|
||||
|
||||
void setRAngleLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->RAngleLoc = Loc;
|
||||
}
|
||||
@ -2049,6 +2185,7 @@ public:
|
||||
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
|
||||
getArgInfos()[i] = AI;
|
||||
}
|
||||
|
||||
TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
|
||||
return getArgInfos()[i];
|
||||
}
|
||||
@ -2090,7 +2227,6 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct PackExpansionTypeLocInfo {
|
||||
SourceLocation EllipsisLoc;
|
||||
};
|
||||
@ -2142,6 +2278,7 @@ public:
|
||||
SourceLocation getKWLoc() const {
|
||||
return this->getLocalData()->KWLoc;
|
||||
}
|
||||
|
||||
void setKWLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->KWLoc = Loc;
|
||||
}
|
||||
@ -2149,6 +2286,7 @@ public:
|
||||
SourceLocation getLParenLoc() const {
|
||||
return this->getLocalData()->LParenLoc;
|
||||
}
|
||||
|
||||
void setLParenLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->LParenLoc = Loc;
|
||||
}
|
||||
@ -2156,6 +2294,7 @@ public:
|
||||
SourceLocation getRParenLoc() const {
|
||||
return this->getLocalData()->RParenLoc;
|
||||
}
|
||||
|
||||
void setRParenLoc(SourceLocation Loc) {
|
||||
this->getLocalData()->RParenLoc = Loc;
|
||||
}
|
||||
@ -2163,6 +2302,7 @@ public:
|
||||
SourceRange getParensRange() const {
|
||||
return SourceRange(getLParenLoc(), getRParenLoc());
|
||||
}
|
||||
|
||||
void setParensRange(SourceRange Range) {
|
||||
setLParenLoc(Range.getBegin());
|
||||
setRParenLoc(Range.getEnd());
|
||||
@ -2217,6 +2357,7 @@ inline T TypeLoc::getAsAdjusted() const {
|
||||
}
|
||||
return Cur.getAs<T>();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_TYPELOC_H
|
||||
|
@ -23,7 +23,7 @@
|
||||
// NON_CANONICAL_TYPE(Class, Base) - A type that can show up
|
||||
// anywhere in the AST but will never be a part of a canonical
|
||||
// type. Clients that only need to deal with canonical types
|
||||
// (ignoring, e.g., typedefs and other type alises used for
|
||||
// (ignoring, e.g., typedefs and other type aliases used for
|
||||
// pretty-printing) can ignore these types.
|
||||
//
|
||||
// DEPENDENT_TYPE(Class, Base) - A type that will only show up
|
||||
@ -73,6 +73,7 @@ TYPE(IncompleteArray, ArrayType)
|
||||
TYPE(VariableArray, ArrayType)
|
||||
DEPENDENT_TYPE(DependentSizedArray, ArrayType)
|
||||
DEPENDENT_TYPE(DependentSizedExtVector, Type)
|
||||
DEPENDENT_TYPE(DependentAddressSpace, Type)
|
||||
TYPE(Vector, Type)
|
||||
TYPE(ExtVector, VectorType)
|
||||
ABSTRACT_TYPE(Function, Type)
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===//
|
||||
//===- UnresolvedSet.h - Unresolved sets of declarations --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -17,20 +17,25 @@
|
||||
|
||||
#include "clang/AST/DeclAccessPair.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/iterator.h"
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class NamedDecl;
|
||||
|
||||
/// The iterator over UnresolvedSets. Serves as both the const and
|
||||
/// non-const iterator.
|
||||
class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
|
||||
UnresolvedSetIterator, DeclAccessPair *,
|
||||
std::random_access_iterator_tag, NamedDecl *,
|
||||
std::ptrdiff_t, NamedDecl *, NamedDecl *> {
|
||||
friend class UnresolvedSetImpl;
|
||||
friend class ASTUnresolvedSet;
|
||||
friend class OverloadExpr;
|
||||
friend class UnresolvedSetImpl;
|
||||
|
||||
explicit UnresolvedSetIterator(DeclAccessPair *Iter)
|
||||
: iterator_adaptor_base(Iter) {}
|
||||
@ -54,12 +59,13 @@ public:
|
||||
|
||||
/// \brief A set of unresolved declarations.
|
||||
class UnresolvedSetImpl {
|
||||
typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
|
||||
using DeclsTy = SmallVectorImpl<DeclAccessPair>;
|
||||
|
||||
// Don't allow direct construction, and only permit subclassing by
|
||||
// UnresolvedSet.
|
||||
private:
|
||||
template <unsigned N> friend class UnresolvedSet;
|
||||
|
||||
UnresolvedSetImpl() = default;
|
||||
UnresolvedSetImpl(const UnresolvedSetImpl &) = default;
|
||||
UnresolvedSetImpl &operator=(const UnresolvedSetImpl &) = default;
|
||||
@ -71,8 +77,8 @@ private:
|
||||
public:
|
||||
// We don't currently support assignment through this iterator, so we might
|
||||
// as well use the same implementation twice.
|
||||
typedef UnresolvedSetIterator iterator;
|
||||
typedef UnresolvedSetIterator const_iterator;
|
||||
using iterator = UnresolvedSetIterator;
|
||||
using const_iterator = UnresolvedSetIterator;
|
||||
|
||||
iterator begin() { return iterator(decls().begin()); }
|
||||
iterator end() { return iterator(decls().end()); }
|
||||
@ -140,7 +146,7 @@ template <unsigned InlineCapacity> class UnresolvedSet :
|
||||
SmallVector<DeclAccessPair, InlineCapacity> Decls;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_UNRESOLVEDSET_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=//
|
||||
//===- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -16,25 +16,31 @@
|
||||
#define LLVM_CLANG_AST_VTTBUILDER_H
|
||||
|
||||
#include "clang/AST/BaseSubobject.h"
|
||||
#include "clang/AST/CXXInheritance.h"
|
||||
#include "clang/AST/GlobalDecl.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include <utility>
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class ASTRecordLayout;
|
||||
class CXXRecordDecl;
|
||||
|
||||
class VTTVTable {
|
||||
llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
|
||||
CharUnits BaseOffset;
|
||||
|
||||
public:
|
||||
VTTVTable() {}
|
||||
VTTVTable() = default;
|
||||
VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
|
||||
: BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
|
||||
: BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
|
||||
VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
|
||||
: BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
|
||||
BaseOffset(Base.getBaseOffset()) {}
|
||||
: BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
|
||||
BaseOffset(Base.getBaseOffset()) {}
|
||||
|
||||
const CXXRecordDecl *getBase() const {
|
||||
return BaseAndIsVirtual.getPointer();
|
||||
@ -57,25 +63,24 @@ struct VTTComponent {
|
||||
uint64_t VTableIndex;
|
||||
BaseSubobject VTableBase;
|
||||
|
||||
VTTComponent() {}
|
||||
VTTComponent() = default;
|
||||
VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
|
||||
: VTableIndex(VTableIndex), VTableBase(VTableBase) {}
|
||||
: VTableIndex(VTableIndex), VTableBase(VTableBase) {}
|
||||
};
|
||||
|
||||
/// \brief Class for building VTT layout information.
|
||||
class VTTBuilder {
|
||||
|
||||
ASTContext &Ctx;
|
||||
|
||||
/// \brief The most derived class for which we're building this vtable.
|
||||
const CXXRecordDecl *MostDerivedClass;
|
||||
|
||||
typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
|
||||
using VTTVTablesVectorTy = SmallVector<VTTVTable, 64>;
|
||||
|
||||
/// \brief The VTT vtables.
|
||||
VTTVTablesVectorTy VTTVTables;
|
||||
|
||||
typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
|
||||
using VTTComponentsVectorTy = SmallVector<VTTComponent, 64>;
|
||||
|
||||
/// \brief The VTT components.
|
||||
VTTComponentsVectorTy VTTComponents;
|
||||
@ -83,9 +88,9 @@ class VTTBuilder {
|
||||
/// \brief The AST record layout of the most derived class.
|
||||
const ASTRecordLayout &MostDerivedClassLayout;
|
||||
|
||||
typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
|
||||
using VisitedVirtualBasesSetTy = llvm::SmallPtrSet<const CXXRecordDecl *, 4>;
|
||||
|
||||
typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
|
||||
using AddressPointsMapTy = llvm::DenseMap<BaseSubobject, uint64_t>;
|
||||
|
||||
/// \brief The sub-VTT indices for the bases of the most derived class.
|
||||
llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
|
||||
@ -153,9 +158,8 @@ public:
|
||||
getSecondaryVirtualPointerIndices() const {
|
||||
return SecondaryVirtualPointerIndices;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_AST_VTTBUILDER_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
//===--- ASTMatchersInternal.h - Structural query framework -----*- C++ -*-===//
|
||||
//===- ASTMatchersInternal.h - Structural query framework -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -38,23 +38,42 @@
|
||||
#include "clang/AST/ASTTypeTraits.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/ExprObjC.h"
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "clang/AST/StmtCXX.h"
|
||||
#include "clang/AST/StmtObjC.h"
|
||||
#include "clang/AST/TemplateName.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/OperatorKinds.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/iterator.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
|
||||
namespace ast_matchers {
|
||||
|
||||
class BoundNodes;
|
||||
@ -158,7 +177,7 @@ public:
|
||||
/// Note that we're using std::map here, as for memoization:
|
||||
/// - we need a comparison operator
|
||||
/// - we need an assignment operator
|
||||
typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap;
|
||||
using IDToNodeMap = std::map<std::string, ast_type_traits::DynTypedNode>;
|
||||
|
||||
const IDToNodeMap &getMap() const {
|
||||
return NodeMap;
|
||||
@ -188,7 +207,7 @@ public:
|
||||
/// BoundNodesTree.
|
||||
class Visitor {
|
||||
public:
|
||||
virtual ~Visitor() {}
|
||||
virtual ~Visitor() = default;
|
||||
|
||||
/// \brief Called multiple times during a single call to VisitMatches(...).
|
||||
///
|
||||
@ -248,7 +267,7 @@ class ASTMatchFinder;
|
||||
class DynMatcherInterface
|
||||
: public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
|
||||
public:
|
||||
virtual ~DynMatcherInterface() {}
|
||||
virtual ~DynMatcherInterface() = default;
|
||||
|
||||
/// \brief Returns true if \p DynNode can be matched.
|
||||
///
|
||||
@ -317,26 +336,29 @@ public:
|
||||
/// \brief Takes ownership of the provided implementation pointer.
|
||||
template <typename T>
|
||||
DynTypedMatcher(MatcherInterface<T> *Implementation)
|
||||
: AllowBind(false),
|
||||
SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
|
||||
: SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
|
||||
RestrictKind(SupportedKind), Implementation(Implementation) {}
|
||||
|
||||
/// \brief Construct from a variadic function.
|
||||
enum VariadicOperator {
|
||||
/// \brief Matches nodes for which all provided matchers match.
|
||||
VO_AllOf,
|
||||
|
||||
/// \brief Matches nodes for which at least one of the provided matchers
|
||||
/// matches.
|
||||
VO_AnyOf,
|
||||
|
||||
/// \brief Matches nodes for which at least one of the provided matchers
|
||||
/// matches, but doesn't stop at the first match.
|
||||
VO_EachOf,
|
||||
|
||||
/// \brief Matches nodes that do not match the provided matcher.
|
||||
///
|
||||
/// Uses the variadic matcher interface, but fails if
|
||||
/// InnerMatchers.size() != 1.
|
||||
VO_UnaryNot
|
||||
};
|
||||
|
||||
static DynTypedMatcher
|
||||
constructVariadic(VariadicOperator Op,
|
||||
ast_type_traits::ASTNodeKind SupportedKind,
|
||||
@ -382,7 +404,7 @@ public:
|
||||
/// include both in the ID to make it unique.
|
||||
///
|
||||
/// \c MatcherIDType supports operator< and provides strict weak ordering.
|
||||
typedef std::pair<ast_type_traits::ASTNodeKind, uint64_t> MatcherIDType;
|
||||
using MatcherIDType = std::pair<ast_type_traits::ASTNodeKind, uint64_t>;
|
||||
MatcherIDType getID() const {
|
||||
/// FIXME: Document the requirements this imposes on matcher
|
||||
/// implementations (no new() implementation_ during a Matches()).
|
||||
@ -428,13 +450,12 @@ private:
|
||||
DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
|
||||
ast_type_traits::ASTNodeKind RestrictKind,
|
||||
IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
|
||||
: AllowBind(false),
|
||||
SupportedKind(SupportedKind),
|
||||
RestrictKind(RestrictKind),
|
||||
: SupportedKind(SupportedKind), RestrictKind(RestrictKind),
|
||||
Implementation(std::move(Implementation)) {}
|
||||
|
||||
bool AllowBind;
|
||||
bool AllowBind = false;
|
||||
ast_type_traits::ASTNodeKind SupportedKind;
|
||||
|
||||
/// \brief A potentially stricter node kind.
|
||||
///
|
||||
/// It allows to perform implicit and dynamic cast of matchers without
|
||||
@ -545,6 +566,7 @@ public:
|
||||
private:
|
||||
// For Matcher<T> <=> Matcher<U> conversions.
|
||||
template <typename U> friend class Matcher;
|
||||
|
||||
// For DynTypedMatcher::unconditionalConvertTo<T>.
|
||||
friend class DynTypedMatcher;
|
||||
|
||||
@ -618,8 +640,8 @@ bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start,
|
||||
// Metafunction to determine if type T has a member called getDecl.
|
||||
template <typename Ty>
|
||||
class has_getDecl {
|
||||
typedef char yes[1];
|
||||
typedef char no[2];
|
||||
using yes = char[1];
|
||||
using no = char[2];
|
||||
|
||||
template <typename Inner>
|
||||
static yes& test(Inner *I, decltype(I->getDecl()) * = nullptr);
|
||||
@ -728,48 +750,94 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief If getDecl exists as a member of U, returns whether the inner
|
||||
/// matcher matches Node.getDecl().
|
||||
template <typename U>
|
||||
bool matchesSpecialized(
|
||||
const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
|
||||
typename std::enable_if<has_getDecl<U>::value, int>::type = 0) const {
|
||||
return matchesDecl(Node.getDecl(), Finder, Builder);
|
||||
}
|
||||
|
||||
/// \brief Extracts the TagDecl of a QualType and returns whether the inner
|
||||
/// matcher matches on it.
|
||||
/// \brief Forwards to matching on the underlying type of the QualType.
|
||||
bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
|
||||
BoundNodesTreeBuilder *Builder) const {
|
||||
if (Node.isNull())
|
||||
return false;
|
||||
|
||||
if (auto *TD = Node->getAsTagDecl())
|
||||
return matchesDecl(TD, Finder, Builder);
|
||||
else if (auto *TT = Node->getAs<TypedefType>())
|
||||
return matchesDecl(TT->getDecl(), Finder, Builder);
|
||||
// Do not use getAs<TemplateTypeParmType> instead of the direct dyn_cast.
|
||||
// Calling getAs will return the canonical type, but that type does not
|
||||
// store a TemplateTypeParmDecl. We *need* the uncanonical type, if it is
|
||||
// available, and using dyn_cast ensures that.
|
||||
else if (auto *TTP = dyn_cast<TemplateTypeParmType>(Node.getTypePtr()))
|
||||
return matchesDecl(TTP->getDecl(), Finder, Builder);
|
||||
else if (auto *OCIT = Node->getAs<ObjCInterfaceType>())
|
||||
return matchesDecl(OCIT->getDecl(), Finder, Builder);
|
||||
else if (auto *UUT = Node->getAs<UnresolvedUsingType>())
|
||||
return matchesDecl(UUT->getDecl(), Finder, Builder);
|
||||
else if (auto *ICNT = Node->getAs<InjectedClassNameType>())
|
||||
return matchesDecl(ICNT->getDecl(), Finder, Builder);
|
||||
return matchesSpecialized(*Node, Finder, Builder);
|
||||
}
|
||||
|
||||
/// \brief Finds the best declaration for a type and returns whether the inner
|
||||
/// matcher matches on it.
|
||||
bool matchesSpecialized(const Type &Node, ASTMatchFinder *Finder,
|
||||
BoundNodesTreeBuilder *Builder) const {
|
||||
// DeducedType does not have declarations of its own, so
|
||||
// match the deduced type instead.
|
||||
const Type *EffectiveType = &Node;
|
||||
if (const auto *S = dyn_cast<DeducedType>(&Node)) {
|
||||
EffectiveType = S->getDeducedType().getTypePtrOrNull();
|
||||
if (!EffectiveType)
|
||||
return false;
|
||||
}
|
||||
|
||||
// First, for any types that have a declaration, extract the declaration and
|
||||
// match on it.
|
||||
if (const auto *S = dyn_cast<TagType>(EffectiveType)) {
|
||||
return matchesDecl(S->getDecl(), Finder, Builder);
|
||||
}
|
||||
if (const auto *S = dyn_cast<InjectedClassNameType>(EffectiveType)) {
|
||||
return matchesDecl(S->getDecl(), Finder, Builder);
|
||||
}
|
||||
if (const auto *S = dyn_cast<TemplateTypeParmType>(EffectiveType)) {
|
||||
return matchesDecl(S->getDecl(), Finder, Builder);
|
||||
}
|
||||
if (const auto *S = dyn_cast<TypedefType>(EffectiveType)) {
|
||||
return matchesDecl(S->getDecl(), Finder, Builder);
|
||||
}
|
||||
if (const auto *S = dyn_cast<UnresolvedUsingType>(EffectiveType)) {
|
||||
return matchesDecl(S->getDecl(), Finder, Builder);
|
||||
}
|
||||
if (const auto *S = dyn_cast<ObjCObjectType>(EffectiveType)) {
|
||||
return matchesDecl(S->getInterface(), Finder, Builder);
|
||||
}
|
||||
|
||||
// A SubstTemplateTypeParmType exists solely to mark a type substitution
|
||||
// on the instantiated template. As users usually want to match the
|
||||
// template parameter on the uninitialized template, we can always desugar
|
||||
// one level without loss of expressivness.
|
||||
// For example, given:
|
||||
// template<typename T> struct X { T t; } class A {}; X<A> a;
|
||||
// The following matcher will match, which otherwise would not:
|
||||
// fieldDecl(hasType(pointerType())).
|
||||
if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(EffectiveType)) {
|
||||
return matchesSpecialized(S->getReplacementType(), Finder, Builder);
|
||||
}
|
||||
|
||||
// For template specialization types, we want to match the template
|
||||
// declaration, as long as the type is still dependent, and otherwise the
|
||||
// declaration of the instantiated tag type.
|
||||
if (const auto *S = dyn_cast<TemplateSpecializationType>(EffectiveType)) {
|
||||
if (!S->isTypeAlias() && S->isSugared()) {
|
||||
// If the template is non-dependent, we want to match the instantiated
|
||||
// tag type.
|
||||
// For example, given:
|
||||
// template<typename T> struct X {}; X<int> a;
|
||||
// The following matcher will match, which otherwise would not:
|
||||
// templateSpecializationType(hasDeclaration(cxxRecordDecl())).
|
||||
return matchesSpecialized(*S->desugar(), Finder, Builder);
|
||||
}
|
||||
// If the template is dependent or an alias, match the template
|
||||
// declaration.
|
||||
return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder,
|
||||
Builder);
|
||||
}
|
||||
|
||||
// FIXME: We desugar elaborated types. This makes the assumption that users
|
||||
// do never want to match on whether a type is elaborated - there are
|
||||
// arguments for both sides; for now, continue desugaring.
|
||||
if (const auto *S = dyn_cast<ElaboratedType>(EffectiveType)) {
|
||||
return matchesSpecialized(S->desugar(), Finder, Builder);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Gets the TemplateDecl from a TemplateSpecializationType
|
||||
/// and returns whether the inner matches on it.
|
||||
bool matchesSpecialized(const TemplateSpecializationType &Node,
|
||||
ASTMatchFinder *Finder,
|
||||
/// \brief Extracts the Decl the DeclRefExpr references and returns whether
|
||||
/// the inner matcher matches on it.
|
||||
bool matchesSpecialized(const DeclRefExpr &Node, ASTMatchFinder *Finder,
|
||||
BoundNodesTreeBuilder *Builder) const {
|
||||
return matchesDecl(Node.getTemplateName().getAsTemplateDecl(),
|
||||
Finder, Builder);
|
||||
return matchesDecl(Node.getDecl(), Finder, Builder);
|
||||
}
|
||||
|
||||
/// \brief Extracts the Decl of the callee of a CallExpr and returns whether
|
||||
@ -811,6 +879,13 @@ private:
|
||||
return matchesDecl(Node.getLabel(), Finder, Builder);
|
||||
}
|
||||
|
||||
/// \brief Extracts the declaration of a LabelStmt and returns whether the
|
||||
/// inner matcher matches on it.
|
||||
bool matchesSpecialized(const LabelStmt &Node, ASTMatchFinder *Finder,
|
||||
BoundNodesTreeBuilder *Builder) const {
|
||||
return matchesDecl(Node.getDecl(), Finder, Builder);
|
||||
}
|
||||
|
||||
/// \brief Returns whether the inner matcher \c Node. Returns false if \c Node
|
||||
/// is \c NULL.
|
||||
bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
|
||||
@ -863,6 +938,7 @@ public:
|
||||
enum TraversalKind {
|
||||
/// Will traverse any child nodes.
|
||||
TK_AsIs,
|
||||
|
||||
/// Will not traverse implicit casts and parentheses.
|
||||
TK_IgnoreImplicitCastsAndParentheses
|
||||
};
|
||||
@ -871,6 +947,7 @@ public:
|
||||
enum BindKind {
|
||||
/// Stop at the first match and only bind the first match.
|
||||
BK_First,
|
||||
|
||||
/// Create results for all combinations of bindings that match.
|
||||
BK_All
|
||||
};
|
||||
@ -879,11 +956,12 @@ public:
|
||||
enum AncestorMatchMode {
|
||||
/// All ancestors.
|
||||
AMM_All,
|
||||
|
||||
/// Direct parent only.
|
||||
AMM_ParentOnly
|
||||
};
|
||||
|
||||
virtual ~ASTMatchFinder() {}
|
||||
virtual ~ASTMatchFinder() = default;
|
||||
|
||||
/// \brief Returns true if the given class is directly or indirectly derived
|
||||
/// from a base type matching \c base.
|
||||
@ -906,7 +984,7 @@ public:
|
||||
std::is_base_of<TypeLoc, T>::value ||
|
||||
std::is_base_of<QualType, T>::value,
|
||||
"unsupported type for recursive matching");
|
||||
return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
|
||||
return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
|
||||
Matcher, Builder, Traverse, Bind);
|
||||
}
|
||||
|
||||
@ -969,17 +1047,17 @@ template <typename... Ts> struct TypeList {}; // Empty sentinel type list.
|
||||
|
||||
template <typename T1, typename... Ts> struct TypeList<T1, Ts...> {
|
||||
/// \brief The first type on the list.
|
||||
typedef T1 head;
|
||||
using head = T1;
|
||||
|
||||
/// \brief A sublist with the tail. ie everything but the head.
|
||||
///
|
||||
/// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
|
||||
/// end of the list.
|
||||
typedef TypeList<Ts...> tail;
|
||||
using tail = TypeList<Ts...>;
|
||||
};
|
||||
|
||||
/// \brief The empty type list.
|
||||
typedef TypeList<> EmptyTypeList;
|
||||
using EmptyTypeList = TypeList<>;
|
||||
|
||||
/// \brief Helper meta-function to determine if some type \c T is present or
|
||||
/// a parent type in the list.
|
||||
@ -997,8 +1075,9 @@ struct TypeListContainsSuperOf<EmptyTypeList, T> {
|
||||
/// \brief A "type list" that contains all types.
|
||||
///
|
||||
/// Useful for matchers like \c anything and \c unless.
|
||||
typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
|
||||
QualType, Type, TypeLoc, CXXCtorInitializer> AllNodeBaseTypes;
|
||||
using AllNodeBaseTypes =
|
||||
TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
|
||||
Type, TypeLoc, CXXCtorInitializer>;
|
||||
|
||||
/// \brief Helper meta-function to extract the argument out of a function of
|
||||
/// type void(Arg).
|
||||
@ -1006,20 +1085,22 @@ typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
|
||||
/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
|
||||
template <class T> struct ExtractFunctionArgMeta;
|
||||
template <class T> struct ExtractFunctionArgMeta<void(T)> {
|
||||
typedef T type;
|
||||
using type = T;
|
||||
};
|
||||
|
||||
/// \brief Default type lists for ArgumentAdaptingMatcher matchers.
|
||||
typedef AllNodeBaseTypes AdaptativeDefaultFromTypes;
|
||||
typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
|
||||
TypeLoc, QualType> AdaptativeDefaultToTypes;
|
||||
using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
|
||||
using AdaptativeDefaultToTypes =
|
||||
TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
|
||||
QualType>;
|
||||
|
||||
/// \brief All types that are supported by HasDeclarationMatcher above.
|
||||
typedef TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
|
||||
InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr,
|
||||
QualType, RecordType, TagType, TemplateSpecializationType,
|
||||
TemplateTypeParmType, TypedefType, UnresolvedUsingType>
|
||||
HasDeclarationSupportedTypes;
|
||||
using HasDeclarationSupportedTypes =
|
||||
TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
|
||||
ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
|
||||
MemberExpr, QualType, RecordType, TagType,
|
||||
TemplateSpecializationType, TemplateTypeParmType, TypedefType,
|
||||
UnresolvedUsingType>;
|
||||
|
||||
/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by
|
||||
/// "adapting" a \c To into a \c T.
|
||||
@ -1043,7 +1124,7 @@ struct ArgumentAdaptingMatcherFunc {
|
||||
explicit Adaptor(const Matcher<T> &InnerMatcher)
|
||||
: InnerMatcher(InnerMatcher) {}
|
||||
|
||||
typedef ToTypes ReturnTypes;
|
||||
using ReturnTypes = ToTypes;
|
||||
|
||||
template <typename To> operator Matcher<To>() const {
|
||||
return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
|
||||
@ -1080,7 +1161,8 @@ template <template <typename T> class MatcherT,
|
||||
typename ReturnTypesF = void(AllNodeBaseTypes)>
|
||||
class PolymorphicMatcherWithParam0 {
|
||||
public:
|
||||
typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
|
||||
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
|
||||
|
||||
template <typename T>
|
||||
operator Matcher<T>() const {
|
||||
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
|
||||
@ -1097,7 +1179,7 @@ public:
|
||||
explicit PolymorphicMatcherWithParam1(const P1 &Param1)
|
||||
: Param1(Param1) {}
|
||||
|
||||
typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
|
||||
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
|
||||
|
||||
template <typename T>
|
||||
operator Matcher<T>() const {
|
||||
@ -1118,7 +1200,7 @@ public:
|
||||
PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2)
|
||||
: Param1(Param1), Param2(Param2) {}
|
||||
|
||||
typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
|
||||
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
|
||||
|
||||
template <typename T>
|
||||
operator Matcher<T>() const {
|
||||
@ -1137,8 +1219,8 @@ private:
|
||||
/// This is useful when a matcher syntactically requires a child matcher,
|
||||
/// but the context doesn't care. See for example: anything().
|
||||
class TrueMatcher {
|
||||
public:
|
||||
typedef AllNodeBaseTypes ReturnTypes;
|
||||
public:
|
||||
using ReturnTypes = AllNodeBaseTypes;
|
||||
|
||||
template <typename T>
|
||||
operator Matcher<T>() const {
|
||||
@ -1184,7 +1266,6 @@ public:
|
||||
/// ChildT must be an AST base type.
|
||||
template <typename T, typename ChildT>
|
||||
class HasMatcher : public WrapperMatcherInterface<T> {
|
||||
|
||||
public:
|
||||
explicit HasMatcher(const Matcher<ChildT> &ChildMatcher)
|
||||
: HasMatcher::WrapperMatcherInterface(ChildMatcher) {}
|
||||
@ -1278,7 +1359,7 @@ template<typename T>
|
||||
BindableMatcher<T> makeAllOfComposite(
|
||||
ArrayRef<const Matcher<T> *> InnerMatchers) {
|
||||
// For the size() == 0 case, we return a "true" matcher.
|
||||
if (InnerMatchers.size() == 0) {
|
||||
if (InnerMatchers.empty()) {
|
||||
return BindableMatcher<T>(TrueMatcher());
|
||||
}
|
||||
// For the size() == 1 case, we simply return that one matcher.
|
||||
@ -1287,7 +1368,8 @@ BindableMatcher<T> makeAllOfComposite(
|
||||
return BindableMatcher<T>(*InnerMatchers[0]);
|
||||
}
|
||||
|
||||
typedef llvm::pointee_iterator<const Matcher<T> *const *> PI;
|
||||
using PI = llvm::pointee_iterator<const Matcher<T> *const *>;
|
||||
|
||||
std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
|
||||
PI(InnerMatchers.end()));
|
||||
return BindableMatcher<T>(
|
||||
@ -1580,12 +1662,13 @@ template <typename InnerTBase,
|
||||
typename ReturnTypesF>
|
||||
class TypeTraversePolymorphicMatcher {
|
||||
private:
|
||||
typedef TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
|
||||
ReturnTypesF> Self;
|
||||
using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
|
||||
ReturnTypesF>;
|
||||
|
||||
static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers);
|
||||
|
||||
public:
|
||||
typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
|
||||
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
|
||||
|
||||
explicit TypeTraversePolymorphicMatcher(
|
||||
ArrayRef<const Matcher<InnerTBase> *> InnerMatchers)
|
||||
@ -1612,6 +1695,7 @@ private:
|
||||
template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher {
|
||||
struct Wrapper {
|
||||
Wrapper() : M(Func()) {}
|
||||
|
||||
Matcher M;
|
||||
};
|
||||
|
||||
@ -1657,6 +1741,7 @@ struct NotEqualsBoundNodePredicate {
|
||||
bool operator()(const internal::BoundNodesMap &Nodes) const {
|
||||
return Nodes.getNode(ID) != Node;
|
||||
}
|
||||
|
||||
std::string ID;
|
||||
ast_type_traits::DynTypedNode Node;
|
||||
};
|
||||
@ -1712,9 +1797,10 @@ CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) {
|
||||
return Node.getSubStmt();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace ast_matchers
|
||||
} // end namespace clang
|
||||
} // namespace ast_matchers
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
|
||||
|
@ -367,6 +367,27 @@
|
||||
// FIXME: add a matcher for TypeLoc derived classes using its custom casting
|
||||
// API (no longer dyn_cast) if/when we need such matching
|
||||
|
||||
#define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \
|
||||
ReturnTypesF) \
|
||||
namespace internal { \
|
||||
template <typename T> struct TypeMatcher##MatcherName##Getter { \
|
||||
static QualType (T::*value())() const { return &T::FunctionName; } \
|
||||
}; \
|
||||
} \
|
||||
extern const ::clang::ast_matchers::internal:: \
|
||||
TypeTraversePolymorphicMatcher< \
|
||||
QualType, \
|
||||
::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
|
||||
::clang::ast_matchers::internal::TypeTraverseMatcher, \
|
||||
ReturnTypesF>::Func MatcherName
|
||||
|
||||
#define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \
|
||||
const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
|
||||
QualType, \
|
||||
::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
|
||||
::clang::ast_matchers::internal::TypeTraverseMatcher, \
|
||||
ReturnTypesF>::Func MatcherName
|
||||
|
||||
/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
|
||||
/// the matcher \c MatcherName that can be used to traverse from one \c Type
|
||||
/// to another.
|
||||
@ -386,6 +407,30 @@
|
||||
::clang::ast_matchers::internal::TypeTraverseMatcher, \
|
||||
ReturnTypesF>::Func MatcherName
|
||||
|
||||
#define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \
|
||||
ReturnTypesF) \
|
||||
namespace internal { \
|
||||
template <typename T> struct TypeLocMatcher##MatcherName##Getter { \
|
||||
static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \
|
||||
}; \
|
||||
} \
|
||||
extern const ::clang::ast_matchers::internal:: \
|
||||
TypeTraversePolymorphicMatcher< \
|
||||
TypeLoc, \
|
||||
::clang::ast_matchers::internal:: \
|
||||
TypeLocMatcher##MatcherName##Getter, \
|
||||
::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
|
||||
ReturnTypesF>::Func MatcherName##Loc; \
|
||||
AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF)
|
||||
|
||||
#define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \
|
||||
const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
|
||||
TypeLoc, \
|
||||
::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \
|
||||
::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
|
||||
ReturnTypesF>::Func MatcherName##Loc; \
|
||||
AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)
|
||||
|
||||
/// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
|
||||
/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
|
||||
#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- Parser.h - Matcher expression parser -----*- C++ -*-===//
|
||||
//===- Parser.h - Matcher expression parser ---------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -6,7 +6,7 @@
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
//
|
||||
/// \file
|
||||
/// \brief Simple matcher expression parser.
|
||||
///
|
||||
@ -30,24 +30,28 @@
|
||||
/// <Identifier> := [a-zA-Z]+
|
||||
/// <ArgumentList> := <Expression> | <Expression>,<ArgumentList>
|
||||
/// \endcode
|
||||
///
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
|
||||
#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
|
||||
|
||||
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
|
||||
#include "clang/ASTMatchers/ASTMatchersInternal.h"
|
||||
#include "clang/ASTMatchers/Dynamic/Registry.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/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
namespace ast_matchers {
|
||||
namespace dynamic {
|
||||
|
||||
class Diagnostics;
|
||||
|
||||
/// \brief Matcher expression parser.
|
||||
class Parser {
|
||||
public:
|
||||
@ -124,8 +128,8 @@ public:
|
||||
/// \brief Sema implementation that uses the matcher registry to process the
|
||||
/// tokens.
|
||||
class RegistrySema : public Parser::Sema {
|
||||
public:
|
||||
~RegistrySema() override;
|
||||
public:
|
||||
~RegistrySema() override;
|
||||
|
||||
llvm::Optional<MatcherCtor>
|
||||
lookupMatcherCtor(StringRef MatcherName) override;
|
||||
@ -143,7 +147,7 @@ public:
|
||||
getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) override;
|
||||
};
|
||||
|
||||
typedef llvm::StringMap<VariantValue> NamedValueMap;
|
||||
using NamedValueMap = llvm::StringMap<VariantValue>;
|
||||
|
||||
/// \brief Parse a matcher expression.
|
||||
///
|
||||
@ -247,13 +251,14 @@ private:
|
||||
const NamedValueMap *const NamedValues;
|
||||
Diagnostics *const Error;
|
||||
|
||||
typedef std::vector<std::pair<MatcherCtor, unsigned> > ContextStackTy;
|
||||
using ContextStackTy = std::vector<std::pair<MatcherCtor, unsigned>>;
|
||||
|
||||
ContextStackTy ContextStack;
|
||||
std::vector<MatcherCompletion> Completions;
|
||||
};
|
||||
|
||||
} // namespace dynamic
|
||||
} // namespace ast_matchers
|
||||
} // namespace clang
|
||||
} // namespace dynamic
|
||||
} // namespace ast_matchers
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
|
||||
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- Registry.h - Matcher registry --------------------------*- C++ -*-===//
|
||||
//===- Registry.h - Matcher registry ----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -6,12 +6,12 @@
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
//
|
||||
/// \file
|
||||
/// \brief Registry of all known matchers.
|
||||
///
|
||||
/// The registry provides a generic interface to construct any matcher by name.
|
||||
///
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
|
||||
@ -34,9 +34,9 @@ namespace internal {
|
||||
|
||||
class MatcherDescriptor;
|
||||
|
||||
} // end namespace internal
|
||||
} // namespace internal
|
||||
|
||||
typedef const internal::MatcherDescriptor *MatcherCtor;
|
||||
using MatcherCtor = const internal::MatcherDescriptor *;
|
||||
|
||||
struct MatcherCompletion {
|
||||
MatcherCompletion() = default;
|
||||
@ -129,8 +129,8 @@ public:
|
||||
Diagnostics *Error);
|
||||
};
|
||||
|
||||
} // end namespace dynamic
|
||||
} // end namespace ast_matchers
|
||||
} // end namespace clang
|
||||
} // namespace dynamic
|
||||
} // namespace ast_matchers
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/StmtCXX.h"
|
||||
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/AnalysisDeclContext.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
|
||||
namespace clang {
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
|
||||
#define LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
|
||||
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/AnalysisDeclContext.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/Support/GenericDomTree.h"
|
||||
|
@ -15,7 +15,7 @@
|
||||
#define LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/AnalysisDeclContext.h"
|
||||
#include "llvm/ADT/ImmutableSet.h"
|
||||
|
||||
namespace clang {
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/AnalysisDeclContext.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
|
||||
namespace clang {
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
|
||||
#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
|
||||
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/AnalysisDeclContext.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
|
||||
#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
|
||||
#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/AnalysisDeclContext.h"
|
||||
#include "clang/Basic/OperatorKinds.h"
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
|
@ -92,6 +92,7 @@ enum TIL_BinaryOpcode : unsigned char {
|
||||
BOP_Neq, // !=
|
||||
BOP_Lt, // <
|
||||
BOP_Leq, // <=
|
||||
BOP_Cmp, // <=>
|
||||
BOP_LogicAnd, // && (no short-circuit)
|
||||
BOP_LogicOr // || (no short-circuit)
|
||||
};
|
||||
@ -909,15 +910,10 @@ class Project : public SExpr {
|
||||
public:
|
||||
static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
|
||||
|
||||
Project(SExpr *R, StringRef SName)
|
||||
: SExpr(COP_Project), Rec(R), SlotName(SName), Cvdecl(nullptr)
|
||||
{ }
|
||||
Project(SExpr *R, const clang::ValueDecl *Cvd)
|
||||
: SExpr(COP_Project), Rec(R), SlotName(Cvd->getName()), Cvdecl(Cvd)
|
||||
{ }
|
||||
Project(const Project &P, SExpr *R)
|
||||
: SExpr(P), Rec(R), SlotName(P.SlotName), Cvdecl(P.Cvdecl)
|
||||
{ }
|
||||
: SExpr(COP_Project), Rec(R), Cvdecl(Cvd) {
|
||||
assert(Cvd && "ValueDecl must not be null");
|
||||
}
|
||||
|
||||
SExpr *record() { return Rec; }
|
||||
const SExpr *record() const { return Rec; }
|
||||
@ -931,10 +927,14 @@ public:
|
||||
}
|
||||
|
||||
StringRef slotName() const {
|
||||
if (Cvdecl)
|
||||
if (Cvdecl->getDeclName().isIdentifier())
|
||||
return Cvdecl->getName();
|
||||
else
|
||||
return SlotName;
|
||||
if (!SlotName) {
|
||||
SlotName = "";
|
||||
llvm::raw_string_ostream OS(*SlotName);
|
||||
Cvdecl->printName(OS);
|
||||
}
|
||||
return *SlotName;
|
||||
}
|
||||
|
||||
template <class V>
|
||||
@ -953,7 +953,7 @@ public:
|
||||
|
||||
private:
|
||||
SExpr* Rec;
|
||||
StringRef SlotName;
|
||||
mutable llvm::Optional<std::string> SlotName;
|
||||
const clang::ValueDecl *Cvdecl;
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-//
|
||||
//=== AnalysisDeclContext.h - Analysis context for Path Sens analysis --*- C++ -*-//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -12,10 +12,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
|
||||
#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
|
||||
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
|
||||
#define LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/Analysis/BodyFarm.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
#include "clang/Analysis/CodeInjector.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
@ -416,23 +417,25 @@ class AnalysisDeclContextManager {
|
||||
/// Pointer to an interface that can provide function bodies for
|
||||
/// declarations from external source.
|
||||
std::unique_ptr<CodeInjector> Injector;
|
||||
|
||||
|
||||
/// A factory for creating and caching implementations for common
|
||||
/// methods during the analysis.
|
||||
BodyFarm FunctionBodyFarm;
|
||||
|
||||
/// Flag to indicate whether or not bodies should be synthesized
|
||||
/// for well-known functions.
|
||||
bool SynthesizeBodies;
|
||||
|
||||
public:
|
||||
AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
|
||||
AnalysisDeclContextManager(ASTContext &ASTCtx, bool useUnoptimizedCFG = false,
|
||||
bool addImplicitDtors = false,
|
||||
bool addInitializers = false,
|
||||
bool addTemporaryDtors = false,
|
||||
bool addLifetime = false,
|
||||
bool addLifetime = false, bool addLoopExit = false,
|
||||
bool synthesizeBodies = false,
|
||||
bool addStaticInitBranches = false,
|
||||
bool addCXXNewAllocator = true,
|
||||
CodeInjector* injector = nullptr);
|
||||
|
||||
~AnalysisDeclContextManager();
|
||||
CodeInjector *injector = nullptr);
|
||||
|
||||
AnalysisDeclContext *getContext(const Decl *D);
|
||||
|
||||
@ -471,6 +474,9 @@ public:
|
||||
return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
|
||||
}
|
||||
|
||||
/// Get a reference to {@code BodyFarm} instance.
|
||||
BodyFarm &getBodyFarm();
|
||||
|
||||
/// Discard all previously created AnalysisDeclContexts.
|
||||
void clear();
|
||||
|
@ -28,24 +28,27 @@ class ObjCMethodDecl;
|
||||
class ObjCPropertyDecl;
|
||||
class Stmt;
|
||||
class CodeInjector;
|
||||
|
||||
|
||||
class BodyFarm {
|
||||
public:
|
||||
BodyFarm(ASTContext &C, CodeInjector *injector) : C(C), Injector(injector) {}
|
||||
|
||||
|
||||
/// Factory method for creating bodies for ordinary functions.
|
||||
Stmt *getBody(const FunctionDecl *D);
|
||||
|
||||
/// Factory method for creating bodies for Objective-C properties.
|
||||
Stmt *getBody(const ObjCMethodDecl *D);
|
||||
|
||||
/// Remove copy constructor to avoid accidental copying.
|
||||
BodyFarm(const BodyFarm &other) = delete;
|
||||
|
||||
private:
|
||||
typedef llvm::DenseMap<const Decl *, Optional<Stmt *> > BodyMap;
|
||||
typedef llvm::DenseMap<const Decl *, Optional<Stmt *>> BodyMap;
|
||||
|
||||
ASTContext &C;
|
||||
BodyMap Bodies;
|
||||
CodeInjector *Injector;
|
||||
};
|
||||
}
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
//===--- CFG.h - Classes for representing and building CFGs------*- C++ -*-===//
|
||||
//===- CFG.h - Classes for representing and building CFGs -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -17,38 +17,38 @@
|
||||
|
||||
#include "clang/AST/Stmt.h"
|
||||
#include "clang/Analysis/Support/BumpVector.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/None.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"
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
class CXXDestructorDecl;
|
||||
class Decl;
|
||||
class Stmt;
|
||||
class Expr;
|
||||
class FieldDecl;
|
||||
class VarDecl;
|
||||
class CXXCtorInitializer;
|
||||
class CXXBaseSpecifier;
|
||||
class CXXBindTemporaryExpr;
|
||||
class CFG;
|
||||
class PrinterHelper;
|
||||
class LangOptions;
|
||||
class ASTContext;
|
||||
class CXXRecordDecl;
|
||||
class CXXDeleteExpr;
|
||||
class CXXNewExpr;
|
||||
class BinaryOperator;
|
||||
|
||||
class ASTContext;
|
||||
class BinaryOperator;
|
||||
class CFG;
|
||||
class CXXBaseSpecifier;
|
||||
class CXXBindTemporaryExpr;
|
||||
class CXXCtorInitializer;
|
||||
class CXXDeleteExpr;
|
||||
class CXXDestructorDecl;
|
||||
class CXXNewExpr;
|
||||
class CXXRecordDecl;
|
||||
class Decl;
|
||||
class FieldDecl;
|
||||
class LangOptions;
|
||||
class VarDecl;
|
||||
|
||||
/// CFGElement - Represents a top-level expression in a basic block.
|
||||
class CFGElement {
|
||||
@ -59,6 +59,7 @@ public:
|
||||
Initializer,
|
||||
NewAllocator,
|
||||
LifetimeEnds,
|
||||
LoopExit,
|
||||
// dtor kind
|
||||
AutomaticObjectDtor,
|
||||
DeleteDtor,
|
||||
@ -75,14 +76,14 @@ protected:
|
||||
llvm::PointerIntPair<void *, 2> Data2;
|
||||
|
||||
CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
|
||||
: Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
|
||||
Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
|
||||
: Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
|
||||
Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
|
||||
assert(getKind() == kind);
|
||||
}
|
||||
|
||||
CFGElement() {}
|
||||
public:
|
||||
CFGElement() = default;
|
||||
|
||||
public:
|
||||
/// \brief Convert to the specified CFGElement type, asserting that this
|
||||
/// CFGElement is of the desired type.
|
||||
template<typename T>
|
||||
@ -124,7 +125,9 @@ public:
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
CFGStmt() {}
|
||||
|
||||
CFGStmt() = default;
|
||||
|
||||
static bool isKind(const CFGElement &E) {
|
||||
return E.getKind() == Statement;
|
||||
}
|
||||
@ -143,7 +146,9 @@ public:
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
CFGInitializer() {}
|
||||
|
||||
CFGInitializer() = default;
|
||||
|
||||
static bool isKind(const CFGElement &E) {
|
||||
return E.getKind() == Initializer;
|
||||
}
|
||||
@ -162,12 +167,38 @@ public:
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
CFGNewAllocator() {}
|
||||
|
||||
CFGNewAllocator() = default;
|
||||
|
||||
static bool isKind(const CFGElement &elem) {
|
||||
return elem.getKind() == NewAllocator;
|
||||
}
|
||||
};
|
||||
|
||||
/// Represents the point where a loop ends.
|
||||
/// This element is is only produced when building the CFG for the static
|
||||
/// analyzer and hidden behind the 'cfg-loopexit' analyzer config flag.
|
||||
///
|
||||
/// Note: a loop exit element can be reached even when the loop body was never
|
||||
/// entered.
|
||||
class CFGLoopExit : public CFGElement {
|
||||
public:
|
||||
explicit CFGLoopExit(const Stmt *stmt) : CFGElement(LoopExit, stmt) {}
|
||||
|
||||
const Stmt *getLoopStmt() const {
|
||||
return static_cast<Stmt *>(Data1.getPointer());
|
||||
}
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
|
||||
CFGLoopExit() = default;
|
||||
|
||||
static bool isKind(const CFGElement &elem) {
|
||||
return elem.getKind() == LoopExit;
|
||||
}
|
||||
};
|
||||
|
||||
/// Represents the point where the lifetime of an automatic object ends
|
||||
class CFGLifetimeEnds : public CFGElement {
|
||||
public:
|
||||
@ -184,7 +215,9 @@ public:
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
CFGLifetimeEnds() {}
|
||||
|
||||
CFGLifetimeEnds() = default;
|
||||
|
||||
static bool isKind(const CFGElement &elem) {
|
||||
return elem.getKind() == LifetimeEnds;
|
||||
}
|
||||
@ -194,7 +227,8 @@ private:
|
||||
/// by compiler on various occasions.
|
||||
class CFGImplicitDtor : public CFGElement {
|
||||
protected:
|
||||
CFGImplicitDtor() {}
|
||||
CFGImplicitDtor() = default;
|
||||
|
||||
CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr)
|
||||
: CFGElement(kind, data1, data2) {
|
||||
assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
|
||||
@ -206,6 +240,7 @@ public:
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
|
||||
static bool isKind(const CFGElement &E) {
|
||||
Kind kind = E.getKind();
|
||||
return kind >= DTOR_BEGIN && kind <= DTOR_END;
|
||||
@ -231,7 +266,9 @@ public:
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
CFGAutomaticObjDtor() {}
|
||||
|
||||
CFGAutomaticObjDtor() = default;
|
||||
|
||||
static bool isKind(const CFGElement &elem) {
|
||||
return elem.getKind() == AutomaticObjectDtor;
|
||||
}
|
||||
@ -255,7 +292,9 @@ public:
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
CFGDeleteDtor() {}
|
||||
|
||||
CFGDeleteDtor() = default;
|
||||
|
||||
static bool isKind(const CFGElement &elem) {
|
||||
return elem.getKind() == DeleteDtor;
|
||||
}
|
||||
@ -274,7 +313,9 @@ public:
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
CFGBaseDtor() {}
|
||||
|
||||
CFGBaseDtor() = default;
|
||||
|
||||
static bool isKind(const CFGElement &E) {
|
||||
return E.getKind() == BaseDtor;
|
||||
}
|
||||
@ -293,7 +334,9 @@ public:
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
CFGMemberDtor() {}
|
||||
|
||||
CFGMemberDtor() = default;
|
||||
|
||||
static bool isKind(const CFGElement &E) {
|
||||
return E.getKind() == MemberDtor;
|
||||
}
|
||||
@ -312,7 +355,9 @@ public:
|
||||
|
||||
private:
|
||||
friend class CFGElement;
|
||||
CFGTemporaryDtor() {}
|
||||
|
||||
CFGTemporaryDtor() = default;
|
||||
|
||||
static bool isKind(const CFGElement &E) {
|
||||
return E.getKind() == TemporaryDtor;
|
||||
}
|
||||
@ -326,8 +371,9 @@ private:
|
||||
/// of matching full expression.
|
||||
class CFGTerminator {
|
||||
llvm::PointerIntPair<Stmt *, 1> Data;
|
||||
|
||||
public:
|
||||
CFGTerminator() {}
|
||||
CFGTerminator() = default;
|
||||
CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false)
|
||||
: Data(S, TemporaryDtorsBranch) {}
|
||||
|
||||
@ -373,21 +419,23 @@ public:
|
||||
/// &&, || expression that uses result of && or ||, RHS
|
||||
///
|
||||
/// But note that any of that may be NULL in case of optimized-out edges.
|
||||
///
|
||||
class CFGBlock {
|
||||
class ElementList {
|
||||
typedef BumpVector<CFGElement> ImplTy;
|
||||
using ImplTy = BumpVector<CFGElement>;
|
||||
|
||||
ImplTy Impl;
|
||||
|
||||
public:
|
||||
ElementList(BumpVectorContext &C) : Impl(C, 4) {}
|
||||
|
||||
typedef std::reverse_iterator<ImplTy::iterator> iterator;
|
||||
typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator;
|
||||
typedef ImplTy::iterator reverse_iterator;
|
||||
typedef ImplTy::const_iterator const_reverse_iterator;
|
||||
typedef ImplTy::const_reference const_reference;
|
||||
using iterator = std::reverse_iterator<ImplTy::iterator>;
|
||||
using const_iterator = std::reverse_iterator<ImplTy::const_iterator>;
|
||||
using reverse_iterator = ImplTy::iterator;
|
||||
using const_reverse_iterator = ImplTy::const_iterator;
|
||||
using const_reference = ImplTy::const_reference;
|
||||
|
||||
void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
|
||||
|
||||
reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E,
|
||||
BumpVectorContext &C) {
|
||||
return Impl.insert(I, Cnt, E, C);
|
||||
@ -405,10 +453,10 @@ class CFGBlock {
|
||||
const_reverse_iterator rbegin() const { return Impl.begin(); }
|
||||
const_reverse_iterator rend() const { return Impl.end(); }
|
||||
|
||||
CFGElement operator[](size_t i) const {
|
||||
assert(i < Impl.size());
|
||||
return Impl[Impl.size() - 1 - i];
|
||||
}
|
||||
CFGElement operator[](size_t i) const {
|
||||
assert(i < Impl.size());
|
||||
return Impl[Impl.size() - 1 - i];
|
||||
}
|
||||
|
||||
size_t size() const { return Impl.size(); }
|
||||
bool empty() const { return Impl.empty(); }
|
||||
@ -420,7 +468,7 @@ class CFGBlock {
|
||||
/// Label - An (optional) label that prefixes the executable
|
||||
/// statements in the block. When this variable is non-NULL, it is
|
||||
/// either an instance of LabelStmt, SwitchCase or CXXCatchStmt.
|
||||
Stmt *Label;
|
||||
Stmt *Label = nullptr;
|
||||
|
||||
/// Terminator - The terminator for a basic block that
|
||||
/// indicates the type of control-flow that occurs between a block
|
||||
@ -430,7 +478,7 @@ class CFGBlock {
|
||||
/// LoopTarget - Some blocks are used to represent the "loop edge" to
|
||||
/// the start of a loop from within the loop body. This Stmt* will be
|
||||
/// refer to the loop statement for such blocks (and be null otherwise).
|
||||
const Stmt *LoopTarget;
|
||||
const Stmt *LoopTarget = nullptr;
|
||||
|
||||
/// BlockID - A numerical ID assigned to a CFGBlock during construction
|
||||
/// of the CFG.
|
||||
@ -450,7 +498,7 @@ public:
|
||||
};
|
||||
|
||||
CFGBlock *ReachableBlock;
|
||||
llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock;
|
||||
llvm::PointerIntPair<CFGBlock *, 2> UnreachableBlock;
|
||||
|
||||
public:
|
||||
/// Construct an AdjacentBlock with a possibly unreachable block.
|
||||
@ -493,7 +541,7 @@ public:
|
||||
private:
|
||||
/// Predecessors/Successors - Keep track of the predecessor / successor
|
||||
/// CFG blocks.
|
||||
typedef BumpVector<AdjacentBlock> AdjacentBlocks;
|
||||
using AdjacentBlocks = BumpVector<AdjacentBlock>;
|
||||
AdjacentBlocks Preds;
|
||||
AdjacentBlocks Succs;
|
||||
|
||||
@ -513,15 +561,14 @@ private:
|
||||
|
||||
public:
|
||||
explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
|
||||
: Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr),
|
||||
BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false),
|
||||
Parent(parent) {}
|
||||
: Elements(C), Terminator(nullptr), BlockID(blockid), Preds(C, 1),
|
||||
Succs(C, 1), HasNoReturnElement(false), Parent(parent) {}
|
||||
|
||||
// Statement iterators
|
||||
typedef ElementList::iterator iterator;
|
||||
typedef ElementList::const_iterator const_iterator;
|
||||
typedef ElementList::reverse_iterator reverse_iterator;
|
||||
typedef ElementList::const_reverse_iterator const_reverse_iterator;
|
||||
using iterator = ElementList::iterator;
|
||||
using const_iterator = ElementList::const_iterator;
|
||||
using reverse_iterator = ElementList::reverse_iterator;
|
||||
using const_reverse_iterator = ElementList::const_reverse_iterator;
|
||||
|
||||
CFGElement front() const { return Elements.front(); }
|
||||
CFGElement back() const { return Elements.back(); }
|
||||
@ -542,19 +589,19 @@ public:
|
||||
CFGElement operator[](size_t i) const { return Elements[i]; }
|
||||
|
||||
// CFG iterators
|
||||
typedef AdjacentBlocks::iterator pred_iterator;
|
||||
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;
|
||||
using pred_iterator = AdjacentBlocks::iterator;
|
||||
using const_pred_iterator = AdjacentBlocks::const_iterator;
|
||||
using pred_reverse_iterator = AdjacentBlocks::reverse_iterator;
|
||||
using const_pred_reverse_iterator = AdjacentBlocks::const_reverse_iterator;
|
||||
using pred_range = llvm::iterator_range<pred_iterator>;
|
||||
using pred_const_range = llvm::iterator_range<const_pred_iterator>;
|
||||
|
||||
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;
|
||||
using succ_iterator = AdjacentBlocks::iterator;
|
||||
using const_succ_iterator = AdjacentBlocks::const_iterator;
|
||||
using succ_reverse_iterator = AdjacentBlocks::reverse_iterator;
|
||||
using const_succ_reverse_iterator = AdjacentBlocks::const_reverse_iterator;
|
||||
using succ_range = llvm::iterator_range<succ_iterator>;
|
||||
using succ_const_range = llvm::iterator_range<const_succ_iterator>;
|
||||
|
||||
pred_iterator pred_begin() { return Preds.begin(); }
|
||||
pred_iterator pred_end() { return Preds.end(); }
|
||||
@ -566,10 +613,11 @@ public:
|
||||
const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); }
|
||||
const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
|
||||
|
||||
pred_range preds() {
|
||||
pred_range preds() {
|
||||
return pred_range(pred_begin(), pred_end());
|
||||
}
|
||||
pred_const_range preds() const {
|
||||
|
||||
pred_const_range preds() const {
|
||||
return pred_const_range(pred_begin(), pred_end());
|
||||
}
|
||||
|
||||
@ -583,10 +631,11 @@ public:
|
||||
const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); }
|
||||
const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
|
||||
|
||||
succ_range succs() {
|
||||
succ_range succs() {
|
||||
return succ_range(succ_begin(), succ_end());
|
||||
}
|
||||
succ_const_range succs() const {
|
||||
|
||||
succ_const_range succs() const {
|
||||
return succ_const_range(succ_begin(), succ_end());
|
||||
}
|
||||
|
||||
@ -599,13 +648,11 @@ public:
|
||||
|
||||
class FilterOptions {
|
||||
public:
|
||||
FilterOptions() {
|
||||
IgnoreNullPredecessors = 1;
|
||||
IgnoreDefaultsWithCoveredEnums = 0;
|
||||
}
|
||||
|
||||
unsigned IgnoreNullPredecessors : 1;
|
||||
unsigned IgnoreDefaultsWithCoveredEnums : 1;
|
||||
|
||||
FilterOptions()
|
||||
: IgnoreNullPredecessors(1), IgnoreDefaultsWithCoveredEnums(0) {}
|
||||
};
|
||||
|
||||
static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src,
|
||||
@ -617,6 +664,7 @@ public:
|
||||
IMPL I, E;
|
||||
const FilterOptions F;
|
||||
const CFGBlock *From;
|
||||
|
||||
public:
|
||||
explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
|
||||
const CFGBlock *from,
|
||||
@ -634,17 +682,18 @@ public:
|
||||
}
|
||||
|
||||
const CFGBlock *operator*() const { return *I; }
|
||||
|
||||
private:
|
||||
bool Filter(const CFGBlock *To) {
|
||||
return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
|
||||
}
|
||||
};
|
||||
|
||||
typedef FilteredCFGBlockIterator<const_pred_iterator, true>
|
||||
filtered_pred_iterator;
|
||||
using filtered_pred_iterator =
|
||||
FilteredCFGBlockIterator<const_pred_iterator, true>;
|
||||
|
||||
typedef FilteredCFGBlockIterator<const_succ_iterator, false>
|
||||
filtered_succ_iterator;
|
||||
using filtered_succ_iterator =
|
||||
FilteredCFGBlockIterator<const_succ_iterator, false>;
|
||||
|
||||
filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const {
|
||||
return filtered_pred_iterator(pred_begin(), pred_end(), this, f);
|
||||
@ -728,6 +777,10 @@ public:
|
||||
Elements.push_back(CFGLifetimeEnds(VD, S), C);
|
||||
}
|
||||
|
||||
void appendLoopExit(const Stmt *LoopStmt, BumpVectorContext &C) {
|
||||
Elements.push_back(CFGLoopExit(LoopStmt), C);
|
||||
}
|
||||
|
||||
void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) {
|
||||
Elements.push_back(CFGDeleteDtor(RD, DE), C);
|
||||
}
|
||||
@ -763,11 +816,12 @@ public:
|
||||
/// operator error is found when building the CFG.
|
||||
class CFGCallback {
|
||||
public:
|
||||
CFGCallback() {}
|
||||
CFGCallback() = default;
|
||||
virtual ~CFGCallback() = default;
|
||||
|
||||
virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
|
||||
virtual void compareBitwiseEquality(const BinaryOperator *B,
|
||||
bool isAlwaysTrue) {}
|
||||
virtual ~CFGCallback() {}
|
||||
};
|
||||
|
||||
/// CFG - Represents a source-level, intra-procedural CFG that represents the
|
||||
@ -785,19 +839,24 @@ public:
|
||||
|
||||
class BuildOptions {
|
||||
std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
|
||||
|
||||
public:
|
||||
typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
|
||||
ForcedBlkExprs **forcedBlkExprs;
|
||||
CFGCallback *Observer;
|
||||
bool PruneTriviallyFalseEdges;
|
||||
bool AddEHEdges;
|
||||
bool AddInitializers;
|
||||
bool AddImplicitDtors;
|
||||
bool AddLifetime;
|
||||
bool AddTemporaryDtors;
|
||||
bool AddStaticInitBranches;
|
||||
bool AddCXXNewAllocator;
|
||||
bool AddCXXDefaultInitExprInCtors;
|
||||
using ForcedBlkExprs = llvm::DenseMap<const Stmt *, const CFGBlock *>;
|
||||
|
||||
ForcedBlkExprs **forcedBlkExprs = nullptr;
|
||||
CFGCallback *Observer = nullptr;
|
||||
bool PruneTriviallyFalseEdges = true;
|
||||
bool AddEHEdges = false;
|
||||
bool AddInitializers = false;
|
||||
bool AddImplicitDtors = false;
|
||||
bool AddLifetime = false;
|
||||
bool AddLoopExit = false;
|
||||
bool AddTemporaryDtors = false;
|
||||
bool AddStaticInitBranches = false;
|
||||
bool AddCXXNewAllocator = false;
|
||||
bool AddCXXDefaultInitExprInCtors = false;
|
||||
|
||||
BuildOptions() = default;
|
||||
|
||||
bool alwaysAdd(const Stmt *stmt) const {
|
||||
return alwaysAddMask[stmt->getStmtClass()];
|
||||
@ -812,15 +871,6 @@ public:
|
||||
alwaysAddMask.set();
|
||||
return *this;
|
||||
}
|
||||
|
||||
BuildOptions()
|
||||
: forcedBlkExprs(nullptr), Observer(nullptr),
|
||||
PruneTriviallyFalseEdges(true),
|
||||
AddEHEdges(false),
|
||||
AddInitializers(false), AddImplicitDtors(false),
|
||||
AddLifetime(false),
|
||||
AddTemporaryDtors(false), AddStaticInitBranches(false),
|
||||
AddCXXNewAllocator(false), AddCXXDefaultInitExprInCtors(false) {}
|
||||
};
|
||||
|
||||
/// buildCFG - Builds a CFG from an AST.
|
||||
@ -844,11 +894,11 @@ public:
|
||||
// Block Iterators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
typedef BumpVector<CFGBlock*> CFGBlockListTy;
|
||||
typedef CFGBlockListTy::iterator iterator;
|
||||
typedef CFGBlockListTy::const_iterator const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
using CFGBlockListTy = BumpVector<CFGBlock *>;
|
||||
using iterator = CFGBlockListTy::iterator;
|
||||
using const_iterator = CFGBlockListTy::const_iterator;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
CFGBlock & front() { return *Blocks.front(); }
|
||||
CFGBlock & back() { return *Blocks.back(); }
|
||||
@ -876,10 +926,12 @@ public:
|
||||
CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; }
|
||||
const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; }
|
||||
|
||||
typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator;
|
||||
using try_block_iterator = std::vector<const CFGBlock *>::const_iterator;
|
||||
|
||||
try_block_iterator try_blocks_begin() const {
|
||||
return TryDispatchBlocks.begin();
|
||||
}
|
||||
|
||||
try_block_iterator try_blocks_end() const {
|
||||
return TryDispatchBlocks.end();
|
||||
}
|
||||
@ -900,9 +952,9 @@ public:
|
||||
SyntheticDeclStmts[Synthetic] = Source;
|
||||
}
|
||||
|
||||
typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator
|
||||
synthetic_stmt_iterator;
|
||||
typedef llvm::iterator_range<synthetic_stmt_iterator> synthetic_stmt_range;
|
||||
using synthetic_stmt_iterator =
|
||||
llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator;
|
||||
using synthetic_stmt_range = llvm::iterator_range<synthetic_stmt_iterator>;
|
||||
|
||||
/// Iterates over synthetic DeclStmts in the CFG.
|
||||
///
|
||||
@ -962,9 +1014,7 @@ public:
|
||||
// Internal: constructors and data.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
CFG()
|
||||
: Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0),
|
||||
Blocks(BlkBVC, 10) {}
|
||||
CFG() : Blocks(BlkBVC, 10) {}
|
||||
|
||||
llvm::BumpPtrAllocator& getAllocator() {
|
||||
return BlkBVC.getAllocator();
|
||||
@ -975,11 +1025,13 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
CFGBlock *Entry;
|
||||
CFGBlock *Exit;
|
||||
CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch
|
||||
// for indirect gotos
|
||||
unsigned NumBlockIDs;
|
||||
CFGBlock *Entry = nullptr;
|
||||
CFGBlock *Exit = nullptr;
|
||||
|
||||
// Special block to contain collective dispatch for indirect gotos
|
||||
CFGBlock* IndirectGotoBlock = nullptr;
|
||||
|
||||
unsigned NumBlockIDs = 0;
|
||||
|
||||
BumpVectorContext BlkBVC;
|
||||
|
||||
@ -993,7 +1045,8 @@ private:
|
||||
/// source DeclStmt.
|
||||
llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
|
||||
};
|
||||
} // end namespace clang
|
||||
|
||||
} // namespace clang
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
|
||||
@ -1004,7 +1057,8 @@ namespace llvm {
|
||||
/// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
|
||||
/// CFGTerminator to a specific Stmt class.
|
||||
template <> struct simplify_type< ::clang::CFGTerminator> {
|
||||
typedef ::clang::Stmt *SimpleType;
|
||||
using SimpleType = ::clang::Stmt *;
|
||||
|
||||
static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) {
|
||||
return Val.getStmt();
|
||||
}
|
||||
@ -1013,50 +1067,44 @@ template <> struct simplify_type< ::clang::CFGTerminator> {
|
||||
// Traits for: CFGBlock
|
||||
|
||||
template <> struct GraphTraits< ::clang::CFGBlock *> {
|
||||
typedef ::clang::CFGBlock *NodeRef;
|
||||
typedef ::clang::CFGBlock::succ_iterator ChildIteratorType;
|
||||
using NodeRef = ::clang::CFGBlock *;
|
||||
using ChildIteratorType = ::clang::CFGBlock::succ_iterator;
|
||||
|
||||
static NodeRef getEntryNode(::clang::CFGBlock *BB) { return BB; }
|
||||
|
||||
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
|
||||
|
||||
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
|
||||
};
|
||||
|
||||
template <> struct GraphTraits< const ::clang::CFGBlock *> {
|
||||
typedef const ::clang::CFGBlock *NodeRef;
|
||||
typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType;
|
||||
using NodeRef = const ::clang::CFGBlock *;
|
||||
using ChildIteratorType = ::clang::CFGBlock::const_succ_iterator;
|
||||
|
||||
static NodeRef getEntryNode(const clang::CFGBlock *BB) { return BB; }
|
||||
|
||||
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
|
||||
|
||||
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > {
|
||||
typedef ::clang::CFGBlock *NodeRef;
|
||||
typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
|
||||
template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> {
|
||||
using NodeRef = ::clang::CFGBlock *;
|
||||
using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator;
|
||||
|
||||
static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G) {
|
||||
return G.Graph;
|
||||
}
|
||||
|
||||
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
|
||||
|
||||
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
|
||||
typedef const ::clang::CFGBlock *NodeRef;
|
||||
typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
|
||||
template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> {
|
||||
using NodeRef = const ::clang::CFGBlock *;
|
||||
using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator;
|
||||
|
||||
static NodeRef getEntryNode(Inverse<const ::clang::CFGBlock *> G) {
|
||||
return G.Graph;
|
||||
}
|
||||
|
||||
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
|
||||
|
||||
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
|
||||
};
|
||||
|
||||
@ -1064,8 +1112,7 @@ template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
|
||||
|
||||
template <> struct GraphTraits< ::clang::CFG* >
|
||||
: public GraphTraits< ::clang::CFGBlock *> {
|
||||
|
||||
typedef ::clang::CFG::iterator nodes_iterator;
|
||||
using nodes_iterator = ::clang::CFG::iterator;
|
||||
|
||||
static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); }
|
||||
static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
|
||||
@ -1075,44 +1122,47 @@ template <> struct GraphTraits< ::clang::CFG* >
|
||||
|
||||
template <> struct GraphTraits<const ::clang::CFG* >
|
||||
: public GraphTraits<const ::clang::CFGBlock *> {
|
||||
|
||||
typedef ::clang::CFG::const_iterator nodes_iterator;
|
||||
using nodes_iterator = ::clang::CFG::const_iterator;
|
||||
|
||||
static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); }
|
||||
|
||||
static nodes_iterator nodes_begin( const ::clang::CFG* F) {
|
||||
return F->nodes_begin();
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_end( const ::clang::CFG* F) {
|
||||
return F->nodes_end();
|
||||
}
|
||||
|
||||
static unsigned size(const ::clang::CFG* F) {
|
||||
return F->size();
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse< ::clang::CFG*> >
|
||||
: public GraphTraits<Inverse< ::clang::CFGBlock*> > {
|
||||
|
||||
typedef ::clang::CFG::iterator nodes_iterator;
|
||||
template <> struct GraphTraits<Inverse< ::clang::CFG *>>
|
||||
: public GraphTraits<Inverse< ::clang::CFGBlock *>> {
|
||||
using nodes_iterator = ::clang::CFG::iterator;
|
||||
|
||||
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(); }
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
|
||||
: public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
|
||||
|
||||
typedef ::clang::CFG::const_iterator nodes_iterator;
|
||||
template <> struct GraphTraits<Inverse<const ::clang::CFG *>>
|
||||
: public GraphTraits<Inverse<const ::clang::CFGBlock *>> {
|
||||
using nodes_iterator = ::clang::CFG::const_iterator;
|
||||
|
||||
static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); }
|
||||
|
||||
static nodes_iterator nodes_begin(const ::clang::CFG* F) {
|
||||
return F->nodes_begin();
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_end(const ::clang::CFG* F) {
|
||||
return F->nodes_end();
|
||||
}
|
||||
};
|
||||
} // end llvm namespace
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_CLANG_ANALYSIS_CFG_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//== CallGraph.h - AST-based Call graph ------------------------*- C++ -*--==//
|
||||
//===- CallGraph.h - AST-based Call graph -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -12,19 +12,27 @@
|
||||
// A call graph for functions whose definitions/bodies are available in the
|
||||
// current translation unit. The graph has a "virtual" root node that contains
|
||||
// edges to all externally available functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH_H
|
||||
#define LLVM_CLANG_ANALYSIS_CALLGRAPH_H
|
||||
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <memory>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CallGraphNode;
|
||||
class Decl;
|
||||
class DeclContext;
|
||||
class Stmt;
|
||||
|
||||
/// \brief The AST-based call graph.
|
||||
///
|
||||
@ -34,8 +42,8 @@ class CallGraphNode;
|
||||
class CallGraph : public RecursiveASTVisitor<CallGraph> {
|
||||
friend class CallGraphNode;
|
||||
|
||||
typedef llvm::DenseMap<const Decl *, std::unique_ptr<CallGraphNode>>
|
||||
FunctionMapTy;
|
||||
using FunctionMapTy =
|
||||
llvm::DenseMap<const Decl *, std::unique_ptr<CallGraphNode>>;
|
||||
|
||||
/// FunctionMap owns all CallGraphNodes.
|
||||
FunctionMapTy FunctionMap;
|
||||
@ -65,10 +73,11 @@ public:
|
||||
/// one into the graph.
|
||||
CallGraphNode *getOrInsertNode(Decl *);
|
||||
|
||||
using iterator = FunctionMapTy::iterator;
|
||||
using const_iterator = FunctionMapTy::const_iterator;
|
||||
|
||||
/// Iterators through all the elements in the graph. Note, this gives
|
||||
/// non-deterministic order.
|
||||
typedef FunctionMapTy::iterator iterator;
|
||||
typedef FunctionMapTy::const_iterator const_iterator;
|
||||
iterator begin() { return FunctionMap.begin(); }
|
||||
iterator end() { return FunctionMap.end(); }
|
||||
const_iterator begin() const { return FunctionMap.begin(); }
|
||||
@ -84,8 +93,8 @@ public:
|
||||
/// Iterators through all the nodes of the graph that have no parent. These
|
||||
/// are the unreachable nodes, which are either unused or are due to us
|
||||
/// failing to add a call edge due to the analysis imprecision.
|
||||
typedef llvm::SetVector<CallGraphNode *>::iterator nodes_iterator;
|
||||
typedef llvm::SetVector<CallGraphNode *>::const_iterator const_nodes_iterator;
|
||||
using nodes_iterator = llvm::SetVector<CallGraphNode *>::iterator;
|
||||
using const_nodes_iterator = llvm::SetVector<CallGraphNode *>::const_iterator;
|
||||
|
||||
void print(raw_ostream &os) const;
|
||||
void dump() const;
|
||||
@ -133,7 +142,7 @@ private:
|
||||
|
||||
class CallGraphNode {
|
||||
public:
|
||||
typedef CallGraphNode* CallRecord;
|
||||
using CallRecord = CallGraphNode *;
|
||||
|
||||
private:
|
||||
/// \brief The function/method declaration.
|
||||
@ -145,17 +154,17 @@ private:
|
||||
public:
|
||||
CallGraphNode(Decl *D) : FD(D) {}
|
||||
|
||||
typedef SmallVectorImpl<CallRecord>::iterator iterator;
|
||||
typedef SmallVectorImpl<CallRecord>::const_iterator const_iterator;
|
||||
using iterator = SmallVectorImpl<CallRecord>::iterator;
|
||||
using const_iterator = SmallVectorImpl<CallRecord>::const_iterator;
|
||||
|
||||
/// Iterators through all the callees/children of the node.
|
||||
inline iterator begin() { return CalledFunctions.begin(); }
|
||||
inline iterator end() { return CalledFunctions.end(); }
|
||||
inline const_iterator begin() const { return CalledFunctions.begin(); }
|
||||
inline const_iterator end() const { return CalledFunctions.end(); }
|
||||
iterator begin() { return CalledFunctions.begin(); }
|
||||
iterator end() { return CalledFunctions.end(); }
|
||||
const_iterator begin() const { return CalledFunctions.begin(); }
|
||||
const_iterator end() const { return CalledFunctions.end(); }
|
||||
|
||||
inline bool empty() const {return CalledFunctions.empty(); }
|
||||
inline unsigned size() const {return CalledFunctions.size(); }
|
||||
bool empty() const { return CalledFunctions.empty(); }
|
||||
unsigned size() const { return CalledFunctions.size(); }
|
||||
|
||||
void addCallee(CallGraphNode *N) {
|
||||
CalledFunctions.push_back(N);
|
||||
@ -167,35 +176,33 @@ public:
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
} // end clang namespace
|
||||
} // namespace clang
|
||||
|
||||
// Graph traits for iteration, viewing.
|
||||
namespace llvm {
|
||||
|
||||
template <> struct GraphTraits<clang::CallGraphNode*> {
|
||||
typedef clang::CallGraphNode NodeType;
|
||||
typedef clang::CallGraphNode *NodeRef;
|
||||
typedef NodeType::iterator ChildIteratorType;
|
||||
using NodeType = clang::CallGraphNode;
|
||||
using NodeRef = clang::CallGraphNode *;
|
||||
using ChildIteratorType = NodeType::iterator;
|
||||
|
||||
static NodeType *getEntryNode(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(); }
|
||||
static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
|
||||
static 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;
|
||||
using NodeType = const clang::CallGraphNode;
|
||||
using NodeRef = const clang::CallGraphNode *;
|
||||
using ChildIteratorType = NodeType::const_iterator;
|
||||
|
||||
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(); }
|
||||
static ChildIteratorType child_begin(NodeType *N) { return N->begin();}
|
||||
static ChildIteratorType child_end(NodeType *N) { return N->end(); }
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<clang::CallGraph*>
|
||||
: public GraphTraits<clang::CallGraphNode*> {
|
||||
|
||||
static NodeType *getEntryNode(clang::CallGraph *CGN) {
|
||||
return CGN->getRoot(); // Start at the external node!
|
||||
}
|
||||
@ -206,19 +213,18 @@ template <> struct GraphTraits<clang::CallGraph*>
|
||||
}
|
||||
|
||||
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
|
||||
typedef mapped_iterator<clang::CallGraph::iterator, decltype(&CGGetValue)>
|
||||
nodes_iterator;
|
||||
using nodes_iterator =
|
||||
mapped_iterator<clang::CallGraph::iterator, decltype(&CGGetValue)>;
|
||||
|
||||
static nodes_iterator nodes_begin(clang::CallGraph *CG) {
|
||||
return nodes_iterator(CG->begin(), &CGGetValue);
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_end (clang::CallGraph *CG) {
|
||||
return nodes_iterator(CG->end(), &CGGetValue);
|
||||
}
|
||||
|
||||
static unsigned size(clang::CallGraph *CG) {
|
||||
return CG->size();
|
||||
}
|
||||
static unsigned size(clang::CallGraph *CG) { return CG->size(); }
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<const clang::CallGraph*> :
|
||||
@ -233,21 +239,20 @@ template <> struct GraphTraits<const clang::CallGraph*> :
|
||||
}
|
||||
|
||||
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
|
||||
typedef mapped_iterator<clang::CallGraph::const_iterator,
|
||||
decltype(&CGGetValue)>
|
||||
nodes_iterator;
|
||||
using nodes_iterator =
|
||||
mapped_iterator<clang::CallGraph::const_iterator, decltype(&CGGetValue)>;
|
||||
|
||||
static nodes_iterator nodes_begin(const clang::CallGraph *CG) {
|
||||
return nodes_iterator(CG->begin(), &CGGetValue);
|
||||
}
|
||||
|
||||
static nodes_iterator nodes_end(const clang::CallGraph *CG) {
|
||||
return nodes_iterator(CG->end(), &CGGetValue);
|
||||
}
|
||||
static unsigned size(const clang::CallGraph *CG) {
|
||||
return CG->size();
|
||||
}
|
||||
|
||||
static unsigned size(const clang::CallGraph *CG) { return CG->size(); }
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_ANALYSIS_CALLGRAPH_H
|
||||
|
@ -7,19 +7,15 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// /file
|
||||
/// This file defines classes for searching and anlyzing source code clones.
|
||||
/// \file
|
||||
/// This file defines classes for searching and analyzing source code clones.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_CLONEDETECTION_H
|
||||
#define LLVM_CLANG_AST_CLONEDETECTION_H
|
||||
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Regex.h"
|
||||
#include <vector>
|
||||
|
||||
@ -31,192 +27,6 @@ class VarDecl;
|
||||
class ASTContext;
|
||||
class CompoundStmt;
|
||||
|
||||
namespace clone_detection {
|
||||
|
||||
/// Returns a string that represents all macro expansions that expanded into the
|
||||
/// given SourceLocation.
|
||||
///
|
||||
/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
|
||||
/// A and B are expanded from the same macros in the same order.
|
||||
std::string getMacroStack(SourceLocation Loc, ASTContext &Context);
|
||||
|
||||
/// Collects the data of a single Stmt.
|
||||
///
|
||||
/// This class defines what a code clone is: If it collects for two statements
|
||||
/// the same data, then those two statements are considered to be clones of each
|
||||
/// other.
|
||||
///
|
||||
/// All collected data is forwarded to the given data consumer of the type T.
|
||||
/// The data consumer class needs to provide a member method with the signature:
|
||||
/// update(StringRef Str)
|
||||
template <typename T>
|
||||
class StmtDataCollector : public ConstStmtVisitor<StmtDataCollector<T>> {
|
||||
|
||||
ASTContext &Context;
|
||||
/// The data sink to which all data is forwarded.
|
||||
T &DataConsumer;
|
||||
|
||||
public:
|
||||
/// Collects data of the given Stmt.
|
||||
/// \param S The given statement.
|
||||
/// \param Context The ASTContext of S.
|
||||
/// \param DataConsumer The data sink to which all data is forwarded.
|
||||
StmtDataCollector(const Stmt *S, ASTContext &Context, T &DataConsumer)
|
||||
: Context(Context), DataConsumer(DataConsumer) {
|
||||
this->Visit(S);
|
||||
}
|
||||
|
||||
typedef unsigned DataPiece;
|
||||
|
||||
// Below are utility methods for appending different data to the vector.
|
||||
|
||||
void addData(DataPiece Integer) {
|
||||
DataConsumer.update(
|
||||
StringRef(reinterpret_cast<char *>(&Integer), sizeof(Integer)));
|
||||
}
|
||||
|
||||
void addData(llvm::StringRef Str) { DataConsumer.update(Str); }
|
||||
|
||||
void addData(const QualType &QT) { addData(QT.getAsString()); }
|
||||
|
||||
// The functions below collect the class specific data of each Stmt subclass.
|
||||
|
||||
// Utility macro for defining a visit method for a given class. This method
|
||||
// calls back to the ConstStmtVisitor to visit all parent classes.
|
||||
#define DEF_ADD_DATA(CLASS, CODE) \
|
||||
void Visit##CLASS(const CLASS *S) { \
|
||||
CODE; \
|
||||
ConstStmtVisitor<StmtDataCollector>::Visit##CLASS(S); \
|
||||
}
|
||||
|
||||
DEF_ADD_DATA(Stmt, {
|
||||
addData(S->getStmtClass());
|
||||
// This ensures that macro generated code isn't identical to macro-generated
|
||||
// code.
|
||||
addData(getMacroStack(S->getLocStart(), Context));
|
||||
addData(getMacroStack(S->getLocEnd(), Context));
|
||||
})
|
||||
DEF_ADD_DATA(Expr, { addData(S->getType()); })
|
||||
|
||||
//--- Builtin functionality ----------------------------------------------//
|
||||
DEF_ADD_DATA(ArrayTypeTraitExpr, { addData(S->getTrait()); })
|
||||
DEF_ADD_DATA(ExpressionTraitExpr, { addData(S->getTrait()); })
|
||||
DEF_ADD_DATA(PredefinedExpr, { addData(S->getIdentType()); })
|
||||
DEF_ADD_DATA(TypeTraitExpr, {
|
||||
addData(S->getTrait());
|
||||
for (unsigned i = 0; i < S->getNumArgs(); ++i)
|
||||
addData(S->getArg(i)->getType());
|
||||
})
|
||||
|
||||
//--- Calls --------------------------------------------------------------//
|
||||
DEF_ADD_DATA(CallExpr, {
|
||||
// Function pointers don't have a callee and we just skip hashing it.
|
||||
if (const FunctionDecl *D = S->getDirectCallee()) {
|
||||
// If the function is a template specialization, we also need to handle
|
||||
// the template arguments as they are not included in the qualified name.
|
||||
if (auto Args = D->getTemplateSpecializationArgs()) {
|
||||
std::string ArgString;
|
||||
|
||||
// Print all template arguments into ArgString
|
||||
llvm::raw_string_ostream OS(ArgString);
|
||||
for (unsigned i = 0; i < Args->size(); ++i) {
|
||||
Args->get(i).print(Context.getLangOpts(), OS);
|
||||
// Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
|
||||
OS << '\n';
|
||||
}
|
||||
OS.flush();
|
||||
|
||||
addData(ArgString);
|
||||
}
|
||||
addData(D->getQualifiedNameAsString());
|
||||
}
|
||||
})
|
||||
|
||||
//--- Exceptions ---------------------------------------------------------//
|
||||
DEF_ADD_DATA(CXXCatchStmt, { addData(S->getCaughtType()); })
|
||||
|
||||
//--- C++ OOP Stmts ------------------------------------------------------//
|
||||
DEF_ADD_DATA(CXXDeleteExpr, {
|
||||
addData(S->isArrayFormAsWritten());
|
||||
addData(S->isGlobalDelete());
|
||||
})
|
||||
|
||||
//--- Casts --------------------------------------------------------------//
|
||||
DEF_ADD_DATA(ObjCBridgedCastExpr, { addData(S->getBridgeKind()); })
|
||||
|
||||
//--- Miscellaneous Exprs ------------------------------------------------//
|
||||
DEF_ADD_DATA(BinaryOperator, { addData(S->getOpcode()); })
|
||||
DEF_ADD_DATA(UnaryOperator, { addData(S->getOpcode()); })
|
||||
|
||||
//--- Control flow -------------------------------------------------------//
|
||||
DEF_ADD_DATA(GotoStmt, { addData(S->getLabel()->getName()); })
|
||||
DEF_ADD_DATA(IndirectGotoStmt, {
|
||||
if (S->getConstantTarget())
|
||||
addData(S->getConstantTarget()->getName());
|
||||
})
|
||||
DEF_ADD_DATA(LabelStmt, { addData(S->getDecl()->getName()); })
|
||||
DEF_ADD_DATA(MSDependentExistsStmt, { addData(S->isIfExists()); })
|
||||
DEF_ADD_DATA(AddrLabelExpr, { addData(S->getLabel()->getName()); })
|
||||
|
||||
//--- Objective-C --------------------------------------------------------//
|
||||
DEF_ADD_DATA(ObjCIndirectCopyRestoreExpr, { addData(S->shouldCopy()); })
|
||||
DEF_ADD_DATA(ObjCPropertyRefExpr, {
|
||||
addData(S->isSuperReceiver());
|
||||
addData(S->isImplicitProperty());
|
||||
})
|
||||
DEF_ADD_DATA(ObjCAtCatchStmt, { addData(S->hasEllipsis()); })
|
||||
|
||||
//--- Miscellaneous Stmts ------------------------------------------------//
|
||||
DEF_ADD_DATA(CXXFoldExpr, {
|
||||
addData(S->isRightFold());
|
||||
addData(S->getOperator());
|
||||
})
|
||||
DEF_ADD_DATA(GenericSelectionExpr, {
|
||||
for (unsigned i = 0; i < S->getNumAssocs(); ++i) {
|
||||
addData(S->getAssocType(i));
|
||||
}
|
||||
})
|
||||
DEF_ADD_DATA(LambdaExpr, {
|
||||
for (const LambdaCapture &C : S->captures()) {
|
||||
addData(C.isPackExpansion());
|
||||
addData(C.getCaptureKind());
|
||||
if (C.capturesVariable())
|
||||
addData(C.getCapturedVar()->getType());
|
||||
}
|
||||
addData(S->isGenericLambda());
|
||||
addData(S->isMutable());
|
||||
})
|
||||
DEF_ADD_DATA(DeclStmt, {
|
||||
auto numDecls = std::distance(S->decl_begin(), S->decl_end());
|
||||
addData(static_cast<DataPiece>(numDecls));
|
||||
for (const Decl *D : S->decls()) {
|
||||
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
||||
addData(VD->getType());
|
||||
}
|
||||
}
|
||||
})
|
||||
DEF_ADD_DATA(AsmStmt, {
|
||||
addData(S->isSimple());
|
||||
addData(S->isVolatile());
|
||||
addData(S->generateAsmString(Context));
|
||||
for (unsigned i = 0; i < S->getNumInputs(); ++i) {
|
||||
addData(S->getInputConstraint(i));
|
||||
}
|
||||
for (unsigned i = 0; i < S->getNumOutputs(); ++i) {
|
||||
addData(S->getOutputConstraint(i));
|
||||
}
|
||||
for (unsigned i = 0; i < S->getNumClobbers(); ++i) {
|
||||
addData(S->getClobber(i));
|
||||
}
|
||||
})
|
||||
DEF_ADD_DATA(AttributedStmt, {
|
||||
for (const Attr *A : S->getAttrs()) {
|
||||
addData(std::string(A->getSpelling()));
|
||||
}
|
||||
})
|
||||
};
|
||||
} // namespace clone_detection
|
||||
|
||||
/// Identifies a list of statements.
|
||||
///
|
||||
/// Can either identify a single arbitrary Stmt object, a continuous sequence of
|
||||
@ -423,9 +233,9 @@ public:
|
||||
/// filtered.
|
||||
/// \param Filter The filter function that should return true for all groups
|
||||
/// that should be removed from the list.
|
||||
static void
|
||||
filterGroups(std::vector<CloneDetector::CloneGroup> &CloneGroups,
|
||||
std::function<bool(const CloneDetector::CloneGroup &)> Filter) {
|
||||
static void filterGroups(
|
||||
std::vector<CloneDetector::CloneGroup> &CloneGroups,
|
||||
llvm::function_ref<bool(const CloneDetector::CloneGroup &)> Filter) {
|
||||
CloneGroups.erase(
|
||||
std::remove_if(CloneGroups.begin(), CloneGroups.end(), Filter),
|
||||
CloneGroups.end());
|
||||
@ -439,25 +249,29 @@ public:
|
||||
/// to the same CloneGroup.
|
||||
static void splitCloneGroups(
|
||||
std::vector<CloneDetector::CloneGroup> &CloneGroups,
|
||||
std::function<bool(const StmtSequence &, const StmtSequence &)> Compare);
|
||||
llvm::function_ref<bool(const StmtSequence &, const StmtSequence &)>
|
||||
Compare);
|
||||
};
|
||||
|
||||
/// Searches all children of the given clones for type II clones (i.e. they are
|
||||
/// identical in every aspect beside the used variable names).
|
||||
class RecursiveCloneTypeIIConstraint {
|
||||
|
||||
/// Generates and saves a hash code for the given Stmt.
|
||||
/// \param S The given Stmt.
|
||||
/// \param D The Decl containing S.
|
||||
/// \param StmtsByHash Output parameter that will contain the hash codes for
|
||||
/// each StmtSequence in the given Stmt.
|
||||
/// \return The hash code of the given Stmt.
|
||||
///
|
||||
/// If the given Stmt is a CompoundStmt, this method will also generate
|
||||
/// hashes for all possible StmtSequences in the children of this Stmt.
|
||||
size_t saveHash(const Stmt *S, const Decl *D,
|
||||
std::vector<std::pair<size_t, StmtSequence>> &StmtsByHash);
|
||||
/// This constraint moves clones into clone groups of type II via hashing.
|
||||
///
|
||||
/// Clones with different hash values are moved into separate clone groups.
|
||||
/// Collisions are possible, and this constraint does nothing to address this
|
||||
/// them. Add the slower RecursiveCloneTypeIIVerifyConstraint later in the
|
||||
/// constraint chain, not necessarily immediately, to eliminate hash collisions
|
||||
/// through a more detailed analysis.
|
||||
class RecursiveCloneTypeIIHashConstraint {
|
||||
public:
|
||||
void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
|
||||
};
|
||||
|
||||
/// This constraint moves clones into clone groups of type II by comparing them.
|
||||
///
|
||||
/// Clones that aren't type II clones are moved into separate clone groups.
|
||||
/// In contrast to the RecursiveCloneTypeIIHashConstraint, all clones in a clone
|
||||
/// group are guaranteed to be be type II clones of each other, but it is too
|
||||
/// slow to efficiently handle large amounts of clones.
|
||||
class RecursiveCloneTypeIIVerifyConstraint {
|
||||
public:
|
||||
void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
|
||||
};
|
||||
@ -474,14 +288,19 @@ public:
|
||||
MinComplexityConstraint(unsigned MinComplexity)
|
||||
: MinComplexity(MinComplexity) {}
|
||||
|
||||
size_t calculateStmtComplexity(const StmtSequence &Seq,
|
||||
/// Calculates the complexity of the given StmtSequence.
|
||||
/// \param Limit The limit of complexity we probe for. After reaching
|
||||
/// this limit during calculation, this method is exiting
|
||||
/// early to improve performance and returns this limit.
|
||||
size_t calculateStmtComplexity(const StmtSequence &Seq, std::size_t Limit,
|
||||
const std::string &ParentMacroStack = "");
|
||||
|
||||
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
|
||||
CloneConstraint::filterGroups(
|
||||
CloneGroups, [this](const CloneDetector::CloneGroup &A) {
|
||||
if (!A.empty())
|
||||
return calculateStmtComplexity(A.front()) < MinComplexity;
|
||||
return calculateStmtComplexity(A.front(), MinComplexity) <
|
||||
MinComplexity;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
@ -15,7 +15,7 @@
|
||||
#ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
|
||||
#define LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
|
||||
|
||||
#include "clang/Analysis/AnalysisContext.h"
|
||||
#include "clang/Analysis/AnalysisDeclContext.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
@ -83,6 +83,7 @@ public:
|
||||
PostImplicitCallKind,
|
||||
MinImplicitCallKind = PreImplicitCallKind,
|
||||
MaxImplicitCallKind = PostImplicitCallKind,
|
||||
LoopExitKind,
|
||||
EpsilonKind};
|
||||
|
||||
private:
|
||||
@ -654,6 +655,29 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
/// Represents a point when we exit a loop.
|
||||
/// When this ProgramPoint is encountered we can be sure that the symbolic
|
||||
/// execution of the corresponding LoopStmt is finished on the given path.
|
||||
/// Note: It is possible to encounter a LoopExit element when we haven't even
|
||||
/// encountered the loop itself. At the current state not all loop exits will
|
||||
/// result in a LoopExit program point.
|
||||
class LoopExit : public ProgramPoint {
|
||||
public:
|
||||
LoopExit(const Stmt *LoopStmt, const LocationContext *LC)
|
||||
: ProgramPoint(LoopStmt, nullptr, LoopExitKind, LC) {}
|
||||
|
||||
const Stmt *getLoopStmt() const {
|
||||
return static_cast<const Stmt *>(getData1());
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ProgramPoint;
|
||||
LoopExit() {}
|
||||
static bool isKind(const ProgramPoint &Location) {
|
||||
return Location.getKind() == LoopExitKind;
|
||||
}
|
||||
};
|
||||
|
||||
/// This is a meta program point, which should be skipped by all the diagnostic
|
||||
/// reasoning etc.
|
||||
class EpsilonPoint : public ProgramPoint {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- BumpVector.h - Vector-like ADT that uses bump allocation --*- C++ -*-=//
|
||||
//===- BumpVector.h - Vector-like ADT that uses bump allocation -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -21,16 +21,18 @@
|
||||
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class BumpVectorContext {
|
||||
llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1> Alloc;
|
||||
|
||||
public:
|
||||
/// Construct a new BumpVectorContext that creates a new BumpPtrAllocator
|
||||
/// and destroys it when the BumpVectorContext object is destroyed.
|
||||
@ -56,11 +58,13 @@ public:
|
||||
|
||||
template<typename T>
|
||||
class BumpVector {
|
||||
T *Begin, *End, *Capacity;
|
||||
T *Begin = nullptr;
|
||||
T *End = nullptr;
|
||||
T *Capacity = nullptr;
|
||||
|
||||
public:
|
||||
// Default ctor - Initialize to empty.
|
||||
explicit BumpVector(BumpVectorContext &C, unsigned N)
|
||||
: Begin(nullptr), End(nullptr), Capacity(nullptr) {
|
||||
explicit BumpVector(BumpVectorContext &C, unsigned N) {
|
||||
reserve(C, N);
|
||||
}
|
||||
|
||||
@ -71,19 +75,19 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T value_type;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using value_type = T;
|
||||
using iterator = T *;
|
||||
using const_iterator = const T *;
|
||||
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
using reference = T &;
|
||||
using const_reference = const T &;
|
||||
using pointer = T *;
|
||||
using const_pointer = const T *;
|
||||
|
||||
// forward iterator creation methods.
|
||||
iterator begin() { return Begin; }
|
||||
@ -92,10 +96,12 @@ public:
|
||||
const_iterator end() const { return End; }
|
||||
|
||||
// reverse iterator creation methods.
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const {
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
bool empty() const { return Begin == End; }
|
||||
size_type size() const { return End-Begin; }
|
||||
@ -166,7 +172,7 @@ public:
|
||||
/// iterator to position after last inserted copy.
|
||||
iterator insert(iterator I, size_t Cnt, const_reference E,
|
||||
BumpVectorContext &C) {
|
||||
assert (I >= Begin && I <= End && "Iterator out of bounds.");
|
||||
assert(I >= Begin && I <= End && "Iterator out of bounds.");
|
||||
if (End + Cnt <= Capacity) {
|
||||
Retry:
|
||||
move_range_right(I, End, Cnt);
|
||||
@ -246,5 +252,6 @@ void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) {
|
||||
Capacity = Begin+NewCapacity;
|
||||
}
|
||||
|
||||
} // end: clang namespace
|
||||
#endif
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H
|
||||
|
@ -16,25 +16,26 @@
|
||||
#ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H
|
||||
#define LLVM_CLANG_BASIC_ADDRESSSPACES_H
|
||||
|
||||
namespace clang {
|
||||
#include <assert.h>
|
||||
|
||||
namespace LangAS {
|
||||
namespace clang {
|
||||
|
||||
/// \brief Defines the address space values used by the address space qualifier
|
||||
/// of QualType.
|
||||
///
|
||||
enum ID {
|
||||
enum class LangAS : unsigned {
|
||||
// The default value 0 is the value used in QualType for the the situation
|
||||
// where there is no address space qualifier. For most languages, this also
|
||||
// corresponds to the situation where there is no address space qualifier in
|
||||
// the source code, except for OpenCL, where the address space value 0 in
|
||||
// QualType represents private address space in OpenCL source code.
|
||||
// where there is no address space qualifier.
|
||||
Default = 0,
|
||||
|
||||
// OpenCL specific address spaces.
|
||||
// In OpenCL each l-value must have certain non-default address space, each
|
||||
// r-value must have no address space (i.e. the default address space). The
|
||||
// pointee of a pointer must have non-default address space.
|
||||
opencl_global,
|
||||
opencl_local,
|
||||
opencl_constant,
|
||||
opencl_private,
|
||||
opencl_generic,
|
||||
|
||||
// CUDA specific address spaces.
|
||||
@ -50,9 +51,24 @@ enum ID {
|
||||
|
||||
/// The type of a lookup table which maps from language-specific address spaces
|
||||
/// to target-specific ones.
|
||||
typedef unsigned Map[FirstTargetAddressSpace];
|
||||
typedef unsigned LangASMap[(unsigned)LangAS::FirstTargetAddressSpace];
|
||||
|
||||
/// \return whether \p AS is a target-specific address space rather than a
|
||||
/// clang AST address space
|
||||
inline bool isTargetAddressSpace(LangAS AS) {
|
||||
return (unsigned)AS >= (unsigned)LangAS::FirstTargetAddressSpace;
|
||||
}
|
||||
|
||||
inline unsigned toTargetAddressSpace(LangAS AS) {
|
||||
assert(isTargetAddressSpace(AS));
|
||||
return (unsigned)AS - (unsigned)LangAS::FirstTargetAddressSpace;
|
||||
}
|
||||
|
||||
inline LangAS getLangASFromTargetAS(unsigned TargetAS) {
|
||||
return static_cast<LangAS>((TargetAS) +
|
||||
(unsigned)LangAS::FirstTargetAddressSpace);
|
||||
}
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,44 @@
|
||||
//===--- AlignedAllocation.h - Aligned Allocation ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief Defines a function that returns the minimum OS versions supporting
|
||||
/// C++17's aligned allocation functions.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
|
||||
#define LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
|
||||
|
||||
#include "clang/Basic/VersionTuple.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
inline VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
|
||||
switch (OS) {
|
||||
default:
|
||||
break;
|
||||
case llvm::Triple::Darwin:
|
||||
case llvm::Triple::MacOSX: // Earliest supporting version is 10.13.
|
||||
return VersionTuple(10U, 13U);
|
||||
case llvm::Triple::IOS:
|
||||
case llvm::Triple::TvOS: // Earliest supporting version is 11.0.0.
|
||||
return VersionTuple(11U);
|
||||
case llvm::Triple::WatchOS: // Earliest supporting version is 4.0.0.
|
||||
return VersionTuple(4U);
|
||||
}
|
||||
|
||||
llvm_unreachable("Unexpected OS");
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
|
@ -18,12 +18,14 @@
|
||||
#include "clang/AST/ASTDiagnostic.h"
|
||||
#include "clang/AST/CommentDiagnostic.h"
|
||||
#include "clang/Analysis/AnalysisDiagnostic.h"
|
||||
#include "clang/CrossTU/CrossTUDiagnostic.h"
|
||||
#include "clang/Driver/DriverDiagnostic.h"
|
||||
#include "clang/Frontend/FrontendDiagnostic.h"
|
||||
#include "clang/Lex/LexDiagnostic.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Sema/SemaDiagnostic.h"
|
||||
#include "clang/Serialization/SerializationDiagnostic.h"
|
||||
#include "clang/Tooling/Refactoring/RefactoringDiagnostic.h"
|
||||
|
||||
namespace clang {
|
||||
template <size_t SizeOfStr, typename FieldType>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,6 +7,24 @@
|
||||
//
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
// To test that the documentation builds cleanly, you must run clang-tblgen to
|
||||
// convert the .td file into a .rst file, and then run sphinx to convert the
|
||||
// .rst file into an HTML file. After completing testing, you should revert the
|
||||
// generated .rst file so that the modified version does not get checked in to
|
||||
// version control.
|
||||
//
|
||||
// To run clang-tblgen to generate the .rst file:
|
||||
// clang-tblgen -gen-attr-docs -I <root>/llvm/tools/clang/include
|
||||
// <root>/llvm/tools/clang/include/clang/Basic/Attr.td -o
|
||||
// <root>/llvm/tools/clang/docs/AttributeReference.rst
|
||||
//
|
||||
// To run sphinx to generate the .html files (note that sphinx-build must be
|
||||
// available on the PATH):
|
||||
// Windows (from within the clang\docs directory):
|
||||
// make.bat html
|
||||
// Non-Windows (from within the clang\docs directory):
|
||||
// make -f Makefile.sphinx html
|
||||
|
||||
def GlobalDocumentation {
|
||||
code Intro =[{..
|
||||
-------------------------------------------------------------------
|
||||
@ -112,6 +130,50 @@ members, and static locals.
|
||||
}];
|
||||
}
|
||||
|
||||
def NoEscapeDocs : Documentation {
|
||||
let Category = DocCatVariable;
|
||||
let Content = [{
|
||||
``noescape`` placed on a function parameter of a pointer type is used to inform
|
||||
the compiler that the pointer cannot escape: that is, no reference to the object
|
||||
the pointer points to that is derived from the parameter value will survive
|
||||
after the function returns. Users are responsible for making sure parameters
|
||||
annotated with ``noescape`` do not actuallly escape.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int *gp;
|
||||
|
||||
void nonescapingFunc(__attribute__((noescape)) int *p) {
|
||||
*p += 100; // OK.
|
||||
}
|
||||
|
||||
void escapingFunc(__attribute__((noescape)) int *p) {
|
||||
gp = p; // Not OK.
|
||||
}
|
||||
|
||||
Additionally, when the parameter is a `block pointer
|
||||
<https://clang.llvm.org/docs/BlockLanguageSpec.html>`, the same restriction
|
||||
applies to copies of the block. For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
typedef void (^BlockTy)();
|
||||
BlockTy g0, g1;
|
||||
|
||||
void nonescapingFunc(__attribute__((noescape)) BlockTy block) {
|
||||
block(); // OK.
|
||||
}
|
||||
|
||||
void escapingFunc(__attribute__((noescape)) BlockTy block) {
|
||||
g0 = block; // Not OK.
|
||||
g1 = Block_copy(block); // Not OK either.
|
||||
}
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
def CarriesDependencyDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
@ -1231,6 +1293,7 @@ Here is an example:
|
||||
|
||||
def ARMInterruptDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "interrupt (ARM)";
|
||||
let Content = [{
|
||||
Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on
|
||||
ARM targets. This attribute may be attached to a function definition and
|
||||
@ -1272,6 +1335,7 @@ The semantics are as follows:
|
||||
|
||||
def MipsInterruptDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "interrupt (MIPS)";
|
||||
let Content = [{
|
||||
Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on
|
||||
MIPS targets. This attribute may be attached to a function definition and instructs
|
||||
@ -1323,8 +1387,52 @@ on the command line.
|
||||
}];
|
||||
}
|
||||
|
||||
def MipsLongCallStyleDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "long_call (gnu::long_call, gnu::far)";
|
||||
let Content = [{
|
||||
Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
|
||||
and ``__attribute__((near))`` attributes on MIPS targets. These attributes may
|
||||
only be added to function declarations and change the code generated
|
||||
by the compiler when directly calling the function. The ``near`` attribute
|
||||
allows calls to the function to be made using the ``jal`` instruction, which
|
||||
requires the function to be located in the same naturally aligned 256MB
|
||||
segment as the caller. The ``long_call`` and ``far`` attributes are synonyms
|
||||
and require the use of a different call sequence that works regardless
|
||||
of the distance between the functions.
|
||||
|
||||
These attributes have no effect for position-independent code.
|
||||
|
||||
These attributes take priority over command line switches such
|
||||
as ``-mlong-calls`` and ``-mno-long-calls``.
|
||||
}];
|
||||
}
|
||||
|
||||
def MipsShortCallStyleDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "short_call (gnu::short_call, gnu::near)";
|
||||
let Content = [{
|
||||
Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
|
||||
``__attribute__((short__call))``, and ``__attribute__((near))`` attributes
|
||||
on MIPS targets. These attributes may only be added to function declarations
|
||||
and change the code generated by the compiler when directly calling
|
||||
the function. The ``short_call`` and ``near`` attributes are synonyms and
|
||||
allow calls to the function to be made using the ``jal`` instruction, which
|
||||
requires the function to be located in the same naturally aligned 256MB segment
|
||||
as the caller. The ``long_call`` and ``far`` attributes are synonyms and
|
||||
require the use of a different call sequence that works regardless
|
||||
of the distance between the functions.
|
||||
|
||||
These attributes have no effect for position-independent code.
|
||||
|
||||
These attributes take priority over command line switches such
|
||||
as ``-mlong-calls`` and ``-mno-long-calls``.
|
||||
}];
|
||||
}
|
||||
|
||||
def AVRInterruptDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "interrupt (AVR)";
|
||||
let Content = [{
|
||||
Clang supports the GNU style ``__attribute__((interrupt))`` attribute on
|
||||
AVR targets. This attribute may be attached to a function definition and instructs
|
||||
@ -2625,6 +2733,18 @@ Marking virtual functions as ``not_tail_called`` is an error:
|
||||
}];
|
||||
}
|
||||
|
||||
def NoThrowDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
Clang supports the GNU style ``__attribute__((nothrow))`` and Microsoft style
|
||||
``__declspec(nothrow)`` attribute as an equivilent of `noexcept` on function
|
||||
declarations. This attribute informs the compiler that the annotated function
|
||||
does not throw an exception. This prevents exception-unwinding. This attribute
|
||||
is particularly useful on functions in the C Standard Library that are
|
||||
guaranteed to not throw an exception.
|
||||
}];
|
||||
}
|
||||
|
||||
def InternalLinkageDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
@ -2673,59 +2793,6 @@ Marking virtual functions as ``disable_tail_calls`` is legal.
|
||||
}];
|
||||
}
|
||||
|
||||
def AnyX86InterruptDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
Clang supports the GNU style ``__attribute__((interrupt))`` attribute on
|
||||
x86/x86-64 targets.The compiler generates function entry and exit sequences
|
||||
suitable for use in an interrupt handler when this attribute is present.
|
||||
The 'IRET' instruction, instead of the 'RET' instruction, is used to return
|
||||
from interrupt or exception handlers. All registers, except for the EFLAGS
|
||||
register which is restored by the 'IRET' instruction, are preserved by the
|
||||
compiler.
|
||||
|
||||
Any interruptible-without-stack-switch code must be compiled with
|
||||
-mno-red-zone since interrupt handlers can and will, because of the
|
||||
hardware design, touch the red zone.
|
||||
|
||||
1. interrupt handler must be declared with a mandatory pointer argument:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct interrupt_frame
|
||||
{
|
||||
uword_t ip;
|
||||
uword_t cs;
|
||||
uword_t flags;
|
||||
uword_t sp;
|
||||
uword_t ss;
|
||||
};
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void f (struct interrupt_frame *frame) {
|
||||
...
|
||||
}
|
||||
|
||||
2. exception handler:
|
||||
|
||||
The exception handler is very similar to the interrupt handler with
|
||||
a different mandatory function signature:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void f (struct interrupt_frame *frame, uword_t error_code) {
|
||||
...
|
||||
}
|
||||
|
||||
and compiler pops 'ERROR_CODE' off stack before the 'IRET' instruction.
|
||||
|
||||
The exception handler should only be used for exceptions which push an
|
||||
error code and all other exceptions must use the interrupt handler.
|
||||
The system will crash if the wrong handler is used.
|
||||
}];
|
||||
}
|
||||
|
||||
def AnyX86NoCallerSavedRegistersDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
@ -2760,6 +2827,31 @@ For example:
|
||||
}];
|
||||
}
|
||||
|
||||
def X86ForceAlignArgPointerDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
Use this attribute to force stack alignment.
|
||||
|
||||
Legacy x86 code uses 4-byte stack alignment. Newer aligned SSE instructions
|
||||
(like 'movaps') that work with the stack require operands to be 16-byte aligned.
|
||||
This attribute realigns the stack in the function prologue to make sure the
|
||||
stack can be used with SSE instructions.
|
||||
|
||||
Note that the x86_64 ABI forces 16-byte stack alignment at the call site.
|
||||
Because of this, 'force_align_arg_pointer' is not needed on x86_64, except in
|
||||
rare cases where the caller does not align the stack properly (e.g. flow
|
||||
jumps from i386 arch code).
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
__attribute__ ((force_align_arg_pointer))
|
||||
void f () {
|
||||
...
|
||||
}
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
def SwiftCallDocs : Documentation {
|
||||
let Category = DocCatVariable;
|
||||
let Content = [{
|
||||
|
@ -26,6 +26,8 @@ enum class AttrSyntax {
|
||||
Microsoft,
|
||||
// Is the identifier known as a C++-style attribute?
|
||||
CXX,
|
||||
// Is the identifier known as a C-style attribute?
|
||||
C,
|
||||
// Is the identifier known as a pragma attribute?
|
||||
Pragma
|
||||
};
|
||||
|
@ -103,9 +103,9 @@
|
||||
#endif
|
||||
|
||||
// Standard libc/libm functions:
|
||||
BUILTIN(__builtin_atan2 , "ddd" , "Fnc")
|
||||
BUILTIN(__builtin_atan2f, "fff" , "Fnc")
|
||||
BUILTIN(__builtin_atan2l, "LdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_atan2 , "ddd" , "Fne")
|
||||
BUILTIN(__builtin_atan2f, "fff" , "Fne")
|
||||
BUILTIN(__builtin_atan2l, "LdLdLd", "Fne")
|
||||
BUILTIN(__builtin_abs , "ii" , "ncF")
|
||||
BUILTIN(__builtin_copysign, "ddd", "ncF")
|
||||
BUILTIN(__builtin_copysignf, "fff", "ncF")
|
||||
@ -113,9 +113,9 @@ BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
|
||||
BUILTIN(__builtin_fabs , "dd" , "ncF")
|
||||
BUILTIN(__builtin_fabsf, "ff" , "ncF")
|
||||
BUILTIN(__builtin_fabsl, "LdLd", "ncF")
|
||||
BUILTIN(__builtin_fmod , "ddd" , "Fnc")
|
||||
BUILTIN(__builtin_fmodf, "fff" , "Fnc")
|
||||
BUILTIN(__builtin_fmodl, "LdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_fmod , "ddd" , "Fne")
|
||||
BUILTIN(__builtin_fmodf, "fff" , "Fne")
|
||||
BUILTIN(__builtin_fmodl, "LdLdLd", "Fne")
|
||||
BUILTIN(__builtin_frexp , "ddi*" , "Fn")
|
||||
BUILTIN(__builtin_frexpf, "ffi*" , "Fn")
|
||||
BUILTIN(__builtin_frexpl, "LdLdi*", "Fn")
|
||||
@ -127,9 +127,9 @@ BUILTIN(__builtin_inff , "f" , "nc")
|
||||
BUILTIN(__builtin_infl , "Ld" , "nc")
|
||||
BUILTIN(__builtin_labs , "LiLi" , "Fnc")
|
||||
BUILTIN(__builtin_llabs, "LLiLLi", "Fnc")
|
||||
BUILTIN(__builtin_ldexp , "ddi" , "Fnc")
|
||||
BUILTIN(__builtin_ldexpf, "ffi" , "Fnc")
|
||||
BUILTIN(__builtin_ldexpl, "LdLdi", "Fnc")
|
||||
BUILTIN(__builtin_ldexp , "ddi" , "Fne")
|
||||
BUILTIN(__builtin_ldexpf, "ffi" , "Fne")
|
||||
BUILTIN(__builtin_ldexpl, "LdLdi", "Fne")
|
||||
BUILTIN(__builtin_modf , "ddd*" , "Fn")
|
||||
BUILTIN(__builtin_modff, "fff*" , "Fn")
|
||||
BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
|
||||
@ -142,119 +142,119 @@ BUILTIN(__builtin_nansl, "LdcC*", "ncF")
|
||||
BUILTIN(__builtin_powi , "ddi" , "Fnc")
|
||||
BUILTIN(__builtin_powif, "ffi" , "Fnc")
|
||||
BUILTIN(__builtin_powil, "LdLdi", "Fnc")
|
||||
BUILTIN(__builtin_pow , "ddd" , "Fnc")
|
||||
BUILTIN(__builtin_powf, "fff" , "Fnc")
|
||||
BUILTIN(__builtin_powl, "LdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_pow , "ddd" , "Fne")
|
||||
BUILTIN(__builtin_powf, "fff" , "Fne")
|
||||
BUILTIN(__builtin_powl, "LdLdLd", "Fne")
|
||||
|
||||
// Standard unary libc/libm functions with double/float/long double variants:
|
||||
BUILTIN(__builtin_acos , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_acosf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_acosl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_acosh , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_acoshf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_acoshl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_asin , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_asinf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_asinl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_asinh , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_asinhf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_asinhl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_atan , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_atanf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_atanl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_atanh , "dd", "Fnc")
|
||||
BUILTIN(__builtin_atanhf, "ff", "Fnc")
|
||||
BUILTIN(__builtin_atanhl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_acos , "dd" , "Fne")
|
||||
BUILTIN(__builtin_acosf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_acosl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_acosh , "dd" , "Fne")
|
||||
BUILTIN(__builtin_acoshf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_acoshl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_asin , "dd" , "Fne")
|
||||
BUILTIN(__builtin_asinf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_asinl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_asinh , "dd" , "Fne")
|
||||
BUILTIN(__builtin_asinhf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_asinhl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_atan , "dd" , "Fne")
|
||||
BUILTIN(__builtin_atanf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_atanl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_atanh , "dd", "Fne")
|
||||
BUILTIN(__builtin_atanhf, "ff", "Fne")
|
||||
BUILTIN(__builtin_atanhl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_cbrt , "dd", "Fnc")
|
||||
BUILTIN(__builtin_cbrtf, "ff", "Fnc")
|
||||
BUILTIN(__builtin_cbrtl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_ceil , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_ceilf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_ceill, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_cos , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_cosf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_cosh , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_coshf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_coshl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_cosl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_erf , "dd", "Fnc")
|
||||
BUILTIN(__builtin_erff, "ff", "Fnc")
|
||||
BUILTIN(__builtin_erfl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_erfc , "dd", "Fnc")
|
||||
BUILTIN(__builtin_erfcf, "ff", "Fnc")
|
||||
BUILTIN(__builtin_erfcl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_exp , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_expf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_expl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_exp2 , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_exp2f, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_exp2l, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_expm1 , "dd", "Fnc")
|
||||
BUILTIN(__builtin_expm1f, "ff", "Fnc")
|
||||
BUILTIN(__builtin_expm1l, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_fdim, "ddd", "Fnc")
|
||||
BUILTIN(__builtin_fdimf, "fff", "Fnc")
|
||||
BUILTIN(__builtin_fdiml, "LdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_cos , "dd" , "Fne")
|
||||
BUILTIN(__builtin_cosf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_cosh , "dd" , "Fne")
|
||||
BUILTIN(__builtin_coshf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_coshl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_cosl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_erf , "dd", "Fne")
|
||||
BUILTIN(__builtin_erff, "ff", "Fne")
|
||||
BUILTIN(__builtin_erfl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_erfc , "dd", "Fne")
|
||||
BUILTIN(__builtin_erfcf, "ff", "Fne")
|
||||
BUILTIN(__builtin_erfcl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_exp , "dd" , "Fne")
|
||||
BUILTIN(__builtin_expf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_expl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_exp2 , "dd" , "Fne")
|
||||
BUILTIN(__builtin_exp2f, "ff" , "Fne")
|
||||
BUILTIN(__builtin_exp2l, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_expm1 , "dd", "Fne")
|
||||
BUILTIN(__builtin_expm1f, "ff", "Fne")
|
||||
BUILTIN(__builtin_expm1l, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_fdim, "ddd", "Fne")
|
||||
BUILTIN(__builtin_fdimf, "fff", "Fne")
|
||||
BUILTIN(__builtin_fdiml, "LdLdLd", "Fne")
|
||||
BUILTIN(__builtin_floor , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_floorf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_floorl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_fma, "dddd", "Fnc")
|
||||
BUILTIN(__builtin_fmaf, "ffff", "Fnc")
|
||||
BUILTIN(__builtin_fmal, "LdLdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_fma, "dddd", "Fne")
|
||||
BUILTIN(__builtin_fmaf, "ffff", "Fne")
|
||||
BUILTIN(__builtin_fmal, "LdLdLdLd", "Fne")
|
||||
BUILTIN(__builtin_fmax, "ddd", "Fnc")
|
||||
BUILTIN(__builtin_fmaxf, "fff", "Fnc")
|
||||
BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_fmin, "ddd", "Fnc")
|
||||
BUILTIN(__builtin_fminf, "fff", "Fnc")
|
||||
BUILTIN(__builtin_fminl, "LdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_hypot , "ddd" , "Fnc")
|
||||
BUILTIN(__builtin_hypotf, "fff" , "Fnc")
|
||||
BUILTIN(__builtin_hypotl, "LdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_ilogb , "id", "Fnc")
|
||||
BUILTIN(__builtin_ilogbf, "if", "Fnc")
|
||||
BUILTIN(__builtin_ilogbl, "iLd", "Fnc")
|
||||
BUILTIN(__builtin_lgamma , "dd", "Fnc")
|
||||
BUILTIN(__builtin_lgammaf, "ff", "Fnc")
|
||||
BUILTIN(__builtin_lgammal, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_llrint, "LLid", "Fnc")
|
||||
BUILTIN(__builtin_llrintf, "LLif", "Fnc")
|
||||
BUILTIN(__builtin_llrintl, "LLiLd", "Fnc")
|
||||
BUILTIN(__builtin_llround , "LLid", "Fnc")
|
||||
BUILTIN(__builtin_llroundf, "LLif", "Fnc")
|
||||
BUILTIN(__builtin_llroundl, "LLiLd", "Fnc")
|
||||
BUILTIN(__builtin_log , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_log10 , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_log10f, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_log10l, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_log1p , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_log1pf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_log1pl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_log2, "dd" , "Fnc")
|
||||
BUILTIN(__builtin_log2f, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_log2l, "LdLd" , "Fnc")
|
||||
BUILTIN(__builtin_logb , "dd", "Fnc")
|
||||
BUILTIN(__builtin_logbf, "ff", "Fnc")
|
||||
BUILTIN(__builtin_logbl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_logf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_logl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_lrint , "Lid", "Fnc")
|
||||
BUILTIN(__builtin_lrintf, "Lif", "Fnc")
|
||||
BUILTIN(__builtin_lrintl, "LiLd", "Fnc")
|
||||
BUILTIN(__builtin_lround , "Lid", "Fnc")
|
||||
BUILTIN(__builtin_lroundf, "Lif", "Fnc")
|
||||
BUILTIN(__builtin_lroundl, "LiLd", "Fnc")
|
||||
BUILTIN(__builtin_hypot , "ddd" , "Fne")
|
||||
BUILTIN(__builtin_hypotf, "fff" , "Fne")
|
||||
BUILTIN(__builtin_hypotl, "LdLdLd", "Fne")
|
||||
BUILTIN(__builtin_ilogb , "id", "Fne")
|
||||
BUILTIN(__builtin_ilogbf, "if", "Fne")
|
||||
BUILTIN(__builtin_ilogbl, "iLd", "Fne")
|
||||
BUILTIN(__builtin_lgamma , "dd", "Fn")
|
||||
BUILTIN(__builtin_lgammaf, "ff", "Fn")
|
||||
BUILTIN(__builtin_lgammal, "LdLd", "Fn")
|
||||
BUILTIN(__builtin_llrint, "LLid", "Fne")
|
||||
BUILTIN(__builtin_llrintf, "LLif", "Fne")
|
||||
BUILTIN(__builtin_llrintl, "LLiLd", "Fne")
|
||||
BUILTIN(__builtin_llround , "LLid", "Fne")
|
||||
BUILTIN(__builtin_llroundf, "LLif", "Fne")
|
||||
BUILTIN(__builtin_llroundl, "LLiLd", "Fne")
|
||||
BUILTIN(__builtin_log , "dd" , "Fne")
|
||||
BUILTIN(__builtin_log10 , "dd" , "Fne")
|
||||
BUILTIN(__builtin_log10f, "ff" , "Fne")
|
||||
BUILTIN(__builtin_log10l, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_log1p , "dd" , "Fne")
|
||||
BUILTIN(__builtin_log1pf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_log1pl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_log2, "dd" , "Fne")
|
||||
BUILTIN(__builtin_log2f, "ff" , "Fne")
|
||||
BUILTIN(__builtin_log2l, "LdLd" , "Fne")
|
||||
BUILTIN(__builtin_logb , "dd", "Fne")
|
||||
BUILTIN(__builtin_logbf, "ff", "Fne")
|
||||
BUILTIN(__builtin_logbl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_logf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_logl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_lrint , "Lid", "Fne")
|
||||
BUILTIN(__builtin_lrintf, "Lif", "Fne")
|
||||
BUILTIN(__builtin_lrintl, "LiLd", "Fne")
|
||||
BUILTIN(__builtin_lround , "Lid", "Fne")
|
||||
BUILTIN(__builtin_lroundf, "Lif", "Fne")
|
||||
BUILTIN(__builtin_lroundl, "LiLd", "Fne")
|
||||
BUILTIN(__builtin_nearbyint , "dd", "Fnc")
|
||||
BUILTIN(__builtin_nearbyintf, "ff", "Fnc")
|
||||
BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_nextafter , "ddd", "Fnc")
|
||||
BUILTIN(__builtin_nextafterf, "fff", "Fnc")
|
||||
BUILTIN(__builtin_nextafterl, "LdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_nexttoward , "ddLd", "Fnc")
|
||||
BUILTIN(__builtin_nexttowardf, "ffLd", "Fnc")
|
||||
BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_remainder , "ddd", "Fnc")
|
||||
BUILTIN(__builtin_remainderf, "fff", "Fnc")
|
||||
BUILTIN(__builtin_remainderl, "LdLdLd", "Fnc")
|
||||
BUILTIN(__builtin_nextafter , "ddd", "Fne")
|
||||
BUILTIN(__builtin_nextafterf, "fff", "Fne")
|
||||
BUILTIN(__builtin_nextafterl, "LdLdLd", "Fne")
|
||||
BUILTIN(__builtin_nexttoward , "ddLd", "Fne")
|
||||
BUILTIN(__builtin_nexttowardf, "ffLd", "Fne")
|
||||
BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fne")
|
||||
BUILTIN(__builtin_remainder , "ddd", "Fne")
|
||||
BUILTIN(__builtin_remainderf, "fff", "Fne")
|
||||
BUILTIN(__builtin_remainderl, "LdLdLd", "Fne")
|
||||
BUILTIN(__builtin_remquo , "dddi*", "Fn")
|
||||
BUILTIN(__builtin_remquof, "fffi*", "Fn")
|
||||
BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn")
|
||||
@ -264,101 +264,101 @@ BUILTIN(__builtin_rintl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_round, "dd" , "Fnc")
|
||||
BUILTIN(__builtin_roundf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_roundl, "LdLd" , "Fnc")
|
||||
BUILTIN(__builtin_scalbln , "ddLi", "Fnc")
|
||||
BUILTIN(__builtin_scalblnf, "ffLi", "Fnc")
|
||||
BUILTIN(__builtin_scalblnl, "LdLdLi", "Fnc")
|
||||
BUILTIN(__builtin_scalbn , "ddi", "Fnc")
|
||||
BUILTIN(__builtin_scalbnf, "ffi", "Fnc")
|
||||
BUILTIN(__builtin_scalbnl, "LdLdi", "Fnc")
|
||||
BUILTIN(__builtin_sin , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_sinf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_sinh , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_sinhf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_sinhl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_sinl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_sqrt , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_sqrtf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_sqrtl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_tan , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_tanf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_tanh , "dd" , "Fnc")
|
||||
BUILTIN(__builtin_tanhf, "ff" , "Fnc")
|
||||
BUILTIN(__builtin_tanhl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_tanl, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_tgamma , "dd", "Fnc")
|
||||
BUILTIN(__builtin_tgammaf, "ff", "Fnc")
|
||||
BUILTIN(__builtin_tgammal, "LdLd", "Fnc")
|
||||
BUILTIN(__builtin_scalbln , "ddLi", "Fne")
|
||||
BUILTIN(__builtin_scalblnf, "ffLi", "Fne")
|
||||
BUILTIN(__builtin_scalblnl, "LdLdLi", "Fne")
|
||||
BUILTIN(__builtin_scalbn , "ddi", "Fne")
|
||||
BUILTIN(__builtin_scalbnf, "ffi", "Fne")
|
||||
BUILTIN(__builtin_scalbnl, "LdLdi", "Fne")
|
||||
BUILTIN(__builtin_sin , "dd" , "Fne")
|
||||
BUILTIN(__builtin_sinf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_sinh , "dd" , "Fne")
|
||||
BUILTIN(__builtin_sinhf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_sinhl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_sinl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_sqrt , "dd" , "Fne")
|
||||
BUILTIN(__builtin_sqrtf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_sqrtl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_tan , "dd" , "Fne")
|
||||
BUILTIN(__builtin_tanf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_tanh , "dd" , "Fne")
|
||||
BUILTIN(__builtin_tanhf, "ff" , "Fne")
|
||||
BUILTIN(__builtin_tanhl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_tanl, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_tgamma , "dd", "Fne")
|
||||
BUILTIN(__builtin_tgammaf, "ff", "Fne")
|
||||
BUILTIN(__builtin_tgammal, "LdLd", "Fne")
|
||||
BUILTIN(__builtin_trunc , "dd", "Fnc")
|
||||
BUILTIN(__builtin_truncf, "ff", "Fnc")
|
||||
BUILTIN(__builtin_truncl, "LdLd", "Fnc")
|
||||
|
||||
// C99 complex builtins
|
||||
BUILTIN(__builtin_cabs, "dXd", "Fnc")
|
||||
BUILTIN(__builtin_cabsf, "fXf", "Fnc")
|
||||
BUILTIN(__builtin_cabsl, "LdXLd", "Fnc")
|
||||
BUILTIN(__builtin_cacos, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_cacosf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_cacosh, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_cacoshf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_cacoshl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_cacosl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_carg, "dXd", "Fnc")
|
||||
BUILTIN(__builtin_cargf, "fXf", "Fnc")
|
||||
BUILTIN(__builtin_cargl, "LdXLd", "Fnc")
|
||||
BUILTIN(__builtin_casin, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_casinf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_casinh, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_casinhf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_casinhl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_casinl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_catan, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_catanf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_catanh, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_catanhf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_catanhl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_catanl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_ccos, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_ccosf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_ccosl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_ccosh, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_ccoshf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_ccoshl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_cexp, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_cexpf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_cexpl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_cabs, "dXd", "Fne")
|
||||
BUILTIN(__builtin_cabsf, "fXf", "Fne")
|
||||
BUILTIN(__builtin_cabsl, "LdXLd", "Fne")
|
||||
BUILTIN(__builtin_cacos, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_cacosf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_cacosh, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_cacoshf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_cacoshl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_cacosl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_carg, "dXd", "Fne")
|
||||
BUILTIN(__builtin_cargf, "fXf", "Fne")
|
||||
BUILTIN(__builtin_cargl, "LdXLd", "Fne")
|
||||
BUILTIN(__builtin_casin, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_casinf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_casinh, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_casinhf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_casinhl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_casinl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_catan, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_catanf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_catanh, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_catanhf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_catanhl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_catanl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_ccos, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_ccosf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_ccosl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_ccosh, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_ccoshf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_ccoshl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_cexp, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_cexpf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_cexpl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_cimag, "dXd", "Fnc")
|
||||
BUILTIN(__builtin_cimagf, "fXf", "Fnc")
|
||||
BUILTIN(__builtin_cimagl, "LdXLd", "Fnc")
|
||||
BUILTIN(__builtin_conj, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_conjf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_conjl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_clog, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_clogf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_clogl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_clog, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_clogf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_clogl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_cproj, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_cprojf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_cprojl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_cpow, "XdXdXd", "Fnc")
|
||||
BUILTIN(__builtin_cpowf, "XfXfXf", "Fnc")
|
||||
BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_cpow, "XdXdXd", "Fne")
|
||||
BUILTIN(__builtin_cpowf, "XfXfXf", "Fne")
|
||||
BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fne")
|
||||
BUILTIN(__builtin_creal, "dXd", "Fnc")
|
||||
BUILTIN(__builtin_crealf, "fXf", "Fnc")
|
||||
BUILTIN(__builtin_creall, "LdXLd", "Fnc")
|
||||
BUILTIN(__builtin_csin, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_csinf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_csinl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_csinh, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_csinhf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_csinhl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_csqrt, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_csqrtf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_csqrtl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_ctan, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_ctanf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_ctanl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_ctanh, "XdXd", "Fnc")
|
||||
BUILTIN(__builtin_ctanhf, "XfXf", "Fnc")
|
||||
BUILTIN(__builtin_ctanhl, "XLdXLd", "Fnc")
|
||||
BUILTIN(__builtin_csin, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_csinf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_csinl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_csinh, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_csinhf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_csinhl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_csqrt, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_csqrtf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_csqrtl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_ctan, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_ctanf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_ctanl, "XLdXLd", "Fne")
|
||||
BUILTIN(__builtin_ctanh, "XdXd", "Fne")
|
||||
BUILTIN(__builtin_ctanhf, "XfXf", "Fne")
|
||||
BUILTIN(__builtin_ctanhl, "XLdXLd", "Fne")
|
||||
|
||||
// FP Comparisons.
|
||||
BUILTIN(__builtin_isgreater , "i.", "Fnc")
|
||||
@ -700,6 +700,21 @@ BUILTIN(__atomic_signal_fence, "vi", "n")
|
||||
BUILTIN(__atomic_always_lock_free, "izvCD*", "n")
|
||||
BUILTIN(__atomic_is_lock_free, "izvCD*", "n")
|
||||
|
||||
// OpenCL 2.0 atomic builtins.
|
||||
ATOMIC_BUILTIN(__opencl_atomic_init, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_load, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_store, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_exchange, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_compare_exchange_strong, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_compare_exchange_weak, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_fetch_add, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_fetch_sub, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_fetch_and, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_fetch_or, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_fetch_xor, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_fetch_min, "v.", "t")
|
||||
ATOMIC_BUILTIN(__opencl_atomic_fetch_max, "v.", "t")
|
||||
|
||||
#undef ATOMIC_BUILTIN
|
||||
|
||||
// Non-overloaded atomic builtins.
|
||||
@ -717,6 +732,7 @@ 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(__annotation, "wC*.","n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
|
||||
LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
|
||||
LIBBUILTIN(_byteswap_ulong, "UNiUNi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
|
||||
@ -992,9 +1008,9 @@ LIBBUILTIN(modf, "ddd*", "fn", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(modff, "fff*", "fn", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(modfl, "LdLdLd*", "fn", "math.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(nan, "dcC*", "fnc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(nanf, "fcC*", "fnc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(nanl, "LdcC*", "fnc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(nan, "dcC*", "fUn", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(nanf, "fcC*", "fUn", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(nanl, "LdcC*", "fUn", "math.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(pow, "ddd", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(powf, "fff", "fne", "math.h", ALL_LANGUAGES)
|
||||
@ -1024,9 +1040,9 @@ LIBBUILTIN(atanh, "dd", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(atanhf, "ff", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(atanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(cbrt, "dd", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cbrtf, "ff", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cbrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cbrt, "dd", "fnc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cbrtf, "ff", "fnc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cbrtl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(ceil, "dd", "fnc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ceilf, "ff", "fnc", "math.h", ALL_LANGUAGES)
|
||||
@ -1146,6 +1162,10 @@ LIBBUILTIN(remainder, "ddd", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(remainderf, "fff", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(remainderl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(remquo, "dddi*", "fn", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(remquof, "fffi*", "fn", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(remquol, "LdLdLdi*", "fn", "math.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(rint, "dd", "fnc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(rintf, "ff", "fnc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(rintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
|
||||
@ -1190,49 +1210,49 @@ LIBBUILTIN(trunc, "dd", "fnc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(truncf, "ff", "fnc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(truncl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(cabs, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cabsf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cabsl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cabs, "dXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cabsf, "fXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cabsl, "LdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(cacos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cacosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cacosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cacos, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cacosf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cacosl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(cacosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cacoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cacoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cacosh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cacoshf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cacoshl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(carg, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cargf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cargl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(carg, "dXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cargf, "fXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cargl, "LdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(casin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(casinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(casinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(casin, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(casinf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(casinl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(casinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(casinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(casinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(casinh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(casinhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(casinhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(catan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(catanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(catanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(catan, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(catanf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(catanl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(catanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(catanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(catanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(catanh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(catanhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(catanhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(ccos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ccosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ccosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ccos, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ccosf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ccosl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(ccosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ccoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ccoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ccosh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ccoshf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ccoshl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(cexp, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cexpf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cexpl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cexp, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cexpf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cexpl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cimagf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
@ -1242,41 +1262,41 @@ LIBBUILTIN(conj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(conjf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(conjl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(clog, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(clogf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(clogl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(clog, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(clogf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(clogl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(cproj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cprojf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cprojl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(cpow, "XdXdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cpowf, "XfXfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cpowl, "XLdXLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cpow, "XdXdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cpowf, "XfXfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cpowl, "XLdXLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(csin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csin, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csinf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csinl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(csinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csinh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csinhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csinhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(csqrt, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csqrtf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csqrtl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csqrt, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csqrtf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(csqrtl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(ctan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ctanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ctanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ctan, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ctanf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ctanl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(ctanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ctanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ctanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ctanh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ctanhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ctanhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
|
||||
|
||||
// __sinpi and friends are OS X specific library functions, but otherwise much
|
||||
// like the standard (non-complex) sin (etc).
|
||||
@ -1398,18 +1418,29 @@ LANGBUILTIN(get_pipe_max_packets, "Ui.", "tn", OCLC20_LANG)
|
||||
// OpenCL v2.0 s6.13.17 - Enqueue kernel functions.
|
||||
// Custom builtin check allows to perform special check of passed block arguments.
|
||||
LANGBUILTIN(enqueue_kernel, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_kernel_work_group_size, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "i.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_kernel_work_group_size, "Ui.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "Ui.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_kernel_max_sub_group_size_for_ndrange, "Ui.", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(get_kernel_sub_group_count_for_ndrange, "Ui.", "tn", OCLC20_LANG)
|
||||
|
||||
// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
|
||||
LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG)
|
||||
LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG)
|
||||
|
||||
// OpenCL half load/store builtin
|
||||
LANGBUILTIN(__builtin_store_half, "vdh*", "n", ALL_OCLC_LANGUAGES)
|
||||
LANGBUILTIN(__builtin_store_halff, "vfh*", "n", ALL_OCLC_LANGUAGES)
|
||||
LANGBUILTIN(__builtin_load_half, "dhC*", "nc", ALL_OCLC_LANGUAGES)
|
||||
LANGBUILTIN(__builtin_load_halff, "fhC*", "nc", ALL_OCLC_LANGUAGES)
|
||||
|
||||
// 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")
|
||||
|
||||
// OpenMP 4.0
|
||||
LANGBUILTIN(omp_is_initial_device, "i", "nc", OMP_LANG)
|
||||
|
||||
// Builtins for XRay
|
||||
BUILTIN(__xray_customevent, "vcC*z", "")
|
||||
|
||||
|
@ -36,10 +36,13 @@ enum LanguageID {
|
||||
CXX_LANG = 0x4, // builtin for cplusplus only.
|
||||
OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
|
||||
MS_LANG = 0x10, // builtin requires MS mode.
|
||||
OCLC20_LANG = 0x20, // builtin for OpenCL C only.
|
||||
OCLC20_LANG = 0x20, // builtin for OpenCL C 2.0 only.
|
||||
OCLC1X_LANG = 0x40, // builtin for OpenCL C 1.x only.
|
||||
OMP_LANG = 0x80, // builtin requires OpenMP.
|
||||
ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
|
||||
ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode.
|
||||
ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode.
|
||||
ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG, // builtin requires MS mode.
|
||||
ALL_OCLC_LANGUAGES = OCLC1X_LANG | OCLC20_LANG // builtin for OCLC languages.
|
||||
};
|
||||
|
||||
namespace Builtin {
|
||||
|
@ -14,6 +14,10 @@
|
||||
|
||||
// The format of this database matches clang/Basic/Builtins.def.
|
||||
|
||||
#if defined(BUILTIN) && !defined(LANGBUILTIN)
|
||||
# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
|
||||
#endif
|
||||
|
||||
// In libgcc
|
||||
BUILTIN(__clear_cache, "vv*v*", "i")
|
||||
|
||||
@ -61,4 +65,9 @@ BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
|
||||
BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc")
|
||||
BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
|
||||
|
||||
LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
|
||||
|
||||
#undef BUILTIN
|
||||
#undef LANGBUILTIN
|
||||
|
@ -21,6 +21,7 @@
|
||||
// SI+ only builtins.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
BUILTIN(__builtin_amdgcn_dispatch_ptr, "Uc*2", "nc")
|
||||
BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "Uc*2", "nc")
|
||||
BUILTIN(__builtin_amdgcn_implicitarg_ptr, "Uc*2", "nc")
|
||||
|
||||
@ -120,6 +121,8 @@ TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
|
||||
// Special builtins.
|
||||
//===----------------------------------------------------------------------===//
|
||||
BUILTIN(__builtin_amdgcn_read_exec, "LUi", "nc")
|
||||
BUILTIN(__builtin_amdgcn_read_exec_lo, "Ui", "nc")
|
||||
BUILTIN(__builtin_amdgcn_read_exec_hi, "Ui", "nc")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// R600-NI only builtins.
|
||||
|
@ -36,6 +36,7 @@ BUILTIN(__builtin_arm_smulwt, "iii", "nc")
|
||||
// Saturating arithmetic
|
||||
BUILTIN(__builtin_arm_qadd, "iii", "nc")
|
||||
BUILTIN(__builtin_arm_qsub, "iii", "nc")
|
||||
BUILTIN(__builtin_arm_qdbl, "ii", "nc")
|
||||
BUILTIN(__builtin_arm_ssat, "iiUi", "nc")
|
||||
BUILTIN(__builtin_arm_usat, "UiiUi", "nc")
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
// The builtins below are not autogenerated from iset.py.
|
||||
// Make sure you do not overwrite these.
|
||||
|
||||
BUILTIN(__builtin_SI_to_SXTHI_asrh, "ii", "")
|
||||
BUILTIN(__builtin_brev_ldd, "LLi*LLi*LLi*i", "")
|
||||
BUILTIN(__builtin_brev_ldw, "i*i*i*i", "")
|
||||
BUILTIN(__builtin_brev_ldh, "s*s*s*i", "")
|
||||
@ -882,6 +881,7 @@ BUILTIN(__builtin_HEXAGON_S2_ct0p,"iLLi","")
|
||||
BUILTIN(__builtin_HEXAGON_S2_ct1p,"iLLi","")
|
||||
BUILTIN(__builtin_HEXAGON_S2_interleave,"LLiLLi","")
|
||||
BUILTIN(__builtin_HEXAGON_S2_deinterleave,"LLiLLi","")
|
||||
BUILTIN(__builtin_HEXAGON_prefetch,"vv*","")
|
||||
BUILTIN(__builtin_HEXAGON_Y2_dccleana,"vv*","")
|
||||
BUILTIN(__builtin_HEXAGON_Y2_dccleaninva,"vv*","")
|
||||
BUILTIN(__builtin_HEXAGON_Y2_dcinva,"vv*","")
|
||||
@ -1470,14 +1470,6 @@ BUILTIN(__builtin_HEXAGON_V6_vassign,"V16iV16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vassign_128B,"V32iV32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vcombine,"V32iV16iV16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vcombine_128B,"V64iV32iV32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutb,"V16iV16iLLii","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutb_128B,"V32iV32iLLii","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutb_acc,"V16iV16iV16iLLii","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutb_acc_128B,"V32iV32iV32iLLii","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutb_dv,"V32iV32iLLii","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutb_dv_128B,"V64iV64iLLii","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutb_dv_acc,"V32iV32iV32iLLii","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutb_dv_acc_128B,"V64iV64iV64iLLii","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vdelta,"V16iV16iV16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vdelta_128B,"V32iV32iV32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrdelta,"V16iV16iV16i","v:60:")
|
||||
@ -1508,4 +1500,216 @@ BUILTIN(__builtin_HEXAGON_V6_lo_128B,"V32iV64i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vassignp,"V32iV32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vassignp_128B,"V64iV64i","v:60:")
|
||||
|
||||
BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai,"vV16iv*V16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai,"vV16iv*V16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai,"vV16iv*V16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai,"vV16iv*V16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai_128B,"vV32iv*V32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai_128B,"vV32iv*V32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai_128B,"vV32iv*V32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai_128B,"vV32iv*V32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq,"vV16iv*V16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq,"vV16iv*V16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq,"vV16iv*V16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq,"vV16iv*V16i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq_128B,"vV32iv*V32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq_128B,"vV32iv*V32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq_128B,"vV32iv*V32i","v:60:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq_128B,"vV32iv*V32i","v:60:")
|
||||
|
||||
BUILTIN(__builtin_HEXAGON_M6_vabsdiffb,"LLiLLiLLi","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_M6_vabsdiffub,"LLiLLiLLi","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_A6_vminub_RdP,"LLiLLiLLi","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_S6_vsplatrbp,"LLii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_S6_vtrunehb_ppp,"LLiLLiLLi","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_S6_vtrunohb_ppp,"LLiLLiLLi","v:62:")
|
||||
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlsrb,"V16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlsrb_128B,"V32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat,"V16iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat_128B,"V32iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat,"V16iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat_128B,"V32iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasrhbsat,"V16iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasrhbsat_128B,"V32iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrounduwuh,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrounduwuh_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrounduhub,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrounduhub_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vadduwsat,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vadduwsat_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv_128B,"V64iV64iV64i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubuwsat,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv_128B,"V64iV64iV64i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddbsat,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddbsat_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv_128B,"V64iV64iV64i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubbsat,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubbsat_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv_128B,"V64iV64iV64i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc,"V32iV32iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc_128B,"V64iV64iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc,"V32iV32iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc_128B,"V64iV64iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc,"V32iV32iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc_128B,"V64iV64iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64,"V32iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64_128B,"V64iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc,"V32iV32iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc_128B,"V64iV64iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpauhb,"V32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpauhb_128B,"V64iV64ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc,"V32iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc_128B,"V64iV64iV64ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyiwub,"V16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_128B,"V32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc,"V16iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc_128B,"V32iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vandnqrt,"V16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vandnqrt_128B,"V32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc,"V16iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc_128B,"V32iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vandvqv,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vandvqv_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vandvnqv,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vandvnqv_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2,"V16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2_128B,"V32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_shuffeqw,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_shuffeqw_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_shuffeqh,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_shuffeqh_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmaxb,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmaxb_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vminb,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vminb_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsatuwuh,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsatuwuh_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_lvsplath,"V16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_lvsplath_128B,"V32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_lvsplatb,"V16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_lvsplatb_128B,"V32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddclbw,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddclbw_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddclbh,"V16iV16iV16i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddclbh_128B,"V32iV32iV32i","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvvbi,"V16iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvvbi_128B,"V32iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci,"V16iV16iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci_128B,"V32iV32iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvwhi,"V32iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvwhi_128B,"V64iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci,"V32iV32iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci_128B,"V64iV64iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm,"V16iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm_128B,"V32iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm,"V32iV16iV16ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm_128B,"V64iV32iV32ii","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddcarry,"V16iV16iV16iv*","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaddcarry_128B,"V32iV32iV32iv*","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubcarry,"V16iV16iV16iv*","v:62:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vsubcarry_128B,"V32iV32iV32iv*","v:62:")
|
||||
|
||||
BUILTIN(__builtin_HEXAGON_A6_vcmpbeq_notany,"iLLiLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_A6_vcmpbeq_notany_128B,"iLLiLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt,"V32iV16iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_128B,"V64iV32iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc,"V32iV32iV16iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt,"V32iV16iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_128B,"V64iV32iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc,"V32iV32iV16iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc_128B,"V64iV64iV32iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat,"V16iV16iV16ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat_128B,"V32iV32iV32ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasruhubsat,"V16iV16iV16ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasruhubsat_128B,"V32iV32iV32ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat,"V16iV16iV16ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat_128B,"V32iV32iV32ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaslh_acc,"V16iV16iV16ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vaslh_acc_128B,"V32iV32iV32ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasrh_acc,"V16iV16iV16ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vasrh_acc_128B,"V32iV32iV32ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vavguw,"V16iV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vavguw_128B,"V32iV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vavguwrnd,"V16iV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vavguwrnd_128B,"V32iV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vavgb,"V16iV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vavgb_128B,"V32iV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vavgbrnd,"V16iV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vavgbrnd_128B,"V32iV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vnavgb,"V16iV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vnavgb_128B,"V32iV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vabsb,"V16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vabsb_128B,"V32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vabsb_sat,"V16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vabsb_sat_128B,"V32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpabuu,"V32iV32ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpabuu_128B,"V64iV64ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc,"V32iV32iV32ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc_128B,"V64iV64iV64ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc,"V32iV32iV16ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc_128B,"V64iV64iV32ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpahhsat,"V16iV16iV16iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpahhsat_128B,"V32iV32iV32iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat,"V16iV16iV16iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat_128B,"V32iV32iV32iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat,"V16iV16iV16iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat_128B,"V32iV32iV32iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlut4,"V16iV16iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vlut4_128B,"V32iV32iLLi","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyuhe,"V16iV16ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_128B,"V32iV32ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc,"V16iV16iV16ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc_128B,"V32iV32iV32ii","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermw,"vv*iiV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermw_128B,"vv*iiV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermh,"vv*iiV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermh_128B,"vv*iiV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermhw,"vv*iiV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermhw_128B,"vv*iiV64i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermwq,"vv*V16iiiV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermwq_128B,"vv*V32iiiV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermhq,"vv*V16iiiV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermhq_128B,"vv*V32iiiV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermhwq,"vv*V16iiiV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vgathermhwq_128B,"vv*V32iiiV64i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermw,"viiV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermw_128B,"viiV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermh,"viiV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermh_128B,"viiV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermw_add,"viiV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermw_add_128B,"viiV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermh_add,"viiV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermh_add_128B,"viiV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermwq,"vV16iiiV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermwq_128B,"vV32iiiV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermhq,"vV16iiiV16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermhq_128B,"vV32iiiV32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermhw,"viiV32iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermhw_128B,"viiV64iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermhwq,"vV16iiiV32iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermhwq_128B,"vV32iiiV64iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add,"viiV32iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add_128B,"viiV64iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vprefixqb,"V16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vprefixqb_128B,"V32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vprefixqh,"V16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vprefixqh_128B,"V32iV32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vprefixqw,"V16iV16i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vprefixqw_128B,"V32iV32i","v:65:")
|
||||
|
||||
BUILTIN(__builtin_HEXAGON_V6_vdd0,"V32i","v:65:")
|
||||
BUILTIN(__builtin_HEXAGON_V6_vdd0_128B,"V64i","v:65:")
|
||||
|
||||
|
||||
#undef BUILTIN
|
||||
|
@ -371,6 +371,9 @@ BUILTIN(__nvvm_bitcast_i2f, "fi", "")
|
||||
BUILTIN(__nvvm_bitcast_ll2d, "dLLi", "")
|
||||
BUILTIN(__nvvm_bitcast_d2ll, "LLid", "")
|
||||
|
||||
// FNS
|
||||
TARGET_BUILTIN(__nvvm_fns, "UiUiUii", "n", "ptx60")
|
||||
|
||||
// Sync
|
||||
|
||||
BUILTIN(__syncthreads, "v", "")
|
||||
@ -378,6 +381,9 @@ BUILTIN(__nvvm_bar0_popc, "ii", "")
|
||||
BUILTIN(__nvvm_bar0_and, "ii", "")
|
||||
BUILTIN(__nvvm_bar0_or, "ii", "")
|
||||
BUILTIN(__nvvm_bar_sync, "vi", "n")
|
||||
TARGET_BUILTIN(__nvvm_bar_warp_sync, "vUi", "n", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_barrier_sync, "vUi", "n", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_barrier_sync_cnt, "vUiUi", "n", "ptx60")
|
||||
|
||||
// Shuffle
|
||||
|
||||
@ -390,6 +396,33 @@ BUILTIN(__nvvm_shfl_bfly_f32, "ffii", "")
|
||||
BUILTIN(__nvvm_shfl_idx_i32, "iiii", "")
|
||||
BUILTIN(__nvvm_shfl_idx_f32, "ffii", "")
|
||||
|
||||
TARGET_BUILTIN(__nvvm_shfl_sync_down_i32, "iUiiii", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_shfl_sync_down_f32, "fUifii", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_shfl_sync_up_i32, "iUiiii", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_shfl_sync_up_f32, "fUifii", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_shfl_sync_bfly_i32, "iUiiii", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_shfl_sync_bfly_f32, "fUifii", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_shfl_sync_idx_i32, "iUiiii", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_shfl_sync_idx_f32, "fUifii", "", "ptx60")
|
||||
|
||||
// Vote
|
||||
BUILTIN(__nvvm_vote_all, "bb", "")
|
||||
BUILTIN(__nvvm_vote_any, "bb", "")
|
||||
BUILTIN(__nvvm_vote_uni, "bb", "")
|
||||
BUILTIN(__nvvm_vote_ballot, "Uib", "")
|
||||
|
||||
TARGET_BUILTIN(__nvvm_vote_all_sync, "bUib", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_vote_any_sync, "bUib", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_vote_uni_sync, "bUib", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_vote_ballot_sync, "UiUib", "", "ptx60")
|
||||
|
||||
// Match
|
||||
TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_match_any_sync_i64, "WiUiWi", "", "ptx60")
|
||||
// These return a pair {value, predicate}, which requires custom lowering.
|
||||
TARGET_BUILTIN(__nvvm_match_all_sync_i32p, "UiUiUii*", "", "ptx60")
|
||||
TARGET_BUILTIN(__nvvm_match_all_sync_i64p, "WiUiWii*", "", "ptx60")
|
||||
|
||||
// Membar
|
||||
|
||||
BUILTIN(__nvvm_membar_cta, "v", "")
|
||||
@ -451,7 +484,7 @@ 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_add_gen_d, "ddD*d", "n", "satom")
|
||||
TARGET_BUILTIN(__nvvm_atom_cta_add_gen_d, "ddD*d", "n", "satom")
|
||||
TARGET_BUILTIN(__nvvm_atom_sys_add_gen_d, "ddD*d", "n", "satom")
|
||||
|
||||
@ -658,5 +691,18 @@ BUILTIN(__nvvm_ldg_f2, "E2fE2fC*", "")
|
||||
BUILTIN(__nvvm_ldg_f4, "E4fE4fC*", "")
|
||||
BUILTIN(__nvvm_ldg_d2, "E2dE2dC*", "")
|
||||
|
||||
// Builtins to support WMMA instructions on sm_70
|
||||
TARGET_BUILTIN(__hmma_m16n16k16_ld_a, "vi*iC*UiIi", "", "ptx60")
|
||||
TARGET_BUILTIN(__hmma_m16n16k16_ld_b, "vi*iC*UiIi", "", "ptx60")
|
||||
TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f16, "vi*iC*UiIi", "", "ptx60")
|
||||
TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f32, "vf*fC*UiIi", "", "ptx60")
|
||||
TARGET_BUILTIN(__hmma_m16n16k16_st_c_f16, "vi*i*UiIi", "", "ptx60")
|
||||
TARGET_BUILTIN(__hmma_m16n16k16_st_c_f32, "vf*f*UiIi", "", "ptx60")
|
||||
|
||||
TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f16, "vi*iC*iC*iC*IiIi", "", "ptx60")
|
||||
TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", "ptx60")
|
||||
TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", "ptx60")
|
||||
TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", "ptx60")
|
||||
|
||||
#undef BUILTIN
|
||||
#undef TARGET_BUILTIN
|
||||
|
@ -32,7 +32,9 @@
|
||||
// Miscellaneous builtin for checking x86 cpu features.
|
||||
// TODO: Make this somewhat generic so that other backends
|
||||
// can use it?
|
||||
BUILTIN(__builtin_cpu_init, "v", "n")
|
||||
BUILTIN(__builtin_cpu_supports, "bcC*", "nc")
|
||||
BUILTIN(__builtin_cpu_is, "bcC*", "nc")
|
||||
|
||||
// Undefined Values
|
||||
//
|
||||
@ -264,8 +266,6 @@ TARGET_BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "", "sse2")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "", "sse2")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "", "sse2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "", "sse2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "", "sse2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "", "sse2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "", "sse2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "", "sse2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "", "sse2")
|
||||
@ -520,8 +520,6 @@ TARGET_BUILTIN(__builtin_ia32_paddusw256, "V16sV16sV16s", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubusb256, "V32cV32cV32c", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIi", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_phaddd256, "V8iV8iV8i", "", "avx2")
|
||||
@ -640,8 +638,21 @@ TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "", "xsaves")
|
||||
TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "", "xsavec")
|
||||
TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves")
|
||||
|
||||
// SHSTK
|
||||
TARGET_BUILTIN(__builtin_ia32_incsspd, "vUi", "u", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_rdsspd, "UiUi", "Un", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_saveprevssp, "v", "", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_rstorssp, "vv*", "", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_wrssd, "vUiv*", "", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_wrussd, "vUiv*", "", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_setssbsy, "v", "", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_clrssbsy, "vv*", "", "shstk")
|
||||
|
||||
//CLFLUSHOPT
|
||||
TARGET_BUILTIN(__builtin_ia32_clflushopt, "vc*", "", "clflushopt")
|
||||
TARGET_BUILTIN(__builtin_ia32_clflushopt, "vvC*", "", "clflushopt")
|
||||
|
||||
//CLWB
|
||||
TARGET_BUILTIN(__builtin_ia32_clwb, "vvC*", "", "clwb")
|
||||
|
||||
// ADX
|
||||
TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx")
|
||||
@ -681,36 +692,18 @@ TARGET_BUILTIN(__builtin_ia32_sha256msg2, "V4iV4iV4i", "", "sha")
|
||||
// FMA
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmsubps, "V4fV4fV4fV4f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmsubpd, "V2dV2dV2dV2d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmsubss, "V4fV4fV4fV4f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmsubsd, "V2dV2dV2dV2d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmaddps, "V4fV4fV4fV4f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmaddss, "V4fV4fV4fV4f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmaddsd, "V2dV2dV2dV2d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmsubps, "V4fV4fV4fV4f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmsubpd, "V2dV2dV2dV2d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmsubss, "V4fV4fV4fV4f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmsubsd, "V2dV2dV2dV2d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddss3, "V4fV4fV4fV4f", "", "fma")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddsd3, "V2dV2dV2dV2d", "", "fma")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "", "fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "", "fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddsubps, "V4fV4fV4fV4f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd, "V2dV2dV2dV2d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmsubaddps, "V4fV4fV4fV4f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddpd256, "V4dV4dV4dV4d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmsubpd256, "V4dV4dV4dV4d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmaddpd256, "V4dV4dV4dV4d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfnmsubpd256, "V4dV4dV4dV4d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmsubaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd256, "V4dV4dV4dV4d", "", "fma|fma4")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl")
|
||||
@ -909,39 +902,10 @@ TARGET_BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "", "avx512
|
||||
TARGET_BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "", "avx512f")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_cmpps256_mask, "UcV8fV8fIiUc", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "", "avx512vl")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqb512_mask, "LLiV64cV64cLLi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqd512_mask, "sV16iV16is", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqq512_mask, "cV8LLiV8LLic", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqw512_mask, "iV32sV32si", "", "avx512bw")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqb256_mask, "iV32cV32ci", "", "avx512vl,avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqd256_mask, "cV8iV8ic", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqq256_mask, "cV4LLiV4LLic", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqw256_mask, "sV16sV16ss", "", "avx512vl,avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqb128_mask, "sV16cV16cs", "", "avx512vl,avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqd128_mask, "cV4iV4ic", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqq128_mask, "cV2LLiV2LLic", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpeqw128_mask, "cV8sV8sc", "", "avx512vl,avx512bw")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtb512_mask, "LLiV64cV64cLLi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtd512_mask, "sV16iV16is", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtq512_mask, "cV8LLiV8LLic", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtw512_mask, "iV32sV32si", "", "avx512bw")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtb256_mask, "iV32cV32ci", "", "avx512vl,avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtd256_mask, "cV8iV8ic", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtq256_mask, "cV4LLiV4LLic", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtw256_mask, "sV16sV16ss", "", "avx512vl,avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtb128_mask, "sV16cV16cs", "", "avx512vl,avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtd128_mask, "cV4iV4ic", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtq128_mask, "cV2LLiV2LLic", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pcmpgtw128_mask, "cV8sV8sc", "", "avx512vl,avx512bw")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "", "avx512vl")
|
||||
@ -973,9 +937,6 @@ TARGET_BUILTIN(__builtin_ia32_pminud512_mask, "V16iV16iV16iV16iUs", "", "avx512f
|
||||
TARGET_BUILTIN(__builtin_ia32_pminuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "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_loaddqusi512_mask, "V16iiC*V16iUs", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "", "avx512f")
|
||||
@ -1072,8 +1033,6 @@ TARGET_BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "", "avx51
|
||||
TARGET_BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddusw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pavgb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pavgw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmaxsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmaxsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmaxub512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
|
||||
@ -1101,6 +1060,10 @@ 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_vpopcntd_128, "V4iV4i", "", "avx512vpopcntdq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpopcntq_128, "V2LLiV2LLi", "", "avx512vpopcntdq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpopcntd_256, "V8iV8i", "", "avx512vpopcntdq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpopcntq_256, "V4LLiV4LLi", "", "avx512vpopcntdq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpopcntd_512, "V16iV16i", "", "avx512vpopcntdq")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8LLiV8LLi", "", "avx512vpopcntdq")
|
||||
|
||||
@ -1378,11 +1341,6 @@ TARGET_BUILTIN(__builtin_ia32_movdqa64load128_mask, "V2LLiV2LLiC*V2LLiUc","","av
|
||||
TARGET_BUILTIN(__builtin_ia32_movdqa64load256_mask, "V4LLiV4LLiC*V4LLiUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2LLi*V2LLiUc","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4LLi*V4LLiUc","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_pbroadcastb512_gpr_mask, "V64ccV64cULLi","","avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pbroadcastb128_gpr_mask, "V16ccV16cUs","","avx512bw,avx512vl")
|
||||
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_vpmadd52huq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
|
||||
@ -1494,28 +1452,6 @@ TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_maskz, "V16iV16iV16iV16iUs","","avx
|
||||
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_ptestmb512, "ULLiV64cV64cULLi","","avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestmw512, "UiV32sV32sUi","","avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmb512, "ULLiV64cV64cULLi","","avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmw512, "UiV32sV32sUi","","avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestmb128, "UsV16cV16cUs","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestmb256, "UiV32cV32cUi","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestmw128, "UcV8sV8sUc","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestmw256, "UsV16sV16sUs","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmb128, "UsV16cV16cUs","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmb256, "UiV32cV32cUi","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmw128, "UcV8sV8sUc","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmw256, "UsV16sV16sUs","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestmd128, "UcV4iV4iUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestmd256, "UcV8iV8iUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestmq128, "UcV2LLiV2LLiUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestmq256, "UcV4LLiV4LLiUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmd128, "UcV4iV4iUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmd256, "UcV8iV8iUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmq128, "UcV2LLiV2LLiUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmq256, "UcV4LLiV4LLiUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmd512, "UsV16iV16iUs","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnmq512, "UcV8LLiV8LLiUc","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_rndscalesd_round_mask, "V2dV2dV2dV2dUcIiIi","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_rndscaless_round_mask, "V4fV4fV4fV4fUcIiIi","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scalefpd512_mask, "V8dV8dV8dV8dUcIi","","avx512f")
|
||||
@ -1587,20 +1523,6 @@ TARGET_BUILTIN(__builtin_ia32_cvtmask2q128, "V2LLiUc","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_cvtmask2q256, "V4LLiUc","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmb512, "V8LLiUc","","avx512cd")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmw512, "V16iUs","","avx512cd")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmb128, "V2LLiUc","","avx512cd,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmb256, "V4LLiUc","","avx512cd,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmw128, "V4iUs","","avx512cd,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmw256, "V8iUs","","avx512cd,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_512_mask, "V16fV4fV16fUs","","avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_512_mask, "V16iV4iV16iUs","","avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_256_mask, "V8fV4fV8fUc","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_128_mask, "V4iV4iV4iUc","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_256_mask, "V8iV4iV8iUc","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pbroadcastw512_gpr_mask, "V32shV32sUi","","avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pbroadcastw256_gpr_mask, "V16shV16sUs","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pbroadcastw128_gpr_mask, "V8ssV8sUc","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmovsdb512_mask, "V16cV16iV16cUs","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmovswb512mem_mask, "vV32c*V32sUi","","avx512bw")
|
||||
|
@ -40,6 +40,7 @@ TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h"
|
||||
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_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "cx16")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "")
|
||||
TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "")
|
||||
@ -60,6 +61,10 @@ 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_incsspq, "vULLi", "u", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_rdsspq, "ULLiULLi", "Un", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_wrssq, "vULLiv*", "", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_wrussq, "vULLiv*", "", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx")
|
||||
TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "")
|
||||
TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "")
|
||||
@ -71,9 +76,6 @@ TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "", "bmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "", "tbm")
|
||||
TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcULLiUiUi", "", "lwp")
|
||||
TARGET_BUILTIN(__builtin_ia32_lwpval64, "vULLiUiUi", "", "lwp")
|
||||
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")
|
||||
|
@ -40,14 +40,14 @@ namespace charinfo {
|
||||
} // end namespace charinfo
|
||||
|
||||
/// Returns true if this is an ASCII character.
|
||||
LLVM_READNONE static inline bool isASCII(char c) {
|
||||
LLVM_READNONE inline bool isASCII(char c) {
|
||||
return static_cast<unsigned char>(c) <= 127;
|
||||
}
|
||||
|
||||
/// Returns true if this is a valid first character of a C identifier,
|
||||
/// which is [a-zA-Z_].
|
||||
LLVM_READONLY static inline bool isIdentifierHead(unsigned char c,
|
||||
bool AllowDollar = false) {
|
||||
LLVM_READONLY inline bool isIdentifierHead(unsigned char c,
|
||||
bool AllowDollar = false) {
|
||||
using namespace charinfo;
|
||||
if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_UNDER))
|
||||
return true;
|
||||
@ -56,8 +56,8 @@ LLVM_READONLY static inline bool isIdentifierHead(unsigned char c,
|
||||
|
||||
/// Returns true if this is a body character of a C identifier,
|
||||
/// which is [a-zA-Z0-9_].
|
||||
LLVM_READONLY static inline bool isIdentifierBody(unsigned char c,
|
||||
bool AllowDollar = false) {
|
||||
LLVM_READONLY inline bool isIdentifierBody(unsigned char c,
|
||||
bool AllowDollar = false) {
|
||||
using namespace charinfo;
|
||||
if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER))
|
||||
return true;
|
||||
@ -68,7 +68,7 @@ LLVM_READONLY static inline bool isIdentifierBody(unsigned char c,
|
||||
/// ' ', '\\t', '\\f', '\\v'.
|
||||
///
|
||||
/// Note that this returns false for '\\0'.
|
||||
LLVM_READONLY static inline bool isHorizontalWhitespace(unsigned char c) {
|
||||
LLVM_READONLY inline bool isHorizontalWhitespace(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_SPACE)) != 0;
|
||||
}
|
||||
@ -76,7 +76,7 @@ LLVM_READONLY static inline bool isHorizontalWhitespace(unsigned char c) {
|
||||
/// Returns true if this character is vertical ASCII whitespace: '\\n', '\\r'.
|
||||
///
|
||||
/// Note that this returns false for '\\0'.
|
||||
LLVM_READONLY static inline bool isVerticalWhitespace(unsigned char c) {
|
||||
LLVM_READONLY inline bool isVerticalWhitespace(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & CHAR_VERT_WS) != 0;
|
||||
}
|
||||
@ -85,43 +85,43 @@ LLVM_READONLY static inline bool isVerticalWhitespace(unsigned char c) {
|
||||
/// ' ', '\\t', '\\f', '\\v', '\\n', '\\r'.
|
||||
///
|
||||
/// Note that this returns false for '\\0'.
|
||||
LLVM_READONLY static inline bool isWhitespace(unsigned char c) {
|
||||
LLVM_READONLY inline bool isWhitespace(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_VERT_WS|CHAR_SPACE)) != 0;
|
||||
}
|
||||
|
||||
/// Return true if this character is an ASCII digit: [0-9]
|
||||
LLVM_READONLY static inline bool isDigit(unsigned char c) {
|
||||
LLVM_READONLY inline bool isDigit(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & CHAR_DIGIT) != 0;
|
||||
}
|
||||
|
||||
/// Return true if this character is a lowercase ASCII letter: [a-z]
|
||||
LLVM_READONLY static inline bool isLowercase(unsigned char c) {
|
||||
LLVM_READONLY inline bool isLowercase(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & CHAR_LOWER) != 0;
|
||||
}
|
||||
|
||||
/// Return true if this character is an uppercase ASCII letter: [A-Z]
|
||||
LLVM_READONLY static inline bool isUppercase(unsigned char c) {
|
||||
LLVM_READONLY inline bool isUppercase(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & CHAR_UPPER) != 0;
|
||||
}
|
||||
|
||||
/// Return true if this character is an ASCII letter: [a-zA-Z]
|
||||
LLVM_READONLY static inline bool isLetter(unsigned char c) {
|
||||
LLVM_READONLY inline bool isLetter(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER)) != 0;
|
||||
}
|
||||
|
||||
/// Return true if this character is an ASCII letter or digit: [a-zA-Z0-9]
|
||||
LLVM_READONLY static inline bool isAlphanumeric(unsigned char c) {
|
||||
LLVM_READONLY inline bool isAlphanumeric(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & (CHAR_DIGIT|CHAR_UPPER|CHAR_LOWER)) != 0;
|
||||
}
|
||||
|
||||
/// Return true if this character is an ASCII hex digit: [0-9a-fA-F]
|
||||
LLVM_READONLY static inline bool isHexDigit(unsigned char c) {
|
||||
LLVM_READONLY inline bool isHexDigit(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & (CHAR_DIGIT|CHAR_XLETTER)) != 0;
|
||||
}
|
||||
@ -129,7 +129,7 @@ LLVM_READONLY static inline bool isHexDigit(unsigned char c) {
|
||||
/// Return true if this character is an ASCII punctuation character.
|
||||
///
|
||||
/// Note that '_' is both a punctuation character and an identifier character!
|
||||
LLVM_READONLY static inline bool isPunctuation(unsigned char c) {
|
||||
LLVM_READONLY inline bool isPunctuation(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & (CHAR_UNDER|CHAR_PERIOD|CHAR_RAWDEL|CHAR_PUNCT)) != 0;
|
||||
}
|
||||
@ -137,7 +137,7 @@ LLVM_READONLY static inline bool isPunctuation(unsigned char c) {
|
||||
/// Return true if this character is an ASCII printable character; that is, a
|
||||
/// character that should take exactly one column to print in a fixed-width
|
||||
/// terminal.
|
||||
LLVM_READONLY static inline bool isPrintable(unsigned char c) {
|
||||
LLVM_READONLY inline bool isPrintable(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|CHAR_PUNCT|
|
||||
CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL|CHAR_SPACE)) != 0;
|
||||
@ -145,14 +145,14 @@ LLVM_READONLY static inline bool isPrintable(unsigned char c) {
|
||||
|
||||
/// Return true if this is the body character of a C preprocessing number,
|
||||
/// which is [a-zA-Z0-9_.].
|
||||
LLVM_READONLY static inline bool isPreprocessingNumberBody(unsigned char c) {
|
||||
LLVM_READONLY inline bool isPreprocessingNumberBody(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] &
|
||||
(CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER|CHAR_PERIOD)) != 0;
|
||||
}
|
||||
|
||||
/// Return true if this is the body character of a C++ raw string delimiter.
|
||||
LLVM_READONLY static inline bool isRawStringDelimBody(unsigned char c) {
|
||||
LLVM_READONLY inline bool isRawStringDelimBody(unsigned char c) {
|
||||
using namespace charinfo;
|
||||
return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|
|
||||
CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL)) != 0;
|
||||
@ -162,7 +162,7 @@ LLVM_READONLY static inline bool isRawStringDelimBody(unsigned char c) {
|
||||
/// Converts the given ASCII character to its lowercase equivalent.
|
||||
///
|
||||
/// If the character is not an uppercase character, it is returned as is.
|
||||
LLVM_READONLY static inline char toLowercase(char c) {
|
||||
LLVM_READONLY inline char toLowercase(char c) {
|
||||
if (isUppercase(c))
|
||||
return c + 'a' - 'A';
|
||||
return c;
|
||||
@ -171,7 +171,7 @@ LLVM_READONLY static inline char toLowercase(char c) {
|
||||
/// Converts the given ASCII character to its uppercase equivalent.
|
||||
///
|
||||
/// If the character is not a lowercase character, it is returned as is.
|
||||
LLVM_READONLY static inline char toUppercase(char c) {
|
||||
LLVM_READONLY inline char toUppercase(char c) {
|
||||
if (isLowercase(c))
|
||||
return c + 'A' - 'a';
|
||||
return c;
|
||||
@ -182,7 +182,7 @@ LLVM_READONLY static inline char toUppercase(char c) {
|
||||
///
|
||||
/// Note that this is a very simple check; it does not accept '$' or UCNs as
|
||||
/// valid identifier characters.
|
||||
LLVM_READONLY static inline bool isValidIdentifier(StringRef S) {
|
||||
LLVM_READONLY inline bool isValidIdentifier(StringRef S) {
|
||||
if (S.empty() || !isIdentifierHead(S[0]))
|
||||
return false;
|
||||
|
||||
|
@ -21,6 +21,8 @@ enum class CudaVersion {
|
||||
CUDA_70,
|
||||
CUDA_75,
|
||||
CUDA_80,
|
||||
CUDA_90,
|
||||
LATEST = CUDA_90,
|
||||
};
|
||||
const char *CudaVersionToString(CudaVersion V);
|
||||
|
||||
@ -41,6 +43,7 @@ enum class CudaArch {
|
||||
SM_60,
|
||||
SM_61,
|
||||
SM_62,
|
||||
SM_70,
|
||||
};
|
||||
const char *CudaArchToString(CudaArch A);
|
||||
|
||||
@ -60,6 +63,7 @@ enum class CudaVirtualArch {
|
||||
COMPUTE_60,
|
||||
COMPUTE_61,
|
||||
COMPUTE_62,
|
||||
COMPUTE_70,
|
||||
};
|
||||
const char *CudaVirtualArchToString(CudaVirtualArch A);
|
||||
|
||||
@ -72,6 +76,9 @@ CudaVirtualArch VirtualArchForCudaArch(CudaArch A);
|
||||
/// Get the earliest CudaVersion that supports the given CudaArch.
|
||||
CudaVersion MinVersionForCudaArch(CudaArch A);
|
||||
|
||||
/// Get the latest CudaVersion that supports the given CudaArch.
|
||||
CudaVersion MaxVersionForCudaArch(CudaArch A);
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -1,66 +1,68 @@
|
||||
class AttrSubject;
|
||||
|
||||
class Decl<bit abstract = 0> : AttrSubject {
|
||||
class Decl<string diagSpelling = "", bit abstract = 0> : AttrSubject {
|
||||
bit Abstract = abstract;
|
||||
string DiagSpelling = diagSpelling;
|
||||
}
|
||||
|
||||
class DDecl<Decl base, bit abstract = 0> : Decl<abstract> {
|
||||
class DDecl<Decl base, string diagSpelling = "", bit abstract = 0>
|
||||
: Decl<diagSpelling, abstract> {
|
||||
Decl Base = base;
|
||||
}
|
||||
|
||||
class DeclContext { }
|
||||
class DeclContext {}
|
||||
|
||||
def TranslationUnit : Decl, DeclContext;
|
||||
def PragmaComment : Decl;
|
||||
def PragmaDetectMismatch : Decl;
|
||||
def ExternCContext : Decl, DeclContext;
|
||||
def Named : Decl<1>;
|
||||
def Namespace : DDecl<Named>, DeclContext;
|
||||
def Named : Decl<"named declarations", 1>;
|
||||
def Namespace : DDecl<Named, "namespaces">, DeclContext;
|
||||
def UsingDirective : DDecl<Named>;
|
||||
def NamespaceAlias : DDecl<Named>;
|
||||
def Label : DDecl<Named>;
|
||||
def Type : DDecl<Named, 1>;
|
||||
def TypedefName : DDecl<Type, 1>;
|
||||
def Label : DDecl<Named, "labels">;
|
||||
def Type : DDecl<Named, "types", 1>;
|
||||
def TypedefName : DDecl<Type, "typedefs", 1>;
|
||||
def Typedef : DDecl<TypedefName>;
|
||||
def TypeAlias : DDecl<TypedefName>;
|
||||
def ObjCTypeParam : DDecl<TypedefName>;
|
||||
def UnresolvedUsingTypename : DDecl<Type>;
|
||||
def Tag : DDecl<Type, 1>, DeclContext;
|
||||
def Enum : DDecl<Tag>;
|
||||
def Record : DDecl<Tag>;
|
||||
def CXXRecord : DDecl<Record>;
|
||||
def Tag : DDecl<Type, "tag types", 1>, DeclContext;
|
||||
def Enum : DDecl<Tag, "enums">;
|
||||
def Record : DDecl<Tag, "structs, unions, classes">;
|
||||
def CXXRecord : DDecl<Record, "classes">;
|
||||
def ClassTemplateSpecialization : DDecl<CXXRecord>;
|
||||
def ClassTemplatePartialSpecialization
|
||||
: DDecl<ClassTemplateSpecialization>;
|
||||
def TemplateTypeParm : DDecl<Type>;
|
||||
def Value : DDecl<Named, 1>;
|
||||
def EnumConstant : DDecl<Value>;
|
||||
def Value : DDecl<Named, "value declarations", 1>;
|
||||
def EnumConstant : DDecl<Value, "enumerators">;
|
||||
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>;
|
||||
def Declarator : DDecl<Value, "declarators", 1>;
|
||||
def Field : DDecl<Declarator, "non-static data members">;
|
||||
def ObjCIvar : DDecl<Field>;
|
||||
def ObjCAtDefsField : DDecl<Field>;
|
||||
def MSProperty : DDecl<Declarator>;
|
||||
def Function : DDecl<Declarator>, DeclContext;
|
||||
def Function : DDecl<Declarator, "functions">, DeclContext;
|
||||
def CXXDeductionGuide : DDecl<Function>;
|
||||
def CXXMethod : DDecl<Function>;
|
||||
def CXXConstructor : DDecl<CXXMethod>;
|
||||
def CXXDestructor : DDecl<CXXMethod>;
|
||||
def CXXConversion : DDecl<CXXMethod>;
|
||||
def Var : DDecl<Declarator>;
|
||||
def Var : DDecl<Declarator, "variables">;
|
||||
def VarTemplateSpecialization : DDecl<Var>;
|
||||
def VarTemplatePartialSpecialization
|
||||
: DDecl<VarTemplateSpecialization>;
|
||||
def ImplicitParam : DDecl<Var>;
|
||||
def ParmVar : DDecl<Var>;
|
||||
def ParmVar : DDecl<Var, "parameters">;
|
||||
def Decomposition : DDecl<Var>;
|
||||
def OMPCapturedExpr : DDecl<Var>;
|
||||
def NonTypeTemplateParm : DDecl<Declarator>;
|
||||
def Template : DDecl<Named, 1>;
|
||||
def RedeclarableTemplate : DDecl<Template, 1>;
|
||||
def Template : DDecl<Named, "templates", 1>;
|
||||
def RedeclarableTemplate : DDecl<Template, "redeclarable templates", 1>;
|
||||
def FunctionTemplate : DDecl<RedeclarableTemplate>;
|
||||
def ClassTemplate : DDecl<RedeclarableTemplate>;
|
||||
def VarTemplate : DDecl<RedeclarableTemplate>;
|
||||
@ -71,15 +73,16 @@ def Named : Decl<1>;
|
||||
def UsingPack : DDecl<Named>;
|
||||
def UsingShadow : DDecl<Named>;
|
||||
def ConstructorUsingShadow : DDecl<UsingShadow>;
|
||||
def ObjCMethod : DDecl<Named>, DeclContext;
|
||||
def ObjCContainer : DDecl<Named, 1>, DeclContext;
|
||||
def ObjCMethod : DDecl<Named, "Objective-C methods">, DeclContext;
|
||||
def ObjCContainer : DDecl<Named, "Objective-C containers", 1>, DeclContext;
|
||||
def ObjCCategory : DDecl<ObjCContainer>;
|
||||
def ObjCProtocol : DDecl<ObjCContainer>;
|
||||
def ObjCInterface : DDecl<ObjCContainer>;
|
||||
def ObjCImpl : DDecl<ObjCContainer, 1>;
|
||||
def ObjCProtocol : DDecl<ObjCContainer, "Objective-C protocols">;
|
||||
def ObjCInterface : DDecl<ObjCContainer, "Objective-C interfaces">;
|
||||
def ObjCImpl
|
||||
: DDecl<ObjCContainer, "Objective-C implementation declarations", 1>;
|
||||
def ObjCCategoryImpl : DDecl<ObjCImpl>;
|
||||
def ObjCImplementation : DDecl<ObjCImpl>;
|
||||
def ObjCProperty : DDecl<Named>;
|
||||
def ObjCProperty : DDecl<Named, "Objective-C properties">;
|
||||
def ObjCCompatibleAlias : DDecl<Named>;
|
||||
def LinkageSpec : Decl, DeclContext;
|
||||
def Export : Decl, DeclContext;
|
||||
@ -89,7 +92,7 @@ def AccessSpec : Decl;
|
||||
def Friend : Decl;
|
||||
def FriendTemplate : Decl;
|
||||
def StaticAssert : Decl;
|
||||
def Block : Decl, DeclContext;
|
||||
def Block : Decl<"blocks">, DeclContext;
|
||||
def Captured : Decl, DeclContext;
|
||||
def ClassScopeFunctionSpecialization : Decl;
|
||||
def Import : Decl;
|
||||
|
@ -575,13 +575,15 @@ public:
|
||||
OverloadsShown getShowOverloads() const { return ShowOverloads; }
|
||||
|
||||
/// \brief Pretend that the last diagnostic issued was ignored, so any
|
||||
/// subsequent notes will be suppressed.
|
||||
/// subsequent notes will be suppressed, or restore a prior ignoring
|
||||
/// state after ignoring some diagnostics and their notes, possibly in
|
||||
/// the middle of another diagnostic.
|
||||
///
|
||||
/// This can be used by clients who suppress diagnostics themselves.
|
||||
void setLastDiagnosticIgnored() {
|
||||
void setLastDiagnosticIgnored(bool Ignored = true) {
|
||||
if (LastDiagLevel == DiagnosticIDs::Fatal)
|
||||
FatalErrorOccurred = true;
|
||||
LastDiagLevel = DiagnosticIDs::Ignored;
|
||||
LastDiagLevel = Ignored ? DiagnosticIDs::Ignored : DiagnosticIDs::Warning;
|
||||
}
|
||||
|
||||
/// \brief Determine whether the previous diagnostic was ignored. This can
|
||||
|
@ -133,10 +133,12 @@ include "DiagnosticASTKinds.td"
|
||||
include "DiagnosticAnalysisKinds.td"
|
||||
include "DiagnosticCommentKinds.td"
|
||||
include "DiagnosticCommonKinds.td"
|
||||
include "DiagnosticCrossTUKinds.td"
|
||||
include "DiagnosticDriverKinds.td"
|
||||
include "DiagnosticFrontendKinds.td"
|
||||
include "DiagnosticLexKinds.td"
|
||||
include "DiagnosticParseKinds.td"
|
||||
include "DiagnosticRefactoringKinds.td"
|
||||
include "DiagnosticSemaKinds.td"
|
||||
include "DiagnosticSerializationKinds.td"
|
||||
|
||||
|
@ -127,6 +127,10 @@ def note_constexpr_access_null : Note<
|
||||
def note_constexpr_access_past_end : Note<
|
||||
"%select{read of|assignment to|increment of|decrement of}0 "
|
||||
"dereferenced one-past-the-end pointer is not allowed in a constant expression">;
|
||||
def note_constexpr_access_unsized_array : Note<
|
||||
"%select{read of|assignment to|increment of|decrement of}0 "
|
||||
"pointer to element of array without known bound "
|
||||
"is not allowed in a constant expression">;
|
||||
def note_constexpr_access_inactive_union_member : Note<
|
||||
"%select{read of|assignment to|increment of|decrement of}0 "
|
||||
"member %1 of union with %select{active member %3|no active member}2 "
|
||||
@ -154,6 +158,11 @@ def note_constexpr_baa_insufficient_alignment : Note<
|
||||
def note_constexpr_baa_value_insufficient_alignment : Note<
|
||||
"value of the aligned pointer (%0) is not a multiple of the asserted %1 "
|
||||
"%plural{1:byte|:bytes}1">;
|
||||
def note_constexpr_unsupported_unsized_array : Note<
|
||||
"array-to-pointer decay of array member without known bound is not supported">;
|
||||
def note_constexpr_unsized_array_indexed : Note<
|
||||
"indexing of array without known bound is not allowed "
|
||||
"in a constant expression">;
|
||||
|
||||
def warn_integer_constant_overflow : Warning<
|
||||
"overflow in expression; result is %0 with type %1">,
|
||||
|
@ -185,6 +185,8 @@ def note_invalid_subexpr_in_const_expr : Note<
|
||||
def err_target_unknown_triple : Error<
|
||||
"unknown target triple '%0', please use -triple or -arch">;
|
||||
def err_target_unknown_cpu : Error<"unknown target CPU '%0'">;
|
||||
def err_target_unsupported_cpu_for_micromips : Error<
|
||||
"micromips is not supported for target CPU '%0'">;
|
||||
def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
|
||||
def err_target_unsupported_abi : Error<"ABI '%0' is not supported on CPU '%1'">;
|
||||
def err_target_unsupported_abi_for_triple : Error<
|
||||
|
@ -0,0 +1,18 @@
|
||||
//==--- DiagnosticCrossTUKinds.td - Cross Translation Unit diagnostics ----===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Component = "CrossTU" in {
|
||||
|
||||
def err_fnmap_parsing : Error<
|
||||
"error parsing index file: '%0' line: %1 'UniqueID filename' format "
|
||||
"expected">;
|
||||
|
||||
def err_multiple_def_index : Error<
|
||||
"multiple definitions are found for the same key in index ">;
|
||||
}
|
@ -29,9 +29,10 @@ def err_drv_no_cuda_installation : Error<
|
||||
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 "
|
||||
def err_drv_cuda_version_unsupported : Error<
|
||||
"GPU arch %0 is supported by CUDA versions between %1 and %2 (inclusive), "
|
||||
"but installation at %3 is %4. Use --cuda-path to specify a different CUDA "
|
||||
"install, pass a different GPU arch with --cuda-gpu-arch, 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<
|
||||
@ -69,6 +70,10 @@ def err_drv_invalid_Xarch_argument_with_args : Error<
|
||||
"invalid Xarch argument: '%0', options requiring arguments are unsupported">;
|
||||
def err_drv_invalid_Xarch_argument_isdriver : Error<
|
||||
"invalid Xarch argument: '%0', cannot change driver behavior inside Xarch argument">;
|
||||
def err_drv_Xopenmp_target_missing_triple : Error<
|
||||
"cannot deduce implicit triple value for -Xopenmp-target, specify triple using -Xopenmp-target=<triple>">;
|
||||
def err_drv_invalid_Xopenmp_target_with_args : Error<
|
||||
"invalid -Xopenmp-target argument: '%0', options requiring arguments are unsupported">;
|
||||
def err_drv_argument_only_allowed_with : Error<
|
||||
"invalid argument '%0' only allowed with '%1'">;
|
||||
def err_drv_argument_not_allowed_with : Error<
|
||||
@ -97,6 +102,10 @@ def err_drv_force_crash : Error<
|
||||
"failing because %select{environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set|'-gen-reproducer' is used}0">;
|
||||
def err_drv_invalid_mfloat_abi : Error<
|
||||
"invalid float ABI '%0'">;
|
||||
def err_drv_invalid_mtp : Error<
|
||||
"invalid thread pointer reading mode '%0'">;
|
||||
def err_drv_missing_arg_mtp : Error<
|
||||
"missing argument to '%0'">;
|
||||
def err_drv_invalid_libcxx_deployment : Error<
|
||||
"invalid deployment target for -stdlib=libc++ (requires %0 or later)">;
|
||||
def err_drv_invalid_argument_to_fdebug_prefix_map : Error<
|
||||
@ -106,6 +115,10 @@ def err_drv_malformed_sanitizer_blacklist : Error<
|
||||
|
||||
def err_target_unsupported_arch
|
||||
: Error<"the target architecture '%0' is not supported by the target '%1'">;
|
||||
def err_cpu_unsupported_isa
|
||||
: Error<"CPU '%0' does not support '%1' execution mode">;
|
||||
def err_arch_unsupported_isa
|
||||
: Error<"Architecture '%0' does not support '%1' execution mode">;
|
||||
|
||||
def err_drv_I_dash_not_supported : Error<
|
||||
"'%0' not supported, please use -iquote instead">;
|
||||
@ -231,7 +244,7 @@ def warn_drv_enabling_rtti_with_exceptions : Warning<
|
||||
InGroup<DiagGroup<"rtti-for-exceptions">>;
|
||||
def warn_drv_disabling_vptr_no_rtti_default : Warning<
|
||||
"implicitly disabling vptr sanitizer because rtti wasn't enabled">,
|
||||
InGroup<DiagGroup<"auto-disable-vptr-sanitizer">>;
|
||||
InGroup<AutoDisableVptrSanitizer>;
|
||||
def warn_drv_object_size_disabled_O0 : Warning<
|
||||
"the object size sanitizer has no effect at -O0, but is explicitly enabled: %0">,
|
||||
InGroup<InvalidCommandLineArgument>;
|
||||
@ -251,6 +264,9 @@ def err_analyzer_config_no_value : Error<
|
||||
def err_analyzer_config_multiple_values : Error<
|
||||
"analyzer-config option '%0' should contain only one '='">;
|
||||
|
||||
def err_drv_invalid_hvx_length : Error<
|
||||
"-mhvx-length is not supported without a -mhvx/-mhvx= flag">;
|
||||
|
||||
def err_drv_modules_validate_once_requires_timestamp : Error<
|
||||
"option '-fmodules-validate-once-per-build-session' requires "
|
||||
"'-fbuild-session-timestamp=<seconds since Epoch>' or '-fbuild-session-file=<file>'">;
|
||||
@ -277,9 +293,27 @@ def warn_target_unsupported_nan2008 : Warning<
|
||||
def warn_target_unsupported_nanlegacy : Warning<
|
||||
"ignoring '-mnan=legacy' option because the '%0' architecture does not support it">,
|
||||
InGroup<UnsupportedNan>;
|
||||
def warn_target_unsupported_abslegacy : Warning<
|
||||
"ignoring '-mabs=legacy' option because the '%0' architecture does not support it">,
|
||||
InGroup<UnsupportedAbs>;
|
||||
def warn_target_unsupported_abs2008 : Warning<
|
||||
"ignoring '-mabs=2008' option because the '%0' architecture does not support it">,
|
||||
InGroup<UnsupportedAbs>;
|
||||
def warn_target_unsupported_compact_branches : Warning<
|
||||
"ignoring '-mcompact-branches=' option because the '%0' architecture does not"
|
||||
" support it">, InGroup<UnsupportedCB>;
|
||||
def warn_drv_unsupported_gpopt : Warning<
|
||||
"ignoring '-mgpopt' option as it cannot be used with %select{|the implicit"
|
||||
" usage of }0-mabicalls">,
|
||||
InGroup<UnsupportedGPOpt>;
|
||||
def warn_drv_unsupported_longcalls : Warning<
|
||||
"ignoring '-mlong-calls' option as it is not currently supported with "
|
||||
"%select{|the implicit usage of }0-mabicalls">,
|
||||
InGroup<OptionIgnored>;
|
||||
def warn_drv_unsupported_abicalls : Warning<
|
||||
"ignoring '-mabicalls' option as it cannot be used with "
|
||||
"non position-independent code and the N64 ABI">,
|
||||
InGroup<OptionIgnored>;
|
||||
|
||||
def warn_drv_unable_to_find_directory_expected : Warning<
|
||||
"unable to find %0 directory, expected to be in '%1'">,
|
||||
@ -300,4 +334,12 @@ def warn_drv_msvc_not_found : Warning<
|
||||
"unable to find a Visual Studio installation; "
|
||||
"try running Clang from a developer command prompt">,
|
||||
InGroup<DiagGroup<"msvc-not-found">>;
|
||||
|
||||
def warn_drv_fine_grained_bitfield_accesses_ignored : Warning<
|
||||
"option '-ffine-grained-bitfield-accesses' cannot be enabled together with a sanitizer; flag ignored">,
|
||||
InGroup<OptionIgnored>;
|
||||
|
||||
def note_drv_verify_prefix_spelling : Note<
|
||||
"-verify prefixes must start with a letter and contain only alphanumeric"
|
||||
" characters, hyphens, and underscores">;
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
//===--- DiagnosticError.h - Diagnostic payload for llvm::Error -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
|
||||
#define LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
|
||||
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// \brief Carries a Clang diagnostic in an llvm::Error.
|
||||
///
|
||||
/// Users should emit the stored diagnostic using the DiagnosticsEngine.
|
||||
class DiagnosticError : public llvm::ErrorInfo<DiagnosticError> {
|
||||
public:
|
||||
DiagnosticError(PartialDiagnosticAt Diag) : Diag(std::move(Diag)) {}
|
||||
|
||||
void log(raw_ostream &OS) const override { OS << "clang diagnostic"; }
|
||||
|
||||
PartialDiagnosticAt &getDiagnostic() { return Diag; }
|
||||
const PartialDiagnosticAt &getDiagnostic() const { return Diag; }
|
||||
|
||||
/// Creates a new \c DiagnosticError that contains the given diagnostic at
|
||||
/// the given location.
|
||||
static llvm::Error create(SourceLocation Loc, PartialDiagnostic Diag) {
|
||||
return llvm::make_error<DiagnosticError>(
|
||||
PartialDiagnosticAt(Loc, std::move(Diag)));
|
||||
}
|
||||
|
||||
/// Extracts and returns the diagnostic payload from the given \c Error if
|
||||
/// the error is a \c DiagnosticError. Returns none if the given error is not
|
||||
/// a \c DiagnosticError.
|
||||
static Optional<PartialDiagnosticAt> take(llvm::Error &Err) {
|
||||
Optional<PartialDiagnosticAt> Result;
|
||||
Err = llvm::handleErrors(std::move(Err), [&](DiagnosticError &E) {
|
||||
Result = std::move(E.getDiagnostic());
|
||||
});
|
||||
return Result;
|
||||
}
|
||||
|
||||
static char ID;
|
||||
|
||||
private:
|
||||
// Users are not expected to use error_code.
|
||||
std::error_code convertToErrorCode() const override {
|
||||
return llvm::inconvertibleErrorCode();
|
||||
}
|
||||
|
||||
PartialDiagnosticAt Diag;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
|
@ -116,6 +116,8 @@ 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 err_fe_invalid_wchar_type
|
||||
: Error<"invalid wchar_t type '%0'; must be one of 'char', 'short', 'int'">;
|
||||
|
||||
def warn_fe_serialized_diag_merge_failure : Warning<
|
||||
"unable to merge a subprocess's serialized diagnostics">,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user