mirror of
https://github.com/opnsense/src.git
synced 2026-02-20 00:11:07 -05:00
Merge clang trunk r351319, resolve conflicts, and update FREEBSD-Xlist.
This commit is contained in:
commit
d5ea6fa648
848 changed files with 72268 additions and 48510 deletions
|
|
@ -5,9 +5,9 @@
|
|||
.gitignore
|
||||
CMakeLists.txt
|
||||
CODE_OWNERS.TXT
|
||||
Driver/
|
||||
INPUTS/
|
||||
INSTALL.txt
|
||||
Makefile
|
||||
ModuleInfo.txt
|
||||
NOTES.txt
|
||||
README.txt
|
||||
|
|
@ -16,118 +16,105 @@ cmake/
|
|||
docs/
|
||||
examples/
|
||||
include/CMakeLists.txt
|
||||
include/Makefile
|
||||
include/clang/AST/CMakeLists.txt
|
||||
include/clang/AST/Makefile
|
||||
include/clang/Basic/CMakeLists.txt
|
||||
include/clang/Basic/Makefile
|
||||
include/clang/Basic/Version.inc.in
|
||||
include/clang/CMakeLists.txt
|
||||
include/clang/Config/
|
||||
include/clang/Driver/CMakeLists.txt
|
||||
include/clang/Driver/Makefile
|
||||
include/clang/Makefile
|
||||
include/clang/Parse/CMakeLists.txt
|
||||
include/clang/Parse/Makefile
|
||||
include/clang/Sema/CMakeLists.txt
|
||||
include/clang/Sema/Makefile
|
||||
include/clang/Serialization/CMakeLists.txt
|
||||
include/clang/Serialization/Makefile
|
||||
include/clang-c/Makefile
|
||||
include/clang/StaticAnalyzer/Checkers/CMakeLists.txt
|
||||
lib/ARCMigrate/CMakeLists.txt
|
||||
lib/ARCMigrate/Makefile
|
||||
lib/AST/CMakeLists.txt
|
||||
lib/AST/Makefile
|
||||
lib/ASTMatchers/CMakeLists.txt
|
||||
lib/ASTMatchers/Dynamic/CMakeLists.txt
|
||||
lib/ASTMatchers/Dynamic/Makefile
|
||||
lib/ASTMatchers/Makefile
|
||||
lib/Analysis/CMakeLists.txt
|
||||
lib/Analysis/Makefile
|
||||
lib/Basic/CMakeLists.txt
|
||||
lib/Basic/Makefile
|
||||
lib/CMakeLists.txt
|
||||
lib/CodeGen/CMakeLists.txt
|
||||
lib/CodeGen/Makefile
|
||||
lib/CodeGen/README.txt
|
||||
lib/CrossTU/CMakeLists.txt
|
||||
lib/Driver/Arch/
|
||||
lib/Driver/CMakeLists.txt
|
||||
lib/Driver/Makefile
|
||||
lib/Edit/CMakeLists.txt
|
||||
lib/Edit/Makefile
|
||||
lib/Format/CMakeLists.txt
|
||||
lib/Format/Makefile
|
||||
lib/Frontend/CMakeLists.txt
|
||||
lib/Frontend/Makefile
|
||||
lib/Frontend/Rewrite/CMakeLists.txt
|
||||
lib/Frontend/Rewrite/Makefile
|
||||
lib/FrontendTool/CMakeLists.txt
|
||||
lib/FrontendTool/Makefile
|
||||
lib/Headers/CMakeLists.txt
|
||||
lib/Headers/Makefile
|
||||
lib/Headers/cuda/
|
||||
lib/Index/CMakeLists.txt
|
||||
lib/Index/Makefile
|
||||
lib/Lex/CMakeLists.txt
|
||||
lib/Lex/Makefile
|
||||
lib/Makefile
|
||||
lib/Parse/CMakeLists.txt
|
||||
lib/Parse/Makefile
|
||||
lib/Rewrite/CMakeLists.txt
|
||||
lib/Rewrite/Makefile
|
||||
lib/Sema/CMakeLists.txt
|
||||
lib/Sema/Makefile
|
||||
lib/Serialization/CMakeLists.txt
|
||||
lib/Serialization/Makefile
|
||||
lib/StaticAnalyzer/CMakeLists.txt
|
||||
lib/StaticAnalyzer/Checkers/CMakeLists.txt
|
||||
lib/StaticAnalyzer/Checkers/Makefile
|
||||
lib/StaticAnalyzer/Core/CMakeLists.txt
|
||||
lib/StaticAnalyzer/Core/Makefile
|
||||
lib/StaticAnalyzer/Frontend/CMakeLists.txt
|
||||
lib/StaticAnalyzer/Frontend/Makefile
|
||||
lib/StaticAnalyzer/Makefile
|
||||
lib/StaticAnalyzer/README.txt
|
||||
lib/Tooling/ASTDiff/CMakeLists.txt
|
||||
lib/Tooling/CMakeLists.txt
|
||||
lib/Tooling/Core/CMakeLists.txt
|
||||
lib/Tooling/Core/Makefile
|
||||
lib/Tooling/Makefile
|
||||
lib/Tooling/Inclusions/CMakeLists.txt
|
||||
lib/Tooling/Refactoring/CMakeLists.txt
|
||||
runtime/
|
||||
test/
|
||||
tools/CMakeLists.txt
|
||||
tools/Makefile
|
||||
tools/arcmt-test/
|
||||
tools/c-arcmt-test/
|
||||
tools/c-index-test/
|
||||
tools/clang-check/
|
||||
tools/clang-format/
|
||||
tools/clang-diff/
|
||||
tools/clang-extdef-mapping/
|
||||
tools/clang-format-vs/
|
||||
tools/clang-format/CMakeLists.txt
|
||||
tools/clang-format/clang-format-bbedit.applescript
|
||||
tools/clang-format/clang-format-diff.py
|
||||
tools/clang-format/clang-format-sublime.py
|
||||
tools/clang-format/clang-format-test.el
|
||||
tools/clang-format/clang-format.el
|
||||
tools/clang-format/clang-format.py
|
||||
tools/clang-format/fuzzer/
|
||||
tools/clang-format/git-clang-format
|
||||
tools/clang-func-mapping/
|
||||
tools/clang-fuzzer/
|
||||
tools/clang-import-test/
|
||||
tools/clang-offload-bundler/
|
||||
tools/clang-refactor/
|
||||
tools/clang-rename/
|
||||
tools/diag-build/
|
||||
tools/diagtool/
|
||||
tools/driver/CMakeLists.txt
|
||||
tools/driver/Info.plist.in
|
||||
tools/driver/Makefile
|
||||
tools/driver/clang_symlink.cmake
|
||||
tools/libclang/
|
||||
tools/scan-build/
|
||||
tools/scan-build-py/
|
||||
tools/scan-view/
|
||||
unittests/
|
||||
utils/ABITest/
|
||||
utils/CIndex/
|
||||
utils/CaptureCmd
|
||||
utils/ClangDataFormat.py
|
||||
utils/ClangVisualizers/
|
||||
utils/CmpDriver
|
||||
utils/FindSpecRefs
|
||||
utils/FuzzTest
|
||||
utils/TableGen/CMakeLists.txt
|
||||
utils/TableGen/Makefile
|
||||
utils/TestUtils/
|
||||
utils/VtableTest/
|
||||
utils/analyzer/
|
||||
utils/bash-autocomplete.sh
|
||||
utils/builtin-defines.c
|
||||
utils/check_cfc/
|
||||
utils/clang-completion-mode.el
|
||||
utils/clang.natvis
|
||||
utils/clangdiag.py
|
||||
utils/find-unused-diagnostics.sh
|
||||
utils/hmaptool/
|
||||
utils/modfuzz.py
|
||||
utils/perf-training/
|
||||
utils/token-delta.py
|
||||
utils/valgrind/
|
||||
www/
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ LLVM Release License
|
|||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2007-2018 University of Illinois at Urbana-Champaign.
|
||||
Copyright (c) 2007-2019 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
|
||||
*/
|
||||
#define CINDEX_VERSION_MAJOR 0
|
||||
#define CINDEX_VERSION_MINOR 49
|
||||
#define CINDEX_VERSION_MINOR 50
|
||||
|
||||
#define CINDEX_VERSION_ENCODE(major, minor) ( \
|
||||
((major) * 10000) \
|
||||
|
|
@ -178,7 +178,6 @@ typedef struct CXVersion {
|
|||
* A negative value indicates that the cursor is not a function declaration.
|
||||
*/
|
||||
enum CXCursor_ExceptionSpecificationKind {
|
||||
|
||||
/**
|
||||
* The cursor has no exception specification.
|
||||
*/
|
||||
|
|
@ -1332,7 +1331,17 @@ enum CXTranslationUnit_Flags {
|
|||
*
|
||||
* The function bodies of the main file are not skipped.
|
||||
*/
|
||||
CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 0x800
|
||||
CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 0x800,
|
||||
|
||||
/**
|
||||
* Used to indicate that attributed types should be included in CXType.
|
||||
*/
|
||||
CXTranslationUnit_IncludeAttributedTypes = 0x1000,
|
||||
|
||||
/**
|
||||
* Used to indicate that implicit attributes should be visited.
|
||||
*/
|
||||
CXTranslationUnit_VisitImplicitAttributes = 0x2000
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2559,7 +2568,25 @@ enum CXCursorKind {
|
|||
CXCursor_VisibilityAttr = 417,
|
||||
CXCursor_DLLExport = 418,
|
||||
CXCursor_DLLImport = 419,
|
||||
CXCursor_LastAttr = CXCursor_DLLImport,
|
||||
CXCursor_NSReturnsRetained = 420,
|
||||
CXCursor_NSReturnsNotRetained = 421,
|
||||
CXCursor_NSReturnsAutoreleased = 422,
|
||||
CXCursor_NSConsumesSelf = 423,
|
||||
CXCursor_NSConsumed = 424,
|
||||
CXCursor_ObjCException = 425,
|
||||
CXCursor_ObjCNSObject = 426,
|
||||
CXCursor_ObjCIndependentClass = 427,
|
||||
CXCursor_ObjCPreciseLifetime = 428,
|
||||
CXCursor_ObjCReturnsInnerPointer = 429,
|
||||
CXCursor_ObjCRequiresSuper = 430,
|
||||
CXCursor_ObjCRootClass = 431,
|
||||
CXCursor_ObjCSubclassingRestricted = 432,
|
||||
CXCursor_ObjCExplicitProtocolImpl = 433,
|
||||
CXCursor_ObjCDesignatedInitializer = 434,
|
||||
CXCursor_ObjCRuntimeVisible = 435,
|
||||
CXCursor_ObjCBoxable = 436,
|
||||
CXCursor_FlagEnum = 437,
|
||||
CXCursor_LastAttr = CXCursor_FlagEnum,
|
||||
|
||||
/* Preprocessing */
|
||||
CXCursor_PreprocessingDirective = 500,
|
||||
|
|
@ -3266,7 +3293,25 @@ enum CXTypeKind {
|
|||
CXType_OCLSampler = 157,
|
||||
CXType_OCLEvent = 158,
|
||||
CXType_OCLQueue = 159,
|
||||
CXType_OCLReserveID = 160
|
||||
CXType_OCLReserveID = 160,
|
||||
|
||||
CXType_ObjCObject = 161,
|
||||
CXType_ObjCTypeParam = 162,
|
||||
CXType_Attributed = 163,
|
||||
|
||||
CXType_OCLIntelSubgroupAVCMcePayload = 164,
|
||||
CXType_OCLIntelSubgroupAVCImePayload = 165,
|
||||
CXType_OCLIntelSubgroupAVCRefPayload = 166,
|
||||
CXType_OCLIntelSubgroupAVCSicPayload = 167,
|
||||
CXType_OCLIntelSubgroupAVCMceResult = 168,
|
||||
CXType_OCLIntelSubgroupAVCImeResult = 169,
|
||||
CXType_OCLIntelSubgroupAVCRefResult = 170,
|
||||
CXType_OCLIntelSubgroupAVCSicResult = 171,
|
||||
CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout = 172,
|
||||
CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173,
|
||||
CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174,
|
||||
|
||||
CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -3291,6 +3336,7 @@ enum CXCallingConv {
|
|||
CXCallingConv_Swift = 13,
|
||||
CXCallingConv_PreserveMost = 14,
|
||||
CXCallingConv_PreserveAll = 15,
|
||||
CXCallingConv_AArch64VectorCall = 16,
|
||||
|
||||
CXCallingConv_Invalid = 100,
|
||||
CXCallingConv_Unexposed = 200
|
||||
|
|
@ -3627,6 +3673,43 @@ CINDEX_LINKAGE int clang_getNumArgTypes(CXType T);
|
|||
*/
|
||||
CINDEX_LINKAGE CXType clang_getArgType(CXType T, unsigned i);
|
||||
|
||||
/**
|
||||
* Retrieves the base type of the ObjCObjectType.
|
||||
*
|
||||
* If the type is not an ObjC object, an invalid type is returned.
|
||||
*/
|
||||
CINDEX_LINKAGE CXType clang_Type_getObjCObjectBaseType(CXType T);
|
||||
|
||||
/**
|
||||
* Retrieve the number of protocol references associated with an ObjC object/id.
|
||||
*
|
||||
* If the type is not an ObjC object, 0 is returned.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Type_getNumObjCProtocolRefs(CXType T);
|
||||
|
||||
/**
|
||||
* Retrieve the decl for a protocol reference for an ObjC object/id.
|
||||
*
|
||||
* If the type is not an ObjC object or there are not enough protocol
|
||||
* references, an invalid cursor is returned.
|
||||
*/
|
||||
CINDEX_LINKAGE CXCursor clang_Type_getObjCProtocolDecl(CXType T, unsigned i);
|
||||
|
||||
/**
|
||||
* Retreive the number of type arguments associated with an ObjC object.
|
||||
*
|
||||
* If the type is not an ObjC object, 0 is returned.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Type_getNumObjCTypeArgs(CXType T);
|
||||
|
||||
/**
|
||||
* Retrieve a type argument associated with an ObjC object.
|
||||
*
|
||||
* If the type is not an ObjC or the index is not valid,
|
||||
* an invalid type is returned.
|
||||
*/
|
||||
CINDEX_LINKAGE CXType clang_Type_getObjCTypeArg(CXType T, unsigned i);
|
||||
|
||||
/**
|
||||
* Return 1 if the CXType is a variadic function type, and 0 otherwise.
|
||||
*/
|
||||
|
|
@ -3700,6 +3783,33 @@ CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T);
|
|||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Type_isTransparentTagTypedef(CXType T);
|
||||
|
||||
enum CXTypeNullabilityKind {
|
||||
/**
|
||||
* Values of this type can never be null.
|
||||
*/
|
||||
CXTypeNullability_NonNull = 0,
|
||||
/**
|
||||
* Values of this type can be null.
|
||||
*/
|
||||
CXTypeNullability_Nullable = 1,
|
||||
/**
|
||||
* Whether values of this type can be null is (explicitly)
|
||||
* unspecified. This captures a (fairly rare) case where we
|
||||
* can't conclude anything about the nullability of the type even
|
||||
* though it has been considered.
|
||||
*/
|
||||
CXTypeNullability_Unspecified = 2,
|
||||
/**
|
||||
* Nullability is not applicable to this type.
|
||||
*/
|
||||
CXTypeNullability_Invalid = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve the nullability kind of a pointer type.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXTypeNullabilityKind clang_Type_getNullability(CXType T);
|
||||
|
||||
/**
|
||||
* List the possible error codes for \c clang_Type_getSizeOf,
|
||||
* \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
|
||||
|
|
@ -3778,6 +3888,13 @@ CINDEX_LINKAGE long long clang_Type_getSizeOf(CXType T);
|
|||
*/
|
||||
CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S);
|
||||
|
||||
/**
|
||||
* Return the type that was modified by this attributed type.
|
||||
*
|
||||
* If the type is not an attributed type, an invalid type is returned.
|
||||
*/
|
||||
CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T);
|
||||
|
||||
/**
|
||||
* Return the offset of the field represented by the Cursor.
|
||||
*
|
||||
|
|
@ -4347,6 +4464,18 @@ typedef enum {
|
|||
CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C,
|
||||
unsigned reserved);
|
||||
|
||||
/**
|
||||
* Given a cursor that represents a property declaration, return the
|
||||
* name of the method that implements the getter.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C);
|
||||
|
||||
/**
|
||||
* Given a cursor that represents a property declaration, return the
|
||||
* name of the method that implements the setter, if any.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertySetterName(CXCursor C);
|
||||
|
||||
/**
|
||||
* 'Qualifiers' written next to the return and parameter types in
|
||||
* Objective-C method declarations.
|
||||
|
|
@ -5491,10 +5620,15 @@ enum CXCompletionContext {
|
|||
*/
|
||||
CXCompletionContext_NaturalLanguage = 1 << 21,
|
||||
|
||||
/**
|
||||
* #include file completions should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_IncludedFile = 1 << 22,
|
||||
|
||||
/**
|
||||
* The current context is unknown, so set all contexts.
|
||||
*/
|
||||
CXCompletionContext_Unknown = ((1 << 22) - 1)
|
||||
CXCompletionContext_Unknown = ((1 << 23) - 1)
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
|
||||
#define LLVM_CLANG_AST_ASTCONTEXT_H
|
||||
|
||||
#include "clang/AST/ASTContextAllocate.h"
|
||||
#include "clang/AST/ASTTypeTraits.h"
|
||||
#include "clang/AST/CanonicalType.h"
|
||||
#include "clang/AST/CommentCommandTraits.h"
|
||||
|
|
@ -22,6 +23,7 @@
|
|||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/AST/PrettyPrinter.h"
|
||||
|
|
@ -30,6 +32,7 @@
|
|||
#include "clang/AST/TemplateName.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/AddressSpaces.h"
|
||||
#include "clang/Basic/AttrKinds.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
|
|
@ -79,6 +82,7 @@ struct fltSemantics;
|
|||
|
||||
namespace clang {
|
||||
|
||||
class APFixedPoint;
|
||||
class APValue;
|
||||
class ASTMutationListener;
|
||||
class ASTRecordLayout;
|
||||
|
|
@ -92,6 +96,7 @@ class CXXMethodDecl;
|
|||
class CXXRecordDecl;
|
||||
class DiagnosticsEngine;
|
||||
class Expr;
|
||||
class FixedPointSemantics;
|
||||
class MangleContext;
|
||||
class MangleNumberingContext;
|
||||
class MaterializeTemporaryExpr;
|
||||
|
|
@ -148,6 +153,22 @@ struct TypeInfo {
|
|||
/// Holds long-lived AST nodes (such as types and decls) that can be
|
||||
/// referred to throughout the semantic analysis of a file.
|
||||
class ASTContext : public RefCountedBase<ASTContext> {
|
||||
public:
|
||||
/// Copy initialization expr of a __block variable and a boolean flag that
|
||||
/// indicates whether the expression can throw.
|
||||
struct BlockVarCopyInit {
|
||||
BlockVarCopyInit() = default;
|
||||
BlockVarCopyInit(Expr *CopyExpr, bool CanThrow)
|
||||
: ExprAndFlag(CopyExpr, CanThrow) {}
|
||||
void setExprAndFlag(Expr *CopyExpr, bool CanThrow) {
|
||||
ExprAndFlag.setPointerAndInt(CopyExpr, CanThrow);
|
||||
}
|
||||
Expr *getCopyExpr() const { return ExprAndFlag.getPointer(); }
|
||||
bool canThrow() const { return ExprAndFlag.getInt(); }
|
||||
llvm::PointerIntPair<Expr *, 1, bool> ExprAndFlag;
|
||||
};
|
||||
|
||||
private:
|
||||
friend class NestedNameSpecifier;
|
||||
|
||||
mutable SmallVector<Type *, 0> Types;
|
||||
|
|
@ -242,8 +263,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
|||
/// interface.
|
||||
llvm::DenseMap<const ObjCMethodDecl*,const ObjCMethodDecl*> ObjCMethodRedecls;
|
||||
|
||||
/// Mapping from __block VarDecls to their copy initialization expr.
|
||||
llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits;
|
||||
/// Mapping from __block VarDecls to BlockVarCopyInit.
|
||||
llvm::DenseMap<const VarDecl *, BlockVarCopyInit> BlockVarCopyInits;
|
||||
|
||||
/// Mapping from class scope functions specialization to their
|
||||
/// template patterns.
|
||||
|
|
@ -316,7 +337,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
|||
mutable IdentifierInfo *BoolName = nullptr;
|
||||
|
||||
/// The identifier 'NSObject'.
|
||||
IdentifierInfo *NSObjectName = nullptr;
|
||||
mutable IdentifierInfo *NSObjectName = nullptr;
|
||||
|
||||
/// The identifier 'NSCopying'.
|
||||
IdentifierInfo *NSCopyingName = nullptr;
|
||||
|
|
@ -549,26 +570,6 @@ public:
|
|||
IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
|
||||
ASTMutationListener *Listener = nullptr;
|
||||
|
||||
/// Contains parents of a node.
|
||||
using ParentVector = llvm::SmallVector<ast_type_traits::DynTypedNode, 2>;
|
||||
|
||||
/// Maps from a node to its parents. This is used for nodes that have
|
||||
/// pointer identity only, which are more common and we can save space by
|
||||
/// only storing a unique pointer to them.
|
||||
using ParentMapPointers =
|
||||
llvm::DenseMap<const void *,
|
||||
llvm::PointerUnion4<const Decl *, const Stmt *,
|
||||
ast_type_traits::DynTypedNode *,
|
||||
ParentVector *>>;
|
||||
|
||||
/// Parent map for nodes without pointer identity. We store a full
|
||||
/// DynTypedNode for all keys.
|
||||
using ParentMapOtherNodes =
|
||||
llvm::DenseMap<ast_type_traits::DynTypedNode,
|
||||
llvm::PointerUnion4<const Decl *, const Stmt *,
|
||||
ast_type_traits::DynTypedNode *,
|
||||
ParentVector *>>;
|
||||
|
||||
/// Container for either a single DynTypedNode or for an ArrayRef to
|
||||
/// DynTypedNode. For use with ParentMap.
|
||||
class DynTypedNodeList {
|
||||
|
|
@ -610,7 +611,17 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// Returns the parents of the given node.
|
||||
// A traversal scope limits the parts of the AST visible to certain analyses.
|
||||
// RecursiveASTVisitor::TraverseAST will only visit reachable nodes, and
|
||||
// getParents() will only observe reachable parent edges.
|
||||
//
|
||||
// The scope is defined by a set of "top-level" declarations.
|
||||
// Initially, it is the entire TU: {getTranslationUnitDecl()}.
|
||||
// Changing the scope clears the parent cache, which is expensive to rebuild.
|
||||
std::vector<Decl *> getTraversalScope() const { return TraversalScope; }
|
||||
void setTraversalScope(const std::vector<Decl *> &);
|
||||
|
||||
/// Returns the parents of the given node (within the traversal scope).
|
||||
///
|
||||
/// Note that this will lazily compute the parents of all nodes
|
||||
/// and store them for later retrieval. Thus, the first call is O(n)
|
||||
|
|
@ -977,7 +988,8 @@ public:
|
|||
/// Get the additional modules in which the definition \p Def has
|
||||
/// been merged.
|
||||
ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def) {
|
||||
auto MergedIt = MergedDefModules.find(Def);
|
||||
auto MergedIt =
|
||||
MergedDefModules.find(cast<NamedDecl>(Def->getCanonicalDecl()));
|
||||
if (MergedIt == MergedDefModules.end())
|
||||
return None;
|
||||
return MergedIt->second;
|
||||
|
|
@ -1041,6 +1053,9 @@ public:
|
|||
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
|
||||
CanQualType OCLQueueTy, OCLReserveIDTy;
|
||||
CanQualType OMPArraySectionTy;
|
||||
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
|
||||
CanQualType Id##Ty;
|
||||
#include "clang/Basic/OpenCLExtensionTypes.def"
|
||||
|
||||
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
|
||||
mutable QualType AutoDeductTy; // Deduction against 'auto'.
|
||||
|
|
@ -1403,7 +1418,7 @@ public:
|
|||
|
||||
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
|
||||
|
||||
QualType getAttributedType(AttributedType::Kind attrKind,
|
||||
QualType getAttributedType(attr::Kind attrKind,
|
||||
QualType modifiedType,
|
||||
QualType equivalentType);
|
||||
|
||||
|
|
@ -1656,7 +1671,7 @@ public:
|
|||
}
|
||||
|
||||
/// Retrieve the identifier 'NSObject'.
|
||||
IdentifierInfo *getNSObjectName() {
|
||||
IdentifierInfo *getNSObjectName() const {
|
||||
if (!NSObjectName) {
|
||||
NSObjectName = &Idents.get("NSObject");
|
||||
}
|
||||
|
|
@ -1961,6 +1976,9 @@ public:
|
|||
|
||||
unsigned char getFixedPointScale(QualType Ty) const;
|
||||
unsigned char getFixedPointIBits(QualType Ty) const;
|
||||
FixedPointSemantics getFixedPointSemantics(QualType Ty) const;
|
||||
APFixedPoint getFixedPointMax(QualType Ty) const;
|
||||
APFixedPoint getFixedPointMin(QualType Ty) const;
|
||||
|
||||
DeclarationNameInfo getNameForTemplate(TemplateName Name,
|
||||
SourceLocation NameLoc) const;
|
||||
|
|
@ -2488,6 +2506,8 @@ public:
|
|||
|
||||
unsigned getTargetAddressSpace(LangAS AS) const;
|
||||
|
||||
LangAS getLangASForBuiltinAddressSpace(unsigned AS) const;
|
||||
|
||||
/// Get target-dependent integer value for null pointer which is used for
|
||||
/// constant folding.
|
||||
uint64_t getTargetNullPointerValue(QualType QT) const;
|
||||
|
|
@ -2657,12 +2677,13 @@ public:
|
|||
/// otherwise returns null.
|
||||
const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const;
|
||||
|
||||
/// Set the copy inialization expression of a block var decl.
|
||||
void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
|
||||
/// Set the copy inialization expression of a block var decl. \p CanThrow
|
||||
/// indicates whether the copy expression can throw or not.
|
||||
void setBlockVarCopyInit(const VarDecl* VD, Expr *CopyExpr, bool CanThrow);
|
||||
|
||||
/// Get the copy initialization expression of the VarDecl \p VD, or
|
||||
/// nullptr if none exists.
|
||||
Expr *getBlockVarCopyInits(const VarDecl* VD);
|
||||
BlockVarCopyInit getBlockVarCopyInit(const VarDecl* VD) const;
|
||||
|
||||
/// Allocate an uninitialized TypeSourceInfo.
|
||||
///
|
||||
|
|
@ -2894,13 +2915,13 @@ private:
|
|||
// but we include it here so that ASTContext can quickly deallocate them.
|
||||
llvm::PointerIntPair<StoredDeclsMap *, 1> LastSDM;
|
||||
|
||||
std::unique_ptr<ParentMapPointers> PointerParents;
|
||||
std::unique_ptr<ParentMapOtherNodes> OtherParents;
|
||||
std::vector<Decl *> TraversalScope;
|
||||
class ParentMap;
|
||||
std::unique_ptr<ParentMap> Parents;
|
||||
|
||||
std::unique_ptr<VTableContextBase> VTContext;
|
||||
|
||||
void ReleaseDeclContextMaps();
|
||||
void ReleaseParentMapEntries();
|
||||
|
||||
public:
|
||||
enum PragmaSectionFlag : unsigned {
|
||||
|
|
@ -2949,8 +2970,8 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
|
|||
/// This placement form of operator new uses the ASTContext's allocator for
|
||||
/// obtaining memory.
|
||||
///
|
||||
/// IMPORTANT: These are also declared in clang/AST/AttrIterator.h! Any changes
|
||||
/// here need to also be made there.
|
||||
/// IMPORTANT: These are also declared in clang/AST/ASTContextAllocate.h!
|
||||
/// Any changes here need to also be made there.
|
||||
///
|
||||
/// We intentionally avoid using a nothrow specification here so that the calls
|
||||
/// to this operator will not perform a null check on the result -- the
|
||||
|
|
@ -2973,7 +2994,7 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
|
|||
/// allocator supports it).
|
||||
/// @return The allocated memory. Could be nullptr.
|
||||
inline void *operator new(size_t Bytes, const clang::ASTContext &C,
|
||||
size_t Alignment) {
|
||||
size_t Alignment /* = 8 */) {
|
||||
return C.Allocate(Bytes, Alignment);
|
||||
}
|
||||
|
||||
|
|
@ -3011,7 +3032,7 @@ inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
|
|||
/// allocator supports it).
|
||||
/// @return The allocated memory. Could be nullptr.
|
||||
inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
|
||||
size_t Alignment = 8) {
|
||||
size_t Alignment /* = 8 */) {
|
||||
return C.Allocate(Bytes, Alignment);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
//===- ASTContextAllocate.h - ASTContext allocate functions -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares ASTContext allocation functions separate from the main
|
||||
// code in ASTContext.h.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
|
||||
#define LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
|
||||
} // namespace clang
|
||||
|
||||
// Defined in ASTContext.h
|
||||
void *operator new(size_t Bytes, const clang::ASTContext &C,
|
||||
size_t Alignment = 8);
|
||||
void *operator new[](size_t Bytes, const clang::ASTContext &C,
|
||||
size_t Alignment = 8);
|
||||
|
||||
// It is good practice to pair new/delete operators. Also, MSVC gives many
|
||||
// warnings if a matching delete overload is not declared, even though the
|
||||
// throw() spec guarantees it will not be implicitly called.
|
||||
void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
|
||||
void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
|
||||
|
||||
#endif // LLVM_CLANG_AST_ASTCONTEXTALLOCATE_H
|
||||
|
|
@ -11,19 +11,9 @@
|
|||
#define LLVM_CLANG_AST_ASTDIAGNOSTIC_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/DiagnosticAST.h"
|
||||
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
|
||||
SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
|
||||
#define ASTSTART
|
||||
#include "clang/Basic/DiagnosticASTKinds.inc"
|
||||
#undef DIAG
|
||||
NUM_BUILTIN_AST_DIAGNOSTICS
|
||||
};
|
||||
} // end namespace diag
|
||||
|
||||
/// DiagnosticsEngine argument formatting function for diagnostics that
|
||||
/// involve AST nodes.
|
||||
///
|
||||
|
|
|
|||
97
contrib/llvm/tools/clang/include/clang/AST/ASTDumperUtils.h
Normal file
97
contrib/llvm/tools/clang/include/clang/AST/ASTDumperUtils.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
//===--- ASTDumperUtils.h - Printing of AST nodes -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements AST utilities for traversal down the tree.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ASTDUMPERUTILS_H
|
||||
#define LLVM_CLANG_AST_ASTDUMPERUTILS_H
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
// Colors used for various parts of the AST dump
|
||||
// Do not use bold yellow for any text. It is hard to read on white screens.
|
||||
|
||||
struct TerminalColor {
|
||||
llvm::raw_ostream::Colors Color;
|
||||
bool Bold;
|
||||
};
|
||||
|
||||
// Red - CastColor
|
||||
// Green - TypeColor
|
||||
// Bold Green - DeclKindNameColor, UndeserializedColor
|
||||
// Yellow - AddressColor, LocationColor
|
||||
// Blue - CommentColor, NullColor, IndentColor
|
||||
// Bold Blue - AttrColor
|
||||
// Bold Magenta - StmtColor
|
||||
// Cyan - ValueKindColor, ObjectKindColor
|
||||
// Bold Cyan - ValueColor, DeclNameColor
|
||||
|
||||
// Decl kind names (VarDecl, FunctionDecl, etc)
|
||||
static const TerminalColor DeclKindNameColor = {llvm::raw_ostream::GREEN, true};
|
||||
// Attr names (CleanupAttr, GuardedByAttr, etc)
|
||||
static const TerminalColor AttrColor = {llvm::raw_ostream::BLUE, true};
|
||||
// Statement names (DeclStmt, ImplicitCastExpr, etc)
|
||||
static const TerminalColor StmtColor = {llvm::raw_ostream::MAGENTA, true};
|
||||
// Comment names (FullComment, ParagraphComment, TextComment, etc)
|
||||
static const TerminalColor CommentColor = {llvm::raw_ostream::BLUE, false};
|
||||
|
||||
// Type names (int, float, etc, plus user defined types)
|
||||
static const TerminalColor TypeColor = {llvm::raw_ostream::GREEN, false};
|
||||
|
||||
// Pointer address
|
||||
static const TerminalColor AddressColor = {llvm::raw_ostream::YELLOW, false};
|
||||
// Source locations
|
||||
static const TerminalColor LocationColor = {llvm::raw_ostream::YELLOW, false};
|
||||
|
||||
// lvalue/xvalue
|
||||
static const TerminalColor ValueKindColor = {llvm::raw_ostream::CYAN, false};
|
||||
// bitfield/objcproperty/objcsubscript/vectorcomponent
|
||||
static const TerminalColor ObjectKindColor = {llvm::raw_ostream::CYAN, false};
|
||||
|
||||
// Null statements
|
||||
static const TerminalColor NullColor = {llvm::raw_ostream::BLUE, false};
|
||||
|
||||
// Undeserialized entities
|
||||
static const TerminalColor UndeserializedColor = {llvm::raw_ostream::GREEN,
|
||||
true};
|
||||
|
||||
// CastKind from CastExpr's
|
||||
static const TerminalColor CastColor = {llvm::raw_ostream::RED, false};
|
||||
|
||||
// Value of the statement
|
||||
static const TerminalColor ValueColor = {llvm::raw_ostream::CYAN, true};
|
||||
// Decl names
|
||||
static const TerminalColor DeclNameColor = {llvm::raw_ostream::CYAN, true};
|
||||
|
||||
// Indents ( `, -. | )
|
||||
static const TerminalColor IndentColor = {llvm::raw_ostream::BLUE, false};
|
||||
|
||||
class ColorScope {
|
||||
llvm::raw_ostream &OS;
|
||||
const bool ShowColors;
|
||||
|
||||
public:
|
||||
ColorScope(llvm::raw_ostream &OS, bool ShowColors, TerminalColor Color)
|
||||
: OS(OS), ShowColors(ShowColors) {
|
||||
if (ShowColors)
|
||||
OS.changeColor(Color.Color, Color.Bold);
|
||||
}
|
||||
~ColorScope() {
|
||||
if (ShowColors)
|
||||
OS.resetColor();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_ASTDUMPERUTILS_H
|
||||
|
|
@ -25,12 +25,15 @@
|
|||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class ASTImporterLookupTable;
|
||||
class CXXBaseSpecifier;
|
||||
class CXXCtorInitializer;
|
||||
class Decl;
|
||||
|
|
@ -43,6 +46,29 @@ class TagDecl;
|
|||
class TypeSourceInfo;
|
||||
class Attr;
|
||||
|
||||
class ImportError : public llvm::ErrorInfo<ImportError> {
|
||||
public:
|
||||
/// \brief Kind of error when importing an AST component.
|
||||
enum ErrorKind {
|
||||
NameConflict, /// Naming ambiguity (likely ODR violation).
|
||||
UnsupportedConstruct, /// Not supported node or case.
|
||||
Unknown /// Other error.
|
||||
};
|
||||
|
||||
ErrorKind Error;
|
||||
|
||||
static char ID;
|
||||
|
||||
ImportError() : Error(Unknown) { }
|
||||
ImportError(const ImportError &Other) : Error(Other.Error) { }
|
||||
ImportError(ErrorKind Error) : Error(Error) { }
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
void log(raw_ostream &OS) const override;
|
||||
std::error_code convertToErrorCode() const override;
|
||||
};
|
||||
|
||||
// \brief Returns with a list of declarations started from the canonical decl
|
||||
// then followed by subsequent decls in the translation unit.
|
||||
// This gives a canonical list for each entry in the redecl chain.
|
||||
|
|
@ -55,12 +81,21 @@ class Attr;
|
|||
/// Imports selected nodes from one AST context into another context,
|
||||
/// merging AST nodes where appropriate.
|
||||
class ASTImporter {
|
||||
friend class ASTNodeImporter;
|
||||
public:
|
||||
using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>;
|
||||
using ImportedCXXBaseSpecifierMap =
|
||||
llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>;
|
||||
|
||||
private:
|
||||
|
||||
/// Pointer to the import specific lookup table, which may be shared
|
||||
/// amongst several ASTImporter objects.
|
||||
/// This is an externally managed resource (and should exist during the
|
||||
/// lifetime of the ASTImporter object)
|
||||
/// If not set then the original C/C++ lookup is used.
|
||||
ASTImporterLookupTable *LookupTable = nullptr;
|
||||
|
||||
/// The contexts we're importing to and from.
|
||||
ASTContext &ToContext, &FromContext;
|
||||
|
||||
|
|
@ -98,9 +133,13 @@ class Attr;
|
|||
/// (which we have already complained about).
|
||||
NonEquivalentDeclSet NonEquivalentDecls;
|
||||
|
||||
using FoundDeclsTy = SmallVector<NamedDecl *, 2>;
|
||||
FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);
|
||||
|
||||
void AddToLookupTable(Decl *ToD);
|
||||
|
||||
public:
|
||||
/// Create a new AST importer.
|
||||
///
|
||||
|
||||
/// \param ToContext The context we'll be importing into.
|
||||
///
|
||||
/// \param ToFileManager The file manager we'll be importing into.
|
||||
|
|
@ -112,9 +151,14 @@ class Attr;
|
|||
/// \param MinimalImport If true, the importer will attempt to import
|
||||
/// as little as it can, e.g., by importing declarations as forward
|
||||
/// declarations that can be completed at a later point.
|
||||
///
|
||||
/// \param LookupTable The importer specific lookup table which may be
|
||||
/// shared amongst several ASTImporter objects.
|
||||
/// If not set then the original C/C++ lookup is used.
|
||||
ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
|
||||
ASTContext &FromContext, FileManager &FromFileManager,
|
||||
bool MinimalImport);
|
||||
bool MinimalImport,
|
||||
ASTImporterLookupTable *LookupTable = nullptr);
|
||||
|
||||
virtual ~ASTImporter();
|
||||
|
||||
|
|
@ -122,31 +166,60 @@ class Attr;
|
|||
/// to-be-completed forward declarations when possible.
|
||||
bool isMinimalImport() const { return Minimal; }
|
||||
|
||||
/// Import the given type from the "from" context into the "to"
|
||||
/// context.
|
||||
/// \brief Import the given object, returns the result.
|
||||
///
|
||||
/// \returns the equivalent type in the "to" context, or a NULL type if
|
||||
/// an error occurred.
|
||||
/// \param To Import the object into this variable.
|
||||
/// \param From Object to import.
|
||||
/// \return Error information (success or error).
|
||||
template <typename ImportT>
|
||||
LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) {
|
||||
To = Import(From);
|
||||
if (From && !To)
|
||||
return llvm::make_error<ImportError>();
|
||||
return llvm::Error::success();
|
||||
// FIXME: this should be the final code
|
||||
//auto ToOrErr = Import(From);
|
||||
//if (ToOrErr)
|
||||
// To = *ToOrErr;
|
||||
//return ToOrErr.takeError();
|
||||
}
|
||||
|
||||
/// Import the given type from the "from" context into the "to"
|
||||
/// context. A null type is imported as a null type (no error).
|
||||
///
|
||||
/// \returns The equivalent type in the "to" context, or the import error.
|
||||
llvm::Expected<QualType> Import_New(QualType FromT);
|
||||
// FIXME: Remove this version.
|
||||
QualType Import(QualType FromT);
|
||||
|
||||
/// Import the given type source information from the
|
||||
/// "from" context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent type source information in the "to"
|
||||
/// context, or NULL if an error occurred.
|
||||
/// \returns The equivalent type source information in the "to"
|
||||
/// context, or the import error.
|
||||
llvm::Expected<TypeSourceInfo *> Import_New(TypeSourceInfo *FromTSI);
|
||||
// FIXME: Remove this version.
|
||||
TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
|
||||
|
||||
/// Import the given attribute from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent attribute in the "to" context.
|
||||
/// \returns The equivalent attribute in the "to" context, or the import
|
||||
/// error.
|
||||
llvm::Expected<Attr *> Import_New(const Attr *FromAttr);
|
||||
// FIXME: Remove this version.
|
||||
Attr *Import(const Attr *FromAttr);
|
||||
|
||||
/// Import the given declaration from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent declaration in the "to" context, or a NULL type
|
||||
/// if an error occurred.
|
||||
/// \returns The equivalent declaration in the "to" context, or the import
|
||||
/// error.
|
||||
llvm::Expected<Decl *> Import_New(Decl *FromD);
|
||||
llvm::Expected<Decl *> Import_New(const Decl *FromD) {
|
||||
return Import_New(const_cast<Decl *>(FromD));
|
||||
}
|
||||
// FIXME: Remove this version.
|
||||
Decl *Import(Decl *FromD);
|
||||
Decl *Import(const Decl *FromD) {
|
||||
return Import(const_cast<Decl *>(FromD));
|
||||
|
|
@ -155,104 +228,137 @@ class Attr;
|
|||
/// Return the copy of the given declaration in the "to" context if
|
||||
/// it has already been imported from the "from" context. Otherwise return
|
||||
/// NULL.
|
||||
Decl *GetAlreadyImportedOrNull(Decl *FromD);
|
||||
Decl *GetAlreadyImportedOrNull(const Decl *FromD) const;
|
||||
|
||||
/// Import the given declaration context from the "from"
|
||||
/// AST context into the "to" AST context.
|
||||
///
|
||||
/// \returns the equivalent declaration context in the "to"
|
||||
/// context, or a NULL type if an error occurred.
|
||||
DeclContext *ImportContext(DeclContext *FromDC);
|
||||
/// context, or error value.
|
||||
llvm::Expected<DeclContext *> ImportContext(DeclContext *FromDC);
|
||||
|
||||
/// Import the given expression from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent expression in the "to" context, or NULL if
|
||||
/// an error occurred.
|
||||
/// \returns The equivalent expression in the "to" context, or the import
|
||||
/// error.
|
||||
llvm::Expected<Expr *> Import_New(Expr *FromE);
|
||||
// FIXME: Remove this version.
|
||||
Expr *Import(Expr *FromE);
|
||||
|
||||
/// Import the given statement from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent statement in the "to" context, or NULL if
|
||||
/// an error occurred.
|
||||
/// \returns The equivalent statement in the "to" context, or the import
|
||||
/// error.
|
||||
llvm::Expected<Stmt *> Import_New(Stmt *FromS);
|
||||
// FIXME: Remove this version.
|
||||
Stmt *Import(Stmt *FromS);
|
||||
|
||||
/// Import the given nested-name-specifier from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent nested-name-specifier in the "to"
|
||||
/// context, or NULL if an error occurred.
|
||||
/// \returns The equivalent nested-name-specifier in the "to"
|
||||
/// context, or the import error.
|
||||
llvm::Expected<NestedNameSpecifier *>
|
||||
Import_New(NestedNameSpecifier *FromNNS);
|
||||
// FIXME: Remove this version.
|
||||
NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
|
||||
|
||||
/// Import the given nested-name-specifier from the "from"
|
||||
/// Import the given nested-name-specifier-loc from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent nested-name-specifier in the "to"
|
||||
/// context.
|
||||
/// \returns The equivalent nested-name-specifier-loc in the "to"
|
||||
/// context, or the import error.
|
||||
llvm::Expected<NestedNameSpecifierLoc>
|
||||
Import_New(NestedNameSpecifierLoc FromNNS);
|
||||
// FIXME: Remove this version.
|
||||
NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS);
|
||||
|
||||
/// Import the goven template name from the "from" context into the
|
||||
/// "to" context.
|
||||
/// Import the given template name from the "from" context into the
|
||||
/// "to" context, or the import error.
|
||||
llvm::Expected<TemplateName> Import_New(TemplateName From);
|
||||
// FIXME: Remove this version.
|
||||
TemplateName Import(TemplateName From);
|
||||
|
||||
/// Import the given source location from the "from" context into
|
||||
/// the "to" context.
|
||||
///
|
||||
/// \returns the equivalent source location in the "to" context, or an
|
||||
/// invalid source location if an error occurred.
|
||||
/// \returns The equivalent source location in the "to" context, or the
|
||||
/// import error.
|
||||
llvm::Expected<SourceLocation> Import_New(SourceLocation FromLoc);
|
||||
// FIXME: Remove this version.
|
||||
SourceLocation Import(SourceLocation FromLoc);
|
||||
|
||||
/// Import the given source range from the "from" context into
|
||||
/// the "to" context.
|
||||
///
|
||||
/// \returns the equivalent source range in the "to" context, or an
|
||||
/// invalid source location if an error occurred.
|
||||
/// \returns The equivalent source range in the "to" context, or the import
|
||||
/// error.
|
||||
llvm::Expected<SourceRange> Import_New(SourceRange FromRange);
|
||||
// FIXME: Remove this version.
|
||||
SourceRange Import(SourceRange FromRange);
|
||||
|
||||
/// Import the given declaration name from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent declaration name in the "to" context,
|
||||
/// or an empty declaration name if an error occurred.
|
||||
/// \returns The equivalent declaration name in the "to" context, or the
|
||||
/// import error.
|
||||
llvm::Expected<DeclarationName> Import_New(DeclarationName FromName);
|
||||
// FIXME: Remove this version.
|
||||
DeclarationName Import(DeclarationName FromName);
|
||||
|
||||
/// Import the given identifier from the "from" context
|
||||
/// into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent identifier in the "to" context.
|
||||
/// \returns The equivalent identifier in the "to" context. Note: It
|
||||
/// returns nullptr only if the FromId was nullptr.
|
||||
IdentifierInfo *Import(const IdentifierInfo *FromId);
|
||||
|
||||
/// Import the given Objective-C selector from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent selector in the "to" context.
|
||||
/// \returns The equivalent selector in the "to" context, or the import
|
||||
/// error.
|
||||
llvm::Expected<Selector> Import_New(Selector FromSel);
|
||||
// FIXME: Remove this version.
|
||||
Selector Import(Selector FromSel);
|
||||
|
||||
/// Import the given file ID from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent file ID in the source manager of the "to"
|
||||
/// context.
|
||||
/// \returns The equivalent file ID in the source manager of the "to"
|
||||
/// context, or the import error.
|
||||
llvm::Expected<FileID> Import_New(FileID);
|
||||
// FIXME: Remove this version.
|
||||
FileID Import(FileID);
|
||||
|
||||
/// Import the given C++ constructor initializer from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent initializer in the "to" context.
|
||||
/// \returns The equivalent initializer in the "to" context, or the import
|
||||
/// error.
|
||||
llvm::Expected<CXXCtorInitializer *>
|
||||
Import_New(CXXCtorInitializer *FromInit);
|
||||
// FIXME: Remove this version.
|
||||
CXXCtorInitializer *Import(CXXCtorInitializer *FromInit);
|
||||
|
||||
/// Import the given CXXBaseSpecifier from the "from" context into
|
||||
/// the "to" context.
|
||||
///
|
||||
/// \returns the equivalent CXXBaseSpecifier in the source manager of the
|
||||
/// "to" context.
|
||||
/// \returns The equivalent CXXBaseSpecifier in the source manager of the
|
||||
/// "to" context, or the import error.
|
||||
llvm::Expected<CXXBaseSpecifier *>
|
||||
Import_New(const CXXBaseSpecifier *FromSpec);
|
||||
// FIXME: Remove this version.
|
||||
CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec);
|
||||
|
||||
/// Import the definition of the given declaration, including all of
|
||||
/// the declarations it contains.
|
||||
///
|
||||
/// This routine is intended to be used
|
||||
LLVM_NODISCARD llvm::Error ImportDefinition_New(Decl *From);
|
||||
|
||||
// FIXME: Compatibility function.
|
||||
// Usages of this should be changed to ImportDefinition_New.
|
||||
void ImportDefinition(Decl *From);
|
||||
|
||||
/// Cope with a name conflict when importing a declaration into the
|
||||
|
|
@ -333,6 +439,13 @@ class Attr;
|
|||
/// equivalent.
|
||||
bool IsStructurallyEquivalent(QualType From, QualType To,
|
||||
bool Complain = true);
|
||||
|
||||
/// Determine the index of a field in its parent record.
|
||||
/// F should be a field (or indirect field) declaration.
|
||||
/// \returns The index of the field in its parent context (starting from 0).
|
||||
/// On error `None` is returned (parent context is non-record).
|
||||
static llvm::Optional<unsigned> getFieldIndex(Decl *F);
|
||||
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
//===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- 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 ASTImporterLookupTable class which implements a
|
||||
// lookup procedure for the import mechanism.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
|
||||
#define LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
|
||||
|
||||
#include "clang/AST/DeclBase.h" // lookup_result
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class NamedDecl;
|
||||
class DeclContext;
|
||||
|
||||
// There are certain cases when normal C/C++ lookup (localUncachedLookup)
|
||||
// does not find AST nodes. E.g.:
|
||||
// Example 1:
|
||||
// template <class T>
|
||||
// struct X {
|
||||
// friend void foo(); // this is never found in the DC of the TU.
|
||||
// };
|
||||
// Example 2:
|
||||
// // The fwd decl to Foo is not found in the lookupPtr of the DC of the
|
||||
// // translation unit decl.
|
||||
// // Here we could find the node by doing a traverse throught the list of
|
||||
// // the Decls in the DC, but that would not scale.
|
||||
// struct A { struct Foo *p; };
|
||||
// This is a severe problem because the importer decides if it has to create a
|
||||
// new Decl or not based on the lookup results.
|
||||
// To overcome these cases we need an importer specific lookup table which
|
||||
// holds every node and we are not interested in any C/C++ specific visibility
|
||||
// considerations. Simply, we must know if there is an existing Decl in a
|
||||
// given DC. Once we found it then we can handle any visibility related tasks.
|
||||
class ASTImporterLookupTable {
|
||||
|
||||
// We store a list of declarations for each name.
|
||||
// And we collect these lists for each DeclContext.
|
||||
// We could have a flat map with (DeclContext, Name) tuple as key, but a two
|
||||
// level map seems easier to handle.
|
||||
using DeclList = llvm::SmallSetVector<NamedDecl *, 2>;
|
||||
using NameMap = llvm::SmallDenseMap<DeclarationName, DeclList, 4>;
|
||||
using DCMap = llvm::DenseMap<DeclContext *, NameMap>;
|
||||
|
||||
void add(DeclContext *DC, NamedDecl *ND);
|
||||
void remove(DeclContext *DC, NamedDecl *ND);
|
||||
|
||||
DCMap LookupTable;
|
||||
|
||||
public:
|
||||
ASTImporterLookupTable(TranslationUnitDecl &TU);
|
||||
void add(NamedDecl *ND);
|
||||
void remove(NamedDecl *ND);
|
||||
using LookupResult = DeclList;
|
||||
LookupResult lookup(DeclContext *DC, DeclarationName Name) const;
|
||||
void dump(DeclContext *DC) const;
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_ASTIMPORTERLOOKUPTABLE_H
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
|
||||
#define LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
|
||||
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
|
@ -114,8 +115,19 @@ struct StructuralEquivalenceContext {
|
|||
private:
|
||||
/// Finish checking all of the structural equivalences.
|
||||
///
|
||||
/// \returns true if an error occurred, false otherwise.
|
||||
/// \returns true if the equivalence check failed (non-equivalence detected),
|
||||
/// false if equivalence was detected.
|
||||
bool Finish();
|
||||
|
||||
/// Check for common properties at Finish.
|
||||
/// \returns true if D1 and D2 may be equivalent,
|
||||
/// false if they are for sure not.
|
||||
bool CheckCommonEquivalence(Decl *D1, Decl *D2);
|
||||
|
||||
/// Check for class dependent properties at Finish.
|
||||
/// \returns true if D1 and D2 may be equivalent,
|
||||
/// false if they are for sure not.
|
||||
bool CheckKindSpecificEquivalence(Decl *D1, Decl *D2);
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#ifndef LLVM_CLANG_AST_ASTVECTOR_H
|
||||
#define LLVM_CLANG_AST_ASTVECTOR_H
|
||||
|
||||
#include "clang/AST/ASTContextAllocate.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#ifndef LLVM_CLANG_AST_ATTR_H
|
||||
#define LLVM_CLANG_AST_ATTR_H
|
||||
|
||||
#include "clang/AST/ASTContextAllocate.h" // For Attrs.inc
|
||||
#include "clang/AST/AttrIterator.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
|
|
@ -113,6 +114,19 @@ public:
|
|||
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
|
||||
};
|
||||
|
||||
class TypeAttr : public Attr {
|
||||
protected:
|
||||
TypeAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
|
||||
bool IsLateParsed)
|
||||
: Attr(AK, R, SpellingListIndex, IsLateParsed) {}
|
||||
|
||||
public:
|
||||
static bool classof(const Attr *A) {
|
||||
return A->getKind() >= attr::FirstTypeAttr &&
|
||||
A->getKind() <= attr::LastTypeAttr;
|
||||
}
|
||||
};
|
||||
|
||||
class StmtAttr : public Attr {
|
||||
protected:
|
||||
StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
|
||||
|
|
|
|||
|
|
@ -26,25 +26,6 @@ namespace clang {
|
|||
class ASTContext;
|
||||
class Attr;
|
||||
|
||||
} // namespace clang
|
||||
|
||||
// Defined in ASTContext.h
|
||||
void *operator new(size_t Bytes, const clang::ASTContext &C,
|
||||
size_t Alignment = 8);
|
||||
|
||||
// FIXME: Being forced to not have a default argument here due to redeclaration
|
||||
// rules on default arguments sucks
|
||||
void *operator new[](size_t Bytes, const clang::ASTContext &C,
|
||||
size_t Alignment);
|
||||
|
||||
// It is good practice to pair new/delete operators. Also, MSVC gives many
|
||||
// warnings if a matching delete overload is not declared, even though the
|
||||
// throw() spec guarantees it will not be implicitly called.
|
||||
void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
|
||||
void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// AttrVec - A vector of Attr, which is how they are stored on the AST.
|
||||
using AttrVec = SmallVector<Attr *, 4>;
|
||||
|
||||
|
|
|
|||
76
contrib/llvm/tools/clang/include/clang/AST/AttrVisitor.h
Normal file
76
contrib/llvm/tools/clang/include/clang/AST/AttrVisitor.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
//===- AttrVisitor.h - Visitor for Attr subclasses --------------*- 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 AttrVisitor interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ATTRVISITOR_H
|
||||
#define LLVM_CLANG_AST_ATTRVISITOR_H
|
||||
|
||||
#include "clang/AST/Attr.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace attrvisitor {
|
||||
|
||||
/// A simple visitor class that helps create attribute visitors.
|
||||
template <template <typename> class Ptr, typename ImplClass,
|
||||
typename RetTy = void, class... ParamTys>
|
||||
class Base {
|
||||
public:
|
||||
#define PTR(CLASS) typename Ptr<CLASS>::type
|
||||
#define DISPATCH(NAME) \
|
||||
return static_cast<ImplClass *>(this)->Visit##NAME(static_cast<PTR(NAME)>(A))
|
||||
|
||||
RetTy Visit(PTR(Attr) A) {
|
||||
switch (A->getKind()) {
|
||||
|
||||
#define ATTR(NAME) \
|
||||
case attr::NAME: \
|
||||
DISPATCH(NAME##Attr);
|
||||
#include "clang/Basic/AttrList.inc"
|
||||
}
|
||||
llvm_unreachable("Attr that isn't part of AttrList.inc!");
|
||||
}
|
||||
|
||||
// If the implementation chooses not to implement a certain visit
|
||||
// method, fall back to the parent.
|
||||
#define ATTR(NAME) \
|
||||
RetTy Visit##NAME##Attr(PTR(NAME##Attr) A) { DISPATCH(Attr); }
|
||||
#include "clang/Basic/AttrList.inc"
|
||||
|
||||
RetTy VisitAttr(PTR(Attr)) { return RetTy(); }
|
||||
|
||||
#undef PTR
|
||||
#undef DISPATCH
|
||||
};
|
||||
|
||||
} // namespace attrvisitor
|
||||
|
||||
/// A simple visitor class that helps create attribute visitors.
|
||||
///
|
||||
/// This class does not preserve constness of Attr pointers (see
|
||||
/// also ConstAttrVisitor).
|
||||
template <typename ImplClass, typename RetTy = void, typename... ParamTys>
|
||||
class AttrVisitor : public attrvisitor::Base<std::add_pointer, ImplClass, RetTy,
|
||||
ParamTys...> {};
|
||||
|
||||
/// A simple visitor class that helps create attribute visitors.
|
||||
///
|
||||
/// This class preserves constness of Attr pointers (see also
|
||||
/// AttrVisitor).
|
||||
template <typename ImplClass, typename RetTy = void, typename... ParamTys>
|
||||
class ConstAttrVisitor
|
||||
: public attrvisitor::Base<llvm::make_const_ptr, ImplClass, RetTy,
|
||||
ParamTys...> {};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_ATTRVISITOR_H
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
#define LLVM_CLANG_AST_BASESUBOBJECT_H
|
||||
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <cstdint>
|
||||
|
|
|
|||
|
|
@ -510,7 +510,7 @@ struct CanProxyAdaptor<FunctionProtoType>
|
|||
}
|
||||
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getTypeQuals)
|
||||
|
||||
using param_type_iterator =
|
||||
CanTypeIterator<FunctionProtoType::param_type_iterator>;
|
||||
|
|
|
|||
|
|
@ -215,10 +215,8 @@ public:
|
|||
|
||||
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
|
||||
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
|
||||
|
||||
SourceLocation getLocation() const LLVM_READONLY { return Loc; }
|
||||
|
|
@ -349,8 +347,7 @@ public:
|
|||
}
|
||||
|
||||
SourceRange getCommandNameRange() const {
|
||||
return SourceRange(getLocStart().getLocWithOffset(-1),
|
||||
getLocEnd());
|
||||
return SourceRange(getBeginLoc().getLocWithOffset(-1), getEndLoc());
|
||||
}
|
||||
|
||||
RenderKind getRenderKind() const {
|
||||
|
|
@ -564,9 +561,9 @@ public:
|
|||
|
||||
ParagraphCommentBits.IsWhitespaceValid = false;
|
||||
|
||||
setSourceRange(SourceRange(Content.front()->getLocStart(),
|
||||
Content.back()->getLocEnd()));
|
||||
setLocation(Content.front()->getLocStart());
|
||||
setSourceRange(SourceRange(Content.front()->getBeginLoc(),
|
||||
Content.back()->getEndLoc()));
|
||||
setLocation(Content.front()->getBeginLoc());
|
||||
}
|
||||
|
||||
static bool classof(const Comment *C) {
|
||||
|
|
@ -660,13 +657,13 @@ public:
|
|||
}
|
||||
|
||||
SourceLocation getCommandNameBeginLoc() const {
|
||||
return getLocStart().getLocWithOffset(1);
|
||||
return getBeginLoc().getLocWithOffset(1);
|
||||
}
|
||||
|
||||
SourceRange getCommandNameRange(const CommandTraits &Traits) const {
|
||||
StringRef Name = getCommandName(Traits);
|
||||
return SourceRange(getCommandNameBeginLoc(),
|
||||
getLocStart().getLocWithOffset(1 + Name.size()));
|
||||
getBeginLoc().getLocWithOffset(1 + Name.size()));
|
||||
}
|
||||
|
||||
unsigned getNumArgs() const {
|
||||
|
|
@ -686,7 +683,7 @@ public:
|
|||
if (Args.size() > 0) {
|
||||
SourceLocation NewLocEnd = Args.back().Range.getEnd();
|
||||
if (NewLocEnd.isValid())
|
||||
setSourceRange(SourceRange(getLocStart(), NewLocEnd));
|
||||
setSourceRange(SourceRange(getBeginLoc(), NewLocEnd));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -700,9 +697,9 @@ public:
|
|||
|
||||
void setParagraph(ParagraphComment *PC) {
|
||||
Paragraph = PC;
|
||||
SourceLocation NewLocEnd = PC->getLocEnd();
|
||||
SourceLocation NewLocEnd = PC->getEndLoc();
|
||||
if (NewLocEnd.isValid())
|
||||
setSourceRange(SourceRange(getLocStart(), NewLocEnd));
|
||||
setSourceRange(SourceRange(getBeginLoc(), NewLocEnd));
|
||||
}
|
||||
|
||||
CommandMarkerKind getCommandMarker() const LLVM_READONLY {
|
||||
|
|
@ -976,7 +973,7 @@ public:
|
|||
}
|
||||
|
||||
SourceRange getTextRange() const {
|
||||
return SourceRange(TextBegin, getLocEnd());
|
||||
return SourceRange(TextBegin, getEndLoc());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1103,9 +1100,9 @@ public:
|
|||
if (Blocks.empty())
|
||||
return;
|
||||
|
||||
setSourceRange(SourceRange(Blocks.front()->getLocStart(),
|
||||
Blocks.back()->getLocEnd()));
|
||||
setLocation(Blocks.front()->getLocStart());
|
||||
setSourceRange(
|
||||
SourceRange(Blocks.front()->getBeginLoc(), Blocks.back()->getEndLoc()));
|
||||
setLocation(Blocks.front()->getBeginLoc());
|
||||
}
|
||||
|
||||
static bool classof(const Comment *C) {
|
||||
|
|
|
|||
|
|
@ -10,20 +10,7 @@
|
|||
#ifndef LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
|
||||
#define LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
|
||||
SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
|
||||
#define COMMENTSTART
|
||||
#include "clang/Basic/DiagnosticCommentKinds.inc"
|
||||
#undef DIAG
|
||||
NUM_BUILTIN_COMMENT_DIAGNOSTICS
|
||||
};
|
||||
} // end namespace diag
|
||||
} // end namespace clang
|
||||
#include "clang/Basic/DiagnosticComment.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -11,22 +11,21 @@
|
|||
#define LLVM_CLANG_AST_COMMENTVISITOR_H
|
||||
|
||||
#include "clang/AST/Comment.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace clang {
|
||||
namespace comments {
|
||||
|
||||
template <typename T> struct make_ptr { using type = T *; };
|
||||
template <typename T> struct make_const_ptr { using type = const T *; };
|
||||
|
||||
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
|
||||
template <template <typename> class Ptr, typename ImplClass,
|
||||
typename RetTy = void, class... ParamTys>
|
||||
class CommentVisitorBase {
|
||||
public:
|
||||
#define PTR(CLASS) typename Ptr<CLASS>::type
|
||||
#define DISPATCH(NAME, CLASS) \
|
||||
return static_cast<ImplClass*>(this)->visit ## NAME(static_cast<PTR(CLASS)>(C))
|
||||
#define DISPATCH(NAME, CLASS) \
|
||||
return static_cast<ImplClass *>(this)->visit##NAME( \
|
||||
static_cast<PTR(CLASS)>(C), std::forward<ParamTys>(P)...)
|
||||
|
||||
RetTy visit(PTR(Comment) C) {
|
||||
RetTy visit(PTR(Comment) C, ParamTys... P) {
|
||||
if (!C)
|
||||
return RetTy();
|
||||
|
||||
|
|
@ -44,25 +43,26 @@ public:
|
|||
// If the derived class does not implement a certain Visit* method, fall back
|
||||
// on Visit* method for the superclass.
|
||||
#define ABSTRACT_COMMENT(COMMENT) COMMENT
|
||||
#define COMMENT(CLASS, PARENT) \
|
||||
RetTy visit ## CLASS(PTR(CLASS) C) { DISPATCH(PARENT, PARENT); }
|
||||
#define COMMENT(CLASS, PARENT) \
|
||||
RetTy visit##CLASS(PTR(CLASS) C, ParamTys... P) { DISPATCH(PARENT, PARENT); }
|
||||
#include "clang/AST/CommentNodes.inc"
|
||||
#undef ABSTRACT_COMMENT
|
||||
#undef COMMENT
|
||||
|
||||
RetTy visitComment(PTR(Comment) C) { return RetTy(); }
|
||||
RetTy visitComment(PTR(Comment) C, ParamTys... P) { return RetTy(); }
|
||||
|
||||
#undef PTR
|
||||
#undef DISPATCH
|
||||
};
|
||||
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
class CommentVisitor :
|
||||
public CommentVisitorBase<make_ptr, ImplClass, RetTy> {};
|
||||
template <typename ImplClass, typename RetTy = void, class... ParamTys>
|
||||
class CommentVisitor : public CommentVisitorBase<std::add_pointer, ImplClass,
|
||||
RetTy, ParamTys...> {};
|
||||
|
||||
template<typename ImplClass, typename RetTy=void>
|
||||
class ConstCommentVisitor :
|
||||
public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
|
||||
template <typename ImplClass, typename RetTy = void, class... ParamTys>
|
||||
class ConstCommentVisitor
|
||||
: public CommentVisitorBase<llvm::make_const_ptr, ImplClass, RetTy,
|
||||
ParamTys...> {};
|
||||
|
||||
} // namespace comments
|
||||
} // namespace clang
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "clang/AST/AttrIterator.h"
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
|
|
@ -406,12 +407,10 @@ public:
|
|||
return SourceRange(getLocation(), getLocation());
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY {
|
||||
return getSourceRange().getBegin();
|
||||
}
|
||||
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return getSourceRange().getEnd();
|
||||
}
|
||||
|
|
@ -483,13 +482,7 @@ public:
|
|||
|
||||
const AttrVec &getAttrs() const;
|
||||
void dropAttrs();
|
||||
|
||||
void addAttr(Attr *A) {
|
||||
if (hasAttrs())
|
||||
getAttrs().push_back(A);
|
||||
else
|
||||
setAttrs(AttrVec(1, A));
|
||||
}
|
||||
void addAttr(Attr *A);
|
||||
|
||||
using attr_iterator = AttrVec::const_iterator;
|
||||
using attr_range = llvm::iterator_range<attr_iterator>;
|
||||
|
|
@ -1072,11 +1065,11 @@ public:
|
|||
unsigned OldNS = IdentifierNamespace;
|
||||
assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
|
||||
IDNS_TagFriend | IDNS_OrdinaryFriend |
|
||||
IDNS_LocalExtern)) &&
|
||||
IDNS_LocalExtern | IDNS_NonMemberOperator)) &&
|
||||
"namespace includes neither ordinary nor tag");
|
||||
assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
|
||||
IDNS_TagFriend | IDNS_OrdinaryFriend |
|
||||
IDNS_LocalExtern)) &&
|
||||
IDNS_LocalExtern | IDNS_NonMemberOperator)) &&
|
||||
"namespace includes other than ordinary or tag");
|
||||
|
||||
Decl *Prev = getPreviousDecl();
|
||||
|
|
@ -1089,7 +1082,8 @@ public:
|
|||
IdentifierNamespace |= IDNS_Tag | IDNS_Type;
|
||||
}
|
||||
|
||||
if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) {
|
||||
if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend |
|
||||
IDNS_LocalExtern | IDNS_NonMemberOperator)) {
|
||||
IdentifierNamespace |= IDNS_OrdinaryFriend;
|
||||
if (PerformFriendInjection ||
|
||||
(Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary))
|
||||
|
|
@ -1143,6 +1137,9 @@ public:
|
|||
|
||||
void dump(raw_ostream &Out, bool Deserialize = false) const;
|
||||
|
||||
/// \return Unique reproducible object identifier
|
||||
int64_t getID() const;
|
||||
|
||||
/// Looks through the Decl's underlying type to extract a FunctionType
|
||||
/// when possible. Will return null if the type underlying the Decl does not
|
||||
/// have a FunctionType.
|
||||
|
|
@ -1251,47 +1248,424 @@ public:
|
|||
/// that directly derive from DeclContext are mentioned, not their subclasses):
|
||||
///
|
||||
/// TranslationUnitDecl
|
||||
/// ExternCContext
|
||||
/// NamespaceDecl
|
||||
/// FunctionDecl
|
||||
/// TagDecl
|
||||
/// OMPDeclareReductionDecl
|
||||
/// FunctionDecl
|
||||
/// ObjCMethodDecl
|
||||
/// ObjCContainerDecl
|
||||
/// LinkageSpecDecl
|
||||
/// ExportDecl
|
||||
/// BlockDecl
|
||||
/// OMPDeclareReductionDecl
|
||||
/// CapturedDecl
|
||||
class DeclContext {
|
||||
/// DeclKind - This indicates which class this is.
|
||||
unsigned DeclKind : 8;
|
||||
/// For makeDeclVisibleInContextImpl
|
||||
friend class ASTDeclReader;
|
||||
/// For reconcileExternalVisibleStorage, CreateStoredDeclsMap,
|
||||
/// hasNeedToReconcileExternalVisibleStorage
|
||||
friend class ExternalASTSource;
|
||||
/// For CreateStoredDeclsMap
|
||||
friend class DependentDiagnostic;
|
||||
/// For hasNeedToReconcileExternalVisibleStorage,
|
||||
/// hasLazyLocalLexicalLookups, hasLazyExternalLexicalLookups
|
||||
friend class ASTWriter;
|
||||
|
||||
/// Whether this declaration context also has some external
|
||||
/// storage that contains additional declarations that are lexically
|
||||
/// part of this context.
|
||||
mutable bool ExternalLexicalStorage : 1;
|
||||
// We use uint64_t in the bit-fields below since some bit-fields
|
||||
// cross the unsigned boundary and this breaks the packing.
|
||||
|
||||
/// Whether this declaration context also has some external
|
||||
/// storage that contains additional declarations that are visible
|
||||
/// in this context.
|
||||
mutable bool ExternalVisibleStorage : 1;
|
||||
/// Stores the bits used by DeclContext.
|
||||
/// If modified NumDeclContextBit, the ctor of DeclContext and the accessor
|
||||
/// methods in DeclContext should be updated appropriately.
|
||||
class DeclContextBitfields {
|
||||
friend class DeclContext;
|
||||
/// DeclKind - This indicates which class this is.
|
||||
uint64_t DeclKind : 7;
|
||||
|
||||
/// Whether this declaration context has had external visible
|
||||
/// storage added since the last lookup. In this case, \c LookupPtr's
|
||||
/// invariant may not hold and needs to be fixed before we perform
|
||||
/// another lookup.
|
||||
mutable bool NeedToReconcileExternalVisibleStorage : 1;
|
||||
/// Whether this declaration context also has some external
|
||||
/// storage that contains additional declarations that are lexically
|
||||
/// part of this context.
|
||||
mutable uint64_t ExternalLexicalStorage : 1;
|
||||
|
||||
/// If \c true, this context may have local lexical declarations
|
||||
/// that are missing from the lookup table.
|
||||
mutable bool HasLazyLocalLexicalLookups : 1;
|
||||
/// Whether this declaration context also has some external
|
||||
/// storage that contains additional declarations that are visible
|
||||
/// in this context.
|
||||
mutable uint64_t ExternalVisibleStorage : 1;
|
||||
|
||||
/// If \c true, the external source may have lexical declarations
|
||||
/// that are missing from the lookup table.
|
||||
mutable bool HasLazyExternalLexicalLookups : 1;
|
||||
/// Whether this declaration context has had externally visible
|
||||
/// storage added since the last lookup. In this case, \c LookupPtr's
|
||||
/// invariant may not hold and needs to be fixed before we perform
|
||||
/// another lookup.
|
||||
mutable uint64_t NeedToReconcileExternalVisibleStorage : 1;
|
||||
|
||||
/// If \c true, lookups should only return identifier from
|
||||
/// DeclContext scope (for example TranslationUnit). Used in
|
||||
/// LookupQualifiedName()
|
||||
mutable bool UseQualifiedLookup : 1;
|
||||
/// If \c true, this context may have local lexical declarations
|
||||
/// that are missing from the lookup table.
|
||||
mutable uint64_t HasLazyLocalLexicalLookups : 1;
|
||||
|
||||
/// If \c true, the external source may have lexical declarations
|
||||
/// that are missing from the lookup table.
|
||||
mutable uint64_t HasLazyExternalLexicalLookups : 1;
|
||||
|
||||
/// If \c true, lookups should only return identifier from
|
||||
/// DeclContext scope (for example TranslationUnit). Used in
|
||||
/// LookupQualifiedName()
|
||||
mutable uint64_t UseQualifiedLookup : 1;
|
||||
};
|
||||
|
||||
/// Number of bits in DeclContextBitfields.
|
||||
enum { NumDeclContextBits = 13 };
|
||||
|
||||
/// Stores the bits used by TagDecl.
|
||||
/// If modified NumTagDeclBits and the accessor
|
||||
/// methods in TagDecl should be updated appropriately.
|
||||
class TagDeclBitfields {
|
||||
friend class TagDecl;
|
||||
/// For the bits in DeclContextBitfields
|
||||
uint64_t : NumDeclContextBits;
|
||||
|
||||
/// The TagKind enum.
|
||||
uint64_t TagDeclKind : 3;
|
||||
|
||||
/// True if this is a definition ("struct foo {};"), false if it is a
|
||||
/// declaration ("struct foo;"). It is not considered a definition
|
||||
/// until the definition has been fully processed.
|
||||
uint64_t IsCompleteDefinition : 1;
|
||||
|
||||
/// True if this is currently being defined.
|
||||
uint64_t IsBeingDefined : 1;
|
||||
|
||||
/// True if this tag declaration is "embedded" (i.e., defined or declared
|
||||
/// for the very first time) in the syntax of a declarator.
|
||||
uint64_t IsEmbeddedInDeclarator : 1;
|
||||
|
||||
/// True if this tag is free standing, e.g. "struct foo;".
|
||||
uint64_t IsFreeStanding : 1;
|
||||
|
||||
/// Indicates whether it is possible for declarations of this kind
|
||||
/// to have an out-of-date definition.
|
||||
///
|
||||
/// This option is only enabled when modules are enabled.
|
||||
uint64_t MayHaveOutOfDateDef : 1;
|
||||
|
||||
/// Has the full definition of this type been required by a use somewhere in
|
||||
/// the TU.
|
||||
uint64_t IsCompleteDefinitionRequired : 1;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in TagDeclBitfields.
|
||||
enum { NumTagDeclBits = 9 };
|
||||
|
||||
/// Stores the bits used by EnumDecl.
|
||||
/// If modified NumEnumDeclBit and the accessor
|
||||
/// methods in EnumDecl should be updated appropriately.
|
||||
class EnumDeclBitfields {
|
||||
friend class EnumDecl;
|
||||
/// For the bits in DeclContextBitfields.
|
||||
uint64_t : NumDeclContextBits;
|
||||
/// For the bits in TagDeclBitfields.
|
||||
uint64_t : NumTagDeclBits;
|
||||
|
||||
/// Width in bits required to store all the non-negative
|
||||
/// enumerators of this enum.
|
||||
uint64_t NumPositiveBits : 8;
|
||||
|
||||
/// Width in bits required to store all the negative
|
||||
/// enumerators of this enum.
|
||||
uint64_t NumNegativeBits : 8;
|
||||
|
||||
/// True if this tag declaration is a scoped enumeration. Only
|
||||
/// possible in C++11 mode.
|
||||
uint64_t IsScoped : 1;
|
||||
|
||||
/// If this tag declaration is a scoped enum,
|
||||
/// then this is true if the scoped enum was declared using the class
|
||||
/// tag, false if it was declared with the struct tag. No meaning is
|
||||
/// associated if this tag declaration is not a scoped enum.
|
||||
uint64_t IsScopedUsingClassTag : 1;
|
||||
|
||||
/// True if this is an enumeration with fixed underlying type. Only
|
||||
/// possible in C++11, Microsoft extensions, or Objective C mode.
|
||||
uint64_t IsFixed : 1;
|
||||
|
||||
/// True if a valid hash is stored in ODRHash.
|
||||
uint64_t HasODRHash : 1;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in EnumDeclBitfields.
|
||||
enum { NumEnumDeclBits = 20 };
|
||||
|
||||
/// Stores the bits used by RecordDecl.
|
||||
/// If modified NumRecordDeclBits and the accessor
|
||||
/// methods in RecordDecl should be updated appropriately.
|
||||
class RecordDeclBitfields {
|
||||
friend class RecordDecl;
|
||||
/// For the bits in DeclContextBitfields.
|
||||
uint64_t : NumDeclContextBits;
|
||||
/// For the bits in TagDeclBitfields.
|
||||
uint64_t : NumTagDeclBits;
|
||||
|
||||
/// This is true if this struct ends with a flexible
|
||||
/// array member (e.g. int X[]) or if this union contains a struct that does.
|
||||
/// If so, this cannot be contained in arrays or other structs as a member.
|
||||
uint64_t HasFlexibleArrayMember : 1;
|
||||
|
||||
/// Whether this is the type of an anonymous struct or union.
|
||||
uint64_t AnonymousStructOrUnion : 1;
|
||||
|
||||
/// This is true if this struct has at least one member
|
||||
/// containing an Objective-C object pointer type.
|
||||
uint64_t HasObjectMember : 1;
|
||||
|
||||
/// This is true if struct has at least one member of
|
||||
/// 'volatile' type.
|
||||
uint64_t HasVolatileMember : 1;
|
||||
|
||||
/// Whether the field declarations of this record have been loaded
|
||||
/// from external storage. To avoid unnecessary deserialization of
|
||||
/// methods/nested types we allow deserialization of just the fields
|
||||
/// when needed.
|
||||
mutable uint64_t LoadedFieldsFromExternalStorage : 1;
|
||||
|
||||
/// Basic properties of non-trivial C structs.
|
||||
uint64_t NonTrivialToPrimitiveDefaultInitialize : 1;
|
||||
uint64_t NonTrivialToPrimitiveCopy : 1;
|
||||
uint64_t NonTrivialToPrimitiveDestroy : 1;
|
||||
|
||||
/// Indicates whether this struct is destroyed in the callee.
|
||||
uint64_t ParamDestroyedInCallee : 1;
|
||||
|
||||
/// Represents the way this type is passed to a function.
|
||||
uint64_t ArgPassingRestrictions : 2;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in RecordDeclBitfields.
|
||||
enum { NumRecordDeclBits = 11 };
|
||||
|
||||
/// Stores the bits used by OMPDeclareReductionDecl.
|
||||
/// If modified NumOMPDeclareReductionDeclBits and the accessor
|
||||
/// methods in OMPDeclareReductionDecl should be updated appropriately.
|
||||
class OMPDeclareReductionDeclBitfields {
|
||||
friend class OMPDeclareReductionDecl;
|
||||
/// For the bits in DeclContextBitfields
|
||||
uint64_t : NumDeclContextBits;
|
||||
|
||||
/// Kind of initializer,
|
||||
/// function call or omp_priv<init_expr> initializtion.
|
||||
uint64_t InitializerKind : 2;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in OMPDeclareReductionDeclBitfields.
|
||||
enum { NumOMPDeclareReductionDeclBits = 2 };
|
||||
|
||||
/// Stores the bits used by FunctionDecl.
|
||||
/// If modified NumFunctionDeclBits and the accessor
|
||||
/// methods in FunctionDecl and CXXDeductionGuideDecl
|
||||
/// (for IsCopyDeductionCandidate) should be updated appropriately.
|
||||
class FunctionDeclBitfields {
|
||||
friend class FunctionDecl;
|
||||
/// For IsCopyDeductionCandidate
|
||||
friend class CXXDeductionGuideDecl;
|
||||
/// For the bits in DeclContextBitfields.
|
||||
uint64_t : NumDeclContextBits;
|
||||
|
||||
uint64_t SClass : 3;
|
||||
uint64_t IsInline : 1;
|
||||
uint64_t IsInlineSpecified : 1;
|
||||
|
||||
/// This is shared by CXXConstructorDecl,
|
||||
/// CXXConversionDecl, and CXXDeductionGuideDecl.
|
||||
uint64_t IsExplicitSpecified : 1;
|
||||
|
||||
uint64_t IsVirtualAsWritten : 1;
|
||||
uint64_t IsPure : 1;
|
||||
uint64_t HasInheritedPrototype : 1;
|
||||
uint64_t HasWrittenPrototype : 1;
|
||||
uint64_t IsDeleted : 1;
|
||||
/// Used by CXXMethodDecl
|
||||
uint64_t IsTrivial : 1;
|
||||
|
||||
/// This flag indicates whether this function is trivial for the purpose of
|
||||
/// calls. This is meaningful only when this function is a copy/move
|
||||
/// constructor or a destructor.
|
||||
uint64_t IsTrivialForCall : 1;
|
||||
|
||||
/// Used by CXXMethodDecl
|
||||
uint64_t IsDefaulted : 1;
|
||||
/// Used by CXXMethodDecl
|
||||
uint64_t IsExplicitlyDefaulted : 1;
|
||||
uint64_t HasImplicitReturnZero : 1;
|
||||
uint64_t IsLateTemplateParsed : 1;
|
||||
uint64_t IsConstexpr : 1;
|
||||
uint64_t InstantiationIsPending : 1;
|
||||
|
||||
/// Indicates if the function uses __try.
|
||||
uint64_t UsesSEHTry : 1;
|
||||
|
||||
/// Indicates if the function was a definition
|
||||
/// but its body was skipped.
|
||||
uint64_t HasSkippedBody : 1;
|
||||
|
||||
/// Indicates if the function declaration will
|
||||
/// have a body, once we're done parsing it.
|
||||
uint64_t WillHaveBody : 1;
|
||||
|
||||
/// Indicates that this function is a multiversioned
|
||||
/// function using attribute 'target'.
|
||||
uint64_t IsMultiVersion : 1;
|
||||
|
||||
/// [C++17] Only used by CXXDeductionGuideDecl. Indicates that
|
||||
/// the Deduction Guide is the implicitly generated 'copy
|
||||
/// deduction candidate' (is used during overload resolution).
|
||||
uint64_t IsCopyDeductionCandidate : 1;
|
||||
|
||||
/// Store the ODRHash after first calculation.
|
||||
uint64_t HasODRHash : 1;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in FunctionDeclBitfields.
|
||||
enum { NumFunctionDeclBits = 25 };
|
||||
|
||||
/// Stores the bits used by CXXConstructorDecl. If modified
|
||||
/// NumCXXConstructorDeclBits and the accessor
|
||||
/// methods in CXXConstructorDecl should be updated appropriately.
|
||||
class CXXConstructorDeclBitfields {
|
||||
friend class CXXConstructorDecl;
|
||||
/// For the bits in DeclContextBitfields.
|
||||
uint64_t : NumDeclContextBits;
|
||||
/// For the bits in FunctionDeclBitfields.
|
||||
uint64_t : NumFunctionDeclBits;
|
||||
|
||||
/// 25 bits to fit in the remaining availible space.
|
||||
/// Note that this makes CXXConstructorDeclBitfields take
|
||||
/// exactly 64 bits and thus the width of NumCtorInitializers
|
||||
/// will need to be shrunk if some bit is added to NumDeclContextBitfields,
|
||||
/// NumFunctionDeclBitfields or CXXConstructorDeclBitfields.
|
||||
uint64_t NumCtorInitializers : 25;
|
||||
uint64_t IsInheritingConstructor : 1;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in CXXConstructorDeclBitfields.
|
||||
enum { NumCXXConstructorDeclBits = 26 };
|
||||
|
||||
/// Stores the bits used by ObjCMethodDecl.
|
||||
/// If modified NumObjCMethodDeclBits and the accessor
|
||||
/// methods in ObjCMethodDecl should be updated appropriately.
|
||||
class ObjCMethodDeclBitfields {
|
||||
friend class ObjCMethodDecl;
|
||||
|
||||
/// For the bits in DeclContextBitfields.
|
||||
uint64_t : NumDeclContextBits;
|
||||
|
||||
/// The conventional meaning of this method; an ObjCMethodFamily.
|
||||
/// This is not serialized; instead, it is computed on demand and
|
||||
/// cached.
|
||||
mutable uint64_t Family : ObjCMethodFamilyBitWidth;
|
||||
|
||||
/// instance (true) or class (false) method.
|
||||
uint64_t IsInstance : 1;
|
||||
uint64_t IsVariadic : 1;
|
||||
|
||||
/// True if this method is the getter or setter for an explicit property.
|
||||
uint64_t IsPropertyAccessor : 1;
|
||||
|
||||
/// Method has a definition.
|
||||
uint64_t IsDefined : 1;
|
||||
|
||||
/// Method redeclaration in the same interface.
|
||||
uint64_t IsRedeclaration : 1;
|
||||
|
||||
/// Is redeclared in the same interface.
|
||||
mutable uint64_t HasRedeclaration : 1;
|
||||
|
||||
/// \@required/\@optional
|
||||
uint64_t DeclImplementation : 2;
|
||||
|
||||
/// in, inout, etc.
|
||||
uint64_t objcDeclQualifier : 7;
|
||||
|
||||
/// Indicates whether this method has a related result type.
|
||||
uint64_t RelatedResultType : 1;
|
||||
|
||||
/// Whether the locations of the selector identifiers are in a
|
||||
/// "standard" position, a enum SelectorLocationsKind.
|
||||
uint64_t SelLocsKind : 2;
|
||||
|
||||
/// Whether this method overrides any other in the class hierarchy.
|
||||
///
|
||||
/// A method is said to override any method in the class's
|
||||
/// base classes, its protocols, or its categories' protocols, that has
|
||||
/// the same selector and is of the same kind (class or instance).
|
||||
/// A method in an implementation is not considered as overriding the same
|
||||
/// method in the interface or its categories.
|
||||
uint64_t IsOverriding : 1;
|
||||
|
||||
/// Indicates if the method was a definition but its body was skipped.
|
||||
uint64_t HasSkippedBody : 1;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in ObjCMethodDeclBitfields.
|
||||
enum { NumObjCMethodDeclBits = 24 };
|
||||
|
||||
/// Stores the bits used by ObjCContainerDecl.
|
||||
/// If modified NumObjCContainerDeclBits and the accessor
|
||||
/// methods in ObjCContainerDecl should be updated appropriately.
|
||||
class ObjCContainerDeclBitfields {
|
||||
friend class ObjCContainerDecl;
|
||||
/// For the bits in DeclContextBitfields
|
||||
uint32_t : NumDeclContextBits;
|
||||
|
||||
// Not a bitfield but this saves space.
|
||||
// Note that ObjCContainerDeclBitfields is full.
|
||||
SourceLocation AtStart;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in ObjCContainerDeclBitfields.
|
||||
/// Note that here we rely on the fact that SourceLocation is 32 bits
|
||||
/// wide. We check this with the static_assert in the ctor of DeclContext.
|
||||
enum { NumObjCContainerDeclBits = 64 - NumDeclContextBits };
|
||||
|
||||
/// Stores the bits used by LinkageSpecDecl.
|
||||
/// If modified NumLinkageSpecDeclBits and the accessor
|
||||
/// methods in LinkageSpecDecl should be updated appropriately.
|
||||
class LinkageSpecDeclBitfields {
|
||||
friend class LinkageSpecDecl;
|
||||
/// For the bits in DeclContextBitfields.
|
||||
uint64_t : NumDeclContextBits;
|
||||
|
||||
/// The language for this linkage specification with values
|
||||
/// in the enum LinkageSpecDecl::LanguageIDs.
|
||||
uint64_t Language : 3;
|
||||
|
||||
/// True if this linkage spec has braces.
|
||||
/// This is needed so that hasBraces() returns the correct result while the
|
||||
/// linkage spec body is being parsed. Once RBraceLoc has been set this is
|
||||
/// not used, so it doesn't need to be serialized.
|
||||
uint64_t HasBraces : 1;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in LinkageSpecDeclBitfields.
|
||||
enum { NumLinkageSpecDeclBits = 4 };
|
||||
|
||||
/// Stores the bits used by BlockDecl.
|
||||
/// If modified NumBlockDeclBits and the accessor
|
||||
/// methods in BlockDecl should be updated appropriately.
|
||||
class BlockDeclBitfields {
|
||||
friend class BlockDecl;
|
||||
/// For the bits in DeclContextBitfields.
|
||||
uint64_t : NumDeclContextBits;
|
||||
|
||||
uint64_t IsVariadic : 1;
|
||||
uint64_t CapturesCXXThis : 1;
|
||||
uint64_t BlockMissingReturnType : 1;
|
||||
uint64_t IsConversionFromLambda : 1;
|
||||
|
||||
/// A bit that indicates this block is passed directly to a function as a
|
||||
/// non-escaping parameter.
|
||||
uint64_t DoesNotEscape : 1;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in BlockDeclBitfields.
|
||||
enum { NumBlockDeclBits = 5 };
|
||||
|
||||
/// Pointer to the data structure used to lookup declarations
|
||||
/// within this context (or a DependentStoredDeclsMap if this is a
|
||||
|
|
@ -1302,9 +1676,50 @@ class DeclContext {
|
|||
mutable StoredDeclsMap *LookupPtr = nullptr;
|
||||
|
||||
protected:
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTWriter;
|
||||
friend class ExternalASTSource;
|
||||
/// This anonymous union stores the bits belonging to DeclContext and classes
|
||||
/// deriving from it. The goal is to use otherwise wasted
|
||||
/// space in DeclContext to store data belonging to derived classes.
|
||||
/// The space saved is especially significient when pointers are aligned
|
||||
/// to 8 bytes. In this case due to alignment requirements we have a
|
||||
/// little less than 8 bytes free in DeclContext which we can use.
|
||||
/// We check that none of the classes in this union is larger than
|
||||
/// 8 bytes with static_asserts in the ctor of DeclContext.
|
||||
union {
|
||||
DeclContextBitfields DeclContextBits;
|
||||
TagDeclBitfields TagDeclBits;
|
||||
EnumDeclBitfields EnumDeclBits;
|
||||
RecordDeclBitfields RecordDeclBits;
|
||||
OMPDeclareReductionDeclBitfields OMPDeclareReductionDeclBits;
|
||||
FunctionDeclBitfields FunctionDeclBits;
|
||||
CXXConstructorDeclBitfields CXXConstructorDeclBits;
|
||||
ObjCMethodDeclBitfields ObjCMethodDeclBits;
|
||||
ObjCContainerDeclBitfields ObjCContainerDeclBits;
|
||||
LinkageSpecDeclBitfields LinkageSpecDeclBits;
|
||||
BlockDeclBitfields BlockDeclBits;
|
||||
|
||||
static_assert(sizeof(DeclContextBitfields) <= 8,
|
||||
"DeclContextBitfields is larger than 8 bytes!");
|
||||
static_assert(sizeof(TagDeclBitfields) <= 8,
|
||||
"TagDeclBitfields is larger than 8 bytes!");
|
||||
static_assert(sizeof(EnumDeclBitfields) <= 8,
|
||||
"EnumDeclBitfields is larger than 8 bytes!");
|
||||
static_assert(sizeof(RecordDeclBitfields) <= 8,
|
||||
"RecordDeclBitfields is larger than 8 bytes!");
|
||||
static_assert(sizeof(OMPDeclareReductionDeclBitfields) <= 8,
|
||||
"OMPDeclareReductionDeclBitfields is larger than 8 bytes!");
|
||||
static_assert(sizeof(FunctionDeclBitfields) <= 8,
|
||||
"FunctionDeclBitfields is larger than 8 bytes!");
|
||||
static_assert(sizeof(CXXConstructorDeclBitfields) <= 8,
|
||||
"CXXConstructorDeclBitfields is larger than 8 bytes!");
|
||||
static_assert(sizeof(ObjCMethodDeclBitfields) <= 8,
|
||||
"ObjCMethodDeclBitfields is larger than 8 bytes!");
|
||||
static_assert(sizeof(ObjCContainerDeclBitfields) <= 8,
|
||||
"ObjCContainerDeclBitfields is larger than 8 bytes!");
|
||||
static_assert(sizeof(LinkageSpecDeclBitfields) <= 8,
|
||||
"LinkageSpecDeclBitfields is larger than 8 bytes!");
|
||||
static_assert(sizeof(BlockDeclBitfields) <= 8,
|
||||
"BlockDeclBitfields is larger than 8 bytes!");
|
||||
};
|
||||
|
||||
/// FirstDecl - The first declaration stored within this declaration
|
||||
/// context.
|
||||
|
|
@ -1322,18 +1737,13 @@ protected:
|
|||
static std::pair<Decl *, Decl *>
|
||||
BuildDeclChain(ArrayRef<Decl*> Decls, bool FieldsAlreadyLoaded);
|
||||
|
||||
DeclContext(Decl::Kind K)
|
||||
: DeclKind(K), ExternalLexicalStorage(false),
|
||||
ExternalVisibleStorage(false),
|
||||
NeedToReconcileExternalVisibleStorage(false),
|
||||
HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false),
|
||||
UseQualifiedLookup(false) {}
|
||||
DeclContext(Decl::Kind K);
|
||||
|
||||
public:
|
||||
~DeclContext();
|
||||
|
||||
Decl::Kind getDeclKind() const {
|
||||
return static_cast<Decl::Kind>(DeclKind);
|
||||
return static_cast<Decl::Kind>(DeclContextBits.DeclKind);
|
||||
}
|
||||
|
||||
const char *getDeclKindName() const;
|
||||
|
|
@ -1372,54 +1782,54 @@ public:
|
|||
return cast<Decl>(this)->getASTContext();
|
||||
}
|
||||
|
||||
bool isClosure() const {
|
||||
return DeclKind == Decl::Block;
|
||||
}
|
||||
bool isClosure() const { return getDeclKind() == Decl::Block; }
|
||||
|
||||
bool isObjCContainer() const {
|
||||
switch (DeclKind) {
|
||||
case Decl::ObjCCategory:
|
||||
case Decl::ObjCCategoryImpl:
|
||||
case Decl::ObjCImplementation:
|
||||
case Decl::ObjCInterface:
|
||||
case Decl::ObjCProtocol:
|
||||
return true;
|
||||
switch (getDeclKind()) {
|
||||
case Decl::ObjCCategory:
|
||||
case Decl::ObjCCategoryImpl:
|
||||
case Decl::ObjCImplementation:
|
||||
case Decl::ObjCInterface:
|
||||
case Decl::ObjCProtocol:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isFunctionOrMethod() const {
|
||||
switch (DeclKind) {
|
||||
switch (getDeclKind()) {
|
||||
case Decl::Block:
|
||||
case Decl::Captured:
|
||||
case Decl::ObjCMethod:
|
||||
return true;
|
||||
default:
|
||||
return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction;
|
||||
return getDeclKind() >= Decl::firstFunction &&
|
||||
getDeclKind() <= Decl::lastFunction;
|
||||
}
|
||||
}
|
||||
|
||||
/// Test whether the context supports looking up names.
|
||||
bool isLookupContext() const {
|
||||
return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec &&
|
||||
DeclKind != Decl::Export;
|
||||
return !isFunctionOrMethod() && getDeclKind() != Decl::LinkageSpec &&
|
||||
getDeclKind() != Decl::Export;
|
||||
}
|
||||
|
||||
bool isFileContext() const {
|
||||
return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
|
||||
return getDeclKind() == Decl::TranslationUnit ||
|
||||
getDeclKind() == Decl::Namespace;
|
||||
}
|
||||
|
||||
bool isTranslationUnit() const {
|
||||
return DeclKind == Decl::TranslationUnit;
|
||||
return getDeclKind() == Decl::TranslationUnit;
|
||||
}
|
||||
|
||||
bool isRecord() const {
|
||||
return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord;
|
||||
return getDeclKind() >= Decl::firstRecord &&
|
||||
getDeclKind() <= Decl::lastRecord;
|
||||
}
|
||||
|
||||
bool isNamespace() const {
|
||||
return DeclKind == Decl::Namespace;
|
||||
}
|
||||
bool isNamespace() const { return getDeclKind() == Decl::Namespace; }
|
||||
|
||||
bool isStdNamespace() const;
|
||||
|
||||
|
|
@ -1887,7 +2297,7 @@ public:
|
|||
void setMustBuildLookupTable() {
|
||||
assert(this == getPrimaryContext() &&
|
||||
"should only be called on primary context");
|
||||
HasLazyExternalLexicalLookups = true;
|
||||
DeclContextBits.HasLazyExternalLexicalLookups = true;
|
||||
}
|
||||
|
||||
/// Retrieve the internal representation of the lookup structure.
|
||||
|
|
@ -1899,24 +2309,28 @@ public:
|
|||
|
||||
/// Whether this DeclContext has external storage containing
|
||||
/// additional declarations that are lexically in this context.
|
||||
bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; }
|
||||
bool hasExternalLexicalStorage() const {
|
||||
return DeclContextBits.ExternalLexicalStorage;
|
||||
}
|
||||
|
||||
/// State whether this DeclContext has external storage for
|
||||
/// declarations lexically in this context.
|
||||
void setHasExternalLexicalStorage(bool ES = true) {
|
||||
ExternalLexicalStorage = ES;
|
||||
void setHasExternalLexicalStorage(bool ES = true) const {
|
||||
DeclContextBits.ExternalLexicalStorage = ES;
|
||||
}
|
||||
|
||||
/// Whether this DeclContext has external storage containing
|
||||
/// additional declarations that are visible in this context.
|
||||
bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; }
|
||||
bool hasExternalVisibleStorage() const {
|
||||
return DeclContextBits.ExternalVisibleStorage;
|
||||
}
|
||||
|
||||
/// State whether this DeclContext has external storage for
|
||||
/// declarations visible in this context.
|
||||
void setHasExternalVisibleStorage(bool ES = true) {
|
||||
ExternalVisibleStorage = ES;
|
||||
void setHasExternalVisibleStorage(bool ES = true) const {
|
||||
DeclContextBits.ExternalVisibleStorage = ES;
|
||||
if (ES && LookupPtr)
|
||||
NeedToReconcileExternalVisibleStorage = true;
|
||||
DeclContextBits.NeedToReconcileExternalVisibleStorage = true;
|
||||
}
|
||||
|
||||
/// Determine whether the given declaration is stored in the list of
|
||||
|
|
@ -1926,14 +2340,14 @@ public:
|
|||
D == LastDecl);
|
||||
}
|
||||
|
||||
bool setUseQualifiedLookup(bool use = true) {
|
||||
bool old_value = UseQualifiedLookup;
|
||||
UseQualifiedLookup = use;
|
||||
bool setUseQualifiedLookup(bool use = true) const {
|
||||
bool old_value = DeclContextBits.UseQualifiedLookup;
|
||||
DeclContextBits.UseQualifiedLookup = use;
|
||||
return old_value;
|
||||
}
|
||||
|
||||
bool shouldUseQualifiedLookup() const {
|
||||
return UseQualifiedLookup;
|
||||
return DeclContextBits.UseQualifiedLookup;
|
||||
}
|
||||
|
||||
static bool classof(const Decl *D);
|
||||
|
|
@ -1945,7 +2359,45 @@ public:
|
|||
bool Deserialize = false) const;
|
||||
|
||||
private:
|
||||
friend class DependentDiagnostic;
|
||||
/// Whether this declaration context has had externally visible
|
||||
/// storage added since the last lookup. In this case, \c LookupPtr's
|
||||
/// invariant may not hold and needs to be fixed before we perform
|
||||
/// another lookup.
|
||||
bool hasNeedToReconcileExternalVisibleStorage() const {
|
||||
return DeclContextBits.NeedToReconcileExternalVisibleStorage;
|
||||
}
|
||||
|
||||
/// State that this declaration context has had externally visible
|
||||
/// storage added since the last lookup. In this case, \c LookupPtr's
|
||||
/// invariant may not hold and needs to be fixed before we perform
|
||||
/// another lookup.
|
||||
void setNeedToReconcileExternalVisibleStorage(bool Need = true) const {
|
||||
DeclContextBits.NeedToReconcileExternalVisibleStorage = Need;
|
||||
}
|
||||
|
||||
/// If \c true, this context may have local lexical declarations
|
||||
/// that are missing from the lookup table.
|
||||
bool hasLazyLocalLexicalLookups() const {
|
||||
return DeclContextBits.HasLazyLocalLexicalLookups;
|
||||
}
|
||||
|
||||
/// If \c true, this context may have local lexical declarations
|
||||
/// that are missing from the lookup table.
|
||||
void setHasLazyLocalLexicalLookups(bool HasLLLL = true) const {
|
||||
DeclContextBits.HasLazyLocalLexicalLookups = HasLLLL;
|
||||
}
|
||||
|
||||
/// If \c true, the external source may have lexical declarations
|
||||
/// that are missing from the lookup table.
|
||||
bool hasLazyExternalLexicalLookups() const {
|
||||
return DeclContextBits.HasLazyExternalLexicalLookups;
|
||||
}
|
||||
|
||||
/// If \c true, the external source may have lexical declarations
|
||||
/// that are missing from the lookup table.
|
||||
void setHasLazyExternalLexicalLookups(bool HasLELL = true) const {
|
||||
DeclContextBits.HasLazyExternalLexicalLookups = HasLELL;
|
||||
}
|
||||
|
||||
void reconcileExternalVisibleStorage() const;
|
||||
bool LoadLexicalDeclsFromExternalStorage() const;
|
||||
|
|
|
|||
|
|
@ -233,14 +233,12 @@ public:
|
|||
|
||||
/// Retrieves the source range that contains the entire base specifier.
|
||||
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
|
||||
|
||||
/// Get the location at which the base class type was written.
|
||||
SourceLocation getBaseTypeLoc() const LLVM_READONLY {
|
||||
return BaseTypeInfo->getTypeLoc().getLocStart();
|
||||
return BaseTypeInfo->getTypeLoc().getBeginLoc();
|
||||
}
|
||||
|
||||
/// Determines whether the base class is a virtual base class (or not).
|
||||
|
|
@ -976,10 +974,7 @@ public:
|
|||
bool needsImplicitDefaultConstructor() const {
|
||||
return !data().UserDeclaredConstructor &&
|
||||
!(data().DeclaredSpecialMembers & SMF_DefaultConstructor) &&
|
||||
// C++14 [expr.prim.lambda]p20:
|
||||
// The closure type associated with a lambda-expression has no
|
||||
// default constructor.
|
||||
!isLambda();
|
||||
(!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
|
||||
}
|
||||
|
||||
/// Determine whether this class has any user-declared constructors.
|
||||
|
|
@ -1169,10 +1164,7 @@ public:
|
|||
!hasUserDeclaredCopyAssignment() &&
|
||||
!hasUserDeclaredMoveConstructor() &&
|
||||
!hasUserDeclaredDestructor() &&
|
||||
// C++1z [expr.prim.lambda]p21: "the closure type has a deleted copy
|
||||
// assignment operator". The intent is that this counts as a user
|
||||
// declared copy assignment, but we do not model it that way.
|
||||
!isLambda();
|
||||
(!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
|
||||
}
|
||||
|
||||
/// Determine whether we need to eagerly declare a move assignment
|
||||
|
|
@ -1212,6 +1204,10 @@ public:
|
|||
/// a template).
|
||||
bool isGenericLambda() const;
|
||||
|
||||
/// Determine whether this lambda should have an implicit default constructor
|
||||
/// and copy and move assignment operators.
|
||||
bool lambdaIsDefaultConstructibleAndAssignable() const;
|
||||
|
||||
/// Retrieve the lambda call operator of the closure type
|
||||
/// if this is a closure type.
|
||||
CXXMethodDecl *getLambdaCallOperator() const;
|
||||
|
|
@ -1545,7 +1541,7 @@ public:
|
|||
///
|
||||
/// C++11 [class]p6:
|
||||
/// "A trivial class is a class that has a trivial default constructor and
|
||||
/// is trivially copiable."
|
||||
/// is trivially copyable."
|
||||
bool isTrivial() const {
|
||||
return isTriviallyCopyable() && hasTrivialDefaultConstructor();
|
||||
}
|
||||
|
|
@ -2001,7 +1997,8 @@ private:
|
|||
SC_None, false, false) {
|
||||
if (EndLocation.isValid())
|
||||
setRangeEnd(EndLocation);
|
||||
IsExplicitSpecified = IsExplicit;
|
||||
setExplicitSpecified(IsExplicit);
|
||||
setIsCopyDeductionCandidate(false);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -2017,21 +2014,20 @@ public:
|
|||
static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
/// Whether this deduction guide is explicit.
|
||||
bool isExplicit() const { return IsExplicitSpecified; }
|
||||
|
||||
/// Whether this deduction guide was declared with the 'explicit' specifier.
|
||||
bool isExplicitSpecified() const { return IsExplicitSpecified; }
|
||||
bool isExplicit() const { return isExplicitSpecified(); }
|
||||
|
||||
/// Get the template for which this guide performs deduction.
|
||||
TemplateDecl *getDeducedTemplate() const {
|
||||
return getDeclName().getCXXDeductionGuideTemplate();
|
||||
}
|
||||
|
||||
void setIsCopyDeductionCandidate() {
|
||||
IsCopyDeductionCandidate = true;
|
||||
void setIsCopyDeductionCandidate(bool isCDC = true) {
|
||||
FunctionDeclBits.IsCopyDeductionCandidate = isCDC;
|
||||
}
|
||||
|
||||
bool isCopyDeductionCandidate() const { return IsCopyDeductionCandidate; }
|
||||
bool isCopyDeductionCandidate() const {
|
||||
return FunctionDeclBits.IsCopyDeductionCandidate;
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
|
|
@ -2111,10 +2107,15 @@ public:
|
|||
Base, IsAppleKext);
|
||||
}
|
||||
|
||||
/// Determine whether this is a usual deallocation function
|
||||
/// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
|
||||
/// delete or delete[] operator with a particular signature.
|
||||
bool isUsualDeallocationFunction() const;
|
||||
/// Determine whether this is a usual deallocation function (C++
|
||||
/// [basic.stc.dynamic.deallocation]p2), which is an overloaded delete or
|
||||
/// delete[] operator with a particular signature. Populates \p PreventedBy
|
||||
/// with the declarations of the functions of the same kind if they were the
|
||||
/// reason for this function returning false. This is used by
|
||||
/// Sema::isUsualDeallocationFunction to reconsider the answer based on the
|
||||
/// context.
|
||||
bool isUsualDeallocationFunction(
|
||||
SmallVectorImpl<const FunctionDecl *> &PreventedBy) const;
|
||||
|
||||
/// Determine whether this is a copy-assignment operator, regardless
|
||||
/// of whether it was declared implicitly or explicitly.
|
||||
|
|
@ -2179,9 +2180,12 @@ public:
|
|||
/// that for the call operator of a lambda closure type, this returns the
|
||||
/// desugared 'this' type (a pointer to the closure type), not the captured
|
||||
/// 'this' type.
|
||||
QualType getThisType(ASTContext &C) const;
|
||||
QualType getThisType() const;
|
||||
|
||||
unsigned getTypeQualifiers() const {
|
||||
static QualType getThisType(const FunctionProtoType *FPT,
|
||||
const CXXRecordDecl *Decl);
|
||||
|
||||
Qualifiers getTypeQualifiers() const {
|
||||
return getType()->getAs<FunctionProtoType>()->getTypeQuals();
|
||||
}
|
||||
|
||||
|
|
@ -2314,6 +2318,9 @@ public:
|
|||
CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
|
||||
SourceLocation L, Expr *Init, SourceLocation R);
|
||||
|
||||
/// \return Unique reproducible object identifier.
|
||||
int64_t getID(const ASTContext &Context) const;
|
||||
|
||||
/// Determine whether this initializer is initializing a base class.
|
||||
bool isBaseInitializer() const {
|
||||
return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
|
||||
|
|
@ -2477,31 +2484,20 @@ public:
|
|||
class CXXConstructorDecl final
|
||||
: public CXXMethodDecl,
|
||||
private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor> {
|
||||
// This class stores some data in DeclContext::CXXConstructorDeclBits
|
||||
// to save some space. Use the provided accessors to access it.
|
||||
|
||||
/// \name Support for base and member initializers.
|
||||
/// \{
|
||||
/// The arguments used to initialize the base or member.
|
||||
LazyCXXCtorInitializersPtr CtorInitializers;
|
||||
unsigned NumCtorInitializers : 31;
|
||||
/// \}
|
||||
|
||||
/// Whether this constructor declaration is an implicitly-declared
|
||||
/// inheriting constructor.
|
||||
unsigned IsInheritingConstructor : 1;
|
||||
|
||||
CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
|
||||
const DeclarationNameInfo &NameInfo,
|
||||
QualType T, TypeSourceInfo *TInfo,
|
||||
bool isExplicitSpecified, bool isInline,
|
||||
bool isImplicitlyDeclared, bool isConstexpr,
|
||||
InheritedConstructor Inherited)
|
||||
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
|
||||
SC_None, isInline, isConstexpr, SourceLocation()),
|
||||
NumCtorInitializers(0), IsInheritingConstructor((bool)Inherited) {
|
||||
setImplicit(isImplicitlyDeclared);
|
||||
if (Inherited)
|
||||
*getTrailingObjects<InheritedConstructor>() = Inherited;
|
||||
IsExplicitSpecified = isExplicitSpecified;
|
||||
}
|
||||
InheritedConstructor Inherited);
|
||||
|
||||
void anchor() override;
|
||||
|
||||
|
|
@ -2544,12 +2540,12 @@ public:
|
|||
|
||||
/// Retrieve an iterator past the last initializer.
|
||||
init_iterator init_end() {
|
||||
return init_begin() + NumCtorInitializers;
|
||||
return init_begin() + getNumCtorInitializers();
|
||||
}
|
||||
|
||||
/// Retrieve an iterator past the last initializer.
|
||||
init_const_iterator init_end() const {
|
||||
return init_begin() + NumCtorInitializers;
|
||||
return init_begin() + getNumCtorInitializers();
|
||||
}
|
||||
|
||||
using init_reverse_iterator = std::reverse_iterator<init_iterator>;
|
||||
|
|
@ -2573,20 +2569,22 @@ public:
|
|||
/// Determine the number of arguments used to initialize the member
|
||||
/// or base.
|
||||
unsigned getNumCtorInitializers() const {
|
||||
return NumCtorInitializers;
|
||||
return CXXConstructorDeclBits.NumCtorInitializers;
|
||||
}
|
||||
|
||||
void setNumCtorInitializers(unsigned numCtorInitializers) {
|
||||
NumCtorInitializers = numCtorInitializers;
|
||||
CXXConstructorDeclBits.NumCtorInitializers = numCtorInitializers;
|
||||
// This assert added because NumCtorInitializers is stored
|
||||
// in CXXConstructorDeclBits as a bitfield and its width has
|
||||
// been shrunk from 32 bits to fit into CXXConstructorDeclBitfields.
|
||||
assert(CXXConstructorDeclBits.NumCtorInitializers ==
|
||||
numCtorInitializers && "NumCtorInitializers overflow!");
|
||||
}
|
||||
|
||||
void setCtorInitializers(CXXCtorInitializer **Initializers) {
|
||||
CtorInitializers = Initializers;
|
||||
}
|
||||
|
||||
/// Whether this function is marked as explicit explicitly.
|
||||
bool isExplicitSpecified() const { return IsExplicitSpecified; }
|
||||
|
||||
/// Whether this function is explicit.
|
||||
bool isExplicit() const {
|
||||
return getCanonicalDecl()->isExplicitSpecified();
|
||||
|
|
@ -2667,12 +2665,20 @@ public:
|
|||
|
||||
/// Determine whether this is an implicit constructor synthesized to
|
||||
/// model a call to a constructor inherited from a base class.
|
||||
bool isInheritingConstructor() const { return IsInheritingConstructor; }
|
||||
bool isInheritingConstructor() const {
|
||||
return CXXConstructorDeclBits.IsInheritingConstructor;
|
||||
}
|
||||
|
||||
/// State that this is an implicit constructor synthesized to
|
||||
/// model a call to a constructor inherited from a base class.
|
||||
void setInheritingConstructor(bool isIC = true) {
|
||||
CXXConstructorDeclBits.IsInheritingConstructor = isIC;
|
||||
}
|
||||
|
||||
/// Get the constructor that this inheriting constructor is based on.
|
||||
InheritedConstructor getInheritedConstructor() const {
|
||||
return IsInheritingConstructor ? *getTrailingObjects<InheritedConstructor>()
|
||||
: InheritedConstructor();
|
||||
return isInheritingConstructor() ?
|
||||
*getTrailingObjects<InheritedConstructor>() : InheritedConstructor();
|
||||
}
|
||||
|
||||
CXXConstructorDecl *getCanonicalDecl() override {
|
||||
|
|
@ -2767,7 +2773,7 @@ class CXXConversionDecl : public CXXMethodDecl {
|
|||
SourceLocation EndLocation)
|
||||
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
|
||||
SC_None, isInline, isConstexpr, EndLocation) {
|
||||
IsExplicitSpecified = isExplicitSpecified;
|
||||
setExplicitSpecified(isExplicitSpecified);
|
||||
}
|
||||
|
||||
void anchor() override;
|
||||
|
|
@ -2785,9 +2791,6 @@ public:
|
|||
SourceLocation EndLocation);
|
||||
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
/// Whether this function is marked as explicit explicitly.
|
||||
bool isExplicitSpecified() const { return IsExplicitSpecified; }
|
||||
|
||||
/// Whether this function is explicit.
|
||||
bool isExplicit() const {
|
||||
return getCanonicalDecl()->isExplicitSpecified();
|
||||
|
|
@ -2822,7 +2825,8 @@ public:
|
|||
/// \endcode
|
||||
class LinkageSpecDecl : public Decl, public DeclContext {
|
||||
virtual void anchor();
|
||||
|
||||
// This class stores some data in DeclContext::LinkageSpecDeclBits to save
|
||||
// some space. Use the provided accessors to access it.
|
||||
public:
|
||||
/// Represents the language in a linkage specification.
|
||||
///
|
||||
|
|
@ -2836,16 +2840,6 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
/// The language for this linkage specification.
|
||||
unsigned Language : 3;
|
||||
|
||||
/// True if this linkage spec has braces.
|
||||
///
|
||||
/// This is needed so that hasBraces() returns the correct result while the
|
||||
/// linkage spec body is being parsed. Once RBraceLoc has been set this is
|
||||
/// not used, so it doesn't need to be serialized.
|
||||
unsigned HasBraces : 1;
|
||||
|
||||
/// The source location for the extern keyword.
|
||||
SourceLocation ExternLoc;
|
||||
|
||||
|
|
@ -2853,10 +2847,7 @@ private:
|
|||
SourceLocation RBraceLoc;
|
||||
|
||||
LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
|
||||
SourceLocation LangLoc, LanguageIDs lang, bool HasBraces)
|
||||
: Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
|
||||
Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc),
|
||||
RBraceLoc(SourceLocation()) {}
|
||||
SourceLocation LangLoc, LanguageIDs lang, bool HasBraces);
|
||||
|
||||
public:
|
||||
static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
|
|
@ -2866,16 +2857,18 @@ public:
|
|||
static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
/// Return the language specified by this linkage specification.
|
||||
LanguageIDs getLanguage() const { return LanguageIDs(Language); }
|
||||
LanguageIDs getLanguage() const {
|
||||
return static_cast<LanguageIDs>(LinkageSpecDeclBits.Language);
|
||||
}
|
||||
|
||||
/// Set the language specified by this linkage specification.
|
||||
void setLanguage(LanguageIDs L) { Language = L; }
|
||||
void setLanguage(LanguageIDs L) { LinkageSpecDeclBits.Language = L; }
|
||||
|
||||
/// Determines whether this linkage specification had braces in
|
||||
/// its syntactic form.
|
||||
bool hasBraces() const {
|
||||
assert(!RBraceLoc.isValid() || HasBraces);
|
||||
return HasBraces;
|
||||
assert(!RBraceLoc.isValid() || LinkageSpecDeclBits.HasBraces);
|
||||
return LinkageSpecDeclBits.HasBraces;
|
||||
}
|
||||
|
||||
SourceLocation getExternLoc() const { return ExternLoc; }
|
||||
|
|
@ -2883,20 +2876,19 @@ public:
|
|||
void setExternLoc(SourceLocation L) { ExternLoc = L; }
|
||||
void setRBraceLoc(SourceLocation L) {
|
||||
RBraceLoc = L;
|
||||
HasBraces = RBraceLoc.isValid();
|
||||
LinkageSpecDeclBits.HasBraces = RBraceLoc.isValid();
|
||||
}
|
||||
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
if (hasBraces())
|
||||
return getRBraceLoc();
|
||||
// No braces: get the end location of the (only) declaration in context
|
||||
// (if present).
|
||||
return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
|
||||
return decls_empty() ? getLocation() : decls_begin()->getEndLoc();
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
return SourceRange(ExternLoc, getLocEnd());
|
||||
return SourceRange(ExternLoc, getEndLoc());
|
||||
}
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
|
|
@ -3701,7 +3693,7 @@ class UnresolvedUsingTypenameDecl
|
|||
|
||||
public:
|
||||
/// Returns the source location of the 'using' keyword.
|
||||
SourceLocation getUsingLoc() const { return getLocStart(); }
|
||||
SourceLocation getUsingLoc() const { return getBeginLoc(); }
|
||||
|
||||
/// Returns the source location of the 'typename' keyword.
|
||||
SourceLocation getTypenameLoc() const { return TypenameLocation; }
|
||||
|
|
@ -3926,6 +3918,7 @@ class MSPropertyDecl : public DeclaratorDecl {
|
|||
: DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
|
||||
GetterId(Getter), SetterId(Setter) {}
|
||||
|
||||
void anchor() override;
|
||||
public:
|
||||
friend class ASTDeclReader;
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ public:
|
|||
if (DD->getOuterLocStart() != DD->getInnerLocStart())
|
||||
return DD->getSourceRange();
|
||||
}
|
||||
return SourceRange(getFriendLoc(), ND->getLocEnd());
|
||||
return SourceRange(getFriendLoc(), ND->getEndLoc());
|
||||
}
|
||||
else if (TypeSourceInfo *TInfo = getFriendType()) {
|
||||
SourceLocation StartL =
|
||||
|
|
|
|||
|
|
@ -137,62 +137,17 @@ public:
|
|||
/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
|
||||
///
|
||||
class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
// This class stores some data in DeclContext::ObjCMethodDeclBits
|
||||
// to save some space. Use the provided accessors to access it.
|
||||
|
||||
public:
|
||||
enum ImplementationControl { None, Required, Optional };
|
||||
|
||||
private:
|
||||
// The conventional meaning of this method; an ObjCMethodFamily.
|
||||
// This is not serialized; instead, it is computed on demand and
|
||||
// cached.
|
||||
mutable unsigned Family : ObjCMethodFamilyBitWidth;
|
||||
|
||||
/// instance (true) or class (false) method.
|
||||
unsigned IsInstance : 1;
|
||||
unsigned IsVariadic : 1;
|
||||
|
||||
/// True if this method is the getter or setter for an explicit property.
|
||||
unsigned IsPropertyAccessor : 1;
|
||||
|
||||
// Method has a definition.
|
||||
unsigned IsDefined : 1;
|
||||
|
||||
/// Method redeclaration in the same interface.
|
||||
unsigned IsRedeclaration : 1;
|
||||
|
||||
/// Is redeclared in the same interface.
|
||||
mutable unsigned HasRedeclaration : 1;
|
||||
|
||||
// NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
|
||||
/// \@required/\@optional
|
||||
unsigned DeclImplementation : 2;
|
||||
|
||||
// NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
|
||||
/// in, inout, etc.
|
||||
unsigned objcDeclQualifier : 7;
|
||||
|
||||
/// Indicates whether this method has a related result type.
|
||||
unsigned RelatedResultType : 1;
|
||||
|
||||
/// Whether the locations of the selector identifiers are in a
|
||||
/// "standard" position, a enum SelectorLocationsKind.
|
||||
unsigned SelLocsKind : 2;
|
||||
|
||||
/// Whether this method overrides any other in the class hierarchy.
|
||||
///
|
||||
/// A method is said to override any method in the class's
|
||||
/// base classes, its protocols, or its categories' protocols, that has
|
||||
/// the same selector and is of the same kind (class or instance).
|
||||
/// A method in an implementation is not considered as overriding the same
|
||||
/// method in the interface or its categories.
|
||||
unsigned IsOverriding : 1;
|
||||
|
||||
/// Indicates if the method was a definition but its body was skipped.
|
||||
unsigned HasSkippedBody : 1;
|
||||
|
||||
// Return type of this method.
|
||||
/// Return type of this method.
|
||||
QualType MethodDeclType;
|
||||
|
||||
// Type source information for the return type.
|
||||
/// Type source information for the return type.
|
||||
TypeSourceInfo *ReturnTInfo;
|
||||
|
||||
/// Array of ParmVarDecls for the formal parameters of this method
|
||||
|
|
@ -203,7 +158,7 @@ private:
|
|||
/// List of attributes for this method declaration.
|
||||
SourceLocation DeclEndLoc; // the location of the ';' or '{'.
|
||||
|
||||
// The following are only used for method definitions, null otherwise.
|
||||
/// The following are only used for method definitions, null otherwise.
|
||||
LazyDeclStmtPtr Body;
|
||||
|
||||
/// SelfDecl - Decl for the implicit self parameter. This is lazily
|
||||
|
|
@ -220,21 +175,14 @@ private:
|
|||
bool isVariadic = false, bool isPropertyAccessor = false,
|
||||
bool isImplicitlyDeclared = false, bool isDefined = false,
|
||||
ImplementationControl impControl = None,
|
||||
bool HasRelatedResultType = false)
|
||||
: NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
|
||||
DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
|
||||
IsInstance(isInstance), IsVariadic(isVariadic),
|
||||
IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined),
|
||||
IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl),
|
||||
objcDeclQualifier(OBJC_TQ_None),
|
||||
RelatedResultType(HasRelatedResultType),
|
||||
SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
|
||||
MethodDeclType(T), ReturnTInfo(ReturnTInfo), DeclEndLoc(endLoc) {
|
||||
setImplicit(isImplicitlyDeclared);
|
||||
}
|
||||
bool HasRelatedResultType = false);
|
||||
|
||||
SelectorLocationsKind getSelLocsKind() const {
|
||||
return (SelectorLocationsKind)SelLocsKind;
|
||||
return static_cast<SelectorLocationsKind>(ObjCMethodDeclBits.SelLocsKind);
|
||||
}
|
||||
|
||||
void setSelLocsKind(SelectorLocationsKind Kind) {
|
||||
ObjCMethodDeclBits.SelLocsKind = Kind;
|
||||
}
|
||||
|
||||
bool hasStandardSelLocs() const {
|
||||
|
|
@ -244,10 +192,10 @@ private:
|
|||
/// Get a pointer to the stored selector identifiers locations array.
|
||||
/// No locations will be stored if HasStandardSelLocs is true.
|
||||
SourceLocation *getStoredSelLocs() {
|
||||
return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
|
||||
return reinterpret_cast<SourceLocation *>(getParams() + NumParams);
|
||||
}
|
||||
const SourceLocation *getStoredSelLocs() const {
|
||||
return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
|
||||
return reinterpret_cast<const SourceLocation *>(getParams() + NumParams);
|
||||
}
|
||||
|
||||
/// Get a pointer to the stored selector identifiers locations array.
|
||||
|
|
@ -297,38 +245,50 @@ public:
|
|||
}
|
||||
|
||||
ObjCDeclQualifier getObjCDeclQualifier() const {
|
||||
return ObjCDeclQualifier(objcDeclQualifier);
|
||||
return static_cast<ObjCDeclQualifier>(ObjCMethodDeclBits.objcDeclQualifier);
|
||||
}
|
||||
|
||||
void setObjCDeclQualifier(ObjCDeclQualifier QV) {
|
||||
ObjCMethodDeclBits.objcDeclQualifier = QV;
|
||||
}
|
||||
void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
|
||||
|
||||
/// Determine whether this method has a result type that is related
|
||||
/// to the message receiver's type.
|
||||
bool hasRelatedResultType() const { return RelatedResultType; }
|
||||
bool hasRelatedResultType() const {
|
||||
return ObjCMethodDeclBits.RelatedResultType;
|
||||
}
|
||||
|
||||
/// Note whether this method has a related result type.
|
||||
void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
|
||||
void setRelatedResultType(bool RRT = true) {
|
||||
ObjCMethodDeclBits.RelatedResultType = RRT;
|
||||
}
|
||||
|
||||
/// True if this is a method redeclaration in the same interface.
|
||||
bool isRedeclaration() const { return IsRedeclaration; }
|
||||
bool isRedeclaration() const { return ObjCMethodDeclBits.IsRedeclaration; }
|
||||
void setIsRedeclaration(bool RD) { ObjCMethodDeclBits.IsRedeclaration = RD; }
|
||||
void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
|
||||
|
||||
/// True if redeclared in the same interface.
|
||||
bool hasRedeclaration() const { return ObjCMethodDeclBits.HasRedeclaration; }
|
||||
void setHasRedeclaration(bool HRD) const {
|
||||
ObjCMethodDeclBits.HasRedeclaration = HRD;
|
||||
}
|
||||
|
||||
/// Returns the location where the declarator ends. It will be
|
||||
/// the location of ';' for a method declaration and the location of '{'
|
||||
/// for a method definition.
|
||||
SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
|
||||
|
||||
// Location information, modeled after the Stmt API.
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return getLocation(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY;
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
return SourceRange(getLocation(), getLocEnd());
|
||||
return SourceRange(getLocation(), getEndLoc());
|
||||
}
|
||||
|
||||
SourceLocation getSelectorStartLoc() const {
|
||||
if (isImplicit())
|
||||
return getLocStart();
|
||||
return getBeginLoc();
|
||||
return getSelectorLoc(0);
|
||||
}
|
||||
|
||||
|
|
@ -409,6 +369,14 @@ public:
|
|||
NumParams);
|
||||
}
|
||||
|
||||
ParmVarDecl *getParamDecl(unsigned Idx) {
|
||||
assert(Idx < NumParams && "Index out of bounds!");
|
||||
return getParams()[Idx];
|
||||
}
|
||||
const ParmVarDecl *getParamDecl(unsigned Idx) const {
|
||||
return const_cast<ObjCMethodDecl *>(this)->getParamDecl(Idx);
|
||||
}
|
||||
|
||||
/// Sets the method's parameters and selector source locations.
|
||||
/// If the method is implicit (not coming from source) \p SelLocs is
|
||||
/// ignored.
|
||||
|
|
@ -451,18 +419,26 @@ public:
|
|||
/// Determines the family of this method.
|
||||
ObjCMethodFamily getMethodFamily() const;
|
||||
|
||||
bool isInstanceMethod() const { return IsInstance; }
|
||||
void setInstanceMethod(bool isInst) { IsInstance = isInst; }
|
||||
bool isVariadic() const { return IsVariadic; }
|
||||
void setVariadic(bool isVar) { IsVariadic = isVar; }
|
||||
bool isInstanceMethod() const { return ObjCMethodDeclBits.IsInstance; }
|
||||
void setInstanceMethod(bool isInst) {
|
||||
ObjCMethodDeclBits.IsInstance = isInst;
|
||||
}
|
||||
|
||||
bool isClassMethod() const { return !IsInstance; }
|
||||
bool isVariadic() const { return ObjCMethodDeclBits.IsVariadic; }
|
||||
void setVariadic(bool isVar) { ObjCMethodDeclBits.IsVariadic = isVar; }
|
||||
|
||||
bool isPropertyAccessor() const { return IsPropertyAccessor; }
|
||||
void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; }
|
||||
bool isClassMethod() const { return !isInstanceMethod(); }
|
||||
|
||||
bool isDefined() const { return IsDefined; }
|
||||
void setDefined(bool isDefined) { IsDefined = isDefined; }
|
||||
bool isPropertyAccessor() const {
|
||||
return ObjCMethodDeclBits.IsPropertyAccessor;
|
||||
}
|
||||
|
||||
void setPropertyAccessor(bool isAccessor) {
|
||||
ObjCMethodDeclBits.IsPropertyAccessor = isAccessor;
|
||||
}
|
||||
|
||||
bool isDefined() const { return ObjCMethodDeclBits.IsDefined; }
|
||||
void setDefined(bool isDefined) { ObjCMethodDeclBits.IsDefined = isDefined; }
|
||||
|
||||
/// Whether this method overrides any other in the class hierarchy.
|
||||
///
|
||||
|
|
@ -471,8 +447,8 @@ public:
|
|||
/// the same selector and is of the same kind (class or instance).
|
||||
/// A method in an implementation is not considered as overriding the same
|
||||
/// method in the interface or its categories.
|
||||
bool isOverriding() const { return IsOverriding; }
|
||||
void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
|
||||
bool isOverriding() const { return ObjCMethodDeclBits.IsOverriding; }
|
||||
void setOverriding(bool IsOver) { ObjCMethodDeclBits.IsOverriding = IsOver; }
|
||||
|
||||
/// Return overridden methods for the given \p Method.
|
||||
///
|
||||
|
|
@ -486,8 +462,10 @@ public:
|
|||
SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
|
||||
|
||||
/// True if the method was a definition but its body was skipped.
|
||||
bool hasSkippedBody() const { return HasSkippedBody; }
|
||||
void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
|
||||
bool hasSkippedBody() const { return ObjCMethodDeclBits.HasSkippedBody; }
|
||||
void setHasSkippedBody(bool Skipped = true) {
|
||||
ObjCMethodDeclBits.HasSkippedBody = Skipped;
|
||||
}
|
||||
|
||||
/// Returns the property associated with this method's selector.
|
||||
///
|
||||
|
|
@ -498,11 +476,11 @@ public:
|
|||
|
||||
// Related to protocols declared in \@protocol
|
||||
void setDeclImplementation(ImplementationControl ic) {
|
||||
DeclImplementation = ic;
|
||||
ObjCMethodDeclBits.DeclImplementation = ic;
|
||||
}
|
||||
|
||||
ImplementationControl getImplementationControl() const {
|
||||
return ImplementationControl(DeclImplementation);
|
||||
return ImplementationControl(ObjCMethodDeclBits.DeclImplementation);
|
||||
}
|
||||
|
||||
bool isOptional() const {
|
||||
|
|
@ -536,6 +514,9 @@ public:
|
|||
/// Returns whether this specific method is a definition.
|
||||
bool isThisDeclarationADefinition() const { return hasBody(); }
|
||||
|
||||
/// Is this method defined in the NSObject base class?
|
||||
bool definedInNSObject(const ASTContext &) const;
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == ObjCMethod; }
|
||||
|
|
@ -986,7 +967,8 @@ public:
|
|||
/// ObjCProtocolDecl, and ObjCImplDecl.
|
||||
///
|
||||
class ObjCContainerDecl : public NamedDecl, public DeclContext {
|
||||
SourceLocation AtStart;
|
||||
// This class stores some data in DeclContext::ObjCContainerDeclBits
|
||||
// to save some space. Use the provided accessors to access it.
|
||||
|
||||
// These two locations in the range mark the end of the method container.
|
||||
// The first points to the '@' token, and the second to the 'end' token.
|
||||
|
|
@ -995,10 +977,8 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
|
|||
void anchor() override;
|
||||
|
||||
public:
|
||||
ObjCContainerDecl(Kind DK, DeclContext *DC,
|
||||
IdentifierInfo *Id, SourceLocation nameLoc,
|
||||
SourceLocation atStartLoc)
|
||||
: NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
|
||||
ObjCContainerDecl(Kind DK, DeclContext *DC, IdentifierInfo *Id,
|
||||
SourceLocation nameLoc, SourceLocation atStartLoc);
|
||||
|
||||
// Iterator access to instance/class properties.
|
||||
using prop_iterator = specific_decl_iterator<ObjCPropertyDecl>;
|
||||
|
|
@ -1132,20 +1112,19 @@ public:
|
|||
virtual void collectPropertiesToImplement(PropertyMap &PM,
|
||||
PropertyDeclOrder &PO) const {}
|
||||
|
||||
SourceLocation getAtStartLoc() const { return AtStart; }
|
||||
void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
|
||||
SourceLocation getAtStartLoc() const { return ObjCContainerDeclBits.AtStart; }
|
||||
|
||||
void setAtStartLoc(SourceLocation Loc) {
|
||||
ObjCContainerDeclBits.AtStart = Loc;
|
||||
}
|
||||
|
||||
// Marks the end of the container.
|
||||
SourceRange getAtEndRange() const {
|
||||
return AtEnd;
|
||||
}
|
||||
SourceRange getAtEndRange() const { return AtEnd; }
|
||||
|
||||
void setAtEndRange(SourceRange atEnd) {
|
||||
AtEnd = atEnd;
|
||||
}
|
||||
void setAtEndRange(SourceRange atEnd) { AtEnd = atEnd; }
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
return SourceRange(AtStart, getAtEndRange().getEnd());
|
||||
return SourceRange(getAtStartLoc(), getAtEndRange().getEnd());
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
|
|
@ -2833,7 +2812,6 @@ public:
|
|||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY;
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
|
||||
void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/OpenMPClause.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/TrailingObjects.h"
|
||||
|
|
@ -100,6 +101,8 @@ public:
|
|||
///
|
||||
/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
|
||||
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
|
||||
// This class stores some data in DeclContext::OMPDeclareReductionDeclBits
|
||||
// to save some space. Use the provided accessors to access it.
|
||||
public:
|
||||
enum InitKind {
|
||||
CallInit, // Initialized by function call.
|
||||
|
|
@ -110,11 +113,17 @@ public:
|
|||
private:
|
||||
friend class ASTDeclReader;
|
||||
/// Combiner for declare reduction construct.
|
||||
Expr *Combiner;
|
||||
Expr *Combiner = nullptr;
|
||||
/// Initializer for declare reduction construct.
|
||||
Expr *Initializer;
|
||||
/// Kind of initializer - function call or omp_priv<init_expr> initializtion.
|
||||
InitKind InitializerKind = CallInit;
|
||||
Expr *Initializer = nullptr;
|
||||
/// In parameter of the combiner.
|
||||
Expr *In = nullptr;
|
||||
/// Out parameter of the combiner.
|
||||
Expr *Out = nullptr;
|
||||
/// Priv parameter of the initializer.
|
||||
Expr *Priv = nullptr;
|
||||
/// Orig parameter of the initializer.
|
||||
Expr *Orig = nullptr;
|
||||
|
||||
/// Reference to the previous declare reduction construct in the same
|
||||
/// scope with the same name. Required for proper templates instantiation if
|
||||
|
|
@ -125,10 +134,7 @@ private:
|
|||
|
||||
OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
||||
DeclarationName Name, QualType Ty,
|
||||
OMPDeclareReductionDecl *PrevDeclInScope)
|
||||
: ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
|
||||
Initializer(nullptr), InitializerKind(CallInit),
|
||||
PrevDeclInScope(PrevDeclInScope) {}
|
||||
OMPDeclareReductionDecl *PrevDeclInScope);
|
||||
|
||||
void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
|
||||
PrevDeclInScope = Prev;
|
||||
|
|
@ -146,19 +152,43 @@ public:
|
|||
/// Get combiner expression of the declare reduction construct.
|
||||
Expr *getCombiner() { return Combiner; }
|
||||
const Expr *getCombiner() const { return Combiner; }
|
||||
/// Get In variable of the combiner.
|
||||
Expr *getCombinerIn() { return In; }
|
||||
const Expr *getCombinerIn() const { return In; }
|
||||
/// Get Out variable of the combiner.
|
||||
Expr *getCombinerOut() { return Out; }
|
||||
const Expr *getCombinerOut() const { return Out; }
|
||||
/// Set combiner expression for the declare reduction construct.
|
||||
void setCombiner(Expr *E) { Combiner = E; }
|
||||
/// Set combiner In and Out vars.
|
||||
void setCombinerData(Expr *InE, Expr *OutE) {
|
||||
In = InE;
|
||||
Out = OutE;
|
||||
}
|
||||
|
||||
/// Get initializer expression (if specified) of the declare reduction
|
||||
/// construct.
|
||||
Expr *getInitializer() { return Initializer; }
|
||||
const Expr *getInitializer() const { return Initializer; }
|
||||
/// Get initializer kind.
|
||||
InitKind getInitializerKind() const { return InitializerKind; }
|
||||
InitKind getInitializerKind() const {
|
||||
return static_cast<InitKind>(OMPDeclareReductionDeclBits.InitializerKind);
|
||||
}
|
||||
/// Get Orig variable of the initializer.
|
||||
Expr *getInitOrig() { return Orig; }
|
||||
const Expr *getInitOrig() const { return Orig; }
|
||||
/// Get Priv variable of the initializer.
|
||||
Expr *getInitPriv() { return Priv; }
|
||||
const Expr *getInitPriv() const { return Priv; }
|
||||
/// Set initializer expression for the declare reduction construct.
|
||||
void setInitializer(Expr *E, InitKind IK) {
|
||||
Initializer = E;
|
||||
InitializerKind = IK;
|
||||
OMPDeclareReductionDeclBits.InitializerKind = IK;
|
||||
}
|
||||
/// Set initializer Orig and Priv vars.
|
||||
void setInitializerData(Expr *OrigE, Expr *PrivE) {
|
||||
Orig = OrigE;
|
||||
Priv = PrivE;
|
||||
}
|
||||
|
||||
/// Get reference to previous declare reduction construct in the same
|
||||
|
|
@ -210,6 +240,76 @@ public:
|
|||
static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
|
||||
};
|
||||
|
||||
/// This represents '#pragma omp requires...' directive.
|
||||
/// For example
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp requires unified_address
|
||||
/// \endcode
|
||||
///
|
||||
class OMPRequiresDecl final
|
||||
: public Decl,
|
||||
private llvm::TrailingObjects<OMPRequiresDecl, OMPClause *> {
|
||||
friend class ASTDeclReader;
|
||||
friend TrailingObjects;
|
||||
|
||||
// Number of clauses associated with this requires declaration
|
||||
unsigned NumClauses = 0;
|
||||
|
||||
virtual void anchor();
|
||||
|
||||
OMPRequiresDecl(Kind DK, DeclContext *DC, SourceLocation L)
|
||||
: Decl(DK, DC, L), NumClauses(0) {}
|
||||
|
||||
/// Returns an array of immutable clauses associated with this requires
|
||||
/// declaration
|
||||
ArrayRef<const OMPClause *> getClauses() const {
|
||||
return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
|
||||
}
|
||||
|
||||
/// Returns an array of clauses associated with this requires declaration
|
||||
MutableArrayRef<OMPClause *> getClauses() {
|
||||
return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
|
||||
NumClauses);
|
||||
}
|
||||
|
||||
/// Sets an array of clauses to this requires declaration
|
||||
void setClauses(ArrayRef<OMPClause *> CL);
|
||||
|
||||
public:
|
||||
/// Create requires node.
|
||||
static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L, ArrayRef<OMPClause *> CL);
|
||||
/// Create deserialized requires node.
|
||||
static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID,
|
||||
unsigned N);
|
||||
|
||||
using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
|
||||
using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
|
||||
using clauselist_range = llvm::iterator_range<clauselist_iterator>;
|
||||
using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
|
||||
|
||||
unsigned clauselist_size() const { return NumClauses; }
|
||||
bool clauselist_empty() const { return NumClauses == 0; }
|
||||
|
||||
clauselist_range clauselists() {
|
||||
return clauselist_range(clauselist_begin(), clauselist_end());
|
||||
}
|
||||
clauselist_const_range clauselists() const {
|
||||
return clauselist_const_range(clauselist_begin(), clauselist_end());
|
||||
}
|
||||
clauselist_iterator clauselist_begin() { return getClauses().begin(); }
|
||||
clauselist_iterator clauselist_end() { return getClauses().end(); }
|
||||
clauselist_const_iterator clauselist_begin() const {
|
||||
return getClauses().begin();
|
||||
}
|
||||
clauselist_const_iterator clauselist_end() const {
|
||||
return getClauses().end();
|
||||
}
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == OMPRequires; }
|
||||
};
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -751,6 +751,7 @@ class RedeclarableTemplateDecl : public TemplateDecl,
|
|||
return getMostRecentDecl();
|
||||
}
|
||||
|
||||
void anchor() override;
|
||||
protected:
|
||||
template <typename EntryType> struct SpecEntryTraits {
|
||||
using DeclType = EntryType;
|
||||
|
|
@ -1093,6 +1094,9 @@ public:
|
|||
/// template.
|
||||
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
|
||||
|
||||
/// Merge \p Prev with our RedeclarableTemplateDecl::Common.
|
||||
void mergePrevDecl(FunctionTemplateDecl *Prev);
|
||||
|
||||
/// Create a function template node.
|
||||
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
|
|
|
|||
|
|
@ -21,15 +21,12 @@
|
|||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclOpenMP.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace declvisitor {
|
||||
|
||||
template <typename T> struct make_ptr { using type = T *; };
|
||||
template <typename T> struct make_const_ptr { using type = const T *; };
|
||||
|
||||
/// A simple visitor class that helps create declaration visitors.
|
||||
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
|
||||
class Base {
|
||||
|
|
@ -66,16 +63,16 @@ public:
|
|||
///
|
||||
/// This class does not preserve constness of Decl pointers (see also
|
||||
/// ConstDeclVisitor).
|
||||
template<typename ImplClass, typename RetTy = void>
|
||||
template <typename ImplClass, typename RetTy = void>
|
||||
class DeclVisitor
|
||||
: public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {};
|
||||
: public declvisitor::Base<std::add_pointer, ImplClass, RetTy> {};
|
||||
|
||||
/// A simple visitor class that helps create declaration visitors.
|
||||
///
|
||||
/// This class preserves constness of Decl pointers (see also DeclVisitor).
|
||||
template<typename ImplClass, typename RetTy = void>
|
||||
template <typename ImplClass, typename RetTy = void>
|
||||
class ConstDeclVisitor
|
||||
: public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {};
|
||||
: public declvisitor::Base<llvm::make_const_ptr, ImplClass, RetTy> {};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
|
|
|
|||
|
|
@ -14,11 +14,14 @@
|
|||
#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
|
||||
#define LLVM_CLANG_AST_DECLARATIONNAME_H
|
||||
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "clang/Basic/OperatorKinds.h"
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <cassert>
|
||||
|
|
@ -30,67 +33,195 @@ namespace clang {
|
|||
|
||||
class ASTContext;
|
||||
template <typename> class CanQual;
|
||||
class CXXDeductionGuideNameExtra;
|
||||
class CXXLiteralOperatorIdName;
|
||||
class CXXOperatorIdName;
|
||||
class CXXSpecialName;
|
||||
class DeclarationNameExtra;
|
||||
class IdentifierInfo;
|
||||
class DeclarationName;
|
||||
class DeclarationNameTable;
|
||||
class MultiKeywordSelector;
|
||||
enum OverloadedOperatorKind : int;
|
||||
struct PrintingPolicy;
|
||||
class QualType;
|
||||
class TemplateDecl;
|
||||
class Type;
|
||||
class TypeSourceInfo;
|
||||
class UsingDirectiveDecl;
|
||||
|
||||
using CanQualType = CanQual<Type>;
|
||||
|
||||
/// DeclarationName - The name of a declaration. In the common case,
|
||||
/// this just stores an IdentifierInfo pointer to a normal
|
||||
/// name. However, it also provides encodings for Objective-C
|
||||
/// selectors (optimizing zero- and one-argument selectors, which make
|
||||
/// up 78% percent of all selectors in Cocoa.h) and special C++ names
|
||||
/// for constructors, destructors, and conversion functions.
|
||||
class DeclarationName {
|
||||
namespace detail {
|
||||
|
||||
/// CXXSpecialNameExtra records the type associated with one of the "special"
|
||||
/// kinds of declaration names in C++, e.g., constructors, destructors, and
|
||||
/// conversion functions. Note that CXXSpecialName is used for C++ constructor,
|
||||
/// destructor and conversion functions, but the actual kind is not stored in
|
||||
/// CXXSpecialName. Instead we use three different FoldingSet<CXXSpecialName>
|
||||
/// in DeclarationNameTable.
|
||||
class alignas(IdentifierInfoAlignment) CXXSpecialNameExtra
|
||||
: public llvm::FoldingSetNode {
|
||||
friend class clang::DeclarationName;
|
||||
friend class clang::DeclarationNameTable;
|
||||
|
||||
/// The type associated with this declaration name.
|
||||
QualType Type;
|
||||
|
||||
/// Extra information associated with this declaration name that
|
||||
/// can be used by the front end. All bits are really needed
|
||||
/// so it is not possible to stash something in the low order bits.
|
||||
void *FETokenInfo;
|
||||
|
||||
CXXSpecialNameExtra(QualType QT) : Type(QT), FETokenInfo(nullptr) {}
|
||||
|
||||
public:
|
||||
/// NameKind - The kind of name this object contains.
|
||||
enum NameKind {
|
||||
Identifier,
|
||||
ObjCZeroArgSelector,
|
||||
ObjCOneArgSelector,
|
||||
ObjCMultiArgSelector,
|
||||
CXXConstructorName,
|
||||
CXXDestructorName,
|
||||
CXXConversionFunctionName,
|
||||
CXXDeductionGuideName,
|
||||
CXXOperatorName,
|
||||
CXXLiteralOperatorName,
|
||||
CXXUsingDirective
|
||||
};
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
ID.AddPointer(Type.getAsOpaquePtr());
|
||||
}
|
||||
};
|
||||
|
||||
static const unsigned NumNameKinds = CXXUsingDirective + 1;
|
||||
/// Contains extra information for the name of a C++ deduction guide.
|
||||
class alignas(IdentifierInfoAlignment) CXXDeductionGuideNameExtra
|
||||
: public detail::DeclarationNameExtra,
|
||||
public llvm::FoldingSetNode {
|
||||
friend class clang::DeclarationName;
|
||||
friend class clang::DeclarationNameTable;
|
||||
|
||||
private:
|
||||
/// The template named by the deduction guide.
|
||||
TemplateDecl *Template;
|
||||
|
||||
/// Extra information associated with this operator name that
|
||||
/// can be used by the front end. All bits are really needed
|
||||
/// so it is not possible to stash something in the low order bits.
|
||||
void *FETokenInfo;
|
||||
|
||||
CXXDeductionGuideNameExtra(TemplateDecl *TD)
|
||||
: DeclarationNameExtra(CXXDeductionGuideName), Template(TD),
|
||||
FETokenInfo(nullptr) {}
|
||||
|
||||
public:
|
||||
void Profile(llvm::FoldingSetNodeID &ID) { ID.AddPointer(Template); }
|
||||
};
|
||||
|
||||
/// Contains extra information for the name of an overloaded operator
|
||||
/// in C++, such as "operator+. This do not includes literal or conversion
|
||||
/// operators. For literal operators see CXXLiteralOperatorIdName and for
|
||||
/// conversion operators see CXXSpecialNameExtra.
|
||||
class alignas(IdentifierInfoAlignment) CXXOperatorIdName {
|
||||
friend class clang::DeclarationName;
|
||||
friend class clang::DeclarationNameTable;
|
||||
|
||||
/// The kind of this operator.
|
||||
OverloadedOperatorKind Kind = OO_None;
|
||||
|
||||
/// Extra information associated with this operator name that
|
||||
/// can be used by the front end. All bits are really needed
|
||||
/// so it is not possible to stash something in the low order bits.
|
||||
void *FETokenInfo = nullptr;
|
||||
};
|
||||
|
||||
/// Contains the actual identifier that makes up the
|
||||
/// name of a C++ literal operator.
|
||||
class alignas(IdentifierInfoAlignment) CXXLiteralOperatorIdName
|
||||
: public detail::DeclarationNameExtra,
|
||||
public llvm::FoldingSetNode {
|
||||
friend class clang::DeclarationName;
|
||||
friend class clang::DeclarationNameTable;
|
||||
|
||||
IdentifierInfo *ID;
|
||||
|
||||
/// Extra information associated with this operator name that
|
||||
/// can be used by the front end. All bits are really needed
|
||||
/// so it is not possible to stash something in the low order bits.
|
||||
void *FETokenInfo;
|
||||
|
||||
CXXLiteralOperatorIdName(IdentifierInfo *II)
|
||||
: DeclarationNameExtra(CXXLiteralOperatorName), ID(II),
|
||||
FETokenInfo(nullptr) {}
|
||||
|
||||
public:
|
||||
void Profile(llvm::FoldingSetNodeID &FSID) { FSID.AddPointer(ID); }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// The name of a declaration. In the common case, this just stores
|
||||
/// an IdentifierInfo pointer to a normal name. However, it also provides
|
||||
/// encodings for Objective-C selectors (optimizing zero- and one-argument
|
||||
/// selectors, which make up 78% percent of all selectors in Cocoa.h),
|
||||
/// special C++ names for constructors, destructors, and conversion functions,
|
||||
/// and C++ overloaded operators.
|
||||
class DeclarationName {
|
||||
friend class DeclarationNameTable;
|
||||
friend class NamedDecl;
|
||||
|
||||
/// StoredNameKind - The kind of name that is actually stored in the
|
||||
/// StoredNameKind represent the kind of name that is actually stored in the
|
||||
/// upper bits of the Ptr field. This is only used internally.
|
||||
///
|
||||
/// Note: The entries here are synchronized with the entries in Selector,
|
||||
/// for efficient translation between the two.
|
||||
/// NameKind, StoredNameKind, and DeclarationNameExtra::ExtraKind
|
||||
/// must satisfy the following properties. These properties enable
|
||||
/// efficient conversion between the various kinds.
|
||||
///
|
||||
/// * The first seven enumerators of StoredNameKind must have the same
|
||||
/// numerical value as the first seven enumerators of NameKind.
|
||||
/// This enable efficient conversion between the two enumerations
|
||||
/// in the usual case.
|
||||
///
|
||||
/// * The enumerations values of DeclarationNameExtra::ExtraKind must start
|
||||
/// at zero, and correspond to the numerical value of the first non-inline
|
||||
/// enumeration values of NameKind minus an offset. This makes conversion
|
||||
/// between DeclarationNameExtra::ExtraKind and NameKind possible with
|
||||
/// a single addition/substraction.
|
||||
///
|
||||
/// * The enumeration values of Selector::IdentifierInfoFlag must correspond
|
||||
/// to the relevant enumeration values of StoredNameKind.
|
||||
/// More specifically:
|
||||
/// * ZeroArg == StoredObjCZeroArgSelector,
|
||||
/// * OneArg == StoredObjCOneArgSelector,
|
||||
/// * MultiArg == StoredDeclarationNameExtra
|
||||
///
|
||||
/// * PtrMask must mask the low 3 bits of Ptr.
|
||||
enum StoredNameKind {
|
||||
StoredIdentifier = 0,
|
||||
StoredObjCZeroArgSelector = 0x01,
|
||||
StoredObjCOneArgSelector = 0x02,
|
||||
StoredDeclarationNameExtra = 0x03,
|
||||
PtrMask = 0x03
|
||||
StoredObjCZeroArgSelector = Selector::ZeroArg,
|
||||
StoredObjCOneArgSelector = Selector::OneArg,
|
||||
StoredCXXConstructorName = 3,
|
||||
StoredCXXDestructorName = 4,
|
||||
StoredCXXConversionFunctionName = 5,
|
||||
StoredCXXOperatorName = 6,
|
||||
StoredDeclarationNameExtra = Selector::MultiArg,
|
||||
PtrMask = 7,
|
||||
UncommonNameKindOffset = 8
|
||||
};
|
||||
|
||||
/// Ptr - The lowest two bits are used to express what kind of name
|
||||
/// we're actually storing, using the values of NameKind. Depending
|
||||
static_assert(alignof(IdentifierInfo) >= 8 &&
|
||||
alignof(detail::DeclarationNameExtra) >= 8 &&
|
||||
alignof(detail::CXXSpecialNameExtra) >= 8 &&
|
||||
alignof(detail::CXXOperatorIdName) >= 8 &&
|
||||
alignof(detail::CXXDeductionGuideNameExtra) >= 8 &&
|
||||
alignof(detail::CXXLiteralOperatorIdName) >= 8,
|
||||
"The various classes that DeclarationName::Ptr can point to"
|
||||
" must be at least aligned to 8 bytes!");
|
||||
|
||||
public:
|
||||
/// The kind of the name stored in this DeclarationName.
|
||||
/// The first 7 enumeration values are stored inline and correspond
|
||||
/// to frequently used kinds. The rest is stored in DeclarationNameExtra
|
||||
/// and correspond to infrequently used kinds.
|
||||
enum NameKind {
|
||||
Identifier = StoredIdentifier,
|
||||
ObjCZeroArgSelector = StoredObjCZeroArgSelector,
|
||||
ObjCOneArgSelector = StoredObjCOneArgSelector,
|
||||
CXXConstructorName = StoredCXXConstructorName,
|
||||
CXXDestructorName = StoredCXXDestructorName,
|
||||
CXXConversionFunctionName = StoredCXXConversionFunctionName,
|
||||
CXXOperatorName = StoredCXXOperatorName,
|
||||
CXXDeductionGuideName = UncommonNameKindOffset +
|
||||
detail::DeclarationNameExtra::CXXDeductionGuideName,
|
||||
CXXLiteralOperatorName =
|
||||
UncommonNameKindOffset +
|
||||
detail::DeclarationNameExtra::CXXLiteralOperatorName,
|
||||
CXXUsingDirective = UncommonNameKindOffset +
|
||||
detail::DeclarationNameExtra::CXXUsingDirective,
|
||||
ObjCMultiArgSelector = UncommonNameKindOffset +
|
||||
detail::DeclarationNameExtra::ObjCMultiArgSelector
|
||||
};
|
||||
|
||||
private:
|
||||
/// The lowest three bits of Ptr are used to express what kind of name
|
||||
/// we're actually storing, using the values of StoredNameKind. Depending
|
||||
/// on the kind of name this is, the upper bits of Ptr may have one
|
||||
/// of several different meanings:
|
||||
///
|
||||
|
|
@ -105,99 +236,141 @@ private:
|
|||
/// with one argument, and Ptr is an IdentifierInfo pointer
|
||||
/// pointing to the selector name.
|
||||
///
|
||||
/// StoredCXXConstructorName - The name of a C++ constructor,
|
||||
/// Ptr points to a CXXSpecialNameExtra.
|
||||
///
|
||||
/// StoredCXXDestructorName - The name of a C++ destructor,
|
||||
/// Ptr points to a CXXSpecialNameExtra.
|
||||
///
|
||||
/// StoredCXXConversionFunctionName - The name of a C++ conversion function,
|
||||
/// Ptr points to a CXXSpecialNameExtra.
|
||||
///
|
||||
/// StoredCXXOperatorName - The name of an overloaded C++ operator,
|
||||
/// Ptr points to a CXXOperatorIdName.
|
||||
///
|
||||
/// StoredDeclarationNameExtra - Ptr is actually a pointer to a
|
||||
/// DeclarationNameExtra structure, whose first value will tell us
|
||||
/// whether this is an Objective-C selector, C++ operator-id name,
|
||||
/// or special C++ name.
|
||||
/// whether this is an Objective-C selector, C++ deduction guide,
|
||||
/// C++ literal operator, or C++ using directive.
|
||||
uintptr_t Ptr = 0;
|
||||
|
||||
// Construct a declaration name from the name of a C++ constructor,
|
||||
// destructor, or conversion function.
|
||||
DeclarationName(DeclarationNameExtra *Name)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned DeclarationNameExtra");
|
||||
Ptr |= StoredDeclarationNameExtra;
|
||||
}
|
||||
|
||||
/// Construct a declaration name from a raw pointer.
|
||||
DeclarationName(uintptr_t Ptr) : Ptr(Ptr) {}
|
||||
|
||||
/// getStoredNameKind - Return the kind of object that is stored in
|
||||
/// Ptr.
|
||||
StoredNameKind getStoredNameKind() const {
|
||||
return static_cast<StoredNameKind>(Ptr & PtrMask);
|
||||
}
|
||||
|
||||
/// getExtra - Get the "extra" information associated with this
|
||||
/// multi-argument selector or C++ special name.
|
||||
DeclarationNameExtra *getExtra() const {
|
||||
assert(getStoredNameKind() == StoredDeclarationNameExtra &&
|
||||
"Declaration name does not store an Extra structure");
|
||||
return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask);
|
||||
void *getPtr() const { return reinterpret_cast<void *>(Ptr & ~PtrMask); }
|
||||
|
||||
void setPtrAndKind(const void *P, StoredNameKind Kind) {
|
||||
uintptr_t PAsInteger = reinterpret_cast<uintptr_t>(P);
|
||||
assert((Kind & ~PtrMask) == 0 &&
|
||||
"Invalid StoredNameKind in setPtrAndKind!");
|
||||
assert((PAsInteger & PtrMask) == 0 &&
|
||||
"Improperly aligned pointer in setPtrAndKind!");
|
||||
Ptr = PAsInteger | Kind;
|
||||
}
|
||||
|
||||
/// getAsCXXSpecialName - If the stored pointer is actually a
|
||||
/// CXXSpecialName, returns a pointer to it. Otherwise, returns
|
||||
/// a NULL pointer.
|
||||
CXXSpecialName *getAsCXXSpecialName() const {
|
||||
NameKind Kind = getNameKind();
|
||||
if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
|
||||
return reinterpret_cast<CXXSpecialName *>(getExtra());
|
||||
return nullptr;
|
||||
/// Construct a declaration name from a DeclarationNameExtra.
|
||||
DeclarationName(detail::DeclarationNameExtra *Name) {
|
||||
setPtrAndKind(Name, StoredDeclarationNameExtra);
|
||||
}
|
||||
|
||||
/// If the stored pointer is actually a CXXDeductionGuideNameExtra, returns a
|
||||
/// pointer to it. Otherwise, returns a NULL pointer.
|
||||
CXXDeductionGuideNameExtra *getAsCXXDeductionGuideNameExtra() const {
|
||||
if (getNameKind() == CXXDeductionGuideName)
|
||||
return reinterpret_cast<CXXDeductionGuideNameExtra *>(getExtra());
|
||||
return nullptr;
|
||||
/// Construct a declaration name from a CXXSpecialNameExtra.
|
||||
DeclarationName(detail::CXXSpecialNameExtra *Name,
|
||||
StoredNameKind StoredKind) {
|
||||
assert((StoredKind == StoredCXXConstructorName ||
|
||||
StoredKind == StoredCXXDestructorName ||
|
||||
StoredKind == StoredCXXConversionFunctionName) &&
|
||||
"Invalid StoredNameKind when constructing a DeclarationName"
|
||||
" from a CXXSpecialNameExtra!");
|
||||
setPtrAndKind(Name, StoredKind);
|
||||
}
|
||||
|
||||
/// getAsCXXOperatorIdName
|
||||
CXXOperatorIdName *getAsCXXOperatorIdName() const {
|
||||
if (getNameKind() == CXXOperatorName)
|
||||
return reinterpret_cast<CXXOperatorIdName *>(getExtra());
|
||||
return nullptr;
|
||||
/// Construct a DeclarationName from a CXXOperatorIdName.
|
||||
DeclarationName(detail::CXXOperatorIdName *Name) {
|
||||
setPtrAndKind(Name, StoredCXXOperatorName);
|
||||
}
|
||||
|
||||
CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
|
||||
if (getNameKind() == CXXLiteralOperatorName)
|
||||
return reinterpret_cast<CXXLiteralOperatorIdName *>(getExtra());
|
||||
return nullptr;
|
||||
/// Assert that the stored pointer points to an IdentifierInfo and return it.
|
||||
IdentifierInfo *castAsIdentifierInfo() const {
|
||||
assert((getStoredNameKind() == StoredIdentifier) &&
|
||||
"DeclarationName does not store an IdentifierInfo!");
|
||||
return static_cast<IdentifierInfo *>(getPtr());
|
||||
}
|
||||
|
||||
/// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
|
||||
/// for this name as a void pointer if it's not an identifier.
|
||||
void *getFETokenInfoAsVoidSlow() const;
|
||||
/// Assert that the stored pointer points to a DeclarationNameExtra
|
||||
/// and return it.
|
||||
detail::DeclarationNameExtra *castAsExtra() const {
|
||||
assert((getStoredNameKind() == StoredDeclarationNameExtra) &&
|
||||
"DeclarationName does not store an Extra structure!");
|
||||
return static_cast<detail::DeclarationNameExtra *>(getPtr());
|
||||
}
|
||||
|
||||
/// Assert that the stored pointer points to a CXXSpecialNameExtra
|
||||
/// and return it.
|
||||
detail::CXXSpecialNameExtra *castAsCXXSpecialNameExtra() const {
|
||||
assert((getStoredNameKind() == StoredCXXConstructorName ||
|
||||
getStoredNameKind() == StoredCXXDestructorName ||
|
||||
getStoredNameKind() == StoredCXXConversionFunctionName) &&
|
||||
"DeclarationName does not store a CXXSpecialNameExtra!");
|
||||
return static_cast<detail::CXXSpecialNameExtra *>(getPtr());
|
||||
}
|
||||
|
||||
/// Assert that the stored pointer points to a CXXOperatorIdName
|
||||
/// and return it.
|
||||
detail::CXXOperatorIdName *castAsCXXOperatorIdName() const {
|
||||
assert((getStoredNameKind() == StoredCXXOperatorName) &&
|
||||
"DeclarationName does not store a CXXOperatorIdName!");
|
||||
return static_cast<detail::CXXOperatorIdName *>(getPtr());
|
||||
}
|
||||
|
||||
/// Assert that the stored pointer points to a CXXDeductionGuideNameExtra
|
||||
/// and return it.
|
||||
detail::CXXDeductionGuideNameExtra *castAsCXXDeductionGuideNameExtra() const {
|
||||
assert(getNameKind() == CXXDeductionGuideName &&
|
||||
"DeclarationName does not store a CXXDeductionGuideNameExtra!");
|
||||
return static_cast<detail::CXXDeductionGuideNameExtra *>(getPtr());
|
||||
}
|
||||
|
||||
/// Assert that the stored pointer points to a CXXLiteralOperatorIdName
|
||||
/// and return it.
|
||||
detail::CXXLiteralOperatorIdName *castAsCXXLiteralOperatorIdName() const {
|
||||
assert(getNameKind() == CXXLiteralOperatorName &&
|
||||
"DeclarationName does not store a CXXLiteralOperatorIdName!");
|
||||
return static_cast<detail::CXXLiteralOperatorIdName *>(getPtr());
|
||||
}
|
||||
|
||||
/// Get and set the FETokenInfo in the less common cases where the
|
||||
/// declaration name do not point to an identifier.
|
||||
void *getFETokenInfoSlow() const;
|
||||
void setFETokenInfoSlow(void *T);
|
||||
|
||||
public:
|
||||
/// DeclarationName - Used to create an empty selector.
|
||||
DeclarationName() = default;
|
||||
/// Construct an empty declaration name.
|
||||
DeclarationName() { setPtrAndKind(nullptr, StoredIdentifier); }
|
||||
|
||||
// Construct a declaration name from an IdentifierInfo *.
|
||||
DeclarationName(const IdentifierInfo *II)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(II)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
|
||||
/// Construct a declaration name from an IdentifierInfo *.
|
||||
DeclarationName(const IdentifierInfo *II) {
|
||||
setPtrAndKind(II, StoredIdentifier);
|
||||
}
|
||||
|
||||
// Construct a declaration name from an Objective-C selector.
|
||||
/// Construct a declaration name from an Objective-C selector.
|
||||
DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
|
||||
|
||||
/// getUsingDirectiveName - Return name for all using-directives.
|
||||
static DeclarationName getUsingDirectiveName();
|
||||
/// Returns the name for all C++ using-directives.
|
||||
static DeclarationName getUsingDirectiveName() {
|
||||
// Single instance of DeclarationNameExtra for using-directive
|
||||
static detail::DeclarationNameExtra UDirExtra(
|
||||
detail::DeclarationNameExtra::CXXUsingDirective);
|
||||
return DeclarationName(&UDirExtra);
|
||||
}
|
||||
|
||||
// operator bool() - Evaluates true when this declaration name is
|
||||
// non-empty.
|
||||
/// Evaluates true when this declaration name is non-empty.
|
||||
explicit operator bool() const {
|
||||
return ((Ptr & PtrMask) != 0) ||
|
||||
(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
|
||||
return getPtr() || (getStoredNameKind() != StoredIdentifier);
|
||||
}
|
||||
|
||||
/// Evaluates true when this declaration name is empty.
|
||||
bool isEmpty() const {
|
||||
return !*this;
|
||||
}
|
||||
bool isEmpty() const { return !*this; }
|
||||
|
||||
/// Predicate functions for querying what type of name this is.
|
||||
bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
|
||||
|
|
@ -208,8 +381,19 @@ public:
|
|||
return getStoredNameKind() == StoredObjCOneArgSelector;
|
||||
}
|
||||
|
||||
/// getNameKind - Determine what kind of name this is.
|
||||
NameKind getNameKind() const;
|
||||
/// Determine what kind of name this is.
|
||||
NameKind getNameKind() const {
|
||||
// We rely on the fact that the first 7 NameKind and StoredNameKind
|
||||
// have the same numerical value. This makes the usual case efficient.
|
||||
StoredNameKind StoredKind = getStoredNameKind();
|
||||
if (StoredKind != StoredDeclarationNameExtra)
|
||||
return static_cast<NameKind>(StoredKind);
|
||||
// We have to consult DeclarationNameExtra. We rely on the fact that the
|
||||
// enumeration values of ExtraKind correspond to the enumeration values of
|
||||
// NameKind minus an offset of UncommonNameKindOffset.
|
||||
unsigned ExtraKind = castAsExtra()->getKind();
|
||||
return static_cast<NameKind>(UncommonNameKindOffset + ExtraKind);
|
||||
}
|
||||
|
||||
/// Determines whether the name itself is dependent, e.g., because it
|
||||
/// involves a C++ type that is itself dependent.
|
||||
|
|
@ -219,95 +403,128 @@ public:
|
|||
/// callee in a call expression with dependent arguments.
|
||||
bool isDependentName() const;
|
||||
|
||||
/// getNameAsString - Retrieve the human-readable string for this name.
|
||||
/// Retrieve the human-readable string for this name.
|
||||
std::string getAsString() const;
|
||||
|
||||
/// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
|
||||
/// this declaration name, or NULL if this declaration name isn't a
|
||||
/// simple identifier.
|
||||
/// Retrieve the IdentifierInfo * stored in this declaration name,
|
||||
/// or null if this declaration name isn't a simple identifier.
|
||||
IdentifierInfo *getAsIdentifierInfo() const {
|
||||
if (isIdentifier())
|
||||
return reinterpret_cast<IdentifierInfo *>(Ptr);
|
||||
return castAsIdentifierInfo();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// getAsOpaqueInteger - Get the representation of this declaration
|
||||
/// name as an opaque integer.
|
||||
/// Get the representation of this declaration name as an opaque integer.
|
||||
uintptr_t getAsOpaqueInteger() const { return Ptr; }
|
||||
|
||||
/// getAsOpaquePtr - Get the representation of this declaration name as
|
||||
/// an opaque pointer.
|
||||
void *getAsOpaquePtr() const { return reinterpret_cast<void*>(Ptr); }
|
||||
/// Get the representation of this declaration name as an opaque pointer.
|
||||
void *getAsOpaquePtr() const { return reinterpret_cast<void *>(Ptr); }
|
||||
|
||||
/// Get a declaration name from an opaque pointer returned by getAsOpaquePtr.
|
||||
static DeclarationName getFromOpaquePtr(void *P) {
|
||||
DeclarationName N;
|
||||
N.Ptr = reinterpret_cast<uintptr_t> (P);
|
||||
N.Ptr = reinterpret_cast<uintptr_t>(P);
|
||||
return N;
|
||||
}
|
||||
|
||||
/// Get a declaration name from an opaque integer
|
||||
/// returned by getAsOpaqueInteger.
|
||||
static DeclarationName getFromOpaqueInteger(uintptr_t P) {
|
||||
DeclarationName N;
|
||||
N.Ptr = P;
|
||||
return N;
|
||||
}
|
||||
|
||||
/// getCXXNameType - If this name is one of the C++ names (of a
|
||||
/// constructor, destructor, or conversion function), return the
|
||||
/// type associated with that name.
|
||||
QualType getCXXNameType() const;
|
||||
/// If this name is one of the C++ names (of a constructor, destructor,
|
||||
/// or conversion function), return the type associated with that name.
|
||||
QualType getCXXNameType() const {
|
||||
if (getStoredNameKind() == StoredCXXConstructorName ||
|
||||
getStoredNameKind() == StoredCXXDestructorName ||
|
||||
getStoredNameKind() == StoredCXXConversionFunctionName) {
|
||||
assert(getPtr() && "getCXXNameType on a null DeclarationName!");
|
||||
return castAsCXXSpecialNameExtra()->Type;
|
||||
}
|
||||
return QualType();
|
||||
}
|
||||
|
||||
/// If this name is the name of a C++ deduction guide, return the
|
||||
/// template associated with that name.
|
||||
TemplateDecl *getCXXDeductionGuideTemplate() const;
|
||||
TemplateDecl *getCXXDeductionGuideTemplate() const {
|
||||
if (getNameKind() == CXXDeductionGuideName) {
|
||||
assert(getPtr() &&
|
||||
"getCXXDeductionGuideTemplate on a null DeclarationName!");
|
||||
return castAsCXXDeductionGuideNameExtra()->Template;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// getCXXOverloadedOperator - If this name is the name of an
|
||||
/// overloadable operator in C++ (e.g., @c operator+), retrieve the
|
||||
/// kind of overloaded operator.
|
||||
OverloadedOperatorKind getCXXOverloadedOperator() const;
|
||||
/// If this name is the name of an overloadable operator in C++
|
||||
/// (e.g., @c operator+), retrieve the kind of overloaded operator.
|
||||
OverloadedOperatorKind getCXXOverloadedOperator() const {
|
||||
if (getStoredNameKind() == StoredCXXOperatorName) {
|
||||
assert(getPtr() && "getCXXOverloadedOperator on a null DeclarationName!");
|
||||
return castAsCXXOperatorIdName()->Kind;
|
||||
}
|
||||
return OO_None;
|
||||
}
|
||||
|
||||
/// getCXXLiteralIdentifier - If this name is the name of a literal
|
||||
/// operator, retrieve the identifier associated with it.
|
||||
IdentifierInfo *getCXXLiteralIdentifier() const;
|
||||
/// If this name is the name of a literal operator,
|
||||
/// retrieve the identifier associated with it.
|
||||
IdentifierInfo *getCXXLiteralIdentifier() const {
|
||||
if (getNameKind() == CXXLiteralOperatorName) {
|
||||
assert(getPtr() && "getCXXLiteralIdentifier on a null DeclarationName!");
|
||||
return castAsCXXLiteralOperatorIdName()->ID;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// getObjCSelector - Get the Objective-C selector stored in this
|
||||
/// declaration name.
|
||||
/// Get the Objective-C selector stored in this declaration name.
|
||||
Selector getObjCSelector() const {
|
||||
assert((getNameKind() == ObjCZeroArgSelector ||
|
||||
getNameKind() == ObjCOneArgSelector ||
|
||||
getNameKind() == ObjCMultiArgSelector ||
|
||||
Ptr == 0) && "Not a selector!");
|
||||
getNameKind() == ObjCMultiArgSelector || !getPtr()) &&
|
||||
"Not a selector!");
|
||||
return Selector(Ptr);
|
||||
}
|
||||
|
||||
/// getFETokenInfo/setFETokenInfo - The language front-end is
|
||||
/// allowed to associate arbitrary metadata with some kinds of
|
||||
/// declaration names, including normal identifiers and C++
|
||||
/// constructors, destructors, and conversion functions.
|
||||
template<typename T>
|
||||
T *getFETokenInfo() const {
|
||||
if (const IdentifierInfo *Info = getAsIdentifierInfo())
|
||||
return Info->getFETokenInfo<T>();
|
||||
return static_cast<T*>(getFETokenInfoAsVoidSlow());
|
||||
/// Get and set FETokenInfo. The language front-end is allowed to associate
|
||||
/// arbitrary metadata with some kinds of declaration names, including normal
|
||||
/// identifiers and C++ constructors, destructors, and conversion functions.
|
||||
void *getFETokenInfo() const {
|
||||
assert(getPtr() && "getFETokenInfo on an empty DeclarationName!");
|
||||
if (getStoredNameKind() == StoredIdentifier)
|
||||
return castAsIdentifierInfo()->getFETokenInfo();
|
||||
return getFETokenInfoSlow();
|
||||
}
|
||||
|
||||
void setFETokenInfo(void *T);
|
||||
void setFETokenInfo(void *T) {
|
||||
assert(getPtr() && "setFETokenInfo on an empty DeclarationName!");
|
||||
if (getStoredNameKind() == StoredIdentifier)
|
||||
castAsIdentifierInfo()->setFETokenInfo(T);
|
||||
else
|
||||
setFETokenInfoSlow(T);
|
||||
}
|
||||
|
||||
/// operator== - Determine whether the specified names are identical..
|
||||
/// Determine whether the specified names are identical.
|
||||
friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
|
||||
return LHS.Ptr == RHS.Ptr;
|
||||
}
|
||||
|
||||
/// operator!= - Determine whether the specified names are different.
|
||||
/// Determine whether the specified names are different.
|
||||
friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
|
||||
return LHS.Ptr != RHS.Ptr;
|
||||
}
|
||||
|
||||
static DeclarationName getEmptyMarker() {
|
||||
return DeclarationName(uintptr_t(-1));
|
||||
DeclarationName Name;
|
||||
Name.Ptr = uintptr_t(-1);
|
||||
return Name;
|
||||
}
|
||||
|
||||
static DeclarationName getTombstoneMarker() {
|
||||
return DeclarationName(uintptr_t(-2));
|
||||
DeclarationName Name;
|
||||
Name.Ptr = uintptr_t(-2);
|
||||
return Name;
|
||||
}
|
||||
|
||||
static int compare(DeclarationName LHS, DeclarationName RHS);
|
||||
|
|
@ -343,67 +560,88 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
|
|||
return DeclarationName::compare(LHS, RHS) >= 0;
|
||||
}
|
||||
|
||||
/// DeclarationNameTable - Used to store and retrieve DeclarationName
|
||||
/// DeclarationNameTable is used to store and retrieve DeclarationName
|
||||
/// instances for the various kinds of declaration names, e.g., normal
|
||||
/// identifiers, C++ constructor names, etc. This class contains
|
||||
/// uniqued versions of each of the C++ special names, which can be
|
||||
/// retrieved using its member functions (e.g.,
|
||||
/// getCXXConstructorName).
|
||||
/// retrieved using its member functions (e.g., getCXXConstructorName).
|
||||
class DeclarationNameTable {
|
||||
/// Used to allocate elements in the FoldingSets below.
|
||||
const ASTContext &Ctx;
|
||||
|
||||
// Actually a FoldingSet<CXXSpecialName> *
|
||||
void *CXXSpecialNamesImpl;
|
||||
/// Manage the uniqued CXXSpecialNameExtra representing C++ constructors.
|
||||
/// getCXXConstructorName and getCXXSpecialName can be used to obtain
|
||||
/// a DeclarationName from the corresponding type of the constructor.
|
||||
llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXConstructorNames;
|
||||
|
||||
// Operator names
|
||||
CXXOperatorIdName *CXXOperatorNames;
|
||||
/// Manage the uniqued CXXSpecialNameExtra representing C++ destructors.
|
||||
/// getCXXDestructorName and getCXXSpecialName can be used to obtain
|
||||
/// a DeclarationName from the corresponding type of the destructor.
|
||||
llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXDestructorNames;
|
||||
|
||||
// Actually a CXXOperatorIdName*
|
||||
void *CXXLiteralOperatorNames;
|
||||
/// Manage the uniqued CXXSpecialNameExtra representing C++ conversion
|
||||
/// functions. getCXXConversionFunctionName and getCXXSpecialName can be
|
||||
/// used to obtain a DeclarationName from the corresponding type of the
|
||||
/// conversion function.
|
||||
llvm::FoldingSet<detail::CXXSpecialNameExtra> CXXConversionFunctionNames;
|
||||
|
||||
// FoldingSet<CXXDeductionGuideNameExtra> *
|
||||
void *CXXDeductionGuideNames;
|
||||
/// Manage the uniqued CXXOperatorIdName, which contain extra information
|
||||
/// for the name of overloaded C++ operators. getCXXOperatorName
|
||||
/// can be used to obtain a DeclarationName from the operator kind.
|
||||
detail::CXXOperatorIdName CXXOperatorNames[NUM_OVERLOADED_OPERATORS];
|
||||
|
||||
/// Manage the uniqued CXXLiteralOperatorIdName, which contain extra
|
||||
/// information for the name of C++ literal operators.
|
||||
/// getCXXLiteralOperatorName can be used to obtain a DeclarationName
|
||||
/// from the corresponding IdentifierInfo.
|
||||
llvm::FoldingSet<detail::CXXLiteralOperatorIdName> CXXLiteralOperatorNames;
|
||||
|
||||
/// Manage the uniqued CXXDeductionGuideNameExtra, which contain
|
||||
/// extra information for the name of a C++ deduction guide.
|
||||
/// getCXXDeductionGuideName can be used to obtain a DeclarationName
|
||||
/// from the corresponding template declaration.
|
||||
llvm::FoldingSet<detail::CXXDeductionGuideNameExtra> CXXDeductionGuideNames;
|
||||
|
||||
public:
|
||||
DeclarationNameTable(const ASTContext &C);
|
||||
DeclarationNameTable(const DeclarationNameTable &) = delete;
|
||||
DeclarationNameTable &operator=(const DeclarationNameTable &) = delete;
|
||||
DeclarationNameTable(DeclarationNameTable &&) = delete;
|
||||
DeclarationNameTable &operator=(DeclarationNameTable &&) = delete;
|
||||
~DeclarationNameTable() = default;
|
||||
|
||||
~DeclarationNameTable();
|
||||
|
||||
/// getIdentifier - Create a declaration name that is a simple
|
||||
/// identifier.
|
||||
/// Create a declaration name that is a simple identifier.
|
||||
DeclarationName getIdentifier(const IdentifierInfo *ID) {
|
||||
return DeclarationName(ID);
|
||||
}
|
||||
|
||||
/// getCXXConstructorName - Returns the name of a C++ constructor
|
||||
/// for the given Type.
|
||||
/// Returns the name of a C++ constructor for the given Type.
|
||||
DeclarationName getCXXConstructorName(CanQualType Ty);
|
||||
|
||||
/// getCXXDestructorName - Returns the name of a C++ destructor
|
||||
/// for the given Type.
|
||||
/// Returns the name of a C++ destructor for the given Type.
|
||||
DeclarationName getCXXDestructorName(CanQualType Ty);
|
||||
|
||||
/// Returns the name of a C++ deduction guide for the given template.
|
||||
DeclarationName getCXXDeductionGuideName(TemplateDecl *TD);
|
||||
|
||||
/// getCXXConversionFunctionName - Returns the name of a C++
|
||||
/// conversion function for the given Type.
|
||||
/// Returns the name of a C++ conversion function for the given Type.
|
||||
DeclarationName getCXXConversionFunctionName(CanQualType Ty);
|
||||
|
||||
/// getCXXSpecialName - Returns a declaration name for special kind
|
||||
/// of C++ name, e.g., for a constructor, destructor, or conversion
|
||||
/// function.
|
||||
/// Returns a declaration name for special kind of C++ name,
|
||||
/// e.g., for a constructor, destructor, or conversion function.
|
||||
/// Kind must be one of:
|
||||
/// * DeclarationName::CXXConstructorName,
|
||||
/// * DeclarationName::CXXDestructorName or
|
||||
/// * DeclarationName::CXXConversionFunctionName
|
||||
DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
|
||||
CanQualType Ty);
|
||||
|
||||
/// getCXXOperatorName - Get the name of the overloadable C++
|
||||
/// operator corresponding to Op.
|
||||
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
|
||||
/// Get the name of the overloadable C++ operator corresponding to Op.
|
||||
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op) {
|
||||
return DeclarationName(&CXXOperatorNames[Op]);
|
||||
}
|
||||
|
||||
/// getCXXLiteralOperatorName - Get the name of the literal operator function
|
||||
/// with II as the identifier.
|
||||
/// Get the name of the literal operator function with II as the identifier.
|
||||
DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
|
||||
};
|
||||
|
||||
|
|
@ -491,9 +729,10 @@ public:
|
|||
/// getNamedTypeInfo - Returns the source type info associated to
|
||||
/// the name. Assumes it is a constructor, destructor or conversion.
|
||||
TypeSourceInfo *getNamedTypeInfo() const {
|
||||
assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
|
||||
Name.getNameKind() == DeclarationName::CXXDestructorName ||
|
||||
Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
|
||||
if (Name.getNameKind() != DeclarationName::CXXConstructorName &&
|
||||
Name.getNameKind() != DeclarationName::CXXDestructorName &&
|
||||
Name.getNameKind() != DeclarationName::CXXConversionFunctionName)
|
||||
return nullptr;
|
||||
return LocInfo.NamedType.TInfo;
|
||||
}
|
||||
|
||||
|
|
@ -509,7 +748,8 @@ public:
|
|||
/// getCXXOperatorNameRange - Gets the range of the operator name
|
||||
/// (without the operator keyword). Assumes it is a (non-literal) operator.
|
||||
SourceRange getCXXOperatorNameRange() const {
|
||||
assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
|
||||
if (Name.getNameKind() != DeclarationName::CXXOperatorName)
|
||||
return SourceRange();
|
||||
return SourceRange(
|
||||
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
|
||||
SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
|
||||
|
|
@ -528,7 +768,8 @@ public:
|
|||
/// operator name (not the operator keyword).
|
||||
/// Assumes it is a literal operator.
|
||||
SourceLocation getCXXLiteralOperatorNameLoc() const {
|
||||
assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
|
||||
if (Name.getNameKind() != DeclarationName::CXXLiteralOperatorName)
|
||||
return SourceLocation();
|
||||
return SourceLocation::
|
||||
getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
|
||||
}
|
||||
|
|
@ -559,15 +800,12 @@ public:
|
|||
|
||||
/// getSourceRange - The range of the declaration name.
|
||||
SourceRange getSourceRange() const LLVM_READONLY {
|
||||
return SourceRange(getLocStart(), getLocEnd());
|
||||
return SourceRange(getBeginLoc(), getEndLoc());
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
SourceLocation EndLoc = getEndLocPrivate();
|
||||
return EndLoc.isValid() ? EndLoc : getLocStart();
|
||||
return EndLoc.isValid() ? EndLoc : getBeginLoc();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
|
|
@ -107,23 +108,22 @@ public:
|
|||
};
|
||||
|
||||
/// EvaluatedExprVisitor - This class visits 'Expr *'s
|
||||
template<typename ImplClass>
|
||||
template <typename ImplClass>
|
||||
class EvaluatedExprVisitor
|
||||
: public EvaluatedExprVisitorBase<make_ptr, ImplClass> {
|
||||
: public EvaluatedExprVisitorBase<std::add_pointer, ImplClass> {
|
||||
public:
|
||||
explicit EvaluatedExprVisitor(const ASTContext &Context) :
|
||||
EvaluatedExprVisitorBase<make_ptr, ImplClass>(Context) { }
|
||||
explicit EvaluatedExprVisitor(const ASTContext &Context)
|
||||
: EvaluatedExprVisitorBase<std::add_pointer, ImplClass>(Context) {}
|
||||
};
|
||||
|
||||
/// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
|
||||
template<typename ImplClass>
|
||||
template <typename ImplClass>
|
||||
class ConstEvaluatedExprVisitor
|
||||
: public EvaluatedExprVisitorBase<make_const_ptr, ImplClass> {
|
||||
: public EvaluatedExprVisitorBase<llvm::make_const_ptr, ImplClass> {
|
||||
public:
|
||||
explicit ConstEvaluatedExprVisitor(const ASTContext &Context) :
|
||||
EvaluatedExprVisitorBase<make_const_ptr, ImplClass>(Context) { }
|
||||
explicit ConstEvaluatedExprVisitor(const ASTContext &Context)
|
||||
: EvaluatedExprVisitorBase<llvm::make_const_ptr, ImplClass>(Context) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -67,10 +67,8 @@ public:
|
|||
SourceLocation getAtLoc() const { return AtLoc; }
|
||||
void setAtLoc(SourceLocation L) { AtLoc = L; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return String->getLocEnd(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return String->getEndLoc(); }
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&String, &String+1); }
|
||||
|
|
@ -96,9 +94,7 @@ public:
|
|||
bool getValue() const { return Value; }
|
||||
void setValue(bool V) { Value = V; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
|
||||
|
||||
SourceLocation getLocation() const { return Loc; }
|
||||
|
|
@ -145,9 +141,7 @@ public:
|
|||
|
||||
SourceLocation getAtLoc() const { return Range.getBegin(); }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
|
||||
|
||||
SourceRange getSourceRange() const LLVM_READONLY {
|
||||
|
|
@ -200,9 +194,7 @@ public:
|
|||
static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
|
||||
unsigned NumElements);
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
|
||||
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
|
||||
|
||||
|
|
@ -367,9 +359,7 @@ public:
|
|||
return DictWithObjectsMethod;
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
|
||||
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
|
||||
|
||||
|
|
@ -422,9 +412,7 @@ public:
|
|||
EncodedType = EncType;
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
|
||||
|
||||
// Iterators
|
||||
|
|
@ -459,9 +447,7 @@ public:
|
|||
void setAtLoc(SourceLocation L) { AtLoc = L; }
|
||||
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
|
||||
|
||||
/// getNumArgs - Return the number of actual arguments to this call.
|
||||
|
|
@ -510,9 +496,7 @@ public:
|
|||
void setAtLoc(SourceLocation L) { AtLoc = L; }
|
||||
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
|
||||
|
||||
// Iterators
|
||||
|
|
@ -572,11 +556,9 @@ public:
|
|||
SourceLocation getLocation() const { return Loc; }
|
||||
void setLocation(SourceLocation L) { Loc = L; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY {
|
||||
return isFreeIvar() ? Loc : getBase()->getLocStart();
|
||||
return isFreeIvar() ? Loc : getBase()->getBeginLoc();
|
||||
}
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
|
||||
|
||||
SourceLocation getOpLoc() const { return OpLoc; }
|
||||
|
|
@ -760,12 +742,11 @@ public:
|
|||
/// Determine the type of the base, regardless of the kind of receiver.
|
||||
QualType getReceiverType(const ASTContext &ctx) const;
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY {
|
||||
return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
|
||||
return isObjectReceiver() ? getBase()->getBeginLoc()
|
||||
: getReceiverLocation();
|
||||
}
|
||||
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return IdLoc; }
|
||||
|
||||
// Iterators
|
||||
|
|
@ -858,12 +839,10 @@ public:
|
|||
SourceLocation getRBracket() const { return RBracket; }
|
||||
void setRBracket(SourceLocation RB) { RBracket = RB; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY {
|
||||
return SubExprs[BASE]->getLocStart();
|
||||
return SubExprs[BASE]->getBeginLoc();
|
||||
}
|
||||
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return RBracket; }
|
||||
|
||||
Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
|
||||
|
|
@ -1386,7 +1365,7 @@ public:
|
|||
|
||||
SourceLocation getSelectorStartLoc() const {
|
||||
if (isImplicit())
|
||||
return getLocStart();
|
||||
return getBeginLoc();
|
||||
return getSelectorLoc(0);
|
||||
}
|
||||
|
||||
|
|
@ -1417,9 +1396,7 @@ public:
|
|||
RBracLoc = R.getEnd();
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return LBracLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return RBracLoc; }
|
||||
|
||||
// Iterators
|
||||
|
|
@ -1496,16 +1473,14 @@ public:
|
|||
SourceLocation getOpLoc() const { return OpLoc; }
|
||||
void setOpLoc(SourceLocation L) { OpLoc = L; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY {
|
||||
return getBase()->getLocStart();
|
||||
return getBase()->getBeginLoc();
|
||||
}
|
||||
|
||||
SourceLocation getBaseLocEnd() const LLVM_READONLY {
|
||||
return getBase()->getLocEnd();
|
||||
return getBase()->getEndLoc();
|
||||
}
|
||||
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return IsaMemberLoc; }
|
||||
|
||||
SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
|
||||
|
|
@ -1575,13 +1550,11 @@ public:
|
|||
child_range children() { return child_range(&Operand, &Operand+1); }
|
||||
|
||||
// Source locations are determined by the subexpression.
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY {
|
||||
return Operand->getLocStart();
|
||||
return Operand->getBeginLoc();
|
||||
}
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return Operand->getLocEnd();
|
||||
return Operand->getEndLoc();
|
||||
}
|
||||
|
||||
SourceLocation getExprLoc() const LLVM_READONLY {
|
||||
|
|
@ -1601,8 +1574,7 @@ public:
|
|||
/// \endcode
|
||||
class ObjCBridgedCastExpr final
|
||||
: public ExplicitCastExpr,
|
||||
private llvm::TrailingObjects<
|
||||
ObjCBridgedCastExpr, CastExpr::BasePathSizeTy, CXXBaseSpecifier *> {
|
||||
private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> {
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
friend class CastExpr;
|
||||
|
|
@ -1612,10 +1584,6 @@ class ObjCBridgedCastExpr final
|
|||
SourceLocation BridgeKeywordLoc;
|
||||
unsigned Kind : 2;
|
||||
|
||||
size_t numTrailingObjects(OverloadToken<CastExpr::BasePathSizeTy>) const {
|
||||
return path_empty() ? 0 : 1;
|
||||
}
|
||||
|
||||
public:
|
||||
ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
|
||||
CastKind CK, SourceLocation BridgeKeywordLoc,
|
||||
|
|
@ -1641,12 +1609,10 @@ public:
|
|||
/// The location of the bridge keyword.
|
||||
SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
|
||||
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return getSubExpr()->getLocEnd();
|
||||
return getSubExpr()->getEndLoc();
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
|
|
@ -1683,9 +1649,7 @@ public:
|
|||
explicit ObjCAvailabilityCheckExpr(EmptyShell Shell)
|
||||
: Expr(ObjCAvailabilityCheckExprClass, Shell) {}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const { return AtLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const { return RParen; }
|
||||
SourceRange getSourceRange() const { return {AtLoc, RParen}; }
|
||||
|
||||
|
|
|
|||
|
|
@ -101,11 +101,9 @@ public:
|
|||
/// Set length of the array section.
|
||||
void setLength(Expr *E) { SubExprs[LENGTH] = E; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY {
|
||||
return getBase()->getLocStart();
|
||||
return getBase()->getBeginLoc();
|
||||
}
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
|
||||
|
||||
SourceLocation getColonLoc() const { return ColonLoc; }
|
||||
|
|
|
|||
|
|
@ -303,6 +303,8 @@ public:
|
|||
|
||||
QualType getRepresentativeType(ASTContext &C) const;
|
||||
|
||||
ArgType makeVectorType(ASTContext &C, unsigned NumElts) const;
|
||||
|
||||
std::string getRepresentativeTypeName(ASTContext &C) const;
|
||||
};
|
||||
|
||||
|
|
@ -322,6 +324,10 @@ public:
|
|||
: start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
|
||||
UsesPositionalArg(0), UsesDotPrefix(0) {}
|
||||
|
||||
explicit OptionalAmount(unsigned Amount)
|
||||
: start(nullptr), length(0), hs(Constant), amt(Amount),
|
||||
UsesPositionalArg(false), UsesDotPrefix(false) {}
|
||||
|
||||
bool isInvalid() const {
|
||||
return hs == Invalid;
|
||||
}
|
||||
|
|
@ -379,6 +385,8 @@ protected:
|
|||
LengthModifier LM;
|
||||
OptionalAmount FieldWidth;
|
||||
ConversionSpecifier CS;
|
||||
OptionalAmount VectorNumElts;
|
||||
|
||||
/// Positional arguments, an IEEE extension:
|
||||
/// IEEE Std 1003.1, 2004 Edition
|
||||
/// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
|
||||
|
|
@ -386,7 +394,8 @@ protected:
|
|||
unsigned argIndex;
|
||||
public:
|
||||
FormatSpecifier(bool isPrintf)
|
||||
: CS(isPrintf), UsesPositionalArg(false), argIndex(0) {}
|
||||
: CS(isPrintf), VectorNumElts(false),
|
||||
UsesPositionalArg(false), argIndex(0) {}
|
||||
|
||||
void setLengthModifier(LengthModifier lm) {
|
||||
LM = lm;
|
||||
|
|
@ -414,6 +423,14 @@ public:
|
|||
return FieldWidth;
|
||||
}
|
||||
|
||||
void setVectorNumElts(const OptionalAmount &Amt) {
|
||||
VectorNumElts = Amt;
|
||||
}
|
||||
|
||||
const OptionalAmount &getVectorNumElts() const {
|
||||
return VectorNumElts;
|
||||
}
|
||||
|
||||
void setFieldWidth(const OptionalAmount &Amt) {
|
||||
FieldWidth = Amt;
|
||||
}
|
||||
|
|
@ -475,13 +492,19 @@ class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
|
|||
OptionalFlag HasObjCTechnicalTerm; // '[tt]'
|
||||
OptionalFlag IsPrivate; // '{private}'
|
||||
OptionalFlag IsPublic; // '{public}'
|
||||
OptionalFlag IsSensitive; // '{sensitive}'
|
||||
OptionalAmount Precision;
|
||||
StringRef MaskType;
|
||||
|
||||
ArgType getScalarArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
|
||||
|
||||
public:
|
||||
PrintfSpecifier()
|
||||
: FormatSpecifier(/* isPrintf = */ true), HasThousandsGrouping("'"),
|
||||
IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "),
|
||||
HasAlternativeForm("#"), HasLeadingZeroes("0"),
|
||||
HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public") {}
|
||||
HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public"),
|
||||
IsSensitive("sensitive") {}
|
||||
|
||||
static PrintfSpecifier Parse(const char *beg, const char *end);
|
||||
|
||||
|
|
@ -512,6 +535,9 @@ public:
|
|||
}
|
||||
void setIsPrivate(const char *position) { IsPrivate.setPosition(position); }
|
||||
void setIsPublic(const char *position) { IsPublic.setPosition(position); }
|
||||
void setIsSensitive(const char *position) {
|
||||
IsSensitive.setPosition(position);
|
||||
}
|
||||
void setUsesPositionalArg() { UsesPositionalArg = true; }
|
||||
|
||||
// Methods for querying the format specifier.
|
||||
|
|
@ -551,8 +577,12 @@ public:
|
|||
const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; }
|
||||
const OptionalFlag &isPrivate() const { return IsPrivate; }
|
||||
const OptionalFlag &isPublic() const { return IsPublic; }
|
||||
const OptionalFlag &isSensitive() const { return IsSensitive; }
|
||||
bool usesPositionalArg() const { return UsesPositionalArg; }
|
||||
|
||||
StringRef getMaskType() const { return MaskType; }
|
||||
void setMaskType(StringRef S) { MaskType = S; }
|
||||
|
||||
/// Changes the specifier and length according to a QualType, retaining any
|
||||
/// flags or options. Returns true on success, or false when a conversion
|
||||
/// was not successful.
|
||||
|
|
@ -685,6 +715,9 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Handle mask types whose sizes are not between one and eight bytes.
|
||||
virtual void handleInvalidMaskType(StringRef MaskType) {}
|
||||
|
||||
// Scanf-specific handlers.
|
||||
|
||||
virtual bool HandleInvalidScanfConversionSpecifier(
|
||||
|
|
@ -34,6 +34,7 @@ namespace clang {
|
|||
/// a VarDecl, a FunctionDecl or a BlockDecl.
|
||||
class GlobalDecl {
|
||||
llvm::PointerIntPair<const Decl *, 2> Value;
|
||||
unsigned MultiVersionIndex = 0;
|
||||
|
||||
void Init(const Decl *D) {
|
||||
assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
|
||||
|
|
@ -45,7 +46,10 @@ class GlobalDecl {
|
|||
public:
|
||||
GlobalDecl() = default;
|
||||
GlobalDecl(const VarDecl *D) { Init(D);}
|
||||
GlobalDecl(const FunctionDecl *D) { Init(D); }
|
||||
GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
|
||||
: MultiVersionIndex(MVIndex) {
|
||||
Init(D);
|
||||
}
|
||||
GlobalDecl(const BlockDecl *D) { Init(D); }
|
||||
GlobalDecl(const CapturedDecl *D) { Init(D); }
|
||||
GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
|
||||
|
|
@ -57,6 +61,7 @@ public:
|
|||
GlobalDecl CanonGD;
|
||||
CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
|
||||
CanonGD.Value.setInt(Value.getInt());
|
||||
CanonGD.MultiVersionIndex = MultiVersionIndex;
|
||||
|
||||
return CanonGD;
|
||||
}
|
||||
|
|
@ -73,8 +78,17 @@ public:
|
|||
return static_cast<CXXDtorType>(Value.getInt());
|
||||
}
|
||||
|
||||
unsigned getMultiVersionIndex() const {
|
||||
assert(isa<FunctionDecl>(getDecl()) &&
|
||||
!isa<CXXConstructorDecl>(getDecl()) &&
|
||||
!isa<CXXDestructorDecl>(getDecl()) &&
|
||||
"Decl is not a plain FunctionDecl!");
|
||||
return MultiVersionIndex;
|
||||
}
|
||||
|
||||
friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
|
||||
return LHS.Value == RHS.Value;
|
||||
return LHS.Value == RHS.Value &&
|
||||
LHS.MultiVersionIndex == RHS.MultiVersionIndex;
|
||||
}
|
||||
|
||||
void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
|
||||
|
|
@ -90,6 +104,16 @@ public:
|
|||
Result.Value.setPointer(D);
|
||||
return Result;
|
||||
}
|
||||
|
||||
GlobalDecl getWithMultiVersionIndex(unsigned Index) {
|
||||
assert(isa<FunctionDecl>(getDecl()) &&
|
||||
!isa<CXXConstructorDecl>(getDecl()) &&
|
||||
!isa<CXXDestructorDecl>(getDecl()) &&
|
||||
"Decl is not a plain FunctionDecl!");
|
||||
GlobalDecl Result(*this);
|
||||
Result.MultiVersionIndex = Index;
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
|
|
|||
|
|
@ -99,8 +99,8 @@ public:
|
|||
LexicallyNestedDeclarations.clear();
|
||||
for (++I; I != E; ++I) {
|
||||
Decl *Sibling = *I;
|
||||
if (!SM.isBeforeInTranslationUnit(Sibling->getLocStart(),
|
||||
Child->getLocEnd()))
|
||||
if (!SM.isBeforeInTranslationUnit(Sibling->getBeginLoc(),
|
||||
Child->getEndLoc()))
|
||||
break;
|
||||
if (!BaseType::canIgnoreChildDeclWhileTraversingDeclContext(Sibling))
|
||||
LexicallyNestedDeclarations.push_back(Sibling);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#ifndef LLVM_CLANG_AST_MANGLE_H
|
||||
#define LLVM_CLANG_AST_MANGLE_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/ABI.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
|
|
|||
|
|
@ -166,6 +166,14 @@ public:
|
|||
return getOrInitSelector(StringRef("isEqual"), isEqualSel);
|
||||
}
|
||||
|
||||
Selector getNewSelector() const {
|
||||
return getOrInitNullarySelector("new", NewSel);
|
||||
}
|
||||
|
||||
Selector getInitSelector() const {
|
||||
return getOrInitNullarySelector("init", InitSel);
|
||||
}
|
||||
|
||||
/// Enumerates the NSNumber methods used to generate literals.
|
||||
enum NSNumberLiteralMethodKind {
|
||||
NSNumberWithChar,
|
||||
|
|
@ -229,6 +237,7 @@ private:
|
|||
bool isObjCEnumerator(const Expr *E,
|
||||
StringRef name, IdentifierInfo *&II) const;
|
||||
Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const;
|
||||
Selector getOrInitNullarySelector(StringRef Id, Selector &Sel) const;
|
||||
|
||||
ASTContext &Ctx;
|
||||
|
||||
|
|
@ -251,7 +260,7 @@ private:
|
|||
|
||||
mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,
|
||||
setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,
|
||||
isEqualSel;
|
||||
isEqualSel, InitSel, NewSel;
|
||||
|
||||
mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
|
||||
mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId;
|
||||
|
|
|
|||
|
|
@ -212,9 +212,12 @@ public:
|
|||
/// parameter pack (for C++11 variadic templates).
|
||||
bool containsUnexpandedParameterPack() const;
|
||||
|
||||
/// Print this nested name specifier to the given output
|
||||
/// stream.
|
||||
void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
|
||||
/// Print this nested name specifier to the given output stream. If
|
||||
/// `ResolveTemplateArguments` is true, we'll print actual types, e.g.
|
||||
/// `ns::SomeTemplate<int, MyClass>` instead of
|
||||
/// `ns::SomeTemplate<Container::value_type, T>`.
|
||||
void print(raw_ostream &OS, const PrintingPolicy &Policy,
|
||||
bool ResolveTemplateArguments = false) const;
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) const {
|
||||
ID.AddPointer(Prefix.getOpaqueValue());
|
||||
|
|
@ -225,6 +228,8 @@ public:
|
|||
/// in debugging.
|
||||
void dump(const LangOptions &LO) const;
|
||||
void dump() const;
|
||||
void dump(llvm::raw_ostream &OS) const;
|
||||
void dump(llvm::raw_ostream &OS, const LangOptions &LO) const;
|
||||
};
|
||||
|
||||
/// A C++ nested-name-specifier augmented with source location
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@
|
|||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ODRHASH_H
|
||||
#define LLVM_CLANG_AST_ODRHASH_H
|
||||
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/AST/TemplateBase.h"
|
||||
|
|
@ -80,7 +83,7 @@ public:
|
|||
void AddIdentifierInfo(const IdentifierInfo *II);
|
||||
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS);
|
||||
void AddTemplateName(TemplateName Name);
|
||||
void AddDeclarationName(DeclarationName Name);
|
||||
void AddDeclarationName(DeclarationName Name, bool TreatAsDecl = false);
|
||||
void AddTemplateArgument(TemplateArgument TA);
|
||||
void AddTemplateParameterList(const TemplateParameterList *TPL);
|
||||
|
||||
|
|
@ -88,6 +91,11 @@ public:
|
|||
void AddBoolean(bool value);
|
||||
|
||||
static bool isWhitelistedDecl(const Decl* D, const DeclContext *Parent);
|
||||
|
||||
private:
|
||||
void AddDeclarationNameImpl(DeclarationName Name);
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -52,7 +52,10 @@ public:
|
|||
|
||||
// The item is corresponding to the '%m' format specifier, no value is
|
||||
// populated in the buffer and the runtime is loading the errno value.
|
||||
ErrnoKind
|
||||
ErrnoKind,
|
||||
|
||||
// The item is a mask type.
|
||||
MaskKind
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
@ -60,7 +63,10 @@ public:
|
|||
IsPrivate = 0x1,
|
||||
|
||||
// The item is marked "public" in the format string.
|
||||
IsPublic = 0x2
|
||||
IsPublic = 0x2,
|
||||
|
||||
// The item is marked "sensitive" in the format string.
|
||||
IsSensitive = 0x4 | IsPrivate
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
@ -69,21 +75,24 @@ private:
|
|||
CharUnits ConstValue;
|
||||
CharUnits Size; // size of the data, not including the header bytes
|
||||
unsigned Flags = 0;
|
||||
StringRef MaskType;
|
||||
|
||||
public:
|
||||
OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags)
|
||||
: TheKind(kind), TheExpr(expr), Size(size), Flags(flags) {}
|
||||
OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags,
|
||||
StringRef maskType = StringRef())
|
||||
: TheKind(kind), TheExpr(expr), Size(size), Flags(flags),
|
||||
MaskType(maskType) {
|
||||
assert(((Flags == 0) || (Flags == IsPrivate) || (Flags == IsPublic) ||
|
||||
(Flags == IsSensitive)) &&
|
||||
"unexpected privacy flag");
|
||||
}
|
||||
|
||||
OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)
|
||||
: TheKind(CountKind), ConstValue(value),
|
||||
Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {}
|
||||
|
||||
unsigned char getDescriptorByte() const {
|
||||
unsigned char result = 0;
|
||||
if (getIsPrivate())
|
||||
result |= IsPrivate;
|
||||
if (getIsPublic())
|
||||
result |= IsPublic;
|
||||
unsigned char result = Flags;
|
||||
result |= ((unsigned)getKind()) << 4;
|
||||
return result;
|
||||
}
|
||||
|
|
@ -92,11 +101,12 @@ public:
|
|||
|
||||
Kind getKind() const { return TheKind; }
|
||||
bool getIsPrivate() const { return (Flags & IsPrivate) != 0; }
|
||||
bool getIsPublic() const { return (Flags & IsPublic) != 0; }
|
||||
|
||||
const Expr *getExpr() const { return TheExpr; }
|
||||
CharUnits getConstValue() const { return ConstValue; }
|
||||
CharUnits size() const { return Size; }
|
||||
|
||||
StringRef getMaskType() const { return MaskType; }
|
||||
};
|
||||
|
||||
class OSLogBufferLayout {
|
||||
|
|
@ -120,14 +130,10 @@ public:
|
|||
Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); });
|
||||
}
|
||||
|
||||
bool hasPublicItems() const {
|
||||
return llvm::any_of(
|
||||
Items, [](const OSLogBufferItem &Item) { return Item.getIsPublic(); });
|
||||
}
|
||||
|
||||
bool hasNonScalar() const {
|
||||
bool hasNonScalarOrMask() const {
|
||||
return llvm::any_of(Items, [](const OSLogBufferItem &Item) {
|
||||
return Item.getKind() != OSLogBufferItem::ScalarKind;
|
||||
return Item.getKind() != OSLogBufferItem::ScalarKind ||
|
||||
!Item.getMaskType().empty();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +141,7 @@ public:
|
|||
unsigned char result = 0;
|
||||
if (hasPrivateItems())
|
||||
result |= HasPrivateItems;
|
||||
if (hasNonScalar())
|
||||
if (hasNonScalarOrMask())
|
||||
result |= HasNonScalarItems;
|
||||
return result;
|
||||
}
|
||||
|
|
@ -64,11 +64,9 @@ protected:
|
|||
|
||||
public:
|
||||
/// Returns the starting location of the clause.
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const { return StartLoc; }
|
||||
|
||||
/// Returns the ending location of the clause.
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const { return EndLoc; }
|
||||
|
||||
/// Sets the starting location of the clause.
|
||||
|
|
@ -736,6 +734,210 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// This represents 'unified_address' clause in the '#pragma omp requires'
|
||||
/// directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp requires unified_address
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp requires' has 'unified_address'
|
||||
/// clause.
|
||||
class OMPUnifiedAddressClause final : public OMPClause {
|
||||
public:
|
||||
friend class OMPClauseReader;
|
||||
/// Build 'unified_address' clause.
|
||||
///
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_unified_address, StartLoc, EndLoc) {}
|
||||
|
||||
/// Build an empty clause.
|
||||
OMPUnifiedAddressClause()
|
||||
: OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {}
|
||||
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_unified_address;
|
||||
}
|
||||
};
|
||||
|
||||
/// This represents 'unified_shared_memory' clause in the '#pragma omp requires'
|
||||
/// directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp requires unified_shared_memory
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp requires' has 'unified_shared_memory'
|
||||
/// clause.
|
||||
class OMPUnifiedSharedMemoryClause final : public OMPClause {
|
||||
public:
|
||||
friend class OMPClauseReader;
|
||||
/// Build 'unified_shared_memory' clause.
|
||||
///
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_unified_shared_memory, StartLoc, EndLoc) {}
|
||||
|
||||
/// Build an empty clause.
|
||||
OMPUnifiedSharedMemoryClause()
|
||||
: OMPClause(OMPC_unified_shared_memory, SourceLocation(), SourceLocation()) {}
|
||||
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_unified_shared_memory;
|
||||
}
|
||||
};
|
||||
|
||||
/// This represents 'reverse_offload' clause in the '#pragma omp requires'
|
||||
/// directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp requires reverse_offload
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp requires' has 'reverse_offload'
|
||||
/// clause.
|
||||
class OMPReverseOffloadClause final : public OMPClause {
|
||||
public:
|
||||
friend class OMPClauseReader;
|
||||
/// Build 'reverse_offload' clause.
|
||||
///
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_reverse_offload, StartLoc, EndLoc) {}
|
||||
|
||||
/// Build an empty clause.
|
||||
OMPReverseOffloadClause()
|
||||
: OMPClause(OMPC_reverse_offload, SourceLocation(), SourceLocation()) {}
|
||||
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_reverse_offload;
|
||||
}
|
||||
};
|
||||
|
||||
/// This represents 'dynamic_allocators' clause in the '#pragma omp requires'
|
||||
/// directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp requires dynamic_allocators
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp requires' has 'dynamic_allocators'
|
||||
/// clause.
|
||||
class OMPDynamicAllocatorsClause final : public OMPClause {
|
||||
public:
|
||||
friend class OMPClauseReader;
|
||||
/// Build 'dynamic_allocators' clause.
|
||||
///
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_dynamic_allocators, StartLoc, EndLoc) {}
|
||||
|
||||
/// Build an empty clause.
|
||||
OMPDynamicAllocatorsClause()
|
||||
: OMPClause(OMPC_dynamic_allocators, SourceLocation(), SourceLocation()) {
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_dynamic_allocators;
|
||||
}
|
||||
};
|
||||
|
||||
/// This represents 'atomic_default_mem_order' clause in the '#pragma omp
|
||||
/// requires' directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp requires atomic_default_mem_order(seq_cst)
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp requires' has simple
|
||||
/// atomic_default_mem_order' clause with kind 'seq_cst'.
|
||||
class OMPAtomicDefaultMemOrderClause final : public OMPClause {
|
||||
friend class OMPClauseReader;
|
||||
|
||||
/// Location of '('
|
||||
SourceLocation LParenLoc;
|
||||
|
||||
/// A kind of the 'atomic_default_mem_order' clause.
|
||||
OpenMPAtomicDefaultMemOrderClauseKind Kind =
|
||||
OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown;
|
||||
|
||||
/// Start location of the kind in source code.
|
||||
SourceLocation KindKwLoc;
|
||||
|
||||
/// Set kind of the clause.
|
||||
///
|
||||
/// \param K Kind of clause.
|
||||
void setAtomicDefaultMemOrderKind(OpenMPAtomicDefaultMemOrderClauseKind K) {
|
||||
Kind = K;
|
||||
}
|
||||
|
||||
/// Set clause kind location.
|
||||
///
|
||||
/// \param KLoc Kind location.
|
||||
void setAtomicDefaultMemOrderKindKwLoc(SourceLocation KLoc) {
|
||||
KindKwLoc = KLoc;
|
||||
}
|
||||
|
||||
public:
|
||||
/// Build 'atomic_default_mem_order' clause with argument \a A ('seq_cst',
|
||||
/// 'acq_rel' or 'relaxed').
|
||||
///
|
||||
/// \param A Argument of the clause ('seq_cst', 'acq_rel' or 'relaxed').
|
||||
/// \param ALoc Starting location of the argument.
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
OMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind A,
|
||||
SourceLocation ALoc, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_atomic_default_mem_order, StartLoc, EndLoc),
|
||||
LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
|
||||
|
||||
/// Build an empty clause.
|
||||
OMPAtomicDefaultMemOrderClause()
|
||||
: OMPClause(OMPC_atomic_default_mem_order, SourceLocation(),
|
||||
SourceLocation()) {}
|
||||
|
||||
/// Sets the location of '('.
|
||||
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
|
||||
|
||||
/// Returns the locaiton of '('.
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
|
||||
/// Returns kind of the clause.
|
||||
OpenMPAtomicDefaultMemOrderClauseKind getAtomicDefaultMemOrderKind() const {
|
||||
return Kind;
|
||||
}
|
||||
|
||||
/// Returns location of clause kind.
|
||||
SourceLocation getAtomicDefaultMemOrderKindKwLoc() const { return KindKwLoc; }
|
||||
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_atomic_default_mem_order;
|
||||
}
|
||||
};
|
||||
|
||||
/// This represents 'schedule' clause in the '#pragma omp ...' directive.
|
||||
///
|
||||
/// \code
|
||||
|
|
@ -992,8 +1194,8 @@ public:
|
|||
/// Set loop counter for the specified loop.
|
||||
void setLoopCounter(unsigned NumLoop, Expr *Counter);
|
||||
/// Get loops counter for the specified loop.
|
||||
Expr *getLoopCunter(unsigned NumLoop);
|
||||
const Expr *getLoopCunter(unsigned NumLoop) const;
|
||||
Expr *getLoopCounter(unsigned NumLoop);
|
||||
const Expr *getLoopCounter(unsigned NumLoop) const;
|
||||
|
||||
child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
|
||||
|
||||
|
|
@ -3859,8 +4061,19 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
|
|||
return getUniqueDeclarationsNum() + getTotalComponentListNum();
|
||||
}
|
||||
|
||||
/// Map type modifier for the 'map' clause.
|
||||
OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
|
||||
public:
|
||||
/// Number of allowed map-type-modifiers.
|
||||
static constexpr unsigned NumberOfModifiers =
|
||||
OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1;
|
||||
|
||||
private:
|
||||
/// Map-type-modifiers for the 'map' clause.
|
||||
OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = {
|
||||
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown
|
||||
};
|
||||
|
||||
/// Location of map-type-modifiers for the 'map' clause.
|
||||
SourceLocation MapTypeModifiersLoc[NumberOfModifiers];
|
||||
|
||||
/// Map type for the 'map' clause.
|
||||
OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
|
||||
|
|
@ -3878,7 +4091,8 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
|
|||
/// NumUniqueDeclarations declarations, \a NumComponentLists total component
|
||||
/// lists, and \a NumComponents total expression components.
|
||||
///
|
||||
/// \param MapTypeModifier Map type modifier.
|
||||
/// \param MapModifiers Map-type-modifiers.
|
||||
/// \param MapModifiersLoc Locations of map-type-modifiers.
|
||||
/// \param MapType Map type.
|
||||
/// \param MapTypeIsImplicit Map type is inferred implicitly.
|
||||
/// \param MapLoc Location of the map type.
|
||||
|
|
@ -3889,7 +4103,8 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
|
|||
/// clause.
|
||||
/// \param NumComponentLists Number of component lists in this clause.
|
||||
/// \param NumComponents Total number of expression components in the clause.
|
||||
explicit OMPMapClause(OpenMPMapClauseKind MapTypeModifier,
|
||||
explicit OMPMapClause(ArrayRef<OpenMPMapModifierKind> MapModifiers,
|
||||
ArrayRef<SourceLocation> MapModifiersLoc,
|
||||
OpenMPMapClauseKind MapType, bool MapTypeIsImplicit,
|
||||
SourceLocation MapLoc, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation EndLoc,
|
||||
|
|
@ -3898,8 +4113,17 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
|
|||
: OMPMappableExprListClause(OMPC_map, StartLoc, LParenLoc, EndLoc,
|
||||
NumVars, NumUniqueDeclarations,
|
||||
NumComponentLists, NumComponents),
|
||||
MapTypeModifier(MapTypeModifier), MapType(MapType),
|
||||
MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {}
|
||||
MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit),
|
||||
MapLoc(MapLoc) {
|
||||
assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size()
|
||||
&& "Unexpected number of map type modifiers.");
|
||||
llvm::copy(MapModifiers, std::begin(MapTypeModifiers));
|
||||
|
||||
assert(llvm::array_lengthof(MapTypeModifiersLoc) ==
|
||||
MapModifiersLoc.size() &&
|
||||
"Unexpected number of map type modifier locations.");
|
||||
llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc));
|
||||
}
|
||||
|
||||
/// Build an empty clause.
|
||||
///
|
||||
|
|
@ -3914,10 +4138,25 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
|
|||
OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(),
|
||||
NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
|
||||
|
||||
/// Set type modifier for the clause.
|
||||
/// Set map-type-modifier for the clause.
|
||||
///
|
||||
/// \param T Type Modifier for the clause.
|
||||
void setMapTypeModifier(OpenMPMapClauseKind T) { MapTypeModifier = T; }
|
||||
/// \param I index for map-type-modifier.
|
||||
/// \param T map-type-modifier for the clause.
|
||||
void setMapTypeModifier(unsigned I, OpenMPMapModifierKind T) {
|
||||
assert(I < NumberOfModifiers &&
|
||||
"Unexpected index to store map type modifier, exceeds array size.");
|
||||
MapTypeModifiers[I] = T;
|
||||
}
|
||||
|
||||
/// Set location for the map-type-modifier.
|
||||
///
|
||||
/// \param I index for map-type-modifier location.
|
||||
/// \param TLoc map-type-modifier location.
|
||||
void setMapTypeModifierLoc(unsigned I, SourceLocation TLoc) {
|
||||
assert(I < NumberOfModifiers &&
|
||||
"Index to store map type modifier location exceeds array size.");
|
||||
MapTypeModifiersLoc[I] = TLoc;
|
||||
}
|
||||
|
||||
/// Set type for the clause.
|
||||
///
|
||||
|
|
@ -3941,7 +4180,8 @@ public:
|
|||
/// \param Vars The original expression used in the clause.
|
||||
/// \param Declarations Declarations used in the clause.
|
||||
/// \param ComponentLists Component lists used in the clause.
|
||||
/// \param TypeModifier Map type modifier.
|
||||
/// \param MapModifiers Map-type-modifiers.
|
||||
/// \param MapModifiersLoc Location of map-type-modifiers.
|
||||
/// \param Type Map type.
|
||||
/// \param TypeIsImplicit Map type is inferred implicitly.
|
||||
/// \param TypeLoc Location of the map type.
|
||||
|
|
@ -3950,7 +4190,8 @@ public:
|
|||
ArrayRef<Expr *> Vars,
|
||||
ArrayRef<ValueDecl *> Declarations,
|
||||
MappableExprComponentListsRef ComponentLists,
|
||||
OpenMPMapClauseKind TypeModifier,
|
||||
ArrayRef<OpenMPMapModifierKind> MapModifiers,
|
||||
ArrayRef<SourceLocation> MapModifiersLoc,
|
||||
OpenMPMapClauseKind Type, bool TypeIsImplicit,
|
||||
SourceLocation TypeLoc);
|
||||
|
||||
|
|
@ -3980,9 +4221,33 @@ public:
|
|||
/// messages for some target directives.
|
||||
bool isImplicitMapType() const LLVM_READONLY { return MapTypeIsImplicit; }
|
||||
|
||||
/// Fetches the map type modifier for the clause.
|
||||
OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY {
|
||||
return MapTypeModifier;
|
||||
/// Fetches the map-type-modifier at 'Cnt' index of array of modifiers.
|
||||
///
|
||||
/// \param Cnt index for map-type-modifier.
|
||||
OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY {
|
||||
assert(Cnt < NumberOfModifiers &&
|
||||
"Requested modifier exceeds the total number of modifiers.");
|
||||
return MapTypeModifiers[Cnt];
|
||||
}
|
||||
|
||||
/// Fetches the map-type-modifier location at 'Cnt' index of array of
|
||||
/// modifiers' locations.
|
||||
///
|
||||
/// \param Cnt index for map-type-modifier location.
|
||||
SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY {
|
||||
assert(Cnt < NumberOfModifiers &&
|
||||
"Requested modifier location exceeds total number of modifiers.");
|
||||
return MapTypeModifiersLoc[Cnt];
|
||||
}
|
||||
|
||||
/// Fetches ArrayRef of map-type-modifiers.
|
||||
ArrayRef<OpenMPMapModifierKind> getMapTypeModifiers() const LLVM_READONLY {
|
||||
return llvm::makeArrayRef(MapTypeModifiers);
|
||||
}
|
||||
|
||||
/// Fetches ArrayRef of location of map-type-modifiers.
|
||||
ArrayRef<SourceLocation> getMapTypeModifiersLoc() const LLVM_READONLY {
|
||||
return llvm::makeArrayRef(MapTypeModifiersLoc);
|
||||
}
|
||||
|
||||
/// Fetches location of clause mapping kind.
|
||||
|
|
@ -5043,6 +5308,59 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// This class implements a simple visitor for OMPClause
|
||||
/// subclasses.
|
||||
template<class ImplClass, template <typename> class Ptr, typename RetTy>
|
||||
class OMPClauseVisitorBase {
|
||||
public:
|
||||
#define PTR(CLASS) typename Ptr<CLASS>::type
|
||||
#define DISPATCH(CLASS) \
|
||||
return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))
|
||||
|
||||
#define OPENMP_CLAUSE(Name, Class) \
|
||||
RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); }
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
|
||||
RetTy Visit(PTR(OMPClause) S) {
|
||||
// Top switch clause: visit each OMPClause.
|
||||
switch (S->getClauseKind()) {
|
||||
default: llvm_unreachable("Unknown clause kind!");
|
||||
#define OPENMP_CLAUSE(Name, Class) \
|
||||
case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S));
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
}
|
||||
}
|
||||
// Base case, ignore it. :)
|
||||
RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); }
|
||||
#undef PTR
|
||||
#undef DISPATCH
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using const_ptr = typename std::add_pointer<typename std::add_const<T>::type>;
|
||||
|
||||
template<class ImplClass, typename RetTy = void>
|
||||
class OMPClauseVisitor :
|
||||
public OMPClauseVisitorBase <ImplClass, std::add_pointer, RetTy> {};
|
||||
template<class ImplClass, typename RetTy = void>
|
||||
class ConstOMPClauseVisitor :
|
||||
public OMPClauseVisitorBase <ImplClass, const_ptr, RetTy> {};
|
||||
|
||||
class OMPClausePrinter final : public OMPClauseVisitor<OMPClausePrinter> {
|
||||
raw_ostream &OS;
|
||||
const PrintingPolicy &Policy;
|
||||
|
||||
/// Process clauses with list of variables.
|
||||
template <typename T> void VisitOMPClauseList(T *Node, char StartSym);
|
||||
|
||||
public:
|
||||
OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
|
||||
: OS(OS), Policy(Policy) {}
|
||||
|
||||
#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S);
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
|
||||
|
|
|
|||
|
|
@ -197,6 +197,14 @@ CAST_OPERATION(IntegralToBoolean)
|
|||
/// float f = i;
|
||||
CAST_OPERATION(IntegralToFloating)
|
||||
|
||||
/// CK_FixedPointCast - Fixed point to fixed point.
|
||||
/// (_Accum) 0.5r
|
||||
CAST_OPERATION(FixedPointCast)
|
||||
|
||||
/// CK_FixedPointToBoolean - Fixed point to boolean.
|
||||
/// (bool) 0.5r
|
||||
CAST_OPERATION(FixedPointToBoolean)
|
||||
|
||||
/// CK_FloatingToIntegral - Floating point to integral. Rounds
|
||||
/// towards zero, discarding any fractional component.
|
||||
/// (int) f
|
||||
|
|
@ -318,11 +326,9 @@ CAST_OPERATION(CopyAndAutoreleaseBlockObject)
|
|||
// callee of a call expression.
|
||||
CAST_OPERATION(BuiltinFnToFnPtr)
|
||||
|
||||
// Convert a zero value for OpenCL event_t initialization.
|
||||
CAST_OPERATION(ZeroToOCLEvent)
|
||||
|
||||
// Convert a zero value for OpenCL queue_t initialization.
|
||||
CAST_OPERATION(ZeroToOCLQueue)
|
||||
// Convert a zero value for OpenCL opaque types initialization (event_t,
|
||||
// queue_t, etc.)
|
||||
CAST_OPERATION(ZeroToOCLOpaqueType)
|
||||
|
||||
// Convert a pointer to a different address space.
|
||||
CAST_OPERATION(AddressSpaceConversion)
|
||||
|
|
|
|||
|
|
@ -38,21 +38,20 @@ public:
|
|||
struct PrintingPolicy {
|
||||
/// Create a default printing policy for the specified language.
|
||||
PrintingPolicy(const LangOptions &LO)
|
||||
: Indentation(2), SuppressSpecifiers(false),
|
||||
SuppressTagKeyword(LO.CPlusPlus),
|
||||
IncludeTagDefinition(false), SuppressScope(false),
|
||||
SuppressUnwrittenScope(false), SuppressInitializers(false),
|
||||
ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
|
||||
SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
|
||||
SuppressTemplateArgsInCXXConstructors(false),
|
||||
Bool(LO.Bool), Restrict(LO.C99),
|
||||
Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11),
|
||||
UseVoidForZeroParams(!LO.CPlusPlus),
|
||||
TerseOutput(false), PolishForDeclaration(false),
|
||||
Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
|
||||
IncludeNewlines(true), MSVCFormatting(false),
|
||||
ConstantsAsWritten(false), SuppressImplicitBase(false),
|
||||
FullyQualifiedName(false) { }
|
||||
: Indentation(2), SuppressSpecifiers(false),
|
||||
SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false),
|
||||
SuppressScope(false), SuppressUnwrittenScope(false),
|
||||
SuppressInitializers(false), ConstantArraySizeAsWritten(false),
|
||||
AnonymousTagLocations(true), SuppressStrongLifetime(false),
|
||||
SuppressLifetimeQualifiers(false),
|
||||
SuppressTemplateArgsInCXXConstructors(false), Bool(LO.Bool),
|
||||
Restrict(LO.C99), Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11),
|
||||
UseVoidForZeroParams(!LO.CPlusPlus), TerseOutput(false),
|
||||
PolishForDeclaration(false), Half(LO.Half),
|
||||
MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
|
||||
MSVCFormatting(false), ConstantsAsWritten(false),
|
||||
SuppressImplicitBase(false), FullyQualifiedName(false),
|
||||
RemapFilePaths(false), PrintCanonicalTypes(false) {}
|
||||
|
||||
/// Adjust this printing policy for cases where it's known that we're
|
||||
/// printing C++ code (for instance, if AST dumping reaches a C++-only
|
||||
|
|
@ -81,7 +80,7 @@ struct PrintingPolicy {
|
|||
/// declaration for "x", so that we will print "int *x"; it will be
|
||||
/// \c true when we print "y", so that we suppress printing the
|
||||
/// "const int" type specifier and instead only print the "*y".
|
||||
bool SuppressSpecifiers : 1;
|
||||
unsigned SuppressSpecifiers : 1;
|
||||
|
||||
/// Whether type printing should skip printing the tag keyword.
|
||||
///
|
||||
|
|
@ -91,7 +90,7 @@ struct PrintingPolicy {
|
|||
/// \code
|
||||
/// struct Geometry::Point;
|
||||
/// \endcode
|
||||
bool SuppressTagKeyword : 1;
|
||||
unsigned SuppressTagKeyword : 1;
|
||||
|
||||
/// When true, include the body of a tag definition.
|
||||
///
|
||||
|
|
@ -101,14 +100,14 @@ struct PrintingPolicy {
|
|||
/// \code
|
||||
/// typedef struct { int x, y; } Point;
|
||||
/// \endcode
|
||||
bool IncludeTagDefinition : 1;
|
||||
unsigned IncludeTagDefinition : 1;
|
||||
|
||||
/// Suppresses printing of scope specifiers.
|
||||
bool SuppressScope : 1;
|
||||
unsigned SuppressScope : 1;
|
||||
|
||||
/// Suppress printing parts of scope specifiers that don't need
|
||||
/// to be written, e.g., for inline or anonymous namespaces.
|
||||
bool SuppressUnwrittenScope : 1;
|
||||
unsigned SuppressUnwrittenScope : 1;
|
||||
|
||||
/// Suppress printing of variable initializers.
|
||||
///
|
||||
|
|
@ -121,7 +120,7 @@ struct PrintingPolicy {
|
|||
///
|
||||
/// SuppressInitializers will be true when printing "auto x", so that the
|
||||
/// internal initializer constructed for x will not be printed.
|
||||
bool SuppressInitializers : 1;
|
||||
unsigned SuppressInitializers : 1;
|
||||
|
||||
/// Whether we should print the sizes of constant array expressions as written
|
||||
/// in the sources.
|
||||
|
|
@ -139,12 +138,12 @@ struct PrintingPolicy {
|
|||
/// int a[104];
|
||||
/// char a[9] = "A string";
|
||||
/// \endcode
|
||||
bool ConstantArraySizeAsWritten : 1;
|
||||
unsigned ConstantArraySizeAsWritten : 1;
|
||||
|
||||
/// When printing an anonymous tag name, also print the location of that
|
||||
/// entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just prints
|
||||
/// "(anonymous)" for the name.
|
||||
bool AnonymousTagLocations : 1;
|
||||
unsigned AnonymousTagLocations : 1;
|
||||
|
||||
/// When true, suppress printing of the __strong lifetime qualifier in ARC.
|
||||
unsigned SuppressStrongLifetime : 1;
|
||||
|
|
@ -199,7 +198,7 @@ struct PrintingPolicy {
|
|||
/// Use whitespace and punctuation like MSVC does. In particular, this prints
|
||||
/// anonymous namespaces as `anonymous namespace' and does not insert spaces
|
||||
/// after template arguments.
|
||||
bool MSVCFormatting : 1;
|
||||
unsigned MSVCFormatting : 1;
|
||||
|
||||
/// Whether we should print the constant expressions as written in the
|
||||
/// sources.
|
||||
|
|
@ -217,14 +216,23 @@ struct PrintingPolicy {
|
|||
/// 0x10
|
||||
/// 2.5e3
|
||||
/// \endcode
|
||||
bool ConstantsAsWritten : 1;
|
||||
unsigned ConstantsAsWritten : 1;
|
||||
|
||||
/// When true, don't print the implicit 'self' or 'this' expressions.
|
||||
bool SuppressImplicitBase : 1;
|
||||
unsigned 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;
|
||||
unsigned FullyQualifiedName : 1;
|
||||
|
||||
/// Whether to apply -fdebug-prefix-map to any file paths.
|
||||
unsigned RemapFilePaths : 1;
|
||||
|
||||
/// Whether to print types as written or canonically.
|
||||
unsigned PrintCanonicalTypes : 1;
|
||||
|
||||
/// When RemapFilePaths is true, this function performs the action.
|
||||
std::function<std::string(StringRef)> remapPath;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
|
|
|||
|
|
@ -101,9 +101,7 @@ public:
|
|||
}
|
||||
|
||||
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
|
||||
|
||||
const char *getBriefText(const ASTContext &Context) const {
|
||||
|
|
@ -182,7 +180,7 @@ public:
|
|||
explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { }
|
||||
|
||||
bool operator()(const RawComment &LHS, const RawComment &RHS) {
|
||||
return SM.isBeforeInTranslationUnit(LHS.getLocStart(), RHS.getLocStart());
|
||||
return SM.isBeforeInTranslationUnit(LHS.getBeginLoc(), RHS.getBeginLoc());
|
||||
}
|
||||
|
||||
bool operator()(const RawComment *LHS, const RawComment *RHS) {
|
||||
|
|
|
|||
|
|
@ -176,6 +176,16 @@ public:
|
|||
/// Return whether this visitor should traverse post-order.
|
||||
bool shouldTraversePostOrder() const { return false; }
|
||||
|
||||
/// Recursively visits an entire AST, starting from the top-level Decls
|
||||
/// in the AST traversal scope (by default, the TranslationUnitDecl).
|
||||
/// \returns false if visitation was terminated early.
|
||||
bool TraverseAST(ASTContext &AST) {
|
||||
for (Decl *D : AST.getTraversalScope())
|
||||
if (!getDerived().TraverseDecl(D))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Recursively visit a statement or expression, by
|
||||
/// dispatching to Traverse*() based on the argument's dynamic type.
|
||||
///
|
||||
|
|
@ -288,14 +298,6 @@ public:
|
|||
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
|
||||
Expr *Init);
|
||||
|
||||
/// Recursively visit the body of a lambda expression.
|
||||
///
|
||||
/// This provides a hook for visitors that need more context when visiting
|
||||
/// \c LE->getBody().
|
||||
///
|
||||
/// \returns false if the visitation was terminated early, true otherwise.
|
||||
bool TraverseLambdaBody(LambdaExpr *LE, DataRecursionQueue *Queue = nullptr);
|
||||
|
||||
/// Recursively visit the syntactic or semantic form of an
|
||||
/// initialization list.
|
||||
///
|
||||
|
|
@ -926,13 +928,6 @@ RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(
|
||||
LambdaExpr *LE, DataRecursionQueue *Queue) {
|
||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(LE->getBody());
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------- Type traversal -----------------
|
||||
|
||||
// This macro makes available a variable T, the passed-in type.
|
||||
|
|
@ -1373,9 +1368,14 @@ DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
|
|||
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);
|
||||
// BlockDecls are traversed through BlockExprs,
|
||||
// CapturedDecls are traversed through CapturedStmts.
|
||||
if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child))
|
||||
return true;
|
||||
// Lambda classes are traversed through LambdaExprs.
|
||||
if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child))
|
||||
return Cls->isLambda();
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
|
|
@ -1589,6 +1589,12 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
|
|||
for (auto *I : D->varlists()) {
|
||||
TRY_TO(TraverseStmt(I));
|
||||
}
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_DECL(OMPRequiresDecl, {
|
||||
for (auto *C : D->clauselists()) {
|
||||
TRY_TO(TraverseOMPClause(C));
|
||||
}
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, {
|
||||
|
|
@ -2174,6 +2180,8 @@ DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
|
|||
|
||||
DEF_TRAVERSE_STMT(CXXForRangeStmt, {
|
||||
if (!getDerived().shouldVisitImplicitCode()) {
|
||||
if (S->getInit())
|
||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit());
|
||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
|
||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
|
||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
|
||||
|
|
@ -2191,6 +2199,8 @@ DEF_TRAVERSE_STMT(ReturnStmt, {})
|
|||
DEF_TRAVERSE_STMT(SwitchStmt, {})
|
||||
DEF_TRAVERSE_STMT(WhileStmt, {})
|
||||
|
||||
DEF_TRAVERSE_STMT(ConstantExpr, {})
|
||||
|
||||
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
|
||||
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
|
||||
TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
|
||||
|
|
@ -2384,6 +2394,7 @@ DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
|
|||
|
||||
// Walk only the visible parts of lambda expressions.
|
||||
DEF_TRAVERSE_STMT(LambdaExpr, {
|
||||
// Visit the capture list.
|
||||
for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
|
||||
const LambdaCapture *C = S->capture_begin() + I;
|
||||
if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
|
||||
|
|
@ -2391,32 +2402,31 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
|
|||
}
|
||||
}
|
||||
|
||||
TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
|
||||
FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
|
||||
|
||||
if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
|
||||
// Visit the whole type.
|
||||
TRY_TO(TraverseTypeLoc(TL));
|
||||
if (getDerived().shouldVisitImplicitCode()) {
|
||||
// The implicit model is simple: everything else is in the lambda class.
|
||||
TRY_TO(TraverseDecl(S->getLambdaClass()));
|
||||
} else {
|
||||
// We need to poke around to find the bits that might be explicitly written.
|
||||
TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
|
||||
FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
|
||||
|
||||
if (S->hasExplicitParameters()) {
|
||||
// Visit parameters.
|
||||
for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
|
||||
for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
|
||||
TRY_TO(TraverseDecl(Proto.getParam(I)));
|
||||
}
|
||||
} else if (S->hasExplicitResultType()) {
|
||||
TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
|
||||
}
|
||||
if (S->hasExplicitResultType())
|
||||
TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
|
||||
|
||||
auto *T = Proto.getTypePtr();
|
||||
for (const auto &E : T->exceptions()) {
|
||||
for (const auto &E : T->exceptions())
|
||||
TRY_TO(TraverseType(E));
|
||||
}
|
||||
|
||||
if (Expr *NE = T->getNoexceptExpr())
|
||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE);
|
||||
}
|
||||
|
||||
ReturnValue = TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue);
|
||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
|
||||
}
|
||||
ShouldVisitChildren = false;
|
||||
})
|
||||
|
||||
|
|
@ -2853,6 +2863,36 @@ bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedAddressClause(
|
||||
OMPUnifiedAddressClause *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedSharedMemoryClause(
|
||||
OMPUnifiedSharedMemoryClause *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPReverseOffloadClause(
|
||||
OMPReverseOffloadClause *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPDynamicAllocatorsClause(
|
||||
OMPDynamicAllocatorsClause *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPAtomicDefaultMemOrderClause(
|
||||
OMPAtomicDefaultMemOrderClause *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool
|
||||
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -41,11 +41,9 @@ public:
|
|||
CXXCatchStmt(EmptyShell Empty)
|
||||
: Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return CatchLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return HandlerBlock->getLocEnd();
|
||||
return HandlerBlock->getEndLoc();
|
||||
}
|
||||
|
||||
SourceLocation getCatchLoc() const { return CatchLoc; }
|
||||
|
|
@ -88,13 +86,11 @@ public:
|
|||
static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
|
||||
unsigned numHandlers);
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return getTryLoc(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
|
||||
SourceLocation getTryLoc() const { return TryLoc; }
|
||||
SourceLocation getEndLoc() const {
|
||||
return getStmts()[NumHandlers]->getLocEnd();
|
||||
return getStmts()[NumHandlers]->getEndLoc();
|
||||
}
|
||||
|
||||
CompoundStmt *getTryBlock() {
|
||||
|
|
@ -122,14 +118,15 @@ public:
|
|||
};
|
||||
|
||||
/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
|
||||
/// statement, represented as 'for (range-declarator : range-expression)'.
|
||||
/// statement, represented as 'for (range-declarator : range-expression)'
|
||||
/// or 'for (init-statement range-declarator : range-expression)'.
|
||||
///
|
||||
/// This is stored in a partially-desugared form to allow full semantic
|
||||
/// analysis of the constituent components. The original syntactic components
|
||||
/// can be extracted using getLoopVariable and getRangeInit.
|
||||
class CXXForRangeStmt : public Stmt {
|
||||
SourceLocation ForLoc;
|
||||
enum { RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END };
|
||||
enum { INIT, RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END };
|
||||
// SubExprs[RANGE] is an expression or declstmt.
|
||||
// SubExprs[COND] and SubExprs[INC] are expressions.
|
||||
Stmt *SubExprs[END];
|
||||
|
|
@ -139,16 +136,17 @@ class CXXForRangeStmt : public Stmt {
|
|||
|
||||
friend class ASTStmtReader;
|
||||
public:
|
||||
CXXForRangeStmt(DeclStmt *Range, DeclStmt *Begin, DeclStmt *End,
|
||||
Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
|
||||
SourceLocation FL, SourceLocation CAL, SourceLocation CL,
|
||||
SourceLocation RPL);
|
||||
CXXForRangeStmt(Stmt *InitStmt, DeclStmt *Range, DeclStmt *Begin,
|
||||
DeclStmt *End, Expr *Cond, Expr *Inc, DeclStmt *LoopVar,
|
||||
Stmt *Body, SourceLocation FL, SourceLocation CAL,
|
||||
SourceLocation CL, SourceLocation RPL);
|
||||
CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
|
||||
|
||||
|
||||
Stmt *getInit() { return SubExprs[INIT]; }
|
||||
VarDecl *getLoopVariable();
|
||||
Expr *getRangeInit();
|
||||
|
||||
const Stmt *getInit() const { return SubExprs[INIT]; }
|
||||
const VarDecl *getLoopVariable() const;
|
||||
const Expr *getRangeInit() const;
|
||||
|
||||
|
|
@ -183,6 +181,7 @@ public:
|
|||
}
|
||||
const Stmt *getBody() const { return SubExprs[BODY]; }
|
||||
|
||||
void setInit(Stmt *S) { SubExprs[INIT] = S; }
|
||||
void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
|
||||
void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
|
||||
void setBeginStmt(Stmt *S) { SubExprs[BEGINSTMT] = S; }
|
||||
|
|
@ -197,11 +196,9 @@ public:
|
|||
SourceLocation getColonLoc() const { return ColonLoc; }
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return ForLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return SubExprs[BODY]->getLocEnd();
|
||||
return SubExprs[BODY]->getEndLoc();
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
|
|
@ -285,11 +282,9 @@ public:
|
|||
return reinterpret_cast<CompoundStmt *>(SubStmt);
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return SubStmt->getLocEnd();
|
||||
return SubStmt->getEndLoc();
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
|
|
@ -408,14 +403,12 @@ public:
|
|||
return {getStoredStmts() + SubStmt::FirstParamMove, NumParams};
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY {
|
||||
return getBody() ? getBody()->getLocStart()
|
||||
: getPromiseDecl()->getLocStart();
|
||||
return getBody() ? getBody()->getBeginLoc()
|
||||
: getPromiseDecl()->getBeginLoc();
|
||||
}
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return getBody() ? getBody()->getLocEnd() : getPromiseDecl()->getLocEnd();
|
||||
return getBody() ? getBody()->getEndLoc() : getPromiseDecl()->getEndLoc();
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
|
|
@ -475,11 +468,9 @@ public:
|
|||
bool isImplicit() const { return IsImplicit; }
|
||||
void setIsImplicit(bool value = true) { IsImplicit = value; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return CoreturnLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return getOperand() ? getOperand()->getLocEnd() : getLocStart();
|
||||
return getOperand() ? getOperand()->getEndLoc() : getBeginLoc();
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ class Stmt {
|
|||
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));
|
||||
addData(data_collection::getMacroStack(S->getBeginLoc(), Context));
|
||||
addData(data_collection::getMacroStack(S->getEndLoc(), Context));
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ class ExpressionTraitExpr {
|
|||
}
|
||||
class PredefinedExpr {
|
||||
code Code = [{
|
||||
addData(S->getIdentType());
|
||||
addData(S->getIdentKind());
|
||||
}];
|
||||
}
|
||||
class TypeTraitExpr {
|
||||
|
|
|
|||
|
|
@ -55,11 +55,9 @@ public:
|
|||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return ForLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return SubExprs[BODY]->getLocEnd();
|
||||
return SubExprs[BODY]->getEndLoc();
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
|
|
@ -106,10 +104,8 @@ public:
|
|||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtCatchLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return Body->getLocEnd(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY { return Body->getEndLoc(); }
|
||||
|
||||
bool hasEllipsis() const { return getCatchParamDecl() == nullptr; }
|
||||
|
||||
|
|
@ -137,11 +133,9 @@ public:
|
|||
Stmt *getFinallyBody() { return AtFinallyStmt; }
|
||||
void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtFinallyLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return AtFinallyStmt->getLocEnd();
|
||||
return AtFinallyStmt->getEndLoc();
|
||||
}
|
||||
|
||||
SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
|
||||
|
|
@ -244,9 +238,7 @@ public:
|
|||
getStmts()[1 + NumCatchStmts] = S;
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtTryLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY;
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
|
|
@ -303,11 +295,9 @@ public:
|
|||
}
|
||||
void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtSynchronizedLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return getSynchBody()->getLocEnd();
|
||||
return getSynchBody()->getEndLoc();
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
|
|
@ -339,11 +329,9 @@ public:
|
|||
SourceLocation getThrowLoc() const LLVM_READONLY { return AtThrowLoc; }
|
||||
void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtThrowLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return Throw ? Throw->getLocEnd() : AtThrowLoc;
|
||||
return Throw ? Throw->getEndLoc() : AtThrowLoc;
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
|
|
@ -369,11 +357,9 @@ public:
|
|||
Stmt *getSubStmt() { return SubStmt; }
|
||||
void setSubStmt(Stmt *S) { SubStmt = S; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return SubStmt->getLocEnd();
|
||||
return SubStmt->getEndLoc();
|
||||
}
|
||||
|
||||
SourceLocation getAtLoc() const { return AtLoc; }
|
||||
|
|
|
|||
|
|
@ -165,10 +165,8 @@ public:
|
|||
}
|
||||
|
||||
/// Returns starting location of directive kind.
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const { return StartLoc; }
|
||||
/// Returns ending location of directive.
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
SourceLocation getEndLoc() const { return EndLoc; }
|
||||
|
||||
/// Set starting location of directive kind.
|
||||
|
|
@ -394,9 +392,11 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
|||
CombinedConditionOffset = 25,
|
||||
CombinedNextLowerBoundOffset = 26,
|
||||
CombinedNextUpperBoundOffset = 27,
|
||||
CombinedDistConditionOffset = 28,
|
||||
CombinedParForInDistConditionOffset = 29,
|
||||
// Offset to the end (and start of the following counters/updates/finals
|
||||
// arrays) for combined distribute loop directives.
|
||||
CombinedDistributeEnd = 28,
|
||||
CombinedDistributeEnd = 30,
|
||||
};
|
||||
|
||||
/// Get the counters storage.
|
||||
|
|
@ -607,6 +607,17 @@ protected:
|
|||
"expected loop bound sharing directive");
|
||||
*std::next(child_begin(), CombinedNextUpperBoundOffset) = CombNUB;
|
||||
}
|
||||
void setCombinedDistCond(Expr *CombDistCond) {
|
||||
assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
||||
"expected loop bound distribute sharing directive");
|
||||
*std::next(child_begin(), CombinedDistConditionOffset) = CombDistCond;
|
||||
}
|
||||
void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
|
||||
assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
||||
"expected loop bound distribute sharing directive");
|
||||
*std::next(child_begin(),
|
||||
CombinedParForInDistConditionOffset) = CombParForInDistCond;
|
||||
}
|
||||
void setCounters(ArrayRef<Expr *> A);
|
||||
void setPrivateCounters(ArrayRef<Expr *> A);
|
||||
void setInits(ArrayRef<Expr *> A);
|
||||
|
|
@ -639,6 +650,13 @@ public:
|
|||
/// Update of UpperBound for statically scheduled omp loops for
|
||||
/// outer loop in combined constructs (e.g. 'distribute parallel for')
|
||||
Expr *NUB;
|
||||
/// Distribute Loop condition used when composing 'omp distribute'
|
||||
/// with 'omp for' in a same construct when schedule is chunked.
|
||||
Expr *DistCond;
|
||||
/// 'omp parallel for' loop condition used when composed with
|
||||
/// 'omp distribute' in the same construct and when schedule is
|
||||
/// chunked and the chunk size is 1.
|
||||
Expr *ParForInDistCond;
|
||||
};
|
||||
|
||||
/// The expressions built for the OpenMP loop CodeGen for the
|
||||
|
|
@ -756,6 +774,8 @@ public:
|
|||
DistCombinedFields.Cond = nullptr;
|
||||
DistCombinedFields.NLB = nullptr;
|
||||
DistCombinedFields.NUB = nullptr;
|
||||
DistCombinedFields.DistCond = nullptr;
|
||||
DistCombinedFields.ParForInDistCond = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -924,6 +944,18 @@ public:
|
|||
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
||||
*std::next(child_begin(), CombinedNextUpperBoundOffset)));
|
||||
}
|
||||
Expr *getCombinedDistCond() const {
|
||||
assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
||||
"expected loop bound distribute sharing directive");
|
||||
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
||||
*std::next(child_begin(), CombinedDistConditionOffset)));
|
||||
}
|
||||
Expr *getCombinedParForInDistCond() const {
|
||||
assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
||||
"expected loop bound distribute sharing directive");
|
||||
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
||||
*std::next(child_begin(), CombinedParForInDistConditionOffset)));
|
||||
}
|
||||
const Stmt *getBody() const {
|
||||
// This relies on the loop form is already checked by Sema.
|
||||
const Stmt *Body =
|
||||
|
|
|
|||
|
|
@ -22,15 +22,12 @@
|
|||
#include "clang/AST/StmtObjC.h"
|
||||
#include "clang/AST/StmtOpenMP.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
template <typename T> struct make_ptr { using type = T *; };
|
||||
template <typename T> struct make_const_ptr { using type = const T *; };
|
||||
|
||||
/// StmtVisitorBase - This class implements a simple visitor for Stmt
|
||||
/// subclasses. Since Expr derives from Stmt, this also includes support for
|
||||
/// visiting Exprs.
|
||||
|
|
@ -182,53 +179,19 @@ public:
|
|||
///
|
||||
/// This class does not preserve constness of Stmt pointers (see also
|
||||
/// ConstStmtVisitor).
|
||||
template<typename ImplClass, typename RetTy=void, typename... ParamTys>
|
||||
template <typename ImplClass, typename RetTy = void, typename... ParamTys>
|
||||
class StmtVisitor
|
||||
: public StmtVisitorBase<make_ptr, ImplClass, RetTy, ParamTys...> {};
|
||||
: public StmtVisitorBase<std::add_pointer, ImplClass, RetTy, ParamTys...> {
|
||||
};
|
||||
|
||||
/// ConstStmtVisitor - This class implements a simple visitor for Stmt
|
||||
/// subclasses. Since Expr derives from Stmt, this also includes support for
|
||||
/// visiting Exprs.
|
||||
///
|
||||
/// This class preserves constness of Stmt pointers (see also StmtVisitor).
|
||||
template<typename ImplClass, typename RetTy=void, typename... ParamTys>
|
||||
class ConstStmtVisitor
|
||||
: public StmtVisitorBase<make_const_ptr, ImplClass, RetTy, ParamTys...> {};
|
||||
|
||||
/// This class implements a simple visitor for OMPClause
|
||||
/// subclasses.
|
||||
template<class ImplClass, template <typename> class Ptr, typename RetTy>
|
||||
class OMPClauseVisitorBase {
|
||||
public:
|
||||
#define PTR(CLASS) typename Ptr<CLASS>::type
|
||||
#define DISPATCH(CLASS) \
|
||||
return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))
|
||||
|
||||
#define OPENMP_CLAUSE(Name, Class) \
|
||||
RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); }
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
|
||||
RetTy Visit(PTR(OMPClause) S) {
|
||||
// Top switch clause: visit each OMPClause.
|
||||
switch (S->getClauseKind()) {
|
||||
default: llvm_unreachable("Unknown clause kind!");
|
||||
#define OPENMP_CLAUSE(Name, Class) \
|
||||
case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S));
|
||||
#include "clang/Basic/OpenMPKinds.def"
|
||||
}
|
||||
}
|
||||
// Base case, ignore it. :)
|
||||
RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); }
|
||||
#undef PTR
|
||||
#undef DISPATCH
|
||||
};
|
||||
|
||||
template<class ImplClass, typename RetTy = void>
|
||||
class OMPClauseVisitor :
|
||||
public OMPClauseVisitorBase <ImplClass, make_ptr, RetTy> {};
|
||||
template<class ImplClass, typename RetTy = void>
|
||||
class ConstOMPClauseVisitor :
|
||||
public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {};
|
||||
template <typename ImplClass, typename RetTy = void, typename... ParamTys>
|
||||
class ConstStmtVisitor : public StmtVisitorBase<llvm::make_const_ptr, ImplClass,
|
||||
RetTy, ParamTys...> {};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
//===- TemplateArgumentVisitor.h - Visitor for TArg subclasses --*- 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 TemplateArgumentVisitor interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H
|
||||
#define LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H
|
||||
|
||||
#include "clang/AST/TemplateBase.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace templateargumentvisitor {
|
||||
|
||||
/// A simple visitor class that helps create template argument visitors.
|
||||
template <template <typename> class Ref, typename ImplClass,
|
||||
typename RetTy = void, typename... ParamTys>
|
||||
class Base {
|
||||
public:
|
||||
#define REF(CLASS) typename Ref<CLASS>::type
|
||||
#define DISPATCH(NAME) \
|
||||
case TemplateArgument::NAME: \
|
||||
return static_cast<ImplClass *>(this)->Visit##NAME##TemplateArgument( \
|
||||
TA, std::forward<ParamTys>(P)...)
|
||||
|
||||
RetTy Visit(REF(TemplateArgument) TA, ParamTys... P) {
|
||||
switch (TA.getKind()) {
|
||||
DISPATCH(Null);
|
||||
DISPATCH(Type);
|
||||
DISPATCH(Declaration);
|
||||
DISPATCH(NullPtr);
|
||||
DISPATCH(Integral);
|
||||
DISPATCH(Template);
|
||||
DISPATCH(TemplateExpansion);
|
||||
DISPATCH(Expression);
|
||||
DISPATCH(Pack);
|
||||
}
|
||||
llvm_unreachable("TemplateArgument is not covered in switch!");
|
||||
}
|
||||
|
||||
// If the implementation chooses not to implement a certain visit
|
||||
// method, fall back to the parent.
|
||||
|
||||
#define VISIT_METHOD(CATEGORY) \
|
||||
RetTy Visit##CATEGORY##TemplateArgument(REF(TemplateArgument) TA, \
|
||||
ParamTys... P) { \
|
||||
return VisitTemplateArgument(TA, std::forward<ParamTys>(P)...); \
|
||||
}
|
||||
|
||||
VISIT_METHOD(Null);
|
||||
VISIT_METHOD(Type);
|
||||
VISIT_METHOD(Declaration);
|
||||
VISIT_METHOD(NullPtr);
|
||||
VISIT_METHOD(Integral);
|
||||
VISIT_METHOD(Template);
|
||||
VISIT_METHOD(TemplateExpansion);
|
||||
VISIT_METHOD(Expression);
|
||||
VISIT_METHOD(Pack);
|
||||
|
||||
RetTy VisitTemplateArgument(REF(TemplateArgument), ParamTys...) {
|
||||
return RetTy();
|
||||
}
|
||||
|
||||
#undef REF
|
||||
#undef DISPATCH
|
||||
#undef VISIT_METHOD
|
||||
};
|
||||
|
||||
} // namespace templateargumentvisitor
|
||||
|
||||
/// A simple visitor class that helps create template argument visitors.
|
||||
///
|
||||
/// This class does not preserve constness of TemplateArgument references (see
|
||||
/// also ConstTemplateArgumentVisitor).
|
||||
template <typename ImplClass, typename RetTy = void, typename... ParamTys>
|
||||
class TemplateArgumentVisitor
|
||||
: public templateargumentvisitor::Base<std::add_lvalue_reference, ImplClass,
|
||||
RetTy, ParamTys...> {};
|
||||
|
||||
/// A simple visitor class that helps create template argument visitors.
|
||||
///
|
||||
/// This class preserves constness of TemplateArgument references (see also
|
||||
/// TemplateArgumentVisitor).
|
||||
template <typename ImplClass, typename RetTy = void, typename... ParamTys>
|
||||
class ConstTemplateArgumentVisitor
|
||||
: public templateargumentvisitor::Base<llvm::make_const_ref, ImplClass,
|
||||
RetTy, ParamTys...> {};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_TEMPLATEARGUMENTVISITOR_H
|
||||
|
|
@ -467,7 +467,7 @@ public:
|
|||
: Argument(Argument), LocInfo(E) {
|
||||
|
||||
// Permit any kind of template argument that can be represented with an
|
||||
// expression
|
||||
// expression.
|
||||
assert(Argument.getKind() == TemplateArgument::NullPtr ||
|
||||
Argument.getKind() == TemplateArgument::Integral ||
|
||||
Argument.getKind() == TemplateArgument::Declaration ||
|
||||
|
|
@ -530,19 +530,22 @@ public:
|
|||
}
|
||||
|
||||
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
|
||||
assert(Argument.getKind() == TemplateArgument::Template ||
|
||||
Argument.getKind() == TemplateArgument::TemplateExpansion);
|
||||
if (Argument.getKind() != TemplateArgument::Template &&
|
||||
Argument.getKind() != TemplateArgument::TemplateExpansion)
|
||||
return NestedNameSpecifierLoc();
|
||||
return LocInfo.getTemplateQualifierLoc();
|
||||
}
|
||||
|
||||
SourceLocation getTemplateNameLoc() const {
|
||||
assert(Argument.getKind() == TemplateArgument::Template ||
|
||||
Argument.getKind() == TemplateArgument::TemplateExpansion);
|
||||
if (Argument.getKind() != TemplateArgument::Template &&
|
||||
Argument.getKind() != TemplateArgument::TemplateExpansion)
|
||||
return SourceLocation();
|
||||
return LocInfo.getTemplateNameLoc();
|
||||
}
|
||||
|
||||
SourceLocation getTemplateEllipsisLoc() const {
|
||||
assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
|
||||
if (Argument.getKind() != TemplateArgument::TemplateExpansion)
|
||||
return SourceLocation();
|
||||
return LocInfo.getTemplateEllipsisLoc();
|
||||
}
|
||||
};
|
||||
|
|
@ -617,13 +620,17 @@ public:
|
|||
/// The number of template arguments in TemplateArgs.
|
||||
unsigned NumTemplateArgs;
|
||||
|
||||
SourceLocation getLAngleLoc() const { return LAngleLoc; }
|
||||
SourceLocation getRAngleLoc() const { return RAngleLoc; }
|
||||
|
||||
/// Retrieve the template arguments
|
||||
const TemplateArgumentLoc *getTemplateArgs() const {
|
||||
return getTrailingObjects<TemplateArgumentLoc>();
|
||||
}
|
||||
unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
|
||||
|
||||
llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
|
||||
return llvm::makeArrayRef(getTemplateArgs(), NumTemplateArgs);
|
||||
return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
|
||||
}
|
||||
|
||||
const TemplateArgumentLoc &operator[](unsigned I) const {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
|
||||
#define LLVM_CLANG_AST_TEMPLATENAME_H
|
||||
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
|
|
|
|||
298
contrib/llvm/tools/clang/include/clang/AST/TextNodeDumper.h
Normal file
298
contrib/llvm/tools/clang/include/clang/AST/TextNodeDumper.h
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
//===--- TextNodeDumper.h - Printing of AST nodes -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements AST dumping of components of individual AST nodes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_TEXTNODEDUMPER_H
|
||||
#define LLVM_CLANG_AST_TEXTNODEDUMPER_H
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/ASTDumperUtils.h"
|
||||
#include "clang/AST/AttrVisitor.h"
|
||||
#include "clang/AST/CommentCommandTraits.h"
|
||||
#include "clang/AST/CommentVisitor.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
#include "clang/AST/TemplateArgumentVisitor.h"
|
||||
#include "clang/AST/TypeVisitor.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class TextTreeStructure {
|
||||
raw_ostream &OS;
|
||||
const bool ShowColors;
|
||||
|
||||
/// Pending[i] is an action to dump an entity at level i.
|
||||
llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending;
|
||||
|
||||
/// Indicates whether we're at the top level.
|
||||
bool TopLevel = true;
|
||||
|
||||
/// Indicates if we're handling the first child after entering a new depth.
|
||||
bool FirstChild = true;
|
||||
|
||||
/// Prefix for currently-being-dumped entity.
|
||||
std::string Prefix;
|
||||
|
||||
public:
|
||||
/// Add a child of the current node. Calls DoAddChild without arguments
|
||||
template <typename Fn> void AddChild(Fn DoAddChild) {
|
||||
return AddChild("", DoAddChild);
|
||||
}
|
||||
|
||||
/// Add a child of the current node with an optional label.
|
||||
/// Calls DoAddChild without arguments.
|
||||
template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
|
||||
// If we're at the top level, there's nothing interesting to do; just
|
||||
// run the dumper.
|
||||
if (TopLevel) {
|
||||
TopLevel = false;
|
||||
DoAddChild();
|
||||
while (!Pending.empty()) {
|
||||
Pending.back()(true);
|
||||
Pending.pop_back();
|
||||
}
|
||||
Prefix.clear();
|
||||
OS << "\n";
|
||||
TopLevel = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to capture an owning-string in the lambda because the lambda
|
||||
// is invoked in a deferred manner.
|
||||
std::string LabelStr = Label;
|
||||
auto DumpWithIndent = [this, DoAddChild, LabelStr](bool IsLastChild) {
|
||||
// Print out the appropriate tree structure and work out the prefix for
|
||||
// children of this node. For instance:
|
||||
//
|
||||
// A Prefix = ""
|
||||
// |-B Prefix = "| "
|
||||
// | `-C Prefix = "| "
|
||||
// `-D Prefix = " "
|
||||
// |-E Prefix = " | "
|
||||
// `-F Prefix = " "
|
||||
// G Prefix = ""
|
||||
//
|
||||
// Note that the first level gets no prefix.
|
||||
{
|
||||
OS << '\n';
|
||||
ColorScope Color(OS, ShowColors, IndentColor);
|
||||
OS << Prefix << (IsLastChild ? '`' : '|') << '-';
|
||||
if (!LabelStr.empty())
|
||||
OS << LabelStr << ": ";
|
||||
|
||||
this->Prefix.push_back(IsLastChild ? ' ' : '|');
|
||||
this->Prefix.push_back(' ');
|
||||
}
|
||||
|
||||
FirstChild = true;
|
||||
unsigned Depth = Pending.size();
|
||||
|
||||
DoAddChild();
|
||||
|
||||
// If any children are left, they're the last at their nesting level.
|
||||
// Dump those ones out now.
|
||||
while (Depth < Pending.size()) {
|
||||
Pending.back()(true);
|
||||
this->Pending.pop_back();
|
||||
}
|
||||
|
||||
// Restore the old prefix.
|
||||
this->Prefix.resize(Prefix.size() - 2);
|
||||
};
|
||||
|
||||
if (FirstChild) {
|
||||
Pending.push_back(std::move(DumpWithIndent));
|
||||
} else {
|
||||
Pending.back()(false);
|
||||
Pending.back() = std::move(DumpWithIndent);
|
||||
}
|
||||
FirstChild = false;
|
||||
}
|
||||
|
||||
TextTreeStructure(raw_ostream &OS, bool ShowColors)
|
||||
: OS(OS), ShowColors(ShowColors) {}
|
||||
};
|
||||
|
||||
class TextNodeDumper
|
||||
: public TextTreeStructure,
|
||||
public comments::ConstCommentVisitor<TextNodeDumper, void,
|
||||
const comments::FullComment *>,
|
||||
public ConstAttrVisitor<TextNodeDumper>,
|
||||
public ConstTemplateArgumentVisitor<TextNodeDumper>,
|
||||
public ConstStmtVisitor<TextNodeDumper>,
|
||||
public TypeVisitor<TextNodeDumper> {
|
||||
raw_ostream &OS;
|
||||
const bool ShowColors;
|
||||
|
||||
/// Keep track of the last location we print out so that we can
|
||||
/// print out deltas from then on out.
|
||||
const char *LastLocFilename = "";
|
||||
unsigned LastLocLine = ~0U;
|
||||
|
||||
const SourceManager *SM;
|
||||
|
||||
/// The policy to use for printing; can be defaulted.
|
||||
PrintingPolicy PrintPolicy;
|
||||
|
||||
const comments::CommandTraits *Traits;
|
||||
|
||||
const char *getCommandName(unsigned CommandID);
|
||||
|
||||
public:
|
||||
TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM,
|
||||
const PrintingPolicy &PrintPolicy,
|
||||
const comments::CommandTraits *Traits);
|
||||
|
||||
void Visit(const comments::Comment *C, const comments::FullComment *FC);
|
||||
|
||||
void Visit(const Attr *A);
|
||||
|
||||
void Visit(const TemplateArgument &TA, SourceRange R,
|
||||
const Decl *From = nullptr, StringRef Label = {});
|
||||
|
||||
void Visit(const Stmt *Node);
|
||||
|
||||
void Visit(const Type *T);
|
||||
|
||||
void Visit(QualType T);
|
||||
|
||||
void Visit(const Decl *D);
|
||||
|
||||
void Visit(const CXXCtorInitializer *Init);
|
||||
|
||||
void Visit(const OMPClause *C);
|
||||
|
||||
void Visit(const BlockDecl::Capture &C);
|
||||
|
||||
void dumpPointer(const void *Ptr);
|
||||
void dumpLocation(SourceLocation Loc);
|
||||
void dumpSourceRange(SourceRange R);
|
||||
void dumpBareType(QualType T, bool Desugar = true);
|
||||
void dumpType(QualType T);
|
||||
void dumpBareDeclRef(const Decl *D);
|
||||
void dumpName(const NamedDecl *ND);
|
||||
void dumpAccessSpecifier(AccessSpecifier AS);
|
||||
|
||||
void dumpDeclRef(const Decl *D, StringRef Label = {});
|
||||
|
||||
void visitTextComment(const comments::TextComment *C,
|
||||
const comments::FullComment *);
|
||||
void visitInlineCommandComment(const comments::InlineCommandComment *C,
|
||||
const comments::FullComment *);
|
||||
void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C,
|
||||
const comments::FullComment *);
|
||||
void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C,
|
||||
const comments::FullComment *);
|
||||
void visitBlockCommandComment(const comments::BlockCommandComment *C,
|
||||
const comments::FullComment *);
|
||||
void visitParamCommandComment(const comments::ParamCommandComment *C,
|
||||
const comments::FullComment *FC);
|
||||
void visitTParamCommandComment(const comments::TParamCommandComment *C,
|
||||
const comments::FullComment *FC);
|
||||
void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C,
|
||||
const comments::FullComment *);
|
||||
void
|
||||
visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C,
|
||||
const comments::FullComment *);
|
||||
void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
|
||||
const comments::FullComment *);
|
||||
|
||||
// Implements Visit methods for Attrs.
|
||||
#include "clang/AST/AttrTextNodeDump.inc"
|
||||
|
||||
void VisitNullTemplateArgument(const TemplateArgument &TA);
|
||||
void VisitTypeTemplateArgument(const TemplateArgument &TA);
|
||||
void VisitDeclarationTemplateArgument(const TemplateArgument &TA);
|
||||
void VisitNullPtrTemplateArgument(const TemplateArgument &TA);
|
||||
void VisitIntegralTemplateArgument(const TemplateArgument &TA);
|
||||
void VisitTemplateTemplateArgument(const TemplateArgument &TA);
|
||||
void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA);
|
||||
void VisitExpressionTemplateArgument(const TemplateArgument &TA);
|
||||
void VisitPackTemplateArgument(const TemplateArgument &TA);
|
||||
|
||||
void VisitIfStmt(const IfStmt *Node);
|
||||
void VisitSwitchStmt(const SwitchStmt *Node);
|
||||
void VisitWhileStmt(const WhileStmt *Node);
|
||||
void VisitLabelStmt(const LabelStmt *Node);
|
||||
void VisitGotoStmt(const GotoStmt *Node);
|
||||
void VisitCaseStmt(const CaseStmt *Node);
|
||||
void VisitCallExpr(const CallExpr *Node);
|
||||
void VisitCastExpr(const CastExpr *Node);
|
||||
void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
|
||||
void VisitDeclRefExpr(const DeclRefExpr *Node);
|
||||
void VisitPredefinedExpr(const PredefinedExpr *Node);
|
||||
void VisitCharacterLiteral(const CharacterLiteral *Node);
|
||||
void VisitIntegerLiteral(const IntegerLiteral *Node);
|
||||
void VisitFixedPointLiteral(const FixedPointLiteral *Node);
|
||||
void VisitFloatingLiteral(const FloatingLiteral *Node);
|
||||
void VisitStringLiteral(const StringLiteral *Str);
|
||||
void VisitInitListExpr(const InitListExpr *ILE);
|
||||
void VisitUnaryOperator(const UnaryOperator *Node);
|
||||
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
|
||||
void VisitMemberExpr(const MemberExpr *Node);
|
||||
void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
|
||||
void VisitBinaryOperator(const BinaryOperator *Node);
|
||||
void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
|
||||
void VisitAddrLabelExpr(const AddrLabelExpr *Node);
|
||||
void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
|
||||
void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
|
||||
void VisitCXXThisExpr(const CXXThisExpr *Node);
|
||||
void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
|
||||
void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
|
||||
void VisitCXXConstructExpr(const CXXConstructExpr *Node);
|
||||
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
|
||||
void VisitCXXNewExpr(const CXXNewExpr *Node);
|
||||
void VisitCXXDeleteExpr(const CXXDeleteExpr *Node);
|
||||
void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
|
||||
void VisitExprWithCleanups(const ExprWithCleanups *Node);
|
||||
void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
|
||||
void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
|
||||
void
|
||||
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *Node);
|
||||
void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
|
||||
void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
|
||||
void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
|
||||
void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
|
||||
void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
|
||||
void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
|
||||
void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
|
||||
void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
|
||||
void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
|
||||
void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
|
||||
|
||||
void VisitRValueReferenceType(const ReferenceType *T);
|
||||
void VisitArrayType(const ArrayType *T);
|
||||
void VisitConstantArrayType(const ConstantArrayType *T);
|
||||
void VisitVariableArrayType(const VariableArrayType *T);
|
||||
void VisitDependentSizedArrayType(const DependentSizedArrayType *T);
|
||||
void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T);
|
||||
void VisitVectorType(const VectorType *T);
|
||||
void VisitFunctionType(const FunctionType *T);
|
||||
void VisitFunctionProtoType(const FunctionProtoType *T);
|
||||
void VisitUnresolvedUsingType(const UnresolvedUsingType *T);
|
||||
void VisitTypedefType(const TypedefType *T);
|
||||
void VisitUnaryTransformType(const UnaryTransformType *T);
|
||||
void VisitTagType(const TagType *T);
|
||||
void VisitTemplateTypeParmType(const TemplateTypeParmType *T);
|
||||
void VisitAutoType(const AutoType *T);
|
||||
void VisitTemplateSpecializationType(const TemplateSpecializationType *T);
|
||||
void VisitInjectedClassNameType(const InjectedClassNameType *T);
|
||||
void VisitObjCInterfaceType(const ObjCInterfaceType *T);
|
||||
void VisitPackExpansionType(const PackExpansionType *T);
|
||||
|
||||
private:
|
||||
void dumpCXXTemporary(const CXXTemporary *Temporary);
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_TEXTNODEDUMPER_H
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef LLVM_CLANG_AST_TYPELOC_H
|
||||
#define LLVM_CLANG_AST_TYPELOC_H
|
||||
|
||||
#include "clang/AST/Attr.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/AST/TemplateBase.h"
|
||||
|
|
@ -151,8 +152,6 @@ public:
|
|||
return SourceRange(getBeginLoc(), getEndLoc());
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
|
||||
|
||||
/// Get the local source range.
|
||||
SourceRange getLocalSourceRange() const {
|
||||
|
|
@ -843,16 +842,7 @@ class SubstTemplateTypeParmPackTypeLoc :
|
|||
};
|
||||
|
||||
struct AttributedLocInfo {
|
||||
union {
|
||||
Expr *ExprOperand;
|
||||
|
||||
/// A raw SourceLocation.
|
||||
unsigned EnumOperandLoc;
|
||||
};
|
||||
|
||||
SourceRange OperandParens;
|
||||
|
||||
SourceLocation AttrLoc;
|
||||
const Attr *TypeAttr;
|
||||
};
|
||||
|
||||
/// Type source information for an attributed type.
|
||||
|
|
@ -861,24 +851,10 @@ class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
|
|||
AttributedType,
|
||||
AttributedLocInfo> {
|
||||
public:
|
||||
AttributedType::Kind getAttrKind() const {
|
||||
attr::Kind getAttrKind() const {
|
||||
return getTypePtr()->getAttrKind();
|
||||
}
|
||||
|
||||
bool hasAttrExprOperand() const {
|
||||
return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
|
||||
getAttrKind() <= AttributedType::LastExprOperandKind);
|
||||
}
|
||||
|
||||
bool hasAttrEnumOperand() const {
|
||||
return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
|
||||
getAttrKind() <= AttributedType::LastEnumOperandKind);
|
||||
}
|
||||
|
||||
bool hasAttrOperand() const {
|
||||
return hasAttrExprOperand() || hasAttrEnumOperand();
|
||||
}
|
||||
|
||||
bool isQualifier() const {
|
||||
return getTypePtr()->isQualifier();
|
||||
}
|
||||
|
|
@ -891,51 +867,16 @@ public:
|
|||
return getInnerTypeLoc();
|
||||
}
|
||||
|
||||
/// The location of the attribute name, i.e.
|
||||
/// __attribute__((regparm(1000)))
|
||||
/// ^~~~~~~
|
||||
SourceLocation getAttrNameLoc() const {
|
||||
return getLocalData()->AttrLoc;
|
||||
/// The type attribute.
|
||||
const Attr *getAttr() const {
|
||||
return getLocalData()->TypeAttr;
|
||||
}
|
||||
void setAttrNameLoc(SourceLocation loc) {
|
||||
getLocalData()->AttrLoc = loc;
|
||||
void setAttr(const Attr *A) {
|
||||
getLocalData()->TypeAttr = A;
|
||||
}
|
||||
|
||||
/// The attribute's expression operand, if it has one.
|
||||
/// void *cur_thread __attribute__((address_space(21)))
|
||||
/// ^~
|
||||
Expr *getAttrExprOperand() const {
|
||||
assert(hasAttrExprOperand());
|
||||
return getLocalData()->ExprOperand;
|
||||
}
|
||||
void setAttrExprOperand(Expr *e) {
|
||||
assert(hasAttrExprOperand());
|
||||
getLocalData()->ExprOperand = e;
|
||||
}
|
||||
|
||||
/// The location of the attribute's enumerated operand, if it has one.
|
||||
/// void * __attribute__((objc_gc(weak)))
|
||||
/// ^~~~
|
||||
SourceLocation getAttrEnumOperandLoc() const {
|
||||
assert(hasAttrEnumOperand());
|
||||
return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
|
||||
}
|
||||
void setAttrEnumOperandLoc(SourceLocation loc) {
|
||||
assert(hasAttrEnumOperand());
|
||||
getLocalData()->EnumOperandLoc = loc.getRawEncoding();
|
||||
}
|
||||
|
||||
/// The location of the parentheses around the operand, if there is
|
||||
/// an operand.
|
||||
/// void * __attribute__((objc_gc(weak)))
|
||||
/// ^ ^
|
||||
SourceRange getAttrOperandParensRange() const {
|
||||
assert(hasAttrOperand());
|
||||
return getLocalData()->OperandParens;
|
||||
}
|
||||
void setAttrOperandParensRange(SourceRange range) {
|
||||
assert(hasAttrOperand());
|
||||
getLocalData()->OperandParens = range;
|
||||
template<typename T> const T *getAttrAs() {
|
||||
return dyn_cast_or_null<T>(getAttr());
|
||||
}
|
||||
|
||||
SourceRange getLocalSourceRange() const {
|
||||
|
|
@ -948,21 +889,11 @@ public:
|
|||
// ^~ ~~
|
||||
// That enclosure doesn't necessarily belong to a single attribute
|
||||
// anyway.
|
||||
SourceRange range(getAttrNameLoc());
|
||||
if (hasAttrOperand())
|
||||
range.setEnd(getAttrOperandParensRange().getEnd());
|
||||
return range;
|
||||
return getAttr() ? getAttr()->getRange() : SourceRange();
|
||||
}
|
||||
|
||||
void initializeLocal(ASTContext &Context, SourceLocation loc) {
|
||||
setAttrNameLoc(loc);
|
||||
if (hasAttrExprOperand()) {
|
||||
setAttrOperandParensRange(SourceRange(loc));
|
||||
setAttrExprOperand(nullptr);
|
||||
} else if (hasAttrEnumOperand()) {
|
||||
setAttrOperandParensRange(SourceRange(loc));
|
||||
setAttrEnumOperandLoc(loc);
|
||||
}
|
||||
setAttr(nullptr);
|
||||
}
|
||||
|
||||
QualType getInnerType() const {
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
|
|||
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
|
||||
auto &SourceManager = Finder->getASTContext().getSourceManager();
|
||||
return SourceManager.isInMainFile(
|
||||
SourceManager.getExpansionLoc(Node.getLocStart()));
|
||||
SourceManager.getExpansionLoc(Node.getBeginLoc()));
|
||||
}
|
||||
|
||||
/// Matches AST nodes that were expanded within system-header-files.
|
||||
|
|
@ -265,7 +265,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
|
|||
AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
|
||||
auto &SourceManager = Finder->getASTContext().getSourceManager();
|
||||
auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
|
||||
auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc());
|
||||
if (ExpansionLoc.isInvalid()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -291,7 +291,7 @@ AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
|
|||
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
|
||||
std::string, RegExp) {
|
||||
auto &SourceManager = Finder->getASTContext().getSourceManager();
|
||||
auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
|
||||
auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc());
|
||||
if (ExpansionLoc.isInvalid()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -420,6 +420,25 @@ extern const internal::VariadicDynCastAllOfMatcher<
|
|||
Decl, ClassTemplateSpecializationDecl>
|
||||
classTemplateSpecializationDecl;
|
||||
|
||||
/// Matches C++ class template partial specializations.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
/// template<class T1, class T2, int I>
|
||||
/// class A {};
|
||||
///
|
||||
/// template<class T, int I>
|
||||
/// class A<T, T*, I> {};
|
||||
///
|
||||
/// template<>
|
||||
/// class A<int, int, 1> {};
|
||||
/// \endcode
|
||||
/// classTemplatePartialSpecializationDecl()
|
||||
/// matches the specialization \c A<T,T*,I> but not \c A<int,int,1>
|
||||
extern const internal::VariadicDynCastAllOfMatcher<
|
||||
Decl, ClassTemplatePartialSpecializationDecl>
|
||||
classTemplatePartialSpecializationDecl;
|
||||
|
||||
/// Matches declarator declarations (field, variable, function
|
||||
/// and non-type template parameter declarations).
|
||||
///
|
||||
|
|
@ -626,12 +645,12 @@ AST_MATCHER(FunctionDecl, isMain) {
|
|||
///
|
||||
/// Given
|
||||
/// \code
|
||||
/// tempalate<typename T> class A {};
|
||||
/// typedef A<int> B;
|
||||
/// template<typename T> class A {}; #1
|
||||
/// template<> class A<int> {}; #2
|
||||
/// \endcode
|
||||
/// classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
|
||||
/// matches 'B' with classTemplateDecl() matching the class template
|
||||
/// declaration of 'A'.
|
||||
/// matches '#2' with classTemplateDecl() matching the class template
|
||||
/// declaration of 'A' at #1.
|
||||
AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate,
|
||||
internal::Matcher<ClassTemplateDecl>, InnerMatcher) {
|
||||
const ClassTemplateDecl* Decl = Node.getSpecializedTemplate();
|
||||
|
|
@ -792,11 +811,70 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts,
|
|||
/// varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))
|
||||
/// \endcode
|
||||
/// would match the declaration for fp.
|
||||
AST_MATCHER_P(QualType, ignoringParens,
|
||||
internal::Matcher<QualType>, InnerMatcher) {
|
||||
AST_MATCHER_P_OVERLOAD(QualType, ignoringParens, internal::Matcher<QualType>,
|
||||
InnerMatcher, 0) {
|
||||
return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
|
||||
}
|
||||
|
||||
/// Overload \c ignoringParens for \c Expr.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
/// const char* str = ("my-string");
|
||||
/// \endcode
|
||||
/// The matcher
|
||||
/// \code
|
||||
/// implicitCastExpr(hasSourceExpression(ignoringParens(stringLiteral())))
|
||||
/// \endcode
|
||||
/// would match the implicit cast resulting from the assignment.
|
||||
AST_MATCHER_P_OVERLOAD(Expr, ignoringParens, internal::Matcher<Expr>,
|
||||
InnerMatcher, 1) {
|
||||
const Expr *E = Node.IgnoreParens();
|
||||
return InnerMatcher.matches(*E, Finder, Builder);
|
||||
}
|
||||
|
||||
/// Matches expressions that are instantiation-dependent even if it is
|
||||
/// neither type- nor value-dependent.
|
||||
///
|
||||
/// In the following example, the expression sizeof(sizeof(T() + T()))
|
||||
/// is instantiation-dependent (since it involves a template parameter T),
|
||||
/// but is neither type- nor value-dependent, since the type of the inner
|
||||
/// sizeof is known (std::size_t) and therefore the size of the outer
|
||||
/// sizeof is known.
|
||||
/// \code
|
||||
/// template<typename T>
|
||||
/// void f(T x, T y) { sizeof(sizeof(T() + T()); }
|
||||
/// \endcode
|
||||
/// expr(isInstantiationDependent()) matches sizeof(sizeof(T() + T())
|
||||
AST_MATCHER(Expr, isInstantiationDependent) {
|
||||
return Node.isInstantiationDependent();
|
||||
}
|
||||
|
||||
/// Matches expressions that are type-dependent because the template type
|
||||
/// is not yet instantiated.
|
||||
///
|
||||
/// For example, the expressions "x" and "x + y" are type-dependent in
|
||||
/// the following code, but "y" is not type-dependent:
|
||||
/// \code
|
||||
/// template<typename T>
|
||||
/// void add(T x, int y) {
|
||||
/// x + y;
|
||||
/// }
|
||||
/// \endcode
|
||||
/// expr(isTypeDependent()) matches x + y
|
||||
AST_MATCHER(Expr, isTypeDependent) { return Node.isTypeDependent(); }
|
||||
|
||||
/// Matches expression that are value-dependent because they contain a
|
||||
/// non-type template parameter.
|
||||
///
|
||||
/// For example, the array bound of "Chars" in the following example is
|
||||
/// value-dependent.
|
||||
/// \code
|
||||
/// template<int Size> int f() { return Size; }
|
||||
/// \endcode
|
||||
/// expr(isValueDependent()) matches return Size
|
||||
AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); }
|
||||
|
||||
/// Matches classTemplateSpecializations, templateSpecializationType and
|
||||
/// functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
|
||||
///
|
||||
|
|
@ -868,7 +946,7 @@ AST_MATCHER_P(TemplateArgument, refersToType,
|
|||
/// Given
|
||||
/// \code
|
||||
/// template<template <typename> class S> class X {};
|
||||
/// template<typename T> class Y {};"
|
||||
/// template<typename T> class Y {};
|
||||
/// X<Y> xi;
|
||||
/// \endcode
|
||||
/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
|
||||
|
|
@ -1080,6 +1158,17 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
|
|||
/// matches 'm'.
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
|
||||
|
||||
/// Matches indirect field declarations.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
/// struct X { struct { int a; }; };
|
||||
/// \endcode
|
||||
/// indirectFieldDecl()
|
||||
/// matches 'a'.
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Decl, IndirectFieldDecl>
|
||||
indirectFieldDecl;
|
||||
|
||||
/// Matches function declarations.
|
||||
///
|
||||
/// Example matches f
|
||||
|
|
@ -1141,6 +1230,34 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
|
|||
/// matches this->x, x, y.x, a, this->b
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
|
||||
|
||||
/// Matches unresolved member expressions.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
/// struct X {
|
||||
/// template <class T> void f();
|
||||
/// void g();
|
||||
/// };
|
||||
/// template <class T> void h() { X x; x.f<T>(); x.g(); }
|
||||
/// \endcode
|
||||
/// unresolvedMemberExpr()
|
||||
/// matches x.f<T>
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedMemberExpr>
|
||||
unresolvedMemberExpr;
|
||||
|
||||
/// Matches member expressions where the actual member referenced could not be
|
||||
/// resolved because the base expression or the member name was dependent.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
/// template <class T> void f() { T t; t.g(); }
|
||||
/// \endcode
|
||||
/// cxxDependentScopeMemberExpr()
|
||||
/// matches t.g
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
|
||||
CXXDependentScopeMemberExpr>
|
||||
cxxDependentScopeMemberExpr;
|
||||
|
||||
/// Matches call expressions.
|
||||
///
|
||||
/// Example matches x.y() and y()
|
||||
|
|
@ -1151,6 +1268,28 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
|
|||
/// \endcode
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
|
||||
|
||||
/// Matches call expressions which were resolved using ADL.
|
||||
///
|
||||
/// Example matches y(x) but not y(42) or NS::y(x).
|
||||
/// \code
|
||||
/// namespace NS {
|
||||
/// struct X {};
|
||||
/// void y(X);
|
||||
/// }
|
||||
///
|
||||
/// void y(...);
|
||||
///
|
||||
/// void test() {
|
||||
/// NS::X x;
|
||||
/// y(x); // Matches
|
||||
/// NS::y(x); // Doesn't match
|
||||
/// y(42); // Doesn't match
|
||||
/// using NS::y;
|
||||
/// y(x); // Found by both unqualified lookup and ADL, doesn't match
|
||||
// }
|
||||
/// \endcode
|
||||
AST_MATCHER(CallExpr, usesADL) { return Node.usesADL(); }
|
||||
|
||||
/// Matches lambda expressions.
|
||||
///
|
||||
/// Example matches [&](){return 5;}
|
||||
|
|
@ -1485,6 +1624,18 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl,
|
|||
UnresolvedUsingTypenameDecl>
|
||||
unresolvedUsingTypenameDecl;
|
||||
|
||||
/// Matches a constant expression wrapper.
|
||||
///
|
||||
/// Example matches the constant in the case statement:
|
||||
/// (matcher = constantExpr())
|
||||
/// \code
|
||||
/// switch (a) {
|
||||
/// case 37: break;
|
||||
/// }
|
||||
/// \endcode
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr>
|
||||
constantExpr;
|
||||
|
||||
/// Matches parentheses used in expressions.
|
||||
///
|
||||
/// Example matches (foo() + 1)
|
||||
|
|
@ -1658,6 +1809,14 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr>
|
|||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr>
|
||||
objcIvarRefExpr;
|
||||
|
||||
/// Matches a reference to a block.
|
||||
///
|
||||
/// Example: matches "^{}":
|
||||
/// \code
|
||||
/// void f() { ^{}(); }
|
||||
/// \endcode
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, BlockExpr> blockExpr;
|
||||
|
||||
/// Matches if statements.
|
||||
///
|
||||
/// Example matches 'if (x) {}'
|
||||
|
|
@ -1975,6 +2134,11 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
|
|||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral>
|
||||
floatLiteral;
|
||||
|
||||
/// Matches imaginary literals, which are based on integer and floating
|
||||
/// point literals e.g.: 1i, 1.0i
|
||||
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral>
|
||||
imaginaryLiteral;
|
||||
|
||||
/// Matches user defined literal operator call.
|
||||
///
|
||||
/// Example match: "foo"_suffix
|
||||
|
|
@ -2331,8 +2495,9 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
|
|||
/// alignof.
|
||||
inline internal::Matcher<Stmt> alignOfExpr(
|
||||
const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
|
||||
return stmt(unaryExprOrTypeTraitExpr(allOf(
|
||||
ofKind(UETT_AlignOf), InnerMatcher)));
|
||||
return stmt(unaryExprOrTypeTraitExpr(
|
||||
allOf(anyOf(ofKind(UETT_AlignOf), ofKind(UETT_PreferredAlignOf)),
|
||||
InnerMatcher)));
|
||||
}
|
||||
|
||||
/// Same as unaryExprOrTypeTraitExpr, but only matching
|
||||
|
|
@ -3205,6 +3370,20 @@ AST_MATCHER_P(
|
|||
InnerMatcher.matches(*Initializer, Finder, Builder));
|
||||
}
|
||||
|
||||
/// \brief Matches a static variable with local scope.
|
||||
///
|
||||
/// Example matches y (matcher = varDecl(isStaticLocal()))
|
||||
/// \code
|
||||
/// void f() {
|
||||
/// int x;
|
||||
/// static int y;
|
||||
/// }
|
||||
/// static int z;
|
||||
/// \endcode
|
||||
AST_MATCHER(VarDecl, isStaticLocal) {
|
||||
return Node.isStaticLocal();
|
||||
}
|
||||
|
||||
/// Matches a variable declaration that has function scope and is a
|
||||
/// non-static local variable.
|
||||
///
|
||||
|
|
@ -3335,6 +3514,19 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument,
|
|||
*Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
|
||||
}
|
||||
|
||||
/// Matches the n'th item of an initializer list expression.
|
||||
///
|
||||
/// Example matches y.
|
||||
/// (matcher = initListExpr(hasInit(0, expr())))
|
||||
/// \code
|
||||
/// int x{y}.
|
||||
/// \endcode
|
||||
AST_MATCHER_P2(InitListExpr, hasInit, unsigned, N,
|
||||
ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
|
||||
return N < Node.getNumInits() &&
|
||||
InnerMatcher.matches(*Node.getInit(N), Finder, Builder);
|
||||
}
|
||||
|
||||
/// Matches declaration statements that contain a specific number of
|
||||
/// declarations.
|
||||
///
|
||||
|
|
@ -3390,7 +3582,7 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
|
|||
/// } catch (...) {
|
||||
/// // ...
|
||||
/// }
|
||||
/// /endcode
|
||||
/// \endcode
|
||||
/// cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int).
|
||||
AST_MATCHER(CXXCatchStmt, isCatchAll) {
|
||||
return Node.getExceptionDecl() == nullptr;
|
||||
|
|
@ -3532,9 +3724,9 @@ AST_MATCHER(CXXCtorInitializer, isMemberInitializer) {
|
|||
/// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
|
||||
/// matches [i f:12]
|
||||
AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
|
||||
CXXConstructExpr,
|
||||
ObjCMessageExpr),
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(
|
||||
CallExpr, CXXConstructExpr,
|
||||
CXXUnresolvedConstructExpr, ObjCMessageExpr),
|
||||
internal::Matcher<Expr>, InnerMatcher) {
|
||||
for (const Expr *Arg : Node.arguments()) {
|
||||
BoundNodesTreeBuilder Result(*Builder);
|
||||
|
|
@ -4603,13 +4795,24 @@ AST_MATCHER(CXXMethodDecl, isUserProvided) {
|
|||
/// \code
|
||||
/// class Y {
|
||||
/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
|
||||
/// template <class T> void f() { this->f<T>(); f<T>(); }
|
||||
/// int a;
|
||||
/// static int b;
|
||||
/// };
|
||||
/// template <class T>
|
||||
/// class Z {
|
||||
/// void x() { this->m; }
|
||||
/// };
|
||||
/// \endcode
|
||||
/// memberExpr(isArrow())
|
||||
/// matches this->x, x, y.x, a, this->b
|
||||
AST_MATCHER(MemberExpr, isArrow) {
|
||||
/// cxxDependentScopeMemberExpr(isArrow())
|
||||
/// matches this->m
|
||||
/// unresolvedMemberExpr(isArrow())
|
||||
/// matches this->f<T>, f<T>
|
||||
AST_POLYMORPHIC_MATCHER(
|
||||
isArrow, AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
|
||||
CXXDependentScopeMemberExpr)) {
|
||||
return Node.isArrow();
|
||||
}
|
||||
|
||||
|
|
@ -4773,8 +4976,17 @@ AST_MATCHER_P(MemberExpr, member,
|
|||
/// matches "x.m" and "m"
|
||||
/// with hasObjectExpression(...)
|
||||
/// matching "x" and the implicit object expression of "m" which has type X*.
|
||||
AST_MATCHER_P(MemberExpr, hasObjectExpression,
|
||||
internal::Matcher<Expr>, InnerMatcher) {
|
||||
AST_POLYMORPHIC_MATCHER_P(
|
||||
hasObjectExpression,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
|
||||
CXXDependentScopeMemberExpr),
|
||||
internal::Matcher<Expr>, InnerMatcher) {
|
||||
if (const auto *E = dyn_cast<UnresolvedMemberExpr>(&Node))
|
||||
if (E->isImplicitAccess())
|
||||
return false;
|
||||
if (const auto *E = dyn_cast<CXXDependentScopeMemberExpr>(&Node))
|
||||
if (E->isImplicitAccess())
|
||||
return false;
|
||||
return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
|
||||
}
|
||||
|
||||
|
|
@ -5169,7 +5381,7 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
|
|||
/// decltype(2.0) b = 2.0;
|
||||
/// \endcode
|
||||
/// decltypeType(hasUnderlyingType(isInteger()))
|
||||
/// matches "auto a"
|
||||
/// matches the type of "a"
|
||||
///
|
||||
/// Usable as: Matcher<DecltypeType>
|
||||
AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
SmallVector<BoundNodesMap, 16> Bindings;
|
||||
SmallVector<BoundNodesMap, 1> Bindings;
|
||||
};
|
||||
|
||||
class ASTMatchFinder;
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@ private:
|
|||
const NamedValueMap *NamedValues,
|
||||
Diagnostics *Error);
|
||||
|
||||
bool parseBindID(std::string &BindID);
|
||||
bool parseExpressionImpl(VariantValue *Value);
|
||||
bool parseMatcherExpressionImpl(const TokenInfo &NameToken,
|
||||
VariantValue *Value);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
//===---------- ExprMutationAnalyzer.h ------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
|
||||
#define LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "clang/AST/AST.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class FunctionParmMutationAnalyzer;
|
||||
|
||||
/// Analyzes whether any mutative operations are applied to an expression within
|
||||
/// a given statement.
|
||||
class ExprMutationAnalyzer {
|
||||
public:
|
||||
ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
|
||||
: Stm(Stm), Context(Context) {}
|
||||
|
||||
bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
|
||||
bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
|
||||
const Stmt *findMutation(const Expr *Exp);
|
||||
const Stmt *findMutation(const Decl *Dec);
|
||||
|
||||
bool isPointeeMutated(const Expr *Exp) {
|
||||
return findPointeeMutation(Exp) != nullptr;
|
||||
}
|
||||
bool isPointeeMutated(const Decl *Dec) {
|
||||
return findPointeeMutation(Dec) != nullptr;
|
||||
}
|
||||
const Stmt *findPointeeMutation(const Expr *Exp);
|
||||
const Stmt *findPointeeMutation(const Decl *Dec);
|
||||
|
||||
private:
|
||||
using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *);
|
||||
using ResultMap = llvm::DenseMap<const Expr *, const Stmt *>;
|
||||
|
||||
const Stmt *findMutationMemoized(const Expr *Exp,
|
||||
llvm::ArrayRef<MutationFinder> Finders,
|
||||
ResultMap &MemoizedResults);
|
||||
const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
|
||||
|
||||
bool isUnevaluated(const Expr *Exp);
|
||||
|
||||
const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
|
||||
const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
|
||||
const Stmt *
|
||||
findExprPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
|
||||
const Stmt *
|
||||
findDeclPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
|
||||
|
||||
const Stmt *findDirectMutation(const Expr *Exp);
|
||||
const Stmt *findMemberMutation(const Expr *Exp);
|
||||
const Stmt *findArrayElementMutation(const Expr *Exp);
|
||||
const Stmt *findCastMutation(const Expr *Exp);
|
||||
const Stmt *findRangeLoopMutation(const Expr *Exp);
|
||||
const Stmt *findReferenceMutation(const Expr *Exp);
|
||||
const Stmt *findFunctionArgMutation(const Expr *Exp);
|
||||
|
||||
const Stmt &Stm;
|
||||
ASTContext &Context;
|
||||
llvm::DenseMap<const FunctionDecl *,
|
||||
std::unique_ptr<FunctionParmMutationAnalyzer>>
|
||||
FuncParmAnalyzer;
|
||||
ResultMap Results;
|
||||
ResultMap PointeeResults;
|
||||
};
|
||||
|
||||
// A convenient wrapper around ExprMutationAnalyzer for analyzing function
|
||||
// params.
|
||||
class FunctionParmMutationAnalyzer {
|
||||
public:
|
||||
FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context);
|
||||
|
||||
bool isMutated(const ParmVarDecl *Parm) {
|
||||
return findMutation(Parm) != nullptr;
|
||||
}
|
||||
const Stmt *findMutation(const ParmVarDecl *Parm);
|
||||
|
||||
private:
|
||||
ExprMutationAnalyzer BodyAnalyzer;
|
||||
llvm::DenseMap<const ParmVarDecl *, const Stmt *> Results;
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
|
||||
|
|
@ -88,9 +88,13 @@ public:
|
|||
/// before the given block-level expression (see runOnAllBlocks).
|
||||
bool isLive(const Stmt *Loc, const Stmt *StmtVal);
|
||||
|
||||
/// Print to stderr the liveness information associated with
|
||||
/// Print to stderr the variable liveness information associated with
|
||||
/// each basic block.
|
||||
void dumpBlockLiveness(const SourceManager& M);
|
||||
void dumpBlockLiveness(const SourceManager &M);
|
||||
|
||||
/// Print to stderr the statement liveness information associated with
|
||||
/// each basic block.
|
||||
void dumpStmtLiveness(const SourceManager &M);
|
||||
|
||||
void runOnAllBlocks(Observer &obs);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
//== PseudoConstantAnalysis.h - Find Pseudo-constants in the AST -*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file tracks the usage of variables in a Decl body to see if they are
|
||||
// never written to, implying that they constant. This is useful in static
|
||||
// analysis to see if a developer might have intended a variable to be const.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H
|
||||
#define LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H
|
||||
|
||||
#include "clang/AST/Stmt.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class PseudoConstantAnalysis {
|
||||
public:
|
||||
PseudoConstantAnalysis(const Stmt *DeclBody);
|
||||
~PseudoConstantAnalysis();
|
||||
|
||||
bool isPseudoConstant(const VarDecl *VD);
|
||||
bool wasReferenced(const VarDecl *VD);
|
||||
|
||||
private:
|
||||
void RunAnalysis();
|
||||
inline static const Decl *getDecl(const Expr *E);
|
||||
|
||||
// for storing the result of analyzed ValueDecls
|
||||
void *NonConstantsImpl;
|
||||
void *UsedVarsImpl;
|
||||
|
||||
const Stmt *DeclBody;
|
||||
bool Analyzed;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -397,6 +397,8 @@ private:
|
|||
CallingContext *Ctx) ;
|
||||
til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx);
|
||||
til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx);
|
||||
til::SExpr *translateObjCIVarRefExpr(const ObjCIvarRefExpr *IVRE,
|
||||
CallingContext *Ctx);
|
||||
til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx,
|
||||
const Expr *SelfE = nullptr);
|
||||
til::SExpr *translateCXXMemberCallExpr(const CXXMemberCallExpr *ME,
|
||||
|
|
|
|||
|
|
@ -1643,10 +1643,10 @@ private:
|
|||
friend class SCFG;
|
||||
|
||||
// assign unique ids to all instructions
|
||||
int renumberInstrs(int id);
|
||||
unsigned renumberInstrs(unsigned id);
|
||||
|
||||
int topologicalSort(SimpleArray<BasicBlock *> &Blocks, int ID);
|
||||
int topologicalFinalSort(SimpleArray<BasicBlock *> &Blocks, int ID);
|
||||
unsigned topologicalSort(SimpleArray<BasicBlock *> &Blocks, unsigned ID);
|
||||
unsigned topologicalFinalSort(SimpleArray<BasicBlock *> &Blocks, unsigned ID);
|
||||
void computeDominator();
|
||||
void computePostDominator();
|
||||
|
||||
|
|
@ -1657,7 +1657,7 @@ private:
|
|||
SCFG *CFGPtr = nullptr;
|
||||
|
||||
// Unique ID for this BB in the containing CFG. IDs are in topological order.
|
||||
int BlockID : 31;
|
||||
unsigned BlockID : 31;
|
||||
|
||||
// Bit to determine if a block has been visited during a traversal.
|
||||
bool Visited : 1;
|
||||
|
|
|
|||
|
|
@ -785,7 +785,26 @@ protected:
|
|||
void printCast(const Cast *E, StreamType &SS) {
|
||||
if (!CStyle) {
|
||||
SS << "cast[";
|
||||
SS << E->castOpcode();
|
||||
switch (E->castOpcode()) {
|
||||
case CAST_none:
|
||||
SS << "none";
|
||||
break;
|
||||
case CAST_extendNum:
|
||||
SS << "extendNum";
|
||||
break;
|
||||
case CAST_truncNum:
|
||||
SS << "truncNum";
|
||||
break;
|
||||
case CAST_toFloat:
|
||||
SS << "toFloat";
|
||||
break;
|
||||
case CAST_toInt:
|
||||
SS << "toInt";
|
||||
break;
|
||||
case CAST_objToPtr:
|
||||
SS << "objToPtr";
|
||||
break;
|
||||
}
|
||||
SS << "](";
|
||||
self()->printSExpr(E->expr(), SS, Prec_Unary);
|
||||
SS << ")";
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ class ImplicitParamDecl;
|
|||
class LocationContext;
|
||||
class LocationContextManager;
|
||||
class ParentMap;
|
||||
class PseudoConstantAnalysis;
|
||||
class StackFrameContext;
|
||||
class Stmt;
|
||||
class VarDecl;
|
||||
|
|
@ -84,7 +83,6 @@ class AnalysisDeclContext {
|
|||
bool builtCFG = false;
|
||||
bool builtCompleteCFG = false;
|
||||
std::unique_ptr<ParentMap> PM;
|
||||
std::unique_ptr<PseudoConstantAnalysis> PCA;
|
||||
std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
|
||||
|
||||
llvm::BumpPtrAllocator A;
|
||||
|
|
@ -175,7 +173,6 @@ public:
|
|||
bool isCFGBuilt() const { return builtCFG; }
|
||||
|
||||
ParentMap &getParentMap();
|
||||
PseudoConstantAnalysis *getPseudoConstantAnalysis();
|
||||
|
||||
using referenced_decls_iterator = const VarDecl * const *;
|
||||
|
||||
|
|
@ -230,17 +227,23 @@ private:
|
|||
AnalysisDeclContext *Ctx;
|
||||
|
||||
const LocationContext *Parent;
|
||||
int64_t ID;
|
||||
|
||||
protected:
|
||||
LocationContext(ContextKind k, AnalysisDeclContext *ctx,
|
||||
const LocationContext *parent)
|
||||
: Kind(k), Ctx(ctx), Parent(parent) {}
|
||||
const LocationContext *parent,
|
||||
int64_t ID)
|
||||
: Kind(k), Ctx(ctx), Parent(parent), ID(ID) {}
|
||||
|
||||
public:
|
||||
virtual ~LocationContext();
|
||||
|
||||
ContextKind getKind() const { return Kind; }
|
||||
|
||||
int64_t getID() const {
|
||||
return ID;
|
||||
}
|
||||
|
||||
AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
|
||||
|
||||
const LocationContext *getParent() const { return Parent; }
|
||||
|
|
@ -300,8 +303,9 @@ class StackFrameContext : public LocationContext {
|
|||
|
||||
StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent,
|
||||
const Stmt *s, const CFGBlock *blk,
|
||||
unsigned idx)
|
||||
: LocationContext(StackFrame, ctx, parent), CallSite(s),
|
||||
unsigned idx,
|
||||
int64_t ID)
|
||||
: LocationContext(StackFrame, ctx, parent, ID), CallSite(s),
|
||||
Block(blk), Index(idx) {}
|
||||
|
||||
public:
|
||||
|
|
@ -337,8 +341,8 @@ class ScopeContext : public LocationContext {
|
|||
const Stmt *Enter;
|
||||
|
||||
ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
|
||||
const Stmt *s)
|
||||
: LocationContext(Scope, ctx, parent), Enter(s) {}
|
||||
const Stmt *s, int64_t ID)
|
||||
: LocationContext(Scope, ctx, parent, ID), Enter(s) {}
|
||||
|
||||
public:
|
||||
~ScopeContext() override = default;
|
||||
|
|
@ -364,9 +368,10 @@ class BlockInvocationContext : public LocationContext {
|
|||
const void *ContextData;
|
||||
|
||||
BlockInvocationContext(AnalysisDeclContext *ctx,
|
||||
const LocationContext *parent,
|
||||
const BlockDecl *bd, const void *contextData)
|
||||
: LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
|
||||
const LocationContext *parent, const BlockDecl *bd,
|
||||
const void *contextData, int64_t ID)
|
||||
: LocationContext(Block, ctx, parent, ID), BD(bd),
|
||||
ContextData(contextData) {}
|
||||
|
||||
public:
|
||||
~BlockInvocationContext() override = default;
|
||||
|
|
@ -392,6 +397,9 @@ public:
|
|||
class LocationContextManager {
|
||||
llvm::FoldingSet<LocationContext> Contexts;
|
||||
|
||||
/// ID used for generating a new location context.
|
||||
int64_t NewID = 0;
|
||||
|
||||
public:
|
||||
~LocationContextManager();
|
||||
|
||||
|
|
|
|||
|
|
@ -10,19 +10,6 @@
|
|||
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISDIAGNOSTIC_H
|
||||
#define LLVM_CLANG_ANALYSIS_ANALYSISDIAGNOSTIC_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
|
||||
SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
|
||||
#define ANALYSISSTART
|
||||
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
|
||||
#undef DIAG
|
||||
NUM_BUILTIN_ANALYSIS_DIAGNOSTICS
|
||||
};
|
||||
} // end namespace diag
|
||||
} // end namespace clang
|
||||
#include "clang/Basic/DiagnosticAnalysis.h"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ public:
|
|||
bool TraverseStmt(Stmt *S) { return true; }
|
||||
|
||||
bool shouldWalkTypesOfTypeLocs() const { return false; }
|
||||
bool shouldVisitTemplateInstantiations() const { return true; }
|
||||
|
||||
private:
|
||||
/// Add the given declaration to the call graph.
|
||||
|
|
|
|||
|
|
@ -122,7 +122,6 @@ public:
|
|||
/// Returns the start sourcelocation of the first statement in this sequence.
|
||||
///
|
||||
/// This method should only be called on a non-empty StmtSequence object.
|
||||
SourceLocation getStartLoc() const LLVM_READONLY { return getBeginLoc(); }
|
||||
SourceLocation getBeginLoc() const;
|
||||
|
||||
/// Returns the end sourcelocation of the last statement in this sequence.
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "clang/Analysis/Support/BumpVector.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/ExprObjC.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
|
|
@ -623,9 +624,16 @@ public:
|
|||
};
|
||||
|
||||
class ArgumentConstructionContext : public ConstructionContext {
|
||||
const Expr *CE; // The call of which the context is an argument.
|
||||
unsigned Index; // Which argument we're constructing.
|
||||
const CXXBindTemporaryExpr *BTE; // Whether the object needs to be destroyed.
|
||||
// The call of which the context is an argument.
|
||||
const Expr *CE;
|
||||
|
||||
// Which argument we're constructing. Note that when numbering between
|
||||
// arguments and parameters is inconsistent (eg., operator calls),
|
||||
// this is the index of the argument, not of the parameter.
|
||||
unsigned Index;
|
||||
|
||||
// Whether the object needs to be destroyed.
|
||||
const CXXBindTemporaryExpr *BTE;
|
||||
|
||||
friend class ConstructionContext; // Allows to create<>() itself.
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ public:
|
|||
CallEnterKind,
|
||||
CallExitBeginKind,
|
||||
CallExitEndKind,
|
||||
FunctionExitKind,
|
||||
PreImplicitCallKind,
|
||||
PostImplicitCallKind,
|
||||
MinImplicitCallKind = PreImplicitCallKind,
|
||||
|
|
@ -214,6 +215,10 @@ public:
|
|||
ID.AddPointer(getTag());
|
||||
}
|
||||
|
||||
void print(StringRef CR, llvm::raw_ostream &Out) const;
|
||||
|
||||
LLVM_DUMP_METHOD void dump() const;
|
||||
|
||||
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
|
||||
const LocationContext *LC,
|
||||
const ProgramPointTag *tag);
|
||||
|
|
@ -329,6 +334,29 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class FunctionExitPoint : public ProgramPoint {
|
||||
public:
|
||||
explicit FunctionExitPoint(const ReturnStmt *S,
|
||||
const LocationContext *LC,
|
||||
const ProgramPointTag *tag = nullptr)
|
||||
: ProgramPoint(S, FunctionExitKind, LC, tag) {}
|
||||
|
||||
const CFGBlock *getBlock() const {
|
||||
return &getLocationContext()->getCFG()->getExit();
|
||||
}
|
||||
|
||||
const ReturnStmt *getStmt() const {
|
||||
return reinterpret_cast<const ReturnStmt *>(getData1());
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ProgramPoint;
|
||||
FunctionExitPoint() = default;
|
||||
static bool isKind(const ProgramPoint &Location) {
|
||||
return Location.getKind() == FunctionExitKind;
|
||||
}
|
||||
};
|
||||
|
||||
// PostCondition represents the post program point of a branch condition.
|
||||
class PostCondition : public PostStmt {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -7,13 +7,12 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SELECTOREXTRAS_H
|
||||
#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SELECTOREXTRAS_H
|
||||
#ifndef LLVM_CLANG_LIB_ANALYSIS_SELECTOREXTRAS_H
|
||||
#define LLVM_CLANG_LIB_ANALYSIS_SELECTOREXTRAS_H
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
|
||||
namespace clang {
|
||||
namespace ento {
|
||||
|
||||
template <typename... IdentifierInfos>
|
||||
static inline Selector getKeywordSelector(ASTContext &Ctx,
|
||||
|
|
@ -33,14 +32,6 @@ static inline void lazyInitKeywordSelector(Selector &Sel, ASTContext &Ctx,
|
|||
Sel = getKeywordSelector(Ctx, IIs...);
|
||||
}
|
||||
|
||||
static inline void lazyInitNullarySelector(Selector &Sel, ASTContext &Ctx,
|
||||
const char *Name) {
|
||||
if (!Sel.isNull())
|
||||
return;
|
||||
Sel = GetNullarySelector(Name, Ctx);
|
||||
}
|
||||
|
||||
} // end namespace ento
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
@ -27,8 +27,8 @@ inline llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
|
|||
default:
|
||||
break;
|
||||
case llvm::Triple::Darwin:
|
||||
case llvm::Triple::MacOSX: // Earliest supporting version is 10.13.
|
||||
return llvm::VersionTuple(10U, 13U);
|
||||
case llvm::Triple::MacOSX: // Earliest supporting version is 10.14.
|
||||
return llvm::VersionTuple(10U, 14U);
|
||||
case llvm::Triple::IOS:
|
||||
case llvm::Triple::TvOS: // Earliest supporting version is 11.0.0.
|
||||
return llvm::VersionTuple(11U);
|
||||
|
|
|
|||
|
|
@ -15,17 +15,17 @@
|
|||
#ifndef LLVM_CLANG_BASIC_ALLDIAGNOSTICS_H
|
||||
#define LLVM_CLANG_BASIC_ALLDIAGNOSTICS_H
|
||||
|
||||
#include "clang/AST/ASTDiagnostic.h"
|
||||
#include "clang/AST/CommentDiagnostic.h"
|
||||
#include "clang/Analysis/AnalysisDiagnostic.h"
|
||||
#include "clang/CrossTU/CrossTUDiagnostic.h"
|
||||
#include "clang/Driver/DriverDiagnostic.h"
|
||||
#include "clang/Frontend/FrontendDiagnostic.h"
|
||||
#include "clang/Lex/LexDiagnostic.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Sema/SemaDiagnostic.h"
|
||||
#include "clang/Serialization/SerializationDiagnostic.h"
|
||||
#include "clang/Tooling/Refactoring/RefactoringDiagnostic.h"
|
||||
#include "clang/Basic/DiagnosticAST.h"
|
||||
#include "clang/Basic/DiagnosticAnalysis.h"
|
||||
#include "clang/Basic/DiagnosticComment.h"
|
||||
#include "clang/Basic/DiagnosticCrossTU.h"
|
||||
#include "clang/Basic/DiagnosticDriver.h"
|
||||
#include "clang/Basic/DiagnosticFrontend.h"
|
||||
#include "clang/Basic/DiagnosticLex.h"
|
||||
#include "clang/Basic/DiagnosticParse.h"
|
||||
#include "clang/Basic/DiagnosticSema.h"
|
||||
#include "clang/Basic/DiagnosticSerialization.h"
|
||||
#include "clang/Basic/DiagnosticRefactoring.h"
|
||||
|
||||
namespace clang {
|
||||
template <size_t SizeOfStr, typename FieldType>
|
||||
|
|
|
|||
|
|
@ -90,6 +90,15 @@ def NonBitField : SubsetSubject<Field,
|
|||
[{!S->isBitField()}],
|
||||
"non-bit-field non-static data members">;
|
||||
|
||||
def NonStaticCXXMethod : SubsetSubject<CXXMethod,
|
||||
[{!S->isStatic()}],
|
||||
"non-static member functions">;
|
||||
|
||||
def NonStaticNonConstCXXMethod
|
||||
: SubsetSubject<CXXMethod,
|
||||
[{!S->isStatic() && !S->isConst()}],
|
||||
"non-static non-const member functions">;
|
||||
|
||||
def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
|
||||
[{S->isInstanceMethod()}],
|
||||
"Objective-C instance methods">;
|
||||
|
|
@ -145,8 +154,9 @@ def HasFunctionProto : SubsetSubject<DeclBase,
|
|||
// function. Accepted as a function type attribute on the type of such a
|
||||
// member function.
|
||||
// FIXME: This does not actually ever match currently.
|
||||
def ImplicitObjectParameter : SubsetSubject<Function, [{false}],
|
||||
"implicit object parameters">;
|
||||
def ImplicitObjectParameter
|
||||
: SubsetSubject<Function, [{static_cast<void>(S), false}],
|
||||
"implicit object parameters">;
|
||||
|
||||
// A single argument to an attribute
|
||||
class Argument<string name, bit optional, bit fake = 0> {
|
||||
|
|
@ -288,8 +298,9 @@ def COnly : LangOpt<"CPlusPlus", 1>;
|
|||
def CPlusPlus : LangOpt<"CPlusPlus">;
|
||||
def OpenCL : LangOpt<"OpenCL">;
|
||||
def RenderScript : LangOpt<"RenderScript">;
|
||||
def ObjC : LangOpt<"ObjC1">;
|
||||
def ObjC : LangOpt<"ObjC">;
|
||||
def BlocksSupported : LangOpt<"Blocks">;
|
||||
def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">;
|
||||
|
||||
// Defines targets for target-specific attributes. Empty lists are unchecked.
|
||||
class TargetSpec {
|
||||
|
|
@ -467,13 +478,12 @@ class Attr {
|
|||
// in a class template definition.
|
||||
bit MeaningfulToClassTemplateDefinition = 0;
|
||||
// Set to true if this attribute can be used with '#pragma clang attribute'.
|
||||
// By default, when this value is false, an attribute is supported by the
|
||||
// '#pragma clang attribute' only when:
|
||||
// - It has documentation.
|
||||
// By default, an attribute is supported by the '#pragma clang attribute'
|
||||
// only when:
|
||||
// - It has a subject list whose subjects can be represented using subject
|
||||
// match rules.
|
||||
// - It has GNU/CXX11 spelling and doesn't require delayed parsing.
|
||||
bit ForcePragmaAttributeSupport = 0;
|
||||
bit PragmaAttributeSupport;
|
||||
// Lists language options, one of which is required to be true for the
|
||||
// attribute to be applicable. If empty, no language options are required.
|
||||
list<LangOpt> LangOpts = [];
|
||||
|
|
@ -488,10 +498,7 @@ class Attr {
|
|||
}
|
||||
|
||||
/// A type attribute is not processed on a declaration or a statement.
|
||||
class TypeAttr : Attr {
|
||||
// By default, type attributes do not get an AST node.
|
||||
let ASTNode = 0;
|
||||
}
|
||||
class TypeAttr : Attr;
|
||||
|
||||
/// A stmt attribute is not processed on a declaration or a type.
|
||||
class StmtAttr : Attr;
|
||||
|
|
@ -657,6 +664,7 @@ def AnalyzerNoReturn : InheritableAttr {
|
|||
// vendor namespace, or should it use a vendor namespace specific to the
|
||||
// analyzer?
|
||||
let Spellings = [GNU<"analyzer_noreturn">];
|
||||
// TODO: Add subject list.
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
|
|
@ -665,7 +673,7 @@ def Annotate : InheritableParamAttr {
|
|||
let Args = [StringArgument<"Annotation">];
|
||||
// Ensure that the annotate attribute can be used with
|
||||
// '#pragma clang attribute' even though it has no subject list.
|
||||
let ForcePragmaAttributeSupport = 1;
|
||||
let PragmaAttributeSupport = 1;
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
|
|
@ -720,6 +728,7 @@ def Availability : InheritableAttr {
|
|||
.Case("macos_app_extension", "macOS (App Extension)")
|
||||
.Case("tvos_app_extension", "tvOS (App Extension)")
|
||||
.Case("watchos_app_extension", "watchOS (App Extension)")
|
||||
.Case("swift", "Swift")
|
||||
.Default(llvm::StringRef());
|
||||
}
|
||||
static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
|
||||
|
|
@ -808,19 +817,56 @@ def CFUnknownTransfer : InheritableAttr {
|
|||
def CFReturnsRetained : InheritableAttr {
|
||||
let Spellings = [Clang<"cf_returns_retained">];
|
||||
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def CFReturnsNotRetained : InheritableAttr {
|
||||
let Spellings = [Clang<"cf_returns_not_retained">];
|
||||
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def CFConsumed : InheritableParamAttr {
|
||||
let Spellings = [Clang<"cf_consumed">];
|
||||
let Subjects = SubjectList<[ParmVar]>;
|
||||
let Documentation = [Undocumented];
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
// OSObject-based attributes.
|
||||
def OSConsumed : InheritableParamAttr {
|
||||
let Spellings = [Clang<"os_consumed">];
|
||||
let Subjects = SubjectList<[ParmVar]>;
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def OSReturnsRetained : InheritableAttr {
|
||||
let Spellings = [Clang<"os_returns_retained">];
|
||||
let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty, ParmVar]>;
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def OSReturnsNotRetained : InheritableAttr {
|
||||
let Spellings = [Clang<"os_returns_not_retained">];
|
||||
let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty, ParmVar]>;
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def OSReturnsRetainedOnZero : InheritableAttr {
|
||||
let Spellings = [Clang<"os_returns_retained_on_zero">];
|
||||
let Subjects = SubjectList<[ParmVar]>;
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def OSReturnsRetainedOnNonZero : InheritableAttr {
|
||||
let Spellings = [Clang<"os_returns_retained_on_non_zero">];
|
||||
let Subjects = SubjectList<[ParmVar]>;
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def OSConsumesThis : InheritableAttr {
|
||||
let Spellings = [Clang<"os_consumes_this">];
|
||||
let Subjects = SubjectList<[NonStaticCXXMethod]>;
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def Cleanup : InheritableAttr {
|
||||
|
|
@ -855,21 +901,19 @@ def Constructor : InheritableAttr {
|
|||
}
|
||||
|
||||
def CPUSpecific : InheritableAttr {
|
||||
let Spellings = [Clang<"cpu_specific">];
|
||||
let Spellings = [Clang<"cpu_specific">, Declspec<"cpu_specific">];
|
||||
let Args = [VariadicIdentifierArgument<"Cpus">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [CPUSpecificCPUDispatchDocs];
|
||||
let AdditionalMembers = [{
|
||||
unsigned ActiveArgIndex = 0;
|
||||
|
||||
IdentifierInfo *getCurCPUName() const {
|
||||
return *(cpus_begin() + ActiveArgIndex);
|
||||
IdentifierInfo *getCPUName(unsigned Index) const {
|
||||
return *(cpus_begin() + Index);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
def CPUDispatch : InheritableAttr {
|
||||
let Spellings = [Clang<"cpu_dispatch">];
|
||||
let Spellings = [Clang<"cpu_dispatch">, Declspec<"cpu_dispatch">];
|
||||
let Args = [VariadicIdentifierArgument<"Cpus">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [CPUSpecificCPUDispatchDocs];
|
||||
|
|
@ -1089,10 +1133,14 @@ def EnableIf : InheritableAttr {
|
|||
def ExtVectorType : Attr {
|
||||
// This is an OpenCL-related attribute and does not receive a [[]] spelling.
|
||||
let Spellings = [GNU<"ext_vector_type">];
|
||||
// FIXME: This subject list is wrong; this is a type attribute.
|
||||
let Subjects = SubjectList<[TypedefName], ErrorDiag>;
|
||||
let Args = [ExprArgument<"NumElements">];
|
||||
let ASTNode = 0;
|
||||
let Documentation = [Undocumented];
|
||||
// This is a type attribute with an incorrect subject list, so should not be
|
||||
// permitted by #pragma clang attribute.
|
||||
let PragmaAttributeSupport = 0;
|
||||
}
|
||||
|
||||
def FallThrough : StmtAttr {
|
||||
|
|
@ -1165,7 +1213,7 @@ def FormatArg : InheritableAttr {
|
|||
def GNUInline : InheritableAttr {
|
||||
let Spellings = [GCC<"gnu_inline">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
let Documentation = [GnuInlineDocs];
|
||||
}
|
||||
|
||||
def Hot : InheritableAttr {
|
||||
|
|
@ -1218,7 +1266,7 @@ def LayoutVersion : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
|
|||
let Documentation = [LayoutVersionDocs];
|
||||
}
|
||||
|
||||
def LifetimeBound : InheritableAttr {
|
||||
def LifetimeBound : DeclOrTypeAttr {
|
||||
let Spellings = [Clang<"lifetimebound", 0>];
|
||||
let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>;
|
||||
let Documentation = [LifetimeBoundDocs];
|
||||
|
|
@ -1309,6 +1357,9 @@ def Mode : Attr {
|
|||
let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag>;
|
||||
let Args = [IdentifierArgument<"Mode">];
|
||||
let Documentation = [Undocumented];
|
||||
// This is notionally a type attribute, which #pragma clang attribute
|
||||
// generally does not support.
|
||||
let PragmaAttributeSupport = 0;
|
||||
}
|
||||
|
||||
def Naked : InheritableAttr {
|
||||
|
|
@ -1321,12 +1372,16 @@ def NeonPolyVectorType : TypeAttr {
|
|||
let Spellings = [Clang<"neon_polyvector_type">];
|
||||
let Args = [IntArgument<"NumElements">];
|
||||
let Documentation = [Undocumented];
|
||||
// Represented as VectorType instead.
|
||||
let ASTNode = 0;
|
||||
}
|
||||
|
||||
def NeonVectorType : TypeAttr {
|
||||
let Spellings = [Clang<"neon_vector_type">];
|
||||
let Args = [IntArgument<"NumElements">];
|
||||
let Documentation = [Undocumented];
|
||||
// Represented as VectorType instead.
|
||||
let ASTNode = 0;
|
||||
}
|
||||
|
||||
def ReturnsTwice : InheritableAttr {
|
||||
|
|
@ -1501,6 +1556,14 @@ def TypeNullUnspecified : TypeAttr {
|
|||
let Documentation = [TypeNullUnspecifiedDocs];
|
||||
}
|
||||
|
||||
// This is a marker used to indicate that an __unsafe_unretained qualifier was
|
||||
// ignored because ARC is not enabled. The usual representation for this
|
||||
// qualifier is as an ObjCOwnership attribute with Kind == "none".
|
||||
def ObjCInertUnsafeUnretained : TypeAttr {
|
||||
let Spellings = [Keyword<"__unsafe_unretained">];
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
def ObjCKindOf : TypeAttr {
|
||||
let Spellings = [Keyword<"__kindof">];
|
||||
let Documentation = [Undocumented];
|
||||
|
|
@ -1588,34 +1651,34 @@ def ObjCBridgeRelated : InheritableAttr {
|
|||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
def NSReturnsRetained : InheritableAttr {
|
||||
def NSReturnsRetained : DeclOrTypeAttr {
|
||||
let Spellings = [Clang<"ns_returns_retained">];
|
||||
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def NSReturnsNotRetained : InheritableAttr {
|
||||
let Spellings = [Clang<"ns_returns_not_retained">];
|
||||
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def NSReturnsAutoreleased : InheritableAttr {
|
||||
let Spellings = [Clang<"ns_returns_autoreleased">];
|
||||
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def NSConsumesSelf : InheritableAttr {
|
||||
let Spellings = [Clang<"ns_consumes_self">];
|
||||
let Subjects = SubjectList<[ObjCMethod]>;
|
||||
let Documentation = [Undocumented];
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def NSConsumed : InheritableParamAttr {
|
||||
let Spellings = [Clang<"ns_consumed">];
|
||||
let Subjects = SubjectList<[ParmVar]>;
|
||||
let Documentation = [Undocumented];
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
}
|
||||
|
||||
def ObjCException : InheritableAttr {
|
||||
|
|
@ -1764,6 +1827,11 @@ def Pcs : DeclOrTypeAttr {
|
|||
let Documentation = [PcsDocs];
|
||||
}
|
||||
|
||||
def AArch64VectorPcs: DeclOrTypeAttr {
|
||||
let Spellings = [Clang<"aarch64_vector_pcs">];
|
||||
let Documentation = [AArch64VectorPcsDocs];
|
||||
}
|
||||
|
||||
def Pure : InheritableAttr {
|
||||
let Spellings = [GCC<"pure">];
|
||||
let Documentation = [Undocumented];
|
||||
|
|
@ -1773,6 +1841,13 @@ def Regparm : TypeAttr {
|
|||
let Spellings = [GCC<"regparm">];
|
||||
let Args = [UnsignedArgument<"NumParams">];
|
||||
let Documentation = [RegparmDocs];
|
||||
// Represented as part of the enclosing function type.
|
||||
let ASTNode = 0;
|
||||
}
|
||||
|
||||
def NoDeref : TypeAttr {
|
||||
let Spellings = [Clang<"noderef">];
|
||||
let Documentation = [NoDerefDocs];
|
||||
}
|
||||
|
||||
def ReqdWorkGroupSize : InheritableAttr {
|
||||
|
|
@ -2094,10 +2169,9 @@ def ObjCGC : TypeAttr {
|
|||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
def ObjCOwnership : InheritableAttr {
|
||||
def ObjCOwnership : DeclOrTypeAttr {
|
||||
let Spellings = [Clang<"objc_ownership">];
|
||||
let Args = [IdentifierArgument<"Kind">];
|
||||
let ASTNode = 0;
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
|
|
@ -2135,6 +2209,8 @@ def VectorSize : TypeAttr {
|
|||
let Spellings = [GCC<"vector_size">];
|
||||
let Args = [ExprArgument<"NumBytes">];
|
||||
let Documentation = [Undocumented];
|
||||
// Represented as VectorType instead.
|
||||
let ASTNode = 0;
|
||||
}
|
||||
|
||||
def VecTypeHint : InheritableAttr {
|
||||
|
|
@ -2229,7 +2305,7 @@ def AnyX86NoCallerSavedRegisters : InheritableAttr,
|
|||
let Documentation = [AnyX86NoCallerSavedRegistersDocs];
|
||||
}
|
||||
|
||||
def AnyX86NoCfCheck : InheritableAttr, TargetSpecificAttr<TargetAnyX86>{
|
||||
def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86>{
|
||||
let Spellings = [GCC<"nocf_check">];
|
||||
let Subjects = SubjectList<[FunctionLike]>;
|
||||
let Documentation = [AnyX86NoCfCheckDocs];
|
||||
|
|
@ -2658,6 +2734,17 @@ def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
|
|||
let Documentation = [DLLExportDocs];
|
||||
}
|
||||
|
||||
def DLLExportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> {
|
||||
// This attribute is used internally only when -fno-dllexport-inlines is
|
||||
// passed. This attribute is added to inline function of class having
|
||||
// dllexport attribute. And if the function has static local variables, this
|
||||
// attribute is used to whether the variables are exported or not. Also if
|
||||
// function has local static variables, the function is dllexported too.
|
||||
let Spellings = [];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
|
||||
let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
|
||||
let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
|
||||
|
|
@ -2674,6 +2761,16 @@ public:
|
|||
}];
|
||||
}
|
||||
|
||||
def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> {
|
||||
// This attribute is used internally only when -fno-dllexport-inlines is
|
||||
// passed. This attribute is added to inline function of class having
|
||||
// dllimport attribute. And if the function has static local variables, this
|
||||
// attribute is used to whether the variables are imported or not.
|
||||
let Spellings = [];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
def SelectAny : InheritableAttr {
|
||||
let Spellings = [Declspec<"selectany">, GCC<"selectany">];
|
||||
let Documentation = [SelectAnyDocs];
|
||||
|
|
@ -2781,7 +2878,11 @@ def LoopHint : Attr {
|
|||
/// interleave_count: interleaves 'Value' loop iterations.
|
||||
/// unroll: fully unroll loop if State == Enable.
|
||||
/// unroll_count: unrolls loop 'Value' times.
|
||||
/// distribute: attempt to distribute loop if State == Enable
|
||||
/// unroll_and_jam: attempt to unroll and jam loop if State == Enable.
|
||||
/// unroll_and_jam_count: unroll and jams loop 'Value' times.
|
||||
/// distribute: attempt to distribute loop if State == Enable.
|
||||
/// pipeline: disable pipelining loop if State == Disable.
|
||||
/// pipeline_initiation_interval: create loop schedule with initiation interval equal to 'Value'.
|
||||
|
||||
/// #pragma unroll <argument> directive
|
||||
/// <no arg>: fully unrolls loop.
|
||||
|
|
@ -2789,14 +2890,17 @@ def LoopHint : Attr {
|
|||
/// expression: unrolls loop 'Value' times.
|
||||
|
||||
let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">,
|
||||
Pragma<"", "nounroll">];
|
||||
Pragma<"", "nounroll">, Pragma<"", "unroll_and_jam">,
|
||||
Pragma<"", "nounroll_and_jam">];
|
||||
|
||||
/// State of the loop optimization specified by the spelling.
|
||||
let Args = [EnumArgument<"Option", "OptionType",
|
||||
["vectorize", "vectorize_width", "interleave", "interleave_count",
|
||||
"unroll", "unroll_count", "distribute"],
|
||||
"unroll", "unroll_count", "unroll_and_jam", "unroll_and_jam_count",
|
||||
"pipeline", "pipeline_initiation_interval", "distribute"],
|
||||
["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
|
||||
"Unroll", "UnrollCount", "Distribute"]>,
|
||||
"Unroll", "UnrollCount", "UnrollAndJam", "UnrollAndJamCount",
|
||||
"PipelineDisabled", "PipelineInitiationInterval", "Distribute"]>,
|
||||
EnumArgument<"State", "LoopHintState",
|
||||
["enable", "disable", "numeric", "assume_safety", "full"],
|
||||
["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>,
|
||||
|
|
@ -2811,6 +2915,10 @@ def LoopHint : Attr {
|
|||
case InterleaveCount: return "interleave_count";
|
||||
case Unroll: return "unroll";
|
||||
case UnrollCount: return "unroll_count";
|
||||
case UnrollAndJam: return "unroll_and_jam";
|
||||
case UnrollAndJamCount: return "unroll_and_jam_count";
|
||||
case PipelineDisabled: return "pipeline";
|
||||
case PipelineInitiationInterval: return "pipeline_initiation_interval";
|
||||
case Distribute: return "distribute";
|
||||
}
|
||||
llvm_unreachable("Unhandled LoopHint option.");
|
||||
|
|
@ -2820,9 +2928,9 @@ def LoopHint : Attr {
|
|||
unsigned SpellingIndex = getSpellingListIndex();
|
||||
// For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
|
||||
// "nounroll" is already emitted as the pragma name.
|
||||
if (SpellingIndex == Pragma_nounroll)
|
||||
if (SpellingIndex == Pragma_nounroll || SpellingIndex == Pragma_nounroll_and_jam)
|
||||
return;
|
||||
else if (SpellingIndex == Pragma_unroll) {
|
||||
else if (SpellingIndex == Pragma_unroll || SpellingIndex == Pragma_unroll_and_jam) {
|
||||
OS << ' ' << getValueString(Policy);
|
||||
return;
|
||||
}
|
||||
|
|
@ -2858,6 +2966,11 @@ def LoopHint : Attr {
|
|||
return "#pragma nounroll";
|
||||
else if (SpellingIndex == Pragma_unroll)
|
||||
return "#pragma unroll" + (option == UnrollCount ? getValueString(Policy) : "");
|
||||
else if (SpellingIndex == Pragma_nounroll_and_jam)
|
||||
return "#pragma nounroll_and_jam";
|
||||
else if (SpellingIndex == Pragma_unroll_and_jam)
|
||||
return "#pragma unroll_and_jam" +
|
||||
(option == UnrollAndJamCount ? getValueString(Policy) : "");
|
||||
|
||||
assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
|
||||
return getOptionName(option) + getValueString(Policy);
|
||||
|
|
@ -3004,3 +3117,47 @@ def InternalLinkage : InheritableAttr {
|
|||
let Subjects = SubjectList<[Var, Function, CXXRecord]>;
|
||||
let Documentation = [InternalLinkageDocs];
|
||||
}
|
||||
|
||||
def ExcludeFromExplicitInstantiation : InheritableAttr {
|
||||
let Spellings = [Clang<"exclude_from_explicit_instantiation">];
|
||||
let Subjects = SubjectList<[Var, Function, CXXRecord]>;
|
||||
let Documentation = [ExcludeFromExplicitInstantiationDocs];
|
||||
let MeaningfulToClassTemplateDefinition = 1;
|
||||
}
|
||||
|
||||
def Reinitializes : InheritableAttr {
|
||||
let Spellings = [Clang<"reinitializes", 0>];
|
||||
let Subjects = SubjectList<[NonStaticNonConstCXXMethod], ErrorDiag>;
|
||||
let Documentation = [ReinitializesDocs];
|
||||
}
|
||||
|
||||
def NoDestroy : InheritableAttr {
|
||||
let Spellings = [Clang<"no_destroy", 0>];
|
||||
let Subjects = SubjectList<[Var]>;
|
||||
let Documentation = [NoDestroyDocs];
|
||||
}
|
||||
|
||||
def AlwaysDestroy : InheritableAttr {
|
||||
let Spellings = [Clang<"always_destroy", 0>];
|
||||
let Subjects = SubjectList<[Var]>;
|
||||
let Documentation = [AlwaysDestroyDocs];
|
||||
}
|
||||
|
||||
def SpeculativeLoadHardening : InheritableAttr {
|
||||
let Spellings = [Clang<"speculative_load_hardening">];
|
||||
let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
|
||||
let Documentation = [SpeculativeLoadHardeningDocs];
|
||||
}
|
||||
|
||||
def Uninitialized : InheritableAttr {
|
||||
let Spellings = [Clang<"uninitialized", 0>];
|
||||
let Subjects = SubjectList<[LocalVar]>;
|
||||
let Documentation = [UninitializedDocs];
|
||||
}
|
||||
|
||||
def ObjCExternallyRetained : InheritableAttr {
|
||||
let LangOpts = [ObjCAutoRefCount];
|
||||
let Spellings = [Clang<"objc_externally_retained">];
|
||||
let Subjects = SubjectList<[NonParmVar, Function, Block, ObjCMethod]>;
|
||||
let Documentation = [ObjCExternallyRetainedDocs];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ Attributes in Clang
|
|||
.. contents::
|
||||
:local:
|
||||
|
||||
.. |br| raw:: html
|
||||
|
||||
<br/>
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
|
|
@ -51,7 +55,7 @@ def SectionDocs : Documentation {
|
|||
The ``section`` attribute allows you to specify a specific section a
|
||||
global variable or function should be in after translation.
|
||||
}];
|
||||
let Heading = "section (gnu::section, __declspec(allocate))";
|
||||
let Heading = "section, __declspec(allocate)";
|
||||
}
|
||||
|
||||
def InitSegDocs : Documentation {
|
||||
|
|
@ -270,7 +274,7 @@ that appears to be capable of returning to its caller.
|
|||
|
||||
def AssertCapabilityDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "assert_capability (assert_shared_capability, clang::assert_capability, clang::assert_shared_capability)";
|
||||
let Heading = "assert_capability, assert_shared_capability";
|
||||
let Content = [{
|
||||
Marks a function that dynamically tests whether a capability is held, and halts
|
||||
the program if it is not held.
|
||||
|
|
@ -279,7 +283,7 @@ the program if it is not held.
|
|||
|
||||
def AcquireCapabilityDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "acquire_capability (acquire_shared_capability, clang::acquire_capability, clang::acquire_shared_capability)";
|
||||
let Heading = "acquire_capability, acquire_shared_capability";
|
||||
let Content = [{
|
||||
Marks a function as acquiring a capability.
|
||||
}];
|
||||
|
|
@ -287,7 +291,7 @@ Marks a function as acquiring a capability.
|
|||
|
||||
def TryAcquireCapabilityDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "try_acquire_capability (try_acquire_shared_capability, clang::try_acquire_capability, clang::try_acquire_shared_capability)";
|
||||
let Heading = "try_acquire_capability, try_acquire_shared_capability";
|
||||
let Content = [{
|
||||
Marks a function that attempts to acquire a capability. This function may fail to
|
||||
actually acquire the capability; they accept a Boolean value determining
|
||||
|
|
@ -298,7 +302,7 @@ the capability means success (false).
|
|||
|
||||
def ReleaseCapabilityDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability)";
|
||||
let Heading = "release_capability, release_shared_capability";
|
||||
let Content = [{
|
||||
Marks a function as releasing a capability.
|
||||
}];
|
||||
|
|
@ -550,9 +554,9 @@ certain user-defined criteria. For example:
|
|||
|
||||
.. code-block:: c
|
||||
|
||||
void abs(int a)
|
||||
int abs(int a)
|
||||
__attribute__((diagnose_if(a >= 0, "Redundant abs call", "warning")));
|
||||
void must_abs(int a)
|
||||
int must_abs(int a)
|
||||
__attribute__((diagnose_if(a >= 0, "Redundant abs call", "error")));
|
||||
|
||||
int val = abs(1); // warning: Redundant abs call
|
||||
|
|
@ -843,6 +847,73 @@ Query for this feature with ``__has_attribute(objc_method_family)``.
|
|||
}];
|
||||
}
|
||||
|
||||
def RetainBehaviorDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
The behavior of a function with respect to reference counting for Foundation
|
||||
(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming
|
||||
convention (e.g. functions starting with "get" are assumed to return at
|
||||
``+0``).
|
||||
|
||||
It can be overriden using a family of the following attributes. In
|
||||
Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to
|
||||
a function communicates that the object is returned at ``+1``, and the caller
|
||||
is responsible for freeing it.
|
||||
Similiarly, the annotation ``__attribute__((ns_returns_not_retained))``
|
||||
specifies that the object is returned at ``+0`` and the ownership remains with
|
||||
the callee.
|
||||
The annotation ``__attribute__((ns_consumes_self))`` specifies that
|
||||
the Objective-C method call consumes the reference to ``self``, e.g. by
|
||||
attaching it to a supplied parameter.
|
||||
Additionally, parameters can have an annotation
|
||||
``__attribute__((ns_consumed))``, which specifies that passing an owned object
|
||||
as that parameter effectively transfers the ownership, and the caller is no
|
||||
longer responsible for it.
|
||||
These attributes affect code generation when interacting with ARC code, and
|
||||
they are used by the Clang Static Analyzer.
|
||||
|
||||
In C programs using CoreFoundation, a similar set of attributes:
|
||||
``__attribute__((cf_returns_not_retained))``,
|
||||
``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))``
|
||||
have the same respective semantics when applied to CoreFoundation objects.
|
||||
These attributes affect code generation when interacting with ARC code, and
|
||||
they are used by the Clang Static Analyzer.
|
||||
|
||||
Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject),
|
||||
the same attribute family is present:
|
||||
``__attribute__((os_returns_not_retained))``,
|
||||
``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``,
|
||||
with the same respective semantics.
|
||||
Similar to ``__attribute__((ns_consumes_self))``,
|
||||
``__attribute__((os_consumes_this))`` specifies that the method call consumes
|
||||
the reference to "this" (e.g., when attaching it to a different object supplied
|
||||
as a parameter).
|
||||
Out parameters (parameters the function is meant to write into,
|
||||
either via pointers-to-pointers or references-to-pointers)
|
||||
may be annotated with ``__attribute__((os_returns_retained))``
|
||||
or ``__attribute__((os_returns_not_retained))`` which specifies that the object
|
||||
written into the out parameter should (or respectively should not) be released
|
||||
after use.
|
||||
Since often out parameters may or may not be written depending on the exit
|
||||
code of the function,
|
||||
annotations ``__attribute__((os_returns_retained_on_zero))``
|
||||
and ``__attribute__((os_returns_retained_on_non_zero))`` specify that
|
||||
an out parameter at ``+1`` is written if and only if the function returns a zero
|
||||
(respectively non-zero) error code.
|
||||
Observe that return-code-dependent out parameter annotations are only
|
||||
available for retained out parameters, as non-retained object do not have to be
|
||||
released by the callee.
|
||||
These attributes are only used by the Clang Static Analyzer.
|
||||
|
||||
The family of attributes ``X_returns_X_retained`` can be added to functions,
|
||||
C++ methods, and Objective-C methods and properties.
|
||||
Attributes ``X_consumed`` can be added to parameters of methods, functions,
|
||||
and Objective-C methods.
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
|
||||
def NoDebugDocs : Documentation {
|
||||
let Category = DocCatVariable;
|
||||
let Content = [{
|
||||
|
|
@ -1261,7 +1332,7 @@ of silently falling back on dynamic initialization.
|
|||
|
||||
def WarnMaybeUnusedDocs : Documentation {
|
||||
let Category = DocCatVariable;
|
||||
let Heading = "maybe_unused, unused, gnu::unused";
|
||||
let Heading = "maybe_unused, unused";
|
||||
let Content = [{
|
||||
When passing the ``-Wunused`` flag to Clang, entities that are unused by the
|
||||
program may be diagnosed. The ``[[maybe_unused]]`` (or
|
||||
|
|
@ -1287,7 +1358,7 @@ enumerator, a non-static data member, or a label.
|
|||
|
||||
def WarnUnusedResultsDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "nodiscard, warn_unused_result, clang::warn_unused_result, gnu::warn_unused_result";
|
||||
let Heading = "nodiscard, warn_unused_result";
|
||||
let Content = [{
|
||||
Clang supports the ability to diagnose when the results of a function call
|
||||
expression are discarded under suspicious circumstances. A diagnostic is
|
||||
|
|
@ -1312,7 +1383,7 @@ potentially-evaluated discarded-value expression that is not explicitly cast to
|
|||
|
||||
def FallthroughDocs : Documentation {
|
||||
let Category = DocCatStmt;
|
||||
let Heading = "fallthrough, clang::fallthrough";
|
||||
let Heading = "fallthrough";
|
||||
let Content = [{
|
||||
The ``fallthrough`` (or ``clang::fallthrough``) attribute is used
|
||||
to annotate intentional fall-through
|
||||
|
|
@ -1460,7 +1531,7 @@ on the command line.
|
|||
|
||||
def MipsLongCallStyleDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "long_call (gnu::long_call, gnu::far)";
|
||||
let Heading = "long_call, far";
|
||||
let Content = [{
|
||||
Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
|
||||
and ``__attribute__((near))`` attributes on MIPS targets. These attributes may
|
||||
|
|
@ -1481,7 +1552,7 @@ as ``-mlong-calls`` and ``-mno-long-calls``.
|
|||
|
||||
def MipsShortCallStyleDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "short_call (gnu::short_call, gnu::near)";
|
||||
let Heading = "short_call, near";
|
||||
let Content = [{
|
||||
Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``,
|
||||
``__attribute__((short__call))``, and ``__attribute__((near))`` attributes
|
||||
|
|
@ -1738,6 +1809,31 @@ similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and
|
|||
}];
|
||||
}
|
||||
|
||||
def AArch64VectorPcsDocs : Documentation {
|
||||
let Category = DocCatCallingConvs;
|
||||
let Content = [{
|
||||
On AArch64 targets, this attribute changes the calling convention of a
|
||||
function to preserve additional floating-point and Advanced SIMD registers
|
||||
relative to the default calling convention used for AArch64.
|
||||
|
||||
This means it is more efficient to call such functions from code that performs
|
||||
extensive floating-point and vector calculations, because fewer live SIMD and FP
|
||||
registers need to be saved. This property makes it well-suited for e.g.
|
||||
floating-point or vector math library functions, which are typically leaf
|
||||
functions that require a small number of registers.
|
||||
|
||||
However, using this attribute also means that it is more expensive to call
|
||||
a function that adheres to the default calling convention from within such
|
||||
a function. Therefore, it is recommended that this attribute is only used
|
||||
for leaf functions.
|
||||
|
||||
For more information, see the documentation for `aarch64_vector_pcs`_ on
|
||||
the Arm Developer website.
|
||||
|
||||
.. _`aarch64_vector_pcs`: https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi
|
||||
}];
|
||||
}
|
||||
|
||||
def RegparmDocs : Documentation {
|
||||
let Category = DocCatCallingConvs;
|
||||
let Content = [{
|
||||
|
|
@ -1940,7 +2036,7 @@ def NoSanitizeAddressDocs : Documentation {
|
|||
let Category = DocCatFunction;
|
||||
// This function has multiple distinct spellings, and so it requires a custom
|
||||
// heading to be specified. The most common spelling is sufficient.
|
||||
let Heading = "no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address)";
|
||||
let Heading = "no_sanitize_address, no_address_safety_analysis";
|
||||
let Content = [{
|
||||
.. _langext-address_sanitizer:
|
||||
|
||||
|
|
@ -2497,10 +2593,10 @@ def LoopHintDocs : Documentation {
|
|||
let Heading = "#pragma clang loop";
|
||||
let Content = [{
|
||||
The ``#pragma clang loop`` directive allows loop optimization hints to be
|
||||
specified for the subsequent loop. The directive allows vectorization,
|
||||
interleaving, and unrolling to be enabled or disabled. Vector width as well
|
||||
as interleave and unrolling count can be manually specified. See
|
||||
`language extensions
|
||||
specified for the subsequent loop. The directive allows pipelining to be
|
||||
disabled, or vectorization, interleaving, and unrolling to be enabled or disabled.
|
||||
Vector width, interleave count, unrolling count, and the initiation interval
|
||||
for pipelining can be explicitly specified. See `language extensions
|
||||
<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
|
||||
for details.
|
||||
}];
|
||||
|
|
@ -2561,9 +2657,58 @@ for further details including limitations of the unroll hints.
|
|||
}];
|
||||
}
|
||||
|
||||
def PipelineHintDocs : Documentation {
|
||||
let Category = DocCatStmt;
|
||||
let Heading = "#pragma clang loop pipeline, #pragma clang loop pipeline_initiation_interval";
|
||||
let Content = [{
|
||||
Software Pipelining optimization is a technique used to optimize loops by
|
||||
utilizing instruction-level parallelism. It reorders loop instructions to
|
||||
overlap iterations. As a result, the next iteration starts before the previous
|
||||
iteration has finished. The module scheduling technique creates a schedule for
|
||||
one iteration such that when repeating at regular intervals, no inter-iteration
|
||||
dependencies are violated. This constant interval(in cycles) between the start
|
||||
of iterations is called the initiation interval. i.e. The initiation interval
|
||||
is the number of cycles between two iterations of an unoptimized loop in the
|
||||
newly created schedule. A new, optimized loop is created such that a single iteration
|
||||
of the loop executes in the same number of cycles as the initiation interval.
|
||||
For further details see <https://llvm.org/pubs/2005-06-17-LattnerMSThesis-book.pdf>.
|
||||
|
||||
``#pragma clang loop pipeline and #pragma loop pipeline_initiation_interval``
|
||||
could be used as hints for the software pipelining optimization. The pragma is
|
||||
placed immediately before a for, while, do-while, or a C++11 range-based for
|
||||
loop.
|
||||
|
||||
Using ``#pragma clang loop pipeline(disable)`` avoids the software pipelining
|
||||
optimization. The disable state can only be specified:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#pragma clang loop pipeline(disable)
|
||||
for (...) {
|
||||
...
|
||||
}
|
||||
|
||||
Using ``#pragma loop pipeline_initiation_interval`` instructs
|
||||
the software pipeliner to try the specified initiation interval.
|
||||
If a schedule was found then the resulting loop iteration would have
|
||||
the specified cycle count. If a schedule was not found then loop
|
||||
remains unchanged. The initiation interval must be a positive number
|
||||
greater than zero:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#pragma loop pipeline_initiation_interval(10)
|
||||
for (...) {
|
||||
...
|
||||
}
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
|
||||
def OpenCLUnrollHintDocs : Documentation {
|
||||
let Category = DocCatStmt;
|
||||
let Heading = "__attribute__((opencl_unroll_hint))";
|
||||
let Content = [{
|
||||
The opencl_unroll_hint attribute qualifier can be used to specify that a loop
|
||||
(for, while and do loops) can be unrolled. This attribute qualifier can be
|
||||
|
|
@ -2576,7 +2721,6 @@ s6.11.5 for details.
|
|||
|
||||
def OpenCLIntelReqdSubGroupSizeDocs : Documentation {
|
||||
let Category = DocCatStmt;
|
||||
let Heading = "__attribute__((intel_reqd_sub_group_size))";
|
||||
let Content = [{
|
||||
The optional attribute intel_reqd_sub_group_size can be used to indicate that
|
||||
the kernel must be compiled and executed with the specified subgroup size. When
|
||||
|
|
@ -2973,6 +3117,68 @@ This can be used to contain the ABI of a C++ library by excluding unwanted class
|
|||
}];
|
||||
}
|
||||
|
||||
def ExcludeFromExplicitInstantiationDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
The ``exclude_from_explicit_instantiation`` attribute opts-out a member of a
|
||||
class template from being part of explicit template instantiations of that
|
||||
class template. This means that an explicit instantiation will not instantiate
|
||||
members of the class template marked with the attribute, but also that code
|
||||
where an extern template declaration of the enclosing class template is visible
|
||||
will not take for granted that an external instantiation of the class template
|
||||
would provide those members (which would otherwise be a link error, since the
|
||||
explicit instantiation won't provide those members). For example, let's say we
|
||||
don't want the ``data()`` method to be part of libc++'s ABI. To make sure it
|
||||
is not exported from the dylib, we give it hidden visibility:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// in <string>
|
||||
template <class CharT>
|
||||
class basic_string {
|
||||
public:
|
||||
__attribute__((__visibility__("hidden")))
|
||||
const value_type* data() const noexcept { ... }
|
||||
};
|
||||
|
||||
template class basic_string<char>;
|
||||
|
||||
Since an explicit template instantiation declaration for ``basic_string<char>``
|
||||
is provided, the compiler is free to assume that ``basic_string<char>::data()``
|
||||
will be provided by another translation unit, and it is free to produce an
|
||||
external call to this function. However, since ``data()`` has hidden visibility
|
||||
and the explicit template instantiation is provided in a shared library (as
|
||||
opposed to simply another translation unit), ``basic_string<char>::data()``
|
||||
won't be found and a link error will ensue. This happens because the compiler
|
||||
assumes that ``basic_string<char>::data()`` is part of the explicit template
|
||||
instantiation declaration, when it really isn't. To tell the compiler that
|
||||
``data()`` is not part of the explicit template instantiation declaration, the
|
||||
``exclude_from_explicit_instantiation`` attribute can be used:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// in <string>
|
||||
template <class CharT>
|
||||
class basic_string {
|
||||
public:
|
||||
__attribute__((__visibility__("hidden")))
|
||||
__attribute__((exclude_from_explicit_instantiation))
|
||||
const value_type* data() const noexcept { ... }
|
||||
};
|
||||
|
||||
template class basic_string<char>;
|
||||
|
||||
Now, the compiler won't assume that ``basic_string<char>::data()`` is provided
|
||||
externally despite there being an explicit template instantiation declaration:
|
||||
the compiler will implicitly instantiate ``basic_string<char>::data()`` in the
|
||||
TUs where it is used.
|
||||
|
||||
This attribute can be used on static and non-static member functions of class
|
||||
templates, static data members of class templates and member classes of class
|
||||
templates.
|
||||
}];
|
||||
}
|
||||
|
||||
def DisableTailCallsDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
|
|
@ -3368,7 +3574,7 @@ The symbol name of the resolver function is given in quotes. A function with th
|
|||
|
||||
The ``ifunc`` attribute may only be used on a function declaration. A function declaration with an ``ifunc`` attribute is considered to be a definition of the declared entity. The entity must not have weak linkage; for example, in C++, it cannot be applied to a declaration if a definition at that location would be considered inline.
|
||||
|
||||
Not all targets support this attribute. ELF targets support this attribute when using binutils v2.20.1 or higher and glibc v2.11.1 or higher. Non-ELF targets currently do not support this attribute.
|
||||
Not all targets support this attribute. ELF target support depends on both the linker and runtime linker, and is available in at least lld 4.0 and later, binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later. Non-ELF targets currently do not support this attribute.
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
@ -3396,7 +3602,7 @@ See the RenderScript_ documentation for more information.
|
|||
|
||||
def XRayDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument), xray_log_args (clang::xray_log_args)";
|
||||
let Heading = "xray_always_instrument, xray_never_instrument, xray_log_args";
|
||||
let Content = [{
|
||||
``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching.
|
||||
|
||||
|
|
@ -3458,3 +3664,206 @@ the resulting instructions with the call site, rather than with the
|
|||
corresponding line within the inlined callee.
|
||||
}];
|
||||
}
|
||||
|
||||
def NoDerefDocs : Documentation {
|
||||
let Category = DocCatType;
|
||||
let Content = [{
|
||||
The ``noderef`` attribute causes clang to diagnose dereferences of annotated pointer types.
|
||||
This is ideally used with pointers that point to special memory which cannot be read
|
||||
from or written to, but allowing for the pointer to be used in pointer arithmetic.
|
||||
The following are examples of valid expressions where dereferences are diagnosed:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int __attribute__((noderef)) *p;
|
||||
int x = *p; // warning
|
||||
|
||||
int __attribute__((noderef)) **p2;
|
||||
x = **p2; // warning
|
||||
|
||||
int * __attribute__((noderef)) *p3;
|
||||
p = *p3; // warning
|
||||
|
||||
struct S {
|
||||
int a;
|
||||
};
|
||||
struct S __attribute__((noderef)) *s;
|
||||
x = s->a; // warning
|
||||
x = (*s).a; // warning
|
||||
|
||||
Not all dereferences may diagnose a warning if the value directed by the pointer may not be
|
||||
accessed. The following are examples of valid expressions where may not be diagnosed:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int *q;
|
||||
int __attribute__((noderef)) *p;
|
||||
q = &*p;
|
||||
q = *&p;
|
||||
|
||||
struct S {
|
||||
int a;
|
||||
};
|
||||
struct S __attribute__((noderef)) *s;
|
||||
p = &s->a;
|
||||
p = &(*s).a;
|
||||
|
||||
``noderef`` is currently only supported for pointers and arrays and not usable for
|
||||
references or Objective-C object pointers.
|
||||
|
||||
.. code-block: c++
|
||||
|
||||
int x = 2;
|
||||
int __attribute__((noderef)) &y = x; // warning: 'noderef' can only be used on an array or pointer type
|
||||
|
||||
.. code-block: objc
|
||||
|
||||
id __attribute__((noderef)) obj = [NSObject new]; // warning: 'noderef' can only be used on an array or pointer type
|
||||
}];
|
||||
}
|
||||
|
||||
def ReinitializesDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
The ``reinitializes`` attribute can be applied to a non-static, non-const C++
|
||||
member function to indicate that this member function reinitializes the entire
|
||||
object to a known state, independent of the previous state of the object.
|
||||
|
||||
This attribute can be interpreted by static analyzers that warn about uses of an
|
||||
object that has been left in an indeterminate state by a move operation. If a
|
||||
member function marked with the ``reinitializes`` attribute is called on a
|
||||
moved-from object, the analyzer can conclude that the object is no longer in an
|
||||
indeterminate state.
|
||||
|
||||
A typical example where this attribute would be used is on functions that clear
|
||||
a container class:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
template <class T>
|
||||
class Container {
|
||||
public:
|
||||
...
|
||||
[[clang::reinitializes]] void Clear();
|
||||
...
|
||||
};
|
||||
}];
|
||||
}
|
||||
|
||||
def AlwaysDestroyDocs : Documentation {
|
||||
let Category = DocCatVariable;
|
||||
let Content = [{
|
||||
The ``always_destroy`` attribute specifies that a variable with static or thread
|
||||
storage duration should have its exit-time destructor run. This attribute is the
|
||||
default unless clang was invoked with -fno-c++-static-destructors.
|
||||
}];
|
||||
}
|
||||
|
||||
def NoDestroyDocs : Documentation {
|
||||
let Category = DocCatVariable;
|
||||
let Content = [{
|
||||
The ``no_destroy`` attribute specifies that a variable with static or thread
|
||||
storage duration shouldn't have its exit-time destructor run. Annotating every
|
||||
static and thread duration variable with this attribute is equivalent to
|
||||
invoking clang with -fno-c++-static-destructors.
|
||||
}];
|
||||
}
|
||||
|
||||
def UninitializedDocs : Documentation {
|
||||
let Category = DocCatVariable;
|
||||
let Content = [{
|
||||
The command-line parameter ``-ftrivial-auto-var-init=*`` can be used to
|
||||
initialize trivial automatic stack variables. By default, trivial automatic
|
||||
stack variables are uninitialized. This attribute is used to override the
|
||||
command-line parameter, forcing variables to remain uninitialized. It has no
|
||||
semantic meaning in that using uninitialized values is undefined behavior,
|
||||
it rather documents the programmer's intent.
|
||||
}];
|
||||
}
|
||||
|
||||
def GnuInlineDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
The ``gnu_inline`` changes the meaning of ``extern inline`` to use GNU inline
|
||||
semantics, meaning:
|
||||
|
||||
* If any declaration that is declared ``inline`` is not declared ``extern``,
|
||||
then the ``inline`` keyword is just a hint. In particular, an out-of-line
|
||||
definition is still emitted for a function with external linkage, even if all
|
||||
call sites are inlined, unlike in C99 and C++ inline semantics.
|
||||
|
||||
* If all declarations that are declared ``inline`` are also declared
|
||||
``extern``, then the function body is present only for inlining and no
|
||||
out-of-line version is emitted.
|
||||
|
||||
Some important consequences: ``static inline`` emits an out-of-line
|
||||
version if needed, a plain ``inline`` definition emits an out-of-line version
|
||||
always, and an ``extern inline`` definition (in a header) followed by a
|
||||
(non-``extern``) ``inline`` declaration in a source file emits an out-of-line
|
||||
version of the function in that source file but provides the function body for
|
||||
inlining to all includers of the header.
|
||||
|
||||
Either ``__GNUC_GNU_INLINE__`` (GNU inline semantics) or
|
||||
``__GNUC_STDC_INLINE__`` (C99 semantics) will be defined (they are mutually
|
||||
exclusive). If ``__GNUC_STDC_INLINE__`` is defined, then the ``gnu_inline``
|
||||
function attribute can be used to get GNU inline semantics on a per function
|
||||
basis. If ``__GNUC_GNU_INLINE__`` is defined, then the translation unit is
|
||||
already being compiled with GNU inline semantics as the implied default. It is
|
||||
unspecified which macro is defined in a C++ compilation.
|
||||
|
||||
GNU inline semantics are the default behavior with ``-std=gnu89``,
|
||||
``-std=c89``, ``-std=c94``, or ``-fgnu89-inline``.
|
||||
}];
|
||||
}
|
||||
|
||||
def SpeculativeLoadHardeningDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
This attribute can be applied to a function declaration in order to indicate
|
||||
that `Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_
|
||||
should be enabled for the function body. This can also be applied to a method
|
||||
in Objective C.
|
||||
|
||||
Speculative Load Hardening is a best-effort mitigation against
|
||||
information leak attacks that make use of control flow
|
||||
miss-speculation - specifically miss-speculation of whether a branch
|
||||
is taken or not. Typically vulnerabilities enabling such attacks are
|
||||
classified as "Spectre variant #1". Notably, this does not attempt to
|
||||
mitigate against miss-speculation of branch target, classified as
|
||||
"Spectre variant #2" vulnerabilities.
|
||||
|
||||
When inlining, the attribute is sticky. Inlining a function that
|
||||
carries this attribute will cause the caller to gain the
|
||||
attribute. This is intended to provide a maximally conservative model
|
||||
where the code in a function annotated with this attribute will always
|
||||
(even after inlining) end up hardened.
|
||||
}];
|
||||
}
|
||||
|
||||
def ObjCExternallyRetainedDocs : Documentation {
|
||||
let Category = DocCatVariable;
|
||||
let Content = [{
|
||||
The ``objc_externally_retained`` attribute can be applied to strong local
|
||||
variables, functions, methods, or blocks to opt into
|
||||
`externally-retained semantics
|
||||
<https://clang.llvm.org/docs/AutomaticReferenceCounting.html#externally-retained-variables>`_.
|
||||
|
||||
When applied to the definition of a function, method, or block, every parameter
|
||||
of the function with implicit strong retainable object pointer type is
|
||||
considered externally-retained, and becomes ``const``. By explicitly annotating
|
||||
a parameter with ``__strong``, you can opt back into the default
|
||||
non-externally-retained behaviour for that parameter. For instance,
|
||||
``first_param`` is externally-retained below, but not ``second_param``:
|
||||
|
||||
.. code-block:: objc
|
||||
|
||||
__attribute__((objc_externally_retained))
|
||||
void f(NSArray *first_param, __strong NSArray *second_param) {
|
||||
// ...
|
||||
}
|
||||
|
||||
Likewise, when applied to a strong local variable, that variable becomes
|
||||
``const`` and is considered externally-retained.
|
||||
|
||||
When compiled without ``-fobjc-arc``, this attribute is ignored.
|
||||
}]; }
|
||||
|
|
|
|||
|
|
@ -413,6 +413,9 @@ BUILTIN(__builtin_parityll, "iULLi", "nc")
|
|||
BUILTIN(__builtin_popcount , "iUi" , "nc")
|
||||
BUILTIN(__builtin_popcountl , "iULi" , "nc")
|
||||
BUILTIN(__builtin_popcountll, "iULLi", "nc")
|
||||
BUILTIN(__builtin_clrsb , "ii" , "nc")
|
||||
BUILTIN(__builtin_clrsbl , "iLi" , "nc")
|
||||
BUILTIN(__builtin_clrsbll, "iLLi", "nc")
|
||||
|
||||
// FIXME: These type signatures are not correct for targets with int != 32-bits
|
||||
// or with ULL != 64-bits.
|
||||
|
|
@ -425,6 +428,15 @@ BUILTIN(__builtin_bitreverse16, "UsUs", "nc")
|
|||
BUILTIN(__builtin_bitreverse32, "UiUi", "nc")
|
||||
BUILTIN(__builtin_bitreverse64, "ULLiULLi", "nc")
|
||||
|
||||
BUILTIN(__builtin_rotateleft8, "UcUcUc", "nc")
|
||||
BUILTIN(__builtin_rotateleft16, "UsUsUs", "nc")
|
||||
BUILTIN(__builtin_rotateleft32, "UiUiUi", "nc")
|
||||
BUILTIN(__builtin_rotateleft64, "ULLiULLiULLi", "nc")
|
||||
BUILTIN(__builtin_rotateright8, "UcUcUc", "nc")
|
||||
BUILTIN(__builtin_rotateright16, "UsUsUs", "nc")
|
||||
BUILTIN(__builtin_rotateright32, "UiUiUi", "nc")
|
||||
BUILTIN(__builtin_rotateright64, "ULLiULLiULLi", "nc")
|
||||
|
||||
// Random GCC builtins
|
||||
BUILTIN(__builtin_constant_p, "i.", "nctu")
|
||||
BUILTIN(__builtin_classify_type, "i.", "nctu")
|
||||
|
|
@ -471,6 +483,8 @@ BUILTIN(__builtin_wcslen, "zwC*", "nF")
|
|||
BUILTIN(__builtin_wcsncmp, "iwC*wC*z", "nF")
|
||||
BUILTIN(__builtin_wmemchr, "w*wC*wz", "nF")
|
||||
BUILTIN(__builtin_wmemcmp, "iwC*wC*z", "nF")
|
||||
BUILTIN(__builtin_wmemcpy, "w*w*wC*z", "nF")
|
||||
BUILTIN(__builtin_wmemmove, "w*w*wC*z", "nF")
|
||||
BUILTIN(__builtin_return_address, "v*IUi", "n")
|
||||
BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
|
||||
BUILTIN(__builtin_frame_address, "v*IUi", "n")
|
||||
|
|
@ -484,6 +498,7 @@ BUILTIN(__builtin_snprintf, "ic*zcC*.", "nFp:2:")
|
|||
BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:")
|
||||
BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
|
||||
BUILTIN(__builtin_thread_pointer, "v*", "nc")
|
||||
BUILTIN(__builtin_launder, "v*v*", "nt")
|
||||
|
||||
// GCC exception builtins
|
||||
BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t!
|
||||
|
|
@ -524,7 +539,7 @@ BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
|
|||
BUILTIN(__builtin_trap, "v", "nr")
|
||||
BUILTIN(__builtin_debugtrap, "v", "n")
|
||||
BUILTIN(__builtin_unreachable, "v", "nr")
|
||||
BUILTIN(__builtin_shufflevector, "v." , "nc")
|
||||
BUILTIN(__builtin_shufflevector, "v." , "nct")
|
||||
BUILTIN(__builtin_convertvector, "v." , "nct")
|
||||
BUILTIN(__builtin_alloca, "v*z" , "Fn")
|
||||
BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn")
|
||||
|
|
@ -772,6 +787,7 @@ LANGBUILTIN(_InterlockedCompareExchange16, "ssD*ss", "n", ALL_MS_LANGUA
|
|||
LANGBUILTIN(_InterlockedCompareExchange, "NiNiD*NiNi", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedCompareExchange64, "LLiLLiD*LLiLLi", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedCompareExchangePointer_nf, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedDecrement16, "ssD*", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedDecrement, "NiNiD*", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedExchange, "NiNiD*Ni", "n", ALL_MS_LANGUAGES)
|
||||
|
|
@ -803,20 +819,23 @@ LANGBUILTIN(_interlockedbittestandset_acq, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
|
|||
LANGBUILTIN(_interlockedbittestandset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_interlockedbittestandset_rel, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__popcnt64, "ULLiULLi", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__lzcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__lzcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__lzcnt64, "UWiUWi", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__popcnt64, "UWiUWi", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_lrotl, "UNiUNii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotl64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotl64, "UWiUWii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotr8, "UcUcUc", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotr16, "UsUsUc", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotr, "UiUii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_lrotr, "UNiUNii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotr64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotr64, "UWiUWii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES)
|
||||
|
||||
|
|
@ -908,6 +927,8 @@ LIBBUILTIN(wcslen, "zwC*", "f", "wchar.h", ALL_LANGUAGES)
|
|||
LIBBUILTIN(wcsncmp, "iwC*wC*z", "f", "wchar.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(wmemchr, "w*wC*wz", "f", "wchar.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(wmemcmp, "iwC*wC*z", "f", "wchar.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(wmemcpy, "w*w*wC*z", "f", "wchar.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(wmemmove,"w*w*wC*z", "f", "wchar.h", ALL_LANGUAGES)
|
||||
|
||||
// C99
|
||||
// In some systems setjmp is a macro that expands to _setjmp. We undefine
|
||||
|
|
@ -1381,9 +1402,9 @@ BUILTIN(__builtin_subcl, "ULiULiCULiCULiCULi*", "n")
|
|||
BUILTIN(__builtin_subcll, "ULLiULLiCULLiCULLiCULLi*", "n")
|
||||
|
||||
// Checked Arithmetic Builtins for Security.
|
||||
BUILTIN(__builtin_add_overflow, "v.", "nt")
|
||||
BUILTIN(__builtin_sub_overflow, "v.", "nt")
|
||||
BUILTIN(__builtin_mul_overflow, "v.", "nt")
|
||||
BUILTIN(__builtin_add_overflow, "b.", "nt")
|
||||
BUILTIN(__builtin_sub_overflow, "b.", "nt")
|
||||
BUILTIN(__builtin_mul_overflow, "b.", "nt")
|
||||
BUILTIN(__builtin_uadd_overflow, "bUiCUiCUi*", "n")
|
||||
BUILTIN(__builtin_uaddl_overflow, "bULiCULiCULi*", "n")
|
||||
BUILTIN(__builtin_uaddll_overflow, "bULLiCULLiCULLi*", "n")
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LAN
|
|||
TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAdd, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
|
@ -103,6 +104,110 @@ TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h"
|
|||
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(_InterlockedExchangeAdd_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_acq, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_nf, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_rel, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_acq, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_nf, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_rel, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_acq, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_nf, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_rel, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement_acq, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement_nf, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement_rel, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement_acq, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement_nf, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement_rel, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_ReadStatusReg, "ii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_WriteStatusReg, "vii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
#undef BUILTIN
|
||||
#undef LANGBUILTIN
|
||||
#undef TARGET_HEADER_BUILTIN
|
||||
|
|
|
|||
|
|
@ -21,9 +21,10 @@
|
|||
// SI+ only builtins.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
BUILTIN(__builtin_amdgcn_dispatch_ptr, "Uc*4", "nc")
|
||||
BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "Uc*4", "nc")
|
||||
BUILTIN(__builtin_amdgcn_implicitarg_ptr, "Uc*4", "nc")
|
||||
BUILTIN(__builtin_amdgcn_dispatch_ptr, "v*4", "nc")
|
||||
BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "v*4", "nc")
|
||||
BUILTIN(__builtin_amdgcn_implicitarg_ptr, "v*4", "nc")
|
||||
BUILTIN(__builtin_amdgcn_queue_ptr, "v*4", "nc")
|
||||
|
||||
BUILTIN(__builtin_amdgcn_workgroup_id_x, "Ui", "nc")
|
||||
BUILTIN(__builtin_amdgcn_workgroup_id_y, "Ui", "nc")
|
||||
|
|
@ -45,6 +46,8 @@ BUILTIN(__builtin_amdgcn_s_barrier, "v", "n")
|
|||
BUILTIN(__builtin_amdgcn_wave_barrier, "v", "n")
|
||||
BUILTIN(__builtin_amdgcn_s_dcache_inv, "v", "n")
|
||||
BUILTIN(__builtin_amdgcn_buffer_wbinvl1, "v", "n")
|
||||
|
||||
// FIXME: Need to disallow constant address space.
|
||||
BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n")
|
||||
BUILTIN(__builtin_amdgcn_div_scalef, "fffbb*", "n")
|
||||
BUILTIN(__builtin_amdgcn_div_fmas, "ddddb", "nc")
|
||||
|
|
@ -93,9 +96,15 @@ BUILTIN(__builtin_amdgcn_ds_bpermute, "iii", "nc")
|
|||
BUILTIN(__builtin_amdgcn_readfirstlane, "ii", "nc")
|
||||
BUILTIN(__builtin_amdgcn_readlane, "iii", "nc")
|
||||
BUILTIN(__builtin_amdgcn_fmed3f, "ffff", "nc")
|
||||
BUILTIN(__builtin_amdgcn_ds_faddf, "ff*fIiIiIb", "n")
|
||||
BUILTIN(__builtin_amdgcn_ds_fminf, "ff*fIiIiIb", "n")
|
||||
BUILTIN(__builtin_amdgcn_ds_fmaxf, "ff*fIiIiIb", "n")
|
||||
BUILTIN(__builtin_amdgcn_ds_faddf, "ff*3fIiIiIb", "n")
|
||||
BUILTIN(__builtin_amdgcn_ds_fminf, "ff*3fIiIiIb", "n")
|
||||
BUILTIN(__builtin_amdgcn_ds_fmaxf, "ff*3fIiIiIb", "n")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CI+ only builtins.
|
||||
//===----------------------------------------------------------------------===//
|
||||
TARGET_BUILTIN(__builtin_amdgcn_s_dcache_inv_vol, "v", "n", "ci-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_buffer_wbinvl1_vol, "v", "n", "ci-insts")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// VI+ only builtins.
|
||||
|
|
@ -113,6 +122,8 @@ TARGET_BUILTIN(__builtin_amdgcn_fracth, "hh", "nc", "16-bit-insts")
|
|||
TARGET_BUILTIN(__builtin_amdgcn_classh, "bhi", "nc", "16-bit-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_mov_dpp, "iiIiIiIiIb", "nc", "dpp")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_update_dpp, "iiiIiIiIiIb", "nc", "dpp")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_s_dcache_wb, "v", "n", "vi-insts")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// GFX9+ only builtins.
|
||||
|
|
@ -124,13 +135,13 @@ TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
|
|||
// Deep learning builtins.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dl-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dl-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dl-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dl-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dl-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dl-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dl-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dot-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dot-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dot-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot-insts")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Special builtins.
|
||||
|
|
|
|||
|
|
@ -230,6 +230,104 @@ TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h"
|
|||
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(_InterlockedExchangeAdd_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedExchange64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_acq, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_nf, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_rel, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_acq, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_nf, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_rel, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_acq, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_nf, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_rel, "LiLiD*LiLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedOr64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedXor64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedAnd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement_acq, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement_nf, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement_rel, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedIncrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement_acq, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement_nf, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement_rel, "LiLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
#undef BUILTIN
|
||||
#undef LANGBUILTIN
|
||||
#undef TARGET_HEADER_BUILTIN
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,70 +0,0 @@
|
|||
//===-- BuiltinsNios2.def - Nios2 Builtin function database --------*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the Nios2-specific builtin function database. Users of
|
||||
// this file must define the BUILTIN macro to make use of this information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// The format of this database matches clang/Basic/Builtins.def.
|
||||
|
||||
#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
|
||||
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
|
||||
#endif
|
||||
|
||||
// Nios2 R1 builtins:
|
||||
|
||||
//int __builtin_ldbio(volatile const void *);
|
||||
BUILTIN(__builtin_ldbio, "ivDC*", "")
|
||||
//int __builtin_ldbuio(volatile const void *);
|
||||
BUILTIN(__builtin_ldbuio, "ivDC*", "")
|
||||
//int __builtin_ldhio(volatile const void *);
|
||||
BUILTIN(__builtin_ldhio, "ivDC*", "")
|
||||
//int __builtin_ldhuio(volatile const void *);
|
||||
BUILTIN(__builtin_ldhuio, "ivDC*", "")
|
||||
//int __builtin_ldwio(volatile const void *);
|
||||
BUILTIN(__builtin_ldwio, "ivDC*", "")
|
||||
//int __builtin_ldwuio(int);
|
||||
BUILTIN(__builtin_ldwuio, "ii", "")
|
||||
// int __builtin_rdctl(int);
|
||||
BUILTIN(__builtin_rdctl, "iIi", "")
|
||||
// void __builtin_wrctl(int, int);
|
||||
BUILTIN(__builtin_wrctl, "vIii", "")
|
||||
// int __builtin_rdprs(int, int);
|
||||
BUILTIN(__builtin_rdprs, "iii", "")
|
||||
//void __builtin_stbio(volatile void *, int);
|
||||
BUILTIN(__builtin_stbio, "vvD*i", "")
|
||||
//void __builtin_sthio(volatile void *, int);
|
||||
BUILTIN(__builtin_sthio, "vvD*i", "")
|
||||
//void __builtin_stwio(volatile void *, int);
|
||||
BUILTIN(__builtin_stwio, "vvD*i", "")
|
||||
//void __builtin_sync(void);
|
||||
BUILTIN(__builtin_sync, "v", "")
|
||||
// void __builtin_flushd(volatile void *);
|
||||
BUILTIN(__builtin_flushd, "vvD*", "")
|
||||
// void __builtin_flushda(volatile void *);
|
||||
BUILTIN(__builtin_flushda, "vvD*", "")
|
||||
|
||||
// Nios2 R2 builtins:
|
||||
|
||||
// int __builtin_wrpie(int);
|
||||
TARGET_BUILTIN(__builtin_wrpie, "ii", "", "nios2r2mandatory")
|
||||
// void __builtin_eni(int);
|
||||
TARGET_BUILTIN(__builtin_eni, "vi", "", "nios2r2mandatory")
|
||||
// int __builtin_ldex(volatile const void *);
|
||||
TARGET_BUILTIN(__builtin_ldex, "ivDC*", "", "nios2r2mandatory")
|
||||
// int __builtin_stex(volatile void *, int);
|
||||
TARGET_BUILTIN(__builtin_stex, "ivD*i", "", "nios2r2mandatory")
|
||||
// int __builtin_ldsex(volatile const void *);
|
||||
TARGET_BUILTIN(__builtin_ldsex, "ivDC*", "", "nios2r2mpx")
|
||||
// int __builtin_stsex(volatile void *, int);
|
||||
TARGET_BUILTIN(__builtin_stsex, "ivDC*i", "", "nios2r2mpx")
|
||||
|
||||
#undef BUILTIN
|
||||
#undef TARGET_BUILTIN
|
||||
|
|
@ -431,6 +431,8 @@ BUILTIN(__builtin_mulf128_round_to_odd, "LLdLLdLLd", "")
|
|||
BUILTIN(__builtin_divf128_round_to_odd, "LLdLLdLLd", "")
|
||||
BUILTIN(__builtin_fmaf128_round_to_odd, "LLdLLdLLdLLd", "")
|
||||
BUILTIN(__builtin_truncf128_round_to_odd, "dLLd", "")
|
||||
BUILTIN(__builtin_vsx_scalar_extract_expq, "ULLiLLd", "")
|
||||
BUILTIN(__builtin_vsx_scalar_insert_exp_qp, "LLdLLdULLi", "")
|
||||
|
||||
// HTM builtins
|
||||
BUILTIN(__builtin_tbegin, "UiUIi", "")
|
||||
|
|
@ -470,6 +472,10 @@ BUILTIN(__builtin_divde, "SLLiSLLiSLLi", "")
|
|||
BUILTIN(__builtin_divdeu, "ULLiULLiULLi", "")
|
||||
BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "")
|
||||
|
||||
// Vector int128 (un)pack
|
||||
BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "")
|
||||
BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "")
|
||||
|
||||
// FIXME: Obviously incomplete.
|
||||
|
||||
#undef BUILTIN
|
||||
|
|
|
|||
|
|
@ -16,22 +16,94 @@
|
|||
|
||||
// The format of this database matches clang/Basic/Builtins.def.
|
||||
|
||||
#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
|
||||
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
|
||||
#endif
|
||||
|
||||
// Query the current memory size, and increase the current memory size.
|
||||
// Note that memory.size is not "c" (readnone) because it must be sequenced
|
||||
// with respect to memory.grow calls.
|
||||
BUILTIN(__builtin_wasm_memory_size, "zIi", "n")
|
||||
BUILTIN(__builtin_wasm_memory_grow, "zIiz", "n")
|
||||
|
||||
// These are the old names.
|
||||
BUILTIN(__builtin_wasm_mem_size, "zIi", "n")
|
||||
BUILTIN(__builtin_wasm_mem_grow, "zIiz", "n")
|
||||
|
||||
// These are the old old names. They also lack the immediate field.
|
||||
BUILTIN(__builtin_wasm_current_memory, "z", "n")
|
||||
BUILTIN(__builtin_wasm_grow_memory, "zz", "n")
|
||||
// Floating point min/max
|
||||
BUILTIN(__builtin_wasm_min_f32, "fff", "nc")
|
||||
BUILTIN(__builtin_wasm_max_f32, "fff", "nc")
|
||||
BUILTIN(__builtin_wasm_min_f64, "ddd", "nc")
|
||||
BUILTIN(__builtin_wasm_max_f64, "ddd", "nc")
|
||||
|
||||
// Exception handling builtins.
|
||||
BUILTIN(__builtin_wasm_throw, "vUiv*", "r")
|
||||
BUILTIN(__builtin_wasm_rethrow, "v", "r")
|
||||
TARGET_BUILTIN(__builtin_wasm_throw, "vUiv*", "r", "exception-handling")
|
||||
TARGET_BUILTIN(__builtin_wasm_rethrow, "v", "r", "exception-handling")
|
||||
|
||||
// Atomic wait and notify.
|
||||
BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n")
|
||||
BUILTIN(__builtin_wasm_atomic_wait_i64, "iLLi*LLiLLi", "n")
|
||||
BUILTIN(__builtin_wasm_atomic_notify, "Uii*Ui", "n")
|
||||
|
||||
// Saturating fp-to-int conversions
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32_f32, "if", "nc", "nontrapping-fptoint")
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32_f32, "if", "nc", "nontrapping-fptoint")
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32_f64, "id", "nc", "nontrapping-fptoint")
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32_f64, "id", "nc", "nontrapping-fptoint")
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f32, "LLif", "nc", "nontrapping-fptoint")
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f32, "LLif", "nc", "nontrapping-fptoint")
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f64, "LLid", "nc", "nontrapping-fptoint")
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f64, "LLid", "nc", "nontrapping-fptoint")
|
||||
|
||||
// SIMD builtins
|
||||
TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i8x16, "iV16cIi", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc", "unimplemented-simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i16x8, "iV8sIi", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i16x8, "iV8sIi", "nc", "unimplemented-simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_extract_lane_i32x4, "iV4iIi", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_extract_lane_i64x2, "LLiV2LLiIi", "nc", "unimplemented-simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_extract_lane_f32x4, "fV4fIi", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_extract_lane_f64x2, "dV2dIi", "nc", "unimplemented-simd128")
|
||||
|
||||
TARGET_BUILTIN(__builtin_wasm_replace_lane_i8x16, "V16cV16cIii", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_replace_lane_i16x8, "V8sV8sIii", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_replace_lane_i32x4, "V4iV4iIii", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_replace_lane_i64x2, "V2LLiV2LLiIiLLi", "nc", "unimplemented-simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_replace_lane_f32x4, "V4fV4fIif", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_replace_lane_f64x2, "V2dV2dIid", "nc", "unimplemented-simd128")
|
||||
|
||||
TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i8x16, "V16cV16cV16c", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
|
||||
|
||||
TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i8x16, "V16cV16cV16c", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
|
||||
|
||||
TARGET_BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc", "simd128")
|
||||
|
||||
TARGET_BUILTIN(__builtin_wasm_any_true_i8x16, "iV16c", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_any_true_i16x8, "iV8s", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_any_true_i32x4, "iV4i", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_any_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_all_true_i8x16, "iV16c", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_all_true_i16x8, "iV8s", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_all_true_i32x4, "iV4i", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128")
|
||||
|
||||
TARGET_BUILTIN(__builtin_wasm_abs_f32x4, "V4fV4f", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "unimplemented-simd128")
|
||||
|
||||
TARGET_BUILTIN(__builtin_wasm_min_f32x4, "V4fV4fV4f", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_max_f32x4, "V4fV4fV4f", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128")
|
||||
|
||||
TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "unimplemented-simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "unimplemented-simd128")
|
||||
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32x4_f32x4, "V4iV4f", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32x4_f32x4, "V4iV4f", "nc", "simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128")
|
||||
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128")
|
||||
|
||||
#undef BUILTIN
|
||||
#undef TARGET_BUILTIN
|
||||
|
|
|
|||
|
|
@ -719,16 +719,21 @@ TARGET_BUILTIN(__builtin_ia32_wbinvd, "v", "n", "")
|
|||
TARGET_BUILTIN(__builtin_ia32_wbnoinvd, "v", "n", "wbnoinvd")
|
||||
|
||||
// ADX
|
||||
TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "n", "adx")
|
||||
TARGET_BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "n", "")
|
||||
TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "n", "")
|
||||
TARGET_BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "n", "")
|
||||
|
||||
// RDSEED
|
||||
TARGET_BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "n", "rdseed")
|
||||
TARGET_BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "n", "rdseed")
|
||||
|
||||
// LZCNT
|
||||
TARGET_BUILTIN(__builtin_ia32_lzcnt_u16, "UsUs", "nc", "lzcnt")
|
||||
TARGET_BUILTIN(__builtin_ia32_lzcnt_u32, "UiUi", "nc", "lzcnt")
|
||||
|
||||
// BMI
|
||||
TARGET_BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "nc", "bmi")
|
||||
TARGET_BUILTIN(__builtin_ia32_tzcnt_u16, "UsUs", "nc", "")
|
||||
TARGET_BUILTIN(__builtin_ia32_tzcnt_u32, "UiUi", "nc", "")
|
||||
|
||||
// BMI2
|
||||
TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "nc", "bmi2")
|
||||
|
|
@ -963,49 +968,52 @@ TARGET_BUILTIN(__builtin_ia32_vpdpwssds128, "V4iV4iV4iV4i", "ncV:128:", "avx512v
|
|||
TARGET_BUILTIN(__builtin_ia32_vpdpwssds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpdpwssds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8ddC*V8iUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16ffC*V16fUsIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8ddC*V8LLiUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8ffC*V8LLiUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLiLLiC*V8iUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16iiC*V16iUsIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLiLLiC*V8LLiUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8iiC*V8LLiUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vd*UcV8iV8dIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vf*UsV16iV16fIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vd*UcV8LLiV8dIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vf*UcV8LLiV8fIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vLLi*UcV8iV8LLiIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vi*UsV16iV16iIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vLLi*UcV8LLiV8LLiIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vi*UcV8LLiV8iIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2dvC*V2LLiUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLivC*V2LLiUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4dvC*V4LLiUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLivC*V4LLiUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4fvC*V2LLiUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4ivC*V2LLiUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4fvC*V4LLiUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4ivC*V4LLiUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2dvC*V4iUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLivC*V4iUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4dvC*V4iUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLivC*V4iUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4fvC*V4iUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4ivC*V4iUcIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8fvC*V8iUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8ivC*V8iUcIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*V16iUsIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8LLiUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8LLiUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLivC*V8iUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*V16iUsIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLivC*V8LLiUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8LLiUcIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8LLiV8dIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8LLiIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8LLiV8LLiIi", "nV:512:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iIi", "nV:512:", "avx512f")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8iLLiC*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16iiC*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLiLLiC*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLiiC*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iLLi*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16ii*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiLLi*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLii*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLivC*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLivC*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*IiIi", "nV:512:", "avx512pf")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*IiIi", "nV:512:", "avx512pf")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_knotqi, "UcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_knotsi, "UiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_knotdi, "ULLiULLi", "nc", "avx512bw")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "ncV:128:", "avx512vl,avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "ncV:128:", "avx512vl")
|
||||
|
|
@ -1038,10 +1046,10 @@ TARGET_BUILTIN(__builtin_ia32_packssdw512, "V32sV16iV16i", "ncV:512:", "avx512bw
|
|||
TARGET_BUILTIN(__builtin_ia32_packsswb512, "V64cV32sV32s", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_packusdw512, "V32sV16iV16i", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_packuswb512, "V64cV32sV32s", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddusw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddusb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddusw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmaxsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmaxsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pmaxub512, "V64cV64cV64c", "ncV:512:", "avx512bw")
|
||||
|
|
@ -1051,10 +1059,10 @@ TARGET_BUILTIN(__builtin_ia32_pminsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
|
|||
TARGET_BUILTIN(__builtin_ia32_pminub512, "V64cV64cV64c", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pminuw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pshufb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubsb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubsw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubusb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubusw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubusb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_psubusw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512cd,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512cd,avx512vl")
|
||||
|
|
@ -1202,22 +1210,22 @@ TARGET_BUILTIN(__builtin_ia32_scalefpd256_mask, "V4dV4dV4dV4dUc", "ncV:256:", "a
|
|||
TARGET_BUILTIN(__builtin_ia32_scalefps128_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scalefps256_mask, "V8fV8fV8fV8fUc", "ncV:256:", "avx512vl")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vd*UcV2LLiV2dIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vLLi*UcV2LLiV2LLiIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vd*UcV4LLiV4dIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vLLi*UcV4LLiV4LLiIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vf*UcV2LLiV4fIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vi*UcV2LLiV4iIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vf*UcV4LLiV4fIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vi*UcV4LLiV4iIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vd*UcV4iV2dIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vLLi*UcV4iV2LLiIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vd*UcV4iV4dIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vLLi*UcV4iV4LLiIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vf*UcV4iV4fIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vi*UcV4iV4iIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vf*UcV8iV8fIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vi*UcV8iV8iIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vv*UcV2LLiV2dIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vv*UcV2LLiV2LLiIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vv*UcV4LLiV4dIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vv*UcV4LLiV4LLiIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vv*UcV2LLiV4fIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vv*UcV2LLiV4iIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vv*UcV4LLiV4fIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vv*UcV4LLiV4iIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vv*UcV4iV2dIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vv*UcV4iV2LLiIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vv*UcV4iV4dIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vv*UcV4iV4LLiIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vv*UcV4iV4fIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vv*UcV4iV4iIi", "nV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vv*UcV8iV8fIi", "nV:256:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vv*UcV8iV8iIi", "nV:256:", "avx512vl")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_vpermi2vard128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpermi2vard256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl")
|
||||
|
|
@ -1248,43 +1256,25 @@ TARGET_BUILTIN(__builtin_ia32_vpshldw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,a
|
|||
TARGET_BUILTIN(__builtin_ia32_vpshldw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_mask, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_mask, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_mask, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_mask, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_mask, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_mask, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvd128_maskz, "V4iV4iV4iV4iUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvd256_maskz, "V8iV8iV8iV8iUc", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvd512_maskz, "V16iV16iV16iV16iUs", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvw128_maskz, "V8sV8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvw256_maskz, "V16sV16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvw512_maskz, "V32sV32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpshrdd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2")
|
||||
|
|
@ -1734,14 +1724,59 @@ TARGET_BUILTIN(__builtin_ia32_fpclassps512_mask, "UsV16fIiUs", "ncV:512:", "avx5
|
|||
TARGET_BUILTIN(__builtin_ia32_fpclasspd512_mask, "UcV8dIiUc", "ncV:512:", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_fpclasssd_mask, "UcV2dIiUc", "ncV:128:", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_fpclassss_mask, "UcV4fIiUc", "ncV:128:", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kaddqi, "UcUcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kaddhi, "UsUsUs", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kaddsi, "UiUiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kadddi, "ULLiULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kandqi, "UcUcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kandhi, "UsUsUs", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kandsi, "UiUiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kanddi, "ULLiULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kandnqi, "UcUcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kandnhi, "UsUsUs", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kandnsi, "UiUiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kandndi, "ULLiULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_korqi, "UcUcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_korhi, "UsUsUs", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_korsi, "UiUiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kordi, "ULLiULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kortestcqi, "iUcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kortestzqi, "iUcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kortestchi, "iUsUs", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kortestzhi, "iUsUs", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kortestcsi, "iUiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kortestzsi, "iUiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kortestcdi, "iULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kortestzdi, "iULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_ktestcqi, "iUcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_ktestzqi, "iUcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_ktestchi, "iUsUs", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_ktestzhi, "iUsUs", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_ktestcsi, "iUiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_ktestzsi, "iUiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_ktestcdi, "iULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_ktestzdi, "iULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kunpckhi, "UsUsUs", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kxnorqi, "UcUcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kxnorsi, "UiUiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kxnordi, "ULLiULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kxorqi, "UcUcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kxorsi, "UiUiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kxordi, "ULLiULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kshiftliqi, "UcUcIUi", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kshiftlihi, "UsUsIUi", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kshiftlisi, "UiUiIUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kshiftlidi, "ULLiULLiIUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kshiftriqi, "UcUcIUi", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kshiftrihi, "UsUsIUi", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kshiftrisi, "UiUiIUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kshiftridi, "ULLiULLiIUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kmovb, "UcUc", "nc", "avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_kmovw, "UsUs", "nc", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kmovd, "UiUi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_kmovq, "ULLiULLi", "nc", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_palignr512, "V64cV64cV64cIi", "ncV:512:", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_dbpsadbw128, "V8sV16cV16cIi", "ncV:128:", "avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_dbpsadbw256, "V16sV32cV32cIi", "ncV:256:", "avx512bw,avx512vl")
|
||||
|
|
@ -1786,9 +1821,9 @@ TARGET_BUILTIN(__builtin_ia32_cvtsd2ss_round_mask, "V4fV4fV2dV4fUcIi", "ncV:128:
|
|||
TARGET_BUILTIN(__builtin_ia32_cvtsi2ss32, "V4fV4fiIi", "ncV:128:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_cvtss2sd_round_mask, "V2dV2dV4fV2dUcIi", "ncV:128:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_cvtusi2ss32, "V4fV4fUiIi", "ncV:128:", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512_mask, "V64cV64cV64cV64cULLi", "ncV:512:", "avx512vbmi")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128_mask, "V16cV16cV16cV16cUs", "ncV:128:", "avx512vbmi,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256_mask, "V32cV32cV32cV32cUi", "ncV:256:", "avx512vbmi,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512, "V64cV64cV64c", "ncV:512:", "avx512vbmi")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128, "V16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256, "V32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl")
|
||||
|
||||
// generic select intrinsics
|
||||
TARGET_BUILTIN(__builtin_ia32_selectb_128, "V16cUsV16cV16c", "ncV:128:", "avx512bw,avx512vl")
|
||||
|
|
|
|||
|
|
@ -76,12 +76,13 @@ TARGET_BUILTIN(__builtin_ia32_incsspq, "vULLi", "n", "shstk")
|
|||
TARGET_BUILTIN(__builtin_ia32_rdsspq, "ULLiULLi", "n", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_wrssq, "vULLiv*", "n", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_wrussq, "vULLiv*", "n", "shstk")
|
||||
TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "n", "adx")
|
||||
TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "n", "")
|
||||
TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "n", "")
|
||||
TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "n", "")
|
||||
TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "n", "rdrnd")
|
||||
TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "n", "rdseed")
|
||||
TARGET_BUILTIN(__builtin_ia32_lzcnt_u64, "ULLiULLi", "nc", "lzcnt")
|
||||
TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "nc", "bmi")
|
||||
TARGET_BUILTIN(__builtin_ia32_tzcnt_u64, "ULLiULLi", "nc", "")
|
||||
TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "nc", "bmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "nc", "bmi2")
|
||||
TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "nc", "bmi2")
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental
|
|||
CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new
|
||||
///< pass manager.
|
||||
CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
|
||||
CODEGENOPT(IndirectTlsSegRefs, 1, 0) ///< Set when -mno-tls-direct-seg-refs
|
||||
///< is specified.
|
||||
CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls.
|
||||
CODEGENOPT(NoEscapingBlockTailCalls, 1, 0) ///< Do not emit tail calls from
|
||||
///< escaping blocks.
|
||||
|
|
@ -114,6 +116,10 @@ CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the
|
|||
///< compile step.
|
||||
CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole
|
||||
///< program vtable opt).
|
||||
CODEGENOPT(EnableSplitLTOUnit, 1, 0) ///< Enable LTO unit splitting to support
|
||||
/// CFI and traditional whole program
|
||||
/// devirtualization that require whole
|
||||
/// program IR support.
|
||||
CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
|
||||
///< be used with an incremental
|
||||
///< linker.
|
||||
|
|
@ -147,6 +153,8 @@ CODEGENOPT(UniformWGSize , 1, 0) ///< -cl-uniform-work-group-size
|
|||
CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
|
||||
/// Method of Objective-C dispatch to use.
|
||||
ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
|
||||
/// Replace certain message sends with calls to ObjC runtime entrypoints
|
||||
CODEGENOPT(ObjCConvertMessagesToRuntimeCalls , 1, 1)
|
||||
CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is
|
||||
///< enabled.
|
||||
|
||||
|
|
@ -172,11 +180,12 @@ CODEGENOPT(NewStructPathTBAA , 1, 0) ///< Whether or not to use enhanced struct-
|
|||
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
|
||||
CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection
|
||||
///< in AddressSanitizer
|
||||
CODEGENOPT(SanitizeAddressPoisonClassMemberArrayNewCookie, 1,
|
||||
CODEGENOPT(SanitizeAddressPoisonCustomArrayCookie, 1,
|
||||
0) ///< Enable poisoning operator new[] which is not a replaceable
|
||||
///< global allocation function in AddressSanitizer
|
||||
CODEGENOPT(SanitizeAddressGlobalsDeadStripping, 1, 0) ///< Enable linker dead stripping
|
||||
///< of globals in AddressSanitizer
|
||||
CODEGENOPT(SanitizeAddressUseOdrIndicator, 1, 0) ///< Enable ODR indicator globals
|
||||
CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
|
||||
///< MemorySanitizer
|
||||
CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection
|
||||
|
|
@ -211,6 +220,7 @@ CODEGENOPT(SanitizeCoverageStackDepth, 1, 0) ///< Enable max stack depth tracing
|
|||
CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers.
|
||||
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
|
||||
CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float.
|
||||
CODEGENOPT(SpeculativeLoadHardening, 1, 0) ///< Enable speculative load hardening.
|
||||
CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield accesses.
|
||||
CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition.
|
||||
CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers
|
||||
|
|
@ -249,7 +259,9 @@ CODEGENOPT(DebugTypeExtRefs, 1, 0) ///< Whether or not debug info should contain
|
|||
CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should
|
||||
///< contain explicit imports for
|
||||
///< anonymous namespaces
|
||||
CODEGENOPT(EnableSplitDwarf, 1, 0) ///< Whether to enable split DWARF
|
||||
|
||||
ENUM_CODEGENOPT(SplitDwarfMode, DwarfFissionKind, 2, NoFission) ///< DWARF fission mode to use.
|
||||
|
||||
CODEGENOPT(SplitDwarfInlining, 1, 1) ///< Whether to include inlining info in the
|
||||
///< skeleton CU to allow for symbolication
|
||||
///< of inline stack frames without .dwo files.
|
||||
|
|
@ -292,6 +304,9 @@ VALUE_CODEGENOPT(DwarfVersion, 3, 0)
|
|||
/// CodeView and DWARF into the same object.
|
||||
CODEGENOPT(EmitCodeView, 1, 0)
|
||||
|
||||
/// Whether to emit the .debug$H section containing hashes of CodeView types.
|
||||
CODEGENOPT(CodeViewGHash, 1, 0)
|
||||
|
||||
/// The kind of inlining to perform.
|
||||
ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining)
|
||||
|
||||
|
|
@ -326,7 +341,10 @@ CODEGENOPT(DebugInfoForProfiling, 1, 0)
|
|||
CODEGENOPT(PreserveVec3Type, 1, 0)
|
||||
|
||||
/// Whether to emit .debug_gnu_pubnames section instead of .debug_pubnames.
|
||||
CODEGENOPT(GnuPubnames, 1, 0)
|
||||
CODEGENOPT(DebugNameTable, 2, 0)
|
||||
|
||||
/// Whether to use DWARF base address specifiers in .debug_ranges.
|
||||
CODEGENOPT(DebugRangesBaseAddress, 1, 0)
|
||||
|
||||
CODEGENOPT(NoPLT, 1, 0)
|
||||
|
||||
|
|
@ -339,6 +357,12 @@ CODEGENOPT(ForceEmitVTables, 1, 0)
|
|||
/// Whether to emit an address-significance table into the object file.
|
||||
CODEGENOPT(Addrsig, 1, 0)
|
||||
|
||||
ENUM_CODEGENOPT(SignReturnAddress, SignReturnAddressScope, 2, None)
|
||||
ENUM_CODEGENOPT(SignReturnAddressKey, SignReturnAddressKeyValue, 1, AKey)
|
||||
CODEGENOPT(BranchTargetEnforcement, 1, 0)
|
||||
|
||||
/// Whether to emit unused static constants.
|
||||
CODEGENOPT(KeepStaticConsts, 1, 0)
|
||||
|
||||
#undef CODEGENOPT
|
||||
#undef ENUM_CODEGENOPT
|
||||
|
|
@ -11,8 +11,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
|
||||
#define LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
|
||||
#ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H
|
||||
#define LLVM_CLANG_BASIC_CODEGENOPTIONS_H
|
||||
|
||||
#include "clang/Basic/DebugInfoOptions.h"
|
||||
#include "clang/Basic/Sanitizers.h"
|
||||
|
|
@ -33,12 +33,12 @@ class CodeGenOptionsBase {
|
|||
public:
|
||||
#define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits;
|
||||
#define ENUM_CODEGENOPT(Name, Type, Bits, Default)
|
||||
#include "clang/Frontend/CodeGenOptions.def"
|
||||
#include "clang/Basic/CodeGenOptions.def"
|
||||
|
||||
protected:
|
||||
#define CODEGENOPT(Name, Bits, Default)
|
||||
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) unsigned Name : Bits;
|
||||
#include "clang/Frontend/CodeGenOptions.def"
|
||||
#include "clang/Basic/CodeGenOptions.def"
|
||||
};
|
||||
|
||||
/// CodeGenOptions - Track various options which control how the code
|
||||
|
|
@ -71,6 +71,8 @@ public:
|
|||
LocalExecTLSModel
|
||||
};
|
||||
|
||||
enum DwarfFissionKind { NoFission, SplitFileFission, SingleFileFission };
|
||||
|
||||
/// Clang versions with different platform ABI conformance.
|
||||
enum class ClangABI {
|
||||
/// Attempt to be ABI-compatible with code generated by Clang 3.8.x
|
||||
|
|
@ -108,6 +110,14 @@ public:
|
|||
Embed_Marker // Embed a marker as a placeholder for bitcode.
|
||||
};
|
||||
|
||||
enum SignReturnAddressScope {
|
||||
None, // No signing for any function
|
||||
NonLeaf, // Sign the return address of functions that spill LR
|
||||
All // Sign the return address of all functions
|
||||
};
|
||||
|
||||
enum SignReturnAddressKeyValue { AKey, BKey };
|
||||
|
||||
/// The code model to use (-mcmodel).
|
||||
std::string CodeModel;
|
||||
|
||||
|
|
@ -119,6 +129,12 @@ public:
|
|||
/// The filename with path we use for coverage notes files.
|
||||
std::string CoverageNotesFile;
|
||||
|
||||
/// Regexes separated by a semi-colon to filter the files to instrument.
|
||||
std::string ProfileFilterFiles;
|
||||
|
||||
/// Regexes separated by a semi-colon to filter the files to not instrument.
|
||||
std::string ProfileExcludeFiles;
|
||||
|
||||
/// The version string to put into coverage files.
|
||||
char CoverageVersion[4];
|
||||
|
||||
|
|
@ -132,6 +148,10 @@ public:
|
|||
/// non-empty.
|
||||
std::string DwarfDebugFlags;
|
||||
|
||||
/// The string containing the commandline for the llvm.commandline metadata,
|
||||
/// if non-empty.
|
||||
std::string RecordCommandLine;
|
||||
|
||||
std::map<std::string, std::string> DebugPrefixMap;
|
||||
|
||||
/// The ABI to use for passing floating point arguments.
|
||||
|
|
@ -194,6 +214,10 @@ public:
|
|||
/// Name of the profile file to use as input for -fprofile-instr-use
|
||||
std::string ProfileInstrumentUsePath;
|
||||
|
||||
/// Name of the profile remapping file to apply to the profile data supplied
|
||||
/// by -fprofile-sample-use or -fprofile-instr-use.
|
||||
std::string ProfileRemappingFile;
|
||||
|
||||
/// Name of the function summary index file to use for ThinLTO function
|
||||
/// importing.
|
||||
std::string ThinLTOIndexFile;
|
||||
|
|
@ -262,13 +286,15 @@ public:
|
|||
/// Set of XRay instrumentation kinds to emit.
|
||||
XRayInstrSet XRayInstrumentationBundle;
|
||||
|
||||
std::vector<std::string> DefaultFunctionAttrs;
|
||||
|
||||
public:
|
||||
// Define accessors/mutators for code generation options of enumeration type.
|
||||
#define CODEGENOPT(Name, Bits, Default)
|
||||
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
|
||||
Type get##Name() const { return static_cast<Type>(Name); } \
|
||||
void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
|
||||
#include "clang/Frontend/CodeGenOptions.def"
|
||||
#include "clang/Basic/CodeGenOptions.def"
|
||||
|
||||
CodeGenOptions();
|
||||
|
||||
|
|
@ -24,7 +24,8 @@ enum class CudaVersion {
|
|||
CUDA_90,
|
||||
CUDA_91,
|
||||
CUDA_92,
|
||||
LATEST = CUDA_92,
|
||||
CUDA_100,
|
||||
LATEST = CUDA_100,
|
||||
};
|
||||
const char *CudaVersionToString(CudaVersion V);
|
||||
|
||||
|
|
@ -47,6 +48,7 @@ enum class CudaArch {
|
|||
SM_62,
|
||||
SM_70,
|
||||
SM_72,
|
||||
SM_75,
|
||||
GFX600,
|
||||
GFX601,
|
||||
GFX700,
|
||||
|
|
@ -60,6 +62,9 @@ enum class CudaArch {
|
|||
GFX810,
|
||||
GFX900,
|
||||
GFX902,
|
||||
GFX904,
|
||||
GFX906,
|
||||
GFX909,
|
||||
LAST,
|
||||
};
|
||||
const char *CudaArchToString(CudaArch A);
|
||||
|
|
@ -82,6 +87,7 @@ enum class CudaVirtualArch {
|
|||
COMPUTE_62,
|
||||
COMPUTE_70,
|
||||
COMPUTE_72,
|
||||
COMPUTE_75,
|
||||
COMPUTE_AMDGCN,
|
||||
};
|
||||
const char *CudaVirtualArchToString(CudaVirtualArch A);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@
|
|||
namespace clang {
|
||||
namespace codegenoptions {
|
||||
|
||||
enum DebugInfoFormat {
|
||||
DIF_DWARF,
|
||||
DIF_CodeView,
|
||||
};
|
||||
|
||||
enum DebugInfoKind {
|
||||
NoDebugInfo, /// Don't generate debug info.
|
||||
LocTrackingOnly, /// Emit location information but do not generate
|
||||
|
|
@ -21,6 +26,7 @@ enum DebugInfoKind {
|
|||
/// locations for instructions without actually
|
||||
/// emitting debug info for them (e.g., when -Rpass
|
||||
/// is used).
|
||||
DebugDirectivesOnly, /// Emit only debug directives with the line numbers data
|
||||
DebugLineTablesOnly, /// Emit only debug info necessary for generating
|
||||
/// line number tables (-gline-tables-only).
|
||||
LimitedDebugInfo, /// Limit generated debug info to reduce size
|
||||
|
|
|
|||
|
|
@ -97,5 +97,6 @@ def Captured : Decl, DeclContext;
|
|||
def ClassScopeFunctionSpecialization : Decl;
|
||||
def Import : Decl;
|
||||
def OMPThreadPrivate : Decl;
|
||||
def OMPRequires : Decl;
|
||||
def Empty : Decl;
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,9 @@ public:
|
|||
/// IdentifierInfo
|
||||
ak_identifierinfo,
|
||||
|
||||
/// Qualifiers
|
||||
ak_qual,
|
||||
|
||||
/// QualType
|
||||
ak_qualtype,
|
||||
|
||||
|
|
@ -486,10 +489,8 @@ public:
|
|||
DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
|
||||
~DiagnosticsEngine();
|
||||
|
||||
LLVM_DUMP_METHOD void dump() const { DiagStatesByLoc.dump(*SourceMgr); }
|
||||
LLVM_DUMP_METHOD void dump(StringRef DiagName) const {
|
||||
DiagStatesByLoc.dump(*SourceMgr, DiagName);
|
||||
}
|
||||
LLVM_DUMP_METHOD void dump() const;
|
||||
LLVM_DUMP_METHOD void dump(StringRef DiagName) const;
|
||||
|
||||
const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
|
||||
return Diags;
|
||||
|
|
|
|||
29
contrib/llvm/tools/clang/include/clang/Basic/DiagnosticAST.h
Normal file
29
contrib/llvm/tools/clang/include/clang/Basic/DiagnosticAST.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//===--- DiagnosticAST.h - Diagnostics for the AST library ------*- 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_DIAGNOSTICAST_H
|
||||
#define LLVM_CLANG_BASIC_DIAGNOSTICAST_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, CATEGORY) \
|
||||
ENUM,
|
||||
#define ASTSTART
|
||||
#include "clang/Basic/DiagnosticASTKinds.inc"
|
||||
#undef DIAG
|
||||
NUM_BUILTIN_AST_DIAGNOSTICS
|
||||
};
|
||||
} // end namespace diag
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_DIAGNOSTICAST_H
|
||||
|
|
@ -121,6 +121,8 @@ def note_constexpr_ltor_non_const_int : Note<
|
|||
"read of non-const variable %0 is not allowed in a constant expression">;
|
||||
def note_constexpr_ltor_non_constexpr : Note<
|
||||
"read of non-constexpr variable %0 is not allowed in a constant expression">;
|
||||
def note_constexpr_ltor_incomplete_type : Note<
|
||||
"read of incomplete type %0 is not allowed in a constant expression">;
|
||||
def note_constexpr_access_null : Note<
|
||||
"%select{read of|assignment to|increment of|decrement of}0 "
|
||||
"dereferenced null pointer is not allowed in a constant expression">;
|
||||
|
|
@ -163,6 +165,27 @@ def note_constexpr_unsupported_unsized_array : Note<
|
|||
def note_constexpr_unsized_array_indexed : Note<
|
||||
"indexing of array without known bound is not allowed "
|
||||
"in a constant expression">;
|
||||
def note_constexpr_memcpy_null : Note<
|
||||
"%select{source|destination}2 of "
|
||||
"'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' "
|
||||
"is %3">;
|
||||
def note_constexpr_memcpy_type_pun : Note<
|
||||
"cannot constant evaluate '%select{memcpy|memmove}0' from object of "
|
||||
"type %1 to object of type %2">;
|
||||
def note_constexpr_memcpy_nontrivial : Note<
|
||||
"cannot constant evaluate '%select{memcpy|memmove}0' between objects of "
|
||||
"non-trivially-copyable type %1">;
|
||||
def note_constexpr_memcpy_incomplete_type : Note<
|
||||
"cannot constant evaluate '%select{memcpy|memmove}0' between objects of "
|
||||
"incomplete type %1">;
|
||||
def note_constexpr_memcpy_overlap : Note<
|
||||
"'%select{memcpy|wmemcpy}0' between overlapping memory regions">;
|
||||
def note_constexpr_memcpy_unsupported : Note<
|
||||
"'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' "
|
||||
"not supported: %select{"
|
||||
"size to copy (%4) is not a multiple of size of element type %3 (%5)|"
|
||||
"source is not a contiguous array of at least %4 elements of type %3|"
|
||||
"destination is not a contiguous array of at least %4 elements of type %3}2">;
|
||||
|
||||
def warn_integer_constant_overflow : Warning<
|
||||
"overflow in expression; result is %0 with type %1">,
|
||||
|
|
@ -291,4 +314,34 @@ def err_odr_non_type_parameter_type_inconsistent : Error<
|
|||
"non-type template parameter declared with incompatible types in different "
|
||||
"translation units (%0 vs. %1)">;
|
||||
def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
|
||||
|
||||
def remark_sanitize_address_insert_extra_padding_accepted : Remark<
|
||||
"-fsanitize-address-field-padding applied to %0">, ShowInSystemHeader,
|
||||
InGroup<SanitizeAddressRemarks>;
|
||||
def remark_sanitize_address_insert_extra_padding_rejected : Remark<
|
||||
"-fsanitize-address-field-padding ignored for %0 because it "
|
||||
"%select{is not C++|is packed|is a union|is trivially copyable|"
|
||||
"has trivial destructor|is standard layout|is in a blacklisted file|"
|
||||
"is blacklisted}1">, ShowInSystemHeader,
|
||||
InGroup<SanitizeAddressRemarks>;
|
||||
|
||||
def warn_npot_ms_struct : Warning<
|
||||
"ms_struct may not produce Microsoft-compatible layouts with fundamental "
|
||||
"data types with sizes that aren't a power of two">,
|
||||
DefaultError, InGroup<IncompatibleMSStruct>;
|
||||
|
||||
// -Wpadded, -Wpacked
|
||||
def warn_padded_struct_field : Warning<
|
||||
"padding %select{struct|interface|class}0 %1 with %2 "
|
||||
"%select{byte|bit}3%s2 to align %4">,
|
||||
InGroup<Padded>, DefaultIgnore;
|
||||
def warn_padded_struct_anon_field : Warning<
|
||||
"padding %select{struct|interface|class}0 %1 with %2 "
|
||||
"%select{byte|bit}3%s2 to align anonymous bit-field">,
|
||||
InGroup<Padded>, DefaultIgnore;
|
||||
def warn_padded_struct_size : Warning<
|
||||
"padding size of %0 with %1 %select{byte|bit}2%s1 to alignment boundary">,
|
||||
InGroup<Padded>, DefaultIgnore;
|
||||
def warn_unnecessary_packed : Warning<
|
||||
"packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
//===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- 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_DIAGNOSTICANALYSIS_H
|
||||
#define LLVM_CLANG_BASIC_DIAGNOSTICANALYSIS_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, CATEGORY) \
|
||||
ENUM,
|
||||
#define ANALYSISSTART
|
||||
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
|
||||
#undef DIAG
|
||||
NUM_BUILTIN_ANALYSIS_DIAGNOSTICS
|
||||
};
|
||||
} // end namespace diag
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_DIAGNOSTICANALYSIS_H
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
//===--- DiagnosticComment.h - Diagnostics for the AST library --*- 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_DIAGNOSTICCOMMENT_H
|
||||
#define LLVM_CLANG_BASIC_DIAGNOSTICCOMMENT_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, CATEGORY) \
|
||||
ENUM,
|
||||
#define COMMENTSTART
|
||||
#include "clang/Basic/DiagnosticCommentKinds.inc"
|
||||
#undef DIAG
|
||||
NUM_BUILTIN_COMMENT_DIAGNOSTICS
|
||||
};
|
||||
} // end namespace diag
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_DIAGNOSTICCOMMENT_H
|
||||
|
|
@ -131,6 +131,36 @@ def err_nullability_conflicting : Error<
|
|||
|
||||
}
|
||||
|
||||
// OpenCL Section 6.8.g
|
||||
def err_opencl_unknown_type_specifier : Error<
|
||||
"OpenCL %select{C|C++}0 version %1 does not support the '%2' "
|
||||
"%select{type qualifier|storage class specifier}3">;
|
||||
|
||||
def warn_unknown_attribute_ignored : Warning<
|
||||
"unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
|
||||
def err_use_of_tag_name_without_tag : Error<
|
||||
"must use '%1' tag to refer to type %0%select{| in this scope}2">;
|
||||
|
||||
def duplicate_declspec : TextSubstitution<
|
||||
"duplicate '%0' declaration specifier">;
|
||||
|
||||
def ext_duplicate_declspec : Extension<"%sub{duplicate_declspec}0">,
|
||||
InGroup<DuplicateDeclSpecifier>;
|
||||
def ext_warn_duplicate_declspec : ExtWarn<"%sub{duplicate_declspec}0">,
|
||||
InGroup<DuplicateDeclSpecifier>;
|
||||
def warn_duplicate_declspec : Warning<"%sub{duplicate_declspec}0">,
|
||||
InGroup<DuplicateDeclSpecifier>;
|
||||
|
||||
def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">;
|
||||
|
||||
def err_invalid_member_in_interface : Error<
|
||||
"%select{data member |non-public member function |static member function |"
|
||||
"user-declared constructor|user-declared destructor|operator |"
|
||||
"nested class }0%1 is not permitted within an interface type">;
|
||||
|
||||
def err_attribute_uuid_malformed_guid : Error<
|
||||
"uuid attribute contains a malformed GUID">;
|
||||
|
||||
// Sema && Lex
|
||||
def ext_c99_longlong : Extension<
|
||||
"'long long' is an extension when C99 mode is not enabled">,
|
||||
|
|
@ -172,6 +202,8 @@ def err_too_large_for_fixed_point : Error<
|
|||
"this value is too large for this fixed point type">;
|
||||
def err_fixed_point_not_enabled : Error<"compile with "
|
||||
"'-ffixed-point' to enable fixed point types">;
|
||||
def err_unimplemented_conversion_with_fixed_point_type : Error<
|
||||
"conversion between fixed point and %0 is not yet supported">;
|
||||
|
||||
// SEH
|
||||
def err_seh_expected_handler : Error<
|
||||
|
|
@ -187,6 +219,16 @@ def err_seh___finally_block : Error<
|
|||
def note_invalid_subexpr_in_const_expr : Note<
|
||||
"subexpression not valid in a constant expression">;
|
||||
|
||||
// Sema && Frontend
|
||||
let CategoryName = "Inline Assembly Issue" in {
|
||||
def err_asm_invalid_type_in_input : Error<
|
||||
"invalid type %0 in asm input for constraint '%1'">;
|
||||
}
|
||||
|
||||
// Sema && Serialization
|
||||
def warn_dup_category_def : Warning<
|
||||
"duplicate definition of category %1 on interface %0">;
|
||||
|
||||
// Targets
|
||||
|
||||
def err_target_unknown_triple : Error<
|
||||
|
|
@ -199,6 +241,9 @@ def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
|
|||
def err_target_unsupported_abi : Error<"ABI '%0' is not supported on CPU '%1'">;
|
||||
def err_target_unsupported_abi_for_triple : Error<
|
||||
"ABI '%0' is not supported for '%1'">;
|
||||
def err_unsupported_abi_for_opt : Error<"'%0' can only be used with the '%1' ABI">;
|
||||
def err_mips_fp64_req : Error<
|
||||
"'%0' can only be used if the target supports the mfhc1 and mthc1 instructions">;
|
||||
def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">;
|
||||
def err_target_unsupported_fpmath : Error<
|
||||
"the '%0' unit is not supported with this instruction set">;
|
||||
|
|
@ -245,4 +290,10 @@ def err_openclcxx_not_supported : Error<
|
|||
// OpenMP
|
||||
def err_omp_more_one_clause : Error<
|
||||
"directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier| with 'source' dependence}2">;
|
||||
|
||||
// Static Analyzer Core
|
||||
def err_unknown_analyzer_checker : Error<
|
||||
"no analyzer checkers are associated with '%0'">;
|
||||
def note_suggest_disabling_all_checkers : Note<
|
||||
"use -analyzer-disable-all-checks to disable all static analyzer checkers">;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
//===--- DiagnosticCrossTU.h - Diagnostics for Cross TU ---------*- 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_DIAGNOSTICCROSSTU_H
|
||||
#define LLVM_CLANG_BASIC_DIAGNOSTICCROSSTU_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
|
||||
SHOWINSYSHEADER, CATEGORY) \
|
||||
ENUM,
|
||||
#define CROSSTUSTART
|
||||
#include "clang/Basic/DiagnosticCrossTUKinds.inc"
|
||||
#undef DIAG
|
||||
NUM_BUILTIN_CROSSTU_DIAGNOSTICS
|
||||
};
|
||||
} // end namespace diag
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_DIAGNOSTICCROSSTU_H
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue