Merge clang trunk r321017 to contrib/llvm/tools/clang.

This commit is contained in:
dim 2017-12-20 14:26:54 +00:00
commit aad9e6bafb
729 changed files with 63299 additions and 33896 deletions

View File

@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
#define CINDEX_VERSION_MINOR 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.
*/

View File

@ -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);

View File

@ -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) {}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -133,6 +133,9 @@ FLOATING_TYPE(Double, DoubleTy)
// 'long double'
FLOATING_TYPE(LongDouble, LongDoubleTy)
// '_Float16'
FLOATING_TYPE(Float16, HalfTy)
// '__float128'
FLOATING_TYPE(Float128, Float128Ty)

View File

@ -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

View File

@ -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

View File

@ -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() {

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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, "++")

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View 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()));
}
}];
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) \

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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"

View File

@ -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 {

View File

@ -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 {

View File

@ -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"

View File

@ -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>

View File

@ -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;
};

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
});

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 = [{

View File

@ -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
};

View File

@ -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", "")

View File

@ -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 {

View File

@ -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

View File

@ -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.

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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")

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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"

View File

@ -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">,

View File

@ -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<

View File

@ -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 ">;
}

View File

@ -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">;
}

View File

@ -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

View File

@ -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