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. * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/ */
#define CINDEX_VERSION_MAJOR 0 #define CINDEX_VERSION_MAJOR 0
#define CINDEX_VERSION_MINOR 43 #define CINDEX_VERSION_MINOR 45
#define CINDEX_VERSION_ENCODE(major, minor) ( \ #define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \ ((major) * 10000) \
@ -333,6 +333,16 @@ CINDEX_LINKAGE void clang_CXIndex_setGlobalOptions(CXIndex, unsigned options);
*/ */
CINDEX_LINKAGE unsigned clang_CXIndex_getGlobalOptions(CXIndex); 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 * \defgroup CINDEX_FILES File manipulation routines
* *
@ -393,6 +403,21 @@ clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file);
CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu, CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu,
const char *file_name); 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, * \brief Returns non-zero if the \c file1 and \c file2 point to the same file,
* or they are both NULL. * or they are both NULL.
@ -2836,6 +2861,22 @@ enum CXLanguageKind {
*/ */
CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor); 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. * \brief Returns the translation unit that a cursor originated from.
*/ */
@ -3115,8 +3156,9 @@ enum CXTypeKind {
CXType_ObjCSel = 29, CXType_ObjCSel = 29,
CXType_Float128 = 30, CXType_Float128 = 30,
CXType_Half = 31, CXType_Half = 31,
CXType_Float16 = 32,
CXType_FirstBuiltin = CXType_Void, CXType_FirstBuiltin = CXType_Void,
CXType_LastBuiltin = CXType_Half, CXType_LastBuiltin = CXType_Float16,
CXType_Complex = 100, CXType_Complex = 100,
CXType_Pointer = 101, CXType_Pointer = 101,
@ -4275,6 +4317,12 @@ CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor);
*/ */
CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(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); 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. * \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 // The LLVM Compiler Infrastructure
// //
@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// //
/// \file /// \file
/// \brief Defines the clang::ASTContext interface. /// \brief Defines the clang::ASTContext interface.
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H #ifndef LLVM_CLANG_AST_ASTCONTEXT_H
@ -19,8 +19,8 @@
#include "clang/AST/CanonicalType.h" #include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h" #include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclBase.h" #include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h" #include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h" #include "clang/AST/PrettyPrinter.h"
@ -30,32 +30,32 @@
#include "clang/AST/Type.h" #include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h" #include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h" #include "clang/Basic/LangOptions.h"
#include "clang/Basic/Linkage.h" #include "clang/Basic/Linkage.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/OperatorKinds.h" #include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SanitizerBlacklist.h" #include "clang/Basic/SanitizerBlacklist.h"
#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h" #include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/XRayLists.h" #include "clang/Basic/XRayLists.h"
#include "llvm/ADT/APSInt.h" #include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/MapVector.h" #include "llvm/ADT/MapVector.h"
#include "llvm/ADT/None.h" #include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.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/AlignOf.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
@ -65,7 +65,6 @@
#include <cstdint> #include <cstdint>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <new>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
@ -75,50 +74,72 @@ namespace llvm {
struct fltSemantics; struct fltSemantics;
} // end namespace llvm } // namespace llvm
namespace clang { namespace clang {
class APValue;
class ASTMutationListener; class ASTMutationListener;
class ASTRecordLayout; class ASTRecordLayout;
class AtomicExpr; class AtomicExpr;
class BlockExpr; class BlockExpr;
class BuiltinTemplateDecl;
class CharUnits; class CharUnits;
class CXXABI; class CXXABI;
class CXXConstructorDecl;
class CXXMethodDecl;
class CXXRecordDecl;
class DiagnosticsEngine; class DiagnosticsEngine;
class Expr; class Expr;
class MangleContext;
class MangleNumberingContext; class MangleNumberingContext;
class MaterializeTemporaryExpr; class MaterializeTemporaryExpr;
class TargetInfo; class MemberSpecializationInfo;
// Decls class Module;
class MangleContext; class ObjCCategoryDecl;
class ObjCCategoryImplDecl;
class ObjCContainerDecl;
class ObjCImplDecl;
class ObjCImplementationDecl;
class ObjCInterfaceDecl;
class ObjCIvarDecl; class ObjCIvarDecl;
class ObjCMethodDecl;
class ObjCPropertyDecl; 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 UnresolvedSetIterator;
class UsingDecl;
class UsingShadowDecl; class UsingShadowDecl;
class VarTemplateDecl;
class VTableContextBase; class VTableContextBase;
namespace Builtin { namespace Builtin {
class Context; class Context;
} // end namespace Builtin } // namespace Builtin
enum BuiltinTemplateKind : int; enum BuiltinTemplateKind : int;
namespace comments { namespace comments {
class FullComment; class FullComment;
} // end namespace comments } // namespace comments
struct TypeInfo { struct TypeInfo {
uint64_t Width; uint64_t Width = 0;
unsigned Align; unsigned Align = 0;
bool AlignIsRequired : 1; bool AlignIsRequired : 1;
TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {} TypeInfo() : AlignIsRequired(false) {}
TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired) TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
: Width(Width), Align(Align), AlignIsRequired(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 /// \brief Holds long-lived AST nodes (such as types and decls) that can be
/// referred to throughout the semantic analysis of a file. /// referred to throughout the semantic analysis of a file.
class ASTContext : public RefCountedBase<ASTContext> { class ASTContext : public RefCountedBase<ASTContext> {
ASTContext &this_() { return *this; } friend class NestedNameSpecifier;
mutable SmallVector<Type *, 0> Types; mutable SmallVector<Type *, 0> Types;
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes; mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
@ -143,6 +164,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes; mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
mutable llvm::FoldingSet<DependentSizedExtVectorType> mutable llvm::FoldingSet<DependentSizedExtVectorType>
DependentSizedExtVectorTypes; DependentSizedExtVectorTypes;
mutable llvm::FoldingSet<DependentAddressSpaceType>
DependentAddressSpaceTypes;
mutable llvm::FoldingSet<VectorType> VectorTypes; mutable llvm::FoldingSet<VectorType> VectorTypes;
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes; mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&> mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
@ -187,8 +210,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// ///
/// This set is managed by the NestedNameSpecifier class. /// This set is managed by the NestedNameSpecifier class.
mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers; mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
mutable NestedNameSpecifier *GlobalNestedNameSpecifier; mutable NestedNameSpecifier *GlobalNestedNameSpecifier = nullptr;
friend class NestedNameSpecifier;
/// \brief A cache mapping from RecordDecls to ASTRecordLayouts. /// \brief A cache mapping from RecordDecls to ASTRecordLayouts.
/// ///
@ -199,7 +221,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
ObjCLayouts; ObjCLayouts;
/// \brief A cache from types to size and alignment information. /// \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; mutable TypeInfoMap MemoizedTypeInfo;
/// \brief A cache mapping from CXXRecordDecls to key functions. /// \brief A cache mapping from CXXRecordDecls to key functions.
@ -233,7 +255,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
public: public:
CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm) CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
: Parm(Parm) { } : Parm(Parm) {}
TemplateTemplateParmDecl *getParam() const { return Parm; } TemplateTemplateParmDecl *getParam() const { return Parm; }
@ -249,32 +271,32 @@ class ASTContext : public RefCountedBase<ASTContext> {
getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const; getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
/// \brief The typedef for the __int128_t type. /// \brief The typedef for the __int128_t type.
mutable TypedefDecl *Int128Decl; mutable TypedefDecl *Int128Decl = nullptr;
/// \brief The typedef for the __uint128_t type. /// \brief The typedef for the __uint128_t type.
mutable TypedefDecl *UInt128Decl; mutable TypedefDecl *UInt128Decl = nullptr;
/// \brief The typedef for the target specific predefined /// \brief The typedef for the target specific predefined
/// __builtin_va_list type. /// __builtin_va_list type.
mutable TypedefDecl *BuiltinVaListDecl; mutable TypedefDecl *BuiltinVaListDecl = nullptr;
/// The typedef for the predefined \c __builtin_ms_va_list type. /// 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. /// \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. /// \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. /// \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. /// \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. /// \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 // Typedefs which may be provided defining the structure of Objective-C
// pseudo-builtins // pseudo-builtins
@ -298,42 +320,42 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable IdentifierInfo *TypePackElementName = nullptr; mutable IdentifierInfo *TypePackElementName = nullptr;
QualType ObjCConstantStringType; QualType ObjCConstantStringType;
mutable RecordDecl *CFConstantStringTagDecl; mutable RecordDecl *CFConstantStringTagDecl = nullptr;
mutable TypedefDecl *CFConstantStringTypeDecl; mutable TypedefDecl *CFConstantStringTypeDecl = nullptr;
mutable QualType ObjCSuperType; mutable QualType ObjCSuperType;
QualType ObjCNSStringType; QualType ObjCNSStringType;
/// \brief The typedef declaration for the Objective-C "instancetype" type. /// \brief The typedef declaration for the Objective-C "instancetype" type.
TypedefDecl *ObjCInstanceTypeDecl; TypedefDecl *ObjCInstanceTypeDecl = nullptr;
/// \brief The type for the C FILE type. /// \brief The type for the C FILE type.
TypeDecl *FILEDecl; TypeDecl *FILEDecl = nullptr;
/// \brief The type for the C jmp_buf type. /// \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. /// \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. /// \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. /// \brief Type for the Block descriptor for Blocks CodeGen.
/// ///
/// Since this is only used for generation of debug info, it is not /// Since this is only used for generation of debug info, it is not
/// serialized. /// serialized.
mutable RecordDecl *BlockDescriptorType; mutable RecordDecl *BlockDescriptorType = nullptr;
/// \brief Type for the Block descriptor for Blocks CodeGen. /// \brief Type for the Block descriptor for Blocks CodeGen.
/// ///
/// Since this is only used for generation of debug info, it is not /// Since this is only used for generation of debug info, it is not
/// serialized. /// serialized.
mutable RecordDecl *BlockDescriptorExtendedType; mutable RecordDecl *BlockDescriptorExtendedType = nullptr;
/// \brief Declaration for the CUDA cudaConfigureCall function. /// \brief Declaration for the CUDA cudaConfigureCall function.
FunctionDecl *cudaConfigureCallDecl; FunctionDecl *cudaConfigureCallDecl = nullptr;
/// \brief Keeps track of all declaration attributes. /// \brief Keeps track of all declaration attributes.
/// ///
@ -363,12 +385,19 @@ class ASTContext : public RefCountedBase<ASTContext> {
}; };
llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers; llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers;
ASTContext &this_() { return *this; }
public: public:
/// \brief A type synonym for the TemplateOrInstantiation mapping. /// \brief A type synonym for the TemplateOrInstantiation mapping.
typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *> using TemplateOrSpecializationInfo =
TemplateOrSpecializationInfo; llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>;
private: private:
friend class ASTDeclReader;
friend class ASTReader;
friend class ASTWriter;
friend class CXXRecordDecl;
/// \brief A mapping to contain the template or declaration that /// \brief A mapping to contain the template or declaration that
/// a variable declaration describes or was instantiated from, /// a variable declaration describes or was instantiated from,
/// respectively. /// respectively.
@ -438,7 +467,7 @@ private:
/// Since most C++ member functions aren't virtual and therefore /// Since most C++ member functions aren't virtual and therefore
/// don't override anything, we store the overridden functions in /// don't override anything, we store the overridden functions in
/// this map on the side rather than within the CXXMethodDecl structure. /// 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; llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
/// \brief Mapping from each declaration context to its corresponding /// \brief Mapping from each declaration context to its corresponding
@ -454,18 +483,18 @@ private:
/// \brief Mapping that stores parameterIndex values for ParmVarDecls when /// \brief Mapping that stores parameterIndex values for ParmVarDecls when
/// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex. /// 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; ParameterIndexTable ParamIndices;
ImportDecl *FirstLocalImport; ImportDecl *FirstLocalImport = nullptr;
ImportDecl *LastLocalImport; ImportDecl *LastLocalImport = nullptr;
TranslationUnitDecl *TUDecl; TranslationUnitDecl *TUDecl;
mutable ExternCContextDecl *ExternCContext; mutable ExternCContextDecl *ExternCContext = nullptr;
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl; mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr;
mutable BuiltinTemplateDecl *TypePackElementDecl; mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr;
/// \brief The associated SourceManager object.a /// \brief The associated SourceManager object.
SourceManager &SourceMgr; SourceManager &SourceMgr;
/// \brief The language options used to create the AST associated with /// \brief The language options used to create the AST associated with
@ -494,19 +523,14 @@ private:
CXXABI *createCXXABI(const TargetInfo &T); CXXABI *createCXXABI(const TargetInfo &T);
/// \brief The logical -> physical address space map. /// \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 /// \brief Address space map mangling must be used with language specific
/// address spaces (e.g. OpenCL/CUDA) /// address spaces (e.g. OpenCL/CUDA)
bool AddrSpaceMapMangling; bool AddrSpaceMapMangling;
friend class ASTDeclReader; const TargetInfo *Target = nullptr;
friend class ASTReader; const TargetInfo *AuxTarget = nullptr;
friend class ASTWriter;
friend class CXXRecordDecl;
const TargetInfo *Target;
const TargetInfo *AuxTarget;
clang::PrintingPolicy PrintingPolicy; clang::PrintingPolicy PrintingPolicy;
public: public:
@ -515,31 +539,33 @@ public:
Builtin::Context &BuiltinInfo; Builtin::Context &BuiltinInfo;
mutable DeclarationNameTable DeclarationNames; mutable DeclarationNameTable DeclarationNames;
IntrusiveRefCntPtr<ExternalASTSource> ExternalSource; IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
ASTMutationListener *Listener; ASTMutationListener *Listener = nullptr;
/// \brief Contains parents of a node. /// \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 /// \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 /// pointer identity only, which are more common and we can save space by
/// only storing a unique pointer to them. /// only storing a unique pointer to them.
typedef llvm::DenseMap<const void *, using ParentMapPointers =
llvm::PointerUnion4<const Decl *, const Stmt *, llvm::DenseMap<const void *,
ast_type_traits::DynTypedNode *, llvm::PointerUnion4<const Decl *, const Stmt *,
ParentVector *>> ParentMapPointers; ast_type_traits::DynTypedNode *,
ParentVector *>>;
/// Parent map for nodes without pointer identity. We store a full /// Parent map for nodes without pointer identity. We store a full
/// DynTypedNode for all keys. /// DynTypedNode for all keys.
typedef llvm::DenseMap< using ParentMapOtherNodes =
ast_type_traits::DynTypedNode, llvm::DenseMap<ast_type_traits::DynTypedNode,
llvm::PointerUnion4<const Decl *, const Stmt *, llvm::PointerUnion4<const Decl *, const Stmt *,
ast_type_traits::DynTypedNode *, ParentVector *>> ast_type_traits::DynTypedNode *,
ParentMapOtherNodes; ParentVector *>>;
/// Container for either a single DynTypedNode or for an ArrayRef to /// Container for either a single DynTypedNode or for an ArrayRef to
/// DynTypedNode. For use with ParentMap. /// DynTypedNode. For use with ParentMap.
class DynTypedNodeList { class DynTypedNodeList {
typedef ast_type_traits::DynTypedNode DynTypedNode; using DynTypedNode = ast_type_traits::DynTypedNode;
llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode, llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode,
ArrayRef<DynTypedNode>> Storage; ArrayRef<DynTypedNode>> Storage;
bool IsSingleNode; bool IsSingleNode;
@ -548,6 +574,7 @@ public:
DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) { DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
new (Storage.buffer) DynTypedNode(N); new (Storage.buffer) DynTypedNode(N);
} }
DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) { DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
new (Storage.buffer) ArrayRef<DynTypedNode>(A); new (Storage.buffer) ArrayRef<DynTypedNode>(A);
} }
@ -626,13 +653,14 @@ public:
template <typename T> T *Allocate(size_t Num = 1) const { template <typename T> T *Allocate(size_t Num = 1) const {
return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T))); 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 /// Return the total amount of physical memory allocated for representing
/// AST nodes and type information. /// AST nodes and type information.
size_t getASTAllocatedMemory() const { size_t getASTAllocatedMemory() const {
return BumpAlloc.getTotalMemory(); return BumpAlloc.getTotalMemory();
} }
/// Return the total memory used for various side tables. /// Return the total memory used for various side tables.
size_t getSideTableAllocatedMemory() const; size_t getSideTableAllocatedMemory() const;
@ -649,6 +677,7 @@ public:
/// Returns empty type if there is no appropriate target types. /// Returns empty type if there is no appropriate target types.
QualType getIntTypeForBitwidth(unsigned DestWidth, QualType getIntTypeForBitwidth(unsigned DestWidth,
unsigned Signed) const; unsigned Signed) const;
/// getRealTypeForBitwidth - /// getRealTypeForBitwidth -
/// sets floating point QualTy according to specified bitwidth. /// sets floating point QualTy according to specified bitwidth.
/// Returns empty type if there is no appropriate target types. /// Returns empty type if there is no appropriate target types.
@ -676,7 +705,7 @@ public:
RawCommentList Comments; RawCommentList Comments;
/// \brief True if comments are already loaded from ExternalASTSource. /// \brief True if comments are already loaded from ExternalASTSource.
mutable bool CommentsLoaded; mutable bool CommentsLoaded = false;
class RawCommentAndCacheFlags { class RawCommentAndCacheFlags {
public: public:
@ -759,24 +788,24 @@ public:
} }
/// \brief Return the documentation comment attached to a given declaration. /// \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 /// \param OriginalDecl if not nullptr, is set to declaration AST node that
/// the comment, if the comment we found comes from a redeclaration. /// had the comment, if the comment we found comes from a redeclaration.
const RawComment * const RawComment *
getRawCommentForAnyRedecl(const Decl *D, getRawCommentForAnyRedecl(const Decl *D,
const Decl **OriginalDecl = nullptr) const; const Decl **OriginalDecl = nullptr) const;
/// Return parsed documentation comment attached to a given declaration. /// 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. /// preprocessor is not available.
comments::FullComment *getCommentForDecl(const Decl *D, comments::FullComment *getCommentForDecl(const Decl *D,
const Preprocessor *PP) const; const Preprocessor *PP) const;
/// Return parsed documentation comment attached to a given declaration. /// 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. /// redeclarations of the declaration.
comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const; comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const;
@ -788,16 +817,16 @@ private:
/// \brief Iterator that visits import declarations. /// \brief Iterator that visits import declarations.
class import_iterator { class import_iterator {
ImportDecl *Import; ImportDecl *Import = nullptr;
public: public:
typedef ImportDecl *value_type; using value_type = ImportDecl *;
typedef ImportDecl *reference; using reference = ImportDecl *;
typedef ImportDecl *pointer; using pointer = ImportDecl *;
typedef int difference_type; using difference_type = int;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
import_iterator() : Import() {} import_iterator() = default;
explicit import_iterator(ImportDecl *Import) : Import(Import) {} explicit import_iterator(ImportDecl *Import) : Import(Import) {}
reference operator*() const { return Import; } reference operator*() const { return Import; }
@ -876,7 +905,7 @@ public:
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl); void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
// Access to the set of methods overridden by the given C++ method. // 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_cxx_method_iterator
overridden_methods_begin(const CXXMethodDecl *Method) const; overridden_methods_begin(const CXXMethodDecl *Method) const;
@ -884,8 +913,10 @@ public:
overridden_methods_end(const CXXMethodDecl *Method) const; overridden_methods_end(const CXXMethodDecl *Method) const;
unsigned overridden_methods_size(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; overridden_method_range overridden_methods(const CXXMethodDecl *Method) const;
/// \brief Note that the given C++ \p Method overrides the given \p /// \brief Note that the given C++ \p Method overrides the given \p
@ -912,7 +943,8 @@ public:
return Import->NextLocalImport; return Import->NextLocalImport;
} }
typedef llvm::iterator_range<import_iterator> import_range; using import_range = llvm::iterator_range<import_iterator>;
import_range local_imports() const { import_range local_imports() const {
return import_range(import_iterator(FirstLocalImport), import_iterator()); return import_range(import_iterator(FirstLocalImport), import_iterator());
} }
@ -929,6 +961,7 @@ public:
/// and should be visible whenever \p M is visible. /// and should be visible whenever \p M is visible.
void mergeDefinitionIntoModule(NamedDecl *ND, Module *M, void mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
bool NotifyListeners = true); bool NotifyListeners = true);
/// \brief Clean up the merged definition list. Call this if you might have /// \brief Clean up the merged definition list. Call this if you might have
/// added duplicates into the list. /// added duplicates into the list.
void deduplicateMergedDefinitonsFor(NamedDecl *ND); void deduplicateMergedDefinitonsFor(NamedDecl *ND);
@ -973,6 +1006,7 @@ public:
CanQualType UnsignedLongLongTy, UnsignedInt128Ty; CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty; CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
CanQualType Float128ComplexTy; CanQualType Float128ComplexTy;
CanQualType VoidPtrTy, NullPtrTy; CanQualType VoidPtrTy, NullPtrTy;
@ -1067,7 +1101,14 @@ public:
/// The resulting type has a union of the qualifiers from T and the address /// 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 /// space. If T already has an address space specifier, it is silently
/// replaced. /// 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. /// \brief Apply Objective-C protocol qualifiers to the given type.
/// \param allowOnPointerType specifies if we can apply protocol /// \param allowOnPointerType specifies if we can apply protocol
@ -1175,6 +1216,7 @@ public:
/// \brief Return a read_only pipe type for the specified type. /// \brief Return a read_only pipe type for the specified type.
QualType getReadPipeType(QualType T) const; QualType getReadPipeType(QualType T) const;
/// \brief Return a write_only pipe type for the specified type. /// \brief Return a write_only pipe type for the specified type.
QualType getWritePipeType(QualType T) const; QualType getWritePipeType(QualType T) const;
@ -1182,9 +1224,16 @@ public:
/// pointer to blocks. /// pointer to blocks.
QualType getBlockDescriptorExtendedType() const; 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) { void setcudaConfigureCallDecl(FunctionDecl *FD) {
cudaConfigureCallDecl = FD; cudaConfigureCallDecl = FD;
} }
FunctionDecl *getcudaConfigureCallDecl() { FunctionDecl *getcudaConfigureCallDecl() {
return cudaConfigureCallDecl; return cudaConfigureCallDecl;
} }
@ -1192,7 +1241,6 @@ public:
/// Returns true iff we need copy/dispose helpers for the given type. /// Returns true iff we need copy/dispose helpers for the given type.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D); bool BlockRequiresCopying(QualType Ty, const VarDecl *D);
/// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set
/// to false in this case. If HasByrefExtendedLayout returns true, byref variable /// to false in this case. If HasByrefExtendedLayout returns true, byref variable
/// has extended lifetime. /// has extended lifetime.
@ -1269,6 +1317,10 @@ public:
Expr *SizeExpr, Expr *SizeExpr,
SourceLocation AttrLoc) const; SourceLocation AttrLoc) const;
QualType getDependentAddressSpaceType(QualType PointeeType,
Expr *AddrSpaceExpr,
SourceLocation AttrLoc) const;
/// \brief Return a K&R style C function type like 'int()'. /// \brief Return a K&R style C function type like 'int()'.
QualType getFunctionNoProtoType(QualType ResultTy, QualType getFunctionNoProtoType(QualType ResultTy,
const FunctionType::ExtInfo &Info) const; const FunctionType::ExtInfo &Info) const;
@ -1396,6 +1448,7 @@ public:
QualType Canonical = QualType()) const; QualType Canonical = QualType()) const;
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl); bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
/// QT's qualified-id protocol list adopt all protocols in IDecl's list /// QT's qualified-id protocol list adopt all protocols in IDecl's list
/// of protocols. /// of protocols.
@ -1426,7 +1479,7 @@ public:
/// \brief C++11 deduction pattern for 'auto &&' type. /// \brief C++11 deduction pattern for 'auto &&' type.
QualType getAutoRRefDeductType() const; QualType getAutoRRefDeductType() const;
/// \brief C++1z deduced class template specialization type. /// \brief C++17 deduced class template specialization type.
QualType getDeducedTemplateSpecializationType(TemplateName Template, QualType getDeducedTemplateSpecializationType(TemplateName Template,
QualType DeducedType, QualType DeducedType,
bool IsDependent) const; bool IsDependent) const;
@ -1488,6 +1541,11 @@ public:
/// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9). /// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
QualType getPointerDiffType() const; 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 /// \brief Return the unique type for "pid_t" defined in
/// <sys/types.h>. We need this to compute the correct type for vfork(). /// <sys/types.h>. We need this to compute the correct type for vfork().
QualType getProcessIDType() const; QualType getProcessIDType() const;
@ -1581,6 +1639,24 @@ public:
return NSCopyingName; 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'. /// Retrieve the identifier 'bool'.
IdentifierInfo *getBoolName() const { IdentifierInfo *getBoolName() const {
if (!BoolName) if (!BoolName)
@ -1865,10 +1941,17 @@ public:
const TemplateArgument &ArgPack) const; const TemplateArgument &ArgPack) const;
enum GetBuiltinTypeError { enum GetBuiltinTypeError {
GE_None, ///< No error /// No error
GE_Missing_stdio, ///< Missing a type from <stdio.h> GE_None,
GE_Missing_setjmp, ///< Missing a type from <setjmp.h>
GE_Missing_ucontext ///< Missing a type from <ucontext.h> /// 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. /// \brief Return the type for the specified builtin.
@ -2019,7 +2102,7 @@ public:
getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const; getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const;
/// \brief Get our current best idea for the key function of the /// \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 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 /// ...the first non-pure virtual function that is not inline at the
@ -2072,6 +2155,10 @@ public:
void CollectInheritedProtocols(const Decl *CDecl, void CollectInheritedProtocols(const Decl *CDecl,
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols); 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 // Type Operators
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@ -2103,7 +2190,6 @@ public:
bool hasSameType(QualType T1, QualType T2) const { bool hasSameType(QualType T1, QualType T2) const {
return getCanonicalType(T1) == getCanonicalType(T2); return getCanonicalType(T1) == getCanonicalType(T2);
} }
bool hasSameType(const Type *T1, const Type *T2) const { bool hasSameType(const Type *T1, const Type *T2) const {
return getCanonicalType(T1) == getCanonicalType(T2); return getCanonicalType(T1) == getCanonicalType(T2);
} }
@ -2192,7 +2278,7 @@ public:
getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const; getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
/// \brief Retrieves the default calling convention for the current target. /// \brief Retrieves the default calling convention for the current target.
CallingConv getDefaultCallingConvention(bool isVariadic, CallingConv getDefaultCallingConvention(bool IsVariadic,
bool IsCXXMethod) const; bool IsCXXMethod) const;
/// \brief Retrieves the "canonical" template name that refers to a /// \brief Retrieves the "canonical" template name that refers to a
@ -2326,14 +2412,14 @@ public:
return getTargetAddressSpace(Q.getAddressSpace()); 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 /// Get target-dependent integer value for null pointer which is used for
/// constant folding. /// constant folding.
uint64_t getTargetNullPointerValue(QualType QT) const; uint64_t getTargetNullPointerValue(QualType QT) const;
bool addressSpaceMapManglingFor(unsigned AS) const { bool addressSpaceMapManglingFor(LangAS AS) const {
return AddrSpaceMapMangling || AS >= LangAS::FirstTargetAddressSpace; return AddrSpaceMapMangling || isTargetAddressSpace(AS);
} }
private: private:
@ -2355,12 +2441,15 @@ public:
bool isObjCIdType(QualType T) const { bool isObjCIdType(QualType T) const {
return T == getObjCIdType(); return T == getObjCIdType();
} }
bool isObjCClassType(QualType T) const { bool isObjCClassType(QualType T) const {
return T == getObjCClassType(); return T == getObjCClassType();
} }
bool isObjCSelType(QualType T) const { bool isObjCSelType(QualType T) const {
return T == getObjCSelType(); return T == getObjCSelType();
} }
bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS, bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
bool ForCompare); bool ForCompare);
@ -2394,9 +2483,30 @@ public:
QualType mergeObjCGCQualifiers(QualType, QualType); QualType mergeObjCGCQualifiers(QualType, QualType);
bool doFunctionTypesMatchOnExtParameterInfos( /// This function merges the ExtParameterInfo lists of two functions. It
const FunctionProtoType *FromFunctionType, /// returns true if the lists are compatible. The merged list is returned in
const FunctionProtoType *ToFunctionType); /// 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); void ResetObjCLayout(const ObjCContainerDecl *CD);
@ -2432,12 +2542,13 @@ public:
bool isSentinelNullExpr(const Expr *E); 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. /// none exists.
ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D); 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. /// none exists.
ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D); ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
/// \brief Return true if there is at least one \@implementation in the TU. /// \brief Return true if there is at least one \@implementation in the TU.
bool AnyObjCImplementation() { bool AnyObjCImplementation() {
@ -2447,6 +2558,7 @@ public:
/// \brief Set the implementation of ObjCInterfaceDecl. /// \brief Set the implementation of ObjCInterfaceDecl.
void setObjCImplementation(ObjCInterfaceDecl *IFaceD, void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
ObjCImplementationDecl *ImplD); ObjCImplementationDecl *ImplD);
/// \brief Set the implementation of ObjCCategoryDecl. /// \brief Set the implementation of ObjCCategoryDecl.
void setObjCImplementation(ObjCCategoryDecl *CatD, void setObjCImplementation(ObjCCategoryDecl *CatD,
ObjCCategoryImplDecl *ImplD); ObjCCategoryImplDecl *ImplD);
@ -2466,8 +2578,9 @@ public:
/// \brief Set the copy inialization expression of a block var decl. /// \brief Set the copy inialization expression of a block var decl.
void setBlockVarCopyInits(VarDecl*VD, Expr* Init); void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
/// \brief Get the copy initialization expression of the VarDecl \p VD, or /// \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); Expr *getBlockVarCopyInits(const VarDecl* VD);
/// \brief Allocate an uninitialized TypeSourceInfo. /// \brief Allocate an uninitialized TypeSourceInfo.
@ -2636,6 +2749,7 @@ private:
const FieldDecl *Field, const FieldDecl *Field,
bool includeVBases = true, bool includeVBases = true,
QualType *NotEncodedT=nullptr) const; QualType *NotEncodedT=nullptr) const;
public: public:
// Adds the encoding of a method parameter or return type. // Adds the encoding of a method parameter or return type.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
@ -2647,11 +2761,19 @@ public:
bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const; bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
enum class InlineVariableDefinitionKind { enum class InlineVariableDefinitionKind {
None, ///< Not an inline variable. /// Not an inline variable.
Weak, ///< Weak definition of inline variable. None,
WeakUnknown, ///< Weak for now, might become strong later in this TU.
Strong ///< Strong definition. /// 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 /// \brief Determine whether a definition of this inline variable should
/// be treated as a weak or strong definition. For compatibility with /// 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 /// C++14 and before, for a constexpr static data member, if there is an
@ -2661,6 +2783,9 @@ public:
getInlineVariableDefinitionKind(const VarDecl *VD) const; getInlineVariableDefinitionKind(const VarDecl *VD) const;
private: private:
friend class DeclarationNameTable;
friend class DeclContext;
const ASTRecordLayout & const ASTRecordLayout &
getObjCLayout(const ObjCInterfaceDecl *D, getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl) const; const ObjCImplementationDecl *Impl) const;
@ -2673,26 +2798,23 @@ private:
// into the datastructures which avoids this mess during deallocation but is // 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 // 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. // in order to track and run destructors while we're tearing things down.
typedef llvm::SmallVector<std::pair<void (*)(void *), void *>, 16> using DeallocationFunctionsAndArguments =
DeallocationFunctionsAndArguments; llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>;
DeallocationFunctionsAndArguments Deallocations; DeallocationFunctionsAndArguments Deallocations;
// FIXME: This currently contains the set of StoredDeclMaps used // FIXME: This currently contains the set of StoredDeclMaps used
// by DeclContext objects. This probably should not be in ASTContext, // by DeclContext objects. This probably should not be in ASTContext,
// but we include it here so that ASTContext can quickly deallocate them. // but we include it here so that ASTContext can quickly deallocate them.
llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM; llvm::PointerIntPair<StoredDeclsMap *, 1> LastSDM;
friend class DeclContext;
friend class DeclarationNameTable;
void ReleaseDeclContextMaps();
void ReleaseParentMapEntries();
std::unique_ptr<ParentMapPointers> PointerParents; std::unique_ptr<ParentMapPointers> PointerParents;
std::unique_ptr<ParentMapOtherNodes> OtherParents; std::unique_ptr<ParentMapOtherNodes> OtherParents;
std::unique_ptr<VTableContextBase> VTContext; std::unique_ptr<VTableContextBase> VTContext;
void ReleaseDeclContextMaps();
void ReleaseParentMapEntries();
public: public:
enum PragmaSectionFlag : unsigned { enum PragmaSectionFlag : unsigned {
PSF_None = 0, PSF_None = 0,
@ -2712,27 +2834,26 @@ public:
SectionInfo(DeclaratorDecl *Decl, SectionInfo(DeclaratorDecl *Decl,
SourceLocation PragmaSectionLocation, SourceLocation PragmaSectionLocation,
int SectionFlags) int SectionFlags)
: Decl(Decl), : Decl(Decl), PragmaSectionLocation(PragmaSectionLocation),
PragmaSectionLocation(PragmaSectionLocation), SectionFlags(SectionFlags) {}
SectionFlags(SectionFlags) {}
}; };
llvm::StringMap<SectionInfo> SectionInfos; llvm::StringMap<SectionInfo> SectionInfos;
}; };
/// \brief Utility function for constructing a nullary selector. /// \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); IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(0, &II); return Ctx.Selectors.getSelector(0, &II);
} }
/// \brief Utility function for constructing an unary selector. /// \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); IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(1, &II); return Ctx.Selectors.getSelector(1, &II);
} }
} // end namespace clang } // namespace clang
// operator new and delete aren't allowed inside namespaces. // 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 C The ASTContext that provides the allocator.
/// @param Alignment The alignment of the allocated memory (if the underlying /// @param Alignment The alignment of the allocated memory (if the underlying
/// allocator supports it). /// 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, inline void *operator new(size_t Bytes, const clang::ASTContext &C,
size_t Alignment) { size_t Alignment) {
return C.Allocate(Bytes, Alignment); return C.Allocate(Bytes, Alignment);
} }
/// @brief Placement delete companion to the new above. /// @brief Placement delete companion to the new above.
/// ///
/// This operator is just a companion to the new above. There is no way of /// 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 C The ASTContext that provides the allocator.
/// @param Alignment The alignment of the allocated memory (if the underlying /// @param Alignment The alignment of the allocated memory (if the underlying
/// allocator supports it). /// 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, inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
size_t Alignment = 8) { size_t Alignment = 8) {
return C.Allocate(Bytes, Alignment); return C.Allocate(Bytes, Alignment);

View File

@ -22,6 +22,7 @@ namespace clang {
class CXXRecordDecl; class CXXRecordDecl;
class Decl; class Decl;
class DeclContext; class DeclContext;
class Expr;
class FieldDecl; class FieldDecl;
class FunctionDecl; class FunctionDecl;
class FunctionTemplateDecl; class FunctionTemplateDecl;
@ -35,6 +36,7 @@ namespace clang {
class QualType; class QualType;
class RecordDecl; class RecordDecl;
class TagDecl; class TagDecl;
class ValueDecl;
class VarDecl; class VarDecl;
class VarTemplateDecl; class VarTemplateDecl;
class VarTemplateSpecializationDecl; class VarTemplateSpecializationDecl;
@ -80,13 +82,19 @@ public:
/// \brief A virtual destructor's operator delete has been resolved. /// \brief A virtual destructor's operator delete has been resolved.
virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD, virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
const FunctionDecl *Delete) {} const FunctionDecl *Delete,
Expr *ThisArg) {}
/// \brief An implicit member got a definition. /// \brief An implicit member got a definition.
virtual void CompletedImplicitDefinition(const FunctionDecl *D) {} virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
/// \brief A static data member was implicitly instantiated. /// \brief The instantiation of a templated function or variable was
virtual void StaticDataMemberInstantiated(const VarDecl *D) {} /// 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. /// \brief A function template's definition was instantiated.
virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {} 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 // The LLVM Compiler Infrastructure
// //
@ -16,14 +16,22 @@
#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H #define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
#include "clang/AST/ASTVector.h" #include "clang/AST/ASTVector.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/UnresolvedSet.h" #include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/Specifiers.h"
#include <cassert>
#include <cstdint>
namespace clang { namespace clang {
class NamedDecl;
/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator. /// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
class ASTUnresolvedSet { class ASTUnresolvedSet {
friend class LazyASTUnresolvedSet;
struct DeclsTy : ASTVector<DeclAccessPair> { struct DeclsTy : ASTVector<DeclAccessPair> {
DeclsTy() {} DeclsTy() = default;
DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {} DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {}
bool isLazy() const { return getTag(); } bool isLazy() const { return getTag(); }
@ -32,14 +40,12 @@ class ASTUnresolvedSet {
DeclsTy Decls; DeclsTy Decls;
friend class LazyASTUnresolvedSet;
public: public:
ASTUnresolvedSet() {} ASTUnresolvedSet() = default;
ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {} ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
typedef UnresolvedSetIterator iterator; using iterator = UnresolvedSetIterator;
typedef UnresolvedSetIterator const_iterator; using const_iterator = UnresolvedSetIterator;
iterator begin() { return iterator(Decls.begin()); } iterator begin() { return iterator(Decls.begin()); }
iterator end() { return iterator(Decls.end()); } iterator end() { return iterator(Decls.end()); }
@ -98,13 +104,14 @@ public:
} }
void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); } void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); }
void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) { void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) {
assert(Impl.empty() || Impl.Decls.isLazy()); assert(Impl.empty() || Impl.Decls.isLazy());
Impl.Decls.setLazy(true); Impl.Decls.setLazy(true);
Impl.addDecl(C, reinterpret_cast<NamedDecl*>(ID << 2), AS); Impl.addDecl(C, reinterpret_cast<NamedDecl *>(ID << 2), AS);
} }
}; };
} // namespace clang } // 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 // The LLVM Compiler Infrastructure
// //
@ -18,22 +18,26 @@
#ifndef LLVM_CLANG_AST_ASTVECTOR_H #ifndef LLVM_CLANG_AST_ASTVECTOR_H
#define LLVM_CLANG_AST_ASTVECTOR_H #define LLVM_CLANG_AST_ASTVECTOR_H
#include "clang/AST/AttrIterator.h"
#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/type_traits.h"
#include <algorithm> #include <algorithm>
#include <cassert>
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <iterator>
#include <memory> #include <memory>
#include <type_traits>
#include <utility>
namespace clang { namespace clang {
class ASTContext;
class ASTContext;
template<typename T> template<typename T>
class ASTVector { class ASTVector {
private: private:
T *Begin, *End; T *Begin = nullptr;
llvm::PointerIntPair<T*, 1, bool> Capacity; T *End = nullptr;
llvm::PointerIntPair<T *, 1, bool> Capacity;
void setEnd(T *P) { this->End = P; } void setEnd(T *P) { this->End = P; }
@ -45,7 +49,7 @@ protected:
public: public:
// Default ctor - Initialize to empty. // 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) { ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) {
O.Begin = O.End = nullptr; O.Begin = O.End = nullptr;
@ -53,14 +57,15 @@ public:
O.Capacity.setInt(false); O.Capacity.setInt(false);
} }
ASTVector(const ASTContext &C, unsigned N) ASTVector(const ASTContext &C, unsigned N) : Capacity(nullptr, false) {
: Begin(nullptr), End(nullptr), Capacity(nullptr, false) {
reserve(C, N); reserve(C, N);
} }
ASTVector &operator=(ASTVector &&RHS) { ASTVector &operator=(ASTVector &&RHS) {
ASTVector O(std::move(RHS)); ASTVector O(std::move(RHS));
using std::swap; using std::swap;
swap(Begin, O.Begin); swap(Begin, O.Begin);
swap(End, O.End); swap(End, O.End);
swap(Capacity, O.Capacity); swap(Capacity, O.Capacity);
@ -74,19 +79,19 @@ public:
} }
} }
typedef size_t size_type; using size_type = size_t;
typedef ptrdiff_t difference_type; using difference_type = ptrdiff_t;
typedef T value_type; using value_type = T;
typedef T* iterator; using iterator = T *;
typedef const T* const_iterator; using const_iterator = const T *;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
typedef std::reverse_iterator<iterator> reverse_iterator; using reverse_iterator = std::reverse_iterator<iterator>;
typedef T& reference; using reference = T &;
typedef const T& const_reference; using const_reference = const T &;
typedef T* pointer; using pointer = T *;
typedef const T* const_pointer; using const_pointer = const T *;
// forward iterator creation methods. // forward iterator creation methods.
iterator begin() { return Begin; } iterator begin() { return Begin; }
@ -175,7 +180,6 @@ public:
size_t capacity() const { return this->capacity_ptr() - Begin; } size_t capacity() const { return this->capacity_ptr() - Begin; }
/// append - Add the specified range to the end of the SmallVector. /// append - Add the specified range to the end of the SmallVector.
///
template<typename in_iter> template<typename in_iter>
void append(const ASTContext &C, in_iter in_start, in_iter in_end) { void append(const ASTContext &C, in_iter in_start, in_iter in_end) {
size_type NumInputs = std::distance(in_start, 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. /// append - Add the specified range to the end of the SmallVector.
///
void append(const ASTContext &C, size_type NumInputs, const T &Elt) { void append(const ASTContext &C, size_type NumInputs, const T &Elt) {
// Grow allocated space if needed. // Grow allocated space if needed.
if (NumInputs > size_type(this->capacity_ptr()-this->end())) if (NumInputs > size_type(this->capacity_ptr()-this->end()))
@ -368,6 +371,7 @@ protected:
const_iterator capacity_ptr() const { const_iterator capacity_ptr() const {
return (iterator) Capacity.getPointer(); return (iterator) Capacity.getPointer();
} }
iterator capacity_ptr() { 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); Capacity.setPointer(Begin+NewCapacity);
} }
} // end: clang namespace } // namespace clang
#endif
#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 // The LLVM Compiler Infrastructure
// //
@ -15,16 +15,23 @@
#define LLVM_CLANG_AST_ATTRITERATOR_H #define LLVM_CLANG_AST_ATTRITERATOR_H
#include "clang/Basic/LLVM.h" #include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include <cassert>
#include <cstddef>
#include <iterator> #include <iterator>
namespace clang { namespace clang {
class ASTContext;
class Attr; class ASTContext;
} class Attr;
} // namespace clang
// Defined in ASTContext.h // Defined in ASTContext.h
void *operator new(size_t Bytes, const clang::ASTContext &C, void *operator new(size_t Bytes, const clang::ASTContext &C,
size_t Alignment = 8); size_t Alignment = 8);
// FIXME: Being forced to not have a default argument here due to redeclaration // FIXME: Being forced to not have a default argument here due to redeclaration
// rules on default arguments sucks // rules on default arguments sucks
void *operator new[](size_t Bytes, const clang::ASTContext &C, 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 { namespace clang {
/// AttrVec - A vector of Attr, which is how they are stored on the AST. /// 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 /// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
/// providing attributes that are of a specific type. /// providing attributes that are of a specific type.
template <typename SpecificAttr, typename Container = AttrVec> template <typename SpecificAttr, typename Container = AttrVec>
class specific_attr_iterator { class specific_attr_iterator {
typedef typename Container::const_iterator Iterator; using Iterator = typename Container::const_iterator;
/// Current - The current, underlying iterator. /// Current - The current, underlying iterator.
/// In order to ensure we don't dereference an invalid iterator unless /// In order to ensure we don't dereference an invalid iterator unless
@ -67,14 +74,14 @@ class specific_attr_iterator {
} }
public: public:
typedef SpecificAttr* value_type; using value_type = SpecificAttr *;
typedef SpecificAttr* reference; using reference = SpecificAttr *;
typedef SpecificAttr* pointer; using pointer = SpecificAttr *;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
typedef std::ptrdiff_t difference_type; using difference_type = std::ptrdiff_t;
specific_attr_iterator() : Current() { } specific_attr_iterator() = default;
explicit specific_attr_iterator(Iterator i) : Current(i) { } explicit specific_attr_iterator(Iterator i) : Current(i) {}
reference operator*() const { reference operator*() const {
AdvanceToNext(); AdvanceToNext();
@ -136,6 +143,6 @@ inline SpecificAttr *getSpecificAttr(const Container& container) {
return nullptr; 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 // The LLVM Compiler Infrastructure
// //
@ -15,12 +15,15 @@
#define LLVM_CLANG_AST_BASESUBOBJECT_H #define LLVM_CLANG_AST_BASESUBOBJECT_H
#include "clang/AST/CharUnits.h" #include "clang/AST/CharUnits.h"
#include "clang/AST/DeclCXX.h" #include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/type_traits.h" #include "llvm/Support/type_traits.h"
#include <cstdint>
#include <utility>
namespace clang { namespace clang {
class CXXRecordDecl;
// BaseSubobject - Uniquely identifies a direct or indirect base class. // BaseSubobject - Uniquely identifies a direct or indirect base class.
// Stores both the base class decl and the offset from the most derived class to // Stores both the base class decl and the offset from the most derived class to
// the base class. Used for vtable and VTT generation. // the base class. Used for vtable and VTT generation.
@ -32,9 +35,9 @@ class BaseSubobject {
CharUnits BaseOffset; CharUnits BaseOffset;
public: public:
BaseSubobject() { } BaseSubobject() = default;
BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset) BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
: Base(Base), BaseOffset(BaseOffset) { } : Base(Base), BaseOffset(BaseOffset) {}
/// getBase - Returns the base class declaration. /// getBase - Returns the base class declaration.
const CXXRecordDecl *getBase() const { return Base; } const CXXRecordDecl *getBase() const { return Base; }
@ -47,7 +50,7 @@ public:
} }
}; };
} // end namespace clang } // namespace clang
namespace llvm { namespace llvm {
@ -65,7 +68,8 @@ template<> struct DenseMapInfo<clang::BaseSubobject> {
} }
static unsigned getHashValue(const clang::BaseSubobject &Base) { 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(), return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(),
Base.getBaseOffset())); Base.getBaseOffset()));
} }
@ -81,6 +85,6 @@ template <> struct isPodLike<clang::BaseSubobject> {
static const bool value = true; 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' // 'long double'
FLOATING_TYPE(LongDouble, LongDoubleTy) FLOATING_TYPE(LongDouble, LongDoubleTy)
// '_Float16'
FLOATING_TYPE(Float16, HalfTy)
// '__float128' // '__float128'
FLOATING_TYPE(Float128, Float128Ty) FLOATING_TYPE(Float128, Float128Ty)

View File

@ -1,4 +1,4 @@
//===------ CXXInheritance.h - C++ Inheritance ------------------*- C++ -*-===// //===- CXXInheritance.h - C++ Inheritance -----------------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -16,19 +16,23 @@
#include "clang/AST/DeclBase.h" #include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h" #include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.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/MapVector.h"
#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include <cassert> #include "llvm/ADT/iterator_range.h"
#include <list> #include <list>
#include <memory>
#include <utility>
namespace clang { namespace clang {
class CXXBaseSpecifier; class ASTContext;
class CXXMethodDecl;
class CXXRecordDecl;
class NamedDecl; class NamedDecl;
/// \brief Represents an element in a path from a derived class to a /// \brief Represents an element in a path from a derived class to a
@ -66,12 +70,12 @@ struct CXXBasePathElement {
/// subobject is being used. /// subobject is being used.
class CXXBasePath : public SmallVector<CXXBasePathElement, 4> { class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
public: public:
CXXBasePath() : Access(AS_public) {}
/// \brief The access along this inheritance path. This is only /// \brief The access along this inheritance path. This is only
/// calculated when recording paths. AS_none is a special value /// calculated when recording paths. AS_none is a special value
/// used to indicate a path which permits no legal access. /// 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 /// \brief The set of declarations found inside this base class
/// subobject. /// subobject.
@ -113,8 +117,10 @@ public:
/// refer to the same base class subobject of type A (the virtual /// refer to the same base class subobject of type A (the virtual
/// one), there is no ambiguity. /// one), there is no ambiguity.
class CXXBasePaths { class CXXBasePaths {
friend class CXXRecordDecl;
/// \brief The type from which this search originated. /// \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 /// Paths - The actual set of paths that can be taken from the
/// derived class to the same base class. /// derived class to the same base class.
@ -152,15 +158,13 @@ class CXXBasePaths {
CXXBasePath ScratchPath; CXXBasePath ScratchPath;
/// DetectedVirtual - The base class that is virtual. /// DetectedVirtual - The base class that is virtual.
const RecordType *DetectedVirtual; const RecordType *DetectedVirtual = nullptr;
/// \brief Array of the declarations that have been found. This /// \brief Array of the declarations that have been found. This
/// array is constructed only if needed, e.g., to iterate over the /// array is constructed only if needed, e.g., to iterate over the
/// results within LookupResult. /// results within LookupResult.
std::unique_ptr<NamedDecl *[]> DeclsFound; std::unique_ptr<NamedDecl *[]> DeclsFound;
unsigned NumDeclsFound; unsigned NumDeclsFound = 0;
friend class CXXRecordDecl;
void ComputeDeclsFound(); void ComputeDeclsFound();
@ -169,17 +173,16 @@ class CXXBasePaths {
bool LookupInDependent = false); bool LookupInDependent = false);
public: public:
typedef std::list<CXXBasePath>::iterator paths_iterator; using paths_iterator = std::list<CXXBasePath>::iterator;
typedef std::list<CXXBasePath>::const_iterator const_paths_iterator; using const_paths_iterator = std::list<CXXBasePath>::const_iterator;
typedef NamedDecl **decl_iterator; using decl_iterator = NamedDecl **;
/// BasePaths - Construct a new BasePaths structure to record the /// BasePaths - Construct a new BasePaths structure to record the
/// paths for a derived-to-base search. /// paths for a derived-to-base search.
explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true, explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
bool DetectVirtual = true) bool DetectVirtual = true)
: Origin(), FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths), : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
DetectVirtual(DetectVirtual), DetectedVirtual(nullptr), DetectVirtual(DetectVirtual) {}
NumDeclsFound(0) {}
paths_iterator begin() { return Paths.begin(); } paths_iterator begin() { return Paths.begin(); }
paths_iterator end() { return Paths.end(); } paths_iterator end() { return Paths.end(); }
@ -189,7 +192,8 @@ public:
CXXBasePath& front() { return Paths.front(); } CXXBasePath& front() { return Paths.front(); }
const CXXBasePath& front() const { 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(); decl_range found_decls();
/// \brief Determine whether the path from the most-derived type to the /// \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 /// \brief Uniquely identifies a virtual method within a class
/// hierarchy by the method itself and a class subobject number. /// hierarchy by the method itself and a class subobject number.
struct UniqueVirtualMethod { 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. /// \brief The overriding virtual method.
CXXMethodDecl *Method; CXXMethodDecl *Method = nullptr;
/// \brief The subobject in which the overriding virtual method /// \brief The subobject in which the overriding virtual method
/// resides. /// resides.
unsigned Subobject; unsigned Subobject = 0;
/// \brief The virtual base class subobject of which this overridden /// \brief The virtual base class subobject of which this overridden
/// virtual method is a part. Note that this records the closest /// virtual method is a part. Note that this records the closest
/// derived virtual base class subobject. /// 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, friend bool operator==(const UniqueVirtualMethod &X,
const UniqueVirtualMethod &Y) { const UniqueVirtualMethod &Y) {
@ -271,14 +274,16 @@ struct UniqueVirtualMethod {
/// pair is the virtual method that overrides it (including the /// pair is the virtual method that overrides it (including the
/// subobject in which that virtual function occurs). /// subobject in which that virtual function occurs).
class OverridingMethods { class OverridingMethods {
typedef SmallVector<UniqueVirtualMethod, 4> ValuesT; using ValuesT = SmallVector<UniqueVirtualMethod, 4>;
typedef llvm::MapVector<unsigned, ValuesT> MapType; using MapType = llvm::MapVector<unsigned, ValuesT>;
MapType Overrides; MapType Overrides;
public: public:
// Iterate over the set of subobjects that have overriding methods. // Iterate over the set of subobjects that have overriding methods.
typedef MapType::iterator iterator; using iterator = MapType::iterator;
typedef MapType::const_iterator const_iterator; using const_iterator = MapType::const_iterator;
iterator begin() { return Overrides.begin(); } iterator begin() { return Overrides.begin(); }
const_iterator begin() const { return Overrides.begin(); } const_iterator begin() const { return Overrides.begin(); }
iterator end() { return Overrides.end(); } iterator end() { return Overrides.end(); }
@ -287,10 +292,10 @@ public:
// Iterate over the set of overriding virtual methods in a given // Iterate over the set of overriding virtual methods in a given
// subobject. // subobject.
typedef SmallVectorImpl<UniqueVirtualMethod>::iterator using overriding_iterator =
overriding_iterator; SmallVectorImpl<UniqueVirtualMethod>::iterator;
typedef SmallVectorImpl<UniqueVirtualMethod>::const_iterator using overriding_const_iterator =
overriding_const_iterator; SmallVectorImpl<UniqueVirtualMethod>::const_iterator;
// Add a new overriding method for a particular subobject. // Add a new overriding method for a particular subobject.
void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding); void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
@ -357,12 +362,12 @@ public:
/// subobject numbers greater than 0 refer to non-virtual base class /// subobject numbers greater than 0 refer to non-virtual base class
/// subobjects of that type. /// subobjects of that type.
class CXXFinalOverriderMap 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. /// \brief A set of all the primary bases for a class.
class CXXIndirectPrimaryBaseSet 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 // The LLVM Compiler Infrastructure
// //
@ -16,13 +16,29 @@
#define LLVM_CLANG_AST_CANONICALTYPE_H #define LLVM_CLANG_AST_CANONICALTYPE_H
#include "clang/AST/Type.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/ADT/iterator.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
#include <iterator>
#include <type_traits>
namespace clang { namespace clang {
template<typename T> class CanProxy; template<typename T> class CanProxy;
template<typename T> struct CanProxyAdaptor; 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 // 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 /// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
/// be implicitly converted to a QualType, but the reverse operation requires /// be implicitly converted to a QualType, but the reverse operation requires
/// a call to ASTContext::getCanonicalType(). /// a call to ASTContext::getCanonicalType().
///
///
template<typename T = Type> template<typename T = Type>
class CanQual { class CanQual {
/// \brief The actual, canonical type. /// \brief The actual, canonical type.
@ -55,7 +69,7 @@ class CanQual {
public: public:
/// \brief Constructs a NULL canonical type. /// \brief Constructs a NULL canonical type.
CanQual() : Stored() { } CanQual() = default;
/// \brief Converting constructor that permits implicit upcasting of /// \brief Converting constructor that permits implicit upcasting of
/// canonical type pointers. /// canonical type pointers.
@ -66,12 +80,11 @@ public:
/// \brief Retrieve the underlying type pointer, which refers to a /// \brief Retrieve the underlying type pointer, which refers to a
/// canonical type. /// 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()); } const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
/// \brief Retrieve the underlying type pointer, which refers to a /// \brief Retrieve the underlying type pointer, which refers to a
/// canonical type, or NULL. /// canonical type, or nullptr.
///
const T *getTypePtrOrNull() const { const T *getTypePtrOrNull() const {
return cast_or_null<T>(Stored.getTypePtrOrNull()); return cast_or_null<T>(Stored.getTypePtrOrNull());
} }
@ -125,9 +138,11 @@ public:
bool isConstQualified() const { bool isConstQualified() const {
return Stored.isLocalConstQualified(); return Stored.isLocalConstQualified();
} }
bool isVolatileQualified() const { bool isVolatileQualified() const {
return Stored.isLocalVolatileQualified(); return Stored.isLocalVolatileQualified();
} }
bool isRestrictQualified() const { bool isRestrictQualified() const {
return Stored.isLocalRestrictQualified(); return Stored.isLocalRestrictQualified();
} }
@ -195,7 +210,7 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) {
} }
/// \brief Represents a canonical, potentially-qualified type. /// \brief Represents a canonical, potentially-qualified type.
typedef CanQual<Type> CanQualType; using CanQualType = CanQual<Type>;
inline CanQualType Type::getCanonicalTypeUnqualified() const { inline CanQualType Type::getCanonicalTypeUnqualified() const {
return CanQualType::CreateUnsafe(getCanonicalTypeInternal()); return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
@ -320,7 +335,7 @@ public:
/// than the more typical @c QualType, to propagate the notion of "canonical" /// than the more typical @c QualType, to propagate the notion of "canonical"
/// through the system. /// through the system.
template<typename T> template<typename T>
struct CanProxyAdaptor : CanProxyBase<T> { }; struct CanProxyAdaptor : CanProxyBase<T> {};
/// \brief Canonical proxy type returned when retrieving the members of a /// \brief Canonical proxy type returned when retrieving the members of a
/// canonical type or as the result of the @c CanQual<T>::getAs member /// 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> { class CanProxy : public CanProxyAdaptor<T> {
public: public:
/// \brief Build a NULL proxy. /// \brief Build a NULL proxy.
CanProxy() { } CanProxy() = default;
/// \brief Build a proxy to the given canonical type. /// \brief Build a proxy to the given canonical type.
CanProxy(CanQual<T> Stored) { this->Stored = Stored; } CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
@ -342,7 +357,7 @@ public:
operator CanQual<T>() const { return this->Stored; } operator CanQual<T>() const { return this->Stored; }
}; };
} // end namespace clang } // namespace clang
namespace llvm { namespace llvm {
@ -350,8 +365,9 @@ namespace llvm {
/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc. /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
/// to return smart pointer (proxies?). /// to return smart pointer (proxies?).
template<typename T> template<typename T>
struct simplify_type< ::clang::CanQual<T> > { struct simplify_type< ::clang::CanQual<T>> {
typedef const T *SimpleType; using SimpleType = const T *;
static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) { static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
return Val.getTypePtr(); return Val.getTypePtr();
} }
@ -359,19 +375,20 @@ struct simplify_type< ::clang::CanQual<T> > {
// Teach SmallPtrSet that CanQual<T> is "basically a pointer". // Teach SmallPtrSet that CanQual<T> is "basically a pointer".
template<typename T> template<typename T>
class PointerLikeTypeTraits<clang::CanQual<T> > { struct PointerLikeTypeTraits<clang::CanQual<T>> {
public: static void *getAsVoidPointer(clang::CanQual<T> P) {
static inline void *getAsVoidPointer(clang::CanQual<T> P) {
return P.getAsOpaquePtr(); return P.getAsOpaquePtr();
} }
static inline clang::CanQual<T> getFromVoidPointer(void *P) {
static clang::CanQual<T> getFromVoidPointer(void *P) {
return clang::CanQual<T>::getFromOpaquePtr(P); return clang::CanQual<T>::getFromOpaquePtr(P);
} }
// qualifier information is encoded in the low bits. // qualifier information is encoded in the low bits.
enum { NumLowBitsAvailable = 0 }; enum { NumLowBitsAvailable = 0 };
}; };
} // end namespace llvm } // namespace llvm
namespace clang { namespace clang {
@ -389,7 +406,7 @@ struct CanTypeIterator
CanQualType, CanQualType,
typename std::iterator_traits<InputIterator>::difference_type, typename std::iterator_traits<InputIterator>::difference_type,
CanProxy<Type>, CanQualType> { CanProxy<Type>, CanQualType> {
CanTypeIterator() {} CanTypeIterator() = default;
explicit CanTypeIterator(InputIterator Iter) explicit CanTypeIterator(InputIterator Iter)
: CanTypeIterator::iterator_adaptor_base(std::move(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(bool, hasExtParameterInfos)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR( LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(
ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos) ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos)
CanQualType getParamType(unsigned i) const { CanQualType getParamType(unsigned i) const {
return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i)); 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(bool, isVariadic)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
typedef CanTypeIterator<FunctionProtoType::param_type_iterator> using param_type_iterator =
param_type_iterator; CanTypeIterator<FunctionProtoType::param_type_iterator>;
param_type_iterator param_type_begin() const { param_type_iterator param_type_begin() const {
return param_type_iterator(this->getTypePtr()->param_type_begin()); 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, isObjCQualifiedId)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass) 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_begin)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) 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, isObjCQualifiedIdType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType) 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_begin)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
@ -662,7 +682,6 @@ CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const {
return CanProxy<Type>(*this); return CanProxy<Type>(*this);
} }
} } // namespace clang
#endif // LLVM_CLANG_AST_CANONICALTYPE_H
#endif

View File

@ -40,14 +40,14 @@ namespace clang {
typedef int64_t QuantityType; typedef int64_t QuantityType;
private: private:
QuantityType Quantity; QuantityType Quantity = 0;
explicit CharUnits(QuantityType C) : Quantity(C) {} explicit CharUnits(QuantityType C) : Quantity(C) {}
public: public:
/// CharUnits - A default constructor. /// CharUnits - A default constructor.
CharUnits() : Quantity(0) {} CharUnits() = default;
/// Zero - Construct a CharUnits quantity of zero. /// Zero - Construct a CharUnits quantity of zero.
static CharUnits 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 // The LLVM Compiler Infrastructure
// //
@ -16,8 +16,8 @@
namespace clang { namespace clang {
namespace comments { namespace comments {
template <typename T> struct make_ptr { typedef T *type; }; template <typename T> struct make_ptr { using type = T *; };
template <typename T> struct make_const_ptr { typedef const T *type; }; template <typename T> struct make_const_ptr { using type = const T *; };
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void> template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
class CommentVisitorBase { class CommentVisitorBase {
@ -64,7 +64,7 @@ template<typename ImplClass, typename RetTy=void>
class ConstCommentVisitor : class ConstCommentVisitor :
public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {}; public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
} // end namespace comments } // namespace comments
} // end namespace clang } // 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 // The LLVM Compiler Infrastructure
// //
@ -16,33 +16,40 @@
#include "clang/AST/AttrIterator.h" #include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h" #include "clang/AST/DeclarationName.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h" #include "clang/Basic/Specifiers.h"
#include "clang/Basic/VersionTuple.h" #include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/PrettyStackTrace.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <string>
#include <type_traits>
#include <utility>
namespace clang { namespace clang {
class ASTContext;
class ASTMutationListener; class ASTMutationListener;
class BlockDecl; class Attr;
class CXXRecordDecl;
class CompoundStmt;
class DeclContext; class DeclContext;
class DeclarationName;
class DependentDiagnostic;
class EnumDecl;
class ExportDecl;
class ExternalSourceSymbolAttr; class ExternalSourceSymbolAttr;
class FunctionDecl; class FunctionDecl;
class FunctionType; class FunctionType;
class IdentifierInfo;
enum Linkage : unsigned char; enum Linkage : unsigned char;
class LinkageComputer;
class LinkageSpecDecl; class LinkageSpecDecl;
class Module; class Module;
class NamedDecl; class NamedDecl;
class NamespaceDecl;
class ObjCCategoryDecl; class ObjCCategoryDecl;
class ObjCCategoryImplDecl; class ObjCCategoryImplDecl;
class ObjCContainerDecl; class ObjCContainerDecl;
@ -53,23 +60,21 @@ class ObjCMethodDecl;
class ObjCProtocolDecl; class ObjCProtocolDecl;
struct PrintingPolicy; struct PrintingPolicy;
class RecordDecl; class RecordDecl;
class SourceManager;
class Stmt; class Stmt;
class StoredDeclsMap; class StoredDeclsMap;
class TemplateDecl; class TemplateDecl;
class TranslationUnitDecl; class TranslationUnitDecl;
class UsingDirectiveDecl; class UsingDirectiveDecl;
}
namespace clang { /// \brief Captures the result of checking the availability of a
/// declaration.
/// \brief Captures the result of checking the availability of a enum AvailabilityResult {
/// declaration. AR_Available = 0,
enum AvailabilityResult { AR_NotYetIntroduced,
AR_Available = 0, AR_Deprecated,
AR_NotYetIntroduced, AR_Unavailable
AR_Deprecated, };
AR_Unavailable
};
/// Decl - This represents one declaration (or definition), e.g. a variable, /// Decl - This represents one declaration (or definition), e.g. a variable,
/// typedef, function, struct, etc. /// typedef, function, struct, etc.
@ -94,7 +99,7 @@ public:
/// \brief A placeholder type used to construct an empty shell of a /// \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 /// decl-derived type that will be filled in later (e.g., by some
/// deserialization method). /// deserialization method).
struct EmptyShell { }; struct EmptyShell {};
/// IdentifierNamespace - The different namespaces in which /// IdentifierNamespace - The different namespaces in which
/// declarations may appear. According to C99 6.2.3, there are /// declarations may appear. According to C99 6.2.3, there are
@ -208,15 +213,18 @@ public:
enum class ModuleOwnershipKind : unsigned { enum class ModuleOwnershipKind : unsigned {
/// This declaration is not owned by a module. /// This declaration is not owned by a module.
Unowned, Unowned,
/// This declaration has an owning module, but is globally visible /// This declaration has an owning module, but is globally visible
/// (typically because its owning module is visible and we know that /// (typically because its owning module is visible and we know that
/// modules cannot later become hidden in this compilation). /// modules cannot later become hidden in this compilation).
/// After serialization and deserialization, this will be converted /// After serialization and deserialization, this will be converted
/// to VisibleWhenImported. /// to VisibleWhenImported.
Visible, Visible,
/// This declaration has an owning module, and is visible when that /// This declaration has an owning module, and is visible when that
/// module is imported. /// module is imported.
VisibleWhenImported, VisibleWhenImported,
/// This declaration has an owning module, but is only visible to /// This declaration has an owning module, but is only visible to
/// lookups that occur within that module. /// lookups that occur within that module.
ModulePrivate ModulePrivate
@ -238,7 +246,6 @@ private:
DeclContext *LexicalDC; DeclContext *LexicalDC;
}; };
/// DeclCtx - Holds either a DeclContext* or a MultipleDC*. /// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
/// For declarations that don't contain C++ scope specifiers, it contains /// For declarations that don't contain C++ scope specifiers, it contains
/// the DeclContext where the Decl was declared. /// the DeclContext where the Decl was declared.
@ -254,12 +261,14 @@ private:
/// // LexicalDC == global namespace /// // LexicalDC == global namespace
llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx; llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
inline bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); } bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); } bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
inline MultipleDC *getMultipleDC() const {
MultipleDC *getMultipleDC() const {
return DeclCtx.get<MultipleDC*>(); return DeclCtx.get<MultipleDC*>();
} }
inline DeclContext *getSemanticDC() const {
DeclContext *getSemanticDC() const {
return DeclCtx.get<DeclContext*>(); return DeclCtx.get<DeclContext*>();
} }
@ -298,10 +307,16 @@ private:
static bool StatisticsEnabled; static bool StatisticsEnabled;
protected: 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. /// Access - Used by C++ decls for the access specifier.
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
unsigned Access : 2; unsigned Access : 2;
friend class CXXClassMemberWrapper;
/// \brief Whether this declaration was loaded from an AST file. /// \brief Whether this declaration was loaded from an AST file.
unsigned FromASTFile : 1; unsigned FromASTFile : 1;
@ -313,13 +328,6 @@ protected:
/// Otherwise, it is the linkage + 1. /// Otherwise, it is the linkage + 1.
mutable unsigned CacheValidAndLinkage : 3; 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. /// \brief Allocate memory for a deserialized declaration.
/// ///
/// This routine must be used to allocate memory for any declaration that is /// This routine must be used to allocate memory for any declaration that is
@ -357,7 +365,7 @@ private:
protected: protected:
Decl(Kind DK, DeclContext *DC, SourceLocation L) Decl(Kind DK, DeclContext *DC, SourceLocation L)
: NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)), : 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), Implicit(false), Used(false), Referenced(false),
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)), IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
@ -366,9 +374,9 @@ protected:
} }
Decl(Kind DK, EmptyShell Empty) Decl(Kind DK, EmptyShell Empty)
: NextInContextAndBits(), DeclKind(DK), InvalidDecl(0), HasAttrs(false), : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false),
Implicit(false), Used(false), Referenced(false), Used(false), Referenced(false), TopLevelDeclInObjCContainer(false),
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)), IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
CacheValidAndLinkage(0) { CacheValidAndLinkage(0) {
if (StatisticsEnabled) add(DK); if (StatisticsEnabled) add(DK);
@ -392,14 +400,15 @@ protected:
} }
public: public:
/// \brief Source range that this declaration covers. /// \brief Source range that this declaration covers.
virtual SourceRange getSourceRange() const LLVM_READONLY { virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLocation(), getLocation()); return SourceRange(getLocation(), getLocation());
} }
SourceLocation getLocStart() const LLVM_READONLY { SourceLocation getLocStart() const LLVM_READONLY {
return getSourceRange().getBegin(); return getSourceRange().getBegin();
} }
SourceLocation getLocEnd() const LLVM_READONLY { SourceLocation getLocEnd() const LLVM_READONLY {
return getSourceRange().getEnd(); return getSourceRange().getEnd();
} }
@ -460,12 +469,15 @@ public:
} }
bool hasAttrs() const { return HasAttrs; } bool hasAttrs() const { return HasAttrs; }
void setAttrs(const AttrVec& Attrs) { void setAttrs(const AttrVec& Attrs) {
return setAttrsImpl(Attrs, getASTContext()); return setAttrsImpl(Attrs, getASTContext());
} }
AttrVec &getAttrs() { AttrVec &getAttrs() {
return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs()); return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
} }
const AttrVec &getAttrs() const; const AttrVec &getAttrs() const;
void dropAttrs(); void dropAttrs();
@ -476,8 +488,8 @@ public:
setAttrs(AttrVec(1, A)); setAttrs(AttrVec(1, A));
} }
typedef AttrVec::const_iterator attr_iterator; using attr_iterator = AttrVec::const_iterator;
typedef llvm::iterator_range<attr_iterator> attr_range; using attr_range = llvm::iterator_range<attr_iterator>;
attr_range attrs() const { attr_range attrs() const {
return attr_range(attr_begin(), attr_end()); return attr_range(attr_begin(), attr_end());
@ -510,6 +522,7 @@ public:
specific_attr_iterator<T> specific_attr_begin() const { specific_attr_iterator<T> specific_attr_begin() const {
return specific_attr_iterator<T>(attr_begin()); return specific_attr_iterator<T>(attr_begin());
} }
template <typename T> template <typename T>
specific_attr_iterator<T> specific_attr_end() const { specific_attr_iterator<T> specific_attr_end() const {
return specific_attr_iterator<T>(attr_end()); return specific_attr_iterator<T>(attr_end());
@ -518,6 +531,7 @@ public:
template<typename T> T *getAttr() const { template<typename T> T *getAttr() const {
return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr; return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr;
} }
template<typename T> bool hasAttr() const { template<typename T> bool hasAttr() const {
return hasAttrs() && hasSpecificAttr<T>(getAttrs()); return hasAttrs() && hasSpecificAttr<T>(getAttrs());
} }
@ -616,7 +630,6 @@ protected:
} }
public: public:
/// \brief Determine the availability of the given declaration. /// \brief Determine the availability of the given declaration.
/// ///
/// This routine will determine the most restrictive availability of /// This routine will determine the most restrictive availability of
@ -698,6 +711,7 @@ public:
private: private:
Module *getOwningModuleSlow() const; Module *getOwningModuleSlow() const;
protected: protected:
bool hasLocalOwningModuleStorage() const; bool hasLocalOwningModuleStorage() const;
@ -733,11 +747,18 @@ public:
return getModuleOwnershipKind() != ModuleOwnershipKind::Unowned; return getModuleOwnershipKind() != ModuleOwnershipKind::Unowned;
} }
/// Get the module that owns this declaration. /// Get the module that owns this declaration (for visibility purposes).
Module *getOwningModule() const { Module *getOwningModule() const {
return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule(); 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 /// \brief Determine whether this declaration might be hidden from name
/// lookup. Note that the declaration might be visible even if this returns /// lookup. Note that the declaration might be visible even if this returns
/// \c false, if the owning module is visible within the query context. /// \c false, if the owning module is visible within the query context.
@ -770,14 +791,17 @@ public:
unsigned getIdentifierNamespace() const { unsigned getIdentifierNamespace() const {
return IdentifierNamespace; return IdentifierNamespace;
} }
bool isInIdentifierNamespace(unsigned NS) const { bool isInIdentifierNamespace(unsigned NS) const {
return getIdentifierNamespace() & NS; return getIdentifierNamespace() & NS;
} }
static unsigned getIdentifierNamespaceForKind(Kind DK); static unsigned getIdentifierNamespaceForKind(Kind DK);
bool hasTagIdentifierNamespace() const { bool hasTagIdentifierNamespace() const {
return isTagIdentifierNamespace(getIdentifierNamespace()); return isTagIdentifierNamespace(getIdentifierNamespace());
} }
static bool isTagIdentifierNamespace(unsigned NS) { static bool isTagIdentifierNamespace(unsigned NS) {
// TagDecls have Tag and Type set and may also have TagFriend. // TagDecls have Tag and Type set and may also have TagFriend.
return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type); return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type);
@ -865,18 +889,18 @@ public:
/// \brief Iterates through all the redeclarations of the same decl. /// \brief Iterates through all the redeclarations of the same decl.
class redecl_iterator { class redecl_iterator {
/// Current - The current declaration. /// Current - The current declaration.
Decl *Current; Decl *Current = nullptr;
Decl *Starter; Decl *Starter;
public: public:
typedef Decl *value_type; using value_type = Decl *;
typedef const value_type &reference; using reference = const value_type &;
typedef const value_type *pointer; using pointer = const value_type *;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
typedef std::ptrdiff_t difference_type; using difference_type = std::ptrdiff_t;
redecl_iterator() : Current(nullptr) { } redecl_iterator() = default;
explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { } explicit redecl_iterator(Decl *C) : Current(C), Starter(C) {}
reference operator*() const { return Current; } reference operator*() const { return Current; }
value_type operator->() const { return Current; } value_type operator->() const { return Current; }
@ -899,12 +923,13 @@ public:
friend bool operator==(redecl_iterator x, redecl_iterator y) { friend bool operator==(redecl_iterator x, redecl_iterator y) {
return x.Current == y.Current; return x.Current == y.Current;
} }
friend bool operator!=(redecl_iterator x, redecl_iterator y) { friend bool operator!=(redecl_iterator x, redecl_iterator y) {
return x.Current != y.Current; 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 /// \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). /// decl. It will iterate at least once (when this decl is the only one).
@ -915,6 +940,7 @@ public:
redecl_iterator redecls_begin() const { redecl_iterator redecls_begin() const {
return redecl_iterator(const_cast<Decl *>(this)); return redecl_iterator(const_cast<Decl *>(this));
} }
redecl_iterator redecls_end() const { return redecl_iterator(); } redecl_iterator redecls_end() const { return redecl_iterator(); }
/// \brief Retrieve the previous declaration that declares the same entity /// \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 /// declaration, but in the semantic context of the enclosing namespace
/// scope. /// scope.
void setLocalExternDecl() { void setLocalExternDecl() {
assert((IdentifierNamespace == IDNS_Ordinary ||
IdentifierNamespace == IDNS_OrdinaryFriend) &&
"namespace is not ordinary");
Decl *Prev = getPreviousDecl(); Decl *Prev = getPreviousDecl();
IdentifierNamespace &= ~IDNS_Ordinary; 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; IdentifierNamespace |= IDNS_LocalExtern;
if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary) if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)
IdentifierNamespace |= IDNS_Ordinary; IdentifierNamespace |= IDNS_Ordinary;
@ -1094,10 +1122,13 @@ public:
static void printGroup(Decl** Begin, unsigned NumDecls, static void printGroup(Decl** Begin, unsigned NumDecls,
raw_ostream &Out, const PrintingPolicy &Policy, raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation = 0); unsigned Indentation = 0);
// Debuggers don't usually respect default arguments. // Debuggers don't usually respect default arguments.
void dump() const; void dump() const;
// Same as dump(), but forces color printing. // Same as dump(), but forces color printing.
void dumpColor() const; void dumpColor() const;
void dump(raw_ostream &Out, bool Deserialize = false) const; void dump(raw_ostream &Out, bool Deserialize = false) const;
/// \brief Looks through the Decl's underlying type to extract a FunctionType /// \brief Looks through the Decl's underlying type to extract a FunctionType
@ -1132,10 +1163,11 @@ class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
SourceLocation Loc; SourceLocation Loc;
SourceManager &SM; SourceManager &SM;
const char *Message; const char *Message;
public: public:
PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L, PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
SourceManager &sm, const char *Msg) 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; void print(raw_ostream &OS) const override;
}; };
@ -1144,30 +1176,35 @@ public:
/// single result (with no stable storage) or a collection of results (with /// single result (with no stable storage) or a collection of results (with
/// stable storage provided by the lookup table). /// stable storage provided by the lookup table).
class DeclContextLookupResult { class DeclContextLookupResult {
typedef ArrayRef<NamedDecl *> ResultTy; using ResultTy = ArrayRef<NamedDecl *>;
ResultTy Result; ResultTy Result;
// If there is only one lookup result, it would be invalidated by // If there is only one lookup result, it would be invalidated by
// reallocations of the name table, so store it separately. // reallocations of the name table, so store it separately.
NamedDecl *Single; NamedDecl *Single = nullptr;
static NamedDecl *const SingleElementDummyList; static NamedDecl *const SingleElementDummyList;
public: public:
DeclContextLookupResult() : Result(), Single() {} DeclContextLookupResult() = default;
DeclContextLookupResult(ArrayRef<NamedDecl *> Result) DeclContextLookupResult(ArrayRef<NamedDecl *> Result)
: Result(Result), Single() {} : Result(Result) {}
DeclContextLookupResult(NamedDecl *Single) DeclContextLookupResult(NamedDecl *Single)
: Result(SingleElementDummyList), Single(Single) {} : Result(SingleElementDummyList), Single(Single) {}
class iterator; class iterator;
typedef llvm::iterator_adaptor_base<iterator, ResultTy::iterator,
std::random_access_iterator_tag, using IteratorBase =
NamedDecl *const> IteratorBase; llvm::iterator_adaptor_base<iterator, ResultTy::iterator,
std::random_access_iterator_tag,
NamedDecl *const>;
class iterator : public IteratorBase { class iterator : public IteratorBase {
value_type SingleElement; value_type SingleElement;
public: public:
iterator() : IteratorBase(), SingleElement() {} iterator() = default;
explicit iterator(pointer Pos, value_type Single = nullptr) explicit iterator(pointer Pos, value_type Single = nullptr)
: IteratorBase(Pos), SingleElement(Single) {} : IteratorBase(Pos), SingleElement(Single) {}
@ -1175,9 +1212,10 @@ public:
return SingleElement ? SingleElement : IteratorBase::operator*(); return SingleElement ? SingleElement : IteratorBase::operator*();
} }
}; };
typedef iterator const_iterator;
typedef iterator::pointer pointer; using const_iterator = iterator;
typedef iterator::reference reference; using pointer = iterator::pointer;
using reference = iterator::reference;
iterator begin() const { return iterator(Result.begin(), Single); } iterator begin() const { return iterator(Result.begin(), Single); }
iterator end() const { return iterator(Result.end(), Single); } iterator end() const { return iterator(Result.end(), Single); }
@ -1211,7 +1249,6 @@ public:
/// ExportDecl /// ExportDecl
/// BlockDecl /// BlockDecl
/// OMPDeclareReductionDecl /// OMPDeclareReductionDecl
///
class DeclContext { class DeclContext {
/// DeclKind - This indicates which class this is. /// DeclKind - This indicates which class this is.
unsigned DeclKind : 8; unsigned DeclKind : 8;
@ -1251,22 +1288,22 @@ class DeclContext {
/// contains an entry for a DeclarationName (and we haven't lazily /// contains an entry for a DeclarationName (and we haven't lazily
/// omitted anything), then it contains all relevant entries for that /// omitted anything), then it contains all relevant entries for that
/// name (modulo the hasExternalDecls() flag). /// name (modulo the hasExternalDecls() flag).
mutable StoredDeclsMap *LookupPtr; mutable StoredDeclsMap *LookupPtr = nullptr;
protected: protected:
friend class ASTDeclReader;
friend class ASTWriter;
friend class ExternalASTSource;
/// FirstDecl - The first declaration stored within this declaration /// FirstDecl - The first declaration stored within this declaration
/// context. /// context.
mutable Decl *FirstDecl; mutable Decl *FirstDecl = nullptr;
/// LastDecl - The last declaration stored within this declaration /// LastDecl - The last declaration stored within this declaration
/// context. FIXME: We could probably cache this value somewhere /// context. FIXME: We could probably cache this value somewhere
/// outside of the DeclContext, to reduce the size of DeclContext by /// outside of the DeclContext, to reduce the size of DeclContext by
/// another pointer. /// another pointer.
mutable Decl *LastDecl; mutable Decl *LastDecl = nullptr;
friend class ExternalASTSource;
friend class ASTDeclReader;
friend class ASTWriter;
/// \brief Build up a chain of declarations. /// \brief Build up a chain of declarations.
/// ///
@ -1279,8 +1316,7 @@ protected:
ExternalVisibleStorage(false), ExternalVisibleStorage(false),
NeedToReconcileExternalVisibleStorage(false), NeedToReconcileExternalVisibleStorage(false),
HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false), HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false),
UseQualifiedLookup(false), UseQualifiedLookup(false) {}
LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {}
public: public:
~DeclContext(); ~DeclContext();
@ -1288,6 +1324,7 @@ public:
Decl::Kind getDeclKind() const { Decl::Kind getDeclKind() const {
return static_cast<Decl::Kind>(DeclKind); return static_cast<Decl::Kind>(DeclKind);
} }
const char *getDeclKindName() const; const char *getDeclKindName() const;
/// getParent - Returns the containing DeclContext. /// getParent - Returns the containing DeclContext.
@ -1495,19 +1532,20 @@ public:
/// within this context. /// within this context.
class decl_iterator { class decl_iterator {
/// Current - The current declaration. /// Current - The current declaration.
Decl *Current; Decl *Current = nullptr;
public: public:
typedef Decl *value_type; using value_type = Decl *;
typedef const value_type &reference; using reference = const value_type &;
typedef const value_type *pointer; using pointer = const value_type *;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
typedef std::ptrdiff_t difference_type; using difference_type = std::ptrdiff_t;
decl_iterator() : Current(nullptr) { } decl_iterator() = default;
explicit decl_iterator(Decl *C) : Current(C) { } explicit decl_iterator(Decl *C) : Current(C) {}
reference operator*() const { return Current; } reference operator*() const { return Current; }
// This doesn't meet the iterator requirements, but it's convenient // This doesn't meet the iterator requirements, but it's convenient
value_type operator->() const { return Current; } value_type operator->() const { return Current; }
@ -1525,12 +1563,13 @@ public:
friend bool operator==(decl_iterator x, decl_iterator y) { friend bool operator==(decl_iterator x, decl_iterator y) {
return x.Current == y.Current; return x.Current == y.Current;
} }
friend bool operator!=(decl_iterator x, decl_iterator y) { friend bool operator!=(decl_iterator x, decl_iterator y) {
return x.Current != y.Current; 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 /// decls_begin/decls_end - Iterate over the declarations stored in
/// this context. /// this context.
@ -1569,16 +1608,16 @@ public:
} }
public: public:
typedef SpecificDecl *value_type; using value_type = SpecificDecl *;
// TODO: Add reference and pointer typedefs (with some appropriate proxy // TODO: Add reference and pointer types (with some appropriate proxy type)
// type) if we ever have a need for them. // if we ever have a need for them.
typedef void reference; using reference = void;
typedef void pointer; using pointer = void;
typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type using difference_type =
difference_type; std::iterator_traits<DeclContext::decl_iterator>::difference_type;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
specific_decl_iterator() : Current() { } specific_decl_iterator() = default;
/// specific_decl_iterator - Construct a new iterator over a /// specific_decl_iterator - Construct a new iterator over a
/// subset of the declarations the range [C, /// subset of the declarations the range [C,
@ -1593,6 +1632,7 @@ public:
} }
value_type operator*() const { return cast<SpecificDecl>(*Current); } value_type operator*() const { return cast<SpecificDecl>(*Current); }
// This doesn't meet the iterator requirements, but it's convenient // This doesn't meet the iterator requirements, but it's convenient
value_type operator->() const { return **this; } value_type operator->() const { return **this; }
@ -1646,16 +1686,16 @@ public:
} }
public: public:
typedef SpecificDecl *value_type; using value_type = SpecificDecl *;
// TODO: Add reference and pointer typedefs (with some appropriate proxy // TODO: Add reference and pointer types (with some appropriate proxy type)
// type) if we ever have a need for them. // if we ever have a need for them.
typedef void reference; using reference = void;
typedef void pointer; using pointer = void;
typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type using difference_type =
difference_type; std::iterator_traits<DeclContext::decl_iterator>::difference_type;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
filtered_decl_iterator() : Current() { } filtered_decl_iterator() = default;
/// filtered_decl_iterator - Construct a new iterator over a /// filtered_decl_iterator - Construct a new iterator over a
/// subset of the declarations the range [C, /// subset of the declarations the range [C,
@ -1733,8 +1773,8 @@ public:
/// @brief Checks whether a declaration is in this context. /// @brief Checks whether a declaration is in this context.
bool containsDecl(Decl *D) const; bool containsDecl(Decl *D) const;
typedef DeclContextLookupResult lookup_result; using lookup_result = DeclContextLookupResult;
typedef lookup_result::iterator lookup_iterator; using lookup_iterator = lookup_result::iterator;
/// lookup - Find the declarations (if any) with the given Name in /// lookup - Find the declarations (if any) with the given Name in
/// this context. Returns a range of iterators that contains all of /// this context. Returns a range of iterators that contains all of
@ -1780,7 +1820,7 @@ public:
/// of looking up every possible name. /// of looking up every possible name.
class all_lookups_iterator; 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 lookups() const;
lookups_range noload_lookups() const; lookups_range noload_lookups() const;
@ -1796,21 +1836,26 @@ public:
all_lookups_iterator noload_lookups_end() const; all_lookups_iterator noload_lookups_end() const;
struct udir_iterator; struct udir_iterator;
typedef llvm::iterator_adaptor_base<udir_iterator, lookup_iterator,
std::random_access_iterator_tag, using udir_iterator_base =
UsingDirectiveDecl *> udir_iterator_base; llvm::iterator_adaptor_base<udir_iterator, lookup_iterator,
std::random_access_iterator_tag,
UsingDirectiveDecl *>;
struct udir_iterator : udir_iterator_base { struct udir_iterator : udir_iterator_base {
udir_iterator(lookup_iterator I) : udir_iterator_base(I) {} udir_iterator(lookup_iterator I) : udir_iterator_base(I) {}
UsingDirectiveDecl *operator*() const; UsingDirectiveDecl *operator*() const;
}; };
typedef llvm::iterator_range<udir_iterator> udir_range; using udir_range = llvm::iterator_range<udir_iterator>;
udir_range using_directives() const; udir_range using_directives() const;
// These are all defined in DependentDiagnostic.h. // These are all defined in DependentDiagnostic.h.
class ddiag_iterator; 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; inline ddiag_range ddiags() const;
@ -1883,6 +1928,8 @@ public:
bool Deserialize = false) const; bool Deserialize = false) const;
private: private:
friend class DependentDiagnostic;
void reconcileExternalVisibleStorage() const; void reconcileExternalVisibleStorage() const;
bool LoadLexicalDeclsFromExternalStorage() const; bool LoadLexicalDeclsFromExternalStorage() const;
@ -1894,7 +1941,6 @@ private:
/// use of addDeclInternal(). /// use of addDeclInternal().
void makeDeclVisibleInContextInternal(NamedDecl *D); void makeDeclVisibleInContextInternal(NamedDecl *D);
friend class DependentDiagnostic;
StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
void buildLookupImpl(DeclContext *DCtx, bool Internal); void buildLookupImpl(DeclContext *DCtx, bool Internal);
@ -1933,8 +1979,7 @@ struct cast_convert_decl_context<ToTy, true> {
} }
}; };
} // namespace clang
} // end clang.
namespace llvm { namespace llvm {
@ -1954,12 +1999,14 @@ struct cast_convert_val<ToTy,
return *::clang::cast_convert_decl_context<ToTy>::doit(&Val); return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
} }
}; };
template<class ToTy> template<class ToTy>
struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> { struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
static ToTy &doit(::clang::DeclContext &Val) { static ToTy &doit(::clang::DeclContext &Val) {
return *::clang::cast_convert_decl_context<ToTy>::doit(&Val); return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
} }
}; };
template<class ToTy> template<class ToTy>
struct cast_convert_val<ToTy, struct cast_convert_val<ToTy,
const ::clang::DeclContext*, const ::clang::DeclContext*> { const ::clang::DeclContext*, const ::clang::DeclContext*> {
@ -1967,6 +2014,7 @@ struct cast_convert_val<ToTy,
return ::clang::cast_convert_decl_context<ToTy>::doit(Val); return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
} }
}; };
template<class ToTy> template<class ToTy>
struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> { struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
static ToTy *doit(::clang::DeclContext *Val) { 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 // The LLVM Compiler Infrastructure
// //
@ -11,10 +11,12 @@
// of DeclContext. // of DeclContext.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H #ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H #define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclarationName.h" #include "clang/AST/DeclarationName.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
@ -22,6 +24,7 @@
#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include <algorithm> #include <algorithm>
#include <cassert>
namespace clang { namespace clang {
@ -30,21 +33,20 @@ class DependentDiagnostic;
/// \brief An array of decls optimized for the common case of only containing /// \brief An array of decls optimized for the common case of only containing
/// one entry. /// one entry.
struct StoredDeclsList { struct StoredDeclsList {
/// \brief When in vector form, this is what the Data pointer points to. /// \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 /// \brief A collection of declarations, with a flag to indicate if we have
/// further external declarations. /// 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, /// \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 /// or a pointer to a vector with a flag to indicate if there are further
/// external declarations. /// external declarations.
llvm::PointerUnion<NamedDecl*, DeclsAndHasExternalTy> Data; llvm::PointerUnion<NamedDecl *, DeclsAndHasExternalTy> Data;
public: public:
StoredDeclsList() {} StoredDeclsList() = default;
StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) { StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
RHS.Data = (NamedDecl *)nullptr; RHS.Data = (NamedDecl *)nullptr;
@ -186,7 +188,6 @@ public:
/// AddSubsequentDecl - This is called on the second and later decl when it is /// 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. /// not a redeclaration to merge it into the appropriate place in our list.
///
void AddSubsequentDecl(NamedDecl *D) { void AddSubsequentDecl(NamedDecl *D) {
assert(!isNull() && "don't AddSubsequentDecl when we have no decls"); assert(!isNull() && "don't AddSubsequentDecl when we have no decls");
@ -237,28 +238,28 @@ public:
}; };
class StoredDeclsMap class StoredDeclsMap
: public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> { : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
public: public:
static void DestroyAll(StoredDeclsMap *Map, bool Dependent); static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
private: private:
friend class ASTContext; // walks the chain deleting these friend class ASTContext; // walks the chain deleting these
friend class DeclContext; friend class DeclContext;
llvm::PointerIntPair<StoredDeclsMap*, 1> Previous; llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
}; };
class DependentStoredDeclsMap : public StoredDeclsMap { class DependentStoredDeclsMap : public StoredDeclsMap {
public: public:
DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {} DependentStoredDeclsMap() = default;
private: private:
friend class DependentDiagnostic;
friend class DeclContext; // iterates over diagnostics 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 // The LLVM Compiler Infrastructure
// //
@ -15,16 +15,30 @@
#ifndef LLVM_CLANG_AST_DECLFRIEND_H #ifndef LLVM_CLANG_AST_DECLFRIEND_H
#define 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/DeclCXX.h"
#include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/TypeLoc.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/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
#include <cassert>
#include <iterator>
namespace clang { namespace clang {
class ASTContext;
/// FriendDecl - Represents the declaration of a friend entity, /// FriendDecl - Represents the declaration of a friend entity,
/// which can be a function, a type, or a templated function or type. /// which can be a function, a type, or a templated function or type.
// For example: /// For example:
/// ///
/// @code /// @code
/// template <typename T> class A { /// template <typename T> class A {
@ -41,10 +55,14 @@ class FriendDecl final
: public Decl, : public Decl,
private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> { private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> {
virtual void anchor(); virtual void anchor();
public: public:
typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion; using FriendUnion = llvm::PointerUnion<NamedDecl *, TypeSourceInfo *>;
private: private:
friend class CXXRecordDecl;
friend class CXXRecordDecl::friend_iterator;
// The declaration that's a friend of this class. // The declaration that's a friend of this class.
FriendUnion Friend; FriendUnion Friend;
@ -64,35 +82,33 @@ private:
// template <class T> friend class A<T>::B; // template <class T> friend class A<T>::B;
unsigned NumTPLists : 31; unsigned NumTPLists : 31;
friend class CXXRecordDecl::friend_iterator;
friend class CXXRecordDecl;
FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend, FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
SourceLocation FriendL, SourceLocation FriendL,
ArrayRef<TemplateParameterList*> FriendTypeTPLists) ArrayRef<TemplateParameterList *> FriendTypeTPLists)
: Decl(Decl::Friend, DC, L), : Decl(Decl::Friend, DC, L), Friend(Friend), FriendLoc(FriendL),
Friend(Friend), UnsupportedFriend(false), NumTPLists(FriendTypeTPLists.size()) {
NextFriend(),
FriendLoc(FriendL),
UnsupportedFriend(false),
NumTPLists(FriendTypeTPLists.size()) {
for (unsigned i = 0; i < NumTPLists; ++i) for (unsigned i = 0; i < NumTPLists; ++i)
getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i]; getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i];
} }
FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists) FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
: Decl(Decl::Friend, Empty), NextFriend(), : Decl(Decl::Friend, Empty), UnsupportedFriend(false),
UnsupportedFriend(false), NumTPLists(NumFriendTypeTPLists) {}
NumTPLists(NumFriendTypeTPLists) { }
FriendDecl *getNextFriend() { FriendDecl *getNextFriend() {
if (!NextFriend.isOffset()) if (!NextFriend.isOffset())
return cast_or_null<FriendDecl>(NextFriend.get(nullptr)); return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
return getNextFriendSlowCase(); return getNextFriendSlowCase();
} }
FriendDecl *getNextFriendSlowCase(); FriendDecl *getNextFriendSlowCase();
public: public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
friend class ASTNodeImporter;
friend TrailingObjects;
static FriendDecl *Create(ASTContext &C, DeclContext *DC, static FriendDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, FriendUnion Friend_, SourceLocation L, FriendUnion Friend_,
SourceLocation FriendL, SourceLocation FriendL,
@ -108,9 +124,11 @@ public:
TypeSourceInfo *getFriendType() const { TypeSourceInfo *getFriendType() const {
return Friend.dyn_cast<TypeSourceInfo*>(); return Friend.dyn_cast<TypeSourceInfo*>();
} }
unsigned getFriendTypeNumTemplateParameterLists() const { unsigned getFriendTypeNumTemplateParameterLists() const {
return NumTPLists; return NumTPLists;
} }
TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const { TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
assert(N < NumTPLists); assert(N < NumTPLists);
return getTrailingObjects<TemplateParameterList *>()[N]; return getTrailingObjects<TemplateParameterList *>()[N];
@ -119,7 +137,7 @@ public:
/// If this friend declaration doesn't name a type, return the inner /// If this friend declaration doesn't name a type, return the inner
/// declaration. /// declaration.
NamedDecl *getFriendDecl() const { NamedDecl *getFriendDecl() const {
return Friend.dyn_cast<NamedDecl*>(); return Friend.dyn_cast<NamedDecl *>();
} }
/// Retrieves the location of the 'friend' keyword. /// Retrieves the location of the 'friend' keyword.
@ -164,27 +182,24 @@ public:
// Implement isa/cast/dyncast/etc. // Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decl::Friend; } 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. /// An iterator over the friend declarations of a class.
class CXXRecordDecl::friend_iterator { class CXXRecordDecl::friend_iterator {
friend class CXXRecordDecl;
FriendDecl *Ptr; FriendDecl *Ptr;
friend class CXXRecordDecl;
explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {} explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {}
public:
friend_iterator() {}
typedef FriendDecl *value_type; public:
typedef FriendDecl *reference; friend_iterator() = default;
typedef FriendDecl *pointer;
typedef int difference_type; using value_type = FriendDecl *;
typedef std::forward_iterator_tag iterator_category; using reference = FriendDecl *;
using pointer = FriendDecl *;
using difference_type = int;
using iterator_category = std::forward_iterator_tag;
reference operator*() const { return Ptr; } reference operator*() const { return Ptr; }
@ -240,6 +255,6 @@ inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
data().FirstFriend = 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 // The LLVM Compiler Infrastructure
// //
@ -14,26 +14,26 @@
#ifndef LLVM_CLANG_AST_DECLGROUP_H #ifndef LLVM_CLANG_AST_DECLGROUP_H
#define LLVM_CLANG_AST_DECLGROUP_H #define LLVM_CLANG_AST_DECLGROUP_H
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TrailingObjects.h" #include "llvm/Support/TrailingObjects.h"
#include <cassert> #include <cassert>
#include <cstdint>
namespace clang { namespace clang {
class ASTContext; class ASTContext;
class Decl; class Decl;
class DeclGroup;
class DeclGroupIterator;
class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> { class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> {
// FIXME: Include a TypeSpecifier object. // FIXME: Include a TypeSpecifier object.
unsigned NumDecls; unsigned NumDecls = 0;
private: private:
DeclGroup() : NumDecls(0) {} DeclGroup() = default;
DeclGroup(unsigned numdecls, Decl** decls); DeclGroup(unsigned numdecls, Decl** decls);
public: public:
friend TrailingObjects;
static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls); static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
unsigned size() const { return NumDecls; } unsigned size() const { return NumDecls; }
@ -47,23 +47,21 @@ public:
assert (i < NumDecls && "Out-of-bounds access."); assert (i < NumDecls && "Out-of-bounds access.");
return getTrailingObjects<Decl *>()[i]; return getTrailingObjects<Decl *>()[i];
} }
friend TrailingObjects;
}; };
class DeclGroupRef { class DeclGroupRef {
// Note this is not a PointerIntPair because we need the address of the // Note this is not a PointerIntPair because we need the address of the
// non-group case to be valid as a Decl** for iteration. // non-group case to be valid as a Decl** for iteration.
enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 }; enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
Decl* D;
Decl* D = nullptr;
Kind getKind() const { Kind getKind() const {
return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask); return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
} }
public: public:
DeclGroupRef() : D(nullptr) {} DeclGroupRef() = default;
explicit DeclGroupRef(Decl* d) : D(d) {} explicit DeclGroupRef(Decl* d) : D(d) {}
explicit DeclGroupRef(DeclGroup* dg) explicit DeclGroupRef(DeclGroup* dg)
: D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {} : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
@ -76,8 +74,8 @@ public:
return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls)); return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
} }
typedef Decl** iterator; using iterator = Decl **;
typedef Decl* const * const_iterator; using const_iterator = Decl * const *;
bool isNull() const { return D == nullptr; } bool isNull() const { return D == nullptr; }
bool isSingleDecl() const { return getKind() == SingleDeclKind; } bool isSingleDecl() const { return getKind() == SingleDeclKind; }
@ -133,22 +131,26 @@ public:
} }
}; };
} // end clang namespace } // namespace clang
namespace llvm { namespace llvm {
// DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits. // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
template <typename T> template <typename T>
class PointerLikeTypeTraits; struct PointerLikeTypeTraits;
template <> template <>
class PointerLikeTypeTraits<clang::DeclGroupRef> { struct PointerLikeTypeTraits<clang::DeclGroupRef> {
public:
static inline void *getAsVoidPointer(clang::DeclGroupRef P) { static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
return P.getAsOpaquePtr(); return P.getAsOpaquePtr();
} }
static inline clang::DeclGroupRef getFromVoidPointer(void *P) { static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
return clang::DeclGroupRef::getFromOpaquePtr(P); return clang::DeclGroupRef::getFromOpaquePtr(P);
} }
enum { NumLowBitsAvailable = 0 }; 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 // The LLVM Compiler Infrastructure
// //
@ -18,6 +18,9 @@
#include "clang/AST/DeclBase.h" #include "clang/AST/DeclBase.h"
#include "clang/AST/DeclContextInternals.h" #include "clang/AST/DeclContextInternals.h"
#include "clang/AST/DeclarationName.h" #include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
#include <cstddef>
#include <iterator>
namespace clang { namespace clang {
@ -25,14 +28,15 @@ namespace clang {
/// of looking up every possible name. /// of looking up every possible name.
class DeclContext::all_lookups_iterator { class DeclContext::all_lookups_iterator {
StoredDeclsMap::iterator It, End; 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, all_lookups_iterator(StoredDeclsMap::iterator It,
StoredDeclsMap::iterator End) StoredDeclsMap::iterator End)
: It(It), End(End) {} : It(It), End(End) {}
@ -63,6 +67,7 @@ public:
friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) { friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) {
return x.It == y.It; return x.It == y.It;
} }
friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) { friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) {
return x.It != y.It; return x.It != y.It;
} }
@ -110,6 +115,6 @@ DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
return noload_lookups().end(); 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. /// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext { class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
public:
enum InitKind {
CallInit, // Initialized by function call.
DirectInit, // omp_priv(<expr>)
CopyInit // omp_priv = <expr>
};
private: private:
friend class ASTDeclReader; friend class ASTDeclReader;
/// \brief Combiner for declare reduction construct. /// \brief Combiner for declare reduction construct.
Expr *Combiner; Expr *Combiner;
/// \brief Initializer for declare reduction construct. /// \brief Initializer for declare reduction construct.
Expr *Initializer; 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 /// \brief Reference to the previous declare reduction construct in the same
/// scope with the same name. Required for proper templates instantiation if /// scope with the same name. Required for proper templates instantiation if
/// the declare reduction construct is declared inside compound statement. /// the declare reduction construct is declared inside compound statement.
@ -117,7 +127,8 @@ private:
DeclarationName Name, QualType Ty, DeclarationName Name, QualType Ty,
OMPDeclareReductionDecl *PrevDeclInScope) OMPDeclareReductionDecl *PrevDeclInScope)
: ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr), : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
Initializer(nullptr), PrevDeclInScope(PrevDeclInScope) {} Initializer(nullptr), InitializerKind(CallInit),
PrevDeclInScope(PrevDeclInScope) {}
void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) { void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
PrevDeclInScope = Prev; PrevDeclInScope = Prev;
@ -142,8 +153,13 @@ public:
/// construct. /// construct.
Expr *getInitializer() { return Initializer; } Expr *getInitializer() { return Initializer; }
const Expr *getInitializer() const { 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. /// \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 /// \brief Get reference to previous declare reduction construct in the same
/// scope with the same name. /// 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 // The LLVM Compiler Infrastructure
// //
@ -10,27 +10,30 @@
// This file defines the DeclVisitor interface. // This file defines the DeclVisitor interface.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_DECLVISITOR_H #ifndef LLVM_CLANG_AST_DECLVISITOR_H
#define LLVM_CLANG_AST_DECLVISITOR_H #define LLVM_CLANG_AST_DECLVISITOR_H
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h" #include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclTemplate.h"
#include "llvm/Support/ErrorHandling.h"
namespace clang { namespace clang {
namespace declvisitor { namespace declvisitor {
template <typename T> struct make_ptr { typedef T *type; }; template <typename T> struct make_ptr { using type = T *; };
template <typename T> struct make_const_ptr { typedef const T *type; }; template <typename T> struct make_const_ptr { using type = const T *; };
/// \brief A simple visitor class that helps create declaration visitors. /// \brief A simple visitor class that helps create declaration visitors.
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void> template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
class Base { class Base {
public: public:
#define PTR(CLASS) typename Ptr<CLASS>::type #define PTR(CLASS) typename Ptr<CLASS>::type
#define DISPATCH(NAME, CLASS) \ #define DISPATCH(NAME, CLASS) \
return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D)) return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D))
@ -57,23 +60,23 @@ public:
#undef DISPATCH #undef DISPATCH
}; };
} // end namespace declvisitor } // namespace declvisitor
/// \brief A simple visitor class that helps create declaration visitors. /// \brief A simple visitor class that helps create declaration visitors.
/// ///
/// This class does not preserve constness of Decl pointers (see also /// This class does not preserve constness of Decl pointers (see also
/// ConstDeclVisitor). /// ConstDeclVisitor).
template<typename ImplClass, typename RetTy=void> template<typename ImplClass, typename RetTy = void>
class DeclVisitor class DeclVisitor
: public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {}; : public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {};
/// \brief A simple visitor class that helps create declaration visitors. /// \brief A simple visitor class that helps create declaration visitors.
/// ///
/// This class preserves constness of Decl pointers (see also DeclVisitor). /// This class preserves constness of Decl pointers (see also DeclVisitor).
template<typename ImplClass, typename RetTy=void> template<typename ImplClass, typename RetTy = void>
class ConstDeclVisitor class ConstDeclVisitor
: public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {}; : public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {};
} // end namespace clang } // namespace clang
#endif // LLVM_CLANG_AST_DECLVISITOR_H #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 // The LLVM Compiler Infrastructure
// //
@ -10,36 +10,42 @@
// This file declares the DeclarationName and DeclarationNameTable classes. // This file declares the DeclarationName and DeclarationNameTable classes.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H #ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
#define LLVM_CLANG_AST_DECLARATIONNAME_H #define LLVM_CLANG_AST_DECLARATIONNAME_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
namespace llvm { #include <cassert>
template <typename T> struct DenseMapInfo; #include <cstdint>
} #include <cstring>
#include <string>
namespace clang { 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; class ASTContext;
typedef CanQual<Type> CanQualType; 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, /// DeclarationName - The name of a declaration. In the common case,
/// this just stores an IdentifierInfo pointer to a normal /// this just stores an IdentifierInfo pointer to a normal
@ -63,9 +69,13 @@ public:
CXXLiteralOperatorName, CXXLiteralOperatorName,
CXXUsingDirective CXXUsingDirective
}; };
static const unsigned NumNameKinds = CXXUsingDirective + 1; static const unsigned NumNameKinds = CXXUsingDirective + 1;
private: private:
friend class DeclarationNameTable;
friend class NamedDecl;
/// StoredNameKind - The kind of name that is actually stored in the /// StoredNameKind - The kind of name that is actually stored in the
/// upper bits of the Ptr field. This is only used internally. /// upper bits of the Ptr field. This is only used internally.
/// ///
@ -99,7 +109,18 @@ private:
/// DeclarationNameExtra structure, whose first value will tell us /// DeclarationNameExtra structure, whose first value will tell us
/// whether this is an Objective-C selector, C++ operator-id name, /// whether this is an Objective-C selector, C++ operator-id name,
/// or special C++ 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 /// getStoredNameKind - Return the kind of object that is stored in
/// Ptr. /// Ptr.
@ -146,36 +167,22 @@ private:
return nullptr; 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 /// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
/// for this name as a void pointer if it's not an identifier. /// for this name as a void pointer if it's not an identifier.
void *getFETokenInfoAsVoidSlow() const; void *getFETokenInfoAsVoidSlow() const;
public: public:
/// DeclarationName - Used to create an empty selector. /// DeclarationName - Used to create an empty selector.
DeclarationName() : Ptr(0) { } DeclarationName() = default;
// Construct a declaration name from an IdentifierInfo *. // Construct a declaration name from an IdentifierInfo *.
DeclarationName(const IdentifierInfo *II) DeclarationName(const IdentifierInfo *II)
: Ptr(reinterpret_cast<uintptr_t>(II)) { : Ptr(reinterpret_cast<uintptr_t>(II)) {
assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
} }
// Construct a declaration name from an Objective-C selector. // 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. /// getUsingDirectiveName - Return name for all using-directives.
static DeclarationName getUsingDirectiveName(); static DeclarationName getUsingDirectiveName();
@ -344,16 +351,24 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
/// getCXXConstructorName). /// getCXXConstructorName).
class DeclarationNameTable { class DeclarationNameTable {
const ASTContext &Ctx; 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; // Actually a FoldingSet<CXXSpecialName> *
void operator=(const DeclarationNameTable&) = delete; void *CXXSpecialNamesImpl;
// Operator names
CXXOperatorIdName *CXXOperatorNames;
// Actually a CXXOperatorIdName*
void *CXXLiteralOperatorNames;
// FoldingSet<CXXDeductionGuideNameExtra> *
void *CXXDeductionGuideNames;
public: public:
DeclarationNameTable(const ASTContext &C); DeclarationNameTable(const ASTContext &C);
DeclarationNameTable(const DeclarationNameTable &) = delete;
DeclarationNameTable &operator=(const DeclarationNameTable &) = delete;
~DeclarationNameTable(); ~DeclarationNameTable();
/// getIdentifier - Create a declaration name that is a simple /// getIdentifier - Create a declaration name that is a simple
@ -428,10 +443,10 @@ struct DeclarationNameLoc {
}; };
DeclarationNameLoc(DeclarationName Name); DeclarationNameLoc(DeclarationName Name);
// FIXME: this should go away once all DNLocs are properly initialized. // FIXME: this should go away once all DNLocs are properly initialized.
DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); } DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
}; // struct DeclarationNameLoc };
/// DeclarationNameInfo - A collector data type for bundling together /// DeclarationNameInfo - A collector data type for bundling together
/// a DeclarationName and the correspnding source/type location info. /// a DeclarationName and the correspnding source/type location info.
@ -439,29 +454,33 @@ struct DeclarationNameInfo {
private: private:
/// Name - The declaration name, also encoding name kind. /// Name - The declaration name, also encoding name kind.
DeclarationName Name; DeclarationName Name;
/// Loc - The main source location for the declaration name. /// Loc - The main source location for the declaration name.
SourceLocation NameLoc; SourceLocation NameLoc;
/// Info - Further source/type location info for special kinds of names. /// Info - Further source/type location info for special kinds of names.
DeclarationNameLoc LocInfo; DeclarationNameLoc LocInfo;
public: public:
// FIXME: remove it. // FIXME: remove it.
DeclarationNameInfo() {} DeclarationNameInfo() = default;
DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc) DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
: Name(Name), NameLoc(NameLoc), LocInfo(Name) {} : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc, DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
DeclarationNameLoc LocInfo) DeclarationNameLoc LocInfo)
: Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {} : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
/// getName - Returns the embedded declaration name. /// getName - Returns the embedded declaration name.
DeclarationName getName() const { return Name; } DeclarationName getName() const { return Name; }
/// setName - Sets the embedded declaration name. /// setName - Sets the embedded declaration name.
void setName(DeclarationName N) { Name = N; } void setName(DeclarationName N) { Name = N; }
/// getLoc - Returns the main location of the declaration name. /// getLoc - Returns the main location of the declaration name.
SourceLocation getLoc() const { return NameLoc; } SourceLocation getLoc() const { return NameLoc; }
/// setLoc - Sets the main location of the declaration name. /// setLoc - Sets the main location of the declaration name.
void setLoc(SourceLocation L) { NameLoc = L; } void setLoc(SourceLocation L) { NameLoc = L; }
@ -477,6 +496,7 @@ public:
Name.getNameKind() == DeclarationName::CXXConversionFunctionName); Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
return LocInfo.NamedType.TInfo; return LocInfo.NamedType.TInfo;
} }
/// setNamedTypeInfo - Sets the source type info associated to /// setNamedTypeInfo - Sets the source type info associated to
/// the name. Assumes it is a constructor, destructor or conversion. /// the name. Assumes it is a constructor, destructor or conversion.
void setNamedTypeInfo(TypeSourceInfo *TInfo) { void setNamedTypeInfo(TypeSourceInfo *TInfo) {
@ -495,6 +515,7 @@ public:
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc) SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
); );
} }
/// setCXXOperatorNameRange - Sets the range of the operator name /// setCXXOperatorNameRange - Sets the range of the operator name
/// (without the operator keyword). Assumes it is a C++ operator. /// (without the operator keyword). Assumes it is a C++ operator.
void setCXXOperatorNameRange(SourceRange R) { void setCXXOperatorNameRange(SourceRange R) {
@ -511,6 +532,7 @@ public:
return SourceLocation:: return SourceLocation::
getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc); getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
} }
/// setCXXLiteralOperatorNameLoc - Sets the location of the literal /// setCXXLiteralOperatorNameLoc - Sets the location of the literal
/// operator name (not the operator keyword). /// operator name (not the operator keyword).
/// Assumes it is a literal operator. /// Assumes it is a literal operator.
@ -534,15 +556,19 @@ public:
/// getBeginLoc - Retrieve the location of the first token. /// getBeginLoc - Retrieve the location of the first token.
SourceLocation getBeginLoc() const { return NameLoc; } SourceLocation getBeginLoc() const { return NameLoc; }
/// getEndLoc - Retrieve the location of the last token. /// getEndLoc - Retrieve the location of the last token.
SourceLocation getEndLoc() const; SourceLocation getEndLoc() const;
/// getSourceRange - The range of the declaration name. /// getSourceRange - The range of the declaration name.
SourceRange getSourceRange() const LLVM_READONLY { SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLocStart(), getLocEnd()); return SourceRange(getLocStart(), getLocEnd());
} }
SourceLocation getLocStart() const LLVM_READONLY { SourceLocation getLocStart() const LLVM_READONLY {
return getBeginLoc(); return getBeginLoc();
} }
SourceLocation getLocEnd() const LLVM_READONLY { SourceLocation getLocEnd() const LLVM_READONLY {
SourceLocation EndLoc = getEndLoc(); SourceLocation EndLoc = getEndLoc();
return EndLoc.isValid() ? EndLoc : getLocStart(); return EndLoc.isValid() ? EndLoc : getLocStart();
@ -573,9 +599,10 @@ inline raw_ostream &operator<<(raw_ostream &OS,
return OS; return OS;
} }
} // end namespace clang } // namespace clang
namespace llvm { namespace llvm {
/// Define DenseMapInfo so that DeclarationNames can be used as keys /// Define DenseMapInfo so that DeclarationNames can be used as keys
/// in DenseMap and DenseSets. /// in DenseMap and DenseSets.
template<> template<>
@ -601,6 +628,6 @@ struct DenseMapInfo<clang::DeclarationName> {
template <> template <>
struct isPodLike<clang::DeclarationName> { static const bool value = true; }; 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 // The LLVM Compiler Infrastructure
// //
@ -23,6 +23,9 @@
#include "clang/AST/Type.h" #include "clang/AST/Type.h"
#include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include <cassert>
#include <iterator>
namespace clang { namespace clang {
@ -94,6 +97,9 @@ public:
} }
private: private:
friend class DeclContext::ddiag_iterator;
friend class DependentStoredDeclsMap;
DependentDiagnostic(const PartialDiagnostic &PDiag, DependentDiagnostic(const PartialDiagnostic &PDiag,
PartialDiagnostic::Storage *Storage) PartialDiagnostic::Storage *Storage)
: Diag(PDiag, Storage) {} : Diag(PDiag, Storage) {}
@ -102,8 +108,6 @@ private:
DeclContext *Parent, DeclContext *Parent,
const PartialDiagnostic &PDiag); const PartialDiagnostic &PDiag);
friend class DependentStoredDeclsMap;
friend class DeclContext::ddiag_iterator;
DependentDiagnostic *NextDiagnostic; DependentDiagnostic *NextDiagnostic;
PartialDiagnostic Diag; PartialDiagnostic Diag;
@ -118,19 +122,17 @@ private:
} AccessData; } AccessData;
}; };
///
/// An iterator over the dependent diagnostics in a dependent context. /// An iterator over the dependent diagnostics in a dependent context.
class DeclContext::ddiag_iterator { class DeclContext::ddiag_iterator {
public: public:
ddiag_iterator() : Ptr(nullptr) {} ddiag_iterator() = default;
explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {} explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
typedef DependentDiagnostic *value_type; using value_type = DependentDiagnostic *;
typedef DependentDiagnostic *reference; using reference = DependentDiagnostic *;
typedef DependentDiagnostic *pointer; using pointer = DependentDiagnostic *;
typedef int difference_type; using difference_type = int;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
reference operator*() const { return Ptr; } reference operator*() const { return Ptr; }
@ -168,7 +170,7 @@ public:
} }
private: private:
DependentDiagnostic *Ptr; DependentDiagnostic *Ptr = nullptr;
}; };
inline DeclContext::ddiag_range DeclContext::ddiags() const { 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()); 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/AST/Type.h"
#include "clang/Basic/CharInfo.h" #include "clang/Basic/CharInfo.h"
#include "clang/Basic/LangOptions.h" #include "clang/Basic/LangOptions.h"
#include "clang/Basic/SyncScope.h"
#include "clang/Basic/TypeTraits.h" #include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/APFloat.h" #include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h" #include "llvm/ADT/APSInt.h"
@ -274,6 +275,7 @@ public:
MLV_LValueCast, // Specialized form of MLV_InvalidExpression. MLV_LValueCast, // Specialized form of MLV_InvalidExpression.
MLV_IncompleteType, MLV_IncompleteType,
MLV_ConstQualified, MLV_ConstQualified,
MLV_ConstQualifiedField,
MLV_ConstAddrSpace, MLV_ConstAddrSpace,
MLV_ArrayType, MLV_ArrayType,
MLV_NoSetterProperty, MLV_NoSetterProperty,
@ -323,6 +325,7 @@ public:
CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
CM_NoSetterProperty,// Implicit assignment to ObjC property without setter CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
CM_ConstQualified, CM_ConstQualified,
CM_ConstQualifiedField,
CM_ConstAddrSpace, CM_ConstAddrSpace,
CM_ArrayType, CM_ArrayType,
CM_IncompleteType CM_IncompleteType
@ -2345,6 +2348,12 @@ public:
SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocStart() const LLVM_READONLY;
SourceLocation getLocEnd() 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) { static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstCallExprConstant && return T->getStmtClass() >= firstCallExprConstant &&
T->getStmtClass() <= lastCallExprConstant; T->getStmtClass() <= lastCallExprConstant;
@ -2733,7 +2742,6 @@ protected:
ty->containsUnexpandedParameterPack()) || ty->containsUnexpandedParameterPack()) ||
(op && op->containsUnexpandedParameterPack()))), (op && op->containsUnexpandedParameterPack()))),
Op(op) { Op(op) {
assert(kind != CK_Invalid && "creating cast with invalid cast kind");
CastExprBits.Kind = kind; CastExprBits.Kind = kind;
setBasePathSize(BasePathSize); setBasePathSize(BasePathSize);
assert(CastConsistency()); assert(CastConsistency());
@ -2771,6 +2779,16 @@ public:
path_const_iterator path_begin() const { return path_buffer(); } path_const_iterator path_begin() const { return path_buffer(); }
path_const_iterator path_end() const { return path_buffer() + path_size(); } 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) { static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstCastExprConstant && return T->getStmtClass() >= firstCastExprConstant &&
T->getStmtClass() <= lastCastExprConstant; T->getStmtClass() <= lastCastExprConstant;
@ -3054,7 +3072,7 @@ public:
static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; } static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; }
bool isEqualityOp() const { return isEqualityOp(getOpcode()); } 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()); } bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
static Opcode negateComparisonOp(Opcode Opc) { static Opcode negateComparisonOp(Opcode Opc) {
@ -3113,6 +3131,12 @@ public:
return isShiftAssignOp(getOpcode()); 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) { static bool classof(const Stmt *S) {
return S->getStmtClass() >= firstBinaryOperatorConstant && return S->getStmtClass() >= firstBinaryOperatorConstant &&
S->getStmtClass() <= lastBinaryOperatorConstant; S->getStmtClass() <= lastBinaryOperatorConstant;
@ -3986,6 +4010,10 @@ public:
/// initializer)? /// initializer)?
bool isTransparent() const; 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; } SourceLocation getLBraceLoc() const { return LBraceLoc; }
void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; } void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
SourceLocation getRBraceLoc() const { return RBraceLoc; } SourceLocation getRBraceLoc() const { return RBraceLoc; }
@ -3995,6 +4023,9 @@ public:
InitListExpr *getSemanticForm() const { InitListExpr *getSemanticForm() const {
return isSemanticForm() ? nullptr : AltForm.getPointer(); return isSemanticForm() ? nullptr : AltForm.getPointer();
} }
bool isSyntacticForm() const {
return !AltForm.getInt() || !AltForm.getPointer();
}
InitListExpr *getSyntacticForm() const { InitListExpr *getSyntacticForm() const {
return isSemanticForm() ? AltForm.getPointer() : nullptr; return isSemanticForm() ? AltForm.getPointer() : nullptr;
} }
@ -5064,9 +5095,11 @@ public:
/// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, /// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*,
/// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the /// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the
/// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>. /// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>,
/// All of these instructions take one primary pointer and at least one memory /// and corresponding __opencl_atomic_* for OpenCL 2.0.
/// order. /// 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 { class AtomicExpr : public Expr {
public: public:
enum AtomicOp { enum AtomicOp {
@ -5078,14 +5111,16 @@ public:
}; };
private: 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 }; enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
Stmt* SubExprs[END_EXPR]; Stmt *SubExprs[END_EXPR + 1];
unsigned NumSubExprs; unsigned NumSubExprs;
SourceLocation BuiltinLoc, RParenLoc; SourceLocation BuiltinLoc, RParenLoc;
AtomicOp Op; AtomicOp Op;
friend class ASTStmtReader; friend class ASTStmtReader;
public: public:
AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t, AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t,
AtomicOp op, SourceLocation RP); AtomicOp op, SourceLocation RP);
@ -5103,8 +5138,12 @@ public:
Expr *getOrder() const { Expr *getOrder() const {
return cast<Expr>(SubExprs[ORDER]); return cast<Expr>(SubExprs[ORDER]);
} }
Expr *getScope() const {
assert(getScopeModel() && "No scope");
return cast<Expr>(SubExprs[NumSubExprs - 1]);
}
Expr *getVal1() const { 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]); return cast<Expr>(SubExprs[ORDER]);
assert(NumSubExprs > VAL1); assert(NumSubExprs > VAL1);
return cast<Expr>(SubExprs[VAL1]); return cast<Expr>(SubExprs[VAL1]);
@ -5123,6 +5162,7 @@ public:
assert(NumSubExprs > WEAK); assert(NumSubExprs > WEAK);
return cast<Expr>(SubExprs[WEAK]); return cast<Expr>(SubExprs[WEAK]);
} }
QualType getValueType() const;
AtomicOp getOp() const { return Op; } AtomicOp getOp() const { return Op; }
unsigned getNumSubExprs() const { return NumSubExprs; } unsigned getNumSubExprs() const { return NumSubExprs; }
@ -5139,10 +5179,17 @@ public:
bool isCmpXChg() const { bool isCmpXChg() const {
return getOp() == AO__c11_atomic_compare_exchange_strong || return getOp() == AO__c11_atomic_compare_exchange_strong ||
getOp() == AO__c11_atomic_compare_exchange_weak || 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 ||
getOp() == AO__atomic_compare_exchange_n; 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 getBuiltinLoc() const { return BuiltinLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; }
@ -5160,6 +5207,24 @@ public:
const_child_range children() const { const_child_range children() const {
return const_child_range(SubExprs, SubExprs + NumSubExprs); 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 /// 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/ASTImporter.h"
#include "clang/AST/ExternalASTSource.h" #include "clang/AST/ExternalASTSource.h"
#include "llvm/Support/raw_ostream.h"
namespace clang { 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 { class ExternalASTMerger : public ExternalASTSource {
public: public:
struct ImporterPair { /// A single origin for a DeclContext. Unlike Decls, DeclContexts do
std::unique_ptr<ASTImporter> Forward; /// not allow their containing ASTContext to be determined in all cases.
std::unique_ptr<ASTImporter> Reverse; struct DCOrigin {
DeclContext *DC;
ASTContext *AST;
}; };
typedef std::map<const DeclContext *, DCOrigin> OriginMap;
typedef std::vector<std::unique_ptr<ASTImporter>> ImporterVector;
private: 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: 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; ASTContext &AST;
FileManager &FM; FileManager &FM;
}; };
ExternalASTMerger(const ImporterEndpoint &Target, /// A source for an ExternalASTMerger.
llvm::ArrayRef<ImporterEndpoint> Sources); ///
/// 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, bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override; DeclarationName Name) override;
/// Implementation of the ExternalASTSource API.
void void
FindExternalLexicalDecls(const DeclContext *DC, FindExternalLexicalDecls(const DeclContext *DC,
llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Result) override; 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 } // 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 // The LLVM Compiler Infrastructure
// //
@ -11,24 +11,44 @@
// construction of AST nodes from some external source. // construction of AST nodes from some external source.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H #ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
#define LLVM_CLANG_AST_EXTERNALASTSOURCE_H #define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
#include "clang/AST/CharUnits.h" #include "clang/AST/CharUnits.h"
#include "clang/AST/DeclBase.h" #include "clang/AST/DeclBase.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h" #include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.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 { namespace clang {
class ASTConsumer; class ASTConsumer;
class ASTContext;
class CXXBaseSpecifier; class CXXBaseSpecifier;
class CXXCtorInitializer; class CXXCtorInitializer;
class CXXRecordDecl;
class DeclarationName; class DeclarationName;
class ExternalSemaSource; // layering violation required for downcasting
class FieldDecl; class FieldDecl;
class Module; class IdentifierInfo;
class NamedDecl; class NamedDecl;
class ObjCInterfaceDecl;
class RecordDecl; class RecordDecl;
class Selector; class Selector;
class Stmt; class Stmt;
@ -42,30 +62,31 @@ class TagDecl;
/// actual type and declaration nodes, and read parts of declaration /// actual type and declaration nodes, and read parts of declaration
/// contexts. /// contexts.
class ExternalASTSource : public RefCountedBase<ExternalASTSource> { class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
friend class ExternalSemaSource;
/// Generation number for this external AST source. Must be increased /// Generation number for this external AST source. Must be increased
/// whenever we might have added new redeclarations for existing decls. /// 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 /// \brief Whether this AST source also provides information for
/// semantic analysis. /// semantic analysis.
bool SemaSource; bool SemaSource = false;
friend class ExternalSemaSource;
public: public:
ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { } ExternalASTSource() = default;
virtual ~ExternalASTSource(); virtual ~ExternalASTSource();
/// \brief RAII class for safely pairing a StartedDeserializing call /// \brief RAII class for safely pairing a StartedDeserializing call
/// with FinishedDeserializing. /// with FinishedDeserializing.
class Deserializing { class Deserializing {
ExternalASTSource *Source; ExternalASTSource *Source;
public: public:
explicit Deserializing(ExternalASTSource *source) : Source(source) { explicit Deserializing(ExternalASTSource *source) : Source(source) {
assert(Source); assert(Source);
Source->StartedDeserializing(); Source->StartedDeserializing();
} }
~Deserializing() { ~Deserializing() {
Source->FinishedDeserializing(); Source->FinishedDeserializing();
} }
@ -122,7 +143,7 @@ public:
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
/// \brief Update an out-of-date identifier. /// \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, /// \brief Find all declarations with the given name in the given context,
/// and add them to the context by calling SetExternalVisibleDeclsForName /// and add them to the context by calling SetExternalVisibleDeclsForName
@ -154,12 +175,13 @@ public:
const Module *ClangModule = nullptr; const Module *ClangModule = nullptr;
public: public:
ASTSourceDescriptor(){}; ASTSourceDescriptor() = default;
ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
ASTFileSignature Signature) ASTFileSignature Signature)
: PCHModuleName(std::move(Name)), Path(std::move(Path)), : PCHModuleName(std::move(Name)), Path(std::move(Path)),
ASTFile(std::move(ASTFile)), Signature(Signature){}; ASTFile(std::move(ASTFile)), Signature(Signature) {}
ASTSourceDescriptor(const Module &M); ASTSourceDescriptor(const Module &M);
std::string getModuleName() const; std::string getModuleName() const;
StringRef getPath() const { return Path; } StringRef getPath() const { return Path; }
StringRef getASTFile() const { return ASTFile; } StringRef getASTFile() const { return ASTFile; }
@ -246,7 +268,6 @@ public:
/// The default implementation of this method is a no-op. /// The default implementation of this method is a no-op.
virtual void PrintStats(); virtual void PrintStats();
/// \brief Perform layout on the given record. /// \brief Perform layout on the given record.
/// ///
/// This routine allows the external AST source to provide an specific /// This routine allows the external AST source to provide an specific
@ -289,7 +310,7 @@ public:
size_t mmap_bytes; size_t mmap_bytes;
MemoryBufferSizes(size_t malloc_bytes, 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 /// 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 /// 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. /// bit is set, the upper 63 bits are the offset.
mutable uint64_t Ptr; mutable uint64_t Ptr = 0;
public: 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) { explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
if (Offset == 0) if (Offset == 0)
@ -392,15 +413,16 @@ struct LazyGenerationalUpdatePtr {
/// A cache of the value of this pointer, in the most recent generation in /// A cache of the value of this pointer, in the most recent generation in
/// which we queried it. /// which we queried it.
struct LazyData { struct LazyData {
LazyData(ExternalASTSource *Source, T Value)
: ExternalSource(Source), LastGeneration(0), LastValue(Value) {}
ExternalASTSource *ExternalSource; ExternalASTSource *ExternalSource;
uint32_t LastGeneration; uint32_t LastGeneration = 0;
T LastValue; 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. // 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; ValueType Value;
LazyGenerationalUpdatePtr(ValueType V) : Value(V) {} LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
@ -459,25 +481,31 @@ public:
return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr)); return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
} }
}; };
} // end namespace clang
} // namespace clang
/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be /// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
/// placed into a PointerUnion. /// placed into a PointerUnion.
namespace llvm { namespace llvm {
template<typename Owner, typename T, template<typename Owner, typename T,
void (clang::ExternalASTSource::*Update)(Owner)> void (clang::ExternalASTSource::*Update)(Owner)>
struct PointerLikeTypeTraits< struct PointerLikeTypeTraits<
clang::LazyGenerationalUpdatePtr<Owner, T, Update>> { 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 void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); } static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
enum { enum {
NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1 NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
}; };
}; };
}
} // namespace llvm
namespace clang { namespace clang {
/// \brief Represents a lazily-loaded vector of data. /// \brief Represents a lazily-loaded vector of data.
/// ///
/// The lazily-loaded vector of data contains data that is partially loaded /// The lazily-loaded vector of data contains data that is partially loaded
@ -511,13 +539,14 @@ public:
class iterator class iterator
: public llvm::iterator_adaptor_base< : public llvm::iterator_adaptor_base<
iterator, int, std::random_access_iterator_tag, T, int, T *, T &> { iterator, int, std::random_access_iterator_tag, T, int, T *, T &> {
friend class LazyVector;
LazyVector *Self; LazyVector *Self;
iterator(LazyVector *Self, int Position) iterator(LazyVector *Self, int Position)
: iterator::iterator_adaptor_base(Position), Self(Self) {} : iterator::iterator_adaptor_base(Position), Self(Self) {}
bool isLoaded() const { return this->I < 0; } bool isLoaded() const { return this->I < 0; }
friend class LazyVector;
public: public:
iterator() : iterator(nullptr, 0) {} iterator() : iterator(nullptr, 0) {}
@ -562,23 +591,23 @@ public:
}; };
/// \brief A lazy pointer to a statement. /// \brief A lazy pointer to a statement.
typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt> using LazyDeclStmtPtr =
LazyDeclStmtPtr; LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>;
/// \brief A lazy pointer to a declaration. /// \brief A lazy pointer to a declaration.
typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl> using LazyDeclPtr =
LazyDeclPtr; LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>;
/// \brief A lazy pointer to a set of CXXCtorInitializers. /// \brief A lazy pointer to a set of CXXCtorInitializers.
typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t, using LazyCXXCtorInitializersPtr =
&ExternalASTSource::GetExternalCXXCtorInitializers> LazyOffsetPtr<CXXCtorInitializer *, uint64_t,
LazyCXXCtorInitializersPtr; &ExternalASTSource::GetExternalCXXCtorInitializers>;
/// \brief A lazy pointer to a set of CXXBaseSpecifiers. /// \brief A lazy pointer to a set of CXXBaseSpecifiers.
typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, using LazyCXXBaseSpecifiersPtr =
&ExternalASTSource::GetExternalCXXBaseSpecifiers> LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
LazyCXXBaseSpecifiersPtr; &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 // The LLVM Compiler Infrastructure
// //
@ -19,6 +19,12 @@
#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclOpenMP.h"
#include "clang/Basic/ABI.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 { namespace clang {
@ -27,7 +33,7 @@ namespace clang {
/// a CXXDestructorDecl and the destructor type (Base, Complete) or /// a CXXDestructorDecl and the destructor type (Base, Complete) or
/// a VarDecl, a FunctionDecl or a BlockDecl. /// a VarDecl, a FunctionDecl or a BlockDecl.
class GlobalDecl { class GlobalDecl {
llvm::PointerIntPair<const Decl*, 2> Value; llvm::PointerIntPair<const Decl *, 2> Value;
void Init(const Decl *D) { void Init(const Decl *D) {
assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!"); assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
@ -37,19 +43,15 @@ class GlobalDecl {
} }
public: public:
GlobalDecl() {} GlobalDecl() = default;
GlobalDecl(const VarDecl *D) { Init(D);} GlobalDecl(const VarDecl *D) { Init(D);}
GlobalDecl(const FunctionDecl *D) { Init(D); } GlobalDecl(const FunctionDecl *D) { Init(D); }
GlobalDecl(const BlockDecl *D) { Init(D); } GlobalDecl(const BlockDecl *D) { Init(D); }
GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const CapturedDecl *D) { Init(D); }
GlobalDecl(const ObjCMethodDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); } GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
: Value(D, Type) {}
GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
: Value(D, Type) {}
GlobalDecl getCanonicalDecl() const { GlobalDecl getCanonicalDecl() const {
GlobalDecl CanonGD; GlobalDecl CanonGD;
@ -90,10 +92,9 @@ public:
} }
}; };
} // end namespace clang } // namespace clang
namespace llvm { namespace llvm {
template<class> struct DenseMapInfo;
template<> struct DenseMapInfo<clang::GlobalDecl> { template<> struct DenseMapInfo<clang::GlobalDecl> {
static inline clang::GlobalDecl getEmptyKey() { static inline clang::GlobalDecl getEmptyKey() {
@ -113,7 +114,6 @@ namespace llvm {
clang::GlobalDecl RHS) { clang::GlobalDecl RHS) {
return LHS == RHS; return LHS == RHS;
} }
}; };
// GlobalDecl isn't *technically* a POD type. However, its copy constructor, // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
@ -122,6 +122,7 @@ namespace llvm {
struct isPodLike<clang::GlobalDecl> { struct isPodLike<clang::GlobalDecl> {
static const bool value = true; 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 // The LLVM Compiler Infrastructure
// //
@ -11,38 +11,42 @@
// a C++ nested-name-specifier. // a C++ nested-name-specifier.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H #ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H #define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
#include "clang/Basic/Diagnostic.h" #include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include <cstdint>
#include <cstdlib>
#include <utility>
namespace clang { namespace clang {
class ASTContext; class ASTContext;
class CXXRecordDecl; class CXXRecordDecl;
class IdentifierInfo;
class LangOptions;
class NamespaceAliasDecl; class NamespaceAliasDecl;
class NamespaceDecl; class NamespaceDecl;
class IdentifierInfo;
struct PrintingPolicy; struct PrintingPolicy;
class Type; class Type;
class TypeLoc; class TypeLoc;
class LangOptions;
/// \brief Represents a C++ nested name specifier, such as /// \brief Represents a C++ nested name specifier, such as
/// "\::std::vector<int>::". /// "\::std::vector<int>::".
/// ///
/// C++ nested name specifiers are the prefixes to qualified /// 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 /// specifier. Nested name specifiers are made up of a sequence of
/// specifiers, each of which can be a namespace, type, identifier /// specifiers, each of which can be a namespace, type, identifier
/// (for dependent names), decltype specifier, or the global specifier ('::'). /// (for dependent names), decltype specifier, or the global specifier ('::').
/// The last two specifiers can only appear at the start of a /// The last two specifiers can only appear at the start of a
/// nested-namespace-specifier. /// nested-namespace-specifier.
class NestedNameSpecifier : public llvm::FoldingSetNode { class NestedNameSpecifier : public llvm::FoldingSetNode {
/// \brief Enumeration describing /// \brief Enumeration describing
enum StoredSpecifierKind { enum StoredSpecifierKind {
StoredIdentifier = 0, StoredIdentifier = 0,
@ -66,7 +70,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
/// specifier '::'. Otherwise, the pointer is one of /// specifier '::'. Otherwise, the pointer is one of
/// IdentifierInfo*, Namespace*, or Type*, depending on the kind of /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
/// specifier as encoded within the prefix. /// specifier as encoded within the prefix.
void* Specifier; void* Specifier = nullptr;
public: public:
/// \brief The kind of specifier that completes this nested name /// \brief The kind of specifier that completes this nested name
@ -74,17 +78,23 @@ public:
enum SpecifierKind { enum SpecifierKind {
/// \brief An identifier, stored as an IdentifierInfo*. /// \brief An identifier, stored as an IdentifierInfo*.
Identifier, Identifier,
/// \brief A namespace, stored as a NamespaceDecl*. /// \brief A namespace, stored as a NamespaceDecl*.
Namespace, Namespace,
/// \brief A namespace alias, stored as a NamespaceAliasDecl*. /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
NamespaceAlias, NamespaceAlias,
/// \brief A type, stored as a Type*. /// \brief A type, stored as a Type*.
TypeSpec, TypeSpec,
/// \brief A type that was preceded by the 'template' keyword, /// \brief A type that was preceded by the 'template' keyword,
/// stored as a Type*. /// stored as a Type*.
TypeSpecWithTemplate, TypeSpecWithTemplate,
/// \brief The global specifier '::'. There is no stored value. /// \brief The global specifier '::'. There is no stored value.
Global, Global,
/// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of /// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
/// the class it appeared in. /// the class it appeared in.
Super Super
@ -92,17 +102,11 @@ public:
private: private:
/// \brief Builds the global specifier. /// \brief Builds the global specifier.
NestedNameSpecifier() NestedNameSpecifier() : Prefix(nullptr, StoredIdentifier) {}
: Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
/// \brief Copy constructor used internally to clone nested name /// \brief Copy constructor used internally to clone nested name
/// specifiers. /// specifiers.
NestedNameSpecifier(const NestedNameSpecifier &Other) NestedNameSpecifier(const NestedNameSpecifier &Other) = default;
: llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
Specifier(Other.Specifier) {
}
void operator=(const NestedNameSpecifier &) = delete;
/// \brief Either find or insert the given nested name specifier /// \brief Either find or insert the given nested name specifier
/// mockup in the given context. /// mockup in the given context.
@ -110,6 +114,8 @@ private:
const NestedNameSpecifier &Mockup); const NestedNameSpecifier &Mockup);
public: public:
NestedNameSpecifier &operator=(const NestedNameSpecifier &) = delete;
/// \brief Builds a specifier combining a prefix and an identifier. /// \brief Builds a specifier combining a prefix and an identifier.
/// ///
/// The prefix must be dependent, since nested name specifiers /// The prefix must be dependent, since nested name specifiers
@ -224,8 +230,8 @@ public:
/// \brief A C++ nested-name-specifier augmented with source location /// \brief A C++ nested-name-specifier augmented with source location
/// information. /// information.
class NestedNameSpecifierLoc { class NestedNameSpecifierLoc {
NestedNameSpecifier *Qualifier; NestedNameSpecifier *Qualifier = nullptr;
void *Data; void *Data = nullptr;
/// \brief Determines the data length for the last component in the /// \brief Determines the data length for the last component in the
/// given nested-name-specifier. /// given nested-name-specifier.
@ -237,12 +243,12 @@ class NestedNameSpecifierLoc {
public: public:
/// \brief Construct an empty nested-name-specifier. /// \brief Construct an empty nested-name-specifier.
NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { } NestedNameSpecifierLoc() = default;
/// \brief Construct a nested-name-specifier with source location information /// \brief Construct a nested-name-specifier with source location information
/// from /// from
NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data) NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
: Qualifier(Qualifier), Data(Data) { } : Qualifier(Qualifier), Data(Data) {}
/// \brief Evalutes true when this nested-name-specifier location is /// \brief Evalutes true when this nested-name-specifier location is
/// non-empty. /// non-empty.
@ -339,7 +345,7 @@ public:
class NestedNameSpecifierLocBuilder { class NestedNameSpecifierLocBuilder {
/// \brief The current representation of the nested-name-specifier we're /// \brief The current representation of the nested-name-specifier we're
/// building. /// building.
NestedNameSpecifier *Representation; NestedNameSpecifier *Representation = nullptr;
/// \brief Buffer used to store source-location information for the /// \brief Buffer used to store source-location information for the
/// nested-name-specifier. /// nested-name-specifier.
@ -347,21 +353,18 @@ class NestedNameSpecifierLocBuilder {
/// Note that we explicitly manage the buffer (rather than using a /// Note that we explicitly manage the buffer (rather than using a
/// SmallVector) because \c Declarator expects it to be possible to memcpy() /// SmallVector) because \c Declarator expects it to be possible to memcpy()
/// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder. /// 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 /// \brief The size of the buffer used to store source-location information
/// for the nested-name-specifier. /// for the nested-name-specifier.
unsigned BufferSize; unsigned BufferSize = 0;
/// \brief The capacity of the buffer used to store source-location /// \brief The capacity of the buffer used to store source-location
/// information for the nested-name-specifier. /// information for the nested-name-specifier.
unsigned BufferCapacity; unsigned BufferCapacity = 0;
public: public:
NestedNameSpecifierLocBuilder() NestedNameSpecifierLocBuilder() = default;
: Representation(nullptr), Buffer(nullptr), BufferSize(0),
BufferCapacity(0) {}
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other); NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
NestedNameSpecifierLocBuilder & NestedNameSpecifierLocBuilder &
@ -451,6 +454,7 @@ public:
/// \param ColonColonLoc The location of the trailing '::'. /// \param ColonColonLoc The location of the trailing '::'.
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
SourceLocation SuperLoc, SourceLocation ColonColonLoc); SourceLocation SuperLoc, SourceLocation ColonColonLoc);
/// \brief Make a new nested-name-specifier from incomplete source-location /// \brief Make a new nested-name-specifier from incomplete source-location
/// information. /// information.
/// ///
@ -511,6 +515,6 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
return 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. // Convert a pointer to a different address space.
CAST_OPERATION(AddressSpaceConversion) CAST_OPERATION(AddressSpaceConversion)
// Convert an integer initializer to an OpenCL sampler. // Convert an integer initializer to an OpenCL sampler.
CAST_OPERATION(IntToOCLSampler) CAST_OPERATION(IntToOCLSampler)
//===- Binary Operations -------------------------------------------------===// //===- Binary Operations -------------------------------------------------===//
// Operators listed in order of precedence. // 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. // [C++ 5.5] Pointer-to-member operators.
BINARY_OPERATION(PtrMemD, ".*") BINARY_OPERATION(PtrMemD, ".*")
@ -347,6 +348,8 @@ BINARY_OPERATION(Sub, "-")
// [C99 6.5.7] Bitwise shift operators. // [C99 6.5.7] Bitwise shift operators.
BINARY_OPERATION(Shl, "<<") BINARY_OPERATION(Shl, "<<")
BINARY_OPERATION(Shr, ">>") BINARY_OPERATION(Shr, ">>")
// C++20 [expr.spaceship] Three-way comparison operator.
BINARY_OPERATION(Cmp, "<=>")
// [C99 6.5.8] Relational operators. // [C99 6.5.8] Relational operators.
BINARY_OPERATION(LT, "<") BINARY_OPERATION(LT, "<")
BINARY_OPERATION(GT, ">") BINARY_OPERATION(GT, ">")
@ -382,7 +385,8 @@ BINARY_OPERATION(Comma, ",")
//===- Unary Operations ---------------------------------------------------===// //===- 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 // [C99 6.5.2.4] Postfix increment and decrement
UNARY_OPERATION(PostInc, "++") UNARY_OPERATION(PostInc, "++")

View File

@ -23,8 +23,6 @@ enum CastKind {
#include "clang/AST/OperationKinds.def" #include "clang/AST/OperationKinds.def"
}; };
static const CastKind CK_Invalid = static_cast<CastKind>(-1);
enum BinaryOperatorKind { enum BinaryOperatorKind {
#define BINARY_OPERATION(Name, Spelling) BO_##Name, #define BINARY_OPERATION(Name, Spelling) BO_##Name,
#include "clang/AST/OperationKinds.def" #include "clang/AST/OperationKinds.def"

View File

@ -30,8 +30,8 @@ public:
virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0; virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0;
}; };
/// \brief Describes how types, statements, expressions, and /// Describes how types, statements, expressions, and declarations should be
/// declarations should be printed. /// printed.
/// ///
/// This type is intended to be small and suitable for passing by value. /// This type is intended to be small and suitable for passing by value.
/// It is very frequently copied. /// It is very frequently copied.
@ -50,22 +50,24 @@ struct PrintingPolicy {
UseVoidForZeroParams(!LO.CPlusPlus), UseVoidForZeroParams(!LO.CPlusPlus),
TerseOutput(false), PolishForDeclaration(false), TerseOutput(false), PolishForDeclaration(false),
Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), 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 /// Adjust this printing policy for cases where it's known that we're
/// we're printing C++ code (for instance, if AST dumping reaches a /// printing C++ code (for instance, if AST dumping reaches a C++-only
/// C++-only construct). This should not be used if a real LangOptions /// construct). This should not be used if a real LangOptions object is
/// object is available. /// available.
void adjustForCPlusPlus() { void adjustForCPlusPlus() {
SuppressTagKeyword = true; SuppressTagKeyword = true;
Bool = true; Bool = true;
UseVoidForZeroParams = false; 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; 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. /// the given type or declaration.
/// ///
/// This flag is only used when we are printing declarators beyond /// 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". /// "const int" type specifier and instead only print the "*y".
bool SuppressSpecifiers : 1; 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, /// This is used when printing the inner type of elaborated types,
/// (as the tag keyword is part of the elaborated type): /// (as the tag keyword is part of the elaborated type):
@ -91,7 +93,7 @@ struct PrintingPolicy {
/// \endcode /// \endcode
bool SuppressTagKeyword : 1; 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 /// This is used to place the definition of a struct
/// in the middle of another declaration as with: /// in the middle of another declaration as with:
@ -101,14 +103,14 @@ struct PrintingPolicy {
/// \endcode /// \endcode
bool IncludeTagDefinition : 1; bool IncludeTagDefinition : 1;
/// \brief Suppresses printing of scope specifiers. /// Suppresses printing of scope specifiers.
bool SuppressScope : 1; 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. /// to be written, e.g., for inline or anonymous namespaces.
bool SuppressUnwrittenScope : 1; 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 /// This flag is used when printing the loop variable in a for-range
/// statement. For example, given: /// statement. For example, given:
@ -121,8 +123,8 @@ struct PrintingPolicy {
/// internal initializer constructed for x will not be printed. /// internal initializer constructed for x will not be printed.
bool SuppressInitializers : 1; bool SuppressInitializers : 1;
/// \brief Whether we should print the sizes of constant array expressions /// Whether we should print the sizes of constant array expressions as written
/// as written in the sources. /// in the sources.
/// ///
/// This flag determines whether array types declared as /// This flag determines whether array types declared as
/// ///
@ -139,67 +141,90 @@ struct PrintingPolicy {
/// \endcode /// \endcode
bool ConstantArraySizeAsWritten : 1; bool ConstantArraySizeAsWritten : 1;
/// \brief When printing an anonymous tag name, also print the location of /// When printing an anonymous tag name, also print the location of that
/// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just /// entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just prints
/// prints "(anonymous)" for the name. /// "(anonymous)" for the name.
bool AnonymousTagLocations : 1; bool AnonymousTagLocations : 1;
/// \brief When true, suppress printing of the __strong lifetime qualifier in /// When true, suppress printing of the __strong lifetime qualifier in ARC.
/// ARC.
unsigned SuppressStrongLifetime : 1; unsigned SuppressStrongLifetime : 1;
/// \brief When true, suppress printing of lifetime qualifier in /// When true, suppress printing of lifetime qualifier in ARC.
/// ARC.
unsigned SuppressLifetimeQualifiers : 1; unsigned SuppressLifetimeQualifiers : 1;
/// When true, suppresses printing template arguments in names of C++ /// When true, suppresses printing template arguments in names of C++
/// constructors. /// constructors.
unsigned SuppressTemplateArgsInCXXConstructors : 1; 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). /// doesn't actually have 'bool', because, e.g., it is defined as a macro).
unsigned Bool : 1; unsigned Bool : 1;
/// \brief Whether we can use 'restrict' rather than '__restrict'. /// Whether we can use 'restrict' rather than '__restrict'.
unsigned Restrict : 1; unsigned Restrict : 1;
/// \brief Whether we can use 'alignof' rather than '__alignof'. /// Whether we can use 'alignof' rather than '__alignof'.
unsigned Alignof : 1; unsigned Alignof : 1;
/// \brief Whether we can use '_Alignof' rather than '__alignof'. /// Whether we can use '_Alignof' rather than '__alignof'.
unsigned UnderscoreAlignof : 1; unsigned UnderscoreAlignof : 1;
/// \brief Whether we should use '(void)' rather than '()' for a function /// Whether we should use '(void)' rather than '()' for a function prototype
/// prototype with zero parameters. /// with zero parameters.
unsigned UseVoidForZeroParams : 1; 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, /// For example, in this mode we don't print function bodies, class members,
/// declarations inside namespaces etc. Effectively, this should print /// declarations inside namespaces etc. Effectively, this should print
/// only the requested declaration. /// only the requested declaration.
unsigned TerseOutput : 1; unsigned TerseOutput : 1;
/// \brief When true, do certain refinement needed for producing proper /// When true, do certain refinement needed for producing proper declaration
/// declaration tag; such as, do not print attributes attached to the declaration. /// tag; such as, do not print attributes attached to the declaration.
/// ///
unsigned PolishForDeclaration : 1; 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' /// instead of '__fp16'
unsigned Half : 1; 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. /// Microsoft mode when wchar_t is not available.
unsigned MSWChar : 1; 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; unsigned IncludeNewlines : 1;
/// \brief Use whitespace and punctuation like MSVC does. In particular, this /// Use whitespace and punctuation like MSVC does. In particular, this prints
/// prints anonymous namespaces as `anonymous namespace' and does not insert /// anonymous namespaces as `anonymous namespace' and does not insert spaces
/// spaces after template arguments. /// after template arguments.
bool MSVCFormatting : 1; 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 } // end namespace clang

View File

@ -56,8 +56,8 @@
// //
// ===----------------------------------------------------------------------===// // ===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H #ifndef LLVM_CLANG_AST_QUALTYPENAMES_H
#define LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H #define LLVM_CLANG_AST_QUALTYPENAMES_H
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
@ -71,9 +71,20 @@ namespace TypeName {
/// \param[in] Ctx - the ASTContext to be used. /// \param[in] Ctx - the ASTContext to be used.
/// \param[in] WithGlobalNsPrefix - If true, then the global namespace /// \param[in] WithGlobalNsPrefix - If true, then the global namespace
/// specifier "::" will be prepended to the fully qualified name. /// specifier "::" will be prepended to the fully qualified name.
std::string getFullyQualifiedName(QualType QT, std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx,
const ASTContext &Ctx,
bool WithGlobalNsPrefix = false); bool WithGlobalNsPrefix = false);
} // end namespace TypeName
} // end namespace clang /// \brief Generates a QualType that can be used to name the same type
#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H /// 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 // The LLVM Compiler Infrastructure
// //
@ -14,15 +14,20 @@
#ifndef LLVM_CLANG_AST_RECORDLAYOUT_H #ifndef LLVM_CLANG_AST_RECORDLAYOUT_H
#define LLVM_CLANG_AST_RECORDLAYOUT_H #define LLVM_CLANG_AST_RECORDLAYOUT_H
#include "clang/AST/ASTVector.h"
#include "clang/AST/CharUnits.h" #include "clang/AST/CharUnits.h"
#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclCXX.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include <cassert>
#include <cstdint>
namespace clang { namespace clang {
class ASTContext;
class FieldDecl; class ASTContext;
class RecordDecl; class CXXRecordDecl;
class CXXRecordDecl;
/// ASTRecordLayout - /// ASTRecordLayout -
/// This class contains layout information for one RecordDecl, /// This class contains layout information for one RecordDecl,
@ -42,21 +47,21 @@ public:
/// Whether this virtual base requires a vtordisp field in the /// Whether this virtual base requires a vtordisp field in the
/// Microsoft ABI. These fields are required for certain operations /// Microsoft ABI. These fields are required for certain operations
/// in constructors and destructors. /// in constructors and destructors.
bool HasVtorDisp; bool HasVtorDisp = false;
public: public:
VBaseInfo() = default;
VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp)
: VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
bool hasVtorDisp() const { return HasVtorDisp; } bool hasVtorDisp() const { return HasVtorDisp; }
VBaseInfo() : HasVtorDisp(false) {}
VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) :
VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
}; };
typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo> using VBaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>;
VBaseOffsetsMapTy;
private: private:
friend class ASTContext;
/// Size - Size of record in characters. /// Size - Size of record in characters.
CharUnits Size; CharUnits Size;
@ -117,7 +122,7 @@ private:
const CXXRecordDecl *BaseSharingVBPtr; const CXXRecordDecl *BaseSharingVBPtr;
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :) /// 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. /// BaseOffsets - Contains a map from base classes to their offset.
BaseOffsetsMapTy BaseOffsets; BaseOffsetsMapTy BaseOffsets;
@ -128,16 +133,15 @@ private:
/// CXXInfo - If the record layout is for a C++ record, this will have /// CXXInfo - If the record layout is for a C++ record, this will have
/// C++ specific information about the record. /// C++ specific information about the record.
CXXRecordLayoutInfo *CXXInfo; CXXRecordLayoutInfo *CXXInfo = nullptr;
friend class ASTContext;
ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
CharUnits requiredAlignment, CharUnits datasize, CharUnits requiredAlignment, CharUnits datasize,
ArrayRef<uint64_t> fieldoffsets); ArrayRef<uint64_t> fieldoffsets);
using BaseOffsetsMapTy = CXXRecordLayoutInfo::BaseOffsetsMapTy;
// Constructor for C++ records. // Constructor for C++ records.
typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
ASTRecordLayout(const ASTContext &Ctx, ASTRecordLayout(const ASTContext &Ctx,
CharUnits size, CharUnits alignment, CharUnits size, CharUnits alignment,
CharUnits requiredAlignment, CharUnits requiredAlignment,
@ -159,9 +163,9 @@ private:
void Destroy(ASTContext &Ctx); void Destroy(ASTContext &Ctx);
ASTRecordLayout(const ASTRecordLayout &) = delete;
void operator=(const ASTRecordLayout &) = delete;
public: public:
ASTRecordLayout(const ASTRecordLayout &) = delete;
ASTRecordLayout &operator=(const ASTRecordLayout &) = delete;
/// getAlignment - Get the record alignment in characters. /// getAlignment - Get the record alignment in characters.
CharUnits getAlignment() const { return Alignment; } 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(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \
OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \ OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \
OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \ OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \ OPERATOR(NE) OPERATOR(Cmp) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \
OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma) OPERATOR(LAnd) OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
// All compound assign operators. // All compound assign operators.
#define CAO_LIST() \ #define CAO_LIST() \
@ -83,7 +83,7 @@ namespace clang {
return false; \ return false; \
} while (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. /// depth-first traversal on the entire Clang AST and visits each node.
/// ///
/// This class performs three distinct tasks: /// This class performs three distinct tasks:
@ -267,6 +267,12 @@ public:
bool TraverseTemplateArguments(const TemplateArgument *Args, bool TraverseTemplateArguments(const TemplateArgument *Args,
unsigned NumArgs); 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 /// \brief Recursively visit a constructor initializer. This
/// automatically dispatches to another visitor for the initializer /// automatically dispatches to another visitor for the initializer
/// expression, but not for the name of the initializer, so may /// expression, but not for the name of the initializer, so may
@ -309,6 +315,8 @@ public:
// ---- Methods on Stmts ---- // ---- Methods on Stmts ----
Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
private: private:
template<typename T, typename U> template<typename T, typename U>
struct has_same_member_pointer_type : std::false_type {}; struct has_same_member_pointer_type : std::false_type {};
@ -491,6 +499,8 @@ public:
bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; } bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
#include "clang/AST/DeclNodes.inc" #include "clang/AST/DeclNodes.inc"
bool canIgnoreChildDeclWhileTraversingDeclContext(const Decl *Child);
private: private:
// These are helper methods used by more than one Traverse* method. // These are helper methods used by more than one Traverse* method.
bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL); bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
@ -978,6 +988,11 @@ DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
TRY_TO(TraverseStmt(T->getSizeExpr())); TRY_TO(TraverseStmt(T->getSizeExpr()));
}) })
DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
TRY_TO(TraverseStmt(T->getAddrSpaceExpr()));
TRY_TO(TraverseType(T->getPointeeType()));
})
DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, { DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
if (T->getSizeExpr()) if (T->getSizeExpr())
TRY_TO(TraverseStmt(T->getSizeExpr())); TRY_TO(TraverseStmt(T->getSizeExpr()));
@ -1188,6 +1203,11 @@ DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
return TraverseArrayTypeLocHelper(TL); 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: order? why not size expr first?
// FIXME: base VectorTypeLoc is unfinished // FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, { 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 // Therefore each Traverse* only needs to worry about children other
// than those. // 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> template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) { bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
if (!DC) if (!DC)
return true; return true;
for (auto *Child : DC->decls()) { for (auto *Child : DC->decls()) {
// BlockDecls and CapturedDecls are traversed through BlockExprs and if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
// CapturedStmts respectively.
if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
TRY_TO(TraverseDecl(Child)); TRY_TO(TraverseDecl(Child));
} }
@ -1674,8 +1700,8 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
// template declarations. // template declarations.
#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \ #define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \ DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
\ \
/* By default, we do not traverse the instantiations of \ /* By default, we do not traverse the instantiations of \
class templates since they do not appear in the user code. The \ class templates since they do not appear in the user code. The \
@ -1768,13 +1794,20 @@ bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
return true; return true;
} }
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseCXXBaseSpecifier(
const CXXBaseSpecifier &Base) {
TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
return true;
}
template <typename Derived> template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) { bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
if (!TraverseRecordHelper(D)) if (!TraverseRecordHelper(D))
return false; return false;
if (D->isCompleteDefinition()) { if (D->isCompleteDefinition()) {
for (const auto &I : D->bases()) { 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 // We don't traverse the friends or the conversions, as they are
// already in decls_begin()/decls_end(). // already in decls_begin()/decls_end().
@ -2057,7 +2090,7 @@ DEF_TRAVERSE_DECL(ParmVarDecl, {
TRY_TO(WalkUpFrom##STMT(S)); \ TRY_TO(WalkUpFrom##STMT(S)); \
{ CODE; } \ { CODE; } \
if (ShouldVisitChildren) { \ if (ShouldVisitChildren) { \
for (Stmt *SubStmt : S->children()) { \ for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
} \ } \
} \ } \
@ -3038,6 +3071,30 @@ bool RecursiveASTVisitor<Derived>::VisitOMPTaskReductionClause(
return true; 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> template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) { bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
TRY_TO(VisitOMPClauseList(C)); TRY_TO(VisitOMPClauseList(C));
@ -3052,6 +3109,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
template <typename Derived> template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) { bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) {
TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getDevice())); TRY_TO(TraverseStmt(C->getDevice()));
return true; 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 // The LLVM Compiler Infrastructure
// //
@ -15,11 +15,18 @@
#define LLVM_CLANG_AST_REDECLARABLE_H #define LLVM_CLANG_AST_REDECLARABLE_H
#include "clang/AST/ExternalASTSource.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 "llvm/Support/Casting.h"
#include <cassert>
#include <cstddef>
#include <iterator> #include <iterator>
namespace clang { namespace clang {
class ASTContext; class ASTContext;
class Decl;
// Some notes on redeclarables: // Some notes on redeclarables:
// //
@ -82,21 +89,21 @@ protected:
class DeclLink { class DeclLink {
/// A pointer to a known latest declaration, either statically known or /// A pointer to a known latest declaration, either statically known or
/// generationally updated as decls are added by an external source. /// generationally updated as decls are added by an external source.
typedef LazyGenerationalUpdatePtr<const Decl*, Decl*, using KnownLatest =
&ExternalASTSource::CompleteRedeclChain> LazyGenerationalUpdatePtr<const Decl *, Decl *,
KnownLatest; &ExternalASTSource::CompleteRedeclChain>;
/// We store a pointer to the ASTContext in the UninitializedLatest /// We store a pointer to the ASTContext in the UninitializedLatest
/// pointer, but to avoid circular type dependencies when we steal the low /// pointer, but to avoid circular type dependencies when we steal the low
/// bits of this pointer, we use a raw void* here. /// 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 /// 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 /// we've not yet set the previous decl or there isn't one), or to a known
/// previous declaration. /// previous declaration.
typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest; using NotKnownLatest = llvm::PointerUnion<Previous, UninitializedLatest>;
mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next; mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
@ -106,8 +113,7 @@ protected:
DeclLink(LatestTag, const ASTContext &Ctx) DeclLink(LatestTag, const ASTContext &Ctx)
: Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {} : Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
DeclLink(PreviousTag, decl_type *D) DeclLink(PreviousTag, decl_type *D) : Next(NotKnownLatest(Previous(D))) {}
: Next(NotKnownLatest(Previous(D))) {}
bool NextIsPrevious() const { bool NextIsPrevious() const {
return Next.is<NotKnownLatest>() && return Next.is<NotKnownLatest>() &&
@ -182,6 +188,7 @@ protected:
/// ///
/// If there is only one declaration, it is <pointer to self, true> /// If there is only one declaration, it is <pointer to self, true>
DeclLink RedeclLink; DeclLink RedeclLink;
decl_type *First; decl_type *First;
decl_type *getNextRedeclaration() const { decl_type *getNextRedeclaration() const {
@ -189,8 +196,12 @@ protected:
} }
public: public:
Redeclarable(const ASTContext &Ctx) friend class ASTDeclReader;
: RedeclLink(LatestDeclLink(Ctx)), First(static_cast<decl_type *>(this)) {} 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 /// \brief Return the previous declaration of this declaration or NULL if this
/// is the first declaration. /// is the first declaration.
@ -232,20 +243,19 @@ public:
/// \brief Iterates through all the redeclarations of the same decl. /// \brief Iterates through all the redeclarations of the same decl.
class redecl_iterator { class redecl_iterator {
/// Current - The current declaration. /// Current - The current declaration.
decl_type *Current; decl_type *Current = nullptr;
decl_type *Starter; decl_type *Starter;
bool PassedFirst; bool PassedFirst = false;
public: public:
typedef decl_type* value_type; using value_type = decl_type *;
typedef decl_type* reference; using reference = decl_type *;
typedef decl_type* pointer; using pointer = decl_type *;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
typedef std::ptrdiff_t difference_type; using difference_type = std::ptrdiff_t;
redecl_iterator() : Current(nullptr) { } redecl_iterator() = default;
explicit redecl_iterator(decl_type *C) explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) {}
: Current(C), Starter(C), PassedFirst(false) { }
reference operator*() const { return Current; } reference operator*() const { return Current; }
pointer 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 /// \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). /// 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_begin() const { return redecls().begin(); }
redecl_iterator redecls_end() const { return redecls().end(); } 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 /// \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> template<typename decl_type>
class Mergeable { class Mergeable {
public: public:
Mergeable() {} Mergeable() = default;
/// \brief Return the first declaration of this declaration or itself if this /// \brief Return the first declaration of this declaration or itself if this
/// is the only declaration. /// is the only declaration.
@ -344,7 +351,7 @@ public:
/// remember to call getCanonicalDecl() everywhere. /// remember to call getCanonicalDecl() everywhere.
template <typename decl_type> class CanonicalDeclPtr { template <typename decl_type> class CanonicalDeclPtr {
public: public:
CanonicalDeclPtr() : Ptr(nullptr) {} CanonicalDeclPtr() = default;
CanonicalDeclPtr(decl_type *Ptr) CanonicalDeclPtr(decl_type *Ptr)
: Ptr(Ptr ? Ptr->getCanonicalDecl() : nullptr) {} : Ptr(Ptr ? Ptr->getCanonicalDecl() : nullptr) {}
CanonicalDeclPtr(const CanonicalDeclPtr &) = default; CanonicalDeclPtr(const CanonicalDeclPtr &) = default;
@ -362,11 +369,13 @@ public:
private: private:
friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>; friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>;
decl_type *Ptr; decl_type *Ptr = nullptr;
}; };
} // namespace clang } // namespace clang
namespace llvm { namespace llvm {
template <typename decl_type> template <typename decl_type>
struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> { struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
using CanonicalDeclPtr = 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); return BaseInfo::isEqual(LHS, RHS);
} }
}; };
} // namespace llvm } // 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 // The LLVM Compiler Infrastructure
// //
@ -21,13 +21,10 @@
namespace llvm { namespace llvm {
//template <typename T> struct GraphTraits; template <> struct GraphTraits<clang::Stmt *> {
using NodeRef = clang::Stmt *;
using ChildIteratorType = clang::Stmt::child_iterator;
template <> struct GraphTraits<clang::Stmt*> { using nodes_iterator = llvm::df_iterator<clang::Stmt *>;
typedef clang::Stmt * NodeRef;
typedef clang::Stmt::child_iterator ChildIteratorType;
typedef llvm::df_iterator<clang::Stmt*> nodes_iterator;
static NodeRef getEntryNode(clang::Stmt *S) { return S; } static NodeRef getEntryNode(clang::Stmt *S) { return S; }
@ -50,11 +47,10 @@ template <> struct GraphTraits<clang::Stmt*> {
} }
}; };
template <> struct GraphTraits<const clang::Stmt *> {
template <> struct GraphTraits<const clang::Stmt*> { using NodeRef = const clang::Stmt *;
typedef const clang::Stmt * NodeRef; using ChildIteratorType = clang::Stmt::const_child_iterator;
typedef clang::Stmt::const_child_iterator ChildIteratorType; using nodes_iterator = llvm::df_iterator<const clang::Stmt *>;
typedef llvm::df_iterator<const clang::Stmt*> nodes_iterator;
static NodeRef getEntryNode(const clang::Stmt *S) { return S; } 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 // LLVM_CLANG_AST_STMTGRAPHTRAITS_H
#endif

View File

@ -1,4 +1,4 @@
//===--- StmtIterator.h - Iterators for Statements --------------*- C++ -*-===// //===- StmtIterator.h - Iterators for Statements ----------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -14,31 +14,38 @@
#ifndef LLVM_CLANG_AST_STMTITERATOR_H #ifndef LLVM_CLANG_AST_STMTITERATOR_H
#define LLVM_CLANG_AST_STMTITERATOR_H #define LLVM_CLANG_AST_STMTITERATOR_H
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <iterator> #include <iterator>
#include <utility>
namespace clang { namespace clang {
class Stmt;
class Decl; class Decl;
class Stmt;
class VariableArrayType; class VariableArrayType;
class StmtIteratorBase { class StmtIteratorBase {
protected: protected:
enum { StmtMode = 0x0, SizeOfTypeVAMode = 0x1, DeclGroupMode = 0x2, enum {
Flags = 0x3 }; StmtMode = 0x0,
SizeOfTypeVAMode = 0x1,
DeclGroupMode = 0x2,
Flags = 0x3
};
union { union {
Stmt **stmt; Stmt **stmt;
Decl **DGI; Decl **DGI;
}; };
uintptr_t RawVAPtr; uintptr_t RawVAPtr = 0;
Decl **DGE; Decl **DGE;
StmtIteratorBase(Stmt **s) : stmt(s) {}
StmtIteratorBase(const VariableArrayType *t);
StmtIteratorBase(Decl **dgi, Decl **dge);
StmtIteratorBase() : stmt(nullptr) {}
bool inDeclGroup() const { bool inDeclGroup() const {
return (RawVAPtr & Flags) == DeclGroupMode; return (RawVAPtr & Flags) == DeclGroupMode;
} }
@ -56,7 +63,7 @@ protected:
} }
void setVAPtr(const VariableArrayType *P) { void setVAPtr(const VariableArrayType *P) {
assert (inDeclGroup() || inSizeOfTypeVA()); assert(inDeclGroup() || inSizeOfTypeVA());
RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags); RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
} }
@ -65,14 +72,8 @@ protected:
void NextVA(); void NextVA();
Stmt*& GetDeclExpr() const; 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> template <typename DERIVED, typename REFERENCE>
class StmtIteratorImpl : public StmtIteratorBase, class StmtIteratorImpl : public StmtIteratorBase,
public std::iterator<std::forward_iterator_tag, public std::iterator<std::forward_iterator_tag,
@ -80,8 +81,9 @@ class StmtIteratorImpl : public StmtIteratorBase,
REFERENCE, REFERENCE> { REFERENCE, REFERENCE> {
protected: protected:
StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {} StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
public: public:
StmtIteratorImpl() {} StmtIteratorImpl() = default;
StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {} StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {} StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {} StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
@ -120,16 +122,13 @@ public:
struct ConstStmtIterator; struct ConstStmtIterator;
struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> { struct StmtIterator : public StmtIteratorImpl<StmtIterator, Stmt*&> {
explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {} explicit StmtIterator() = default;
StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator, Stmt*&>(S) {}
StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
StmtIterator(Decl** dgi, Decl** dge) StmtIterator(Decl** dgi, Decl** dge)
: StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {} : StmtIteratorImpl<StmtIterator, Stmt*&>(dgi, dge) {}
StmtIterator(const VariableArrayType *t) StmtIterator(const VariableArrayType *t)
: StmtIteratorImpl<StmtIterator,Stmt*&>(t) {} : StmtIteratorImpl<StmtIterator, Stmt*&>(t) {}
private: private:
StmtIterator(const StmtIteratorBase &RHS) StmtIterator(const StmtIteratorBase &RHS)
@ -141,11 +140,9 @@ private:
struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator, struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
const Stmt*> { const Stmt*> {
explicit ConstStmtIterator() : explicit ConstStmtIterator() = default;
StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {} ConstStmtIterator(const StmtIterator& RHS)
: StmtIteratorImpl<ConstStmtIterator, const Stmt*>(RHS) {}
ConstStmtIterator(const StmtIterator& RHS) :
StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
ConstStmtIterator(Stmt * const *S) ConstStmtIterator(Stmt * const *S)
: StmtIteratorImpl<ConstStmtIterator, const Stmt *>( : StmtIteratorImpl<ConstStmtIterator, const Stmt *>(
@ -155,6 +152,7 @@ struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
inline StmtIterator cast_away_const(const ConstStmtIterator &RHS) { inline StmtIterator cast_away_const(const ConstStmtIterator &RHS) {
return 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 { const Stmt *getBody() const {
// This relies on the loop form is already checked by Sema. // 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(); Body = cast<ForStmt>(Body)->getBody();
for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) { for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
Body = Body->IgnoreContainers(); Body = Body->IgnoreContainers();
@ -955,8 +957,15 @@ public:
T->getStmtClass() == OMPTargetSimdDirectiveClass || T->getStmtClass() == OMPTargetSimdDirectiveClass ||
T->getStmtClass() == OMPTeamsDistributeDirectiveClass || T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass || T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass || T->getStmtClass() ==
T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; 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, OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses) unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup, : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
StartLoc, EndLoc, NumClauses, 1) {} StartLoc, EndLoc, NumClauses, 2) {}
/// Build an empty directive. /// Build an empty directive.
/// \param NumClauses Number of clauses. /// \param NumClauses Number of clauses.
@ -1920,7 +1929,12 @@ class OMPTaskgroupDirective : public OMPExecutableDirective {
explicit OMPTaskgroupDirective(unsigned NumClauses) explicit OMPTaskgroupDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup, : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
SourceLocation(), SourceLocation(), NumClauses, SourceLocation(), SourceLocation(), NumClauses,
1) {} 2) {}
/// Sets the task_reduction return variable.
void setReductionRef(Expr *RR) {
*std::next(child_begin(), 1) = RR;
}
public: public:
/// Creates directive. /// Creates directive.
@ -1930,10 +1944,12 @@ public:
/// \param EndLoc Ending Location of the directive. /// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive. /// \param AssociatedStmt Statement, associated with the directive.
/// \param ReductionRef Reference to the task_reduction return variable.
/// ///
static OMPTaskgroupDirective * static OMPTaskgroupDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
Expr *ReductionRef);
/// Creates an empty directive. /// Creates an empty directive.
/// ///
@ -1943,6 +1959,15 @@ public:
static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell); 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) { static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTaskgroupDirectiveClass; return T->getStmtClass() == OMPTaskgroupDirectiveClass;
} }
@ -2330,7 +2355,7 @@ class OMPTargetEnterDataDirective : public OMPExecutableDirective {
unsigned NumClauses) unsigned NumClauses)
: OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass, : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
OMPD_target_enter_data, StartLoc, EndLoc, OMPD_target_enter_data, StartLoc, EndLoc,
NumClauses, /*NumChildren=*/0) {} NumClauses, /*NumChildren=*/1) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
@ -2340,7 +2365,7 @@ class OMPTargetEnterDataDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass, : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
OMPD_target_enter_data, SourceLocation(), OMPD_target_enter_data, SourceLocation(),
SourceLocation(), NumClauses, SourceLocation(), NumClauses,
/*NumChildren=*/0) {} /*NumChildren=*/1) {}
public: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
@ -2349,11 +2374,11 @@ public:
/// \param StartLoc Starting location of the directive kind. /// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive. /// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// ///
static OMPTargetEnterDataDirective *Create(const ASTContext &C, static OMPTargetEnterDataDirective *
SourceLocation StartLoc, Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
ArrayRef<OMPClause *> Clauses);
/// \brief Creates an empty directive with the place for \a N clauses. /// \brief Creates an empty directive with the place for \a N clauses.
/// ///
@ -2389,7 +2414,7 @@ class OMPTargetExitDataDirective : public OMPExecutableDirective {
unsigned NumClauses) unsigned NumClauses)
: OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass, : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
OMPD_target_exit_data, StartLoc, EndLoc, OMPD_target_exit_data, StartLoc, EndLoc,
NumClauses, /*NumChildren=*/0) {} NumClauses, /*NumChildren=*/1) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
@ -2399,7 +2424,7 @@ class OMPTargetExitDataDirective : public OMPExecutableDirective {
: OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass, : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
OMPD_target_exit_data, SourceLocation(), OMPD_target_exit_data, SourceLocation(),
SourceLocation(), NumClauses, SourceLocation(), NumClauses,
/*NumChildren=*/0) {} /*NumChildren=*/1) {}
public: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
@ -2408,11 +2433,11 @@ public:
/// \param StartLoc Starting location of the directive kind. /// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive. /// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// ///
static OMPTargetExitDataDirective *Create(const ASTContext &C, static OMPTargetExitDataDirective *
SourceLocation StartLoc, Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
ArrayRef<OMPClause *> Clauses);
/// \brief Creates an empty directive with the place for \a N clauses. /// \brief Creates an empty directive with the place for \a N clauses.
/// ///
@ -2966,7 +2991,7 @@ class OMPTargetUpdateDirective : public OMPExecutableDirective {
unsigned NumClauses) unsigned NumClauses)
: OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
OMPD_target_update, StartLoc, EndLoc, NumClauses, OMPD_target_update, StartLoc, EndLoc, NumClauses,
0) {} 1) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
@ -2975,7 +3000,7 @@ class OMPTargetUpdateDirective : public OMPExecutableDirective {
explicit OMPTargetUpdateDirective(unsigned NumClauses) explicit OMPTargetUpdateDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
OMPD_target_update, SourceLocation(), OMPD_target_update, SourceLocation(),
SourceLocation(), NumClauses, 0) {} SourceLocation(), NumClauses, 1) {}
public: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
@ -2984,11 +3009,11 @@ public:
/// \param StartLoc Starting location of the directive kind. /// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive. /// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// ///
static OMPTargetUpdateDirective *Create(const ASTContext &C, static OMPTargetUpdateDirective *
SourceLocation StartLoc, Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
ArrayRef<OMPClause *> Clauses);
/// \brief Creates an empty directive with the place for \a NumClauses /// \brief Creates an empty directive with the place for \a NumClauses
/// clauses. /// clauses.
@ -3015,6 +3040,8 @@ public:
/// ///
class OMPDistributeParallelForDirective : public OMPLoopDirective { class OMPDistributeParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader; friend class ASTStmtReader;
/// true if the construct has inner cancel directive.
bool HasCancel = false;
/// \brief Build directive with the given start and end location. /// \brief Build directive with the given start and end location.
/// ///
@ -3028,7 +3055,7 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective {
unsigned CollapsedNum, unsigned NumClauses) unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
OMPD_distribute_parallel_for, StartLoc, EndLoc, OMPD_distribute_parallel_for, StartLoc, EndLoc,
CollapsedNum, NumClauses) {} CollapsedNum, NumClauses), HasCancel(false) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
@ -3039,7 +3066,11 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective {
unsigned NumClauses) unsigned NumClauses)
: OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
OMPD_distribute_parallel_for, SourceLocation(), OMPD_distribute_parallel_for, SourceLocation(),
SourceLocation(), CollapsedNum, NumClauses) {} SourceLocation(), CollapsedNum, NumClauses),
HasCancel(false) {}
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
@ -3051,11 +3082,12 @@ public:
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive. /// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen. /// \param Exprs Helper expressions for CodeGen.
/// \param HasCancel true if this directive has inner cancel directive.
/// ///
static OMPDistributeParallelForDirective * static OMPDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 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 /// \brief Creates an empty directive with the place
/// for \a NumClauses clauses. /// for \a NumClauses clauses.
@ -3069,6 +3101,9 @@ public:
unsigned CollapsedNum, unsigned CollapsedNum,
EmptyShell); EmptyShell);
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
} }
@ -3565,6 +3600,8 @@ public:
/// ///
class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
friend class ASTStmtReader; friend class ASTStmtReader;
/// true if the construct has inner cancel directive.
bool HasCancel = false;
/// Build directive with the given start and end location. /// Build directive with the given start and end location.
/// ///
@ -3579,7 +3616,7 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
unsigned NumClauses) unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass, : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
OMPD_teams_distribute_parallel_for, StartLoc, EndLoc, OMPD_teams_distribute_parallel_for, StartLoc, EndLoc,
CollapsedNum, NumClauses) {} CollapsedNum, NumClauses), HasCancel(false) {}
/// Build an empty directive. /// Build an empty directive.
/// ///
@ -3590,7 +3627,11 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
unsigned NumClauses) unsigned NumClauses)
: OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass, : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
OMPD_teams_distribute_parallel_for, SourceLocation(), OMPD_teams_distribute_parallel_for, SourceLocation(),
SourceLocation(), CollapsedNum, NumClauses) {} SourceLocation(), CollapsedNum, NumClauses),
HasCancel(false) {}
/// Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public: public:
/// Creates directive with a list of \a Clauses. /// Creates directive with a list of \a Clauses.
@ -3602,11 +3643,12 @@ public:
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive. /// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen. /// \param Exprs Helper expressions for CodeGen.
/// \param HasCancel true if this directive has inner cancel directive.
/// ///
static OMPTeamsDistributeParallelForDirective * static OMPTeamsDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 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. /// Creates an empty directive with the place for \a NumClauses clauses.
/// ///
@ -3618,6 +3660,9 @@ public:
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell); EmptyShell);
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
} }
@ -3761,6 +3806,8 @@ public:
class OMPTargetTeamsDistributeParallelForDirective final class OMPTargetTeamsDistributeParallelForDirective final
: public OMPLoopDirective { : public OMPLoopDirective {
friend class ASTStmtReader; friend class ASTStmtReader;
/// true if the construct has inner cancel directive.
bool HasCancel = false;
/// Build directive with the given start and end location. /// Build directive with the given start and end location.
/// ///
@ -3776,7 +3823,8 @@ class OMPTargetTeamsDistributeParallelForDirective final
: OMPLoopDirective(this, : OMPLoopDirective(this,
OMPTargetTeamsDistributeParallelForDirectiveClass, OMPTargetTeamsDistributeParallelForDirectiveClass,
OMPD_target_teams_distribute_parallel_for, StartLoc, OMPD_target_teams_distribute_parallel_for, StartLoc,
EndLoc, CollapsedNum, NumClauses) {} EndLoc, CollapsedNum, NumClauses),
HasCancel(false) {}
/// Build an empty directive. /// Build an empty directive.
/// ///
@ -3788,7 +3836,11 @@ class OMPTargetTeamsDistributeParallelForDirective final
: OMPLoopDirective( : OMPLoopDirective(
this, OMPTargetTeamsDistributeParallelForDirectiveClass, this, OMPTargetTeamsDistributeParallelForDirectiveClass,
OMPD_target_teams_distribute_parallel_for, SourceLocation(), 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: public:
/// Creates directive with a list of \a Clauses. /// Creates directive with a list of \a Clauses.
@ -3800,11 +3852,12 @@ public:
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive. /// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen. /// \param Exprs Helper expressions for CodeGen.
/// \param HasCancel true if this directive has inner cancel directive.
/// ///
static OMPTargetTeamsDistributeParallelForDirective * static OMPTargetTeamsDistributeParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 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. /// Creates an empty directive with the place for \a NumClauses clauses.
/// ///
@ -3816,6 +3869,9 @@ public:
CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
EmptyShell); EmptyShell);
/// Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == return T->getStmtClass() ==
OMPTargetTeamsDistributeParallelForDirectiveClass; 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 // The LLVM Compiler Infrastructure
// //
@ -17,28 +17,33 @@
#include "clang/AST/ExprCXX.h" #include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h" #include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h" #include "clang/AST/ExprOpenMP.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h" #include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h" #include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtOpenMP.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 { namespace clang {
template <typename T> struct make_ptr { typedef T *type; }; template <typename T> struct make_ptr { using type = T *; };
template <typename T> struct make_const_ptr { typedef const T *type; }; template <typename T> struct make_const_ptr { using type = const T *; };
/// StmtVisitorBase - This class implements a simple visitor for Stmt /// StmtVisitorBase - This class implements a simple visitor for Stmt
/// subclasses. Since Expr derives from Stmt, this also includes support for /// subclasses. Since Expr derives from Stmt, this also includes support for
/// visiting Exprs. /// 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 { class StmtVisitorBase {
public: public:
#define PTR(CLASS) typename Ptr<CLASS>::type #define PTR(CLASS) typename Ptr<CLASS>::type
#define DISPATCH(NAME, CLASS) \ #define DISPATCH(NAME, CLASS) \
return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S)) return static_cast<ImplClass*>(this)->Visit ## NAME( \
static_cast<PTR(CLASS)>(S), std::forward<ParamTys>(P)...)
RetTy Visit(PTR(Stmt) S) {
RetTy Visit(PTR(Stmt) S, ParamTys... P) {
// If we have a binary expr, dispatch to the subcode of the binop. A smart // 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 // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
// below. // below.
@ -60,6 +65,7 @@ public:
case BO_GE: DISPATCH(BinGE, BinaryOperator); case BO_GE: DISPATCH(BinGE, BinaryOperator);
case BO_EQ: DISPATCH(BinEQ, BinaryOperator); case BO_EQ: DISPATCH(BinEQ, BinaryOperator);
case BO_NE: DISPATCH(BinNE, BinaryOperator); case BO_NE: DISPATCH(BinNE, BinaryOperator);
case BO_Cmp: DISPATCH(BinCmp, BinaryOperator);
case BO_And: DISPATCH(BinAnd, BinaryOperator); case BO_And: DISPATCH(BinAnd, BinaryOperator);
case BO_Xor: DISPATCH(BinXor, BinaryOperator); case BO_Xor: DISPATCH(BinXor, BinaryOperator);
@ -111,13 +117,13 @@ public:
// If the implementation chooses not to implement a certain visit method, fall // If the implementation chooses not to implement a certain visit method, fall
// back on VisitExpr or whatever else is the superclass. // back on VisitExpr or whatever else is the superclass.
#define STMT(CLASS, PARENT) \ #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" #include "clang/AST/StmtNodes.inc"
// If the implementation doesn't implement binary operator methods, fall back // If the implementation doesn't implement binary operator methods, fall back
// on VisitBinaryOperator. // on VisitBinaryOperator.
#define BINOP_FALLBACK(NAME) \ #define BINOP_FALLBACK(NAME) \
RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \ RetTy VisitBin ## NAME(PTR(BinaryOperator) S, ParamTys... P) { \
DISPATCH(BinaryOperator, BinaryOperator); \ DISPATCH(BinaryOperator, BinaryOperator); \
} }
BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI) BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI)
@ -127,6 +133,8 @@ public:
BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE) BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE)
BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE) BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE)
BINOP_FALLBACK(Cmp)
BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or) BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or)
BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr) BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr)
@ -137,7 +145,7 @@ public:
// If the implementation doesn't implement compound assignment operator // If the implementation doesn't implement compound assignment operator
// methods, fall back on VisitCompoundAssignOperator. // methods, fall back on VisitCompoundAssignOperator.
#define CAO_FALLBACK(NAME) \ #define CAO_FALLBACK(NAME) \
RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \ RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S, ParamTys... P) { \
DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \ DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
} }
CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign) 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 // If the implementation doesn't implement unary operator methods, fall back
// on VisitUnaryOperator. // on VisitUnaryOperator.
#define UNARYOP_FALLBACK(NAME) \ #define UNARYOP_FALLBACK(NAME) \
RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \ RetTy VisitUnary ## NAME(PTR(UnaryOperator) S, ParamTys... P) { \
DISPATCH(UnaryOperator, UnaryOperator); \ DISPATCH(UnaryOperator, UnaryOperator); \
} }
UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec) UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
@ -163,7 +171,7 @@ public:
#undef UNARYOP_FALLBACK #undef UNARYOP_FALLBACK
// Base case, ignore it. :) // Base case, ignore it. :)
RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); } RetTy VisitStmt(PTR(Stmt) Node, ParamTys... P) { return RetTy(); }
#undef PTR #undef PTR
#undef DISPATCH #undef DISPATCH
@ -174,18 +182,18 @@ public:
/// ///
/// This class does not preserve constness of Stmt pointers (see also /// This class does not preserve constness of Stmt pointers (see also
/// ConstStmtVisitor). /// ConstStmtVisitor).
template<typename ImplClass, typename RetTy=void> template<typename ImplClass, typename RetTy=void, typename... ParamTys>
class StmtVisitor class StmtVisitor
: public StmtVisitorBase<make_ptr, ImplClass, RetTy> {}; : public StmtVisitorBase<make_ptr, ImplClass, RetTy, ParamTys...> {};
/// ConstStmtVisitor - This class implements a simple visitor for Stmt /// ConstStmtVisitor - This class implements a simple visitor for Stmt
/// subclasses. Since Expr derives from Stmt, this also includes support for /// subclasses. Since Expr derives from Stmt, this also includes support for
/// visiting Exprs. /// visiting Exprs.
/// ///
/// This class preserves constness of Stmt pointers (see also StmtVisitor). /// 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 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 /// \brief This class implements a simple visitor for OMPClause
/// subclasses. /// subclasses.
@ -222,6 +230,6 @@ template<class ImplClass, typename RetTy = void>
class ConstOMPClauseVisitor : class ConstOMPClauseVisitor :
public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {}; 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 // The LLVM Compiler Infrastructure
// //
@ -15,21 +15,32 @@
#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
#define LLVM_CLANG_AST_TEMPLATEBASE_H #define LLVM_CLANG_AST_TEMPLATEBASE_H
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h" #include "clang/AST/TemplateName.h"
#include "clang/AST/Type.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/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/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TrailingObjects.h" #include "llvm/Support/TrailingObjects.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
namespace llvm { namespace llvm {
class FoldingSetNodeID;
} class FoldingSetNodeID;
} // namespace llvm
namespace clang { namespace clang {
class ASTContext;
class DiagnosticBuilder; class DiagnosticBuilder;
class Expr; class Expr;
struct PrintingPolicy; struct PrintingPolicy;
@ -44,29 +55,37 @@ public:
/// \brief Represents an empty template argument, e.g., one that has not /// \brief Represents an empty template argument, e.g., one that has not
/// been deduced. /// been deduced.
Null = 0, Null = 0,
/// The template argument is a type. /// The template argument is a type.
Type, Type,
/// The template argument is a declaration that was provided for a pointer, /// The template argument is a declaration that was provided for a pointer,
/// reference, or pointer to member non-type template parameter. /// reference, or pointer to member non-type template parameter.
Declaration, Declaration,
/// The template argument is a null pointer or null pointer to member that /// The template argument is a null pointer or null pointer to member that
/// was provided for a non-type template parameter. /// was provided for a non-type template parameter.
NullPtr, NullPtr,
/// The template argument is an integral value stored in an llvm::APSInt /// The template argument is an integral value stored in an llvm::APSInt
/// that was provided for an integral non-type template parameter. /// that was provided for an integral non-type template parameter.
Integral, Integral,
/// The template argument is a template name that was provided for a /// The template argument is a template name that was provided for a
/// template template parameter. /// template template parameter.
Template, Template,
/// The template argument is a pack expansion of a template name that was /// The template argument is a pack expansion of a template name that was
/// provided for a template template parameter. /// provided for a template template parameter.
TemplateExpansion, TemplateExpansion,
/// The template argument is an expression, and we've not resolved it to one /// 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 /// of the other forms yet, either because it's dependent or because we're
/// representing a non-canonical template argument (for instance, in a /// representing a non-canonical template argument (for instance, in a
/// TemplateSpecializationType). Also used to represent a non-dependent /// TemplateSpecializationType). Also used to represent a non-dependent
/// __uuidof expression (a Microsoft extension). /// __uuidof expression (a Microsoft extension).
Expression, Expression,
/// The template argument is actually a parameter pack. Arguments are stored /// The template argument is actually a parameter pack. Arguments are stored
/// in the Args struct. /// in the Args struct.
Pack Pack
@ -88,8 +107,11 @@ private:
unsigned BitWidth : 31; unsigned BitWidth : 31;
unsigned IsUnsigned : 1; unsigned IsUnsigned : 1;
union { union {
uint64_t VAL; ///< Used to store the <= 64 bits integer value. /// Used to store the <= 64 bits integer value.
const uint64_t *pVal; ///< 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; void *Type;
}; };
@ -115,8 +137,6 @@ private:
struct TV TypeOrValue; struct TV TypeOrValue;
}; };
TemplateArgument(TemplateName, bool) = delete;
public: public:
/// \brief Construct an empty, invalid template argument. /// \brief Construct an empty, invalid template argument.
constexpr TemplateArgument() : TypeOrValue({Null, 0}) {} constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
@ -202,6 +222,8 @@ public:
this->Args.NumArgs = Args.size(); this->Args.NumArgs = Args.size();
} }
TemplateArgument(TemplateName, bool) = delete;
static TemplateArgument getEmptyPack() { return TemplateArgument(None); } static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
/// \brief Create a new template argument pack by copying the given set of /// \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. // FIXME: Provide a way to read the integral data without copying the value.
llvm::APSInt getAsIntegral() const { llvm::APSInt getAsIntegral() const {
assert(getKind() == Integral && "Unexpected kind"); assert(getKind() == Integral && "Unexpected kind");
using namespace llvm; using namespace llvm;
if (Integer.BitWidth <= 64) if (Integer.BitWidth <= 64)
return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); 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. /// \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 /// \brief Iterator referencing the first argument of a template argument
/// pack. /// pack.
@ -368,7 +392,6 @@ public:
/// Location information for a TemplateArgument. /// Location information for a TemplateArgument.
struct TemplateArgumentLocInfo { struct TemplateArgumentLocInfo {
private: private:
struct T { struct T {
// FIXME: We'd like to just use the qualifier in the TemplateName, // FIXME: We'd like to just use the qualifier in the TemplateName,
// but template arguments get canonicalized too quickly. // but template arguments get canonicalized too quickly.
@ -393,8 +416,7 @@ public:
TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc, TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc, SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc) SourceLocation EllipsisLoc) {
{
Template.Qualifier = QualifierLoc.getNestedNameSpecifier(); Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
Template.QualifierLocData = QualifierLoc.getOpaqueData(); Template.QualifierLocData = QualifierLoc.getOpaqueData();
Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding(); Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
@ -434,16 +456,15 @@ public:
TemplateArgumentLoc(const TemplateArgument &Argument, TemplateArgumentLoc(const TemplateArgument &Argument,
TemplateArgumentLocInfo Opaque) TemplateArgumentLocInfo Opaque)
: Argument(Argument), LocInfo(Opaque) { : Argument(Argument), LocInfo(Opaque) {}
}
TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
: Argument(Argument), LocInfo(TInfo) { : Argument(Argument), LocInfo(TInfo) {
assert(Argument.getKind() == TemplateArgument::Type); assert(Argument.getKind() == TemplateArgument::Type);
} }
TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
: Argument(Argument), LocInfo(E) { : Argument(Argument), LocInfo(E) {
assert(Argument.getKind() == TemplateArgument::Expression); assert(Argument.getKind() == TemplateArgument::Expression);
} }
@ -451,7 +472,8 @@ public:
NestedNameSpecifierLoc QualifierLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc, SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc = SourceLocation()) SourceLocation EllipsisLoc = SourceLocation())
: Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) { : Argument(Argument),
LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
assert(Argument.getKind() == TemplateArgument::Template || assert(Argument.getKind() == TemplateArgument::Template ||
Argument.getKind() == TemplateArgument::TemplateExpansion); Argument.getKind() == TemplateArgument::TemplateExpansion);
} }
@ -526,16 +548,16 @@ class TemplateArgumentListInfo {
SourceLocation LAngleLoc; SourceLocation LAngleLoc;
SourceLocation RAngleLoc; SourceLocation RAngleLoc;
// This can leak if used in an AST node, use ASTTemplateArgumentListInfo
// instead.
void *operator new(size_t bytes, ASTContext &C) = delete;
public: public:
TemplateArgumentListInfo() {} TemplateArgumentListInfo() = default;
TemplateArgumentListInfo(SourceLocation LAngleLoc, TemplateArgumentListInfo(SourceLocation LAngleLoc,
SourceLocation RAngleLoc) 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 getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; } SourceLocation getRAngleLoc() const { return RAngleLoc; }
@ -574,8 +596,8 @@ struct ASTTemplateArgumentListInfo final
: private llvm::TrailingObjects<ASTTemplateArgumentListInfo, : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
TemplateArgumentLoc> { TemplateArgumentLoc> {
private: private:
friend TrailingObjects;
friend class ASTNodeImporter; friend class ASTNodeImporter;
friend TrailingObjects;
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List); ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
@ -668,6 +690,6 @@ inline const TemplateArgument &
return getArgs()[Idx]; 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 // The LLVM Compiler Infrastructure
// //
@ -14,10 +14,12 @@
#ifndef LLVM_CLANG_AST_TEMPLATENAME_H #ifndef LLVM_CLANG_AST_TEMPLATENAME_H
#define LLVM_CLANG_AST_TEMPLATENAME_H #define LLVM_CLANG_AST_TEMPLATENAME_H
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/Basic/LLVM.h" #include "clang/Basic/LLVM.h"
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
namespace clang { namespace clang {
@ -94,7 +96,7 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
friend class ASTContext; friend class ASTContext;
OverloadedTemplateStorage(unsigned size) OverloadedTemplateStorage(unsigned size)
: UncommonTemplateNameStorage(Overloaded, size) { } : UncommonTemplateNameStorage(Overloaded, size) {}
NamedDecl **getStorage() { NamedDecl **getStorage() {
return reinterpret_cast<NamedDecl **>(this + 1); return reinterpret_cast<NamedDecl **>(this + 1);
@ -104,7 +106,7 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
} }
public: public:
typedef NamedDecl *const *iterator; using iterator = NamedDecl *const *;
iterator begin() const { return getStorage(); } iterator begin() const { return getStorage(); }
iterator end() const { return getStorage() + size(); } iterator end() const { return getStorage() + size(); }
@ -126,8 +128,8 @@ public:
SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter, SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
unsigned Size, unsigned Size,
const TemplateArgument *Arguments) const TemplateArgument *Arguments)
: UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size), : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
Parameter(Parameter), Arguments(Arguments) { } Parameter(Parameter), Arguments(Arguments) {}
/// \brief Retrieve the template template parameter pack being substituted. /// \brief Retrieve the template template parameter pack being substituted.
TemplateTemplateParmDecl *getParameterPack() const { TemplateTemplateParmDecl *getParameterPack() const {
@ -174,10 +176,9 @@ public:
/// specifier in the typedef. "apply" is a nested template, and can /// specifier in the typedef. "apply" is a nested template, and can
/// only be understood in the context of /// only be understood in the context of
class TemplateName { class TemplateName {
typedef llvm::PointerUnion4<TemplateDecl *, using StorageType =
UncommonTemplateNameStorage *, llvm::PointerUnion4<TemplateDecl *, UncommonTemplateNameStorage *,
QualifiedTemplateName *, QualifiedTemplateName *, DependentTemplateName *>;
DependentTemplateName *> StorageType;
StorageType Storage; StorageType Storage;
@ -188,24 +189,29 @@ public:
enum NameKind { enum NameKind {
/// \brief A single template declaration. /// \brief A single template declaration.
Template, Template,
/// \brief A set of overloaded template declarations. /// \brief A set of overloaded template declarations.
OverloadedTemplate, OverloadedTemplate,
/// \brief A qualified template name, where the qualification is kept /// \brief A qualified template name, where the qualification is kept
/// to describe the source code as written. /// to describe the source code as written.
QualifiedTemplate, QualifiedTemplate,
/// \brief A dependent template name that has not been resolved to a /// \brief A dependent template name that has not been resolved to a
/// template (or set of templates). /// template (or set of templates).
DependentTemplate, DependentTemplate,
/// \brief A template template parameter that has been substituted /// \brief A template template parameter that has been substituted
/// for some other template name. /// for some other template name.
SubstTemplateTemplateParm, SubstTemplateTemplateParm,
/// \brief A template template parameter pack that has been substituted for /// \brief A template template parameter pack that has been substituted for
/// a template template argument pack, but has not yet been expanded into /// a template template argument pack, but has not yet been expanded into
/// individual arguments. /// individual arguments.
SubstTemplateTemplateParmPack SubstTemplateTemplateParmPack
}; };
TemplateName() : Storage() { } TemplateName() = default;
explicit TemplateName(TemplateDecl *Template); explicit TemplateName(TemplateDecl *Template);
explicit TemplateName(OverloadedTemplateStorage *Storage); explicit TemplateName(OverloadedTemplateStorage *Storage);
explicit TemplateName(SubstTemplateTemplateParmStorage *Storage); explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
@ -262,6 +268,11 @@ public:
TemplateName getUnderlying() const; 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. /// \brief Determines whether this is a dependent template name.
bool isDependent() const; bool isDependent() const;
@ -320,8 +331,8 @@ class SubstTemplateTemplateParmStorage
SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter, SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
TemplateName replacement) TemplateName replacement)
: UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0), : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
Parameter(parameter), Replacement(replacement) {} Parameter(parameter), Replacement(replacement) {}
public: public:
TemplateTemplateParmDecl *getParameter() const { return Parameter; } TemplateTemplateParmDecl *getParameter() const { return Parameter; }
@ -353,6 +364,8 @@ inline TemplateName TemplateName::getUnderlying() const {
/// manner, it is to TemplateName what ElaboratedType is to Type, /// manner, it is to TemplateName what ElaboratedType is to Type,
/// providing extra syntactic sugar for downstream clients. /// providing extra syntactic sugar for downstream clients.
class QualifiedTemplateName : public llvm::FoldingSetNode { class QualifiedTemplateName : public llvm::FoldingSetNode {
friend class ASTContext;
/// \brief The nested name specifier that qualifies the template name. /// \brief The nested name specifier that qualifies the template name.
/// ///
/// The bit is used to indicate whether the "template" keyword was /// 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. /// that this qualified name refers to.
TemplateDecl *Template; TemplateDecl *Template;
friend class ASTContext;
QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
TemplateDecl *Template) TemplateDecl *Template)
: Qualifier(NNS, TemplateKeyword? 1 : 0), : Qualifier(NNS, TemplateKeyword? 1 : 0), Template(Template) {}
Template(Template) { }
public: public:
/// \brief Return the nested name specifier that qualifies this name. /// \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 /// where "MetaFun::" is the nested name specifier and "apply" is the
/// template name referenced. The "template" keyword is implied. /// template name referenced. The "template" keyword is implied.
class DependentTemplateName : public llvm::FoldingSetNode { class DependentTemplateName : public llvm::FoldingSetNode {
friend class ASTContext;
/// \brief The nested name specifier that qualifies the template /// \brief The nested name specifier that qualifies the template
/// name. /// name.
/// ///
@ -439,29 +451,27 @@ class DependentTemplateName : public llvm::FoldingSetNode {
/// canonical. /// canonical.
TemplateName CanonicalTemplateName; TemplateName CanonicalTemplateName;
friend class ASTContext;
DependentTemplateName(NestedNameSpecifier *Qualifier, DependentTemplateName(NestedNameSpecifier *Qualifier,
const IdentifierInfo *Identifier) const IdentifierInfo *Identifier)
: Qualifier(Qualifier, false), Identifier(Identifier), : Qualifier(Qualifier, false), Identifier(Identifier),
CanonicalTemplateName(this) { } CanonicalTemplateName(this) {}
DependentTemplateName(NestedNameSpecifier *Qualifier, DependentTemplateName(NestedNameSpecifier *Qualifier,
const IdentifierInfo *Identifier, const IdentifierInfo *Identifier,
TemplateName Canon) TemplateName Canon)
: Qualifier(Qualifier, false), Identifier(Identifier), : Qualifier(Qualifier, false), Identifier(Identifier),
CanonicalTemplateName(Canon) { } CanonicalTemplateName(Canon) {}
DependentTemplateName(NestedNameSpecifier *Qualifier, DependentTemplateName(NestedNameSpecifier *Qualifier,
OverloadedOperatorKind Operator) OverloadedOperatorKind Operator)
: Qualifier(Qualifier, true), Operator(Operator), : Qualifier(Qualifier, true), Operator(Operator),
CanonicalTemplateName(this) { } CanonicalTemplateName(this) {}
DependentTemplateName(NestedNameSpecifier *Qualifier, DependentTemplateName(NestedNameSpecifier *Qualifier,
OverloadedOperatorKind Operator, OverloadedOperatorKind Operator,
TemplateName Canon) TemplateName Canon)
: Qualifier(Qualifier, true), Operator(Operator), : Qualifier(Qualifier, true), Operator(Operator),
CanonicalTemplateName(Canon) { } CanonicalTemplateName(Canon) {}
public: public:
/// \brief Return the nested name specifier that qualifies this name. /// \brief Return the nested name specifier that qualifies this name.
@ -509,14 +519,13 @@ public:
} }
}; };
} // end namespace clang. } // namespace clang.
namespace llvm { namespace llvm {
/// \brief The clang::TemplateName class is effectively a pointer. /// \brief The clang::TemplateName class is effectively a pointer.
template<> template<>
class PointerLikeTypeTraits<clang::TemplateName> { struct PointerLikeTypeTraits<clang::TemplateName> {
public:
static inline void *getAsVoidPointer(clang::TemplateName TN) { static inline void *getAsVoidPointer(clang::TemplateName TN) {
return TN.getAsVoidPointer(); return TN.getAsVoidPointer();
} }
@ -529,6 +538,6 @@ public:
enum { NumLowBitsAvailable = 0 }; 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 // The LLVM Compiler Infrastructure
// //
@ -6,26 +6,42 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// //
/// \file /// \file
/// \brief Defines the clang::TypeLoc interface and its subclasses. /// \brief Defines the clang::TypeLoc interface and its subclasses.
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_TYPELOC_H #ifndef LLVM_CLANG_AST_TYPELOC_H
#define LLVM_CLANG_AST_TYPELOC_H #define LLVM_CLANG_AST_TYPELOC_H
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h" #include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h" #include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
namespace clang { namespace clang {
class ASTContext;
class ParmVarDecl; class ASTContext;
class TypeSourceInfo; class CXXRecordDecl;
class UnqualTypeLoc; class Expr;
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
class ObjCTypeParamDecl;
class TemplateTypeParmDecl;
class UnqualTypeLoc;
class UnresolvedUsingTypenameDecl;
// Predeclare all the type nodes. // Predeclare all the type nodes.
#define ABSTRACT_TYPELOC(Class, Base) #define ABSTRACT_TYPELOC(Class, Base)
@ -41,10 +57,16 @@ class TypeLoc {
protected: protected:
// The correctness of this relies on the property that, for Type *Ty, // The correctness of this relies on the property that, for Type *Ty,
// QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
const void *Ty; const void *Ty = nullptr;
void *Data; void *Data = nullptr;
public: 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 /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
/// is of the desired type. /// is of the desired type.
/// ///
@ -88,12 +110,6 @@ public:
Qualified 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 { TypeLocClass getTypeLocClass() const {
if (getType().hasLocalQualifiers()) return Qualified; if (getType().hasLocalQualifiers()) return Qualified;
return (TypeLocClass) getType()->getTypeClass(); return (TypeLocClass) getType()->getTypeClass();
@ -134,6 +150,7 @@ public:
SourceRange getSourceRange() const LLVM_READONLY { SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getBeginLoc(), getEndLoc()); return SourceRange(getBeginLoc(), getEndLoc());
} }
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); } SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
@ -228,7 +245,7 @@ inline TypeLoc TypeSourceInfo::getTypeLoc() const {
/// no direct qualifiers. /// no direct qualifiers.
class UnqualTypeLoc : public TypeLoc { class UnqualTypeLoc : public TypeLoc {
public: public:
UnqualTypeLoc() {} UnqualTypeLoc() = default;
UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {} UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
const Type *getTypePtr() const { const Type *getTypePtr() const {
@ -241,6 +258,7 @@ public:
private: private:
friend class TypeLoc; friend class TypeLoc;
static bool isKind(const TypeLoc &TL) { static bool isKind(const TypeLoc &TL) {
return !TL.getType().hasLocalQualifiers(); return !TL.getType().hasLocalQualifiers();
} }
@ -253,9 +271,7 @@ private:
/// type qualifiers. /// type qualifiers.
class QualifiedTypeLoc : public TypeLoc { class QualifiedTypeLoc : public TypeLoc {
public: public:
SourceRange getLocalSourceRange() const { SourceRange getLocalSourceRange() const { return {}; }
return SourceRange();
}
UnqualTypeLoc getUnqualifiedLoc() const { UnqualTypeLoc getUnqualifiedLoc() const {
unsigned align = unsigned align =
@ -296,6 +312,7 @@ public:
private: private:
friend class TypeLoc; friend class TypeLoc;
static bool isKind(const TypeLoc &TL) { static bool isKind(const TypeLoc &TL) {
return TL.getType().hasLocalQualifiers(); return TL.getType().hasLocalQualifiers();
} }
@ -337,12 +354,12 @@ inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
/// InheritingConcreteTypeLoc instead. /// InheritingConcreteTypeLoc instead.
template <class Base, class Derived, class TypeClass, class LocalData> template <class Base, class Derived, class TypeClass, class LocalData>
class ConcreteTypeLoc : public Base { class ConcreteTypeLoc : public Base {
friend class TypeLoc;
const Derived *asDerived() const { const Derived *asDerived() const {
return static_cast<const Derived*>(this); return static_cast<const Derived*>(this);
} }
friend class TypeLoc;
static bool isKind(const TypeLoc &TL) { static bool isKind(const TypeLoc &TL) {
return !TL.getType().hasLocalQualifiers() && return !TL.getType().hasLocalQualifiers() &&
Derived::classofType(TL.getTypePtr()); Derived::classofType(TL.getTypePtr());
@ -357,6 +374,7 @@ public:
return std::max(unsigned(alignof(LocalData)), return std::max(unsigned(alignof(LocalData)),
asDerived()->getExtraLocalDataAlignment()); asDerived()->getExtraLocalDataAlignment());
} }
unsigned getLocalDataSize() const { unsigned getLocalDataSize() const {
unsigned size = sizeof(LocalData); unsigned size = sizeof(LocalData);
unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
@ -449,9 +467,7 @@ private:
return TypeLoc::getLocalAlignmentForType(T); return TypeLoc::getLocalAlignmentForType(T);
} }
TypeLoc getNextTypeLoc(HasNoInnerType _) const { TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; }
return TypeLoc();
}
TypeLoc getNextTypeLoc(QualType T) const { TypeLoc getNextTypeLoc(QualType T) const {
return TypeLoc(T, getNonLocalData()); return TypeLoc(T, getNonLocalData());
@ -464,6 +480,7 @@ private:
template <class Base, class Derived, class TypeClass> template <class Base, class Derived, class TypeClass>
class InheritingConcreteTypeLoc : public Base { class InheritingConcreteTypeLoc : public Base {
friend class TypeLoc; friend class TypeLoc;
static bool classofType(const Type *Ty) { static bool classofType(const Type *Ty) {
return TypeClass::classof(Ty); return TypeClass::classof(Ty);
} }
@ -482,7 +499,6 @@ public:
} }
}; };
struct TypeSpecLocInfo { struct TypeSpecLocInfo {
SourceLocation NameLoc; SourceLocation NameLoc;
}; };
@ -502,22 +518,25 @@ public:
SourceLocation getNameLoc() const { SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc; return this->getLocalData()->NameLoc;
} }
void setNameLoc(SourceLocation Loc) { void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc; this->getLocalData()->NameLoc = Loc;
} }
SourceRange getLocalSourceRange() const { SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc()); return SourceRange(getNameLoc(), getNameLoc());
} }
void initializeLocal(ASTContext &Context, SourceLocation Loc) { void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setNameLoc(Loc); setNameLoc(Loc);
} }
private: private:
friend class TypeLoc; friend class TypeLoc;
static bool isKind(const TypeLoc &TL); static bool isKind(const TypeLoc &TL);
}; };
struct BuiltinLocInfo { struct BuiltinLocInfo {
SourceRange BuiltinRange; SourceRange BuiltinRange;
}; };
@ -531,9 +550,11 @@ public:
SourceLocation getBuiltinLoc() const { SourceLocation getBuiltinLoc() const {
return getLocalData()->BuiltinRange.getBegin(); return getLocalData()->BuiltinRange.getBegin();
} }
void setBuiltinLoc(SourceLocation Loc) { void setBuiltinLoc(SourceLocation Loc) {
getLocalData()->BuiltinRange = Loc; getLocalData()->BuiltinRange = Loc;
} }
void expandBuiltinRange(SourceRange Range) { void expandBuiltinRange(SourceRange Range) {
SourceRange &BuiltinRange = getLocalData()->BuiltinRange; SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
if (!BuiltinRange.getBegin().isValid()) { if (!BuiltinRange.getBegin().isValid()) {
@ -579,9 +600,11 @@ public:
else else
return TSS_unspecified; return TSS_unspecified;
} }
bool hasWrittenSignSpec() const { bool hasWrittenSignSpec() const {
return getWrittenSignSpec() != TSS_unspecified; return getWrittenSignSpec() != TSS_unspecified;
} }
void setWrittenSignSpec(TypeSpecifierSign written) { void setWrittenSignSpec(TypeSpecifierSign written) {
if (needsExtraLocalData()) if (needsExtraLocalData())
getWrittenBuiltinSpecs().Sign = written; getWrittenBuiltinSpecs().Sign = written;
@ -593,18 +616,22 @@ public:
else else
return TSW_unspecified; return TSW_unspecified;
} }
bool hasWrittenWidthSpec() const { bool hasWrittenWidthSpec() const {
return getWrittenWidthSpec() != TSW_unspecified; return getWrittenWidthSpec() != TSW_unspecified;
} }
void setWrittenWidthSpec(TypeSpecifierWidth written) { void setWrittenWidthSpec(TypeSpecifierWidth written) {
if (needsExtraLocalData()) if (needsExtraLocalData())
getWrittenBuiltinSpecs().Width = written; getWrittenBuiltinSpecs().Width = written;
} }
TypeSpecifierType getWrittenTypeSpec() const; TypeSpecifierType getWrittenTypeSpec() const;
bool hasWrittenTypeSpec() const { bool hasWrittenTypeSpec() const {
return getWrittenTypeSpec() != TST_unspecified; return getWrittenTypeSpec() != TST_unspecified;
} }
void setWrittenTypeSpec(TypeSpecifierType written) { void setWrittenTypeSpec(TypeSpecifierType written) {
if (needsExtraLocalData()) if (needsExtraLocalData())
getWrittenBuiltinSpecs().Type = written; getWrittenBuiltinSpecs().Type = written;
@ -616,6 +643,7 @@ public:
else else
return false; return false;
} }
void setModeAttr(bool written) { void setModeAttr(bool written) {
if (needsExtraLocalData()) if (needsExtraLocalData())
getWrittenBuiltinSpecs().ModeAttr = written; getWrittenBuiltinSpecs().ModeAttr = written;
@ -633,7 +661,6 @@ public:
} }
}; };
/// \brief Wrapper for source info for typedefs. /// \brief Wrapper for source info for typedefs.
class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TypedefTypeLoc, TypedefTypeLoc,
@ -742,6 +769,7 @@ public:
*((SourceLocation*)this->getExtraLocalData()) : *((SourceLocation*)this->getExtraLocalData()) :
SourceLocation(); SourceLocation();
} }
void setProtocolLAngleLoc(SourceLocation Loc) { void setProtocolLAngleLoc(SourceLocation Loc) {
*((SourceLocation*)this->getExtraLocalData()) = Loc; *((SourceLocation*)this->getExtraLocalData()) = Loc;
} }
@ -751,6 +779,7 @@ public:
*((SourceLocation*)this->getExtraLocalData() + 1) : *((SourceLocation*)this->getExtraLocalData() + 1) :
SourceLocation(); SourceLocation();
} }
void setProtocolRAngleLoc(SourceLocation Loc) { void setProtocolRAngleLoc(SourceLocation Loc) {
*((SourceLocation*)this->getExtraLocalData() + 1) = Loc; *((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
} }
@ -763,6 +792,7 @@ public:
assert(i < getNumProtocols() && "Index is out of bounds!"); assert(i < getNumProtocols() && "Index is out of bounds!");
return getProtocolLocArray()[i]; return getProtocolLocArray()[i];
} }
void setProtocolLoc(unsigned i, SourceLocation Loc) { void setProtocolLoc(unsigned i, SourceLocation Loc) {
assert(i < getNumProtocols() && "Index is out of bounds!"); assert(i < getNumProtocols() && "Index is out of bounds!");
getProtocolLocArray()[i] = Loc; getProtocolLocArray()[i] = Loc;
@ -785,9 +815,11 @@ public:
// as well. // as well.
return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ; return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
} }
unsigned getExtraLocalDataAlignment() const { unsigned getExtraLocalDataAlignment() const {
return alignof(SourceLocation); return alignof(SourceLocation);
} }
SourceRange getLocalSourceRange() const { SourceRange getLocalSourceRange() const {
SourceLocation start = getNameLoc(); SourceLocation start = getNameLoc();
SourceLocation end = getProtocolRAngleLoc(); SourceLocation end = getProtocolRAngleLoc();
@ -938,7 +970,6 @@ public:
} }
}; };
struct ObjCObjectTypeLocInfo { struct ObjCObjectTypeLocInfo {
SourceLocation TypeArgsLAngleLoc; SourceLocation TypeArgsLAngleLoc;
SourceLocation TypeArgsRAngleLoc; SourceLocation TypeArgsRAngleLoc;
@ -971,6 +1002,7 @@ public:
SourceLocation getTypeArgsLAngleLoc() const { SourceLocation getTypeArgsLAngleLoc() const {
return this->getLocalData()->TypeArgsLAngleLoc; return this->getLocalData()->TypeArgsLAngleLoc;
} }
void setTypeArgsLAngleLoc(SourceLocation Loc) { void setTypeArgsLAngleLoc(SourceLocation Loc) {
this->getLocalData()->TypeArgsLAngleLoc = Loc; this->getLocalData()->TypeArgsLAngleLoc = Loc;
} }
@ -978,6 +1010,7 @@ public:
SourceLocation getTypeArgsRAngleLoc() const { SourceLocation getTypeArgsRAngleLoc() const {
return this->getLocalData()->TypeArgsRAngleLoc; return this->getLocalData()->TypeArgsRAngleLoc;
} }
void setTypeArgsRAngleLoc(SourceLocation Loc) { void setTypeArgsRAngleLoc(SourceLocation Loc) {
this->getLocalData()->TypeArgsRAngleLoc = Loc; this->getLocalData()->TypeArgsRAngleLoc = Loc;
} }
@ -999,6 +1032,7 @@ public:
SourceLocation getProtocolLAngleLoc() const { SourceLocation getProtocolLAngleLoc() const {
return this->getLocalData()->ProtocolLAngleLoc; return this->getLocalData()->ProtocolLAngleLoc;
} }
void setProtocolLAngleLoc(SourceLocation Loc) { void setProtocolLAngleLoc(SourceLocation Loc) {
this->getLocalData()->ProtocolLAngleLoc = Loc; this->getLocalData()->ProtocolLAngleLoc = Loc;
} }
@ -1006,6 +1040,7 @@ public:
SourceLocation getProtocolRAngleLoc() const { SourceLocation getProtocolRAngleLoc() const {
return this->getLocalData()->ProtocolRAngleLoc; return this->getLocalData()->ProtocolRAngleLoc;
} }
void setProtocolRAngleLoc(SourceLocation Loc) { void setProtocolRAngleLoc(SourceLocation Loc) {
this->getLocalData()->ProtocolRAngleLoc = Loc; this->getLocalData()->ProtocolRAngleLoc = Loc;
} }
@ -1018,6 +1053,7 @@ public:
assert(i < getNumProtocols() && "Index is out of bounds!"); assert(i < getNumProtocols() && "Index is out of bounds!");
return getProtocolLocArray()[i]; return getProtocolLocArray()[i];
} }
void setProtocolLoc(unsigned i, SourceLocation Loc) { void setProtocolLoc(unsigned i, SourceLocation Loc) {
assert(i < getNumProtocols() && "Index is out of bounds!"); assert(i < getNumProtocols() && "Index is out of bounds!");
getProtocolLocArray()[i] = Loc; getProtocolLocArray()[i] = Loc;
@ -1073,7 +1109,6 @@ public:
} }
}; };
struct ObjCInterfaceLocInfo { struct ObjCInterfaceLocInfo {
SourceLocation NameLoc; SourceLocation NameLoc;
SourceLocation NameEndLoc; SourceLocation NameEndLoc;
@ -1127,12 +1162,15 @@ public:
SourceLocation getLParenLoc() const { SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc; return this->getLocalData()->LParenLoc;
} }
SourceLocation getRParenLoc() const { SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc; return this->getLocalData()->RParenLoc;
} }
void setLParenLoc(SourceLocation Loc) { void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc; this->getLocalData()->LParenLoc = Loc;
} }
void setRParenLoc(SourceLocation Loc) { void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc; this->getLocalData()->RParenLoc = Loc;
} }
@ -1161,8 +1199,7 @@ inline TypeLoc TypeLoc::IgnoreParens() const {
return *this; return *this;
} }
struct AdjustedLocInfo {}; // Nothing.
struct AdjustedLocInfo { }; // Nothing.
class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc, class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
AdjustedType, AdjustedLocInfo> { AdjustedType, AdjustedLocInfo> {
@ -1181,9 +1218,7 @@ public:
return getTypePtr()->getOriginalType(); return getTypePtr()->getOriginalType();
} }
SourceRange getLocalSourceRange() const { SourceRange getLocalSourceRange() const { return {}; }
return SourceRange();
}
unsigned getLocalDataSize() const { unsigned getLocalDataSize() const {
// sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
@ -1210,6 +1245,7 @@ public:
SourceLocation getSigilLoc() const { SourceLocation getSigilLoc() const {
return this->getLocalData()->StarLoc; return this->getLocalData()->StarLoc;
} }
void setSigilLoc(SourceLocation Loc) { void setSigilLoc(SourceLocation Loc) {
this->getLocalData()->StarLoc = Loc; this->getLocalData()->StarLoc = Loc;
} }
@ -1231,7 +1267,6 @@ public:
} }
}; };
/// \brief Wrapper for source info for pointers. /// \brief Wrapper for source info for pointers.
class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc, class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
PointerType> { PointerType> {
@ -1239,12 +1274,12 @@ public:
SourceLocation getStarLoc() const { SourceLocation getStarLoc() const {
return getSigilLoc(); return getSigilLoc();
} }
void setStarLoc(SourceLocation Loc) { void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc); setSigilLoc(Loc);
} }
}; };
/// \brief Wrapper for source info for block pointers. /// \brief Wrapper for source info for block pointers.
class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc, class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
BlockPointerType> { BlockPointerType> {
@ -1252,6 +1287,7 @@ public:
SourceLocation getCaretLoc() const { SourceLocation getCaretLoc() const {
return getSigilLoc(); return getSigilLoc();
} }
void setCaretLoc(SourceLocation Loc) { void setCaretLoc(SourceLocation Loc) {
setSigilLoc(Loc); setSigilLoc(Loc);
} }
@ -1269,6 +1305,7 @@ public:
SourceLocation getStarLoc() const { SourceLocation getStarLoc() const {
return getSigilLoc(); return getSigilLoc();
} }
void setStarLoc(SourceLocation Loc) { void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc); setSigilLoc(Loc);
} }
@ -1276,9 +1313,11 @@ public:
const Type *getClass() const { const Type *getClass() const {
return getTypePtr()->getClass(); return getTypePtr()->getClass();
} }
TypeSourceInfo *getClassTInfo() const { TypeSourceInfo *getClassTInfo() const {
return getLocalData()->ClassTInfo; return getLocalData()->ClassTInfo;
} }
void setClassTInfo(TypeSourceInfo* TI) { void setClassTInfo(TypeSourceInfo* TI) {
getLocalData()->ClassTInfo = TI; getLocalData()->ClassTInfo = TI;
} }
@ -1310,7 +1349,6 @@ public:
} }
}; };
class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
ReferenceType> { ReferenceType> {
public: public:
@ -1327,6 +1365,7 @@ public:
SourceLocation getAmpLoc() const { SourceLocation getAmpLoc() const {
return getSigilLoc(); return getSigilLoc();
} }
void setAmpLoc(SourceLocation Loc) { void setAmpLoc(SourceLocation Loc) {
setSigilLoc(Loc); setSigilLoc(Loc);
} }
@ -1340,12 +1379,12 @@ public:
SourceLocation getAmpAmpLoc() const { SourceLocation getAmpAmpLoc() const {
return getSigilLoc(); return getSigilLoc();
} }
void setAmpAmpLoc(SourceLocation Loc) { void setAmpAmpLoc(SourceLocation Loc) {
setSigilLoc(Loc); setSigilLoc(Loc);
} }
}; };
struct FunctionLocInfo { struct FunctionLocInfo {
SourceLocation LocalRangeBegin; SourceLocation LocalRangeBegin;
SourceLocation LParenLoc; SourceLocation LParenLoc;
@ -1371,10 +1410,12 @@ class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
// exception specification information. // exception specification information.
return (SourceRange *)(getParmArray() + getNumParams()); return (SourceRange *)(getParmArray() + getNumParams());
} }
public: public:
SourceLocation getLocalRangeBegin() const { SourceLocation getLocalRangeBegin() const {
return getLocalData()->LocalRangeBegin; return getLocalData()->LocalRangeBegin;
} }
void setLocalRangeBegin(SourceLocation L) { void setLocalRangeBegin(SourceLocation L) {
getLocalData()->LocalRangeBegin = L; getLocalData()->LocalRangeBegin = L;
} }
@ -1382,6 +1423,7 @@ public:
SourceLocation getLocalRangeEnd() const { SourceLocation getLocalRangeEnd() const {
return getLocalData()->LocalRangeEnd; return getLocalData()->LocalRangeEnd;
} }
void setLocalRangeEnd(SourceLocation L) { void setLocalRangeEnd(SourceLocation L) {
getLocalData()->LocalRangeEnd = L; getLocalData()->LocalRangeEnd = L;
} }
@ -1389,6 +1431,7 @@ public:
SourceLocation getLParenLoc() const { SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc; return this->getLocalData()->LParenLoc;
} }
void setLParenLoc(SourceLocation Loc) { void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc; this->getLocalData()->LParenLoc = Loc;
} }
@ -1396,6 +1439,7 @@ public:
SourceLocation getRParenLoc() const { SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc; return this->getLocalData()->RParenLoc;
} }
void setRParenLoc(SourceLocation Loc) { void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc; this->getLocalData()->RParenLoc = Loc;
} }
@ -1407,8 +1451,9 @@ public:
SourceRange getExceptionSpecRange() const { SourceRange getExceptionSpecRange() const {
if (hasExceptionSpec()) if (hasExceptionSpec())
return *getExceptionSpecRangePtr(); return *getExceptionSpecRangePtr();
return SourceRange(); return {};
} }
void setExceptionSpecRange(SourceRange R) { void setExceptionSpecRange(SourceRange R) {
if (hasExceptionSpec()) if (hasExceptionSpec())
*getExceptionSpecRangePtr() = R; *getExceptionSpecRangePtr() = R;
@ -1428,6 +1473,7 @@ public:
return 0; return 0;
return cast<FunctionProtoType>(getTypePtr())->getNumParams(); return cast<FunctionProtoType>(getTypePtr())->getNumParams();
} }
ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; } ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
@ -1474,7 +1520,6 @@ class FunctionNoProtoTypeLoc :
FunctionNoProtoType> { FunctionNoProtoType> {
}; };
struct ArrayLocInfo { struct ArrayLocInfo {
SourceLocation LBracketLoc, RBracketLoc; SourceLocation LBracketLoc, RBracketLoc;
Expr *Size; Expr *Size;
@ -1489,6 +1534,7 @@ public:
SourceLocation getLBracketLoc() const { SourceLocation getLBracketLoc() const {
return getLocalData()->LBracketLoc; return getLocalData()->LBracketLoc;
} }
void setLBracketLoc(SourceLocation Loc) { void setLBracketLoc(SourceLocation Loc) {
getLocalData()->LBracketLoc = Loc; getLocalData()->LBracketLoc = Loc;
} }
@ -1496,6 +1542,7 @@ public:
SourceLocation getRBracketLoc() const { SourceLocation getRBracketLoc() const {
return getLocalData()->RBracketLoc; return getLocalData()->RBracketLoc;
} }
void setRBracketLoc(SourceLocation Loc) { void setRBracketLoc(SourceLocation Loc) {
getLocalData()->RBracketLoc = Loc; getLocalData()->RBracketLoc = Loc;
} }
@ -1507,6 +1554,7 @@ public:
Expr *getSizeExpr() const { Expr *getSizeExpr() const {
return getLocalData()->Size; return getLocalData()->Size;
} }
void setSizeExpr(Expr *Size) { void setSizeExpr(Expr *Size) {
getLocalData()->Size = Size; getLocalData()->Size = Size;
} }
@ -1557,7 +1605,6 @@ class VariableArrayTypeLoc :
VariableArrayType> { VariableArrayType> {
}; };
// Location information for a TemplateName. Rudimentary for now. // Location information for a TemplateName. Rudimentary for now.
struct TemplateNameLocInfo { struct TemplateNameLocInfo {
SourceLocation NameLoc; SourceLocation NameLoc;
@ -1578,6 +1625,7 @@ public:
SourceLocation getTemplateKeywordLoc() const { SourceLocation getTemplateKeywordLoc() const {
return getLocalData()->TemplateKWLoc; return getLocalData()->TemplateKWLoc;
} }
void setTemplateKeywordLoc(SourceLocation Loc) { void setTemplateKeywordLoc(SourceLocation Loc) {
getLocalData()->TemplateKWLoc = Loc; getLocalData()->TemplateKWLoc = Loc;
} }
@ -1585,6 +1633,7 @@ public:
SourceLocation getLAngleLoc() const { SourceLocation getLAngleLoc() const {
return getLocalData()->LAngleLoc; return getLocalData()->LAngleLoc;
} }
void setLAngleLoc(SourceLocation Loc) { void setLAngleLoc(SourceLocation Loc) {
getLocalData()->LAngleLoc = Loc; getLocalData()->LAngleLoc = Loc;
} }
@ -1592,6 +1641,7 @@ public:
SourceLocation getRAngleLoc() const { SourceLocation getRAngleLoc() const {
return getLocalData()->RAngleLoc; return getLocalData()->RAngleLoc;
} }
void setRAngleLoc(SourceLocation Loc) { void setRAngleLoc(SourceLocation Loc) {
getLocalData()->RAngleLoc = Loc; getLocalData()->RAngleLoc = Loc;
} }
@ -1599,9 +1649,11 @@ public:
unsigned getNumArgs() const { unsigned getNumArgs() const {
return getTypePtr()->getNumArgs(); return getTypePtr()->getNumArgs();
} }
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
getArgInfos()[i] = AI; getArgInfos()[i] = AI;
} }
TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
return getArgInfos()[i]; return getArgInfos()[i];
} }
@ -1613,6 +1665,7 @@ public:
SourceLocation getTemplateNameLoc() const { SourceLocation getTemplateNameLoc() const {
return getLocalData()->NameLoc; return getLocalData()->NameLoc;
} }
void setTemplateNameLoc(SourceLocation Loc) { void setTemplateNameLoc(SourceLocation Loc) {
getLocalData()->NameLoc = 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. // All of these need proper implementations.
@ -1717,6 +1838,7 @@ public:
SourceLocation getTypeofLoc() const { SourceLocation getTypeofLoc() const {
return this->getLocalData()->TypeofLoc; return this->getLocalData()->TypeofLoc;
} }
void setTypeofLoc(SourceLocation Loc) { void setTypeofLoc(SourceLocation Loc) {
this->getLocalData()->TypeofLoc = Loc; this->getLocalData()->TypeofLoc = Loc;
} }
@ -1724,6 +1846,7 @@ public:
SourceLocation getLParenLoc() const { SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc; return this->getLocalData()->LParenLoc;
} }
void setLParenLoc(SourceLocation Loc) { void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc; this->getLocalData()->LParenLoc = Loc;
} }
@ -1731,6 +1854,7 @@ public:
SourceLocation getRParenLoc() const { SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc; return this->getLocalData()->RParenLoc;
} }
void setRParenLoc(SourceLocation Loc) { void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc; this->getLocalData()->RParenLoc = Loc;
} }
@ -1738,6 +1862,7 @@ public:
SourceRange getParensRange() const { SourceRange getParensRange() const {
return SourceRange(getLParenLoc(), getRParenLoc()); return SourceRange(getLParenLoc(), getRParenLoc());
} }
void setParensRange(SourceRange range) { void setParensRange(SourceRange range) {
setLParenLoc(range.getBegin()); setLParenLoc(range.getBegin());
setRParenLoc(range.getEnd()); setRParenLoc(range.getEnd());
@ -1761,6 +1886,7 @@ public:
Expr* getUnderlyingExpr() const { Expr* getUnderlyingExpr() const {
return getTypePtr()->getUnderlyingExpr(); return getTypePtr()->getUnderlyingExpr();
} }
// Reimplemented to account for GNU/C++ extension // Reimplemented to account for GNU/C++ extension
// typeof unary-expression // typeof unary-expression
// where there are no parentheses. // where there are no parentheses.
@ -1773,9 +1899,11 @@ public:
QualType getUnderlyingType() const { QualType getUnderlyingType() const {
return this->getTypePtr()->getUnderlyingType(); return this->getTypePtr()->getUnderlyingType();
} }
TypeSourceInfo* getUnderlyingTInfo() const { TypeSourceInfo* getUnderlyingTInfo() const {
return this->getLocalData()->UnderlyingTInfo; return this->getLocalData()->UnderlyingTInfo;
} }
void setUnderlyingTInfo(TypeSourceInfo* TI) const { void setUnderlyingTInfo(TypeSourceInfo* TI) const {
this->getLocalData()->UnderlyingTInfo = TI; this->getLocalData()->UnderlyingTInfo = TI;
} }
@ -1815,6 +1943,7 @@ public:
TypeSourceInfo* getUnderlyingTInfo() const { TypeSourceInfo* getUnderlyingTInfo() const {
return getLocalData()->UnderlyingTInfo; return getLocalData()->UnderlyingTInfo;
} }
void setUnderlyingTInfo(TypeSourceInfo *TInfo) { void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
getLocalData()->UnderlyingTInfo = TInfo; getLocalData()->UnderlyingTInfo = TInfo;
} }
@ -1826,16 +1955,13 @@ public:
SourceRange getParensRange() const { SourceRange getParensRange() const {
return SourceRange(getLParenLoc(), getRParenLoc()); return SourceRange(getLParenLoc(), getRParenLoc());
} }
void setParensRange(SourceRange Range) { void setParensRange(SourceRange Range) {
setLParenLoc(Range.getBegin()); setLParenLoc(Range.getBegin());
setRParenLoc(Range.getEnd()); setRParenLoc(Range.getEnd());
} }
void initializeLocal(ASTContext &Context, SourceLocation Loc) { void initializeLocal(ASTContext &Context, SourceLocation Loc);
setKWLoc(Loc);
setRParenLoc(Loc);
setLParenLoc(Loc);
}
}; };
class DeducedTypeLoc class DeducedTypeLoc
@ -1854,6 +1980,7 @@ public:
SourceLocation getTemplateNameLoc() const { SourceLocation getTemplateNameLoc() const {
return getNameLoc(); return getNameLoc();
} }
void setTemplateNameLoc(SourceLocation Loc) { void setTemplateNameLoc(SourceLocation Loc) {
setNameLoc(Loc); setNameLoc(Loc);
} }
@ -1861,6 +1988,7 @@ public:
struct ElaboratedLocInfo { struct ElaboratedLocInfo {
SourceLocation ElaboratedKWLoc; SourceLocation ElaboratedKWLoc;
/// \brief Data associated with the nested-name-specifier location. /// \brief Data associated with the nested-name-specifier location.
void *QualifierData; void *QualifierData;
}; };
@ -1873,6 +2001,7 @@ public:
SourceLocation getElaboratedKeywordLoc() const { SourceLocation getElaboratedKeywordLoc() const {
return this->getLocalData()->ElaboratedKWLoc; return this->getLocalData()->ElaboratedKWLoc;
} }
void setElaboratedKeywordLoc(SourceLocation Loc) { void setElaboratedKeywordLoc(SourceLocation Loc) {
this->getLocalData()->ElaboratedKWLoc = Loc; this->getLocalData()->ElaboratedKWLoc = Loc;
} }
@ -1931,6 +2060,7 @@ public:
SourceLocation getElaboratedKeywordLoc() const { SourceLocation getElaboratedKeywordLoc() const {
return this->getLocalData()->ElaboratedKWLoc; return this->getLocalData()->ElaboratedKWLoc;
} }
void setElaboratedKeywordLoc(SourceLocation Loc) { void setElaboratedKeywordLoc(SourceLocation Loc) {
this->getLocalData()->ElaboratedKWLoc = Loc; this->getLocalData()->ElaboratedKWLoc = Loc;
} }
@ -1950,6 +2080,7 @@ public:
SourceLocation getNameLoc() const { SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc; return this->getLocalData()->NameLoc;
} }
void setNameLoc(SourceLocation Loc) { void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc; this->getLocalData()->NameLoc = Loc;
} }
@ -1986,6 +2117,7 @@ public:
SourceLocation getElaboratedKeywordLoc() const { SourceLocation getElaboratedKeywordLoc() const {
return this->getLocalData()->ElaboratedKWLoc; return this->getLocalData()->ElaboratedKWLoc;
} }
void setElaboratedKeywordLoc(SourceLocation Loc) { void setElaboratedKeywordLoc(SourceLocation Loc) {
this->getLocalData()->ElaboratedKWLoc = Loc; this->getLocalData()->ElaboratedKWLoc = Loc;
} }
@ -2017,6 +2149,7 @@ public:
SourceLocation getTemplateKeywordLoc() const { SourceLocation getTemplateKeywordLoc() const {
return getLocalData()->TemplateKWLoc; return getLocalData()->TemplateKWLoc;
} }
void setTemplateKeywordLoc(SourceLocation Loc) { void setTemplateKeywordLoc(SourceLocation Loc) {
getLocalData()->TemplateKWLoc = Loc; getLocalData()->TemplateKWLoc = Loc;
} }
@ -2024,6 +2157,7 @@ public:
SourceLocation getTemplateNameLoc() const { SourceLocation getTemplateNameLoc() const {
return this->getLocalData()->NameLoc; return this->getLocalData()->NameLoc;
} }
void setTemplateNameLoc(SourceLocation Loc) { void setTemplateNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc; this->getLocalData()->NameLoc = Loc;
} }
@ -2031,6 +2165,7 @@ public:
SourceLocation getLAngleLoc() const { SourceLocation getLAngleLoc() const {
return this->getLocalData()->LAngleLoc; return this->getLocalData()->LAngleLoc;
} }
void setLAngleLoc(SourceLocation Loc) { void setLAngleLoc(SourceLocation Loc) {
this->getLocalData()->LAngleLoc = Loc; this->getLocalData()->LAngleLoc = Loc;
} }
@ -2038,6 +2173,7 @@ public:
SourceLocation getRAngleLoc() const { SourceLocation getRAngleLoc() const {
return this->getLocalData()->RAngleLoc; return this->getLocalData()->RAngleLoc;
} }
void setRAngleLoc(SourceLocation Loc) { void setRAngleLoc(SourceLocation Loc) {
this->getLocalData()->RAngleLoc = Loc; this->getLocalData()->RAngleLoc = Loc;
} }
@ -2049,6 +2185,7 @@ public:
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
getArgInfos()[i] = AI; getArgInfos()[i] = AI;
} }
TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
return getArgInfos()[i]; return getArgInfos()[i];
} }
@ -2090,7 +2227,6 @@ private:
} }
}; };
struct PackExpansionTypeLocInfo { struct PackExpansionTypeLocInfo {
SourceLocation EllipsisLoc; SourceLocation EllipsisLoc;
}; };
@ -2142,6 +2278,7 @@ public:
SourceLocation getKWLoc() const { SourceLocation getKWLoc() const {
return this->getLocalData()->KWLoc; return this->getLocalData()->KWLoc;
} }
void setKWLoc(SourceLocation Loc) { void setKWLoc(SourceLocation Loc) {
this->getLocalData()->KWLoc = Loc; this->getLocalData()->KWLoc = Loc;
} }
@ -2149,6 +2286,7 @@ public:
SourceLocation getLParenLoc() const { SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc; return this->getLocalData()->LParenLoc;
} }
void setLParenLoc(SourceLocation Loc) { void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc; this->getLocalData()->LParenLoc = Loc;
} }
@ -2156,6 +2294,7 @@ public:
SourceLocation getRParenLoc() const { SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc; return this->getLocalData()->RParenLoc;
} }
void setRParenLoc(SourceLocation Loc) { void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc; this->getLocalData()->RParenLoc = Loc;
} }
@ -2163,6 +2302,7 @@ public:
SourceRange getParensRange() const { SourceRange getParensRange() const {
return SourceRange(getLParenLoc(), getRParenLoc()); return SourceRange(getLParenLoc(), getRParenLoc());
} }
void setParensRange(SourceRange Range) { void setParensRange(SourceRange Range) {
setLParenLoc(Range.getBegin()); setLParenLoc(Range.getBegin());
setRParenLoc(Range.getEnd()); setRParenLoc(Range.getEnd());
@ -2217,6 +2357,7 @@ inline T TypeLoc::getAsAdjusted() const {
} }
return Cur.getAs<T>(); 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 // NON_CANONICAL_TYPE(Class, Base) - A type that can show up
// anywhere in the AST but will never be a part of a canonical // anywhere in the AST but will never be a part of a canonical
// type. Clients that only need to deal with canonical types // 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. // pretty-printing) can ignore these types.
// //
// DEPENDENT_TYPE(Class, Base) - A type that will only show up // DEPENDENT_TYPE(Class, Base) - A type that will only show up
@ -73,6 +73,7 @@ TYPE(IncompleteArray, ArrayType)
TYPE(VariableArray, ArrayType) TYPE(VariableArray, ArrayType)
DEPENDENT_TYPE(DependentSizedArray, ArrayType) DEPENDENT_TYPE(DependentSizedArray, ArrayType)
DEPENDENT_TYPE(DependentSizedExtVector, Type) DEPENDENT_TYPE(DependentSizedExtVector, Type)
DEPENDENT_TYPE(DependentAddressSpace, Type)
TYPE(Vector, Type) TYPE(Vector, Type)
TYPE(ExtVector, VectorType) TYPE(ExtVector, VectorType)
ABSTRACT_TYPE(Function, Type) 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 // The LLVM Compiler Infrastructure
// //
@ -17,20 +17,25 @@
#include "clang/AST/DeclAccessPair.h" #include "clang/AST/DeclAccessPair.h"
#include "clang/Basic/LLVM.h" #include "clang/Basic/LLVM.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator.h"
#include <cstddef>
#include <iterator>
namespace clang { namespace clang {
class NamedDecl;
/// The iterator over UnresolvedSets. Serves as both the const and /// The iterator over UnresolvedSets. Serves as both the const and
/// non-const iterator. /// non-const iterator.
class UnresolvedSetIterator : public llvm::iterator_adaptor_base< class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
UnresolvedSetIterator, DeclAccessPair *, UnresolvedSetIterator, DeclAccessPair *,
std::random_access_iterator_tag, NamedDecl *, std::random_access_iterator_tag, NamedDecl *,
std::ptrdiff_t, NamedDecl *, NamedDecl *> { std::ptrdiff_t, NamedDecl *, NamedDecl *> {
friend class UnresolvedSetImpl;
friend class ASTUnresolvedSet; friend class ASTUnresolvedSet;
friend class OverloadExpr; friend class OverloadExpr;
friend class UnresolvedSetImpl;
explicit UnresolvedSetIterator(DeclAccessPair *Iter) explicit UnresolvedSetIterator(DeclAccessPair *Iter)
: iterator_adaptor_base(Iter) {} : iterator_adaptor_base(Iter) {}
@ -54,12 +59,13 @@ public:
/// \brief A set of unresolved declarations. /// \brief A set of unresolved declarations.
class UnresolvedSetImpl { class UnresolvedSetImpl {
typedef SmallVectorImpl<DeclAccessPair> DeclsTy; using DeclsTy = SmallVectorImpl<DeclAccessPair>;
// Don't allow direct construction, and only permit subclassing by // Don't allow direct construction, and only permit subclassing by
// UnresolvedSet. // UnresolvedSet.
private: private:
template <unsigned N> friend class UnresolvedSet; template <unsigned N> friend class UnresolvedSet;
UnresolvedSetImpl() = default; UnresolvedSetImpl() = default;
UnresolvedSetImpl(const UnresolvedSetImpl &) = default; UnresolvedSetImpl(const UnresolvedSetImpl &) = default;
UnresolvedSetImpl &operator=(const UnresolvedSetImpl &) = default; UnresolvedSetImpl &operator=(const UnresolvedSetImpl &) = default;
@ -71,8 +77,8 @@ private:
public: public:
// We don't currently support assignment through this iterator, so we might // We don't currently support assignment through this iterator, so we might
// as well use the same implementation twice. // as well use the same implementation twice.
typedef UnresolvedSetIterator iterator; using iterator = UnresolvedSetIterator;
typedef UnresolvedSetIterator const_iterator; using const_iterator = UnresolvedSetIterator;
iterator begin() { return iterator(decls().begin()); } iterator begin() { return iterator(decls().begin()); }
iterator end() { return iterator(decls().end()); } iterator end() { return iterator(decls().end()); }
@ -140,7 +146,7 @@ template <unsigned InlineCapacity> class UnresolvedSet :
SmallVector<DeclAccessPair, InlineCapacity> Decls; SmallVector<DeclAccessPair, InlineCapacity> Decls;
}; };
} // namespace clang } // 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 // The LLVM Compiler Infrastructure
// //
@ -16,25 +16,31 @@
#define LLVM_CLANG_AST_VTTBUILDER_H #define LLVM_CLANG_AST_VTTBUILDER_H
#include "clang/AST/BaseSubobject.h" #include "clang/AST/BaseSubobject.h"
#include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h"
#include "clang/AST/GlobalDecl.h" #include "clang/Basic/LLVM.h"
#include "clang/AST/RecordLayout.h" #include "llvm/ADT/DenseMap.h"
#include "clang/Basic/ABI.h" #include "llvm/ADT/PointerIntPair.h"
#include <utility> #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include <cstdint>
namespace clang { namespace clang {
class ASTContext;
class ASTRecordLayout;
class CXXRecordDecl;
class VTTVTable { class VTTVTable {
llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual; llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
CharUnits BaseOffset; CharUnits BaseOffset;
public: public:
VTTVTable() {} VTTVTable() = default;
VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual) VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
: BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {} : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
VTTVTable(BaseSubobject Base, bool BaseIsVirtual) VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
: BaseAndIsVirtual(Base.getBase(), BaseIsVirtual), : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
BaseOffset(Base.getBaseOffset()) {} BaseOffset(Base.getBaseOffset()) {}
const CXXRecordDecl *getBase() const { const CXXRecordDecl *getBase() const {
return BaseAndIsVirtual.getPointer(); return BaseAndIsVirtual.getPointer();
@ -57,25 +63,24 @@ struct VTTComponent {
uint64_t VTableIndex; uint64_t VTableIndex;
BaseSubobject VTableBase; BaseSubobject VTableBase;
VTTComponent() {} VTTComponent() = default;
VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase) VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
: VTableIndex(VTableIndex), VTableBase(VTableBase) {} : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
}; };
/// \brief Class for building VTT layout information. /// \brief Class for building VTT layout information.
class VTTBuilder { class VTTBuilder {
ASTContext &Ctx; ASTContext &Ctx;
/// \brief The most derived class for which we're building this vtable. /// \brief The most derived class for which we're building this vtable.
const CXXRecordDecl *MostDerivedClass; const CXXRecordDecl *MostDerivedClass;
typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy; using VTTVTablesVectorTy = SmallVector<VTTVTable, 64>;
/// \brief The VTT vtables. /// \brief The VTT vtables.
VTTVTablesVectorTy VTTVTables; VTTVTablesVectorTy VTTVTables;
typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy; using VTTComponentsVectorTy = SmallVector<VTTComponent, 64>;
/// \brief The VTT components. /// \brief The VTT components.
VTTComponentsVectorTy VTTComponents; VTTComponentsVectorTy VTTComponents;
@ -83,9 +88,9 @@ class VTTBuilder {
/// \brief The AST record layout of the most derived class. /// \brief The AST record layout of the most derived class.
const ASTRecordLayout &MostDerivedClassLayout; 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. /// \brief The sub-VTT indices for the bases of the most derived class.
llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies; llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
@ -153,9 +158,8 @@ public:
getSecondaryVirtualPointerIndices() const { getSecondaryVirtualPointerIndices() const {
return SecondaryVirtualPointerIndices; 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 // The LLVM Compiler Infrastructure
// //
@ -38,23 +38,42 @@
#include "clang/AST/ASTTypeTraits.h" #include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h" #include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h" #include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Stmt.h" #include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h" #include "clang/AST/TemplateName.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/Type.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/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.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 "llvm/Support/ManagedStatic.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <map> #include <map>
#include <string> #include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector> #include <vector>
namespace clang { namespace clang {
class ASTContext;
namespace ast_matchers { namespace ast_matchers {
class BoundNodes; class BoundNodes;
@ -158,7 +177,7 @@ public:
/// Note that we're using std::map here, as for memoization: /// Note that we're using std::map here, as for memoization:
/// - we need a comparison operator /// - we need a comparison operator
/// - we need an assignment 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 { const IDToNodeMap &getMap() const {
return NodeMap; return NodeMap;
@ -188,7 +207,7 @@ public:
/// BoundNodesTree. /// BoundNodesTree.
class Visitor { class Visitor {
public: public:
virtual ~Visitor() {} virtual ~Visitor() = default;
/// \brief Called multiple times during a single call to VisitMatches(...). /// \brief Called multiple times during a single call to VisitMatches(...).
/// ///
@ -248,7 +267,7 @@ class ASTMatchFinder;
class DynMatcherInterface class DynMatcherInterface
: public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> { : public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
public: public:
virtual ~DynMatcherInterface() {} virtual ~DynMatcherInterface() = default;
/// \brief Returns true if \p DynNode can be matched. /// \brief Returns true if \p DynNode can be matched.
/// ///
@ -317,26 +336,29 @@ public:
/// \brief Takes ownership of the provided implementation pointer. /// \brief Takes ownership of the provided implementation pointer.
template <typename T> template <typename T>
DynTypedMatcher(MatcherInterface<T> *Implementation) DynTypedMatcher(MatcherInterface<T> *Implementation)
: AllowBind(false), : SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
RestrictKind(SupportedKind), Implementation(Implementation) {} RestrictKind(SupportedKind), Implementation(Implementation) {}
/// \brief Construct from a variadic function. /// \brief Construct from a variadic function.
enum VariadicOperator { enum VariadicOperator {
/// \brief Matches nodes for which all provided matchers match. /// \brief Matches nodes for which all provided matchers match.
VO_AllOf, VO_AllOf,
/// \brief Matches nodes for which at least one of the provided matchers /// \brief Matches nodes for which at least one of the provided matchers
/// matches. /// matches.
VO_AnyOf, VO_AnyOf,
/// \brief Matches nodes for which at least one of the provided matchers /// \brief Matches nodes for which at least one of the provided matchers
/// matches, but doesn't stop at the first match. /// matches, but doesn't stop at the first match.
VO_EachOf, VO_EachOf,
/// \brief Matches nodes that do not match the provided matcher. /// \brief Matches nodes that do not match the provided matcher.
/// ///
/// Uses the variadic matcher interface, but fails if /// Uses the variadic matcher interface, but fails if
/// InnerMatchers.size() != 1. /// InnerMatchers.size() != 1.
VO_UnaryNot VO_UnaryNot
}; };
static DynTypedMatcher static DynTypedMatcher
constructVariadic(VariadicOperator Op, constructVariadic(VariadicOperator Op,
ast_type_traits::ASTNodeKind SupportedKind, ast_type_traits::ASTNodeKind SupportedKind,
@ -382,7 +404,7 @@ public:
/// include both in the ID to make it unique. /// include both in the ID to make it unique.
/// ///
/// \c MatcherIDType supports operator< and provides strict weak ordering. /// \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 { MatcherIDType getID() const {
/// FIXME: Document the requirements this imposes on matcher /// FIXME: Document the requirements this imposes on matcher
/// implementations (no new() implementation_ during a Matches()). /// implementations (no new() implementation_ during a Matches()).
@ -428,13 +450,12 @@ private:
DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind, DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
ast_type_traits::ASTNodeKind RestrictKind, ast_type_traits::ASTNodeKind RestrictKind,
IntrusiveRefCntPtr<DynMatcherInterface> Implementation) IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
: AllowBind(false), : SupportedKind(SupportedKind), RestrictKind(RestrictKind),
SupportedKind(SupportedKind),
RestrictKind(RestrictKind),
Implementation(std::move(Implementation)) {} Implementation(std::move(Implementation)) {}
bool AllowBind; bool AllowBind = false;
ast_type_traits::ASTNodeKind SupportedKind; ast_type_traits::ASTNodeKind SupportedKind;
/// \brief A potentially stricter node kind. /// \brief A potentially stricter node kind.
/// ///
/// It allows to perform implicit and dynamic cast of matchers without /// It allows to perform implicit and dynamic cast of matchers without
@ -545,6 +566,7 @@ public:
private: private:
// For Matcher<T> <=> Matcher<U> conversions. // For Matcher<T> <=> Matcher<U> conversions.
template <typename U> friend class Matcher; template <typename U> friend class Matcher;
// For DynTypedMatcher::unconditionalConvertTo<T>. // For DynTypedMatcher::unconditionalConvertTo<T>.
friend class DynTypedMatcher; 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. // Metafunction to determine if type T has a member called getDecl.
template <typename Ty> template <typename Ty>
class has_getDecl { class has_getDecl {
typedef char yes[1]; using yes = char[1];
typedef char no[2]; using no = char[2];
template <typename Inner> template <typename Inner>
static yes& test(Inner *I, decltype(I->getDecl()) * = nullptr); static yes& test(Inner *I, decltype(I->getDecl()) * = nullptr);
@ -728,48 +750,94 @@ public:
} }
private: private:
/// \brief If getDecl exists as a member of U, returns whether the inner /// \brief Forwards to matching on the underlying type of the QualType.
/// 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.
bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder, bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const { BoundNodesTreeBuilder *Builder) const {
if (Node.isNull()) if (Node.isNull())
return false; return false;
if (auto *TD = Node->getAsTagDecl()) return matchesSpecialized(*Node, Finder, Builder);
return matchesDecl(TD, Finder, Builder); }
else if (auto *TT = Node->getAs<TypedefType>())
return matchesDecl(TT->getDecl(), Finder, Builder); /// \brief Finds the best declaration for a type and returns whether the inner
// Do not use getAs<TemplateTypeParmType> instead of the direct dyn_cast. /// matcher matches on it.
// Calling getAs will return the canonical type, but that type does not bool matchesSpecialized(const Type &Node, ASTMatchFinder *Finder,
// store a TemplateTypeParmDecl. We *need* the uncanonical type, if it is BoundNodesTreeBuilder *Builder) const {
// available, and using dyn_cast ensures that. // DeducedType does not have declarations of its own, so
else if (auto *TTP = dyn_cast<TemplateTypeParmType>(Node.getTypePtr())) // match the deduced type instead.
return matchesDecl(TTP->getDecl(), Finder, Builder); const Type *EffectiveType = &Node;
else if (auto *OCIT = Node->getAs<ObjCInterfaceType>()) if (const auto *S = dyn_cast<DeducedType>(&Node)) {
return matchesDecl(OCIT->getDecl(), Finder, Builder); EffectiveType = S->getDeducedType().getTypePtrOrNull();
else if (auto *UUT = Node->getAs<UnresolvedUsingType>()) if (!EffectiveType)
return matchesDecl(UUT->getDecl(), Finder, Builder); return false;
else if (auto *ICNT = Node->getAs<InjectedClassNameType>()) }
return matchesDecl(ICNT->getDecl(), Finder, Builder);
// 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; return false;
} }
/// \brief Gets the TemplateDecl from a TemplateSpecializationType /// \brief Extracts the Decl the DeclRefExpr references and returns whether
/// and returns whether the inner matches on it. /// the inner matcher matches on it.
bool matchesSpecialized(const TemplateSpecializationType &Node, bool matchesSpecialized(const DeclRefExpr &Node, ASTMatchFinder *Finder,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const { BoundNodesTreeBuilder *Builder) const {
return matchesDecl(Node.getTemplateName().getAsTemplateDecl(), return matchesDecl(Node.getDecl(), Finder, Builder);
Finder, Builder);
} }
/// \brief Extracts the Decl of the callee of a CallExpr and returns whether /// \brief Extracts the Decl of the callee of a CallExpr and returns whether
@ -811,6 +879,13 @@ private:
return matchesDecl(Node.getLabel(), Finder, Builder); 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 /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node
/// is \c NULL. /// is \c NULL.
bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder, bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
@ -863,6 +938,7 @@ public:
enum TraversalKind { enum TraversalKind {
/// Will traverse any child nodes. /// Will traverse any child nodes.
TK_AsIs, TK_AsIs,
/// Will not traverse implicit casts and parentheses. /// Will not traverse implicit casts and parentheses.
TK_IgnoreImplicitCastsAndParentheses TK_IgnoreImplicitCastsAndParentheses
}; };
@ -871,6 +947,7 @@ public:
enum BindKind { enum BindKind {
/// Stop at the first match and only bind the first match. /// Stop at the first match and only bind the first match.
BK_First, BK_First,
/// Create results for all combinations of bindings that match. /// Create results for all combinations of bindings that match.
BK_All BK_All
}; };
@ -879,11 +956,12 @@ public:
enum AncestorMatchMode { enum AncestorMatchMode {
/// All ancestors. /// All ancestors.
AMM_All, AMM_All,
/// Direct parent only. /// Direct parent only.
AMM_ParentOnly AMM_ParentOnly
}; };
virtual ~ASTMatchFinder() {} virtual ~ASTMatchFinder() = default;
/// \brief Returns true if the given class is directly or indirectly derived /// \brief Returns true if the given class is directly or indirectly derived
/// from a base type matching \c base. /// from a base type matching \c base.
@ -906,7 +984,7 @@ public:
std::is_base_of<TypeLoc, T>::value || std::is_base_of<TypeLoc, T>::value ||
std::is_base_of<QualType, T>::value, std::is_base_of<QualType, T>::value,
"unsupported type for recursive matching"); "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); 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...> { template <typename T1, typename... Ts> struct TypeList<T1, Ts...> {
/// \brief The first type on the list. /// \brief The first type on the list.
typedef T1 head; using head = T1;
/// \brief A sublist with the tail. ie everything but the head. /// \brief A sublist with the tail. ie everything but the head.
/// ///
/// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
/// end of the list. /// end of the list.
typedef TypeList<Ts...> tail; using tail = TypeList<Ts...>;
}; };
/// \brief The empty type list. /// \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 /// \brief Helper meta-function to determine if some type \c T is present or
/// a parent type in the list. /// a parent type in the list.
@ -997,8 +1075,9 @@ struct TypeListContainsSuperOf<EmptyTypeList, T> {
/// \brief A "type list" that contains all types. /// \brief A "type list" that contains all types.
/// ///
/// Useful for matchers like \c anything and \c unless. /// Useful for matchers like \c anything and \c unless.
typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, using AllNodeBaseTypes =
QualType, Type, TypeLoc, CXXCtorInitializer> AllNodeBaseTypes; TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
Type, TypeLoc, CXXCtorInitializer>;
/// \brief Helper meta-function to extract the argument out of a function of /// \brief Helper meta-function to extract the argument out of a function of
/// type void(Arg). /// type void(Arg).
@ -1006,20 +1085,22 @@ typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc,
/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details. /// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
template <class T> struct ExtractFunctionArgMeta; template <class T> struct ExtractFunctionArgMeta;
template <class T> struct ExtractFunctionArgMeta<void(T)> { template <class T> struct ExtractFunctionArgMeta<void(T)> {
typedef T type; using type = T;
}; };
/// \brief Default type lists for ArgumentAdaptingMatcher matchers. /// \brief Default type lists for ArgumentAdaptingMatcher matchers.
typedef AllNodeBaseTypes AdaptativeDefaultFromTypes; using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, using AdaptativeDefaultToTypes =
TypeLoc, QualType> AdaptativeDefaultToTypes; TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
QualType>;
/// \brief All types that are supported by HasDeclarationMatcher above. /// \brief All types that are supported by HasDeclarationMatcher above.
typedef TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType, using HasDeclarationSupportedTypes =
InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr, TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
QualType, RecordType, TagType, TemplateSpecializationType, ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
TemplateTypeParmType, TypedefType, UnresolvedUsingType> MemberExpr, QualType, RecordType, TagType,
HasDeclarationSupportedTypes; TemplateSpecializationType, TemplateTypeParmType, TypedefType,
UnresolvedUsingType>;
/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by /// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by
/// "adapting" a \c To into a \c T. /// "adapting" a \c To into a \c T.
@ -1043,7 +1124,7 @@ struct ArgumentAdaptingMatcherFunc {
explicit Adaptor(const Matcher<T> &InnerMatcher) explicit Adaptor(const Matcher<T> &InnerMatcher)
: InnerMatcher(InnerMatcher) {} : InnerMatcher(InnerMatcher) {}
typedef ToTypes ReturnTypes; using ReturnTypes = ToTypes;
template <typename To> operator Matcher<To>() const { template <typename To> operator Matcher<To>() const {
return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher)); return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
@ -1080,7 +1161,8 @@ template <template <typename T> class MatcherT,
typename ReturnTypesF = void(AllNodeBaseTypes)> typename ReturnTypesF = void(AllNodeBaseTypes)>
class PolymorphicMatcherWithParam0 { class PolymorphicMatcherWithParam0 {
public: public:
typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value, static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
@ -1097,7 +1179,7 @@ public:
explicit PolymorphicMatcherWithParam1(const P1 &Param1) explicit PolymorphicMatcherWithParam1(const P1 &Param1)
: Param1(Param1) {} : Param1(Param1) {}
typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
@ -1118,7 +1200,7 @@ public:
PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2) PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2)
: Param1(Param1), Param2(Param2) {} : Param1(Param1), Param2(Param2) {}
typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
@ -1137,8 +1219,8 @@ private:
/// This is useful when a matcher syntactically requires a child matcher, /// This is useful when a matcher syntactically requires a child matcher,
/// but the context doesn't care. See for example: anything(). /// but the context doesn't care. See for example: anything().
class TrueMatcher { class TrueMatcher {
public: public:
typedef AllNodeBaseTypes ReturnTypes; using ReturnTypes = AllNodeBaseTypes;
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
@ -1184,7 +1266,6 @@ public:
/// ChildT must be an AST base type. /// ChildT must be an AST base type.
template <typename T, typename ChildT> template <typename T, typename ChildT>
class HasMatcher : public WrapperMatcherInterface<T> { class HasMatcher : public WrapperMatcherInterface<T> {
public: public:
explicit HasMatcher(const Matcher<ChildT> &ChildMatcher) explicit HasMatcher(const Matcher<ChildT> &ChildMatcher)
: HasMatcher::WrapperMatcherInterface(ChildMatcher) {} : HasMatcher::WrapperMatcherInterface(ChildMatcher) {}
@ -1278,7 +1359,7 @@ template<typename T>
BindableMatcher<T> makeAllOfComposite( BindableMatcher<T> makeAllOfComposite(
ArrayRef<const Matcher<T> *> InnerMatchers) { ArrayRef<const Matcher<T> *> InnerMatchers) {
// For the size() == 0 case, we return a "true" matcher. // For the size() == 0 case, we return a "true" matcher.
if (InnerMatchers.size() == 0) { if (InnerMatchers.empty()) {
return BindableMatcher<T>(TrueMatcher()); return BindableMatcher<T>(TrueMatcher());
} }
// For the size() == 1 case, we simply return that one matcher. // For the size() == 1 case, we simply return that one matcher.
@ -1287,7 +1368,8 @@ BindableMatcher<T> makeAllOfComposite(
return BindableMatcher<T>(*InnerMatchers[0]); 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()), std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
PI(InnerMatchers.end())); PI(InnerMatchers.end()));
return BindableMatcher<T>( return BindableMatcher<T>(
@ -1580,12 +1662,13 @@ template <typename InnerTBase,
typename ReturnTypesF> typename ReturnTypesF>
class TypeTraversePolymorphicMatcher { class TypeTraversePolymorphicMatcher {
private: private:
typedef TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
ReturnTypesF> Self; ReturnTypesF>;
static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers); static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers);
public: public:
typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
explicit TypeTraversePolymorphicMatcher( explicit TypeTraversePolymorphicMatcher(
ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) ArrayRef<const Matcher<InnerTBase> *> InnerMatchers)
@ -1612,6 +1695,7 @@ private:
template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher { template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher {
struct Wrapper { struct Wrapper {
Wrapper() : M(Func()) {} Wrapper() : M(Func()) {}
Matcher M; Matcher M;
}; };
@ -1657,6 +1741,7 @@ struct NotEqualsBoundNodePredicate {
bool operator()(const internal::BoundNodesMap &Nodes) const { bool operator()(const internal::BoundNodesMap &Nodes) const {
return Nodes.getNode(ID) != Node; return Nodes.getNode(ID) != Node;
} }
std::string ID; std::string ID;
ast_type_traits::DynTypedNode Node; ast_type_traits::DynTypedNode Node;
}; };
@ -1712,9 +1797,10 @@ CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) {
return Node.getSubStmt(); return Node.getSubStmt();
} }
} // namespace internal
} // end namespace internal } // namespace ast_matchers
} // end namespace ast_matchers
} // end namespace clang } // namespace clang
#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H

View File

@ -367,6 +367,27 @@
// FIXME: add a matcher for TypeLoc derived classes using its custom casting // FIXME: add a matcher for TypeLoc derived classes using its custom casting
// API (no longer dyn_cast) if/when we need such matching // 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 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
/// the matcher \c MatcherName that can be used to traverse from one \c Type /// the matcher \c MatcherName that can be used to traverse from one \c Type
/// to another. /// to another.
@ -386,6 +407,30 @@
::clang::ast_matchers::internal::TypeTraverseMatcher, \ ::clang::ast_matchers::internal::TypeTraverseMatcher, \
ReturnTypesF>::Func MatcherName 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 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ #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 // The LLVM Compiler Infrastructure
// //
@ -6,7 +6,7 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// //
/// \file /// \file
/// \brief Simple matcher expression parser. /// \brief Simple matcher expression parser.
/// ///
@ -30,24 +30,28 @@
/// <Identifier> := [a-zA-Z]+ /// <Identifier> := [a-zA-Z]+
/// <ArgumentList> := <Expression> | <Expression>,<ArgumentList> /// <ArgumentList> := <Expression> | <Expression>,<ArgumentList>
/// \endcode /// \endcode
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H #ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
#define 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/Registry.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h" #include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include <utility>
#include <vector>
namespace clang { namespace clang {
namespace ast_matchers { namespace ast_matchers {
namespace dynamic { namespace dynamic {
class Diagnostics;
/// \brief Matcher expression parser. /// \brief Matcher expression parser.
class Parser { class Parser {
public: public:
@ -124,8 +128,8 @@ public:
/// \brief Sema implementation that uses the matcher registry to process the /// \brief Sema implementation that uses the matcher registry to process the
/// tokens. /// tokens.
class RegistrySema : public Parser::Sema { class RegistrySema : public Parser::Sema {
public: public:
~RegistrySema() override; ~RegistrySema() override;
llvm::Optional<MatcherCtor> llvm::Optional<MatcherCtor>
lookupMatcherCtor(StringRef MatcherName) override; lookupMatcherCtor(StringRef MatcherName) override;
@ -143,7 +147,7 @@ public:
getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) override; getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) override;
}; };
typedef llvm::StringMap<VariantValue> NamedValueMap; using NamedValueMap = llvm::StringMap<VariantValue>;
/// \brief Parse a matcher expression. /// \brief Parse a matcher expression.
/// ///
@ -247,13 +251,14 @@ private:
const NamedValueMap *const NamedValues; const NamedValueMap *const NamedValues;
Diagnostics *const Error; Diagnostics *const Error;
typedef std::vector<std::pair<MatcherCtor, unsigned> > ContextStackTy; using ContextStackTy = std::vector<std::pair<MatcherCtor, unsigned>>;
ContextStackTy ContextStack; ContextStackTy ContextStack;
std::vector<MatcherCompletion> Completions; std::vector<MatcherCompletion> Completions;
}; };
} // namespace dynamic } // namespace dynamic
} // namespace ast_matchers } // namespace ast_matchers
} // namespace clang } // 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 // The LLVM Compiler Infrastructure
// //
@ -6,12 +6,12 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// //
/// \file /// \file
/// \brief Registry of all known matchers. /// \brief Registry of all known matchers.
/// ///
/// The registry provides a generic interface to construct any matcher by name. /// The registry provides a generic interface to construct any matcher by name.
/// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H #ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
@ -34,9 +34,9 @@ namespace internal {
class MatcherDescriptor; class MatcherDescriptor;
} // end namespace internal } // namespace internal
typedef const internal::MatcherDescriptor *MatcherCtor; using MatcherCtor = const internal::MatcherDescriptor *;
struct MatcherCompletion { struct MatcherCompletion {
MatcherCompletion() = default; MatcherCompletion() = default;
@ -129,8 +129,8 @@ public:
Diagnostics *Error); Diagnostics *Error);
}; };
} // end namespace dynamic } // namespace dynamic
} // end namespace ast_matchers } // namespace ast_matchers
} // end namespace clang } // namespace clang
#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H #endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H

View File

@ -19,7 +19,7 @@
#include "clang/AST/ExprCXX.h" #include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtCXX.h" #include "clang/AST/StmtCXX.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h" #include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/AnalysisContext.h" #include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceLocation.h"
namespace clang { namespace clang {

View File

@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
#define 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 "clang/Analysis/CFG.h"
#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/GenericDomTree.h" #include "llvm/Support/GenericDomTree.h"

View File

@ -15,7 +15,7 @@
#define LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H #define LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/Analysis/AnalysisContext.h" #include "clang/Analysis/AnalysisDeclContext.h"
#include "llvm/ADT/ImmutableSet.h" #include "llvm/ADT/ImmutableSet.h"
namespace clang { namespace clang {

View File

@ -21,7 +21,7 @@
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/BitVector.h" #include "llvm/ADT/BitVector.h"
#include "clang/Analysis/AnalysisContext.h" #include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h" #include "clang/Analysis/CFG.h"
namespace clang { namespace clang {

View File

@ -19,7 +19,7 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
#define 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 "clang/Basic/SourceLocation.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"

View File

@ -25,7 +25,7 @@
#include "clang/Analysis/Analyses/PostOrderCFGView.h" #include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/Analyses/ThreadSafetyTIL.h" #include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h" #include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
#include "clang/Analysis/AnalysisContext.h" #include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/OperatorKinds.h" #include "clang/Basic/OperatorKinds.h"
#include <memory> #include <memory>
#include <ostream> #include <ostream>

View File

@ -92,6 +92,7 @@ enum TIL_BinaryOpcode : unsigned char {
BOP_Neq, // != BOP_Neq, // !=
BOP_Lt, // < BOP_Lt, // <
BOP_Leq, // <= BOP_Leq, // <=
BOP_Cmp, // <=>
BOP_LogicAnd, // && (no short-circuit) BOP_LogicAnd, // && (no short-circuit)
BOP_LogicOr // || (no short-circuit) BOP_LogicOr // || (no short-circuit)
}; };
@ -909,15 +910,10 @@ class Project : public SExpr {
public: public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Project; } 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) Project(SExpr *R, const clang::ValueDecl *Cvd)
: SExpr(COP_Project), Rec(R), SlotName(Cvd->getName()), Cvdecl(Cvd) : SExpr(COP_Project), Rec(R), Cvdecl(Cvd) {
{ } assert(Cvd && "ValueDecl must not be null");
Project(const Project &P, SExpr *R) }
: SExpr(P), Rec(R), SlotName(P.SlotName), Cvdecl(P.Cvdecl)
{ }
SExpr *record() { return Rec; } SExpr *record() { return Rec; }
const SExpr *record() const { return Rec; } const SExpr *record() const { return Rec; }
@ -931,10 +927,14 @@ public:
} }
StringRef slotName() const { StringRef slotName() const {
if (Cvdecl) if (Cvdecl->getDeclName().isIdentifier())
return Cvdecl->getName(); return Cvdecl->getName();
else if (!SlotName) {
return SlotName; SlotName = "";
llvm::raw_string_ostream OS(*SlotName);
Cvdecl->printName(OS);
}
return *SlotName;
} }
template <class V> template <class V>
@ -953,7 +953,7 @@ public:
private: private:
SExpr* Rec; SExpr* Rec;
StringRef SlotName; mutable llvm::Optional<std::string> SlotName;
const clang::ValueDecl *Cvdecl; 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 // The LLVM Compiler Infrastructure
// //
@ -12,10 +12,11 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H #ifndef LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H #define LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/Analysis/BodyFarm.h"
#include "clang/Analysis/CFG.h" #include "clang/Analysis/CFG.h"
#include "clang/Analysis/CodeInjector.h" #include "clang/Analysis/CodeInjector.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
@ -416,23 +417,25 @@ class AnalysisDeclContextManager {
/// Pointer to an interface that can provide function bodies for /// Pointer to an interface that can provide function bodies for
/// declarations from external source. /// declarations from external source.
std::unique_ptr<CodeInjector> Injector; 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 /// Flag to indicate whether or not bodies should be synthesized
/// for well-known functions. /// for well-known functions.
bool SynthesizeBodies; bool SynthesizeBodies;
public: public:
AnalysisDeclContextManager(bool useUnoptimizedCFG = false, AnalysisDeclContextManager(ASTContext &ASTCtx, bool useUnoptimizedCFG = false,
bool addImplicitDtors = false, bool addImplicitDtors = false,
bool addInitializers = false, bool addInitializers = false,
bool addTemporaryDtors = false, bool addTemporaryDtors = false,
bool addLifetime = false, bool addLifetime = false, bool addLoopExit = false,
bool synthesizeBodies = false, bool synthesizeBodies = false,
bool addStaticInitBranches = false, bool addStaticInitBranches = false,
bool addCXXNewAllocator = true, bool addCXXNewAllocator = true,
CodeInjector* injector = nullptr); CodeInjector *injector = nullptr);
~AnalysisDeclContextManager();
AnalysisDeclContext *getContext(const Decl *D); AnalysisDeclContext *getContext(const Decl *D);
@ -471,6 +474,9 @@ public:
return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx); return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
} }
/// Get a reference to {@code BodyFarm} instance.
BodyFarm &getBodyFarm();
/// Discard all previously created AnalysisDeclContexts. /// Discard all previously created AnalysisDeclContexts.
void clear(); void clear();

View File

@ -28,24 +28,27 @@ class ObjCMethodDecl;
class ObjCPropertyDecl; class ObjCPropertyDecl;
class Stmt; class Stmt;
class CodeInjector; class CodeInjector;
class BodyFarm { class BodyFarm {
public: public:
BodyFarm(ASTContext &C, CodeInjector *injector) : C(C), Injector(injector) {} BodyFarm(ASTContext &C, CodeInjector *injector) : C(C), Injector(injector) {}
/// Factory method for creating bodies for ordinary functions. /// Factory method for creating bodies for ordinary functions.
Stmt *getBody(const FunctionDecl *D); Stmt *getBody(const FunctionDecl *D);
/// Factory method for creating bodies for Objective-C properties. /// Factory method for creating bodies for Objective-C properties.
Stmt *getBody(const ObjCMethodDecl *D); Stmt *getBody(const ObjCMethodDecl *D);
/// Remove copy constructor to avoid accidental copying.
BodyFarm(const BodyFarm &other) = delete;
private: private:
typedef llvm::DenseMap<const Decl *, Optional<Stmt *> > BodyMap; typedef llvm::DenseMap<const Decl *, Optional<Stmt *>> BodyMap;
ASTContext &C; ASTContext &C;
BodyMap Bodies; BodyMap Bodies;
CodeInjector *Injector; CodeInjector *Injector;
}; };
} } // namespace clang
#endif #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 // The LLVM Compiler Infrastructure
// //
@ -17,38 +17,38 @@
#include "clang/AST/Stmt.h" #include "clang/AST/Stmt.h"
#include "clang/Analysis/Support/BumpVector.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/DenseMap.h"
#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include <bitset> #include <bitset>
#include <cassert> #include <cassert>
#include <cstddef>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <vector>
namespace clang { namespace clang {
class CXXDestructorDecl;
class Decl; class ASTContext;
class Stmt; class BinaryOperator;
class Expr; class CFG;
class FieldDecl; class CXXBaseSpecifier;
class VarDecl; class CXXBindTemporaryExpr;
class CXXCtorInitializer; class CXXCtorInitializer;
class CXXBaseSpecifier; class CXXDeleteExpr;
class CXXBindTemporaryExpr; class CXXDestructorDecl;
class CFG; class CXXNewExpr;
class PrinterHelper; class CXXRecordDecl;
class LangOptions; class Decl;
class ASTContext; class FieldDecl;
class CXXRecordDecl; class LangOptions;
class CXXDeleteExpr; class VarDecl;
class CXXNewExpr;
class BinaryOperator;
/// CFGElement - Represents a top-level expression in a basic block. /// CFGElement - Represents a top-level expression in a basic block.
class CFGElement { class CFGElement {
@ -59,6 +59,7 @@ public:
Initializer, Initializer,
NewAllocator, NewAllocator,
LifetimeEnds, LifetimeEnds,
LoopExit,
// dtor kind // dtor kind
AutomaticObjectDtor, AutomaticObjectDtor,
DeleteDtor, DeleteDtor,
@ -75,14 +76,14 @@ protected:
llvm::PointerIntPair<void *, 2> Data2; llvm::PointerIntPair<void *, 2> Data2;
CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr) CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
: Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3), : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) { Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
assert(getKind() == kind); assert(getKind() == kind);
} }
CFGElement() {} CFGElement() = default;
public:
public:
/// \brief Convert to the specified CFGElement type, asserting that this /// \brief Convert to the specified CFGElement type, asserting that this
/// CFGElement is of the desired type. /// CFGElement is of the desired type.
template<typename T> template<typename T>
@ -124,7 +125,9 @@ public:
private: private:
friend class CFGElement; friend class CFGElement;
CFGStmt() {}
CFGStmt() = default;
static bool isKind(const CFGElement &E) { static bool isKind(const CFGElement &E) {
return E.getKind() == Statement; return E.getKind() == Statement;
} }
@ -143,7 +146,9 @@ public:
private: private:
friend class CFGElement; friend class CFGElement;
CFGInitializer() {}
CFGInitializer() = default;
static bool isKind(const CFGElement &E) { static bool isKind(const CFGElement &E) {
return E.getKind() == Initializer; return E.getKind() == Initializer;
} }
@ -162,12 +167,38 @@ public:
private: private:
friend class CFGElement; friend class CFGElement;
CFGNewAllocator() {}
CFGNewAllocator() = default;
static bool isKind(const CFGElement &elem) { static bool isKind(const CFGElement &elem) {
return elem.getKind() == NewAllocator; 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 /// Represents the point where the lifetime of an automatic object ends
class CFGLifetimeEnds : public CFGElement { class CFGLifetimeEnds : public CFGElement {
public: public:
@ -184,7 +215,9 @@ public:
private: private:
friend class CFGElement; friend class CFGElement;
CFGLifetimeEnds() {}
CFGLifetimeEnds() = default;
static bool isKind(const CFGElement &elem) { static bool isKind(const CFGElement &elem) {
return elem.getKind() == LifetimeEnds; return elem.getKind() == LifetimeEnds;
} }
@ -194,7 +227,8 @@ private:
/// by compiler on various occasions. /// by compiler on various occasions.
class CFGImplicitDtor : public CFGElement { class CFGImplicitDtor : public CFGElement {
protected: protected:
CFGImplicitDtor() {} CFGImplicitDtor() = default;
CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr) CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr)
: CFGElement(kind, data1, data2) { : CFGElement(kind, data1, data2) {
assert(kind >= DTOR_BEGIN && kind <= DTOR_END); assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
@ -206,6 +240,7 @@ public:
private: private:
friend class CFGElement; friend class CFGElement;
static bool isKind(const CFGElement &E) { static bool isKind(const CFGElement &E) {
Kind kind = E.getKind(); Kind kind = E.getKind();
return kind >= DTOR_BEGIN && kind <= DTOR_END; return kind >= DTOR_BEGIN && kind <= DTOR_END;
@ -231,7 +266,9 @@ public:
private: private:
friend class CFGElement; friend class CFGElement;
CFGAutomaticObjDtor() {}
CFGAutomaticObjDtor() = default;
static bool isKind(const CFGElement &elem) { static bool isKind(const CFGElement &elem) {
return elem.getKind() == AutomaticObjectDtor; return elem.getKind() == AutomaticObjectDtor;
} }
@ -255,7 +292,9 @@ public:
private: private:
friend class CFGElement; friend class CFGElement;
CFGDeleteDtor() {}
CFGDeleteDtor() = default;
static bool isKind(const CFGElement &elem) { static bool isKind(const CFGElement &elem) {
return elem.getKind() == DeleteDtor; return elem.getKind() == DeleteDtor;
} }
@ -274,7 +313,9 @@ public:
private: private:
friend class CFGElement; friend class CFGElement;
CFGBaseDtor() {}
CFGBaseDtor() = default;
static bool isKind(const CFGElement &E) { static bool isKind(const CFGElement &E) {
return E.getKind() == BaseDtor; return E.getKind() == BaseDtor;
} }
@ -293,7 +334,9 @@ public:
private: private:
friend class CFGElement; friend class CFGElement;
CFGMemberDtor() {}
CFGMemberDtor() = default;
static bool isKind(const CFGElement &E) { static bool isKind(const CFGElement &E) {
return E.getKind() == MemberDtor; return E.getKind() == MemberDtor;
} }
@ -312,7 +355,9 @@ public:
private: private:
friend class CFGElement; friend class CFGElement;
CFGTemporaryDtor() {}
CFGTemporaryDtor() = default;
static bool isKind(const CFGElement &E) { static bool isKind(const CFGElement &E) {
return E.getKind() == TemporaryDtor; return E.getKind() == TemporaryDtor;
} }
@ -326,8 +371,9 @@ private:
/// of matching full expression. /// of matching full expression.
class CFGTerminator { class CFGTerminator {
llvm::PointerIntPair<Stmt *, 1> Data; llvm::PointerIntPair<Stmt *, 1> Data;
public: public:
CFGTerminator() {} CFGTerminator() = default;
CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false) CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false)
: Data(S, TemporaryDtorsBranch) {} : Data(S, TemporaryDtorsBranch) {}
@ -373,21 +419,23 @@ public:
/// &&, || expression that uses result of && or ||, RHS /// &&, || expression that uses result of && or ||, RHS
/// ///
/// But note that any of that may be NULL in case of optimized-out edges. /// But note that any of that may be NULL in case of optimized-out edges.
///
class CFGBlock { class CFGBlock {
class ElementList { class ElementList {
typedef BumpVector<CFGElement> ImplTy; using ImplTy = BumpVector<CFGElement>;
ImplTy Impl; ImplTy Impl;
public: public:
ElementList(BumpVectorContext &C) : Impl(C, 4) {} ElementList(BumpVectorContext &C) : Impl(C, 4) {}
typedef std::reverse_iterator<ImplTy::iterator> iterator; using iterator = std::reverse_iterator<ImplTy::iterator>;
typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator; using const_iterator = std::reverse_iterator<ImplTy::const_iterator>;
typedef ImplTy::iterator reverse_iterator; using reverse_iterator = ImplTy::iterator;
typedef ImplTy::const_iterator const_reverse_iterator; using const_reverse_iterator = ImplTy::const_iterator;
typedef ImplTy::const_reference const_reference; using const_reference = ImplTy::const_reference;
void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); } void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E, reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E,
BumpVectorContext &C) { BumpVectorContext &C) {
return Impl.insert(I, Cnt, E, 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 rbegin() const { return Impl.begin(); }
const_reverse_iterator rend() const { return Impl.end(); } const_reverse_iterator rend() const { return Impl.end(); }
CFGElement operator[](size_t i) const { CFGElement operator[](size_t i) const {
assert(i < Impl.size()); assert(i < Impl.size());
return Impl[Impl.size() - 1 - i]; return Impl[Impl.size() - 1 - i];
} }
size_t size() const { return Impl.size(); } size_t size() const { return Impl.size(); }
bool empty() const { return Impl.empty(); } bool empty() const { return Impl.empty(); }
@ -420,7 +468,7 @@ class CFGBlock {
/// Label - An (optional) label that prefixes the executable /// Label - An (optional) label that prefixes the executable
/// statements in the block. When this variable is non-NULL, it is /// statements in the block. When this variable is non-NULL, it is
/// either an instance of LabelStmt, SwitchCase or CXXCatchStmt. /// either an instance of LabelStmt, SwitchCase or CXXCatchStmt.
Stmt *Label; Stmt *Label = nullptr;
/// Terminator - The terminator for a basic block that /// Terminator - The terminator for a basic block that
/// indicates the type of control-flow that occurs between a block /// 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 /// 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 /// 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). /// 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 /// BlockID - A numerical ID assigned to a CFGBlock during construction
/// of the CFG. /// of the CFG.
@ -450,7 +498,7 @@ public:
}; };
CFGBlock *ReachableBlock; CFGBlock *ReachableBlock;
llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock; llvm::PointerIntPair<CFGBlock *, 2> UnreachableBlock;
public: public:
/// Construct an AdjacentBlock with a possibly unreachable block. /// Construct an AdjacentBlock with a possibly unreachable block.
@ -493,7 +541,7 @@ public:
private: private:
/// Predecessors/Successors - Keep track of the predecessor / successor /// Predecessors/Successors - Keep track of the predecessor / successor
/// CFG blocks. /// CFG blocks.
typedef BumpVector<AdjacentBlock> AdjacentBlocks; using AdjacentBlocks = BumpVector<AdjacentBlock>;
AdjacentBlocks Preds; AdjacentBlocks Preds;
AdjacentBlocks Succs; AdjacentBlocks Succs;
@ -513,15 +561,14 @@ private:
public: public:
explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent) explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
: Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr), : Elements(C), Terminator(nullptr), BlockID(blockid), Preds(C, 1),
BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false), Succs(C, 1), HasNoReturnElement(false), Parent(parent) {}
Parent(parent) {}
// Statement iterators // Statement iterators
typedef ElementList::iterator iterator; using iterator = ElementList::iterator;
typedef ElementList::const_iterator const_iterator; using const_iterator = ElementList::const_iterator;
typedef ElementList::reverse_iterator reverse_iterator; using reverse_iterator = ElementList::reverse_iterator;
typedef ElementList::const_reverse_iterator const_reverse_iterator; using const_reverse_iterator = ElementList::const_reverse_iterator;
CFGElement front() const { return Elements.front(); } CFGElement front() const { return Elements.front(); }
CFGElement back() const { return Elements.back(); } CFGElement back() const { return Elements.back(); }
@ -542,19 +589,19 @@ public:
CFGElement operator[](size_t i) const { return Elements[i]; } CFGElement operator[](size_t i) const { return Elements[i]; }
// CFG iterators // CFG iterators
typedef AdjacentBlocks::iterator pred_iterator; using pred_iterator = AdjacentBlocks::iterator;
typedef AdjacentBlocks::const_iterator const_pred_iterator; using const_pred_iterator = AdjacentBlocks::const_iterator;
typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator; using pred_reverse_iterator = AdjacentBlocks::reverse_iterator;
typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator; using const_pred_reverse_iterator = AdjacentBlocks::const_reverse_iterator;
typedef llvm::iterator_range<pred_iterator> pred_range; using pred_range = llvm::iterator_range<pred_iterator>;
typedef llvm::iterator_range<const_pred_iterator> pred_const_range; using pred_const_range = llvm::iterator_range<const_pred_iterator>;
typedef AdjacentBlocks::iterator succ_iterator; using succ_iterator = AdjacentBlocks::iterator;
typedef AdjacentBlocks::const_iterator const_succ_iterator; using const_succ_iterator = AdjacentBlocks::const_iterator;
typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator; using succ_reverse_iterator = AdjacentBlocks::reverse_iterator;
typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator; using const_succ_reverse_iterator = AdjacentBlocks::const_reverse_iterator;
typedef llvm::iterator_range<succ_iterator> succ_range; using succ_range = llvm::iterator_range<succ_iterator>;
typedef llvm::iterator_range<const_succ_iterator> succ_const_range; using succ_const_range = llvm::iterator_range<const_succ_iterator>;
pred_iterator pred_begin() { return Preds.begin(); } pred_iterator pred_begin() { return Preds.begin(); }
pred_iterator pred_end() { return Preds.end(); } 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_rbegin() const { return Preds.rbegin(); }
const_pred_reverse_iterator pred_rend() const { return Preds.rend(); } const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
pred_range preds() { pred_range preds() {
return pred_range(pred_begin(), pred_end()); 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()); 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_rbegin() const { return Succs.rbegin(); }
const_succ_reverse_iterator succ_rend() const { return Succs.rend(); } const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
succ_range succs() { succ_range succs() {
return succ_range(succ_begin(), succ_end()); 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()); return succ_const_range(succ_begin(), succ_end());
} }
@ -599,13 +648,11 @@ public:
class FilterOptions { class FilterOptions {
public: public:
FilterOptions() {
IgnoreNullPredecessors = 1;
IgnoreDefaultsWithCoveredEnums = 0;
}
unsigned IgnoreNullPredecessors : 1; unsigned IgnoreNullPredecessors : 1;
unsigned IgnoreDefaultsWithCoveredEnums : 1; unsigned IgnoreDefaultsWithCoveredEnums : 1;
FilterOptions()
: IgnoreNullPredecessors(1), IgnoreDefaultsWithCoveredEnums(0) {}
}; };
static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src, static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src,
@ -617,6 +664,7 @@ public:
IMPL I, E; IMPL I, E;
const FilterOptions F; const FilterOptions F;
const CFGBlock *From; const CFGBlock *From;
public: public:
explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e, explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
const CFGBlock *from, const CFGBlock *from,
@ -634,17 +682,18 @@ public:
} }
const CFGBlock *operator*() const { return *I; } const CFGBlock *operator*() const { return *I; }
private: private:
bool Filter(const CFGBlock *To) { bool Filter(const CFGBlock *To) {
return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To); return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
} }
}; };
typedef FilteredCFGBlockIterator<const_pred_iterator, true> using filtered_pred_iterator =
filtered_pred_iterator; FilteredCFGBlockIterator<const_pred_iterator, true>;
typedef FilteredCFGBlockIterator<const_succ_iterator, false> using filtered_succ_iterator =
filtered_succ_iterator; FilteredCFGBlockIterator<const_succ_iterator, false>;
filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const { filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const {
return filtered_pred_iterator(pred_begin(), pred_end(), this, f); return filtered_pred_iterator(pred_begin(), pred_end(), this, f);
@ -728,6 +777,10 @@ public:
Elements.push_back(CFGLifetimeEnds(VD, S), C); 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) { void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) {
Elements.push_back(CFGDeleteDtor(RD, DE), C); Elements.push_back(CFGDeleteDtor(RD, DE), C);
} }
@ -763,11 +816,12 @@ public:
/// operator error is found when building the CFG. /// operator error is found when building the CFG.
class CFGCallback { class CFGCallback {
public: public:
CFGCallback() {} CFGCallback() = default;
virtual ~CFGCallback() = default;
virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {} virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
virtual void compareBitwiseEquality(const BinaryOperator *B, virtual void compareBitwiseEquality(const BinaryOperator *B,
bool isAlwaysTrue) {} bool isAlwaysTrue) {}
virtual ~CFGCallback() {}
}; };
/// CFG - Represents a source-level, intra-procedural CFG that represents the /// CFG - Represents a source-level, intra-procedural CFG that represents the
@ -785,19 +839,24 @@ public:
class BuildOptions { class BuildOptions {
std::bitset<Stmt::lastStmtConstant> alwaysAddMask; std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
public: public:
typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs; using ForcedBlkExprs = llvm::DenseMap<const Stmt *, const CFGBlock *>;
ForcedBlkExprs **forcedBlkExprs;
CFGCallback *Observer; ForcedBlkExprs **forcedBlkExprs = nullptr;
bool PruneTriviallyFalseEdges; CFGCallback *Observer = nullptr;
bool AddEHEdges; bool PruneTriviallyFalseEdges = true;
bool AddInitializers; bool AddEHEdges = false;
bool AddImplicitDtors; bool AddInitializers = false;
bool AddLifetime; bool AddImplicitDtors = false;
bool AddTemporaryDtors; bool AddLifetime = false;
bool AddStaticInitBranches; bool AddLoopExit = false;
bool AddCXXNewAllocator; bool AddTemporaryDtors = false;
bool AddCXXDefaultInitExprInCtors; bool AddStaticInitBranches = false;
bool AddCXXNewAllocator = false;
bool AddCXXDefaultInitExprInCtors = false;
BuildOptions() = default;
bool alwaysAdd(const Stmt *stmt) const { bool alwaysAdd(const Stmt *stmt) const {
return alwaysAddMask[stmt->getStmtClass()]; return alwaysAddMask[stmt->getStmtClass()];
@ -812,15 +871,6 @@ public:
alwaysAddMask.set(); alwaysAddMask.set();
return *this; 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. /// buildCFG - Builds a CFG from an AST.
@ -844,11 +894,11 @@ public:
// Block Iterators // Block Iterators
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
typedef BumpVector<CFGBlock*> CFGBlockListTy; using CFGBlockListTy = BumpVector<CFGBlock *>;
typedef CFGBlockListTy::iterator iterator; using iterator = CFGBlockListTy::iterator;
typedef CFGBlockListTy::const_iterator const_iterator; using const_iterator = CFGBlockListTy::const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator; using reverse_iterator = std::reverse_iterator<iterator>;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
CFGBlock & front() { return *Blocks.front(); } CFGBlock & front() { return *Blocks.front(); }
CFGBlock & back() { return *Blocks.back(); } CFGBlock & back() { return *Blocks.back(); }
@ -876,10 +926,12 @@ public:
CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; } CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; }
const CFGBlock * getIndirectGotoBlock() const { 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 { try_block_iterator try_blocks_begin() const {
return TryDispatchBlocks.begin(); return TryDispatchBlocks.begin();
} }
try_block_iterator try_blocks_end() const { try_block_iterator try_blocks_end() const {
return TryDispatchBlocks.end(); return TryDispatchBlocks.end();
} }
@ -900,9 +952,9 @@ public:
SyntheticDeclStmts[Synthetic] = Source; SyntheticDeclStmts[Synthetic] = Source;
} }
typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator using synthetic_stmt_iterator =
synthetic_stmt_iterator; llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator;
typedef llvm::iterator_range<synthetic_stmt_iterator> synthetic_stmt_range; using synthetic_stmt_range = llvm::iterator_range<synthetic_stmt_iterator>;
/// Iterates over synthetic DeclStmts in the CFG. /// Iterates over synthetic DeclStmts in the CFG.
/// ///
@ -962,9 +1014,7 @@ public:
// Internal: constructors and data. // Internal: constructors and data.
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
CFG() CFG() : Blocks(BlkBVC, 10) {}
: Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0),
Blocks(BlkBVC, 10) {}
llvm::BumpPtrAllocator& getAllocator() { llvm::BumpPtrAllocator& getAllocator() {
return BlkBVC.getAllocator(); return BlkBVC.getAllocator();
@ -975,11 +1025,13 @@ public:
} }
private: private:
CFGBlock *Entry; CFGBlock *Entry = nullptr;
CFGBlock *Exit; CFGBlock *Exit = nullptr;
CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch
// for indirect gotos // Special block to contain collective dispatch for indirect gotos
unsigned NumBlockIDs; CFGBlock* IndirectGotoBlock = nullptr;
unsigned NumBlockIDs = 0;
BumpVectorContext BlkBVC; BumpVectorContext BlkBVC;
@ -993,7 +1045,8 @@ private:
/// source DeclStmt. /// source DeclStmt.
llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts; llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
}; };
} // end namespace clang
} // namespace clang
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// GraphTraits specializations for CFG basic block graphs (source-level CFGs) // 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 /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
/// CFGTerminator to a specific Stmt class. /// CFGTerminator to a specific Stmt class.
template <> struct simplify_type< ::clang::CFGTerminator> { template <> struct simplify_type< ::clang::CFGTerminator> {
typedef ::clang::Stmt *SimpleType; using SimpleType = ::clang::Stmt *;
static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) { static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) {
return Val.getStmt(); return Val.getStmt();
} }
@ -1013,50 +1067,44 @@ template <> struct simplify_type< ::clang::CFGTerminator> {
// Traits for: CFGBlock // Traits for: CFGBlock
template <> struct GraphTraits< ::clang::CFGBlock *> { template <> struct GraphTraits< ::clang::CFGBlock *> {
typedef ::clang::CFGBlock *NodeRef; using NodeRef = ::clang::CFGBlock *;
typedef ::clang::CFGBlock::succ_iterator ChildIteratorType; using ChildIteratorType = ::clang::CFGBlock::succ_iterator;
static NodeRef getEntryNode(::clang::CFGBlock *BB) { return BB; } static NodeRef getEntryNode(::clang::CFGBlock *BB) { return BB; }
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); } static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
}; };
template <> struct GraphTraits< const ::clang::CFGBlock *> { template <> struct GraphTraits< const ::clang::CFGBlock *> {
typedef const ::clang::CFGBlock *NodeRef; using NodeRef = const ::clang::CFGBlock *;
typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType; using ChildIteratorType = ::clang::CFGBlock::const_succ_iterator;
static NodeRef getEntryNode(const clang::CFGBlock *BB) { return BB; } static NodeRef getEntryNode(const clang::CFGBlock *BB) { return BB; }
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); } static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
}; };
template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > { template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> {
typedef ::clang::CFGBlock *NodeRef; using NodeRef = ::clang::CFGBlock *;
typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType; using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator;
static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G) { static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G) {
return G.Graph; return G.Graph;
} }
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); } static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); } static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
}; };
template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > { template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> {
typedef const ::clang::CFGBlock *NodeRef; using NodeRef = const ::clang::CFGBlock *;
typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType; using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator;
static NodeRef getEntryNode(Inverse<const ::clang::CFGBlock *> G) { static NodeRef getEntryNode(Inverse<const ::clang::CFGBlock *> G) {
return G.Graph; return G.Graph;
} }
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); } static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); } 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* > template <> struct GraphTraits< ::clang::CFG* >
: public GraphTraits< ::clang::CFGBlock *> { : public GraphTraits< ::clang::CFGBlock *> {
using nodes_iterator = ::clang::CFG::iterator;
typedef ::clang::CFG::iterator nodes_iterator;
static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); } static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); }
static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();} static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
@ -1075,44 +1122,47 @@ template <> struct GraphTraits< ::clang::CFG* >
template <> struct GraphTraits<const ::clang::CFG* > template <> struct GraphTraits<const ::clang::CFG* >
: public GraphTraits<const ::clang::CFGBlock *> { : public GraphTraits<const ::clang::CFGBlock *> {
using nodes_iterator = ::clang::CFG::const_iterator;
typedef ::clang::CFG::const_iterator nodes_iterator;
static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); } static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); }
static nodes_iterator nodes_begin( const ::clang::CFG* F) { static nodes_iterator nodes_begin( const ::clang::CFG* F) {
return F->nodes_begin(); return F->nodes_begin();
} }
static nodes_iterator nodes_end( const ::clang::CFG* F) { static nodes_iterator nodes_end( const ::clang::CFG* F) {
return F->nodes_end(); return F->nodes_end();
} }
static unsigned size(const ::clang::CFG* F) { static unsigned size(const ::clang::CFG* F) {
return F->size(); return F->size();
} }
}; };
template <> struct GraphTraits<Inverse< ::clang::CFG*> > template <> struct GraphTraits<Inverse< ::clang::CFG *>>
: public GraphTraits<Inverse< ::clang::CFGBlock*> > { : public GraphTraits<Inverse< ::clang::CFGBlock *>> {
using nodes_iterator = ::clang::CFG::iterator;
typedef ::clang::CFG::iterator nodes_iterator;
static NodeRef getEntryNode(::clang::CFG *F) { return &F->getExit(); } static NodeRef getEntryNode(::clang::CFG *F) { return &F->getExit(); }
static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();} static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); } static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
}; };
template <> struct GraphTraits<Inverse<const ::clang::CFG*> > template <> struct GraphTraits<Inverse<const ::clang::CFG *>>
: public GraphTraits<Inverse<const ::clang::CFGBlock*> > { : public GraphTraits<Inverse<const ::clang::CFGBlock *>> {
using nodes_iterator = ::clang::CFG::const_iterator;
typedef ::clang::CFG::const_iterator nodes_iterator;
static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); } static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); }
static nodes_iterator nodes_begin(const ::clang::CFG* F) { static nodes_iterator nodes_begin(const ::clang::CFG* F) {
return F->nodes_begin(); return F->nodes_begin();
} }
static nodes_iterator nodes_end(const ::clang::CFG* F) { static nodes_iterator nodes_end(const ::clang::CFG* F) {
return F->nodes_end(); return F->nodes_end();
} }
}; };
} // end llvm namespace
} // namespace llvm
#endif // LLVM_CLANG_ANALYSIS_CFG_H #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 // The LLVM Compiler Infrastructure
// //
@ -12,19 +12,27 @@
// A call graph for functions whose definitions/bodies are available in the // A call graph for functions whose definitions/bodies are available in the
// current translation unit. The graph has a "virtual" root node that contains // current translation unit. The graph has a "virtual" root node that contains
// edges to all externally available functions. // edges to all externally available functions.
//
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH_H #ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH_H
#define 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 "clang/AST/RecursiveASTVisitor.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include <memory>
namespace clang { namespace clang {
class CallGraphNode; class CallGraphNode;
class Decl;
class DeclContext;
class Stmt;
/// \brief The AST-based call graph. /// \brief The AST-based call graph.
/// ///
@ -34,8 +42,8 @@ class CallGraphNode;
class CallGraph : public RecursiveASTVisitor<CallGraph> { class CallGraph : public RecursiveASTVisitor<CallGraph> {
friend class CallGraphNode; friend class CallGraphNode;
typedef llvm::DenseMap<const Decl *, std::unique_ptr<CallGraphNode>> using FunctionMapTy =
FunctionMapTy; llvm::DenseMap<const Decl *, std::unique_ptr<CallGraphNode>>;
/// FunctionMap owns all CallGraphNodes. /// FunctionMap owns all CallGraphNodes.
FunctionMapTy FunctionMap; FunctionMapTy FunctionMap;
@ -65,10 +73,11 @@ public:
/// one into the graph. /// one into the graph.
CallGraphNode *getOrInsertNode(Decl *); CallGraphNode *getOrInsertNode(Decl *);
using iterator = FunctionMapTy::iterator;
using const_iterator = FunctionMapTy::const_iterator;
/// Iterators through all the elements in the graph. Note, this gives /// Iterators through all the elements in the graph. Note, this gives
/// non-deterministic order. /// non-deterministic order.
typedef FunctionMapTy::iterator iterator;
typedef FunctionMapTy::const_iterator const_iterator;
iterator begin() { return FunctionMap.begin(); } iterator begin() { return FunctionMap.begin(); }
iterator end() { return FunctionMap.end(); } iterator end() { return FunctionMap.end(); }
const_iterator begin() const { return FunctionMap.begin(); } 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 /// 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 /// are the unreachable nodes, which are either unused or are due to us
/// failing to add a call edge due to the analysis imprecision. /// failing to add a call edge due to the analysis imprecision.
typedef llvm::SetVector<CallGraphNode *>::iterator nodes_iterator; using nodes_iterator = llvm::SetVector<CallGraphNode *>::iterator;
typedef llvm::SetVector<CallGraphNode *>::const_iterator const_nodes_iterator; using const_nodes_iterator = llvm::SetVector<CallGraphNode *>::const_iterator;
void print(raw_ostream &os) const; void print(raw_ostream &os) const;
void dump() const; void dump() const;
@ -133,7 +142,7 @@ private:
class CallGraphNode { class CallGraphNode {
public: public:
typedef CallGraphNode* CallRecord; using CallRecord = CallGraphNode *;
private: private:
/// \brief The function/method declaration. /// \brief The function/method declaration.
@ -145,17 +154,17 @@ private:
public: public:
CallGraphNode(Decl *D) : FD(D) {} CallGraphNode(Decl *D) : FD(D) {}
typedef SmallVectorImpl<CallRecord>::iterator iterator; using iterator = SmallVectorImpl<CallRecord>::iterator;
typedef SmallVectorImpl<CallRecord>::const_iterator const_iterator; using const_iterator = SmallVectorImpl<CallRecord>::const_iterator;
/// Iterators through all the callees/children of the node. /// Iterators through all the callees/children of the node.
inline iterator begin() { return CalledFunctions.begin(); } iterator begin() { return CalledFunctions.begin(); }
inline iterator end() { return CalledFunctions.end(); } iterator end() { return CalledFunctions.end(); }
inline const_iterator begin() const { return CalledFunctions.begin(); } const_iterator begin() const { return CalledFunctions.begin(); }
inline const_iterator end() const { return CalledFunctions.end(); } const_iterator end() const { return CalledFunctions.end(); }
inline bool empty() const {return CalledFunctions.empty(); } bool empty() const { return CalledFunctions.empty(); }
inline unsigned size() const {return CalledFunctions.size(); } unsigned size() const { return CalledFunctions.size(); }
void addCallee(CallGraphNode *N) { void addCallee(CallGraphNode *N) {
CalledFunctions.push_back(N); CalledFunctions.push_back(N);
@ -167,35 +176,33 @@ public:
void dump() const; void dump() const;
}; };
} // end clang namespace } // namespace clang
// Graph traits for iteration, viewing. // Graph traits for iteration, viewing.
namespace llvm { namespace llvm {
template <> struct GraphTraits<clang::CallGraphNode*> { template <> struct GraphTraits<clang::CallGraphNode*> {
typedef clang::CallGraphNode NodeType; using NodeType = clang::CallGraphNode;
typedef clang::CallGraphNode *NodeRef; using NodeRef = clang::CallGraphNode *;
typedef NodeType::iterator ChildIteratorType; using ChildIteratorType = NodeType::iterator;
static NodeType *getEntryNode(clang::CallGraphNode *CGN) { return CGN; } static NodeType *getEntryNode(clang::CallGraphNode *CGN) { return CGN; }
static inline ChildIteratorType child_begin(NodeType *N) { static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
return N->begin(); static ChildIteratorType child_end(NodeType *N) { return N->end(); }
}
static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
}; };
template <> struct GraphTraits<const clang::CallGraphNode*> { template <> struct GraphTraits<const clang::CallGraphNode*> {
typedef const clang::CallGraphNode NodeType; using NodeType = const clang::CallGraphNode;
typedef const clang::CallGraphNode *NodeRef; using NodeRef = const clang::CallGraphNode *;
typedef NodeType::const_iterator ChildIteratorType; using ChildIteratorType = NodeType::const_iterator;
static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; } static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; }
static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();} static ChildIteratorType child_begin(NodeType *N) { return N->begin();}
static inline ChildIteratorType child_end(NodeType *N) { return N->end(); } static ChildIteratorType child_end(NodeType *N) { return N->end(); }
}; };
template <> struct GraphTraits<clang::CallGraph*> template <> struct GraphTraits<clang::CallGraph*>
: public GraphTraits<clang::CallGraphNode*> { : public GraphTraits<clang::CallGraphNode*> {
static NodeType *getEntryNode(clang::CallGraph *CGN) { static NodeType *getEntryNode(clang::CallGraph *CGN) {
return CGN->getRoot(); // Start at the external node! 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 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef mapped_iterator<clang::CallGraph::iterator, decltype(&CGGetValue)> using nodes_iterator =
nodes_iterator; mapped_iterator<clang::CallGraph::iterator, decltype(&CGGetValue)>;
static nodes_iterator nodes_begin(clang::CallGraph *CG) { static nodes_iterator nodes_begin(clang::CallGraph *CG) {
return nodes_iterator(CG->begin(), &CGGetValue); return nodes_iterator(CG->begin(), &CGGetValue);
} }
static nodes_iterator nodes_end (clang::CallGraph *CG) { static nodes_iterator nodes_end (clang::CallGraph *CG) {
return nodes_iterator(CG->end(), &CGGetValue); return nodes_iterator(CG->end(), &CGGetValue);
} }
static unsigned size(clang::CallGraph *CG) { static unsigned size(clang::CallGraph *CG) { return CG->size(); }
return CG->size();
}
}; };
template <> struct GraphTraits<const clang::CallGraph*> : 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 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef mapped_iterator<clang::CallGraph::const_iterator, using nodes_iterator =
decltype(&CGGetValue)> mapped_iterator<clang::CallGraph::const_iterator, decltype(&CGGetValue)>;
nodes_iterator;
static nodes_iterator nodes_begin(const clang::CallGraph *CG) { static nodes_iterator nodes_begin(const clang::CallGraph *CG) {
return nodes_iterator(CG->begin(), &CGGetValue); return nodes_iterator(CG->begin(), &CGGetValue);
} }
static nodes_iterator nodes_end(const clang::CallGraph *CG) { static nodes_iterator nodes_end(const clang::CallGraph *CG) {
return nodes_iterator(CG->end(), &CGGetValue); 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 /// \file
/// This file defines classes for searching and anlyzing source code clones. /// This file defines classes for searching and analyzing source code clones.
/// ///
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_CLONEDETECTION_H #ifndef LLVM_CLANG_AST_CLONEDETECTION_H
#define LLVM_CLANG_AST_CLONEDETECTION_H #define LLVM_CLANG_AST_CLONEDETECTION_H
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/StmtVisitor.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 "llvm/Support/Regex.h"
#include <vector> #include <vector>
@ -31,192 +27,6 @@ class VarDecl;
class ASTContext; class ASTContext;
class CompoundStmt; 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. /// Identifies a list of statements.
/// ///
/// Can either identify a single arbitrary Stmt object, a continuous sequence of /// Can either identify a single arbitrary Stmt object, a continuous sequence of
@ -423,9 +233,9 @@ public:
/// filtered. /// filtered.
/// \param Filter The filter function that should return true for all groups /// \param Filter The filter function that should return true for all groups
/// that should be removed from the list. /// that should be removed from the list.
static void static void filterGroups(
filterGroups(std::vector<CloneDetector::CloneGroup> &CloneGroups, std::vector<CloneDetector::CloneGroup> &CloneGroups,
std::function<bool(const CloneDetector::CloneGroup &)> Filter) { llvm::function_ref<bool(const CloneDetector::CloneGroup &)> Filter) {
CloneGroups.erase( CloneGroups.erase(
std::remove_if(CloneGroups.begin(), CloneGroups.end(), Filter), std::remove_if(CloneGroups.begin(), CloneGroups.end(), Filter),
CloneGroups.end()); CloneGroups.end());
@ -439,25 +249,29 @@ public:
/// to the same CloneGroup. /// to the same CloneGroup.
static void splitCloneGroups( static void splitCloneGroups(
std::vector<CloneDetector::CloneGroup> &CloneGroups, 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 /// This constraint moves clones into clone groups of type II via hashing.
/// identical in every aspect beside the used variable names). ///
class RecursiveCloneTypeIIConstraint { /// Clones with different hash values are moved into separate clone groups.
/// Collisions are possible, and this constraint does nothing to address this
/// Generates and saves a hash code for the given Stmt. /// them. Add the slower RecursiveCloneTypeIIVerifyConstraint later in the
/// \param S The given Stmt. /// constraint chain, not necessarily immediately, to eliminate hash collisions
/// \param D The Decl containing S. /// through a more detailed analysis.
/// \param StmtsByHash Output parameter that will contain the hash codes for class RecursiveCloneTypeIIHashConstraint {
/// each StmtSequence in the given Stmt. public:
/// \return The hash code of the given Stmt. void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
/// };
/// 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 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: public:
void constrain(std::vector<CloneDetector::CloneGroup> &Sequences); void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
}; };
@ -474,14 +288,19 @@ public:
MinComplexityConstraint(unsigned MinComplexity) MinComplexityConstraint(unsigned MinComplexity)
: MinComplexity(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 = ""); const std::string &ParentMacroStack = "");
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) { void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
CloneConstraint::filterGroups( CloneConstraint::filterGroups(
CloneGroups, [this](const CloneDetector::CloneGroup &A) { CloneGroups, [this](const CloneDetector::CloneGroup &A) {
if (!A.empty()) if (!A.empty())
return calculateStmtComplexity(A.front()) < MinComplexity; return calculateStmtComplexity(A.front(), MinComplexity) <
MinComplexity;
else else
return false; return false;
}); });

View File

@ -15,7 +15,7 @@
#ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H #ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
#define 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 "clang/Analysis/CFG.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
@ -83,6 +83,7 @@ public:
PostImplicitCallKind, PostImplicitCallKind,
MinImplicitCallKind = PreImplicitCallKind, MinImplicitCallKind = PreImplicitCallKind,
MaxImplicitCallKind = PostImplicitCallKind, MaxImplicitCallKind = PostImplicitCallKind,
LoopExitKind,
EpsilonKind}; EpsilonKind};
private: 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 /// This is a meta program point, which should be skipped by all the diagnostic
/// reasoning etc. /// reasoning etc.
class EpsilonPoint : public ProgramPoint { 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 // The LLVM Compiler Infrastructure
// //
@ -21,16 +21,18 @@
#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include "llvm/Support/type_traits.h" #include <cassert>
#include <algorithm> #include <cstddef>
#include <cstring> #include <cstring>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <type_traits>
namespace clang { namespace clang {
class BumpVectorContext { class BumpVectorContext {
llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1> Alloc; llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1> Alloc;
public: public:
/// Construct a new BumpVectorContext that creates a new BumpPtrAllocator /// Construct a new BumpVectorContext that creates a new BumpPtrAllocator
/// and destroys it when the BumpVectorContext object is destroyed. /// and destroys it when the BumpVectorContext object is destroyed.
@ -56,11 +58,13 @@ public:
template<typename T> template<typename T>
class BumpVector { class BumpVector {
T *Begin, *End, *Capacity; T *Begin = nullptr;
T *End = nullptr;
T *Capacity = nullptr;
public: public:
// Default ctor - Initialize to empty. // Default ctor - Initialize to empty.
explicit BumpVector(BumpVectorContext &C, unsigned N) explicit BumpVector(BumpVectorContext &C, unsigned N) {
: Begin(nullptr), End(nullptr), Capacity(nullptr) {
reserve(C, N); reserve(C, N);
} }
@ -71,19 +75,19 @@ public:
} }
} }
typedef size_t size_type; using size_type = size_t;
typedef ptrdiff_t difference_type; using difference_type = ptrdiff_t;
typedef T value_type; using value_type = T;
typedef T* iterator; using iterator = T *;
typedef const T* const_iterator; using const_iterator = const T *;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
typedef std::reverse_iterator<iterator> reverse_iterator; using reverse_iterator = std::reverse_iterator<iterator>;
typedef T& reference; using reference = T &;
typedef const T& const_reference; using const_reference = const T &;
typedef T* pointer; using pointer = T *;
typedef const T* const_pointer; using const_pointer = const T *;
// forward iterator creation methods. // forward iterator creation methods.
iterator begin() { return Begin; } iterator begin() { return Begin; }
@ -92,10 +96,12 @@ public:
const_iterator end() const { return End; } const_iterator end() const { return End; }
// reverse iterator creation methods. // 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()); } const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); } reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin());} const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
bool empty() const { return Begin == End; } bool empty() const { return Begin == End; }
size_type size() const { return End-Begin; } size_type size() const { return End-Begin; }
@ -166,7 +172,7 @@ public:
/// iterator to position after last inserted copy. /// iterator to position after last inserted copy.
iterator insert(iterator I, size_t Cnt, const_reference E, iterator insert(iterator I, size_t Cnt, const_reference E,
BumpVectorContext &C) { BumpVectorContext &C) {
assert (I >= Begin && I <= End && "Iterator out of bounds."); assert(I >= Begin && I <= End && "Iterator out of bounds.");
if (End + Cnt <= Capacity) { if (End + Cnt <= Capacity) {
Retry: Retry:
move_range_right(I, End, Cnt); move_range_right(I, End, Cnt);
@ -246,5 +252,6 @@ void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) {
Capacity = Begin+NewCapacity; Capacity = Begin+NewCapacity;
} }
} // end: clang namespace } // namespace clang
#endif
#endif // LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H

View File

@ -16,25 +16,26 @@
#ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H #ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H
#define 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 /// \brief Defines the address space values used by the address space qualifier
/// of QualType. /// of QualType.
/// ///
enum ID { enum class LangAS : unsigned {
// The default value 0 is the value used in QualType for the the situation // 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 // where there is no address space qualifier.
// 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.
Default = 0, Default = 0,
// OpenCL specific address spaces. // 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_global,
opencl_local, opencl_local,
opencl_constant, opencl_constant,
opencl_private,
opencl_generic, opencl_generic,
// CUDA specific address spaces. // CUDA specific address spaces.
@ -50,9 +51,24 @@ enum ID {
/// The type of a lookup table which maps from language-specific address spaces /// The type of a lookup table which maps from language-specific address spaces
/// to target-specific ones. /// 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 #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/ASTDiagnostic.h"
#include "clang/AST/CommentDiagnostic.h" #include "clang/AST/CommentDiagnostic.h"
#include "clang/Analysis/AnalysisDiagnostic.h" #include "clang/Analysis/AnalysisDiagnostic.h"
#include "clang/CrossTU/CrossTUDiagnostic.h"
#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/DriverDiagnostic.h"
#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/LexDiagnostic.h"
#include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/ParseDiagnostic.h"
#include "clang/Sema/SemaDiagnostic.h" #include "clang/Sema/SemaDiagnostic.h"
#include "clang/Serialization/SerializationDiagnostic.h" #include "clang/Serialization/SerializationDiagnostic.h"
#include "clang/Tooling/Refactoring/RefactoringDiagnostic.h"
namespace clang { namespace clang {
template <size_t SizeOfStr, typename FieldType> 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 { def GlobalDocumentation {
code Intro =[{.. 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 { def CarriesDependencyDocs : Documentation {
let Category = DocCatFunction; let Category = DocCatFunction;
let Content = [{ let Content = [{
@ -1231,6 +1293,7 @@ Here is an example:
def ARMInterruptDocs : Documentation { def ARMInterruptDocs : Documentation {
let Category = DocCatFunction; let Category = DocCatFunction;
let Heading = "interrupt (ARM)";
let Content = [{ let Content = [{
Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on
ARM targets. This attribute may be attached to a function definition and ARM targets. This attribute may be attached to a function definition and
@ -1272,6 +1335,7 @@ The semantics are as follows:
def MipsInterruptDocs : Documentation { def MipsInterruptDocs : Documentation {
let Category = DocCatFunction; let Category = DocCatFunction;
let Heading = "interrupt (MIPS)";
let Content = [{ let Content = [{
Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on
MIPS targets. This attribute may be attached to a function definition and instructs 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 { def AVRInterruptDocs : Documentation {
let Category = DocCatFunction; let Category = DocCatFunction;
let Heading = "interrupt (AVR)";
let Content = [{ let Content = [{
Clang supports the GNU style ``__attribute__((interrupt))`` attribute on Clang supports the GNU style ``__attribute__((interrupt))`` attribute on
AVR targets. This attribute may be attached to a function definition and instructs 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 { def InternalLinkageDocs : Documentation {
let Category = DocCatFunction; let Category = DocCatFunction;
let Content = [{ 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 { def AnyX86NoCallerSavedRegistersDocs : Documentation {
let Category = DocCatFunction; let Category = DocCatFunction;
let Content = [{ 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 { def SwiftCallDocs : Documentation {
let Category = DocCatVariable; let Category = DocCatVariable;
let Content = [{ let Content = [{

View File

@ -26,6 +26,8 @@ enum class AttrSyntax {
Microsoft, Microsoft,
// Is the identifier known as a C++-style attribute? // Is the identifier known as a C++-style attribute?
CXX, CXX,
// Is the identifier known as a C-style attribute?
C,
// Is the identifier known as a pragma attribute? // Is the identifier known as a pragma attribute?
Pragma Pragma
}; };

View File

@ -103,9 +103,9 @@
#endif #endif
// Standard libc/libm functions: // Standard libc/libm functions:
BUILTIN(__builtin_atan2 , "ddd" , "Fnc") BUILTIN(__builtin_atan2 , "ddd" , "Fne")
BUILTIN(__builtin_atan2f, "fff" , "Fnc") BUILTIN(__builtin_atan2f, "fff" , "Fne")
BUILTIN(__builtin_atan2l, "LdLdLd", "Fnc") BUILTIN(__builtin_atan2l, "LdLdLd", "Fne")
BUILTIN(__builtin_abs , "ii" , "ncF") BUILTIN(__builtin_abs , "ii" , "ncF")
BUILTIN(__builtin_copysign, "ddd", "ncF") BUILTIN(__builtin_copysign, "ddd", "ncF")
BUILTIN(__builtin_copysignf, "fff", "ncF") BUILTIN(__builtin_copysignf, "fff", "ncF")
@ -113,9 +113,9 @@ BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
BUILTIN(__builtin_fabs , "dd" , "ncF") BUILTIN(__builtin_fabs , "dd" , "ncF")
BUILTIN(__builtin_fabsf, "ff" , "ncF") BUILTIN(__builtin_fabsf, "ff" , "ncF")
BUILTIN(__builtin_fabsl, "LdLd", "ncF") BUILTIN(__builtin_fabsl, "LdLd", "ncF")
BUILTIN(__builtin_fmod , "ddd" , "Fnc") BUILTIN(__builtin_fmod , "ddd" , "Fne")
BUILTIN(__builtin_fmodf, "fff" , "Fnc") BUILTIN(__builtin_fmodf, "fff" , "Fne")
BUILTIN(__builtin_fmodl, "LdLdLd", "Fnc") BUILTIN(__builtin_fmodl, "LdLdLd", "Fne")
BUILTIN(__builtin_frexp , "ddi*" , "Fn") BUILTIN(__builtin_frexp , "ddi*" , "Fn")
BUILTIN(__builtin_frexpf, "ffi*" , "Fn") BUILTIN(__builtin_frexpf, "ffi*" , "Fn")
BUILTIN(__builtin_frexpl, "LdLdi*", "Fn") BUILTIN(__builtin_frexpl, "LdLdi*", "Fn")
@ -127,9 +127,9 @@ BUILTIN(__builtin_inff , "f" , "nc")
BUILTIN(__builtin_infl , "Ld" , "nc") BUILTIN(__builtin_infl , "Ld" , "nc")
BUILTIN(__builtin_labs , "LiLi" , "Fnc") BUILTIN(__builtin_labs , "LiLi" , "Fnc")
BUILTIN(__builtin_llabs, "LLiLLi", "Fnc") BUILTIN(__builtin_llabs, "LLiLLi", "Fnc")
BUILTIN(__builtin_ldexp , "ddi" , "Fnc") BUILTIN(__builtin_ldexp , "ddi" , "Fne")
BUILTIN(__builtin_ldexpf, "ffi" , "Fnc") BUILTIN(__builtin_ldexpf, "ffi" , "Fne")
BUILTIN(__builtin_ldexpl, "LdLdi", "Fnc") BUILTIN(__builtin_ldexpl, "LdLdi", "Fne")
BUILTIN(__builtin_modf , "ddd*" , "Fn") BUILTIN(__builtin_modf , "ddd*" , "Fn")
BUILTIN(__builtin_modff, "fff*" , "Fn") BUILTIN(__builtin_modff, "fff*" , "Fn")
BUILTIN(__builtin_modfl, "LdLdLd*", "Fn") BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
@ -142,119 +142,119 @@ BUILTIN(__builtin_nansl, "LdcC*", "ncF")
BUILTIN(__builtin_powi , "ddi" , "Fnc") BUILTIN(__builtin_powi , "ddi" , "Fnc")
BUILTIN(__builtin_powif, "ffi" , "Fnc") BUILTIN(__builtin_powif, "ffi" , "Fnc")
BUILTIN(__builtin_powil, "LdLdi", "Fnc") BUILTIN(__builtin_powil, "LdLdi", "Fnc")
BUILTIN(__builtin_pow , "ddd" , "Fnc") BUILTIN(__builtin_pow , "ddd" , "Fne")
BUILTIN(__builtin_powf, "fff" , "Fnc") BUILTIN(__builtin_powf, "fff" , "Fne")
BUILTIN(__builtin_powl, "LdLdLd", "Fnc") BUILTIN(__builtin_powl, "LdLdLd", "Fne")
// Standard unary libc/libm functions with double/float/long double variants: // Standard unary libc/libm functions with double/float/long double variants:
BUILTIN(__builtin_acos , "dd" , "Fnc") BUILTIN(__builtin_acos , "dd" , "Fne")
BUILTIN(__builtin_acosf, "ff" , "Fnc") BUILTIN(__builtin_acosf, "ff" , "Fne")
BUILTIN(__builtin_acosl, "LdLd", "Fnc") BUILTIN(__builtin_acosl, "LdLd", "Fne")
BUILTIN(__builtin_acosh , "dd" , "Fnc") BUILTIN(__builtin_acosh , "dd" , "Fne")
BUILTIN(__builtin_acoshf, "ff" , "Fnc") BUILTIN(__builtin_acoshf, "ff" , "Fne")
BUILTIN(__builtin_acoshl, "LdLd", "Fnc") BUILTIN(__builtin_acoshl, "LdLd", "Fne")
BUILTIN(__builtin_asin , "dd" , "Fnc") BUILTIN(__builtin_asin , "dd" , "Fne")
BUILTIN(__builtin_asinf, "ff" , "Fnc") BUILTIN(__builtin_asinf, "ff" , "Fne")
BUILTIN(__builtin_asinl, "LdLd", "Fnc") BUILTIN(__builtin_asinl, "LdLd", "Fne")
BUILTIN(__builtin_asinh , "dd" , "Fnc") BUILTIN(__builtin_asinh , "dd" , "Fne")
BUILTIN(__builtin_asinhf, "ff" , "Fnc") BUILTIN(__builtin_asinhf, "ff" , "Fne")
BUILTIN(__builtin_asinhl, "LdLd", "Fnc") BUILTIN(__builtin_asinhl, "LdLd", "Fne")
BUILTIN(__builtin_atan , "dd" , "Fnc") BUILTIN(__builtin_atan , "dd" , "Fne")
BUILTIN(__builtin_atanf, "ff" , "Fnc") BUILTIN(__builtin_atanf, "ff" , "Fne")
BUILTIN(__builtin_atanl, "LdLd", "Fnc") BUILTIN(__builtin_atanl, "LdLd", "Fne")
BUILTIN(__builtin_atanh , "dd", "Fnc") BUILTIN(__builtin_atanh , "dd", "Fne")
BUILTIN(__builtin_atanhf, "ff", "Fnc") BUILTIN(__builtin_atanhf, "ff", "Fne")
BUILTIN(__builtin_atanhl, "LdLd", "Fnc") BUILTIN(__builtin_atanhl, "LdLd", "Fne")
BUILTIN(__builtin_cbrt , "dd", "Fnc") BUILTIN(__builtin_cbrt , "dd", "Fnc")
BUILTIN(__builtin_cbrtf, "ff", "Fnc") BUILTIN(__builtin_cbrtf, "ff", "Fnc")
BUILTIN(__builtin_cbrtl, "LdLd", "Fnc") BUILTIN(__builtin_cbrtl, "LdLd", "Fnc")
BUILTIN(__builtin_ceil , "dd" , "Fnc") BUILTIN(__builtin_ceil , "dd" , "Fnc")
BUILTIN(__builtin_ceilf, "ff" , "Fnc") BUILTIN(__builtin_ceilf, "ff" , "Fnc")
BUILTIN(__builtin_ceill, "LdLd", "Fnc") BUILTIN(__builtin_ceill, "LdLd", "Fnc")
BUILTIN(__builtin_cos , "dd" , "Fnc") BUILTIN(__builtin_cos , "dd" , "Fne")
BUILTIN(__builtin_cosf, "ff" , "Fnc") BUILTIN(__builtin_cosf, "ff" , "Fne")
BUILTIN(__builtin_cosh , "dd" , "Fnc") BUILTIN(__builtin_cosh , "dd" , "Fne")
BUILTIN(__builtin_coshf, "ff" , "Fnc") BUILTIN(__builtin_coshf, "ff" , "Fne")
BUILTIN(__builtin_coshl, "LdLd", "Fnc") BUILTIN(__builtin_coshl, "LdLd", "Fne")
BUILTIN(__builtin_cosl, "LdLd", "Fnc") BUILTIN(__builtin_cosl, "LdLd", "Fne")
BUILTIN(__builtin_erf , "dd", "Fnc") BUILTIN(__builtin_erf , "dd", "Fne")
BUILTIN(__builtin_erff, "ff", "Fnc") BUILTIN(__builtin_erff, "ff", "Fne")
BUILTIN(__builtin_erfl, "LdLd", "Fnc") BUILTIN(__builtin_erfl, "LdLd", "Fne")
BUILTIN(__builtin_erfc , "dd", "Fnc") BUILTIN(__builtin_erfc , "dd", "Fne")
BUILTIN(__builtin_erfcf, "ff", "Fnc") BUILTIN(__builtin_erfcf, "ff", "Fne")
BUILTIN(__builtin_erfcl, "LdLd", "Fnc") BUILTIN(__builtin_erfcl, "LdLd", "Fne")
BUILTIN(__builtin_exp , "dd" , "Fnc") BUILTIN(__builtin_exp , "dd" , "Fne")
BUILTIN(__builtin_expf, "ff" , "Fnc") BUILTIN(__builtin_expf, "ff" , "Fne")
BUILTIN(__builtin_expl, "LdLd", "Fnc") BUILTIN(__builtin_expl, "LdLd", "Fne")
BUILTIN(__builtin_exp2 , "dd" , "Fnc") BUILTIN(__builtin_exp2 , "dd" , "Fne")
BUILTIN(__builtin_exp2f, "ff" , "Fnc") BUILTIN(__builtin_exp2f, "ff" , "Fne")
BUILTIN(__builtin_exp2l, "LdLd", "Fnc") BUILTIN(__builtin_exp2l, "LdLd", "Fne")
BUILTIN(__builtin_expm1 , "dd", "Fnc") BUILTIN(__builtin_expm1 , "dd", "Fne")
BUILTIN(__builtin_expm1f, "ff", "Fnc") BUILTIN(__builtin_expm1f, "ff", "Fne")
BUILTIN(__builtin_expm1l, "LdLd", "Fnc") BUILTIN(__builtin_expm1l, "LdLd", "Fne")
BUILTIN(__builtin_fdim, "ddd", "Fnc") BUILTIN(__builtin_fdim, "ddd", "Fne")
BUILTIN(__builtin_fdimf, "fff", "Fnc") BUILTIN(__builtin_fdimf, "fff", "Fne")
BUILTIN(__builtin_fdiml, "LdLdLd", "Fnc") BUILTIN(__builtin_fdiml, "LdLdLd", "Fne")
BUILTIN(__builtin_floor , "dd" , "Fnc") BUILTIN(__builtin_floor , "dd" , "Fnc")
BUILTIN(__builtin_floorf, "ff" , "Fnc") BUILTIN(__builtin_floorf, "ff" , "Fnc")
BUILTIN(__builtin_floorl, "LdLd", "Fnc") BUILTIN(__builtin_floorl, "LdLd", "Fnc")
BUILTIN(__builtin_fma, "dddd", "Fnc") BUILTIN(__builtin_fma, "dddd", "Fne")
BUILTIN(__builtin_fmaf, "ffff", "Fnc") BUILTIN(__builtin_fmaf, "ffff", "Fne")
BUILTIN(__builtin_fmal, "LdLdLdLd", "Fnc") BUILTIN(__builtin_fmal, "LdLdLdLd", "Fne")
BUILTIN(__builtin_fmax, "ddd", "Fnc") BUILTIN(__builtin_fmax, "ddd", "Fnc")
BUILTIN(__builtin_fmaxf, "fff", "Fnc") BUILTIN(__builtin_fmaxf, "fff", "Fnc")
BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc") BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc")
BUILTIN(__builtin_fmin, "ddd", "Fnc") BUILTIN(__builtin_fmin, "ddd", "Fnc")
BUILTIN(__builtin_fminf, "fff", "Fnc") BUILTIN(__builtin_fminf, "fff", "Fnc")
BUILTIN(__builtin_fminl, "LdLdLd", "Fnc") BUILTIN(__builtin_fminl, "LdLdLd", "Fnc")
BUILTIN(__builtin_hypot , "ddd" , "Fnc") BUILTIN(__builtin_hypot , "ddd" , "Fne")
BUILTIN(__builtin_hypotf, "fff" , "Fnc") BUILTIN(__builtin_hypotf, "fff" , "Fne")
BUILTIN(__builtin_hypotl, "LdLdLd", "Fnc") BUILTIN(__builtin_hypotl, "LdLdLd", "Fne")
BUILTIN(__builtin_ilogb , "id", "Fnc") BUILTIN(__builtin_ilogb , "id", "Fne")
BUILTIN(__builtin_ilogbf, "if", "Fnc") BUILTIN(__builtin_ilogbf, "if", "Fne")
BUILTIN(__builtin_ilogbl, "iLd", "Fnc") BUILTIN(__builtin_ilogbl, "iLd", "Fne")
BUILTIN(__builtin_lgamma , "dd", "Fnc") BUILTIN(__builtin_lgamma , "dd", "Fn")
BUILTIN(__builtin_lgammaf, "ff", "Fnc") BUILTIN(__builtin_lgammaf, "ff", "Fn")
BUILTIN(__builtin_lgammal, "LdLd", "Fnc") BUILTIN(__builtin_lgammal, "LdLd", "Fn")
BUILTIN(__builtin_llrint, "LLid", "Fnc") BUILTIN(__builtin_llrint, "LLid", "Fne")
BUILTIN(__builtin_llrintf, "LLif", "Fnc") BUILTIN(__builtin_llrintf, "LLif", "Fne")
BUILTIN(__builtin_llrintl, "LLiLd", "Fnc") BUILTIN(__builtin_llrintl, "LLiLd", "Fne")
BUILTIN(__builtin_llround , "LLid", "Fnc") BUILTIN(__builtin_llround , "LLid", "Fne")
BUILTIN(__builtin_llroundf, "LLif", "Fnc") BUILTIN(__builtin_llroundf, "LLif", "Fne")
BUILTIN(__builtin_llroundl, "LLiLd", "Fnc") BUILTIN(__builtin_llroundl, "LLiLd", "Fne")
BUILTIN(__builtin_log , "dd" , "Fnc") BUILTIN(__builtin_log , "dd" , "Fne")
BUILTIN(__builtin_log10 , "dd" , "Fnc") BUILTIN(__builtin_log10 , "dd" , "Fne")
BUILTIN(__builtin_log10f, "ff" , "Fnc") BUILTIN(__builtin_log10f, "ff" , "Fne")
BUILTIN(__builtin_log10l, "LdLd", "Fnc") BUILTIN(__builtin_log10l, "LdLd", "Fne")
BUILTIN(__builtin_log1p , "dd" , "Fnc") BUILTIN(__builtin_log1p , "dd" , "Fne")
BUILTIN(__builtin_log1pf, "ff" , "Fnc") BUILTIN(__builtin_log1pf, "ff" , "Fne")
BUILTIN(__builtin_log1pl, "LdLd", "Fnc") BUILTIN(__builtin_log1pl, "LdLd", "Fne")
BUILTIN(__builtin_log2, "dd" , "Fnc") BUILTIN(__builtin_log2, "dd" , "Fne")
BUILTIN(__builtin_log2f, "ff" , "Fnc") BUILTIN(__builtin_log2f, "ff" , "Fne")
BUILTIN(__builtin_log2l, "LdLd" , "Fnc") BUILTIN(__builtin_log2l, "LdLd" , "Fne")
BUILTIN(__builtin_logb , "dd", "Fnc") BUILTIN(__builtin_logb , "dd", "Fne")
BUILTIN(__builtin_logbf, "ff", "Fnc") BUILTIN(__builtin_logbf, "ff", "Fne")
BUILTIN(__builtin_logbl, "LdLd", "Fnc") BUILTIN(__builtin_logbl, "LdLd", "Fne")
BUILTIN(__builtin_logf, "ff" , "Fnc") BUILTIN(__builtin_logf, "ff" , "Fne")
BUILTIN(__builtin_logl, "LdLd", "Fnc") BUILTIN(__builtin_logl, "LdLd", "Fne")
BUILTIN(__builtin_lrint , "Lid", "Fnc") BUILTIN(__builtin_lrint , "Lid", "Fne")
BUILTIN(__builtin_lrintf, "Lif", "Fnc") BUILTIN(__builtin_lrintf, "Lif", "Fne")
BUILTIN(__builtin_lrintl, "LiLd", "Fnc") BUILTIN(__builtin_lrintl, "LiLd", "Fne")
BUILTIN(__builtin_lround , "Lid", "Fnc") BUILTIN(__builtin_lround , "Lid", "Fne")
BUILTIN(__builtin_lroundf, "Lif", "Fnc") BUILTIN(__builtin_lroundf, "Lif", "Fne")
BUILTIN(__builtin_lroundl, "LiLd", "Fnc") BUILTIN(__builtin_lroundl, "LiLd", "Fne")
BUILTIN(__builtin_nearbyint , "dd", "Fnc") BUILTIN(__builtin_nearbyint , "dd", "Fnc")
BUILTIN(__builtin_nearbyintf, "ff", "Fnc") BUILTIN(__builtin_nearbyintf, "ff", "Fnc")
BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc") BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc")
BUILTIN(__builtin_nextafter , "ddd", "Fnc") BUILTIN(__builtin_nextafter , "ddd", "Fne")
BUILTIN(__builtin_nextafterf, "fff", "Fnc") BUILTIN(__builtin_nextafterf, "fff", "Fne")
BUILTIN(__builtin_nextafterl, "LdLdLd", "Fnc") BUILTIN(__builtin_nextafterl, "LdLdLd", "Fne")
BUILTIN(__builtin_nexttoward , "ddLd", "Fnc") BUILTIN(__builtin_nexttoward , "ddLd", "Fne")
BUILTIN(__builtin_nexttowardf, "ffLd", "Fnc") BUILTIN(__builtin_nexttowardf, "ffLd", "Fne")
BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fnc") BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fne")
BUILTIN(__builtin_remainder , "ddd", "Fnc") BUILTIN(__builtin_remainder , "ddd", "Fne")
BUILTIN(__builtin_remainderf, "fff", "Fnc") BUILTIN(__builtin_remainderf, "fff", "Fne")
BUILTIN(__builtin_remainderl, "LdLdLd", "Fnc") BUILTIN(__builtin_remainderl, "LdLdLd", "Fne")
BUILTIN(__builtin_remquo , "dddi*", "Fn") BUILTIN(__builtin_remquo , "dddi*", "Fn")
BUILTIN(__builtin_remquof, "fffi*", "Fn") BUILTIN(__builtin_remquof, "fffi*", "Fn")
BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn") BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn")
@ -264,101 +264,101 @@ BUILTIN(__builtin_rintl, "LdLd", "Fnc")
BUILTIN(__builtin_round, "dd" , "Fnc") BUILTIN(__builtin_round, "dd" , "Fnc")
BUILTIN(__builtin_roundf, "ff" , "Fnc") BUILTIN(__builtin_roundf, "ff" , "Fnc")
BUILTIN(__builtin_roundl, "LdLd" , "Fnc") BUILTIN(__builtin_roundl, "LdLd" , "Fnc")
BUILTIN(__builtin_scalbln , "ddLi", "Fnc") BUILTIN(__builtin_scalbln , "ddLi", "Fne")
BUILTIN(__builtin_scalblnf, "ffLi", "Fnc") BUILTIN(__builtin_scalblnf, "ffLi", "Fne")
BUILTIN(__builtin_scalblnl, "LdLdLi", "Fnc") BUILTIN(__builtin_scalblnl, "LdLdLi", "Fne")
BUILTIN(__builtin_scalbn , "ddi", "Fnc") BUILTIN(__builtin_scalbn , "ddi", "Fne")
BUILTIN(__builtin_scalbnf, "ffi", "Fnc") BUILTIN(__builtin_scalbnf, "ffi", "Fne")
BUILTIN(__builtin_scalbnl, "LdLdi", "Fnc") BUILTIN(__builtin_scalbnl, "LdLdi", "Fne")
BUILTIN(__builtin_sin , "dd" , "Fnc") BUILTIN(__builtin_sin , "dd" , "Fne")
BUILTIN(__builtin_sinf, "ff" , "Fnc") BUILTIN(__builtin_sinf, "ff" , "Fne")
BUILTIN(__builtin_sinh , "dd" , "Fnc") BUILTIN(__builtin_sinh , "dd" , "Fne")
BUILTIN(__builtin_sinhf, "ff" , "Fnc") BUILTIN(__builtin_sinhf, "ff" , "Fne")
BUILTIN(__builtin_sinhl, "LdLd", "Fnc") BUILTIN(__builtin_sinhl, "LdLd", "Fne")
BUILTIN(__builtin_sinl, "LdLd", "Fnc") BUILTIN(__builtin_sinl, "LdLd", "Fne")
BUILTIN(__builtin_sqrt , "dd" , "Fnc") BUILTIN(__builtin_sqrt , "dd" , "Fne")
BUILTIN(__builtin_sqrtf, "ff" , "Fnc") BUILTIN(__builtin_sqrtf, "ff" , "Fne")
BUILTIN(__builtin_sqrtl, "LdLd", "Fnc") BUILTIN(__builtin_sqrtl, "LdLd", "Fne")
BUILTIN(__builtin_tan , "dd" , "Fnc") BUILTIN(__builtin_tan , "dd" , "Fne")
BUILTIN(__builtin_tanf, "ff" , "Fnc") BUILTIN(__builtin_tanf, "ff" , "Fne")
BUILTIN(__builtin_tanh , "dd" , "Fnc") BUILTIN(__builtin_tanh , "dd" , "Fne")
BUILTIN(__builtin_tanhf, "ff" , "Fnc") BUILTIN(__builtin_tanhf, "ff" , "Fne")
BUILTIN(__builtin_tanhl, "LdLd", "Fnc") BUILTIN(__builtin_tanhl, "LdLd", "Fne")
BUILTIN(__builtin_tanl, "LdLd", "Fnc") BUILTIN(__builtin_tanl, "LdLd", "Fne")
BUILTIN(__builtin_tgamma , "dd", "Fnc") BUILTIN(__builtin_tgamma , "dd", "Fne")
BUILTIN(__builtin_tgammaf, "ff", "Fnc") BUILTIN(__builtin_tgammaf, "ff", "Fne")
BUILTIN(__builtin_tgammal, "LdLd", "Fnc") BUILTIN(__builtin_tgammal, "LdLd", "Fne")
BUILTIN(__builtin_trunc , "dd", "Fnc") BUILTIN(__builtin_trunc , "dd", "Fnc")
BUILTIN(__builtin_truncf, "ff", "Fnc") BUILTIN(__builtin_truncf, "ff", "Fnc")
BUILTIN(__builtin_truncl, "LdLd", "Fnc") BUILTIN(__builtin_truncl, "LdLd", "Fnc")
// C99 complex builtins // C99 complex builtins
BUILTIN(__builtin_cabs, "dXd", "Fnc") BUILTIN(__builtin_cabs, "dXd", "Fne")
BUILTIN(__builtin_cabsf, "fXf", "Fnc") BUILTIN(__builtin_cabsf, "fXf", "Fne")
BUILTIN(__builtin_cabsl, "LdXLd", "Fnc") BUILTIN(__builtin_cabsl, "LdXLd", "Fne")
BUILTIN(__builtin_cacos, "XdXd", "Fnc") BUILTIN(__builtin_cacos, "XdXd", "Fne")
BUILTIN(__builtin_cacosf, "XfXf", "Fnc") BUILTIN(__builtin_cacosf, "XfXf", "Fne")
BUILTIN(__builtin_cacosh, "XdXd", "Fnc") BUILTIN(__builtin_cacosh, "XdXd", "Fne")
BUILTIN(__builtin_cacoshf, "XfXf", "Fnc") BUILTIN(__builtin_cacoshf, "XfXf", "Fne")
BUILTIN(__builtin_cacoshl, "XLdXLd", "Fnc") BUILTIN(__builtin_cacoshl, "XLdXLd", "Fne")
BUILTIN(__builtin_cacosl, "XLdXLd", "Fnc") BUILTIN(__builtin_cacosl, "XLdXLd", "Fne")
BUILTIN(__builtin_carg, "dXd", "Fnc") BUILTIN(__builtin_carg, "dXd", "Fne")
BUILTIN(__builtin_cargf, "fXf", "Fnc") BUILTIN(__builtin_cargf, "fXf", "Fne")
BUILTIN(__builtin_cargl, "LdXLd", "Fnc") BUILTIN(__builtin_cargl, "LdXLd", "Fne")
BUILTIN(__builtin_casin, "XdXd", "Fnc") BUILTIN(__builtin_casin, "XdXd", "Fne")
BUILTIN(__builtin_casinf, "XfXf", "Fnc") BUILTIN(__builtin_casinf, "XfXf", "Fne")
BUILTIN(__builtin_casinh, "XdXd", "Fnc") BUILTIN(__builtin_casinh, "XdXd", "Fne")
BUILTIN(__builtin_casinhf, "XfXf", "Fnc") BUILTIN(__builtin_casinhf, "XfXf", "Fne")
BUILTIN(__builtin_casinhl, "XLdXLd", "Fnc") BUILTIN(__builtin_casinhl, "XLdXLd", "Fne")
BUILTIN(__builtin_casinl, "XLdXLd", "Fnc") BUILTIN(__builtin_casinl, "XLdXLd", "Fne")
BUILTIN(__builtin_catan, "XdXd", "Fnc") BUILTIN(__builtin_catan, "XdXd", "Fne")
BUILTIN(__builtin_catanf, "XfXf", "Fnc") BUILTIN(__builtin_catanf, "XfXf", "Fne")
BUILTIN(__builtin_catanh, "XdXd", "Fnc") BUILTIN(__builtin_catanh, "XdXd", "Fne")
BUILTIN(__builtin_catanhf, "XfXf", "Fnc") BUILTIN(__builtin_catanhf, "XfXf", "Fne")
BUILTIN(__builtin_catanhl, "XLdXLd", "Fnc") BUILTIN(__builtin_catanhl, "XLdXLd", "Fne")
BUILTIN(__builtin_catanl, "XLdXLd", "Fnc") BUILTIN(__builtin_catanl, "XLdXLd", "Fne")
BUILTIN(__builtin_ccos, "XdXd", "Fnc") BUILTIN(__builtin_ccos, "XdXd", "Fne")
BUILTIN(__builtin_ccosf, "XfXf", "Fnc") BUILTIN(__builtin_ccosf, "XfXf", "Fne")
BUILTIN(__builtin_ccosl, "XLdXLd", "Fnc") BUILTIN(__builtin_ccosl, "XLdXLd", "Fne")
BUILTIN(__builtin_ccosh, "XdXd", "Fnc") BUILTIN(__builtin_ccosh, "XdXd", "Fne")
BUILTIN(__builtin_ccoshf, "XfXf", "Fnc") BUILTIN(__builtin_ccoshf, "XfXf", "Fne")
BUILTIN(__builtin_ccoshl, "XLdXLd", "Fnc") BUILTIN(__builtin_ccoshl, "XLdXLd", "Fne")
BUILTIN(__builtin_cexp, "XdXd", "Fnc") BUILTIN(__builtin_cexp, "XdXd", "Fne")
BUILTIN(__builtin_cexpf, "XfXf", "Fnc") BUILTIN(__builtin_cexpf, "XfXf", "Fne")
BUILTIN(__builtin_cexpl, "XLdXLd", "Fnc") BUILTIN(__builtin_cexpl, "XLdXLd", "Fne")
BUILTIN(__builtin_cimag, "dXd", "Fnc") BUILTIN(__builtin_cimag, "dXd", "Fnc")
BUILTIN(__builtin_cimagf, "fXf", "Fnc") BUILTIN(__builtin_cimagf, "fXf", "Fnc")
BUILTIN(__builtin_cimagl, "LdXLd", "Fnc") BUILTIN(__builtin_cimagl, "LdXLd", "Fnc")
BUILTIN(__builtin_conj, "XdXd", "Fnc") BUILTIN(__builtin_conj, "XdXd", "Fnc")
BUILTIN(__builtin_conjf, "XfXf", "Fnc") BUILTIN(__builtin_conjf, "XfXf", "Fnc")
BUILTIN(__builtin_conjl, "XLdXLd", "Fnc") BUILTIN(__builtin_conjl, "XLdXLd", "Fnc")
BUILTIN(__builtin_clog, "XdXd", "Fnc") BUILTIN(__builtin_clog, "XdXd", "Fne")
BUILTIN(__builtin_clogf, "XfXf", "Fnc") BUILTIN(__builtin_clogf, "XfXf", "Fne")
BUILTIN(__builtin_clogl, "XLdXLd", "Fnc") BUILTIN(__builtin_clogl, "XLdXLd", "Fne")
BUILTIN(__builtin_cproj, "XdXd", "Fnc") BUILTIN(__builtin_cproj, "XdXd", "Fnc")
BUILTIN(__builtin_cprojf, "XfXf", "Fnc") BUILTIN(__builtin_cprojf, "XfXf", "Fnc")
BUILTIN(__builtin_cprojl, "XLdXLd", "Fnc") BUILTIN(__builtin_cprojl, "XLdXLd", "Fnc")
BUILTIN(__builtin_cpow, "XdXdXd", "Fnc") BUILTIN(__builtin_cpow, "XdXdXd", "Fne")
BUILTIN(__builtin_cpowf, "XfXfXf", "Fnc") BUILTIN(__builtin_cpowf, "XfXfXf", "Fne")
BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fnc") BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fne")
BUILTIN(__builtin_creal, "dXd", "Fnc") BUILTIN(__builtin_creal, "dXd", "Fnc")
BUILTIN(__builtin_crealf, "fXf", "Fnc") BUILTIN(__builtin_crealf, "fXf", "Fnc")
BUILTIN(__builtin_creall, "LdXLd", "Fnc") BUILTIN(__builtin_creall, "LdXLd", "Fnc")
BUILTIN(__builtin_csin, "XdXd", "Fnc") BUILTIN(__builtin_csin, "XdXd", "Fne")
BUILTIN(__builtin_csinf, "XfXf", "Fnc") BUILTIN(__builtin_csinf, "XfXf", "Fne")
BUILTIN(__builtin_csinl, "XLdXLd", "Fnc") BUILTIN(__builtin_csinl, "XLdXLd", "Fne")
BUILTIN(__builtin_csinh, "XdXd", "Fnc") BUILTIN(__builtin_csinh, "XdXd", "Fne")
BUILTIN(__builtin_csinhf, "XfXf", "Fnc") BUILTIN(__builtin_csinhf, "XfXf", "Fne")
BUILTIN(__builtin_csinhl, "XLdXLd", "Fnc") BUILTIN(__builtin_csinhl, "XLdXLd", "Fne")
BUILTIN(__builtin_csqrt, "XdXd", "Fnc") BUILTIN(__builtin_csqrt, "XdXd", "Fne")
BUILTIN(__builtin_csqrtf, "XfXf", "Fnc") BUILTIN(__builtin_csqrtf, "XfXf", "Fne")
BUILTIN(__builtin_csqrtl, "XLdXLd", "Fnc") BUILTIN(__builtin_csqrtl, "XLdXLd", "Fne")
BUILTIN(__builtin_ctan, "XdXd", "Fnc") BUILTIN(__builtin_ctan, "XdXd", "Fne")
BUILTIN(__builtin_ctanf, "XfXf", "Fnc") BUILTIN(__builtin_ctanf, "XfXf", "Fne")
BUILTIN(__builtin_ctanl, "XLdXLd", "Fnc") BUILTIN(__builtin_ctanl, "XLdXLd", "Fne")
BUILTIN(__builtin_ctanh, "XdXd", "Fnc") BUILTIN(__builtin_ctanh, "XdXd", "Fne")
BUILTIN(__builtin_ctanhf, "XfXf", "Fnc") BUILTIN(__builtin_ctanhf, "XfXf", "Fne")
BUILTIN(__builtin_ctanhl, "XLdXLd", "Fnc") BUILTIN(__builtin_ctanhl, "XLdXLd", "Fne")
// FP Comparisons. // FP Comparisons.
BUILTIN(__builtin_isgreater , "i.", "Fnc") BUILTIN(__builtin_isgreater , "i.", "Fnc")
@ -700,6 +700,21 @@ BUILTIN(__atomic_signal_fence, "vi", "n")
BUILTIN(__atomic_always_lock_free, "izvCD*", "n") BUILTIN(__atomic_always_lock_free, "izvCD*", "n")
BUILTIN(__atomic_is_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 #undef ATOMIC_BUILTIN
// Non-overloaded atomic builtins. // Non-overloaded atomic builtins.
@ -717,6 +732,7 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
// Microsoft builtins. These are only active with -fms-extensions. // Microsoft builtins. These are only active with -fms-extensions.
LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__annotation, "wC*.","n", ALL_MS_LANGUAGES)
LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES) LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
LIBBUILTIN(_byteswap_ulong, "UNiUNi", "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(modff, "fff*", "fn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(modfl, "LdLdLd*", "fn", "math.h", ALL_LANGUAGES) LIBBUILTIN(modfl, "LdLdLd*", "fn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(nan, "dcC*", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(nan, "dcC*", "fUn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(nanf, "fcC*", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(nanf, "fcC*", "fUn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(nanl, "LdcC*", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(nanl, "LdcC*", "fUn", "math.h", ALL_LANGUAGES)
LIBBUILTIN(pow, "ddd", "fne", "math.h", ALL_LANGUAGES) LIBBUILTIN(pow, "ddd", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(powf, "fff", "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(atanhf, "ff", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(atanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES) LIBBUILTIN(atanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(cbrt, "dd", "fne", "math.h", ALL_LANGUAGES) LIBBUILTIN(cbrt, "dd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(cbrtf, "ff", "fne", "math.h", ALL_LANGUAGES) LIBBUILTIN(cbrtf, "ff", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(cbrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES) LIBBUILTIN(cbrtl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(ceil, "dd", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(ceil, "dd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(ceilf, "ff", "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(remainderf, "fff", "fne", "math.h", ALL_LANGUAGES)
LIBBUILTIN(remainderl, "LdLdLd", "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(rint, "dd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(rintf, "ff", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(rintf, "ff", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(rintl, "LdLd", "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(truncf, "ff", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(truncl, "LdLd", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(truncl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
LIBBUILTIN(cabs, "dXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cabs, "dXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cabsf, "fXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cabsf, "fXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cabsl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cabsl, "LdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cacos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cacos, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cacosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cacosf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cacosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cacosl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cacosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cacosh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cacoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cacoshf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cacoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cacoshl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(carg, "dXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(carg, "dXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cargf, "fXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cargf, "fXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cargl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cargl, "LdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(casin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(casin, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(casinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(casinf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(casinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(casinl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(casinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(casinh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(casinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(casinhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(casinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(casinhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(catan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(catan, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(catanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(catanf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(catanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(catanl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(catanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(catanh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(catanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(catanhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(catanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(catanhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ccos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ccos, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ccosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ccosf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ccosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ccosl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ccosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ccosh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ccoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ccoshf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ccoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ccoshl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cexp, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cexp, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cexpf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cexpf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cexpl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cexpl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cimagf, "fXf", "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(conjf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(conjl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(conjl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(clog, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(clog, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(clogf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(clogf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(clogl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(clogl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cproj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cproj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cprojf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cprojf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cprojl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cprojl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cpow, "XdXdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cpow, "XdXdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cpowf, "XfXfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cpowf, "XfXfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(cpowl, "XLdXLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(cpowl, "XLdXLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(csin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(csin, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(csinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(csinf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(csinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(csinl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(csinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(csinh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(csinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(csinhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(csinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(csinhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(csqrt, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(csqrt, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(csqrtf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(csqrtf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(csqrtl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(csqrtl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ctan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ctan, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ctanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ctanf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ctanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ctanl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ctanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ctanh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ctanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ctanhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
LIBBUILTIN(ctanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES) LIBBUILTIN(ctanhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
// __sinpi and friends are OS X specific library functions, but otherwise much // __sinpi and friends are OS X specific library functions, but otherwise much
// like the standard (non-complex) sin (etc). // 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. // OpenCL v2.0 s6.13.17 - Enqueue kernel functions.
// Custom builtin check allows to perform special check of passed block arguments. // Custom builtin check allows to perform special check of passed block arguments.
LANGBUILTIN(enqueue_kernel, "i.", "tn", OCLC20_LANG) LANGBUILTIN(enqueue_kernel, "i.", "tn", OCLC20_LANG)
LANGBUILTIN(get_kernel_work_group_size, "i.", "tn", OCLC20_LANG) LANGBUILTIN(get_kernel_work_group_size, "Ui.", "tn", OCLC20_LANG)
LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "i.", "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. // OpenCL v2.0 s6.13.9 - Address space qualifier functions.
LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG) LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG)
LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG) LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG)
LANGBUILTIN(to_private, "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 // Builtins for os_log/os_trace
BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut") BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut")
BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt") 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 // Builtins for XRay
BUILTIN(__xray_customevent, "vcC*z", "") BUILTIN(__xray_customevent, "vcC*z", "")

View File

@ -36,10 +36,13 @@ enum LanguageID {
CXX_LANG = 0x4, // builtin for cplusplus only. CXX_LANG = 0x4, // builtin for cplusplus only.
OBJC_LANG = 0x8, // builtin for objective-c and objective-c++ OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
MS_LANG = 0x10, // builtin requires MS mode. 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_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode. 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 { namespace Builtin {

View File

@ -14,6 +14,10 @@
// The format of this database matches clang/Basic/Builtins.def. // 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 // In libgcc
BUILTIN(__clear_cache, "vv*v*", "i") 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_wsr64, "vcC*LUi", "nc")
BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "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 BUILTIN
#undef LANGBUILTIN

View File

@ -21,6 +21,7 @@
// SI+ only builtins. // SI+ only builtins.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
BUILTIN(__builtin_amdgcn_dispatch_ptr, "Uc*2", "nc")
BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "Uc*2", "nc") BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "Uc*2", "nc")
BUILTIN(__builtin_amdgcn_implicitarg_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. // Special builtins.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
BUILTIN(__builtin_amdgcn_read_exec, "LUi", "nc") 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. // R600-NI only builtins.

View File

@ -36,6 +36,7 @@ BUILTIN(__builtin_arm_smulwt, "iii", "nc")
// Saturating arithmetic // Saturating arithmetic
BUILTIN(__builtin_arm_qadd, "iii", "nc") BUILTIN(__builtin_arm_qadd, "iii", "nc")
BUILTIN(__builtin_arm_qsub, "iii", "nc") BUILTIN(__builtin_arm_qsub, "iii", "nc")
BUILTIN(__builtin_arm_qdbl, "ii", "nc")
BUILTIN(__builtin_arm_ssat, "iiUi", "nc") BUILTIN(__builtin_arm_ssat, "iiUi", "nc")
BUILTIN(__builtin_arm_usat, "UiiUi", "nc") BUILTIN(__builtin_arm_usat, "UiiUi", "nc")

View File

@ -17,7 +17,6 @@
// The builtins below are not autogenerated from iset.py. // The builtins below are not autogenerated from iset.py.
// Make sure you do not overwrite these. // 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_ldd, "LLi*LLi*LLi*i", "")
BUILTIN(__builtin_brev_ldw, "i*i*i*i", "") BUILTIN(__builtin_brev_ldw, "i*i*i*i", "")
BUILTIN(__builtin_brev_ldh, "s*s*s*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_ct1p,"iLLi","")
BUILTIN(__builtin_HEXAGON_S2_interleave,"LLiLLi","") BUILTIN(__builtin_HEXAGON_S2_interleave,"LLiLLi","")
BUILTIN(__builtin_HEXAGON_S2_deinterleave,"LLiLLi","") BUILTIN(__builtin_HEXAGON_S2_deinterleave,"LLiLLi","")
BUILTIN(__builtin_HEXAGON_prefetch,"vv*","")
BUILTIN(__builtin_HEXAGON_Y2_dccleana,"vv*","") BUILTIN(__builtin_HEXAGON_Y2_dccleana,"vv*","")
BUILTIN(__builtin_HEXAGON_Y2_dccleaninva,"vv*","") BUILTIN(__builtin_HEXAGON_Y2_dccleaninva,"vv*","")
BUILTIN(__builtin_HEXAGON_Y2_dcinva,"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_vassign_128B,"V32iV32i","v:60:")
BUILTIN(__builtin_HEXAGON_V6_vcombine,"V32iV16iV16i","v:60:") BUILTIN(__builtin_HEXAGON_V6_vcombine,"V32iV16iV16i","v:60:")
BUILTIN(__builtin_HEXAGON_V6_vcombine_128B,"V64iV32iV32i","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,"V16iV16iV16i","v:60:")
BUILTIN(__builtin_HEXAGON_V6_vdelta_128B,"V32iV32iV32i","v:60:") BUILTIN(__builtin_HEXAGON_V6_vdelta_128B,"V32iV32iV32i","v:60:")
BUILTIN(__builtin_HEXAGON_V6_vrdelta,"V16iV16iV16i","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,"V32iV32i","v:60:")
BUILTIN(__builtin_HEXAGON_V6_vassignp_128B,"V64iV64i","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 #undef BUILTIN

View File

@ -371,6 +371,9 @@ BUILTIN(__nvvm_bitcast_i2f, "fi", "")
BUILTIN(__nvvm_bitcast_ll2d, "dLLi", "") BUILTIN(__nvvm_bitcast_ll2d, "dLLi", "")
BUILTIN(__nvvm_bitcast_d2ll, "LLid", "") BUILTIN(__nvvm_bitcast_d2ll, "LLid", "")
// FNS
TARGET_BUILTIN(__nvvm_fns, "UiUiUii", "n", "ptx60")
// Sync // Sync
BUILTIN(__syncthreads, "v", "") BUILTIN(__syncthreads, "v", "")
@ -378,6 +381,9 @@ BUILTIN(__nvvm_bar0_popc, "ii", "")
BUILTIN(__nvvm_bar0_and, "ii", "") BUILTIN(__nvvm_bar0_and, "ii", "")
BUILTIN(__nvvm_bar0_or, "ii", "") BUILTIN(__nvvm_bar0_or, "ii", "")
BUILTIN(__nvvm_bar_sync, "vi", "n") 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 // Shuffle
@ -390,6 +396,33 @@ BUILTIN(__nvvm_shfl_bfly_f32, "ffii", "")
BUILTIN(__nvvm_shfl_idx_i32, "iiii", "") BUILTIN(__nvvm_shfl_idx_i32, "iiii", "")
BUILTIN(__nvvm_shfl_idx_f32, "ffii", "") 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 // Membar
BUILTIN(__nvvm_membar_cta, "v", "") 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") 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_g_d, "ddD*1d", "n")
BUILTIN(__nvvm_atom_add_s_d, "ddD*3d", "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_cta_add_gen_d, "ddD*d", "n", "satom")
TARGET_BUILTIN(__nvvm_atom_sys_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_f4, "E4fE4fC*", "")
BUILTIN(__nvvm_ldg_d2, "E2dE2dC*", "") 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 BUILTIN
#undef TARGET_BUILTIN #undef TARGET_BUILTIN

View File

@ -32,7 +32,9 @@
// Miscellaneous builtin for checking x86 cpu features. // Miscellaneous builtin for checking x86 cpu features.
// TODO: Make this somewhat generic so that other backends // TODO: Make this somewhat generic so that other backends
// can use it? // can use it?
BUILTIN(__builtin_cpu_init, "v", "n")
BUILTIN(__builtin_cpu_supports, "bcC*", "nc") BUILTIN(__builtin_cpu_supports, "bcC*", "nc")
BUILTIN(__builtin_cpu_is, "bcC*", "nc")
// Undefined Values // Undefined Values
// //
@ -264,8 +266,6 @@ TARGET_BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "", "sse2") TARGET_BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "", "sse2") TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_pmulhw128, "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_pmaxub128, "V16cV16cV16c", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "", "sse2") TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "", "sse2")
TARGET_BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "", "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_psubusb256, "V32cV32cV32c", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIi", "", "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_pblendvb256, "V32cV32cV32cV32c", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "", "avx2") TARGET_BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "", "avx2")
TARGET_BUILTIN(__builtin_ia32_phaddd256, "V8iV8iV8i", "", "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_xsavec, "vv*ULLi", "", "xsavec")
TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves") 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 //CLFLUSHOPT
TARGET_BUILTIN(__builtin_ia32_clflushopt, "vc*", "", "clflushopt") TARGET_BUILTIN(__builtin_ia32_clflushopt, "vvC*", "", "clflushopt")
//CLWB
TARGET_BUILTIN(__builtin_ia32_clwb, "vvC*", "", "clwb")
// ADX // ADX
TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx") TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx")
@ -681,36 +692,18 @@ TARGET_BUILTIN(__builtin_ia32_sha256msg2, "V4iV4iV4i", "", "sha")
// FMA // FMA
TARGET_BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "", "fma|fma4") TARGET_BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "", "fma|fma4") TARGET_BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "", "fma|fma4") TARGET_BUILTIN(__builtin_ia32_vfmaddss3, "V4fV4fV4fV4f", "", "fma")
TARGET_BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "", "fma|fma4") TARGET_BUILTIN(__builtin_ia32_vfmaddsd3, "V2dV2dV2dV2d", "", "fma")
TARGET_BUILTIN(__builtin_ia32_vfmsubps, "V4fV4fV4fV4f", "", "fma|fma4") TARGET_BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "", "fma4")
TARGET_BUILTIN(__builtin_ia32_vfmsubpd, "V2dV2dV2dV2d", "", "fma|fma4") TARGET_BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "", "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_vfmaddsubps, "V4fV4fV4fV4f", "", "fma|fma4") TARGET_BUILTIN(__builtin_ia32_vfmaddsubps, "V4fV4fV4fV4f", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd, "V2dV2dV2dV2d", "", "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_vfmaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddpd256, "V4dV4dV4dV4d", "", "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_vfnmaddps256, "V8fV8fV8fV8f", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfnmaddpd256, "V4dV4dV4dV4d", "", "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_vfmaddsubps256, "V8fV8fV8fV8f", "", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "", "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_mask, "V2dV2dV2dV2dUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_mask3, "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_cvttps2udq512_mask, "V16iV16fV16iUsIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvttpd2udq512_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_cmpps256_mask, "UcV8fV8fIiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "", "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_cmppd512_mask, "UcV8dV8dIiUcIi", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "", "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_pminuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8LLiV16iV16i", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8LLiV16iV16i", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_pmuludq512, "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_loaddqusi512_mask, "V16iiC*V16iUs", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "", "avx512f")
TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "", "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_paddsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_paddusw512_mask, "V32sV32sV32sV32sUi", "", "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_pmaxsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmaxsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmaxub512_mask, "V64cV64cV64cV64cULLi", "", "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_vplzcntd_512_mask, "V16iV16iV16iUs", "", "avx512cd")
TARGET_BUILTIN(__builtin_ia32_vplzcntq_512_mask, "V8LLiV8LLiV8LLiUc", "", "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_vpopcntd_512, "V16iV16i", "", "avx512vpopcntdq")
TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8LLiV8LLi", "", "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_movdqa64load256_mask, "V4LLiV4LLiC*V4LLiUc","","avx512vl")
TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2LLi*V2LLiUc","","avx512f") TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2LLi*V2LLiUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4LLi*V4LLiUc","","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_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma") TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma")
TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512_mask, "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_vpermt2varpd512_maskz, "V8dV8LLiV8dV8dUc","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_maskz, "V16fV16iV16fV16fUs","","avx512f") TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_maskz, "V16fV16iV16fV16fUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","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_rndscalesd_round_mask, "V2dV2dV2dV2dUcIiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_rndscaless_round_mask, "V4fV4fV4fV4fUcIiIi","","avx512f") TARGET_BUILTIN(__builtin_ia32_rndscaless_round_mask, "V4fV4fV4fV4fUcIiIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_scalefpd512_mask, "V8dV8dV8dV8dUcIi","","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_cvtmask2q256, "V4LLiUc","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi","","avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi","","avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi","","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_pmovsdb512_mask, "V16cV16iV16cUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs","","avx512f") TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs","","avx512f")
TARGET_BUILTIN(__builtin_ia32_pmovswb512mem_mask, "vV32c*V32sUi","","avx512bw") 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(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "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(_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_readeflags_u64, "ULLi", "n", "")
TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "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_xrstors64, "vv*ULLi", "", "xsaves")
TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec") TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec")
TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves") 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_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx")
TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "") TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "")
TARGET_BUILTIN(__builtin_ia32_subborrow_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_bextri_u64, "ULLiULLiIULLi", "", "tbm")
TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcULLiUiUi", "", "lwp") TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcULLiUiUi", "", "lwp")
TARGET_BUILTIN(__builtin_ia32_lwpval64, "vULLiUiUi", "", "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_vcvtsd2si64, "LLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi","","avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi","","avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi","","avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi","","avx512f")

View File

@ -40,14 +40,14 @@ namespace charinfo {
} // end namespace charinfo } // end namespace charinfo
/// Returns true if this is an ASCII character. /// 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; return static_cast<unsigned char>(c) <= 127;
} }
/// Returns true if this is a valid first character of a C identifier, /// Returns true if this is a valid first character of a C identifier,
/// which is [a-zA-Z_]. /// which is [a-zA-Z_].
LLVM_READONLY static inline bool isIdentifierHead(unsigned char c, LLVM_READONLY inline bool isIdentifierHead(unsigned char c,
bool AllowDollar = false) { bool AllowDollar = false) {
using namespace charinfo; using namespace charinfo;
if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_UNDER)) if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_UNDER))
return true; 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, /// Returns true if this is a body character of a C identifier,
/// which is [a-zA-Z0-9_]. /// which is [a-zA-Z0-9_].
LLVM_READONLY static inline bool isIdentifierBody(unsigned char c, LLVM_READONLY inline bool isIdentifierBody(unsigned char c,
bool AllowDollar = false) { bool AllowDollar = false) {
using namespace charinfo; using namespace charinfo;
if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER)) if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER))
return true; return true;
@ -68,7 +68,7 @@ LLVM_READONLY static inline bool isIdentifierBody(unsigned char c,
/// ' ', '\\t', '\\f', '\\v'. /// ' ', '\\t', '\\f', '\\v'.
/// ///
/// Note that this returns false for '\\0'. /// 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; using namespace charinfo;
return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_SPACE)) != 0; 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'. /// Returns true if this character is vertical ASCII whitespace: '\\n', '\\r'.
/// ///
/// Note that this returns false for '\\0'. /// 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; using namespace charinfo;
return (InfoTable[c] & CHAR_VERT_WS) != 0; 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'. /// ' ', '\\t', '\\f', '\\v', '\\n', '\\r'.
/// ///
/// Note that this returns false for '\\0'. /// 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; using namespace charinfo;
return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_VERT_WS|CHAR_SPACE)) != 0; return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_VERT_WS|CHAR_SPACE)) != 0;
} }
/// Return true if this character is an ASCII digit: [0-9] /// 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; using namespace charinfo;
return (InfoTable[c] & CHAR_DIGIT) != 0; return (InfoTable[c] & CHAR_DIGIT) != 0;
} }
/// Return true if this character is a lowercase ASCII letter: [a-z] /// 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; using namespace charinfo;
return (InfoTable[c] & CHAR_LOWER) != 0; return (InfoTable[c] & CHAR_LOWER) != 0;
} }
/// Return true if this character is an uppercase ASCII letter: [A-Z] /// 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; using namespace charinfo;
return (InfoTable[c] & CHAR_UPPER) != 0; return (InfoTable[c] & CHAR_UPPER) != 0;
} }
/// Return true if this character is an ASCII letter: [a-zA-Z] /// 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; using namespace charinfo;
return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER)) != 0; return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER)) != 0;
} }
/// Return true if this character is an ASCII letter or digit: [a-zA-Z0-9] /// 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; using namespace charinfo;
return (InfoTable[c] & (CHAR_DIGIT|CHAR_UPPER|CHAR_LOWER)) != 0; return (InfoTable[c] & (CHAR_DIGIT|CHAR_UPPER|CHAR_LOWER)) != 0;
} }
/// Return true if this character is an ASCII hex digit: [0-9a-fA-F] /// 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; using namespace charinfo;
return (InfoTable[c] & (CHAR_DIGIT|CHAR_XLETTER)) != 0; 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. /// Return true if this character is an ASCII punctuation character.
/// ///
/// Note that '_' is both a punctuation character and an identifier 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; using namespace charinfo;
return (InfoTable[c] & (CHAR_UNDER|CHAR_PERIOD|CHAR_RAWDEL|CHAR_PUNCT)) != 0; 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 /// 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 /// character that should take exactly one column to print in a fixed-width
/// terminal. /// terminal.
LLVM_READONLY static inline bool isPrintable(unsigned char c) { LLVM_READONLY inline bool isPrintable(unsigned char c) {
using namespace charinfo; using namespace charinfo;
return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|CHAR_PUNCT| return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|CHAR_PUNCT|
CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL|CHAR_SPACE)) != 0; 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, /// Return true if this is the body character of a C preprocessing number,
/// which is [a-zA-Z0-9_.]. /// 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; using namespace charinfo;
return (InfoTable[c] & return (InfoTable[c] &
(CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER|CHAR_PERIOD)) != 0; (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. /// 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; using namespace charinfo;
return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD| return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|
CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL)) != 0; 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. /// Converts the given ASCII character to its lowercase equivalent.
/// ///
/// If the character is not an uppercase character, it is returned as is. /// 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)) if (isUppercase(c))
return c + 'a' - 'A'; return c + 'a' - 'A';
return c; return c;
@ -171,7 +171,7 @@ LLVM_READONLY static inline char toLowercase(char c) {
/// Converts the given ASCII character to its uppercase equivalent. /// Converts the given ASCII character to its uppercase equivalent.
/// ///
/// If the character is not a lowercase character, it is returned as is. /// 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)) if (isLowercase(c))
return c + 'A' - 'a'; return c + 'A' - 'a';
return c; 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 /// Note that this is a very simple check; it does not accept '$' or UCNs as
/// valid identifier characters. /// valid identifier characters.
LLVM_READONLY static inline bool isValidIdentifier(StringRef S) { LLVM_READONLY inline bool isValidIdentifier(StringRef S) {
if (S.empty() || !isIdentifierHead(S[0])) if (S.empty() || !isIdentifierHead(S[0]))
return false; return false;

View File

@ -21,6 +21,8 @@ enum class CudaVersion {
CUDA_70, CUDA_70,
CUDA_75, CUDA_75,
CUDA_80, CUDA_80,
CUDA_90,
LATEST = CUDA_90,
}; };
const char *CudaVersionToString(CudaVersion V); const char *CudaVersionToString(CudaVersion V);
@ -41,6 +43,7 @@ enum class CudaArch {
SM_60, SM_60,
SM_61, SM_61,
SM_62, SM_62,
SM_70,
}; };
const char *CudaArchToString(CudaArch A); const char *CudaArchToString(CudaArch A);
@ -60,6 +63,7 @@ enum class CudaVirtualArch {
COMPUTE_60, COMPUTE_60,
COMPUTE_61, COMPUTE_61,
COMPUTE_62, COMPUTE_62,
COMPUTE_70,
}; };
const char *CudaVirtualArchToString(CudaVirtualArch A); const char *CudaVirtualArchToString(CudaVirtualArch A);
@ -72,6 +76,9 @@ CudaVirtualArch VirtualArchForCudaArch(CudaArch A);
/// Get the earliest CudaVersion that supports the given CudaArch. /// Get the earliest CudaVersion that supports the given CudaArch.
CudaVersion MinVersionForCudaArch(CudaArch A); CudaVersion MinVersionForCudaArch(CudaArch A);
/// Get the latest CudaVersion that supports the given CudaArch.
CudaVersion MaxVersionForCudaArch(CudaArch A);
} // namespace clang } // namespace clang
#endif #endif

View File

@ -1,66 +1,68 @@
class AttrSubject; class AttrSubject;
class Decl<bit abstract = 0> : AttrSubject { class Decl<string diagSpelling = "", bit abstract = 0> : AttrSubject {
bit Abstract = abstract; 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; Decl Base = base;
} }
class DeclContext { } class DeclContext {}
def TranslationUnit : Decl, DeclContext; def TranslationUnit : Decl, DeclContext;
def PragmaComment : Decl; def PragmaComment : Decl;
def PragmaDetectMismatch : Decl; def PragmaDetectMismatch : Decl;
def ExternCContext : Decl, DeclContext; def ExternCContext : Decl, DeclContext;
def Named : Decl<1>; def Named : Decl<"named declarations", 1>;
def Namespace : DDecl<Named>, DeclContext; def Namespace : DDecl<Named, "namespaces">, DeclContext;
def UsingDirective : DDecl<Named>; def UsingDirective : DDecl<Named>;
def NamespaceAlias : DDecl<Named>; def NamespaceAlias : DDecl<Named>;
def Label : DDecl<Named>; def Label : DDecl<Named, "labels">;
def Type : DDecl<Named, 1>; def Type : DDecl<Named, "types", 1>;
def TypedefName : DDecl<Type, 1>; def TypedefName : DDecl<Type, "typedefs", 1>;
def Typedef : DDecl<TypedefName>; def Typedef : DDecl<TypedefName>;
def TypeAlias : DDecl<TypedefName>; def TypeAlias : DDecl<TypedefName>;
def ObjCTypeParam : DDecl<TypedefName>; def ObjCTypeParam : DDecl<TypedefName>;
def UnresolvedUsingTypename : DDecl<Type>; def UnresolvedUsingTypename : DDecl<Type>;
def Tag : DDecl<Type, 1>, DeclContext; def Tag : DDecl<Type, "tag types", 1>, DeclContext;
def Enum : DDecl<Tag>; def Enum : DDecl<Tag, "enums">;
def Record : DDecl<Tag>; def Record : DDecl<Tag, "structs, unions, classes">;
def CXXRecord : DDecl<Record>; def CXXRecord : DDecl<Record, "classes">;
def ClassTemplateSpecialization : DDecl<CXXRecord>; def ClassTemplateSpecialization : DDecl<CXXRecord>;
def ClassTemplatePartialSpecialization def ClassTemplatePartialSpecialization
: DDecl<ClassTemplateSpecialization>; : DDecl<ClassTemplateSpecialization>;
def TemplateTypeParm : DDecl<Type>; def TemplateTypeParm : DDecl<Type>;
def Value : DDecl<Named, 1>; def Value : DDecl<Named, "value declarations", 1>;
def EnumConstant : DDecl<Value>; def EnumConstant : DDecl<Value, "enumerators">;
def UnresolvedUsingValue : DDecl<Value>; def UnresolvedUsingValue : DDecl<Value>;
def IndirectField : DDecl<Value>; def IndirectField : DDecl<Value>;
def Binding : DDecl<Value>; def Binding : DDecl<Value>;
def OMPDeclareReduction : DDecl<Value>, DeclContext; def OMPDeclareReduction : DDecl<Value>, DeclContext;
def Declarator : DDecl<Value, 1>; def Declarator : DDecl<Value, "declarators", 1>;
def Field : DDecl<Declarator>; def Field : DDecl<Declarator, "non-static data members">;
def ObjCIvar : DDecl<Field>; def ObjCIvar : DDecl<Field>;
def ObjCAtDefsField : DDecl<Field>; def ObjCAtDefsField : DDecl<Field>;
def MSProperty : DDecl<Declarator>; def MSProperty : DDecl<Declarator>;
def Function : DDecl<Declarator>, DeclContext; def Function : DDecl<Declarator, "functions">, DeclContext;
def CXXDeductionGuide : DDecl<Function>; def CXXDeductionGuide : DDecl<Function>;
def CXXMethod : DDecl<Function>; def CXXMethod : DDecl<Function>;
def CXXConstructor : DDecl<CXXMethod>; def CXXConstructor : DDecl<CXXMethod>;
def CXXDestructor : DDecl<CXXMethod>; def CXXDestructor : DDecl<CXXMethod>;
def CXXConversion : DDecl<CXXMethod>; def CXXConversion : DDecl<CXXMethod>;
def Var : DDecl<Declarator>; def Var : DDecl<Declarator, "variables">;
def VarTemplateSpecialization : DDecl<Var>; def VarTemplateSpecialization : DDecl<Var>;
def VarTemplatePartialSpecialization def VarTemplatePartialSpecialization
: DDecl<VarTemplateSpecialization>; : DDecl<VarTemplateSpecialization>;
def ImplicitParam : DDecl<Var>; def ImplicitParam : DDecl<Var>;
def ParmVar : DDecl<Var>; def ParmVar : DDecl<Var, "parameters">;
def Decomposition : DDecl<Var>; def Decomposition : DDecl<Var>;
def OMPCapturedExpr : DDecl<Var>; def OMPCapturedExpr : DDecl<Var>;
def NonTypeTemplateParm : DDecl<Declarator>; def NonTypeTemplateParm : DDecl<Declarator>;
def Template : DDecl<Named, 1>; def Template : DDecl<Named, "templates", 1>;
def RedeclarableTemplate : DDecl<Template, 1>; def RedeclarableTemplate : DDecl<Template, "redeclarable templates", 1>;
def FunctionTemplate : DDecl<RedeclarableTemplate>; def FunctionTemplate : DDecl<RedeclarableTemplate>;
def ClassTemplate : DDecl<RedeclarableTemplate>; def ClassTemplate : DDecl<RedeclarableTemplate>;
def VarTemplate : DDecl<RedeclarableTemplate>; def VarTemplate : DDecl<RedeclarableTemplate>;
@ -71,15 +73,16 @@ def Named : Decl<1>;
def UsingPack : DDecl<Named>; def UsingPack : DDecl<Named>;
def UsingShadow : DDecl<Named>; def UsingShadow : DDecl<Named>;
def ConstructorUsingShadow : DDecl<UsingShadow>; def ConstructorUsingShadow : DDecl<UsingShadow>;
def ObjCMethod : DDecl<Named>, DeclContext; def ObjCMethod : DDecl<Named, "Objective-C methods">, DeclContext;
def ObjCContainer : DDecl<Named, 1>, DeclContext; def ObjCContainer : DDecl<Named, "Objective-C containers", 1>, DeclContext;
def ObjCCategory : DDecl<ObjCContainer>; def ObjCCategory : DDecl<ObjCContainer>;
def ObjCProtocol : DDecl<ObjCContainer>; def ObjCProtocol : DDecl<ObjCContainer, "Objective-C protocols">;
def ObjCInterface : DDecl<ObjCContainer>; def ObjCInterface : DDecl<ObjCContainer, "Objective-C interfaces">;
def ObjCImpl : DDecl<ObjCContainer, 1>; def ObjCImpl
: DDecl<ObjCContainer, "Objective-C implementation declarations", 1>;
def ObjCCategoryImpl : DDecl<ObjCImpl>; def ObjCCategoryImpl : DDecl<ObjCImpl>;
def ObjCImplementation : DDecl<ObjCImpl>; def ObjCImplementation : DDecl<ObjCImpl>;
def ObjCProperty : DDecl<Named>; def ObjCProperty : DDecl<Named, "Objective-C properties">;
def ObjCCompatibleAlias : DDecl<Named>; def ObjCCompatibleAlias : DDecl<Named>;
def LinkageSpec : Decl, DeclContext; def LinkageSpec : Decl, DeclContext;
def Export : Decl, DeclContext; def Export : Decl, DeclContext;
@ -89,7 +92,7 @@ def AccessSpec : Decl;
def Friend : Decl; def Friend : Decl;
def FriendTemplate : Decl; def FriendTemplate : Decl;
def StaticAssert : Decl; def StaticAssert : Decl;
def Block : Decl, DeclContext; def Block : Decl<"blocks">, DeclContext;
def Captured : Decl, DeclContext; def Captured : Decl, DeclContext;
def ClassScopeFunctionSpecialization : Decl; def ClassScopeFunctionSpecialization : Decl;
def Import : Decl; def Import : Decl;

View File

@ -575,13 +575,15 @@ public:
OverloadsShown getShowOverloads() const { return ShowOverloads; } OverloadsShown getShowOverloads() const { return ShowOverloads; }
/// \brief Pretend that the last diagnostic issued was ignored, so any /// \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. /// This can be used by clients who suppress diagnostics themselves.
void setLastDiagnosticIgnored() { void setLastDiagnosticIgnored(bool Ignored = true) {
if (LastDiagLevel == DiagnosticIDs::Fatal) if (LastDiagLevel == DiagnosticIDs::Fatal)
FatalErrorOccurred = true; FatalErrorOccurred = true;
LastDiagLevel = DiagnosticIDs::Ignored; LastDiagLevel = Ignored ? DiagnosticIDs::Ignored : DiagnosticIDs::Warning;
} }
/// \brief Determine whether the previous diagnostic was ignored. This can /// \brief Determine whether the previous diagnostic was ignored. This can

View File

@ -133,10 +133,12 @@ include "DiagnosticASTKinds.td"
include "DiagnosticAnalysisKinds.td" include "DiagnosticAnalysisKinds.td"
include "DiagnosticCommentKinds.td" include "DiagnosticCommentKinds.td"
include "DiagnosticCommonKinds.td" include "DiagnosticCommonKinds.td"
include "DiagnosticCrossTUKinds.td"
include "DiagnosticDriverKinds.td" include "DiagnosticDriverKinds.td"
include "DiagnosticFrontendKinds.td" include "DiagnosticFrontendKinds.td"
include "DiagnosticLexKinds.td" include "DiagnosticLexKinds.td"
include "DiagnosticParseKinds.td" include "DiagnosticParseKinds.td"
include "DiagnosticRefactoringKinds.td"
include "DiagnosticSemaKinds.td" include "DiagnosticSemaKinds.td"
include "DiagnosticSerializationKinds.td" include "DiagnosticSerializationKinds.td"

View File

@ -127,6 +127,10 @@ def note_constexpr_access_null : Note<
def note_constexpr_access_past_end : Note< def note_constexpr_access_past_end : Note<
"%select{read of|assignment to|increment of|decrement of}0 " "%select{read of|assignment to|increment of|decrement of}0 "
"dereferenced one-past-the-end pointer is not allowed in a constant expression">; "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< def note_constexpr_access_inactive_union_member : Note<
"%select{read of|assignment to|increment of|decrement of}0 " "%select{read of|assignment to|increment of|decrement of}0 "
"member %1 of union with %select{active member %3|no active member}2 " "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< def note_constexpr_baa_value_insufficient_alignment : Note<
"value of the aligned pointer (%0) is not a multiple of the asserted %1 " "value of the aligned pointer (%0) is not a multiple of the asserted %1 "
"%plural{1:byte|:bytes}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< def warn_integer_constant_overflow : Warning<
"overflow in expression; result is %0 with type %1">, "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< def err_target_unknown_triple : Error<
"unknown target triple '%0', please use -triple or -arch">; "unknown target triple '%0', please use -triple or -arch">;
def err_target_unknown_cpu : Error<"unknown target CPU '%0'">; 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_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 : Error<"ABI '%0' is not supported on CPU '%1'">;
def err_target_unsupported_abi_for_triple : Error< 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< def err_drv_no_cuda_libdevice : Error<
"cannot find libdevice for %0. Provide path to different CUDA installation " "cannot find libdevice for %0. Provide path to different CUDA installation "
"via --cuda-path, or pass -nocudalib to build without linking with libdevice.">; "via --cuda-path, or pass -nocudalib to build without linking with libdevice.">;
def err_drv_cuda_version_too_low : Error< def err_drv_cuda_version_unsupported : Error<
"GPU arch %1 requires CUDA version at least %3, but installation at %0 is %2. " "GPU arch %0 is supported by CUDA versions between %1 and %2 (inclusive), "
"Use --cuda-path to specify a different CUDA install, or pass " "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.">; "--no-cuda-version-check.">;
def err_drv_cuda_nvptx_host : Error<"unsupported use of NVPTX for host compilation.">; def err_drv_cuda_nvptx_host : Error<"unsupported use of NVPTX for host compilation.">;
def err_drv_invalid_thread_model_for_target : Error< 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">; "invalid Xarch argument: '%0', options requiring arguments are unsupported">;
def err_drv_invalid_Xarch_argument_isdriver : Error< def err_drv_invalid_Xarch_argument_isdriver : Error<
"invalid Xarch argument: '%0', cannot change driver behavior inside Xarch argument">; "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< def err_drv_argument_only_allowed_with : Error<
"invalid argument '%0' only allowed with '%1'">; "invalid argument '%0' only allowed with '%1'">;
def err_drv_argument_not_allowed_with : Error< 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">; "failing because %select{environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set|'-gen-reproducer' is used}0">;
def err_drv_invalid_mfloat_abi : Error< def err_drv_invalid_mfloat_abi : Error<
"invalid float ABI '%0'">; "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< def err_drv_invalid_libcxx_deployment : Error<
"invalid deployment target for -stdlib=libc++ (requires %0 or later)">; "invalid deployment target for -stdlib=libc++ (requires %0 or later)">;
def err_drv_invalid_argument_to_fdebug_prefix_map : Error< 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 def err_target_unsupported_arch
: Error<"the target architecture '%0' is not supported by the target '%1'">; : 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< def err_drv_I_dash_not_supported : Error<
"'%0' not supported, please use -iquote instead">; "'%0' not supported, please use -iquote instead">;
@ -231,7 +244,7 @@ def warn_drv_enabling_rtti_with_exceptions : Warning<
InGroup<DiagGroup<"rtti-for-exceptions">>; InGroup<DiagGroup<"rtti-for-exceptions">>;
def warn_drv_disabling_vptr_no_rtti_default : Warning< def warn_drv_disabling_vptr_no_rtti_default : Warning<
"implicitly disabling vptr sanitizer because rtti wasn't enabled">, "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< def warn_drv_object_size_disabled_O0 : Warning<
"the object size sanitizer has no effect at -O0, but is explicitly enabled: %0">, "the object size sanitizer has no effect at -O0, but is explicitly enabled: %0">,
InGroup<InvalidCommandLineArgument>; InGroup<InvalidCommandLineArgument>;
@ -251,6 +264,9 @@ def err_analyzer_config_no_value : Error<
def err_analyzer_config_multiple_values : Error< def err_analyzer_config_multiple_values : Error<
"analyzer-config option '%0' should contain only one '='">; "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< def err_drv_modules_validate_once_requires_timestamp : Error<
"option '-fmodules-validate-once-per-build-session' requires " "option '-fmodules-validate-once-per-build-session' requires "
"'-fbuild-session-timestamp=<seconds since Epoch>' or '-fbuild-session-file=<file>'">; "'-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< def warn_target_unsupported_nanlegacy : Warning<
"ignoring '-mnan=legacy' option because the '%0' architecture does not support it">, "ignoring '-mnan=legacy' option because the '%0' architecture does not support it">,
InGroup<UnsupportedNan>; 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< def warn_target_unsupported_compact_branches : Warning<
"ignoring '-mcompact-branches=' option because the '%0' architecture does not" "ignoring '-mcompact-branches=' option because the '%0' architecture does not"
" support it">, InGroup<UnsupportedCB>; " 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< def warn_drv_unable_to_find_directory_expected : Warning<
"unable to find %0 directory, expected to be in '%1'">, "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; " "unable to find a Visual Studio installation; "
"try running Clang from a developer command prompt">, "try running Clang from a developer command prompt">,
InGroup<DiagGroup<"msvc-not-found">>; 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">; "action %0 not compiled in">;
def err_fe_invalid_alignment : Error< def err_fe_invalid_alignment : Error<
"invalid value '%1' in '%0'; alignment must be a power of 2">; "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< def warn_fe_serialized_diag_merge_failure : Warning<
"unable to merge a subprocess's serialized diagnostics">, "unable to merge a subprocess's serialized diagnostics">,

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