Merge clang trunk r300422 and resolve conflicts.
This commit is contained in:
commit
20e90f04ad
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang500-import/; revision=317030
@ -478,8 +478,8 @@ CINDEX_LINKAGE void clang_getExpansionLocation(CXSourceLocation location,
|
||||
unsigned *offset);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the file, line, column, and offset represented by
|
||||
* the given source location, as specified in a # line directive.
|
||||
* \brief Retrieve the file, line and column represented by the given source
|
||||
* location, as specified in a # line directive.
|
||||
*
|
||||
* Example: given the following source code in a file somefile.c
|
||||
*
|
||||
@ -3011,8 +3011,9 @@ enum CXTypeKind {
|
||||
CXType_ObjCClass = 28,
|
||||
CXType_ObjCSel = 29,
|
||||
CXType_Float128 = 30,
|
||||
CXType_Half = 31,
|
||||
CXType_FirstBuiltin = CXType_Void,
|
||||
CXType_LastBuiltin = CXType_ObjCSel,
|
||||
CXType_LastBuiltin = CXType_Half,
|
||||
|
||||
CXType_Complex = 100,
|
||||
CXType_Pointer = 101,
|
||||
@ -3435,6 +3436,16 @@ CINDEX_LINKAGE long long clang_getArraySize(CXType T);
|
||||
*/
|
||||
CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T);
|
||||
|
||||
/**
|
||||
* \brief Determine if a typedef is 'transparent' tag.
|
||||
*
|
||||
* A typedef is considered 'transparent' if it shares a name and spelling
|
||||
* location with its underlying tag type, as is the case with the NS_ENUM macro.
|
||||
*
|
||||
* \returns non-zero if transparent and zero otherwise.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Type_isTransparentTagTypedef(CXType T);
|
||||
|
||||
/**
|
||||
* \brief List the possible error codes for \c clang_Type_getSizeOf,
|
||||
* \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
|
||||
@ -4023,8 +4034,8 @@ CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Given a cursor that represents an Objective-C method or property
|
||||
* declaration, return non-zero if the declaration was affected by "@optional".
|
||||
* Returns zero if the cursor is not such a declaration or it is "@required".
|
||||
* declaration, return non-zero if the declaration was affected by "\@optional".
|
||||
* Returns zero if the cursor is not such a declaration or it is "\@required".
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C);
|
||||
|
||||
@ -4700,7 +4711,7 @@ enum CXCompletionChunkKind {
|
||||
*/
|
||||
CXCompletionChunk_HorizontalSpace,
|
||||
/**
|
||||
* Vertical space ('\n'), after which it is generally a good idea to
|
||||
* Vertical space ('\\n'), after which it is generally a good idea to
|
||||
* perform indentation.
|
||||
*/
|
||||
CXCompletionChunk_VerticalSpace
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "clang/Basic/SanitizerBlacklist.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include "clang/Basic/XRayLists.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
@ -66,6 +67,7 @@
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -167,18 +169,20 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
mutable llvm::FoldingSet<DependentUnaryTransformType>
|
||||
DependentUnaryTransformTypes;
|
||||
mutable llvm::FoldingSet<AutoType> AutoTypes;
|
||||
mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
|
||||
DeducedTemplateSpecializationTypes;
|
||||
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
|
||||
llvm::FoldingSet<AttributedType> AttributedTypes;
|
||||
mutable llvm::FoldingSet<PipeType> PipeTypes;
|
||||
|
||||
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
|
||||
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
|
||||
mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage>
|
||||
mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage>
|
||||
SubstTemplateTemplateParms;
|
||||
mutable llvm::ContextualFoldingSet<SubstTemplateTemplateParmPackStorage,
|
||||
ASTContext&>
|
||||
ASTContext&>
|
||||
SubstTemplateTemplateParmPacks;
|
||||
|
||||
|
||||
/// \brief The set of nested name specifiers.
|
||||
///
|
||||
/// This set is managed by the NestedNameSpecifier class.
|
||||
@ -200,17 +204,17 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
/// \brief A cache mapping from CXXRecordDecls to key functions.
|
||||
llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr> KeyFunctions;
|
||||
|
||||
|
||||
/// \brief Mapping from ObjCContainers to their ObjCImplementations.
|
||||
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
|
||||
|
||||
|
||||
/// \brief Mapping from ObjCMethod to its duplicate declaration in the same
|
||||
/// interface.
|
||||
llvm::DenseMap<const ObjCMethodDecl*,const ObjCMethodDecl*> ObjCMethodRedecls;
|
||||
|
||||
/// \brief Mapping from __block VarDecls to their copy initialization expr.
|
||||
llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits;
|
||||
|
||||
|
||||
/// \brief Mapping from class scope functions specialization to their
|
||||
/// template patterns.
|
||||
llvm::DenseMap<const FunctionDecl*, FunctionDecl*>
|
||||
@ -226,21 +230,21 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// is used in canonical template names.
|
||||
class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
|
||||
TemplateTemplateParmDecl *Parm;
|
||||
|
||||
|
||||
public:
|
||||
CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
|
||||
CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
|
||||
: Parm(Parm) { }
|
||||
|
||||
|
||||
TemplateTemplateParmDecl *getParam() const { return Parm; }
|
||||
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); }
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
TemplateTemplateParmDecl *Parm);
|
||||
};
|
||||
mutable llvm::FoldingSet<CanonicalTemplateTemplateParm>
|
||||
CanonTemplateTemplateParms;
|
||||
|
||||
|
||||
TemplateTemplateParmDecl *
|
||||
getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
|
||||
|
||||
@ -259,7 +263,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
/// \brief The typedef for the predefined \c id type.
|
||||
mutable TypedefDecl *ObjCIdDecl;
|
||||
|
||||
|
||||
/// \brief The typedef for the predefined \c SEL type.
|
||||
mutable TypedefDecl *ObjCSelDecl;
|
||||
|
||||
@ -268,7 +272,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
/// \brief The typedef for the predefined \c Protocol class in Objective-C.
|
||||
mutable ObjCInterfaceDecl *ObjCProtocolClassDecl;
|
||||
|
||||
|
||||
/// \brief The typedef for the predefined 'BOOL' type.
|
||||
mutable TypedefDecl *BOOLDecl;
|
||||
|
||||
@ -298,12 +302,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
mutable TypedefDecl *CFConstantStringTypeDecl;
|
||||
|
||||
mutable QualType ObjCSuperType;
|
||||
|
||||
|
||||
QualType ObjCNSStringType;
|
||||
|
||||
/// \brief The typedef declaration for the Objective-C "instancetype" type.
|
||||
TypedefDecl *ObjCInstanceTypeDecl;
|
||||
|
||||
|
||||
/// \brief The type for the C FILE type.
|
||||
TypeDecl *FILEDecl;
|
||||
|
||||
@ -451,11 +455,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// \brief Mapping that stores parameterIndex values for ParmVarDecls when
|
||||
/// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
|
||||
typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable;
|
||||
ParameterIndexTable ParamIndices;
|
||||
|
||||
ParameterIndexTable ParamIndices;
|
||||
|
||||
ImportDecl *FirstLocalImport;
|
||||
ImportDecl *LastLocalImport;
|
||||
|
||||
|
||||
TranslationUnitDecl *TUDecl;
|
||||
mutable ExternCContextDecl *ExternCContext;
|
||||
mutable BuiltinTemplateDecl *MakeIntegerSeqDecl;
|
||||
@ -472,6 +476,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// entities should not be instrumented.
|
||||
std::unique_ptr<SanitizerBlacklist> SanitizerBL;
|
||||
|
||||
/// \brief Function filtering mechanism to determine whether a given function
|
||||
/// should be imbued with the XRay "always" or "never" attributes.
|
||||
std::unique_ptr<XRayFunctionFilter> XRayFilter;
|
||||
|
||||
/// \brief The allocator used to create AST objects.
|
||||
///
|
||||
/// AST objects are never destructed; rather, all memory associated with the
|
||||
@ -488,7 +496,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// \brief The logical -> physical address space map.
|
||||
const LangAS::Map *AddrSpaceMap;
|
||||
|
||||
/// \brief Address space map mangling must be used with language specific
|
||||
/// \brief Address space map mangling must be used with language specific
|
||||
/// address spaces (e.g. OpenCL/CUDA)
|
||||
bool AddrSpaceMapMangling;
|
||||
|
||||
@ -500,7 +508,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
const TargetInfo *Target;
|
||||
const TargetInfo *AuxTarget;
|
||||
clang::PrintingPolicy PrintingPolicy;
|
||||
|
||||
|
||||
public:
|
||||
IdentifierTable &Idents;
|
||||
SelectorTable &Selectors;
|
||||
@ -604,7 +612,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
void setPrintingPolicy(const clang::PrintingPolicy &Policy) {
|
||||
PrintingPolicy = Policy;
|
||||
}
|
||||
|
||||
|
||||
SourceManager& getSourceManager() { return SourceMgr; }
|
||||
const SourceManager& getSourceManager() const { return SourceMgr; }
|
||||
|
||||
@ -619,7 +627,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
|
||||
}
|
||||
void Deallocate(void *Ptr) const { }
|
||||
|
||||
|
||||
/// Return the total amount of physical memory allocated for representing
|
||||
/// AST nodes and type information.
|
||||
size_t getASTAllocatedMemory() const {
|
||||
@ -627,7 +635,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
}
|
||||
/// Return the total memory used for various side tables.
|
||||
size_t getSideTableAllocatedMemory() const;
|
||||
|
||||
|
||||
PartialDiagnostic::StorageAllocator &getDiagAllocator() {
|
||||
return DiagAllocator;
|
||||
}
|
||||
@ -647,13 +655,17 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
QualType getRealTypeForBitwidth(unsigned DestWidth) const;
|
||||
|
||||
bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;
|
||||
|
||||
|
||||
const LangOptions& getLangOpts() const { return LangOpts; }
|
||||
|
||||
const SanitizerBlacklist &getSanitizerBlacklist() const {
|
||||
return *SanitizerBL;
|
||||
}
|
||||
|
||||
const XRayFunctionFilter &getXRayFilter() const {
|
||||
return *XRayFilter;
|
||||
}
|
||||
|
||||
DiagnosticsEngine &getDiagnostics() const;
|
||||
|
||||
FullSourceLoc getFullLoc(SourceLocation Loc) const {
|
||||
@ -862,7 +874,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
|
||||
|
||||
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
|
||||
|
||||
|
||||
// Access to the set of methods overridden by the given C++ method.
|
||||
typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator;
|
||||
overridden_cxx_method_iterator
|
||||
@ -878,7 +890,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
/// \brief Note that the given C++ \p Method overrides the given \p
|
||||
/// Overridden method.
|
||||
void addOverriddenMethod(const CXXMethodDecl *Method,
|
||||
void addOverriddenMethod(const CXXMethodDecl *Method,
|
||||
const CXXMethodDecl *Overridden);
|
||||
|
||||
/// \brief Return C++ or ObjC overridden methods for the given \p Method.
|
||||
@ -891,7 +903,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
void getOverriddenMethods(
|
||||
const NamedDecl *Method,
|
||||
SmallVectorImpl<const NamedDecl *> &Overridden) const;
|
||||
|
||||
|
||||
/// \brief Notify the AST context that a new import declaration has been
|
||||
/// parsed or implicitly created within this translation unit.
|
||||
void addedLocalImportDecl(ImportDecl *Import);
|
||||
@ -899,7 +911,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
static ImportDecl *getNextLocalImport(ImportDecl *Import) {
|
||||
return Import->NextLocalImport;
|
||||
}
|
||||
|
||||
|
||||
typedef llvm::iterator_range<import_iterator> import_range;
|
||||
import_range local_imports() const {
|
||||
return import_range(import_iterator(FirstLocalImport), import_iterator());
|
||||
@ -973,7 +985,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
CanQualType SingletonId;
|
||||
#include "clang/Basic/OpenCLImageTypes.def"
|
||||
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
|
||||
CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy;
|
||||
CanQualType OCLQueueTy, OCLReserveIDTy;
|
||||
CanQualType OMPArraySectionTy;
|
||||
|
||||
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
|
||||
@ -1179,15 +1191,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
/// Returns true iff we need copy/dispose helpers for the given type.
|
||||
bool BlockRequiresCopying(QualType Ty, const VarDecl *D);
|
||||
|
||||
|
||||
|
||||
|
||||
/// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set
|
||||
/// to false in this case. If HasByrefExtendedLayout returns true, byref variable
|
||||
/// has extended lifetime.
|
||||
/// has extended lifetime.
|
||||
bool getByrefLifetime(QualType Ty,
|
||||
Qualifiers::ObjCLifetime &Lifetime,
|
||||
bool &HasByrefExtendedLayout) const;
|
||||
|
||||
|
||||
/// \brief Return the uniqued reference to the type for an lvalue reference
|
||||
/// to the specified type.
|
||||
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true)
|
||||
@ -1231,7 +1243,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
|
||||
ArrayType::ArraySizeModifier ASM,
|
||||
unsigned IndexTypeQuals) const;
|
||||
|
||||
|
||||
/// \brief Returns a vla type where known sizes are replaced with [*].
|
||||
QualType getVariableArrayDecayedType(QualType Ty) const;
|
||||
|
||||
@ -1355,6 +1367,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
|
||||
const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;
|
||||
|
||||
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl);
|
||||
|
||||
/// Get a template argument list with one argument per template parameter
|
||||
/// in a template parameter list, such as for the injected class name of
|
||||
/// a class template.
|
||||
@ -1380,7 +1394,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
|
||||
ArrayRef<ObjCProtocolDecl *> protocols,
|
||||
QualType Canonical = QualType()) const;
|
||||
|
||||
|
||||
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
|
||||
/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
|
||||
/// QT's qualified-id protocol list adopt all protocols in IDecl's list
|
||||
@ -1412,6 +1426,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// \brief C++11 deduction pattern for 'auto &&' type.
|
||||
QualType getAutoRRefDeductType() const;
|
||||
|
||||
/// \brief C++1z deduced class template specialization type.
|
||||
QualType getDeducedTemplateSpecializationType(TemplateName Template,
|
||||
QualType DeducedType,
|
||||
bool IsDependent) const;
|
||||
|
||||
/// \brief Return the unique reference to the type for the specified TagDecl
|
||||
/// (struct/union/class/enum) decl.
|
||||
QualType getTagDeclType(const TagDecl *Decl) const;
|
||||
@ -1471,11 +1490,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
/// \brief Return the C structure type used to represent constant CFStrings.
|
||||
QualType getCFConstantStringType() const;
|
||||
|
||||
|
||||
/// \brief Returns the C struct type for objc_super
|
||||
QualType getObjCSuperType() const;
|
||||
void setObjCSuperType(QualType ST) { ObjCSuperType = ST; }
|
||||
|
||||
|
||||
/// Get the structure type used to representation CFStrings, or NULL
|
||||
/// if it hasn't yet been built.
|
||||
QualType getRawCFConstantStringType() const {
|
||||
@ -1496,11 +1515,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
QualType getObjCNSStringType() const {
|
||||
return ObjCNSStringType;
|
||||
}
|
||||
|
||||
|
||||
void setObjCNSStringType(QualType T) {
|
||||
ObjCNSStringType = T;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Retrieve the type that \c id has been defined to, which may be
|
||||
/// different from the built-in \c id if \c id has been typedef'd.
|
||||
QualType getObjCIdRedefinitionType() const {
|
||||
@ -1508,7 +1527,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
return getObjCIdType();
|
||||
return ObjCIdRedefinitionType;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Set the user-written type that redefines \c id.
|
||||
void setObjCIdRedefinitionType(QualType RedefType) {
|
||||
ObjCIdRedefinitionType = RedefType;
|
||||
@ -1521,7 +1540,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
return getObjCClassType();
|
||||
return ObjCClassRedefinitionType;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Set the user-written type that redefines 'SEL'.
|
||||
void setObjCClassRedefinitionType(QualType RedefType) {
|
||||
ObjCClassRedefinitionType = RedefType;
|
||||
@ -1534,7 +1553,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
return getObjCSelType();
|
||||
return ObjCSelRedefinitionType;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Set the user-written type that redefines 'SEL'.
|
||||
void setObjCSelRedefinitionType(QualType RedefType) {
|
||||
ObjCSelRedefinitionType = RedefType;
|
||||
@ -1586,7 +1605,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// \brief Retrieve the typedef declaration corresponding to the Objective-C
|
||||
/// "instancetype" type.
|
||||
TypedefDecl *getObjCInstanceTypeDecl();
|
||||
|
||||
|
||||
/// \brief Set the type for the C FILE type.
|
||||
void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; }
|
||||
|
||||
@ -1671,7 +1690,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
/// \brief Return the encoded type for this block declaration.
|
||||
std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const;
|
||||
|
||||
|
||||
/// getObjCEncodingForPropertyDecl - Return the encoded type for
|
||||
/// this method declaration. If non-NULL, Container must be either
|
||||
/// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
|
||||
@ -1681,7 +1700,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
|
||||
ObjCProtocolDecl *rProto) const;
|
||||
|
||||
|
||||
ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl(
|
||||
const ObjCPropertyDecl *PD,
|
||||
const Decl *Container) const;
|
||||
@ -1693,7 +1712,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// \brief Retrieve the typedef corresponding to the predefined \c id type
|
||||
/// in Objective-C.
|
||||
TypedefDecl *getObjCIdDecl() const;
|
||||
|
||||
|
||||
/// \brief Represents the Objective-CC \c id type.
|
||||
///
|
||||
/// This is set up lazily, by Sema. \c id is always a (typedef for a)
|
||||
@ -1705,26 +1724,26 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// \brief Retrieve the typedef corresponding to the predefined 'SEL' type
|
||||
/// in Objective-C.
|
||||
TypedefDecl *getObjCSelDecl() const;
|
||||
|
||||
|
||||
/// \brief Retrieve the type that corresponds to the predefined Objective-C
|
||||
/// 'SEL' type.
|
||||
QualType getObjCSelType() const {
|
||||
QualType getObjCSelType() const {
|
||||
return getTypeDeclType(getObjCSelDecl());
|
||||
}
|
||||
|
||||
/// \brief Retrieve the typedef declaration corresponding to the predefined
|
||||
/// Objective-C 'Class' type.
|
||||
TypedefDecl *getObjCClassDecl() const;
|
||||
|
||||
|
||||
/// \brief Represents the Objective-C \c Class type.
|
||||
///
|
||||
/// This is set up lazily, by Sema. \c Class is always a (typedef for a)
|
||||
/// pointer type, a pointer to a struct.
|
||||
QualType getObjCClassType() const {
|
||||
QualType getObjCClassType() const {
|
||||
return getTypeDeclType(getObjCClassDecl());
|
||||
}
|
||||
|
||||
/// \brief Retrieve the Objective-C class declaration corresponding to
|
||||
/// \brief Retrieve the Objective-C class declaration corresponding to
|
||||
/// the predefined \c Protocol class.
|
||||
ObjCInterfaceDecl *getObjCProtocolDecl() const;
|
||||
|
||||
@ -1742,12 +1761,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
QualType getBOOLType() const {
|
||||
return getTypeDeclType(getBOOLDecl());
|
||||
}
|
||||
|
||||
|
||||
/// \brief Retrieve the type of the Objective-C \c Protocol class.
|
||||
QualType getObjCProtoType() const {
|
||||
return getObjCInterfaceType(getObjCProtocolDecl());
|
||||
}
|
||||
|
||||
|
||||
/// \brief Retrieve the C type declaration corresponding to the predefined
|
||||
/// \c __builtin_va_list type.
|
||||
TypedefDecl *getBuiltinVaListDecl() const;
|
||||
@ -1810,7 +1829,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
qs.addObjCLifetime(lifetime);
|
||||
return getQualifiedType(type, qs);
|
||||
}
|
||||
|
||||
|
||||
/// getUnqualifiedObjCPointerType - Returns version of
|
||||
/// Objective-C pointer type with lifetime qualifier removed.
|
||||
QualType getUnqualifiedObjCPointerType(QualType type) const {
|
||||
@ -1821,7 +1840,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
Qs.removeObjCLifetime();
|
||||
return getQualifiedType(type.getUnqualifiedType(), Qs);
|
||||
}
|
||||
|
||||
|
||||
DeclarationNameInfo getNameForTemplate(TemplateName Name,
|
||||
SourceLocation NameLoc) const;
|
||||
|
||||
@ -1840,7 +1859,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
TemplateName replacement) const;
|
||||
TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
|
||||
const TemplateArgument &ArgPack) const;
|
||||
|
||||
|
||||
enum GetBuiltinTypeError {
|
||||
GE_None, ///< No error
|
||||
GE_Missing_stdio, ///< Missing a type from <stdio.h>
|
||||
@ -1905,7 +1924,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
uint64_t getCharWidth() const {
|
||||
return getTypeSize(CharTy);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Convert a size in bits to a size in characters.
|
||||
CharUnits toCharUnitsFromBits(int64_t BitSize) const;
|
||||
|
||||
@ -1927,11 +1946,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// example, from alignment attributes).
|
||||
unsigned getTypeAlignIfKnown(QualType T) const;
|
||||
|
||||
/// \brief Return the ABI-specified alignment of a (complete) type \p T, in
|
||||
/// \brief Return the ABI-specified alignment of a (complete) type \p T, in
|
||||
/// characters.
|
||||
CharUnits getTypeAlignInChars(QualType T) const;
|
||||
CharUnits getTypeAlignInChars(const Type *T) const;
|
||||
|
||||
|
||||
// getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the
|
||||
// type is a record, its data size is returned.
|
||||
std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const;
|
||||
@ -2036,10 +2055,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
VTableContextBase *getVTableContext();
|
||||
|
||||
MangleContext *createMangleContext();
|
||||
|
||||
|
||||
void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
|
||||
SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const;
|
||||
|
||||
|
||||
unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const;
|
||||
void CollectInheritedProtocols(const Decl *CDecl,
|
||||
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
|
||||
@ -2115,7 +2134,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
*SubTnullability == NullabilityKind::Unspecified ||
|
||||
*SuperTnullability == NullabilityKind::Unspecified)
|
||||
return true;
|
||||
|
||||
|
||||
if (IsParam) {
|
||||
// Ok for the superclass method parameter to be "nonnull" and the subclass
|
||||
// method parameter to be "nullable"
|
||||
@ -2134,9 +2153,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
|
||||
const ObjCMethodDecl *MethodImp);
|
||||
|
||||
|
||||
bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
|
||||
|
||||
|
||||
/// \brief Retrieves the "canonical" nested name specifier for a
|
||||
/// given nested name specifier.
|
||||
///
|
||||
@ -2190,7 +2209,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// \brief Determine whether the given template names refer to the same
|
||||
/// template.
|
||||
bool hasSameTemplateName(TemplateName X, TemplateName Y);
|
||||
|
||||
|
||||
/// \brief Retrieve the "canonical" template argument.
|
||||
///
|
||||
/// The canonical template argument is the simplest template argument
|
||||
@ -2217,7 +2236,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
const {
|
||||
return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T));
|
||||
}
|
||||
|
||||
|
||||
/// \brief Return the innermost element type of an array type.
|
||||
///
|
||||
/// For example, will return "int" for int[m][n]
|
||||
@ -2236,14 +2255,14 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// parameter type used by semantic analysis (C99 6.7.5.3p[7,8],
|
||||
/// C++ [dcl.fct]p3). The adjusted parameter type is returned.
|
||||
QualType getAdjustedParameterType(QualType T) const;
|
||||
|
||||
|
||||
/// \brief Retrieve the parameter type as adjusted for use in the signature
|
||||
/// of a function, decaying array and function types and removing top-level
|
||||
/// cv-qualifiers.
|
||||
QualType getSignatureParameterType(QualType T) const;
|
||||
|
||||
|
||||
QualType getExceptionObjectType(QualType T) const;
|
||||
|
||||
|
||||
/// \brief Return the properly qualified result of decaying the specified
|
||||
/// array type to a pointer.
|
||||
///
|
||||
@ -2269,7 +2288,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// promotion occurs.
|
||||
QualType isPromotableBitField(Expr *E) const;
|
||||
|
||||
/// \brief Return the highest ranked integer type, see C99 6.3.1.8p1.
|
||||
/// \brief Return the highest ranked integer type, see C99 6.3.1.8p1.
|
||||
///
|
||||
/// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If
|
||||
/// \p LHS < \p RHS, return -1.
|
||||
@ -2298,12 +2317,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
return getTargetAddressSpace(Q.getAddressSpace());
|
||||
}
|
||||
|
||||
unsigned getTargetAddressSpace(unsigned AS) const {
|
||||
if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count)
|
||||
return AS;
|
||||
else
|
||||
return (*AddrSpaceMap)[AS - LangAS::Offset];
|
||||
}
|
||||
unsigned getTargetAddressSpace(unsigned AS) const;
|
||||
|
||||
/// Get target-dependent integer value for null pointer which is used for
|
||||
/// constant folding.
|
||||
@ -2311,8 +2325,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
bool addressSpaceMapManglingFor(unsigned AS) const {
|
||||
return AddrSpaceMapMangling ||
|
||||
AS < LangAS::Offset ||
|
||||
AS >= LangAS::Offset + LangAS::Count;
|
||||
AS >= LangAS::Count;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2325,11 +2338,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// Compatibility predicates used to check assignment expressions.
|
||||
bool typesAreCompatible(QualType T1, QualType T2,
|
||||
bool typesAreCompatible(QualType T1, QualType T2,
|
||||
bool CompareUnqualified = false); // C99 6.2.7p1
|
||||
|
||||
bool propertyTypesAreCompatible(QualType, QualType);
|
||||
bool typesAreBlockPointerCompatible(QualType, QualType);
|
||||
bool propertyTypesAreCompatible(QualType, QualType);
|
||||
bool typesAreBlockPointerCompatible(QualType, QualType);
|
||||
|
||||
bool isObjCIdType(QualType T) const {
|
||||
return T == getObjCIdType();
|
||||
@ -2344,7 +2357,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
bool ForCompare);
|
||||
|
||||
bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS);
|
||||
|
||||
|
||||
// Check the safety of assignment from LHS to RHS
|
||||
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
|
||||
const ObjCObjectPointerType *RHSOPT);
|
||||
@ -2370,9 +2383,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
QualType mergeTransparentUnionType(QualType, QualType,
|
||||
bool OfBlockPointer=false,
|
||||
bool Unqualified = false);
|
||||
|
||||
|
||||
QualType mergeObjCGCQualifiers(QualType, QualType);
|
||||
|
||||
|
||||
bool doFunctionTypesMatchOnExtParameterInfos(
|
||||
const FunctionProtoType *FromFunctionType,
|
||||
const FunctionProtoType *ToFunctionType);
|
||||
@ -2442,7 +2455,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// an Objective-C method/property/ivar etc. that is part of an interface,
|
||||
/// otherwise returns null.
|
||||
const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const;
|
||||
|
||||
|
||||
/// \brief Set the copy inialization expression of a block var decl.
|
||||
void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
|
||||
/// \brief Get the copy initialization expression of the VarDecl \p VD, or
|
||||
@ -2466,10 +2479,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// initialized to a given location, which defaults to the empty
|
||||
/// location.
|
||||
TypeSourceInfo *
|
||||
getTrivialTypeSourceInfo(QualType T,
|
||||
getTrivialTypeSourceInfo(QualType T,
|
||||
SourceLocation Loc = SourceLocation()) const;
|
||||
|
||||
/// \brief Add a deallocation callback that will be invoked when the
|
||||
/// \brief Add a deallocation callback that will be invoked when the
|
||||
/// ASTContext is destroyed.
|
||||
///
|
||||
/// \param Callback A callback function that will be invoked on destruction.
|
||||
@ -2478,6 +2491,16 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
/// when it is called.
|
||||
void AddDeallocation(void (*Callback)(void*), void *Data);
|
||||
|
||||
/// If T isn't trivially destructible, calls AddDeallocation to register it
|
||||
/// for destruction.
|
||||
template <typename T>
|
||||
void addDestruction(T *Ptr) {
|
||||
if (!std::is_trivially_destructible<T>::value) {
|
||||
auto DestroyPtr = [](void *V) { static_cast<T *>(V)->~T(); };
|
||||
AddDeallocation(DestroyPtr, Ptr);
|
||||
}
|
||||
}
|
||||
|
||||
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
|
||||
GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
|
||||
|
||||
@ -2534,15 +2557,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
/// \brief The number of implicitly-declared default constructors.
|
||||
static unsigned NumImplicitDefaultConstructors;
|
||||
|
||||
/// \brief The number of implicitly-declared default constructors for
|
||||
|
||||
/// \brief The number of implicitly-declared default constructors for
|
||||
/// which declarations were built.
|
||||
static unsigned NumImplicitDefaultConstructorsDeclared;
|
||||
|
||||
/// \brief The number of implicitly-declared copy constructors.
|
||||
static unsigned NumImplicitCopyConstructors;
|
||||
|
||||
/// \brief The number of implicitly-declared copy constructors for
|
||||
|
||||
/// \brief The number of implicitly-declared copy constructors for
|
||||
/// which declarations were built.
|
||||
static unsigned NumImplicitCopyConstructorsDeclared;
|
||||
|
||||
@ -2555,25 +2578,25 @@ class ASTContext : public RefCountedBase<ASTContext> {
|
||||
|
||||
/// \brief The number of implicitly-declared copy assignment operators.
|
||||
static unsigned NumImplicitCopyAssignmentOperators;
|
||||
|
||||
/// \brief The number of implicitly-declared copy assignment operators for
|
||||
|
||||
/// \brief The number of implicitly-declared copy assignment operators for
|
||||
/// which declarations were built.
|
||||
static unsigned NumImplicitCopyAssignmentOperatorsDeclared;
|
||||
|
||||
/// \brief The number of implicitly-declared move assignment operators.
|
||||
static unsigned NumImplicitMoveAssignmentOperators;
|
||||
|
||||
/// \brief The number of implicitly-declared move assignment operators for
|
||||
|
||||
/// \brief The number of implicitly-declared move assignment operators for
|
||||
/// which declarations were built.
|
||||
static unsigned NumImplicitMoveAssignmentOperatorsDeclared;
|
||||
|
||||
/// \brief The number of implicitly-declared destructors.
|
||||
static unsigned NumImplicitDestructors;
|
||||
|
||||
/// \brief The number of implicitly-declared destructors for which
|
||||
|
||||
/// \brief The number of implicitly-declared destructors for which
|
||||
/// declarations were built.
|
||||
static unsigned NumImplicitDestructorsDeclared;
|
||||
|
||||
|
||||
public:
|
||||
/// \brief Initialize built-in types.
|
||||
///
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
|
@ -169,9 +169,6 @@ BUILTIN_TYPE(OCLClkEvent, OCLClkEventTy)
|
||||
// OpenCL queue_t.
|
||||
BUILTIN_TYPE(OCLQueue, OCLQueueTy)
|
||||
|
||||
// OpenCL ndrange_t.
|
||||
BUILTIN_TYPE(OCLNDRange, OCLNDRangeTy)
|
||||
|
||||
// OpenCL reserve_id_t.
|
||||
BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy)
|
||||
|
||||
|
@ -838,7 +838,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
|
||||
|
||||
/// Describes the kind of default argument for this parameter. By default
|
||||
/// this is none. If this is normal, then the default argument is stored in
|
||||
/// the \c VarDecl initalizer expression unless we were unble to parse
|
||||
/// the \c VarDecl initializer expression unless we were unable to parse
|
||||
/// (even an invalid) expression for the default argument.
|
||||
unsigned DefaultArgKind : 2;
|
||||
|
||||
@ -1605,9 +1605,14 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
|
||||
|
||||
// FIXME: This can be packed into the bitfields in DeclContext.
|
||||
// NOTE: VC++ packs bitfields poorly if the types differ.
|
||||
unsigned SClass : 2;
|
||||
unsigned SClass : 3;
|
||||
unsigned IsInline : 1;
|
||||
unsigned IsInlineSpecified : 1;
|
||||
protected:
|
||||
// This is shared by CXXConstructorDecl, CXXConversionDecl, and
|
||||
// CXXDeductionGuideDecl.
|
||||
unsigned IsExplicitSpecified : 1;
|
||||
private:
|
||||
unsigned IsVirtualAsWritten : 1;
|
||||
unsigned IsPure : 1;
|
||||
unsigned HasInheritedPrototype : 1;
|
||||
@ -1708,8 +1713,9 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
|
||||
StartLoc),
|
||||
DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(),
|
||||
SClass(S), IsInline(isInlineSpecified),
|
||||
IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false),
|
||||
IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true),
|
||||
IsInlineSpecified(isInlineSpecified), IsExplicitSpecified(false),
|
||||
IsVirtualAsWritten(false), IsPure(false),
|
||||
HasInheritedPrototype(false), HasWrittenPrototype(true),
|
||||
IsDeleted(false), IsTrivial(false), IsDefaulted(false),
|
||||
IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),
|
||||
IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),
|
||||
@ -2635,12 +2641,17 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
|
||||
typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
|
||||
llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
|
||||
|
||||
// FIXME: This can be packed into the bitfields in Decl.
|
||||
/// If 0, we have not computed IsTransparentTag.
|
||||
/// Otherwise, IsTransparentTag is (CacheIsTransparentTag >> 1).
|
||||
mutable unsigned CacheIsTransparentTag : 2;
|
||||
|
||||
protected:
|
||||
TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
|
||||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
IdentifierInfo *Id, TypeSourceInfo *TInfo)
|
||||
: TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
|
||||
MaybeModedTInfo(TInfo) {}
|
||||
MaybeModedTInfo(TInfo), CacheIsTransparentTag(0) {}
|
||||
|
||||
typedef Redeclarable<TypedefNameDecl> redeclarable_base;
|
||||
TypedefNameDecl *getNextRedeclarationImpl() override {
|
||||
@ -2693,11 +2704,22 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
|
||||
/// this typedef declaration.
|
||||
TagDecl *getAnonDeclWithTypedefName(bool AnyRedecl = false) const;
|
||||
|
||||
/// Determines if this typedef shares a name and spelling location with its
|
||||
/// underlying tag type, as is the case with the NS_ENUM macro.
|
||||
bool isTransparentTag() const {
|
||||
if (CacheIsTransparentTag)
|
||||
return CacheIsTransparentTag & 0x2;
|
||||
return isTransparentTagSlow();
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) {
|
||||
return K >= firstTypedefName && K <= lastTypedefName;
|
||||
}
|
||||
|
||||
private:
|
||||
bool isTransparentTagSlow() const;
|
||||
};
|
||||
|
||||
/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
|
||||
@ -3229,6 +3251,18 @@ class EnumDecl : public TagDecl {
|
||||
return isCompleteDefinition() || isFixed();
|
||||
}
|
||||
|
||||
/// Returns true if this enum is either annotated with
|
||||
/// enum_extensibility(closed) or isn't annotated with enum_extensibility.
|
||||
bool isClosed() const;
|
||||
|
||||
/// Returns true if this enum is annotated with flag_enum and isn't annotated
|
||||
/// with enum_extensibility(open).
|
||||
bool isClosedFlag() const;
|
||||
|
||||
/// Returns true if this enum is annotated with neither flag_enum nor
|
||||
/// enum_extensibility(open).
|
||||
bool isClosedNonFlag() const;
|
||||
|
||||
/// \brief Retrieve the enum definition from which this enumeration could
|
||||
/// be instantiated, if it is an instantiation (rather than a non-template).
|
||||
EnumDecl *getTemplateInstantiationPattern() const;
|
||||
|
@ -654,20 +654,19 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
/// a precompiled header or module) rather than having been parsed.
|
||||
bool isFromASTFile() const { return FromASTFile; }
|
||||
|
||||
/// \brief Retrieve the global declaration ID associated with this
|
||||
/// declaration, which specifies where in the
|
||||
unsigned getGlobalID() const {
|
||||
/// \brief Retrieve the global declaration ID associated with this
|
||||
/// declaration, which specifies where this Decl was loaded from.
|
||||
unsigned getGlobalID() const {
|
||||
if (isFromASTFile())
|
||||
return *((const unsigned*)this - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Retrieve the global ID of the module that owns this particular
|
||||
/// declaration.
|
||||
unsigned getOwningModuleID() const {
|
||||
if (isFromASTFile())
|
||||
return *((const unsigned*)this - 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1030,7 +1029,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
void dump() const;
|
||||
// Same as dump(), but forces color printing.
|
||||
void dumpColor() const;
|
||||
void dump(raw_ostream &Out) const;
|
||||
void dump(raw_ostream &Out, bool Deserialize = false) const;
|
||||
|
||||
/// \brief Looks through the Decl's underlying type to extract a FunctionType
|
||||
/// when possible. Will return null if the type underlying the Decl does not
|
||||
@ -1811,7 +1810,8 @@ class DeclContext {
|
||||
|
||||
void dumpDeclContext() const;
|
||||
void dumpLookups() const;
|
||||
void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false) const;
|
||||
void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false,
|
||||
bool Deserialize = false) const;
|
||||
|
||||
private:
|
||||
void reconcileExternalVisibleStorage() const;
|
||||
|
@ -203,6 +203,11 @@ class CXXBaseSpecifier {
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
|
||||
|
||||
/// \brief Get the location at which the base class type was written.
|
||||
SourceLocation getBaseTypeLoc() const LLVM_READONLY {
|
||||
return BaseTypeInfo->getTypeLoc().getLocStart();
|
||||
}
|
||||
|
||||
/// \brief Determines whether the base class is a virtual base class (or not).
|
||||
bool isVirtual() const { return Virtual; }
|
||||
|
||||
@ -436,9 +441,10 @@ class CXXRecordDecl : public RecordDecl {
|
||||
/// either by the user or implicitly.
|
||||
unsigned DeclaredSpecialMembers : 6;
|
||||
|
||||
/// \brief Whether an implicit copy constructor would have a const-qualified
|
||||
/// parameter.
|
||||
unsigned ImplicitCopyConstructorHasConstParam : 1;
|
||||
/// \brief Whether an implicit copy constructor could have a const-qualified
|
||||
/// parameter, for initializing virtual bases and for other subobjects.
|
||||
unsigned ImplicitCopyConstructorCanHaveConstParamForVBase : 1;
|
||||
unsigned ImplicitCopyConstructorCanHaveConstParamForNonVBase : 1;
|
||||
|
||||
/// \brief Whether an implicit copy assignment operator would have a
|
||||
/// const-qualified parameter.
|
||||
@ -458,6 +464,11 @@ class CXXRecordDecl : public RecordDecl {
|
||||
/// \brief Whether we are currently parsing base specifiers.
|
||||
unsigned IsParsingBaseSpecifiers : 1;
|
||||
|
||||
unsigned HasODRHash : 1;
|
||||
|
||||
/// \brief A hash of parts of the class to help in ODR checking.
|
||||
unsigned ODRHash;
|
||||
|
||||
/// \brief The number of base class specifiers in Bases.
|
||||
unsigned NumBases;
|
||||
|
||||
@ -703,6 +714,8 @@ class CXXRecordDecl : public RecordDecl {
|
||||
return data().IsParsingBaseSpecifiers;
|
||||
}
|
||||
|
||||
unsigned getODRHash() const;
|
||||
|
||||
/// \brief Sets the base classes of this struct or class.
|
||||
void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
|
||||
|
||||
@ -871,7 +884,9 @@ class CXXRecordDecl : public RecordDecl {
|
||||
/// \brief Determine whether an implicit copy constructor for this type
|
||||
/// would have a parameter with a const-qualified reference type.
|
||||
bool implicitCopyConstructorHasConstParam() const {
|
||||
return data().ImplicitCopyConstructorHasConstParam;
|
||||
return data().ImplicitCopyConstructorCanHaveConstParamForNonVBase &&
|
||||
(isAbstract() ||
|
||||
data().ImplicitCopyConstructorCanHaveConstParamForVBase);
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class has a copy constructor with
|
||||
@ -1738,6 +1753,58 @@ class CXXRecordDecl : public RecordDecl {
|
||||
friend class ASTWriter;
|
||||
};
|
||||
|
||||
/// \brief Represents a C++ deduction guide declaration.
|
||||
///
|
||||
/// \code
|
||||
/// template<typename T> struct A { A(); A(T); };
|
||||
/// A() -> A<int>;
|
||||
/// \endcode
|
||||
///
|
||||
/// In this example, there will be an explicit deduction guide from the
|
||||
/// second line, and implicit deduction guide templates synthesized from
|
||||
/// the constructors of \c A.
|
||||
class CXXDeductionGuideDecl : public FunctionDecl {
|
||||
void anchor() override;
|
||||
private:
|
||||
CXXDeductionGuideDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
|
||||
bool IsExplicit, const DeclarationNameInfo &NameInfo,
|
||||
QualType T, TypeSourceInfo *TInfo,
|
||||
SourceLocation EndLocation)
|
||||
: FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
|
||||
SC_None, false, false) {
|
||||
if (EndLocation.isValid())
|
||||
setRangeEnd(EndLocation);
|
||||
IsExplicitSpecified = IsExplicit;
|
||||
}
|
||||
|
||||
public:
|
||||
static CXXDeductionGuideDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation StartLoc, bool IsExplicit,
|
||||
const DeclarationNameInfo &NameInfo,
|
||||
QualType T, TypeSourceInfo *TInfo,
|
||||
SourceLocation EndLocation);
|
||||
|
||||
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; }
|
||||
|
||||
/// Get the template for which this guide performs deduction.
|
||||
TemplateDecl *getDeducedTemplate() const {
|
||||
return getDeclName().getCXXDeductionGuideTemplate();
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == CXXDeductionGuide; }
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
};
|
||||
|
||||
/// \brief Represents a static or instance method of a struct/union/class.
|
||||
///
|
||||
/// In the terminology of the C++ Standard, these are the (static and
|
||||
@ -2161,13 +2228,9 @@ class CXXConstructorDecl final
|
||||
/// \{
|
||||
/// \brief The arguments used to initialize the base or member.
|
||||
LazyCXXCtorInitializersPtr CtorInitializers;
|
||||
unsigned NumCtorInitializers : 30;
|
||||
unsigned NumCtorInitializers : 31;
|
||||
/// \}
|
||||
|
||||
/// \brief Whether this constructor declaration has the \c explicit keyword
|
||||
/// specified.
|
||||
unsigned IsExplicitSpecified : 1;
|
||||
|
||||
/// \brief Whether this constructor declaration is an implicitly-declared
|
||||
/// inheriting constructor.
|
||||
unsigned IsInheritingConstructor : 1;
|
||||
@ -2181,11 +2244,11 @@ class CXXConstructorDecl final
|
||||
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
|
||||
SC_None, isInline, isConstexpr, SourceLocation()),
|
||||
CtorInitializers(nullptr), NumCtorInitializers(0),
|
||||
IsExplicitSpecified(isExplicitSpecified),
|
||||
IsInheritingConstructor((bool)Inherited) {
|
||||
setImplicit(isImplicitlyDeclared);
|
||||
if (Inherited)
|
||||
*getTrailingObjects<InheritedConstructor>() = Inherited;
|
||||
IsExplicitSpecified = isExplicitSpecified;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -2198,15 +2261,6 @@ class CXXConstructorDecl final
|
||||
bool isConstexpr,
|
||||
InheritedConstructor Inherited = InheritedConstructor());
|
||||
|
||||
/// \brief Determine whether this constructor declaration has the
|
||||
/// \c explicit keyword specified.
|
||||
bool isExplicitSpecified() const { return IsExplicitSpecified; }
|
||||
|
||||
/// \brief Determine whether this constructor was marked "explicit" or not.
|
||||
bool isExplicit() const {
|
||||
return cast<CXXConstructorDecl>(getFirstDecl())->isExplicitSpecified();
|
||||
}
|
||||
|
||||
/// \brief Iterates through the member/base initializer list.
|
||||
typedef CXXCtorInitializer **init_iterator;
|
||||
|
||||
@ -2270,6 +2324,14 @@ class CXXConstructorDecl final
|
||||
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();
|
||||
}
|
||||
|
||||
/// \brief Determine whether this constructor is a delegating constructor.
|
||||
bool isDelegatingConstructor() const {
|
||||
return (getNumCtorInitializers() == 1) &&
|
||||
@ -2405,7 +2467,14 @@ class CXXDestructorDecl : public CXXMethodDecl {
|
||||
|
||||
void setOperatorDelete(FunctionDecl *OD);
|
||||
const FunctionDecl *getOperatorDelete() const {
|
||||
return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
|
||||
return getCanonicalDecl()->OperatorDelete;
|
||||
}
|
||||
|
||||
CXXDestructorDecl *getCanonicalDecl() override {
|
||||
return cast<CXXDestructorDecl>(FunctionDecl::getCanonicalDecl());
|
||||
}
|
||||
const CXXDestructorDecl *getCanonicalDecl() const {
|
||||
return const_cast<CXXDestructorDecl*>(this)->getCanonicalDecl();
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
@ -2428,19 +2497,16 @@ class CXXDestructorDecl : public CXXMethodDecl {
|
||||
/// \endcode
|
||||
class CXXConversionDecl : public CXXMethodDecl {
|
||||
void anchor() override;
|
||||
/// Whether this conversion function declaration is marked
|
||||
/// "explicit", meaning that it can only be applied when the user
|
||||
/// explicitly wrote a cast. This is a C++11 feature.
|
||||
bool IsExplicitSpecified : 1;
|
||||
|
||||
CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
|
||||
const DeclarationNameInfo &NameInfo,
|
||||
QualType T, TypeSourceInfo *TInfo,
|
||||
bool isInline, bool isExplicitSpecified,
|
||||
bool isConstexpr, SourceLocation EndLocation)
|
||||
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
|
||||
SC_None, isInline, isConstexpr, EndLocation),
|
||||
IsExplicitSpecified(isExplicitSpecified) { }
|
||||
const DeclarationNameInfo &NameInfo, QualType T,
|
||||
TypeSourceInfo *TInfo, bool isInline,
|
||||
bool isExplicitSpecified, bool isConstexpr,
|
||||
SourceLocation EndLocation)
|
||||
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
|
||||
SC_None, isInline, isConstexpr, EndLocation) {
|
||||
IsExplicitSpecified = isExplicitSpecified;
|
||||
}
|
||||
|
||||
public:
|
||||
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
|
||||
@ -2452,17 +2518,12 @@ class CXXConversionDecl : public CXXMethodDecl {
|
||||
SourceLocation EndLocation);
|
||||
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
/// Whether this conversion function declaration is marked
|
||||
/// "explicit", meaning that it can only be used for direct initialization
|
||||
/// (including explitly written casts). This is a C++11 feature.
|
||||
/// Whether this function is marked as explicit explicitly.
|
||||
bool isExplicitSpecified() const { return IsExplicitSpecified; }
|
||||
|
||||
/// \brief Whether this is an explicit conversion operator (C++11 and later).
|
||||
///
|
||||
/// Explicit conversion operators are only considered for direct
|
||||
/// initialization, e.g., when the user has explicitly written a cast.
|
||||
/// Whether this function is explicit.
|
||||
bool isExplicit() const {
|
||||
return cast<CXXConversionDecl>(getFirstDecl())->isExplicitSpecified();
|
||||
return getCanonicalDecl()->isExplicitSpecified();
|
||||
}
|
||||
|
||||
/// \brief Returns the type that this conversion function is converting to.
|
||||
@ -2474,6 +2535,13 @@ class CXXConversionDecl : public CXXMethodDecl {
|
||||
/// a lambda closure type to a block pointer.
|
||||
bool isLambdaToBlockPointerConversion() const;
|
||||
|
||||
CXXConversionDecl *getCanonicalDecl() override {
|
||||
return cast<CXXConversionDecl>(FunctionDecl::getCanonicalDecl());
|
||||
}
|
||||
const CXXConversionDecl *getCanonicalDecl() const {
|
||||
return const_cast<CXXConversionDecl*>(this)->getCanonicalDecl();
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == CXXConversion; }
|
||||
|
@ -131,7 +131,7 @@ struct StoredDeclsList {
|
||||
} else {
|
||||
DeclsTy &Vec = *getAsVector();
|
||||
Vec.erase(std::remove_if(Vec.begin(), Vec.end(),
|
||||
std::mem_fun(&Decl::isFromASTFile)),
|
||||
[](Decl *D) { return D->isFromASTFile(); }),
|
||||
Vec.end());
|
||||
// Don't have any external decls any more.
|
||||
Data = DeclsAndHasExternalTy(&Vec, false);
|
||||
|
@ -381,15 +381,17 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
ArrayRef<SourceLocation> SelLocs = llvm::None);
|
||||
|
||||
// Iterator access to parameter types.
|
||||
typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
|
||||
typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
|
||||
param_type_iterator;
|
||||
struct GetTypeFn {
|
||||
QualType operator()(const ParmVarDecl *PD) const { return PD->getType(); }
|
||||
};
|
||||
typedef llvm::mapped_iterator<param_const_iterator, GetTypeFn>
|
||||
param_type_iterator;
|
||||
|
||||
param_type_iterator param_type_begin() const {
|
||||
return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
|
||||
return llvm::map_iterator(param_begin(), GetTypeFn());
|
||||
}
|
||||
param_type_iterator param_type_end() const {
|
||||
return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
|
||||
return llvm::map_iterator(param_end(), GetTypeFn());
|
||||
}
|
||||
|
||||
/// createImplicitParams - Used to lazily create the self and cmd
|
||||
@ -743,6 +745,8 @@ class ObjCPropertyDecl : public NamedDecl {
|
||||
|
||||
Selector GetterName; // getter name of NULL if no getter
|
||||
Selector SetterName; // setter name of NULL if no setter
|
||||
SourceLocation GetterNameLoc; // location of the getter attribute's value
|
||||
SourceLocation SetterNameLoc; // location of the setter attribute's value
|
||||
|
||||
ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
|
||||
ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
|
||||
@ -855,10 +859,18 @@ class ObjCPropertyDecl : public NamedDecl {
|
||||
}
|
||||
|
||||
Selector getGetterName() const { return GetterName; }
|
||||
void setGetterName(Selector Sel) { GetterName = Sel; }
|
||||
SourceLocation getGetterNameLoc() const { return GetterNameLoc; }
|
||||
void setGetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
|
||||
GetterName = Sel;
|
||||
GetterNameLoc = Loc;
|
||||
}
|
||||
|
||||
Selector getSetterName() const { return SetterName; }
|
||||
void setSetterName(Selector Sel) { SetterName = Sel; }
|
||||
SourceLocation getSetterNameLoc() const { return SetterNameLoc; }
|
||||
void setSetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
|
||||
SetterName = Sel;
|
||||
SetterNameLoc = Loc;
|
||||
}
|
||||
|
||||
ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
|
||||
void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
|
||||
@ -2320,11 +2332,9 @@ class ObjCImplDecl : public ObjCContainerDecl {
|
||||
protected:
|
||||
ObjCImplDecl(Kind DK, DeclContext *DC,
|
||||
ObjCInterfaceDecl *classInterface,
|
||||
IdentifierInfo *Id,
|
||||
SourceLocation nameLoc, SourceLocation atStartLoc)
|
||||
: ObjCContainerDecl(DK, DC,
|
||||
classInterface? classInterface->getIdentifier()
|
||||
: nullptr,
|
||||
nameLoc, atStartLoc),
|
||||
: ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc),
|
||||
ClassInterface(classInterface) {}
|
||||
|
||||
public:
|
||||
@ -2386,9 +2396,6 @@ class ObjCImplDecl : public ObjCContainerDecl {
|
||||
class ObjCCategoryImplDecl : public ObjCImplDecl {
|
||||
void anchor() override;
|
||||
|
||||
// Category name
|
||||
IdentifierInfo *Id;
|
||||
|
||||
// Category name location
|
||||
SourceLocation CategoryNameLoc;
|
||||
|
||||
@ -2396,8 +2403,9 @@ class ObjCCategoryImplDecl : public ObjCImplDecl {
|
||||
ObjCInterfaceDecl *classInterface,
|
||||
SourceLocation nameLoc, SourceLocation atStartLoc,
|
||||
SourceLocation CategoryNameLoc)
|
||||
: ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
|
||||
Id(Id), CategoryNameLoc(CategoryNameLoc) {}
|
||||
: ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id,
|
||||
nameLoc, atStartLoc),
|
||||
CategoryNameLoc(CategoryNameLoc) {}
|
||||
public:
|
||||
static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
IdentifierInfo *Id,
|
||||
@ -2407,37 +2415,10 @@ class ObjCCategoryImplDecl : public ObjCImplDecl {
|
||||
SourceLocation CategoryNameLoc);
|
||||
static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
/// getIdentifier - Get the identifier that names the category
|
||||
/// interface associated with this implementation.
|
||||
/// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
|
||||
/// with a different meaning. For example:
|
||||
/// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
|
||||
/// returns the class interface name, whereas
|
||||
/// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
|
||||
/// returns the category name.
|
||||
IdentifierInfo *getIdentifier() const {
|
||||
return Id;
|
||||
}
|
||||
void setIdentifier(IdentifierInfo *II) { Id = II; }
|
||||
|
||||
ObjCCategoryDecl *getCategoryDecl() const;
|
||||
|
||||
SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
|
||||
|
||||
/// getName - Get the name of identifier for the class interface associated
|
||||
/// with this implementation as a StringRef.
|
||||
//
|
||||
// FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
|
||||
// meaning.
|
||||
StringRef getName() const { return Id ? Id->getName() : StringRef(); }
|
||||
|
||||
/// @brief Get the name of the class associated with this interface.
|
||||
//
|
||||
// FIXME: Deprecated, move clients to getName().
|
||||
std::string getNameAsString() const {
|
||||
return getName();
|
||||
}
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
|
||||
|
||||
@ -2493,7 +2474,10 @@ class ObjCImplementationDecl : public ObjCImplDecl {
|
||||
SourceLocation superLoc = SourceLocation(),
|
||||
SourceLocation IvarLBraceLoc=SourceLocation(),
|
||||
SourceLocation IvarRBraceLoc=SourceLocation())
|
||||
: ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
|
||||
: ObjCImplDecl(ObjCImplementation, DC, classInterface,
|
||||
classInterface ? classInterface->getIdentifier()
|
||||
: nullptr,
|
||||
nameLoc, atStartLoc),
|
||||
SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
|
||||
IvarRBraceLoc(IvarRBraceLoc),
|
||||
IvarInitializers(nullptr), NumIvarInitializers(0),
|
||||
|
@ -344,6 +344,32 @@ class DefaultArgStorage {
|
||||
// Kinds of Templates
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// \brief Stores the template parameter list and associated constraints for
|
||||
/// \c TemplateDecl objects that track associated constraints.
|
||||
class ConstrainedTemplateDeclInfo {
|
||||
friend TemplateDecl;
|
||||
|
||||
public:
|
||||
ConstrainedTemplateDeclInfo() : TemplateParams(), AssociatedConstraints() {}
|
||||
|
||||
TemplateParameterList *getTemplateParameters() const {
|
||||
return TemplateParams;
|
||||
}
|
||||
|
||||
Expr *getAssociatedConstraints() const { return AssociatedConstraints; }
|
||||
|
||||
protected:
|
||||
void setTemplateParameters(TemplateParameterList *TParams) {
|
||||
TemplateParams = TParams;
|
||||
}
|
||||
|
||||
void setAssociatedConstraints(Expr *AC) { AssociatedConstraints = AC; }
|
||||
|
||||
TemplateParameterList *TemplateParams;
|
||||
Expr *AssociatedConstraints;
|
||||
};
|
||||
|
||||
|
||||
/// \brief The base class of all kinds of template declarations (e.g.,
|
||||
/// class, function, etc.).
|
||||
///
|
||||
@ -352,33 +378,53 @@ class DefaultArgStorage {
|
||||
class TemplateDecl : public NamedDecl {
|
||||
void anchor() override;
|
||||
protected:
|
||||
// This is probably never used.
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name)
|
||||
: NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false),
|
||||
TemplateParams(nullptr) {}
|
||||
|
||||
// Construct a template decl with the given name and parameters.
|
||||
// Used when there is not templated element (tt-params).
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
|
||||
// Used when there is no templated element (e.g., for tt-params).
|
||||
TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
|
||||
SourceLocation L, DeclarationName Name,
|
||||
TemplateParameterList *Params)
|
||||
: NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false),
|
||||
TemplateParams(Params) {}
|
||||
TemplateParams(CTDI) {
|
||||
this->setTemplateParameters(Params);
|
||||
}
|
||||
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
|
||||
TemplateParameterList *Params)
|
||||
: TemplateDecl(nullptr, DK, DC, L, Name, Params) {}
|
||||
|
||||
// Construct a template decl with name, parameters, and templated element.
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
|
||||
TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
|
||||
SourceLocation L, DeclarationName Name,
|
||||
TemplateParameterList *Params, NamedDecl *Decl)
|
||||
: NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl, false),
|
||||
TemplateParams(Params) {}
|
||||
TemplateParams(CTDI) {
|
||||
this->setTemplateParameters(Params);
|
||||
}
|
||||
|
||||
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
|
||||
TemplateParameterList *Params, NamedDecl *Decl)
|
||||
: TemplateDecl(nullptr, DK, DC, L, Name, Params, Decl) {}
|
||||
|
||||
public:
|
||||
/// Get the list of template parameters
|
||||
TemplateParameterList *getTemplateParameters() const {
|
||||
return TemplateParams;
|
||||
const auto *const CTDI =
|
||||
TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
|
||||
return CTDI ? CTDI->getTemplateParameters()
|
||||
: TemplateParams.get<TemplateParameterList *>();
|
||||
}
|
||||
|
||||
/// Get the constraint-expression from the associated requires-clause (if any)
|
||||
const Expr *getRequiresClause() const {
|
||||
return TemplateParams ? TemplateParams->getRequiresClause() : nullptr;
|
||||
const TemplateParameterList *const TP = getTemplateParameters();
|
||||
return TP ? TP->getRequiresClause() : nullptr;
|
||||
}
|
||||
|
||||
Expr *getAssociatedConstraints() const {
|
||||
const TemplateDecl *const C = cast<TemplateDecl>(getCanonicalDecl());
|
||||
const auto *const CTDI =
|
||||
C->TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
|
||||
return CTDI ? CTDI->getAssociatedConstraints() : nullptr;
|
||||
}
|
||||
|
||||
/// Get the underlying, templated declaration.
|
||||
@ -391,7 +437,7 @@ class TemplateDecl : public NamedDecl {
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
return SourceRange(TemplateParams->getTemplateLoc(),
|
||||
return SourceRange(getTemplateParameters()->getTemplateLoc(),
|
||||
TemplatedDecl.getPointer()->getSourceRange().getEnd());
|
||||
}
|
||||
|
||||
@ -407,7 +453,29 @@ class TemplateDecl : public NamedDecl {
|
||||
/// (function or variable) is a concept.
|
||||
llvm::PointerIntPair<NamedDecl *, 1, bool> TemplatedDecl;
|
||||
|
||||
TemplateParameterList* TemplateParams;
|
||||
/// \brief The template parameter list and optional requires-clause
|
||||
/// associated with this declaration; alternatively, a
|
||||
/// \c ConstrainedTemplateDeclInfo if the associated constraints of the
|
||||
/// template are being tracked by this particular declaration.
|
||||
llvm::PointerUnion<TemplateParameterList *,
|
||||
ConstrainedTemplateDeclInfo *>
|
||||
TemplateParams;
|
||||
|
||||
void setTemplateParameters(TemplateParameterList *TParams) {
|
||||
if (auto *const CTDI =
|
||||
TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>()) {
|
||||
CTDI->setTemplateParameters(TParams);
|
||||
} else {
|
||||
TemplateParams = TParams;
|
||||
}
|
||||
}
|
||||
|
||||
void setAssociatedConstraints(Expr *AC) {
|
||||
assert(isCanonicalDecl() &&
|
||||
"Attaching associated constraints to non-canonical Decl");
|
||||
TemplateParams.get<ConstrainedTemplateDeclInfo *>()
|
||||
->setAssociatedConstraints(AC);
|
||||
}
|
||||
|
||||
public:
|
||||
/// \brief Initialize the underlying templated declaration and
|
||||
@ -737,11 +805,17 @@ class RedeclarableTemplateDecl : public TemplateDecl,
|
||||
virtual CommonBase *newCommon(ASTContext &C) const = 0;
|
||||
|
||||
// Construct a template decl with name, parameters, and templated element.
|
||||
RedeclarableTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK,
|
||||
ASTContext &C, DeclContext *DC, SourceLocation L,
|
||||
DeclarationName Name, TemplateParameterList *Params,
|
||||
NamedDecl *Decl)
|
||||
: TemplateDecl(CTDI, DK, DC, L, Name, Params, Decl), redeclarable_base(C),
|
||||
Common() {}
|
||||
|
||||
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L, DeclarationName Name,
|
||||
TemplateParameterList *Params, NamedDecl *Decl)
|
||||
: TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
|
||||
Common() {}
|
||||
: RedeclarableTemplateDecl(nullptr, DK, C, DC, L, Name, Params, Decl) {}
|
||||
|
||||
public:
|
||||
template <class decl_type> friend class RedeclarableTemplate;
|
||||
@ -863,8 +937,6 @@ SpecEntryTraits<FunctionTemplateSpecializationInfo> {
|
||||
|
||||
/// Declaration of a template function.
|
||||
class FunctionTemplateDecl : public RedeclarableTemplateDecl {
|
||||
static void DeallocateCommon(void *Ptr);
|
||||
|
||||
protected:
|
||||
/// \brief Data that is common to all of the declarations of a given
|
||||
/// function template.
|
||||
@ -1407,7 +1479,9 @@ class TemplateTemplateParmDecl final
|
||||
unsigned NumExpansions);
|
||||
|
||||
using TemplateParmPosition::getDepth;
|
||||
using TemplateParmPosition::setDepth;
|
||||
using TemplateParmPosition::getPosition;
|
||||
using TemplateParmPosition::setPosition;
|
||||
using TemplateParmPosition::getIndex;
|
||||
|
||||
/// \brief Whether this template template parameter is a template
|
||||
@ -1960,8 +2034,6 @@ class ClassTemplatePartialSpecializationDecl
|
||||
|
||||
/// Declaration of a class template.
|
||||
class ClassTemplateDecl : public RedeclarableTemplateDecl {
|
||||
static void DeallocateCommon(void *Ptr);
|
||||
|
||||
protected:
|
||||
/// \brief Data that is common to all of the declarations of a given
|
||||
/// class template.
|
||||
@ -1997,10 +2069,16 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
|
||||
llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
|
||||
getPartialSpecializations();
|
||||
|
||||
ClassTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, ASTContext &C,
|
||||
DeclContext *DC, SourceLocation L, DeclarationName Name,
|
||||
TemplateParameterList *Params, NamedDecl *Decl)
|
||||
: RedeclarableTemplateDecl(CTDI, ClassTemplate, C, DC, L, Name, Params,
|
||||
Decl) {}
|
||||
|
||||
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
|
||||
DeclarationName Name, TemplateParameterList *Params,
|
||||
NamedDecl *Decl)
|
||||
: RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
|
||||
: ClassTemplateDecl(nullptr, C, DC, L, Name, Params, Decl) {}
|
||||
|
||||
CommonBase *newCommon(ASTContext &C) const override;
|
||||
|
||||
@ -2023,12 +2101,14 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
|
||||
return getTemplatedDecl()->isThisDeclarationADefinition();
|
||||
}
|
||||
|
||||
// FIXME: remove default argument for AssociatedConstraints
|
||||
/// \brief Create a class template node.
|
||||
static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
DeclarationName Name,
|
||||
TemplateParameterList *Params,
|
||||
NamedDecl *Decl);
|
||||
NamedDecl *Decl,
|
||||
Expr *AssociatedConstraints = nullptr);
|
||||
|
||||
/// \brief Create an empty class template node.
|
||||
static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
@ -2247,8 +2327,6 @@ class FriendTemplateDecl : public Decl {
|
||||
/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
|
||||
/// \endcode
|
||||
class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
|
||||
static void DeallocateCommon(void *Ptr);
|
||||
|
||||
protected:
|
||||
typedef CommonBase Common;
|
||||
|
||||
@ -2773,8 +2851,6 @@ class VarTemplatePartialSpecializationDecl
|
||||
|
||||
/// Declaration of a variable template.
|
||||
class VarTemplateDecl : public RedeclarableTemplateDecl {
|
||||
static void DeallocateCommon(void *Ptr);
|
||||
|
||||
protected:
|
||||
/// \brief Data that is common to all of the declarations of a given
|
||||
/// variable template.
|
||||
@ -2946,6 +3022,16 @@ inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
|
||||
return P.get<TemplateTemplateParmDecl*>();
|
||||
}
|
||||
|
||||
inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
|
||||
auto *TD = dyn_cast<TemplateDecl>(D);
|
||||
return TD && (isa<ClassTemplateDecl>(TD) ||
|
||||
isa<ClassTemplatePartialSpecializationDecl>(TD) ||
|
||||
isa<TypeAliasTemplateDecl>(TD) ||
|
||||
isa<TemplateTemplateParmDecl>(TD))
|
||||
? TD
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
} /* end of namespace clang */
|
||||
|
||||
#endif
|
||||
|
@ -23,6 +23,7 @@ namespace llvm {
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class CXXDeductionGuideNameExtra;
|
||||
class CXXLiteralOperatorIdName;
|
||||
class CXXOperatorIdName;
|
||||
class CXXSpecialName;
|
||||
@ -32,6 +33,7 @@ namespace clang {
|
||||
enum OverloadedOperatorKind : int;
|
||||
struct PrintingPolicy;
|
||||
class QualType;
|
||||
class TemplateDecl;
|
||||
class Type;
|
||||
class TypeSourceInfo;
|
||||
class UsingDirectiveDecl;
|
||||
@ -56,6 +58,7 @@ class DeclarationName {
|
||||
CXXConstructorName,
|
||||
CXXDestructorName,
|
||||
CXXConversionFunctionName,
|
||||
CXXDeductionGuideName,
|
||||
CXXOperatorName,
|
||||
CXXLiteralOperatorName,
|
||||
CXXUsingDirective
|
||||
@ -118,42 +121,36 @@ class DeclarationName {
|
||||
CXXSpecialName *getAsCXXSpecialName() const {
|
||||
NameKind Kind = getNameKind();
|
||||
if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
|
||||
return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
|
||||
return reinterpret_cast<CXXSpecialName *>(getExtra());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
||||
/// getAsCXXOperatorIdName
|
||||
CXXOperatorIdName *getAsCXXOperatorIdName() const {
|
||||
if (getNameKind() == CXXOperatorName)
|
||||
return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
|
||||
return reinterpret_cast<CXXOperatorIdName *>(getExtra());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
|
||||
if (getNameKind() == CXXLiteralOperatorName)
|
||||
return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
|
||||
return reinterpret_cast<CXXLiteralOperatorIdName *>(getExtra());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Construct a declaration name from the name of a C++ constructor,
|
||||
// destructor, or conversion function.
|
||||
DeclarationName(CXXSpecialName *Name)
|
||||
DeclarationName(DeclarationNameExtra *Name)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName");
|
||||
Ptr |= StoredDeclarationNameExtra;
|
||||
}
|
||||
|
||||
// Construct a declaration name from the name of a C++ overloaded
|
||||
// operator.
|
||||
DeclarationName(CXXOperatorIdName *Name)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXOperatorId");
|
||||
Ptr |= StoredDeclarationNameExtra;
|
||||
}
|
||||
|
||||
DeclarationName(CXXLiteralOperatorIdName *Name)
|
||||
: Ptr(reinterpret_cast<uintptr_t>(Name)) {
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
|
||||
assert((Ptr & PtrMask) == 0 && "Improperly aligned DeclarationNameExtra");
|
||||
Ptr |= StoredDeclarationNameExtra;
|
||||
}
|
||||
|
||||
@ -252,6 +249,10 @@ class DeclarationName {
|
||||
/// type associated with that name.
|
||||
QualType getCXXNameType() const;
|
||||
|
||||
/// If this name is the name of a C++ deduction guide, return the
|
||||
/// template associated with that name.
|
||||
TemplateDecl *getCXXDeductionGuideTemplate() const;
|
||||
|
||||
/// getCXXOverloadedOperator - If this name is the name of an
|
||||
/// overloadable operator in C++ (e.g., @c operator+), retrieve the
|
||||
/// kind of overloaded operator.
|
||||
@ -346,6 +347,7 @@ class DeclarationNameTable {
|
||||
void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
|
||||
CXXOperatorIdName *CXXOperatorNames; // Operator names
|
||||
void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
|
||||
void *CXXDeductionGuideNames; // FoldingSet<CXXDeductionGuideNameExtra> *
|
||||
|
||||
DeclarationNameTable(const DeclarationNameTable&) = delete;
|
||||
void operator=(const DeclarationNameTable&) = delete;
|
||||
@ -368,6 +370,9 @@ class DeclarationNameTable {
|
||||
/// 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.
|
||||
DeclarationName getCXXConversionFunctionName(CanQualType Ty);
|
||||
|
@ -115,6 +115,7 @@ class Expr : public Stmt {
|
||||
ExprBits.InstantiationDependent = ID;
|
||||
ExprBits.ValueKind = VK;
|
||||
ExprBits.ObjectKind = OK;
|
||||
assert(ExprBits.ObjectKind == OK && "truncated kind");
|
||||
ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
|
||||
setType(T);
|
||||
}
|
||||
@ -907,6 +908,10 @@ class OpaqueValueExpr : public Expr {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
|
||||
/// The source expression of an opaque value expression is the
|
||||
/// expression which originally generated the value. This is
|
||||
/// provided as a convenience for analyses that don't wish to
|
||||
@ -1167,6 +1172,10 @@ class DeclRefExpr final
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
|
||||
friend TrailingObjects;
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
@ -1222,6 +1231,9 @@ class PredefinedExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&FnName, &FnName + 1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&FnName, &FnName + 1);
|
||||
}
|
||||
|
||||
friend class ASTStmtReader;
|
||||
};
|
||||
@ -1315,6 +1327,9 @@ class IntegerLiteral : public Expr, public APIntStorage {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
class CharacterLiteral : public Expr {
|
||||
@ -1365,6 +1380,9 @@ class CharacterLiteral : public Expr {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
class FloatingLiteral : public Expr, private APFloatStorage {
|
||||
@ -1429,6 +1447,9 @@ class FloatingLiteral : public Expr, private APFloatStorage {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
/// ImaginaryLiteral - We support imaginary integer and floating point literals,
|
||||
@ -1461,6 +1482,9 @@ class ImaginaryLiteral : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Val, &Val+1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&Val, &Val + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/// StringLiteral - This represents a string literal expression, e.g. "foo"
|
||||
@ -1628,6 +1652,9 @@ class StringLiteral : public Expr {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
|
||||
@ -1669,6 +1696,9 @@ class ParenExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Val, &Val+1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&Val, &Val + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/// UnaryOperator - This represents the unary-expression's (except sizeof and
|
||||
@ -1778,6 +1808,9 @@ class UnaryOperator : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Val, &Val+1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&Val, &Val + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/// Helper class for OffsetOfExpr.
|
||||
@ -1981,6 +2014,11 @@ class OffsetOfExpr final
|
||||
Stmt **begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
|
||||
return child_range(begin, begin + NumExprs);
|
||||
}
|
||||
const_child_range children() const {
|
||||
Stmt *const *begin =
|
||||
reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
|
||||
return const_child_range(begin, begin + NumExprs);
|
||||
}
|
||||
friend TrailingObjects;
|
||||
};
|
||||
|
||||
@ -2069,6 +2107,7 @@ class UnaryExprOrTypeTraitExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children();
|
||||
const_child_range children() const;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -2153,6 +2192,9 @@ class ArraySubscriptExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
|
||||
}
|
||||
};
|
||||
|
||||
/// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
|
||||
@ -2313,6 +2355,11 @@ class CallExpr : public Expr {
|
||||
return child_range(&SubExprs[0],
|
||||
&SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START);
|
||||
}
|
||||
|
||||
const_child_range children() const {
|
||||
return const_child_range(&SubExprs[0], &SubExprs[0] + NumArgs +
|
||||
getNumPreArgs() + PREARGS_START);
|
||||
}
|
||||
};
|
||||
|
||||
/// Extra data stored in some MemberExpr objects.
|
||||
@ -2567,6 +2614,9 @@ class MemberExpr final
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Base, &Base+1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&Base, &Base + 1);
|
||||
}
|
||||
|
||||
friend TrailingObjects;
|
||||
friend class ASTReader;
|
||||
@ -2639,6 +2689,9 @@ class CompoundLiteralExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Init, &Init+1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&Init, &Init + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/// CastExpr - Base class for type casts, including both implicit
|
||||
@ -2725,6 +2778,7 @@ class CastExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Op, &Op+1); }
|
||||
const_child_range children() const { return const_child_range(&Op, &Op + 1); }
|
||||
};
|
||||
|
||||
/// ImplicitCastExpr - Allows us to explicitly represent implicit type
|
||||
@ -2917,11 +2971,9 @@ class BinaryOperator : public Expr {
|
||||
private:
|
||||
unsigned Opc : 6;
|
||||
|
||||
// Records the FP_CONTRACT pragma status at the point that this binary
|
||||
// operator was parsed. This bit is only meaningful for operations on
|
||||
// floating point types. For all other types it should default to
|
||||
// false.
|
||||
unsigned FPContractable : 1;
|
||||
// This is only meaningful for operations on floating point types and 0
|
||||
// otherwise.
|
||||
unsigned FPFeatures : 2;
|
||||
SourceLocation OpLoc;
|
||||
|
||||
enum { LHS, RHS, END_EXPR };
|
||||
@ -2930,7 +2982,7 @@ class BinaryOperator : public Expr {
|
||||
|
||||
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
|
||||
ExprValueKind VK, ExprObjectKind OK,
|
||||
SourceLocation opLoc, bool fpContractable)
|
||||
SourceLocation opLoc, FPOptions FPFeatures)
|
||||
: Expr(BinaryOperatorClass, ResTy, VK, OK,
|
||||
lhs->isTypeDependent() || rhs->isTypeDependent(),
|
||||
lhs->isValueDependent() || rhs->isValueDependent(),
|
||||
@ -2938,7 +2990,7 @@ class BinaryOperator : public Expr {
|
||||
rhs->isInstantiationDependent()),
|
||||
(lhs->containsUnexpandedParameterPack() ||
|
||||
rhs->containsUnexpandedParameterPack())),
|
||||
Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
|
||||
Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
|
||||
SubExprs[LHS] = lhs;
|
||||
SubExprs[RHS] = rhs;
|
||||
assert(!isCompoundAssignmentOp() &&
|
||||
@ -3070,19 +3122,26 @@ class BinaryOperator : public Expr {
|
||||
child_range children() {
|
||||
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
|
||||
}
|
||||
|
||||
// Set the FP contractability status of this operator. Only meaningful for
|
||||
// operations on floating point types.
|
||||
void setFPContractable(bool FPC) { FPContractable = FPC; }
|
||||
void setFPFeatures(FPOptions F) { FPFeatures = F.getInt(); }
|
||||
|
||||
FPOptions getFPFeatures() const { return FPOptions(FPFeatures); }
|
||||
|
||||
// Get the FP contractability status of this operator. Only meaningful for
|
||||
// operations on floating point types.
|
||||
bool isFPContractable() const { return FPContractable; }
|
||||
bool isFPContractableWithinStatement() const {
|
||||
return FPOptions(FPFeatures).allowFPContractWithinStatement();
|
||||
}
|
||||
|
||||
protected:
|
||||
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
|
||||
ExprValueKind VK, ExprObjectKind OK,
|
||||
SourceLocation opLoc, bool fpContractable, bool dead2)
|
||||
SourceLocation opLoc, FPOptions FPFeatures, bool dead2)
|
||||
: Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
|
||||
lhs->isTypeDependent() || rhs->isTypeDependent(),
|
||||
lhs->isValueDependent() || rhs->isValueDependent(),
|
||||
@ -3090,7 +3149,7 @@ class BinaryOperator : public Expr {
|
||||
rhs->isInstantiationDependent()),
|
||||
(lhs->containsUnexpandedParameterPack() ||
|
||||
rhs->containsUnexpandedParameterPack())),
|
||||
Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
|
||||
Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
|
||||
SubExprs[LHS] = lhs;
|
||||
SubExprs[RHS] = rhs;
|
||||
}
|
||||
@ -3112,8 +3171,8 @@ class CompoundAssignOperator : public BinaryOperator {
|
||||
CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
|
||||
ExprValueKind VK, ExprObjectKind OK,
|
||||
QualType CompLHSType, QualType CompResultType,
|
||||
SourceLocation OpLoc, bool fpContractable)
|
||||
: BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, fpContractable,
|
||||
SourceLocation OpLoc, FPOptions FPFeatures)
|
||||
: BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
|
||||
true),
|
||||
ComputationLHSType(CompLHSType),
|
||||
ComputationResultType(CompResultType) {
|
||||
@ -3246,6 +3305,9 @@ class ConditionalOperator : public AbstractConditionalOperator {
|
||||
child_range children() {
|
||||
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
|
||||
}
|
||||
};
|
||||
|
||||
/// BinaryConditionalOperator - The GNU extension to the conditional
|
||||
@ -3331,6 +3393,9 @@ class BinaryConditionalOperator : public AbstractConditionalOperator {
|
||||
child_range children() {
|
||||
return child_range(SubExprs, SubExprs + NUM_SUBEXPRS);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(SubExprs, SubExprs + NUM_SUBEXPRS);
|
||||
}
|
||||
};
|
||||
|
||||
inline Expr *AbstractConditionalOperator::getCond() const {
|
||||
@ -3385,6 +3450,9 @@ class AddrLabelExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
/// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
|
||||
@ -3427,6 +3495,9 @@ class StmtExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&SubStmt, &SubStmt+1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&SubStmt, &SubStmt + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/// ShuffleVectorExpr - clang-specific builtin-in function
|
||||
@ -3495,6 +3566,9 @@ class ShuffleVectorExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(&SubExprs[0], &SubExprs[0]+NumExprs);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(&SubExprs[0], &SubExprs[0] + NumExprs);
|
||||
}
|
||||
};
|
||||
|
||||
/// ConvertVectorExpr - Clang builtin function __builtin_convertvector
|
||||
@ -3549,6 +3623,9 @@ class ConvertVectorExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&SrcExpr, &SrcExpr + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
|
||||
@ -3629,6 +3706,9 @@ class ChooseExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
|
||||
}
|
||||
};
|
||||
|
||||
/// GNUNullExpr - Implements the GNU __null extension, which is a name
|
||||
@ -3665,6 +3745,9 @@ class GNUNullExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
/// Represents a call to the builtin function \c __builtin_va_arg.
|
||||
@ -3712,6 +3795,9 @@ class VAArgExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Val, &Val+1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&Val, &Val + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Describes an C or C++ initializer list.
|
||||
@ -3936,10 +4022,16 @@ class InitListExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() {
|
||||
const_child_range CCR = const_cast<const InitListExpr *>(this)->children();
|
||||
return child_range(cast_away_const(CCR.begin()),
|
||||
cast_away_const(CCR.end()));
|
||||
}
|
||||
|
||||
const_child_range children() const {
|
||||
// FIXME: This does not include the array filler expression.
|
||||
if (InitExprs.empty())
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
return const_child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
|
||||
}
|
||||
|
||||
typedef InitExprsTy::iterator iterator;
|
||||
@ -4254,6 +4346,10 @@ class DesignatedInitExpr final
|
||||
Stmt **begin = getTrailingObjects<Stmt *>();
|
||||
return child_range(begin, begin + NumSubExprs);
|
||||
}
|
||||
const_child_range children() const {
|
||||
Stmt * const *begin = getTrailingObjects<Stmt *>();
|
||||
return const_child_range(begin, begin + NumSubExprs);
|
||||
}
|
||||
|
||||
friend TrailingObjects;
|
||||
};
|
||||
@ -4287,6 +4383,9 @@ class NoInitExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
// In cases like:
|
||||
@ -4332,6 +4431,10 @@ class DesignatedInitUpdateExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(&BaseAndUpdaterExprs[0],
|
||||
&BaseAndUpdaterExprs[0] + 2);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a loop initializing the elements of an array.
|
||||
@ -4393,6 +4496,9 @@ class ArrayInitLoopExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(SubExprs, SubExprs + 2);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(SubExprs, SubExprs + 2);
|
||||
}
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
@ -4421,6 +4527,9 @@ class ArrayInitIndexExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
@ -4455,6 +4564,9 @@ class ImplicitValueInitExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
class ParenListExpr : public Expr {
|
||||
@ -4501,6 +4613,9 @@ class ParenListExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(&Exprs[0], &Exprs[0]+NumExprs);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(&Exprs[0], &Exprs[0] + NumExprs);
|
||||
}
|
||||
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
@ -4621,7 +4736,9 @@ class GenericSelectionExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs);
|
||||
}
|
||||
|
||||
const_child_range children() const {
|
||||
return const_child_range(SubExprs, SubExprs + END_EXPR + NumAssocs);
|
||||
}
|
||||
friend class ASTStmtReader;
|
||||
};
|
||||
|
||||
@ -4690,6 +4807,9 @@ class ExtVectorElementExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Base, &Base+1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&Base, &Base + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/// BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
|
||||
@ -4731,6 +4851,9 @@ class BlockExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
/// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2]
|
||||
@ -4776,6 +4899,9 @@ class AsTypeExpr : public Expr {
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
|
||||
const_child_range children() const {
|
||||
return const_child_range(&SrcExpr, &SrcExpr + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/// PseudoObjectExpr - An expression which accesses a pseudo-object
|
||||
@ -4914,8 +5040,15 @@ class PseudoObjectExpr final
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
Stmt **cs = reinterpret_cast<Stmt**>(getSubExprsBuffer());
|
||||
return child_range(cs, cs + getNumSubExprs());
|
||||
const_child_range CCR =
|
||||
const_cast<const PseudoObjectExpr *>(this)->children();
|
||||
return child_range(cast_away_const(CCR.begin()),
|
||||
cast_away_const(CCR.end()));
|
||||
}
|
||||
const_child_range children() const {
|
||||
Stmt *const *cs = const_cast<Stmt *const *>(
|
||||
reinterpret_cast<const Stmt *const *>(getSubExprsBuffer()));
|
||||
return const_child_range(cs, cs + getNumSubExprs());
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
@ -5021,6 +5154,9 @@ class AtomicExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(SubExprs, SubExprs+NumSubExprs);
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(SubExprs, SubExprs + NumSubExprs);
|
||||
}
|
||||
};
|
||||
|
||||
/// TypoExpr - Internal placeholder for expressions where typo correction
|
||||
@ -5039,6 +5175,10 @@ class TypoExpr : public Expr {
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
const_child_range children() const {
|
||||
return const_child_range(const_child_iterator(), const_child_iterator());
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
|
||||
|
||||
|
@ -54,18 +54,16 @@ class CXXOperatorCallExpr : public CallExpr {
|
||||
OverloadedOperatorKind Operator;
|
||||
SourceRange Range;
|
||||
|
||||
// Record the FP_CONTRACT state that applies to this operator call. Only
|
||||
// meaningful for floating point types. For other types this value can be
|
||||
// set to false.
|
||||
unsigned FPContractable : 1;
|
||||
// Only meaningful for floating point types.
|
||||
FPOptions FPFeatures;
|
||||
|
||||
SourceRange getSourceRangeImpl() const LLVM_READONLY;
|
||||
public:
|
||||
CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
|
||||
ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
|
||||
SourceLocation operatorloc, bool fpContractable)
|
||||
SourceLocation operatorloc, FPOptions FPFeatures)
|
||||
: CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc),
|
||||
Operator(Op), FPContractable(fpContractable) {
|
||||
Operator(Op), FPFeatures(FPFeatures) {
|
||||
Range = getSourceRangeImpl();
|
||||
}
|
||||
explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
|
||||
@ -113,11 +111,15 @@ class CXXOperatorCallExpr : public CallExpr {
|
||||
|
||||
// Set the FP contractability status of this operator. Only meaningful for
|
||||
// operations on floating point types.
|
||||
void setFPContractable(bool FPC) { FPContractable = FPC; }
|
||||
void setFPFeatures(FPOptions F) { FPFeatures = F; }
|
||||
|
||||
FPOptions getFPFeatures() const { return FPFeatures; }
|
||||
|
||||
// Get the FP contractability status of this operator. Only meaningful for
|
||||
// operations on floating point types.
|
||||
bool isFPContractable() const { return FPContractable; }
|
||||
bool isFPContractableWithinStatement() const {
|
||||
return FPFeatures.allowFPContractWithinStatement();
|
||||
}
|
||||
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
@ -1470,7 +1472,8 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr {
|
||||
public:
|
||||
CXXTemporaryObjectExpr(const ASTContext &C,
|
||||
CXXConstructorDecl *Cons,
|
||||
TypeSourceInfo *Type,
|
||||
QualType Type,
|
||||
TypeSourceInfo *TSI,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceRange ParenOrBraceRange,
|
||||
bool HadMultipleCandidates,
|
||||
@ -4122,16 +4125,18 @@ class CoroutineSuspendExpr : public Expr {
|
||||
|
||||
enum SubExpr { Common, Ready, Suspend, Resume, Count };
|
||||
Stmt *SubExprs[SubExpr::Count];
|
||||
OpaqueValueExpr *OpaqueValue = nullptr;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
public:
|
||||
CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common,
|
||||
Expr *Ready, Expr *Suspend, Expr *Resume)
|
||||
Expr *Ready, Expr *Suspend, Expr *Resume,
|
||||
OpaqueValueExpr *OpaqueValue)
|
||||
: Expr(SC, Resume->getType(), Resume->getValueKind(),
|
||||
Resume->getObjectKind(), Resume->isTypeDependent(),
|
||||
Resume->isValueDependent(), Common->isInstantiationDependent(),
|
||||
Common->containsUnexpandedParameterPack()),
|
||||
KeywordLoc(KeywordLoc) {
|
||||
KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) {
|
||||
SubExprs[SubExpr::Common] = Common;
|
||||
SubExprs[SubExpr::Ready] = Ready;
|
||||
SubExprs[SubExpr::Suspend] = Suspend;
|
||||
@ -4160,6 +4165,8 @@ class CoroutineSuspendExpr : public Expr {
|
||||
Expr *getCommonExpr() const {
|
||||
return static_cast<Expr*>(SubExprs[SubExpr::Common]);
|
||||
}
|
||||
/// \brief getOpaqueValue - Return the opaque value placeholder.
|
||||
OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
|
||||
|
||||
Expr *getReadyExpr() const {
|
||||
return static_cast<Expr*>(SubExprs[SubExpr::Ready]);
|
||||
@ -4193,11 +4200,17 @@ class CoawaitExpr : public CoroutineSuspendExpr {
|
||||
friend class ASTStmtReader;
|
||||
public:
|
||||
CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready,
|
||||
Expr *Suspend, Expr *Resume)
|
||||
Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue,
|
||||
bool IsImplicit = false)
|
||||
: CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready,
|
||||
Suspend, Resume) {}
|
||||
CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand)
|
||||
: CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {}
|
||||
Suspend, Resume, OpaqueValue) {
|
||||
CoawaitBits.IsImplicit = IsImplicit;
|
||||
}
|
||||
CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand,
|
||||
bool IsImplicit = false)
|
||||
: CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {
|
||||
CoawaitBits.IsImplicit = IsImplicit;
|
||||
}
|
||||
CoawaitExpr(EmptyShell Empty)
|
||||
: CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
|
||||
|
||||
@ -4206,19 +4219,67 @@ class CoawaitExpr : public CoroutineSuspendExpr {
|
||||
return getCommonExpr();
|
||||
}
|
||||
|
||||
bool isImplicit() const { return CoawaitBits.IsImplicit; }
|
||||
void setIsImplicit(bool value = true) { CoawaitBits.IsImplicit = value; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CoawaitExprClass;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a 'co_await' expression while the type of the promise
|
||||
/// is dependent.
|
||||
class DependentCoawaitExpr : public Expr {
|
||||
SourceLocation KeywordLoc;
|
||||
Stmt *SubExprs[2];
|
||||
|
||||
friend class ASTStmtReader;
|
||||
|
||||
public:
|
||||
DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op,
|
||||
UnresolvedLookupExpr *OpCoawait)
|
||||
: Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary,
|
||||
/*TypeDependent*/ true, /*ValueDependent*/ true,
|
||||
/*InstantiationDependent*/ true,
|
||||
Op->containsUnexpandedParameterPack()),
|
||||
KeywordLoc(KeywordLoc) {
|
||||
// NOTE: A co_await expression is dependent on the coroutines promise
|
||||
// type and may be dependent even when the `Op` expression is not.
|
||||
assert(Ty->isDependentType() &&
|
||||
"wrong constructor for non-dependent co_await/co_yield expression");
|
||||
SubExprs[0] = Op;
|
||||
SubExprs[1] = OpCoawait;
|
||||
}
|
||||
|
||||
DependentCoawaitExpr(EmptyShell Empty)
|
||||
: Expr(DependentCoawaitExprClass, Empty) {}
|
||||
|
||||
Expr *getOperand() const { return cast<Expr>(SubExprs[0]); }
|
||||
UnresolvedLookupExpr *getOperatorCoawaitLookup() const {
|
||||
return cast<UnresolvedLookupExpr>(SubExprs[1]);
|
||||
}
|
||||
SourceLocation getKeywordLoc() const { return KeywordLoc; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return getOperand()->getLocEnd();
|
||||
}
|
||||
|
||||
child_range children() { return child_range(SubExprs, SubExprs + 2); }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == DependentCoawaitExprClass;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a 'co_yield' expression.
|
||||
class CoyieldExpr : public CoroutineSuspendExpr {
|
||||
friend class ASTStmtReader;
|
||||
public:
|
||||
CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready,
|
||||
Expr *Suspend, Expr *Resume)
|
||||
Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue)
|
||||
: CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready,
|
||||
Suspend, Resume) {}
|
||||
Suspend, Resume, OpaqueValue) {}
|
||||
CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand)
|
||||
: CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {}
|
||||
CoyieldExpr(EmptyShell Empty)
|
||||
|
@ -0,0 +1,51 @@
|
||||
//===--- ExternalASTMerger.h - Merging External AST Interface ---*- 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 the ExternalASTMerger, which vends a combination of ASTs
|
||||
// from several different ASTContext/FileManager pairs
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_AST_EXTERNALASTMERGER_H
|
||||
#define LLVM_CLANG_AST_EXTERNALASTMERGER_H
|
||||
|
||||
#include "clang/AST/ASTImporter.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ExternalASTMerger : public ExternalASTSource {
|
||||
public:
|
||||
struct ImporterPair {
|
||||
std::unique_ptr<ASTImporter> Forward;
|
||||
std::unique_ptr<ASTImporter> Reverse;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<ImporterPair> Importers;
|
||||
|
||||
public:
|
||||
struct ImporterEndpoint {
|
||||
ASTContext &AST;
|
||||
FileManager &FM;
|
||||
};
|
||||
ExternalASTMerger(const ImporterEndpoint &Target,
|
||||
llvm::ArrayRef<ImporterEndpoint> Sources);
|
||||
|
||||
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
|
||||
DeclarationName Name) override;
|
||||
|
||||
void
|
||||
FindExternalLexicalDecls(const DeclContext *DC,
|
||||
llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
|
||||
SmallVectorImpl<Decl *> &Result) override;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/Basic/Module.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace clang {
|
||||
@ -149,26 +150,30 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
|
||||
StringRef PCHModuleName;
|
||||
StringRef Path;
|
||||
StringRef ASTFile;
|
||||
uint64_t Signature = 0;
|
||||
ASTFileSignature Signature;
|
||||
const Module *ClangModule = nullptr;
|
||||
|
||||
public:
|
||||
ASTSourceDescriptor(){};
|
||||
ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
|
||||
uint64_t Signature)
|
||||
ASTFileSignature Signature)
|
||||
: PCHModuleName(std::move(Name)), Path(std::move(Path)),
|
||||
ASTFile(std::move(ASTFile)), Signature(Signature){};
|
||||
ASTSourceDescriptor(const Module &M);
|
||||
std::string getModuleName() const;
|
||||
StringRef getPath() const { return Path; }
|
||||
StringRef getASTFile() const { return ASTFile; }
|
||||
uint64_t getSignature() const { return Signature; }
|
||||
ASTFileSignature getSignature() const { return Signature; }
|
||||
const Module *getModuleOrNull() const { return ClangModule; }
|
||||
};
|
||||
|
||||
/// Return a descriptor for the corresponding module, if one exists.
|
||||
virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
|
||||
|
||||
enum ExtKind { EK_Always, EK_Never, EK_ReplyHazy };
|
||||
|
||||
virtual ExtKind hasExternalDefinitions(const Decl *D);
|
||||
|
||||
/// \brief Finds all declarations lexically contained within the given
|
||||
/// DeclContext, after applying an optional filter predicate.
|
||||
///
|
||||
|
84
contrib/llvm/tools/clang/include/clang/AST/ODRHash.h
Normal file
84
contrib/llvm/tools/clang/include/clang/AST/ODRHash.h
Normal file
@ -0,0 +1,84 @@
|
||||
//===-- ODRHash.h - Hashing to diagnose ODR failures ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file contains the declaration of the ODRHash class, which calculates
|
||||
/// a hash based on AST nodes, which is stable across different runs.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/AST/TemplateBase.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class Decl;
|
||||
class IdentifierInfo;
|
||||
class NestedNameSpecifer;
|
||||
class Stmt;
|
||||
class TemplateParameterList;
|
||||
|
||||
// ODRHash is used to calculate a hash based on AST node contents that
|
||||
// does not rely on pointer addresses. This allows the hash to not vary
|
||||
// between runs and is usable to detect ODR problems in modules. To use,
|
||||
// construct an ODRHash object, then call Add* methods over the nodes that
|
||||
// need to be hashed. Then call CalculateHash to get the hash value.
|
||||
// Typically, only one Add* call is needed. clear can be called to reuse the
|
||||
// object.
|
||||
class ODRHash {
|
||||
// Use DenseMaps to convert between Decl and Type pointers and an index value.
|
||||
llvm::DenseMap<const Decl*, unsigned> DeclMap;
|
||||
llvm::DenseMap<const Type*, unsigned> TypeMap;
|
||||
|
||||
// Save space by processing bools at the end.
|
||||
llvm::SmallVector<bool, 128> Bools;
|
||||
|
||||
llvm::FoldingSetNodeID ID;
|
||||
|
||||
public:
|
||||
ODRHash() {}
|
||||
|
||||
// Use this for ODR checking classes between modules. This method compares
|
||||
// more information than the AddDecl class.
|
||||
void AddCXXRecordDecl(const CXXRecordDecl *Record);
|
||||
|
||||
// Process SubDecls of the main Decl. This method calls the DeclVisitor
|
||||
// while AddDecl does not.
|
||||
void AddSubDecl(const Decl *D);
|
||||
|
||||
// Reset the object for reuse.
|
||||
void clear();
|
||||
|
||||
// Add booleans to ID and uses it to calculate the hash.
|
||||
unsigned CalculateHash();
|
||||
|
||||
// Add AST nodes that need to be processed.
|
||||
void AddDecl(const Decl *D);
|
||||
void AddType(const Type *T);
|
||||
void AddQualType(QualType T);
|
||||
void AddStmt(const Stmt *S);
|
||||
void AddIdentifierInfo(const IdentifierInfo *II);
|
||||
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS);
|
||||
void AddTemplateName(TemplateName Name);
|
||||
void AddDeclarationName(DeclarationName Name);
|
||||
void AddTemplateArgument(TemplateArgument TA);
|
||||
void AddTemplateParameterList(const TemplateParameterList *TPL);
|
||||
|
||||
// Save booleans until the end to lower the size of data to process.
|
||||
void AddBoolean(bool value);
|
||||
|
||||
static bool isWhitelistedDecl(const Decl* D, const CXXRecordDecl *Record);
|
||||
};
|
||||
|
||||
} // end namespace clang
|
@ -76,10 +76,17 @@ class OMPClauseWithPreInit {
|
||||
friend class OMPClauseReader;
|
||||
/// Pre-initialization statement for the clause.
|
||||
Stmt *PreInit;
|
||||
/// Region that captures the associated stmt.
|
||||
OpenMPDirectiveKind CaptureRegion;
|
||||
|
||||
protected:
|
||||
/// Set pre-initialization statement for the clause.
|
||||
void setPreInitStmt(Stmt *S) { PreInit = S; }
|
||||
OMPClauseWithPreInit(const OMPClause *This) : PreInit(nullptr) {
|
||||
void setPreInitStmt(Stmt *S, OpenMPDirectiveKind ThisRegion = OMPD_unknown) {
|
||||
PreInit = S;
|
||||
CaptureRegion = ThisRegion;
|
||||
}
|
||||
OMPClauseWithPreInit(const OMPClause *This)
|
||||
: PreInit(nullptr), CaptureRegion(OMPD_unknown) {
|
||||
assert(get(This) && "get is not tuned for pre-init.");
|
||||
}
|
||||
|
||||
@ -88,6 +95,8 @@ class OMPClauseWithPreInit {
|
||||
const Stmt *getPreInitStmt() const { return PreInit; }
|
||||
/// Get pre-initialization statement for the clause.
|
||||
Stmt *getPreInitStmt() { return PreInit; }
|
||||
/// Get capture region for the stmt in the clause.
|
||||
OpenMPDirectiveKind getCaptureRegion() { return CaptureRegion; }
|
||||
static OMPClauseWithPreInit *get(OMPClause *C);
|
||||
static const OMPClauseWithPreInit *get(const OMPClause *C);
|
||||
};
|
||||
@ -194,7 +203,7 @@ template <class T> class OMPVarListClause : public OMPClause {
|
||||
/// In this example directive '#pragma omp parallel' has simple 'if' clause with
|
||||
/// condition 'a > 5' and directive name modifier 'parallel'.
|
||||
///
|
||||
class OMPIfClause : public OMPClause {
|
||||
class OMPIfClause : public OMPClause, public OMPClauseWithPreInit {
|
||||
friend class OMPClauseReader;
|
||||
/// \brief Location of '('.
|
||||
SourceLocation LParenLoc;
|
||||
@ -225,26 +234,31 @@ class OMPIfClause : public OMPClause {
|
||||
///
|
||||
/// \param NameModifier [OpenMP 4.1] Directive name modifier of clause.
|
||||
/// \param Cond Condition of the clause.
|
||||
/// \param HelperCond Helper condition for the clause.
|
||||
/// \param CaptureRegion Innermost OpenMP region where expressions in this
|
||||
/// clause must be captured.
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param NameModifierLoc Location of directive name modifier.
|
||||
/// \param ColonLoc [OpenMP 4.1] Location of ':'.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
///
|
||||
OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond,
|
||||
SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation NameModifierLoc, SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
|
||||
Condition(Cond), ColonLoc(ColonLoc), NameModifier(NameModifier),
|
||||
NameModifierLoc(NameModifierLoc) {}
|
||||
OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, Stmt *HelperCond,
|
||||
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation NameModifierLoc,
|
||||
SourceLocation ColonLoc, SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this),
|
||||
LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc),
|
||||
NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) {
|
||||
setPreInitStmt(HelperCond, CaptureRegion);
|
||||
}
|
||||
|
||||
/// \brief Build an empty clause.
|
||||
///
|
||||
OMPIfClause()
|
||||
: OMPClause(OMPC_if, SourceLocation(), SourceLocation()), LParenLoc(),
|
||||
Condition(nullptr), ColonLoc(), NameModifier(OMPD_unknown),
|
||||
NameModifierLoc() {}
|
||||
: OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
|
||||
OMPClauseWithPreInit(this), LParenLoc(), Condition(nullptr), ColonLoc(),
|
||||
NameModifier(OMPD_unknown), NameModifierLoc() {}
|
||||
|
||||
/// \brief Sets the location of '('.
|
||||
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
|
||||
@ -331,7 +345,7 @@ class OMPFinalClause : public OMPClause {
|
||||
/// In this example directive '#pragma omp parallel' has simple 'num_threads'
|
||||
/// clause with number of threads '6'.
|
||||
///
|
||||
class OMPNumThreadsClause : public OMPClause {
|
||||
class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit {
|
||||
friend class OMPClauseReader;
|
||||
/// \brief Location of '('.
|
||||
SourceLocation LParenLoc;
|
||||
@ -346,20 +360,29 @@ class OMPNumThreadsClause : public OMPClause {
|
||||
/// \brief Build 'num_threads' clause with condition \a NumThreads.
|
||||
///
|
||||
/// \param NumThreads Number of threads for the construct.
|
||||
/// \param HelperNumThreads Helper Number of threads for the construct.
|
||||
/// \param CaptureRegion Innermost OpenMP region where expressions in this
|
||||
/// clause must be captured.
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
///
|
||||
OMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_num_threads, StartLoc, EndLoc), LParenLoc(LParenLoc),
|
||||
NumThreads(NumThreads) {}
|
||||
OMPNumThreadsClause(Expr *NumThreads, Stmt *HelperNumThreads,
|
||||
OpenMPDirectiveKind CaptureRegion,
|
||||
SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_num_threads, StartLoc, EndLoc),
|
||||
OMPClauseWithPreInit(this), LParenLoc(LParenLoc),
|
||||
NumThreads(NumThreads) {
|
||||
setPreInitStmt(HelperNumThreads, CaptureRegion);
|
||||
}
|
||||
|
||||
/// \brief Build an empty clause.
|
||||
///
|
||||
OMPNumThreadsClause()
|
||||
: OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
|
||||
LParenLoc(SourceLocation()), NumThreads(nullptr) {}
|
||||
OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
|
||||
NumThreads(nullptr) {}
|
||||
|
||||
/// \brief Sets the location of '('.
|
||||
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
|
||||
@ -3456,7 +3479,7 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
|
||||
/// In this example directive '#pragma omp teams' has clause 'num_teams'
|
||||
/// with single expression 'n'.
|
||||
///
|
||||
class OMPNumTeamsClause : public OMPClause {
|
||||
class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit {
|
||||
friend class OMPClauseReader;
|
||||
/// \brief Location of '('.
|
||||
SourceLocation LParenLoc;
|
||||
@ -3472,20 +3495,27 @@ class OMPNumTeamsClause : public OMPClause {
|
||||
/// \brief Build 'num_teams' clause.
|
||||
///
|
||||
/// \param E Expression associated with this clause.
|
||||
/// \param HelperE Helper Expression associated with this clause.
|
||||
/// \param CaptureRegion Innermost OpenMP region where expressions in this
|
||||
/// clause must be captured.
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
///
|
||||
OMPNumTeamsClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion,
|
||||
SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_num_teams, StartLoc, EndLoc), LParenLoc(LParenLoc),
|
||||
NumTeams(E) {}
|
||||
: OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this),
|
||||
LParenLoc(LParenLoc), NumTeams(E) {
|
||||
setPreInitStmt(HelperE, CaptureRegion);
|
||||
}
|
||||
|
||||
/// \brief Build an empty clause.
|
||||
///
|
||||
OMPNumTeamsClause()
|
||||
: OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()),
|
||||
LParenLoc(SourceLocation()), NumTeams(nullptr) {}
|
||||
: OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()),
|
||||
OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
|
||||
NumTeams(nullptr) {}
|
||||
/// \brief Sets the location of '('.
|
||||
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
|
||||
/// \brief Returns the location of '('.
|
||||
@ -3511,7 +3541,7 @@ class OMPNumTeamsClause : public OMPClause {
|
||||
/// In this example directive '#pragma omp teams' has clause 'thread_limit'
|
||||
/// with single expression 'n'.
|
||||
///
|
||||
class OMPThreadLimitClause : public OMPClause {
|
||||
class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit {
|
||||
friend class OMPClauseReader;
|
||||
/// \brief Location of '('.
|
||||
SourceLocation LParenLoc;
|
||||
@ -3527,20 +3557,28 @@ class OMPThreadLimitClause : public OMPClause {
|
||||
/// \brief Build 'thread_limit' clause.
|
||||
///
|
||||
/// \param E Expression associated with this clause.
|
||||
/// \param HelperE Helper Expression associated with this clause.
|
||||
/// \param CaptureRegion Innermost OpenMP region where expressions in this
|
||||
/// clause must be captured.
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
///
|
||||
OMPThreadLimitClause(Expr *E, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc, SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_thread_limit, StartLoc, EndLoc), LParenLoc(LParenLoc),
|
||||
ThreadLimit(E) {}
|
||||
OMPThreadLimitClause(Expr *E, Stmt *HelperE,
|
||||
OpenMPDirectiveKind CaptureRegion,
|
||||
SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_thread_limit, StartLoc, EndLoc),
|
||||
OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) {
|
||||
setPreInitStmt(HelperE, CaptureRegion);
|
||||
}
|
||||
|
||||
/// \brief Build an empty clause.
|
||||
///
|
||||
OMPThreadLimitClause()
|
||||
: OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()),
|
||||
LParenLoc(SourceLocation()), ThreadLimit(nullptr) {}
|
||||
OMPClauseWithPreInit(this), LParenLoc(SourceLocation()),
|
||||
ThreadLimit(nullptr) {}
|
||||
/// \brief Sets the location of '('.
|
||||
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
|
||||
/// \brief Returns the location of '('.
|
||||
|
@ -774,6 +774,11 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
|
||||
TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
|
||||
break;
|
||||
|
||||
case DeclarationName::CXXDeductionGuideName:
|
||||
TRY_TO(TraverseTemplateName(
|
||||
TemplateName(NameInfo.getName().getCXXDeductionGuideTemplate())));
|
||||
break;
|
||||
|
||||
case DeclarationName::Identifier:
|
||||
case DeclarationName::ObjCZeroArgSelector:
|
||||
case DeclarationName::ObjCOneArgSelector:
|
||||
@ -1008,6 +1013,10 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
|
||||
DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
|
||||
TRY_TO(TraverseTemplateName(T->getTemplateName()));
|
||||
TRY_TO(TraverseType(T->getDeducedType()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_TYPE(RecordType, {})
|
||||
DEF_TRAVERSE_TYPE(EnumType, {})
|
||||
@ -1232,6 +1241,11 @@ DEF_TRAVERSE_TYPELOC(AutoType, {
|
||||
TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
|
||||
TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
|
||||
TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_TYPELOC(RecordType, {})
|
||||
DEF_TRAVERSE_TYPELOC(EnumType, {})
|
||||
DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
|
||||
@ -1932,6 +1946,13 @@ DEF_TRAVERSE_DECL(FunctionDecl, {
|
||||
ReturnValue = TraverseFunctionHelper(D);
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_DECL(CXXDeductionGuideDecl, {
|
||||
// We skip decls_begin/decls_end, which are already covered by
|
||||
// TraverseFunctionHelper().
|
||||
ShouldVisitChildren = false;
|
||||
ReturnValue = TraverseFunctionHelper(D);
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_DECL(CXXMethodDecl, {
|
||||
// We skip decls_begin/decls_end, which are already covered by
|
||||
// TraverseFunctionHelper().
|
||||
@ -2495,6 +2516,12 @@ DEF_TRAVERSE_STMT(CoawaitExpr, {
|
||||
ShouldVisitChildren = false;
|
||||
}
|
||||
})
|
||||
DEF_TRAVERSE_STMT(DependentCoawaitExpr, {
|
||||
if (!getDerived().shouldVisitImplicitCode()) {
|
||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
|
||||
ShouldVisitChildren = false;
|
||||
}
|
||||
})
|
||||
DEF_TRAVERSE_STMT(CoyieldExpr, {
|
||||
if (!getDerived().shouldVisitImplicitCode()) {
|
||||
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
|
||||
@ -2711,6 +2738,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
|
||||
TRY_TO(VisitOMPClauseWithPreInit(C));
|
||||
TRY_TO(TraverseStmt(C->getCondition()));
|
||||
return true;
|
||||
}
|
||||
@ -2724,6 +2752,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
|
||||
template <typename Derived>
|
||||
bool
|
||||
RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
|
||||
TRY_TO(VisitOMPClauseWithPreInit(C));
|
||||
TRY_TO(TraverseStmt(C->getNumThreads()));
|
||||
return true;
|
||||
}
|
||||
@ -2993,6 +3022,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPMapClause(OMPMapClause *C) {
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause(
|
||||
OMPNumTeamsClause *C) {
|
||||
TRY_TO(VisitOMPClauseWithPreInit(C));
|
||||
TRY_TO(TraverseStmt(C->getNumTeams()));
|
||||
return true;
|
||||
}
|
||||
@ -3000,6 +3030,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause(
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause(
|
||||
OMPThreadLimitClause *C) {
|
||||
TRY_TO(VisitOMPClauseWithPreInit(C));
|
||||
TRY_TO(TraverseStmt(C->getThreadLimit()));
|
||||
return true;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ namespace clang {
|
||||
class Expr;
|
||||
class IdentifierInfo;
|
||||
class LabelDecl;
|
||||
class ODRHash;
|
||||
class ParmVarDecl;
|
||||
class PrinterHelper;
|
||||
struct PrintingPolicy;
|
||||
@ -126,13 +127,13 @@ class alignas(void *) Stmt {
|
||||
unsigned : NumStmtBits;
|
||||
|
||||
unsigned ValueKind : 2;
|
||||
unsigned ObjectKind : 2;
|
||||
unsigned ObjectKind : 3;
|
||||
unsigned TypeDependent : 1;
|
||||
unsigned ValueDependent : 1;
|
||||
unsigned InstantiationDependent : 1;
|
||||
unsigned ContainsUnexpandedParameterPack : 1;
|
||||
};
|
||||
enum { NumExprBits = 16 };
|
||||
enum { NumExprBits = 17 };
|
||||
|
||||
class CharacterLiteralBitfields {
|
||||
friend class CharacterLiteral;
|
||||
@ -252,6 +253,14 @@ class alignas(void *) Stmt {
|
||||
unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
|
||||
};
|
||||
|
||||
class CoawaitExprBitfields {
|
||||
friend class CoawaitExpr;
|
||||
|
||||
unsigned : NumExprBits;
|
||||
|
||||
unsigned IsImplicit : 1;
|
||||
};
|
||||
|
||||
union {
|
||||
StmtBitfields StmtBits;
|
||||
CompoundStmtBitfields CompoundStmtBits;
|
||||
@ -268,6 +277,7 @@ class alignas(void *) Stmt {
|
||||
ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
|
||||
InitListExprBitfields InitListExprBits;
|
||||
TypeTraitExprBitfields TypeTraitExprBits;
|
||||
CoawaitExprBitfields CoawaitBits;
|
||||
};
|
||||
|
||||
friend class ASTStmtReader;
|
||||
@ -340,6 +350,8 @@ class alignas(void *) Stmt {
|
||||
|
||||
public:
|
||||
Stmt(StmtClass SC) {
|
||||
static_assert(sizeof(*this) == sizeof(void *),
|
||||
"changing bitfields changed sizeof(Stmt)");
|
||||
static_assert(sizeof(*this) % alignof(void *) == 0,
|
||||
"Insufficient alignment!");
|
||||
StmtBits.sClass = SC;
|
||||
@ -436,6 +448,15 @@ class alignas(void *) Stmt {
|
||||
/// written in the source.
|
||||
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
|
||||
bool Canonical) const;
|
||||
|
||||
/// \brief Calculate a unique representation for a statement that is
|
||||
/// stable across compiler invocations.
|
||||
///
|
||||
/// \param ID profile information will be stored in ID.
|
||||
///
|
||||
/// \param Hash an ODRHash object which will be called where pointers would
|
||||
/// have been used in the Profile function.
|
||||
void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash& Hash) const;
|
||||
};
|
||||
|
||||
/// DeclStmt - Adaptor class for mixing declarations with statements and
|
||||
|
@ -296,7 +296,9 @@ class MSDependentExistsStmt : public Stmt {
|
||||
/// \brief Represents the body of a coroutine. This wraps the normal function
|
||||
/// body and holds the additional semantic context required to set up and tear
|
||||
/// down the coroutine frame.
|
||||
class CoroutineBodyStmt : public Stmt {
|
||||
class CoroutineBodyStmt final
|
||||
: public Stmt,
|
||||
private llvm::TrailingObjects<CoroutineBodyStmt, Stmt *> {
|
||||
enum SubStmt {
|
||||
Body, ///< The body of the coroutine.
|
||||
Promise, ///< The promise statement.
|
||||
@ -307,65 +309,100 @@ class CoroutineBodyStmt : public Stmt {
|
||||
Allocate, ///< Coroutine frame memory allocation.
|
||||
Deallocate, ///< Coroutine frame memory deallocation.
|
||||
ReturnValue, ///< Return value for thunk function.
|
||||
ReturnStmtOnAllocFailure, ///< Return statement if allocation failed.
|
||||
FirstParamMove ///< First offset for move construction of parameter copies.
|
||||
};
|
||||
Stmt *SubStmts[SubStmt::FirstParamMove];
|
||||
unsigned NumParams;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
friend TrailingObjects;
|
||||
|
||||
Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
|
||||
|
||||
Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
|
||||
|
||||
public:
|
||||
CoroutineBodyStmt(Stmt *Body, Stmt *Promise, Stmt *InitSuspend,
|
||||
Stmt *FinalSuspend, Stmt *OnException, Stmt *OnFallthrough,
|
||||
Expr *Allocate, Stmt *Deallocate,
|
||||
Expr *ReturnValue, ArrayRef<Expr *> ParamMoves)
|
||||
: Stmt(CoroutineBodyStmtClass) {
|
||||
SubStmts[CoroutineBodyStmt::Body] = Body;
|
||||
SubStmts[CoroutineBodyStmt::Promise] = Promise;
|
||||
SubStmts[CoroutineBodyStmt::InitSuspend] = InitSuspend;
|
||||
SubStmts[CoroutineBodyStmt::FinalSuspend] = FinalSuspend;
|
||||
SubStmts[CoroutineBodyStmt::OnException] = OnException;
|
||||
SubStmts[CoroutineBodyStmt::OnFallthrough] = OnFallthrough;
|
||||
SubStmts[CoroutineBodyStmt::Allocate] = Allocate;
|
||||
SubStmts[CoroutineBodyStmt::Deallocate] = Deallocate;
|
||||
SubStmts[CoroutineBodyStmt::ReturnValue] = ReturnValue;
|
||||
// FIXME: Tail-allocate space for parameter move expressions and store them.
|
||||
assert(ParamMoves.empty() && "not implemented yet");
|
||||
|
||||
struct CtorArgs {
|
||||
Stmt *Body = nullptr;
|
||||
Stmt *Promise = nullptr;
|
||||
Expr *InitialSuspend = nullptr;
|
||||
Expr *FinalSuspend = nullptr;
|
||||
Stmt *OnException = nullptr;
|
||||
Stmt *OnFallthrough = nullptr;
|
||||
Expr *Allocate = nullptr;
|
||||
Expr *Deallocate = nullptr;
|
||||
Stmt *ReturnValue = nullptr;
|
||||
Stmt *ReturnStmtOnAllocFailure = nullptr;
|
||||
ArrayRef<Stmt *> ParamMoves;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
CoroutineBodyStmt(CtorArgs const& Args);
|
||||
|
||||
public:
|
||||
static CoroutineBodyStmt *Create(const ASTContext &C, CtorArgs const &Args);
|
||||
|
||||
bool hasDependentPromiseType() const {
|
||||
return getPromiseDecl()->getType()->isDependentType();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the body of the coroutine as written. This will be either
|
||||
/// a CompoundStmt or a TryStmt.
|
||||
Stmt *getBody() const {
|
||||
return SubStmts[SubStmt::Body];
|
||||
return getStoredStmts()[SubStmt::Body];
|
||||
}
|
||||
|
||||
Stmt *getPromiseDeclStmt() const { return SubStmts[SubStmt::Promise]; }
|
||||
Stmt *getPromiseDeclStmt() const {
|
||||
return getStoredStmts()[SubStmt::Promise];
|
||||
}
|
||||
VarDecl *getPromiseDecl() const {
|
||||
return cast<VarDecl>(cast<DeclStmt>(getPromiseDeclStmt())->getSingleDecl());
|
||||
}
|
||||
|
||||
Stmt *getInitSuspendStmt() const { return SubStmts[SubStmt::InitSuspend]; }
|
||||
Stmt *getFinalSuspendStmt() const { return SubStmts[SubStmt::FinalSuspend]; }
|
||||
|
||||
Stmt *getExceptionHandler() const { return SubStmts[SubStmt::OnException]; }
|
||||
Stmt *getFallthroughHandler() const {
|
||||
return SubStmts[SubStmt::OnFallthrough];
|
||||
Stmt *getInitSuspendStmt() const {
|
||||
return getStoredStmts()[SubStmt::InitSuspend];
|
||||
}
|
||||
Stmt *getFinalSuspendStmt() const {
|
||||
return getStoredStmts()[SubStmt::FinalSuspend];
|
||||
}
|
||||
|
||||
Expr *getAllocate() const { return cast<Expr>(SubStmts[SubStmt::Allocate]); }
|
||||
Stmt *getDeallocate() const { return SubStmts[SubStmt::Deallocate]; }
|
||||
Stmt *getExceptionHandler() const {
|
||||
return getStoredStmts()[SubStmt::OnException];
|
||||
}
|
||||
Stmt *getFallthroughHandler() const {
|
||||
return getStoredStmts()[SubStmt::OnFallthrough];
|
||||
}
|
||||
|
||||
Expr *getAllocate() const {
|
||||
return cast_or_null<Expr>(getStoredStmts()[SubStmt::Allocate]);
|
||||
}
|
||||
Expr *getDeallocate() const {
|
||||
return cast_or_null<Expr>(getStoredStmts()[SubStmt::Deallocate]);
|
||||
}
|
||||
|
||||
Expr *getReturnValueInit() const {
|
||||
return cast<Expr>(SubStmts[SubStmt::ReturnValue]);
|
||||
return cast_or_null<Expr>(getStoredStmts()[SubStmt::ReturnValue]);
|
||||
}
|
||||
Stmt *getReturnStmtOnAllocFailure() const {
|
||||
return getStoredStmts()[SubStmt::ReturnStmtOnAllocFailure];
|
||||
}
|
||||
ArrayRef<Stmt const *> getParamMoves() const {
|
||||
return {getStoredStmts() + SubStmt::FirstParamMove, NumParams};
|
||||
}
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY {
|
||||
return getBody()->getLocStart();
|
||||
return getBody() ? getBody()->getLocStart()
|
||||
: getPromiseDecl()->getLocStart();
|
||||
}
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return getBody()->getLocEnd();
|
||||
return getBody() ? getBody()->getLocEnd() : getPromiseDecl()->getLocEnd();
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
return child_range(SubStmts, SubStmts + SubStmt::FirstParamMove);
|
||||
return child_range(getStoredStmts(),
|
||||
getStoredStmts() + SubStmt::FirstParamMove + NumParams);
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
@ -390,10 +427,14 @@ class CoreturnStmt : public Stmt {
|
||||
enum SubStmt { Operand, PromiseCall, Count };
|
||||
Stmt *SubStmts[SubStmt::Count];
|
||||
|
||||
bool IsImplicit : 1;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
public:
|
||||
CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall)
|
||||
: Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc) {
|
||||
CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall,
|
||||
bool IsImplicit = false)
|
||||
: Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc),
|
||||
IsImplicit(IsImplicit) {
|
||||
SubStmts[SubStmt::Operand] = Operand;
|
||||
SubStmts[SubStmt::PromiseCall] = PromiseCall;
|
||||
}
|
||||
@ -411,6 +452,9 @@ class CoreturnStmt : public Stmt {
|
||||
return static_cast<Expr*>(SubStmts[PromiseCall]);
|
||||
}
|
||||
|
||||
bool isImplicit() const { return IsImplicit; }
|
||||
void setIsImplicit(bool value = true) { IsImplicit = value; }
|
||||
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return CoreturnLoc; }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY {
|
||||
return getOperand() ? getOperand()->getLocEnd() : getLocStart();
|
||||
|
@ -118,6 +118,8 @@ class StmtIteratorImpl : public StmtIteratorBase,
|
||||
REFERENCE operator->() const { return operator*(); }
|
||||
};
|
||||
|
||||
struct ConstStmtIterator;
|
||||
|
||||
struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
|
||||
explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
|
||||
|
||||
@ -128,6 +130,13 @@ struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
|
||||
|
||||
StmtIterator(const VariableArrayType *t)
|
||||
: StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
|
||||
|
||||
private:
|
||||
StmtIterator(const StmtIteratorBase &RHS)
|
||||
: StmtIteratorImpl<StmtIterator, Stmt *&>(RHS) {}
|
||||
|
||||
inline friend StmtIterator
|
||||
cast_away_const(const ConstStmtIterator &RHS);
|
||||
};
|
||||
|
||||
struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
|
||||
@ -137,8 +146,15 @@ struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
|
||||
|
||||
ConstStmtIterator(const StmtIterator& RHS) :
|
||||
StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
|
||||
|
||||
ConstStmtIterator(Stmt * const *S)
|
||||
: StmtIteratorImpl<ConstStmtIterator, const Stmt *>(
|
||||
const_cast<Stmt **>(S)) {}
|
||||
};
|
||||
|
||||
inline StmtIterator cast_away_const(const ConstStmtIterator &RHS) {
|
||||
return RHS;
|
||||
}
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -198,6 +198,26 @@ class OMPExecutableDirective : public Stmt {
|
||||
return const_cast<Stmt *>(*child_begin());
|
||||
}
|
||||
|
||||
/// \brief Returns the captured statement associated with the
|
||||
/// component region within the (combined) directive.
|
||||
//
|
||||
// \param RegionKind Component region kind.
|
||||
CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
|
||||
SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
|
||||
getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
|
||||
assert(std::any_of(
|
||||
CaptureRegions.begin(), CaptureRegions.end(),
|
||||
[=](const OpenMPDirectiveKind K) { return K == RegionKind; }) &&
|
||||
"RegionKind not found in OpenMP CaptureRegions.");
|
||||
auto *CS = cast<CapturedStmt>(getAssociatedStmt());
|
||||
for (auto ThisCaptureRegion : CaptureRegions) {
|
||||
if (ThisCaptureRegion == RegionKind)
|
||||
return CS;
|
||||
CS = cast<CapturedStmt>(CS->getCapturedStmt());
|
||||
}
|
||||
llvm_unreachable("Incorrect RegionKind specified for directive.");
|
||||
}
|
||||
|
||||
OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
|
||||
|
||||
static bool classof(const Stmt *S) {
|
||||
@ -304,6 +324,11 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
||||
/// allocated: loop counters, their updates and final values.
|
||||
/// PrevLowerBound and PrevUpperBound are used to communicate blocking
|
||||
/// information in composite constructs which require loop blocking
|
||||
/// DistInc is used to generate the increment expression for the distribute
|
||||
/// loop when combined with a further nested loop
|
||||
/// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
|
||||
/// for loop when combined with a previous distribute loop in the same pragma
|
||||
/// (e.g. 'distribute parallel for')
|
||||
///
|
||||
enum {
|
||||
AssociatedStmtOffset = 0,
|
||||
@ -319,7 +344,7 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
||||
// specify the offset to the end (and start of the following counters/
|
||||
// updates/finals arrays).
|
||||
DefaultEnd = 9,
|
||||
// The following 7 exprs are used by worksharing loops only.
|
||||
// The following 12 exprs are used by worksharing and distribute loops only.
|
||||
IsLastIterVariableOffset = 9,
|
||||
LowerBoundVariableOffset = 10,
|
||||
UpperBoundVariableOffset = 11,
|
||||
@ -330,9 +355,11 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
||||
NumIterationsOffset = 16,
|
||||
PrevLowerBoundVariableOffset = 17,
|
||||
PrevUpperBoundVariableOffset = 18,
|
||||
DistIncOffset = 19,
|
||||
PrevEnsureUpperBoundOffset = 20,
|
||||
// Offset to the end (and start of the following counters/updates/finals
|
||||
// arrays) for worksharing loop directives.
|
||||
WorksharingEnd = 19,
|
||||
WorksharingEnd = 21,
|
||||
};
|
||||
|
||||
/// \brief Get the counters storage.
|
||||
@ -501,6 +528,20 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
||||
"expected worksharing loop directive");
|
||||
*std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
|
||||
}
|
||||
void setDistInc(Expr *DistInc) {
|
||||
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
||||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
||||
isOpenMPDistributeDirective(getDirectiveKind())) &&
|
||||
"expected worksharing loop directive");
|
||||
*std::next(child_begin(), DistIncOffset) = DistInc;
|
||||
}
|
||||
void setPrevEnsureUpperBound(Expr *PrevEUB) {
|
||||
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
||||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
||||
isOpenMPDistributeDirective(getDirectiveKind())) &&
|
||||
"expected worksharing loop directive");
|
||||
*std::next(child_begin(), PrevEnsureUpperBoundOffset) = PrevEUB;
|
||||
}
|
||||
void setCounters(ArrayRef<Expr *> A);
|
||||
void setPrivateCounters(ArrayRef<Expr *> A);
|
||||
void setInits(ArrayRef<Expr *> A);
|
||||
@ -535,7 +576,7 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
||||
Expr *UB;
|
||||
/// \brief Stride - local variable passed to runtime.
|
||||
Expr *ST;
|
||||
/// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
|
||||
/// \brief EnsureUpperBound -- expression UB = min(UB, NumIterations).
|
||||
Expr *EUB;
|
||||
/// \brief Update of LowerBound for statically sheduled 'omp for' loops.
|
||||
Expr *NLB;
|
||||
@ -547,6 +588,16 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
||||
/// \brief PreviousUpperBound - local variable passed to runtime in the
|
||||
/// enclosing schedule or null if that does not apply.
|
||||
Expr *PrevUB;
|
||||
/// \brief DistInc - increment expression for distribute loop when found
|
||||
/// combined with a further loop level (e.g. in 'distribute parallel for')
|
||||
/// expression IV = IV + ST
|
||||
Expr *DistInc;
|
||||
/// \brief PrevEUB - expression similar to EUB but to be used when loop
|
||||
/// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for'
|
||||
/// when ensuring that the UB is either the calculated UB by the runtime or
|
||||
/// the end of the assigned distribute chunk)
|
||||
/// expression UB = min (UB, PrevUB)
|
||||
Expr *PrevEUB;
|
||||
/// \brief Counters Loop counters.
|
||||
SmallVector<Expr *, 4> Counters;
|
||||
/// \brief PrivateCounters Loop counters.
|
||||
@ -588,6 +639,8 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
||||
NumIterations = nullptr;
|
||||
PrevLB = nullptr;
|
||||
PrevUB = nullptr;
|
||||
DistInc = nullptr;
|
||||
PrevEUB = nullptr;
|
||||
Counters.resize(Size);
|
||||
PrivateCounters.resize(Size);
|
||||
Inits.resize(Size);
|
||||
@ -719,6 +772,22 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
||||
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
||||
*std::next(child_begin(), PrevUpperBoundVariableOffset)));
|
||||
}
|
||||
Expr *getDistInc() const {
|
||||
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
||||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
||||
isOpenMPDistributeDirective(getDirectiveKind())) &&
|
||||
"expected worksharing loop directive");
|
||||
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
||||
*std::next(child_begin(), DistIncOffset)));
|
||||
}
|
||||
Expr *getPrevEnsureUpperBound() const {
|
||||
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
||||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
||||
isOpenMPDistributeDirective(getDirectiveKind())) &&
|
||||
"expected worksharing loop directive");
|
||||
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
||||
*std::next(child_begin(), PrevEnsureUpperBoundOffset)));
|
||||
}
|
||||
const Stmt *getBody() const {
|
||||
// This relies on the loop form is already checked by Sema.
|
||||
Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
|
||||
|
@ -119,10 +119,7 @@ class TemplateArgument {
|
||||
|
||||
public:
|
||||
/// \brief Construct an empty, invalid template argument.
|
||||
TemplateArgument() {
|
||||
TypeOrValue.Kind = Null;
|
||||
TypeOrValue.V = 0;
|
||||
}
|
||||
constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
|
||||
|
||||
/// \brief Construct a template type argument.
|
||||
TemplateArgument(QualType T, bool isNullPtr = false) {
|
||||
@ -388,8 +385,8 @@ struct TemplateArgumentLocInfo {
|
||||
};
|
||||
|
||||
public:
|
||||
TemplateArgumentLocInfo();
|
||||
|
||||
constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {}
|
||||
|
||||
TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
|
||||
|
||||
TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
|
||||
@ -433,7 +430,7 @@ class TemplateArgumentLoc {
|
||||
TemplateArgumentLocInfo LocInfo;
|
||||
|
||||
public:
|
||||
TemplateArgumentLoc() {}
|
||||
constexpr TemplateArgumentLoc() {}
|
||||
|
||||
TemplateArgumentLoc(const TemplateArgument &Argument,
|
||||
TemplateArgumentLocInfo Opaque)
|
||||
@ -578,6 +575,7 @@ struct ASTTemplateArgumentListInfo final
|
||||
TemplateArgumentLoc> {
|
||||
private:
|
||||
friend TrailingObjects;
|
||||
friend class ASTNodeImporter;
|
||||
|
||||
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
|
||||
|
||||
|
@ -333,6 +333,20 @@ class Qualifiers {
|
||||
|
||||
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
|
||||
unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
|
||||
/// Get the address space attribute value to be printed by diagnostics.
|
||||
unsigned getAddressSpaceAttributePrintValue() const {
|
||||
auto Addr = getAddressSpace();
|
||||
// This function is not supposed to be used with language specific
|
||||
// address spaces. If that happens, the diagnostic message should consider
|
||||
// printing the QualType instead of the address space value.
|
||||
assert(Addr == 0 || Addr >= LangAS::Count);
|
||||
if (Addr)
|
||||
return Addr - LangAS::Count;
|
||||
// TODO: The diagnostic messages where Addr may be 0 should be fixed
|
||||
// since it cannot differentiate the situation where 0 denotes the default
|
||||
// address space or user specified __attribute__((address_space(0))).
|
||||
return 0;
|
||||
}
|
||||
void setAddressSpace(unsigned space) {
|
||||
assert(space <= MaxAddressSpace);
|
||||
Mask = (Mask & ~AddressSpaceMask)
|
||||
@ -1020,6 +1034,9 @@ class QualType {
|
||||
return getQualifiers().hasStrongOrWeakObjCLifetime();
|
||||
}
|
||||
|
||||
// true when Type is objc's weak and weak is enabled but ARC isn't.
|
||||
bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const;
|
||||
|
||||
enum DestructionKind {
|
||||
DK_none,
|
||||
DK_cxx_destructor,
|
||||
@ -1744,7 +1761,6 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
bool isEventT() const; // OpenCL event_t
|
||||
bool isClkEventT() const; // OpenCL clk_event_t
|
||||
bool isQueueT() const; // OpenCL queue_t
|
||||
bool isNDRangeT() const; // OpenCL ndrange_t
|
||||
bool isReserveIDT() const; // OpenCL reserve_id_t
|
||||
|
||||
bool isPipeType() const; // OpenCL pipe type
|
||||
@ -1785,7 +1801,8 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
}
|
||||
|
||||
/// \brief Determine whether this type is an undeduced type, meaning that
|
||||
/// it somehow involves a C++11 'auto' type which has not yet been deduced.
|
||||
/// it somehow involves a C++11 'auto' type or similar which has not yet been
|
||||
/// deduced.
|
||||
bool isUndeducedType() const;
|
||||
|
||||
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
|
||||
@ -1862,10 +1879,22 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
/// not refer to a CXXRecordDecl, returns NULL.
|
||||
const CXXRecordDecl *getPointeeCXXRecordDecl() const;
|
||||
|
||||
/// Get the DeducedType whose type will be deduced for a variable with
|
||||
/// an initializer of this type. This looks through declarators like pointer
|
||||
/// types, but not through decltype or typedefs.
|
||||
DeducedType *getContainedDeducedType() const;
|
||||
|
||||
/// Get the AutoType whose type will be deduced for a variable with
|
||||
/// an initializer of this type. This looks through declarators like pointer
|
||||
/// types, but not through decltype or typedefs.
|
||||
AutoType *getContainedAutoType() const;
|
||||
AutoType *getContainedAutoType() const {
|
||||
return dyn_cast_or_null<AutoType>(getContainedDeducedType());
|
||||
}
|
||||
|
||||
/// Determine whether this type was written with a leading 'auto'
|
||||
/// corresponding to a trailing return type (possibly for a nested
|
||||
/// function type within a pointer to function type or similar).
|
||||
bool hasAutoForTrailingReturnType() const;
|
||||
|
||||
/// Member-template getAs<specific type>'. Look through sugar for
|
||||
/// an instance of \<specific type>. This scheme will eventually
|
||||
@ -1875,6 +1904,13 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
/// immediately following this class.
|
||||
template <typename T> const T *getAs() const;
|
||||
|
||||
/// Member-template getAsAdjusted<specific type>. Look through specific kinds
|
||||
/// of sugar (parens, attributes, etc) for an instance of \<specific type>.
|
||||
/// This is used when you need to walk over sugar nodes that represent some
|
||||
/// kind of type adjustment from a type that was written as a \<specific type>
|
||||
/// to another type that is still canonically a \<specific type>.
|
||||
template <typename T> const T *getAsAdjusted() const;
|
||||
|
||||
/// A variant of getAs<> for array types which silently discards
|
||||
/// qualifiers from the outermost type.
|
||||
const ArrayType *getAsArrayTypeUnsafe() const;
|
||||
@ -2057,7 +2093,7 @@ class BuiltinType : public Type {
|
||||
: Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
|
||||
/*InstantiationDependent=*/(K == Dependent),
|
||||
/*VariablyModified=*/false,
|
||||
/*Unexpanded paramter pack=*/false) {
|
||||
/*Unexpanded parameter pack=*/false) {
|
||||
BuiltinTypeBits.Kind = K;
|
||||
}
|
||||
|
||||
@ -3097,9 +3133,11 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
class ExtParameterInfo {
|
||||
enum {
|
||||
ABIMask = 0x0F,
|
||||
IsConsumed = 0x10
|
||||
IsConsumed = 0x10,
|
||||
HasPassObjSize = 0x20,
|
||||
};
|
||||
unsigned char Data;
|
||||
|
||||
public:
|
||||
ExtParameterInfo() : Data(0) {}
|
||||
|
||||
@ -3128,6 +3166,15 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool hasPassObjectSize() const {
|
||||
return Data & HasPassObjSize;
|
||||
}
|
||||
ExtParameterInfo withHasPassObjectSize() const {
|
||||
ExtParameterInfo Copy = *this;
|
||||
Copy.Data |= HasPassObjSize;
|
||||
return Copy;
|
||||
}
|
||||
|
||||
unsigned char getOpaqueValue() const { return Data; }
|
||||
static ExtParameterInfo getFromOpaqueValue(unsigned char data) {
|
||||
ExtParameterInfo result;
|
||||
@ -4089,25 +4136,60 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
|
||||
/// \brief Common base class for placeholders for types that get replaced by
|
||||
/// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced
|
||||
/// class template types, and (eventually) constrained type names from the C++
|
||||
/// Concepts TS.
|
||||
///
|
||||
/// These types are usually a placeholder for a deduced type. However, before
|
||||
/// the initializer is attached, or (usually) if the initializer is
|
||||
/// type-dependent, there is no deduced type and an auto type is canonical. In
|
||||
/// type-dependent, there is no deduced type and the type is canonical. In
|
||||
/// the latter case, it is also a dependent type.
|
||||
class AutoType : public Type, public llvm::FoldingSetNode {
|
||||
AutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent)
|
||||
: Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
|
||||
/*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
|
||||
/*VariablyModified=*/false, /*ContainsParameterPack=*/false) {
|
||||
if (!DeducedType.isNull()) {
|
||||
if (DeducedType->isDependentType())
|
||||
class DeducedType : public Type {
|
||||
protected:
|
||||
DeducedType(TypeClass TC, QualType DeducedAsType, bool IsDependent,
|
||||
bool IsInstantiationDependent, bool ContainsParameterPack)
|
||||
: Type(TC,
|
||||
// FIXME: Retain the sugared deduced type?
|
||||
DeducedAsType.isNull() ? QualType(this, 0)
|
||||
: DeducedAsType.getCanonicalType(),
|
||||
IsDependent, IsInstantiationDependent,
|
||||
/*VariablyModified=*/false, ContainsParameterPack) {
|
||||
if (!DeducedAsType.isNull()) {
|
||||
if (DeducedAsType->isDependentType())
|
||||
setDependent();
|
||||
if (DeducedType->isInstantiationDependentType())
|
||||
if (DeducedAsType->isInstantiationDependentType())
|
||||
setInstantiationDependent();
|
||||
if (DeducedType->containsUnexpandedParameterPack())
|
||||
if (DeducedAsType->containsUnexpandedParameterPack())
|
||||
setContainsUnexpandedParameterPack();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
bool isSugared() const { return !isCanonicalUnqualified(); }
|
||||
QualType desugar() const { return getCanonicalTypeInternal(); }
|
||||
|
||||
/// \brief Get the type deduced for this placeholder type, or null if it's
|
||||
/// either not been deduced or was deduced to a dependent type.
|
||||
QualType getDeducedType() const {
|
||||
return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
|
||||
}
|
||||
bool isDeduced() const {
|
||||
return !isCanonicalUnqualified() || isDependentType();
|
||||
}
|
||||
|
||||
static bool classof(const Type *T) {
|
||||
return T->getTypeClass() == Auto ||
|
||||
T->getTypeClass() == DeducedTemplateSpecialization;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
|
||||
class AutoType : public DeducedType, public llvm::FoldingSetNode {
|
||||
AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
|
||||
bool IsDeducedAsDependent)
|
||||
: DeducedType(Auto, DeducedAsType, IsDeducedAsDependent,
|
||||
IsDeducedAsDependent, /*ContainsPack=*/false) {
|
||||
AutoTypeBits.Keyword = (unsigned)Keyword;
|
||||
}
|
||||
|
||||
@ -4121,18 +4203,6 @@ class AutoType : public Type, public llvm::FoldingSetNode {
|
||||
return (AutoTypeKeyword)AutoTypeBits.Keyword;
|
||||
}
|
||||
|
||||
bool isSugared() const { return !isCanonicalUnqualified(); }
|
||||
QualType desugar() const { return getCanonicalTypeInternal(); }
|
||||
|
||||
/// \brief Get the type deduced for this auto type, or null if it's either
|
||||
/// not been deduced or was deduced to a dependent type.
|
||||
QualType getDeducedType() const {
|
||||
return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
|
||||
}
|
||||
bool isDeduced() const {
|
||||
return !isCanonicalUnqualified() || isDependentType();
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, getDeducedType(), getKeyword(), isDependentType());
|
||||
}
|
||||
@ -4149,6 +4219,43 @@ class AutoType : public Type, public llvm::FoldingSetNode {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a C++17 deduced template specialization type.
|
||||
class DeducedTemplateSpecializationType : public DeducedType,
|
||||
public llvm::FoldingSetNode {
|
||||
/// The name of the template whose arguments will be deduced.
|
||||
TemplateName Template;
|
||||
|
||||
DeducedTemplateSpecializationType(TemplateName Template,
|
||||
QualType DeducedAsType,
|
||||
bool IsDeducedAsDependent)
|
||||
: DeducedType(DeducedTemplateSpecialization, DeducedAsType,
|
||||
IsDeducedAsDependent || Template.isDependent(),
|
||||
IsDeducedAsDependent || Template.isInstantiationDependent(),
|
||||
Template.containsUnexpandedParameterPack()),
|
||||
Template(Template) {}
|
||||
|
||||
friend class ASTContext; // ASTContext creates these
|
||||
|
||||
public:
|
||||
/// Retrieve the name of the template that we are deducing.
|
||||
TemplateName getTemplateName() const { return Template;}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, getTemplateName(), getDeducedType(), isDependentType());
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
|
||||
QualType Deduced, bool IsDependent) {
|
||||
Template.Profile(ID);
|
||||
ID.AddPointer(Deduced.getAsOpaquePtr());
|
||||
ID.AddBoolean(IsDependent);
|
||||
}
|
||||
|
||||
static bool classof(const Type *T) {
|
||||
return T->getTypeClass() == DeducedTemplateSpecialization;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents a type template specialization; the template
|
||||
/// must be a class template, a type alias template, or a template
|
||||
/// template parameter. A template which cannot be resolved to one of
|
||||
@ -4345,6 +4452,9 @@ class InjectedClassNameType : public Type {
|
||||
const TemplateSpecializationType *getInjectedTST() const {
|
||||
return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
|
||||
}
|
||||
TemplateName getTemplateName() const {
|
||||
return getInjectedTST()->getTemplateName();
|
||||
}
|
||||
|
||||
CXXRecordDecl *getDecl() const;
|
||||
|
||||
@ -5718,10 +5828,6 @@ inline bool Type::isQueueT() const {
|
||||
return isSpecificBuiltinType(BuiltinType::OCLQueue);
|
||||
}
|
||||
|
||||
inline bool Type::isNDRangeT() const {
|
||||
return isSpecificBuiltinType(BuiltinType::OCLNDRange);
|
||||
}
|
||||
|
||||
inline bool Type::isReserveIDT() const {
|
||||
return isSpecificBuiltinType(BuiltinType::OCLReserveID);
|
||||
}
|
||||
@ -5739,7 +5845,7 @@ inline bool Type::isPipeType() const {
|
||||
|
||||
inline bool Type::isOpenCLSpecificType() const {
|
||||
return isSamplerT() || isEventT() || isImageType() || isClkEventT() ||
|
||||
isQueueT() || isNDRangeT() || isReserveIDT() || isPipeType();
|
||||
isQueueT() || isReserveIDT() || isPipeType();
|
||||
}
|
||||
|
||||
inline bool Type::isTemplateTypeParmType() const {
|
||||
@ -5849,8 +5955,8 @@ inline bool Type::isBooleanType() const {
|
||||
}
|
||||
|
||||
inline bool Type::isUndeducedType() const {
|
||||
const AutoType *AT = getContainedAutoType();
|
||||
return AT && !AT->isDeduced();
|
||||
auto *DT = getContainedDeducedType();
|
||||
return DT && !DT->isDeduced();
|
||||
}
|
||||
|
||||
/// \brief Determines whether this is a type for which one can define
|
||||
@ -5932,6 +6038,38 @@ template <typename T> const T *Type::getAs() const {
|
||||
return cast<T>(getUnqualifiedDesugaredType());
|
||||
}
|
||||
|
||||
template <typename T> const T *Type::getAsAdjusted() const {
|
||||
static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!");
|
||||
|
||||
// If this is directly a T type, return it.
|
||||
if (const T *Ty = dyn_cast<T>(this))
|
||||
return Ty;
|
||||
|
||||
// If the canonical form of this type isn't the right kind, reject it.
|
||||
if (!isa<T>(CanonicalType))
|
||||
return nullptr;
|
||||
|
||||
// Strip off type adjustments that do not modify the underlying nature of the
|
||||
// type.
|
||||
const Type *Ty = this;
|
||||
while (Ty) {
|
||||
if (const auto *A = dyn_cast<AttributedType>(Ty))
|
||||
Ty = A->getModifiedType().getTypePtr();
|
||||
else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
|
||||
Ty = E->desugar().getTypePtr();
|
||||
else if (const auto *P = dyn_cast<ParenType>(Ty))
|
||||
Ty = P->desugar().getTypePtr();
|
||||
else if (const auto *A = dyn_cast<AdjustedType>(Ty))
|
||||
Ty = A->desugar().getTypePtr();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Just because the canonical type is correct does not mean we can use cast<>,
|
||||
// since we may not have stripped off all the sugar down to the base type.
|
||||
return dyn_cast<T>(Ty);
|
||||
}
|
||||
|
||||
inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
|
||||
// If this is directly an array type, return it.
|
||||
if (const ArrayType *arr = dyn_cast<ArrayType>(this))
|
||||
|
@ -70,6 +70,13 @@ class TypeLoc {
|
||||
return t;
|
||||
}
|
||||
|
||||
/// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
|
||||
/// this TypeLock is not of the desired type. It will consider type
|
||||
/// adjustments from a type that wad written as a T to another type that is
|
||||
/// still canonically a T (ignores parens, attributes, elaborated types, etc).
|
||||
template <typename T>
|
||||
T getAsAdjusted() const;
|
||||
|
||||
/// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
|
||||
/// except it also defines a Qualified enum that corresponds to the
|
||||
/// QualifiedLoc class.
|
||||
@ -1827,9 +1834,25 @@ class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
|
||||
}
|
||||
};
|
||||
|
||||
class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
|
||||
AutoTypeLoc,
|
||||
AutoType> {
|
||||
class DeducedTypeLoc
|
||||
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
|
||||
DeducedType> {};
|
||||
|
||||
class AutoTypeLoc
|
||||
: public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, AutoType> {
|
||||
};
|
||||
|
||||
class DeducedTemplateSpecializationTypeLoc
|
||||
: public InheritingConcreteTypeLoc<DeducedTypeLoc,
|
||||
DeducedTemplateSpecializationTypeLoc,
|
||||
DeducedTemplateSpecializationType> {
|
||||
public:
|
||||
SourceLocation getTemplateNameLoc() const {
|
||||
return getNameLoc();
|
||||
}
|
||||
void setTemplateNameLoc(SourceLocation Loc) {
|
||||
setNameLoc(Loc);
|
||||
}
|
||||
};
|
||||
|
||||
struct ElaboratedLocInfo {
|
||||
@ -2172,6 +2195,24 @@ class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
|
||||
|
||||
QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline T TypeLoc::getAsAdjusted() const {
|
||||
TypeLoc Cur = *this;
|
||||
while (!T::isKind(Cur)) {
|
||||
if (auto PTL = Cur.getAs<ParenTypeLoc>())
|
||||
Cur = PTL.getInnerLoc();
|
||||
else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
|
||||
Cur = ATL.getModifiedLoc();
|
||||
else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
|
||||
Cur = ETL.getNamedTypeLoc();
|
||||
else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
|
||||
Cur = ATL.getOriginalLoc();
|
||||
else
|
||||
break;
|
||||
}
|
||||
return Cur.getAs<T>();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -96,7 +96,9 @@ DEPENDENT_TYPE(TemplateTypeParm, Type)
|
||||
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
|
||||
DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)
|
||||
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
|
||||
TYPE(Auto, Type)
|
||||
ABSTRACT_TYPE(Deduced, Type)
|
||||
TYPE(Auto, DeducedType)
|
||||
TYPE(DeducedTemplateSpecialization, DeducedType)
|
||||
DEPENDENT_TYPE(InjectedClassName, Type)
|
||||
DEPENDENT_TYPE(DependentName, Type)
|
||||
DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
|
||||
|
@ -26,7 +26,7 @@
|
||||
namespace clang {
|
||||
|
||||
/// \brief Function object that provides a total ordering on QualType values.
|
||||
struct QualTypeOrdering : std::binary_function<QualType, QualType, bool> {
|
||||
struct QualTypeOrdering {
|
||||
bool operator()(QualType T1, QualType T2) const {
|
||||
return std::less<void*>()(T1.getAsOpaquePtr(), T2.getAsOpaquePtr());
|
||||
}
|
||||
|
@ -180,6 +180,16 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
|
||||
/// matches "using Y = int", but not "typedef int X"
|
||||
const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
|
||||
|
||||
/// \brief Matches type alias template declarations.
|
||||
///
|
||||
/// typeAliasTemplateDecl() matches
|
||||
/// \code
|
||||
/// template <typename T>
|
||||
/// using Y = X<T>;
|
||||
/// \endcode
|
||||
const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
|
||||
typeAliasTemplateDecl;
|
||||
|
||||
/// \brief Matches AST nodes that were expanded within the main-file.
|
||||
///
|
||||
/// Example matches X but not Y
|
||||
@ -1118,6 +1128,69 @@ const internal::VariadicDynCastAllOfMatcher<
|
||||
Decl,
|
||||
ObjCInterfaceDecl> objcInterfaceDecl;
|
||||
|
||||
/// \brief Matches Objective-C protocol declarations.
|
||||
///
|
||||
/// Example matches FooDelegate
|
||||
/// \code
|
||||
/// @protocol FooDelegate
|
||||
/// @end
|
||||
/// \endcode
|
||||
const internal::VariadicDynCastAllOfMatcher<
|
||||
Decl,
|
||||
ObjCProtocolDecl> objcProtocolDecl;
|
||||
|
||||
/// \brief Matches Objective-C category declarations.
|
||||
///
|
||||
/// Example matches Foo (Additions)
|
||||
/// \code
|
||||
/// @interface Foo (Additions)
|
||||
/// @end
|
||||
/// \endcode
|
||||
const internal::VariadicDynCastAllOfMatcher<
|
||||
Decl,
|
||||
ObjCCategoryDecl> objcCategoryDecl;
|
||||
|
||||
/// \brief Matches Objective-C method declarations.
|
||||
///
|
||||
/// Example matches both declaration and definition of -[Foo method]
|
||||
/// \code
|
||||
/// @interface Foo
|
||||
/// - (void)method;
|
||||
/// @end
|
||||
///
|
||||
/// @implementation Foo
|
||||
/// - (void)method {}
|
||||
/// @end
|
||||
/// \endcode
|
||||
const internal::VariadicDynCastAllOfMatcher<
|
||||
Decl,
|
||||
ObjCMethodDecl> objcMethodDecl;
|
||||
|
||||
/// \brief Matches Objective-C instance variable declarations.
|
||||
///
|
||||
/// Example matches _enabled
|
||||
/// \code
|
||||
/// @implementation Foo {
|
||||
/// BOOL _enabled;
|
||||
/// }
|
||||
/// @end
|
||||
/// \endcode
|
||||
const internal::VariadicDynCastAllOfMatcher<
|
||||
Decl,
|
||||
ObjCIvarDecl> objcIvarDecl;
|
||||
|
||||
/// \brief Matches Objective-C property declarations.
|
||||
///
|
||||
/// Example matches enabled
|
||||
/// \code
|
||||
/// @interface Foo
|
||||
/// @property BOOL enabled;
|
||||
/// @end
|
||||
/// \endcode
|
||||
const internal::VariadicDynCastAllOfMatcher<
|
||||
Decl,
|
||||
ObjCPropertyDecl> objcPropertyDecl;
|
||||
|
||||
/// \brief Matches expressions that introduce cleanups to be run at the end
|
||||
/// of the sub-expression's evaluation.
|
||||
///
|
||||
@ -2522,7 +2595,7 @@ AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
|
||||
/// \brief Matches on the receiver of an ObjectiveC Message expression.
|
||||
///
|
||||
/// Example
|
||||
/// matcher = objCMessageExpr(hasRecieverType(asString("UIWebView *")));
|
||||
/// matcher = objCMessageExpr(hasReceiverType(asString("UIWebView *")));
|
||||
/// matches the [webView ...] message invocation.
|
||||
/// \code
|
||||
/// NSString *webViewJavaScript = ...
|
||||
@ -5507,7 +5580,7 @@ AST_MATCHER_FUNCTION(internal::Matcher<Expr>, nullPointerConstant) {
|
||||
integerLiteral(equals(0), hasParent(expr(hasType(pointerType())))));
|
||||
}
|
||||
|
||||
/// \brief Matches declaration of the function the statemenet belongs to
|
||||
/// \brief Matches declaration of the function the statement belongs to
|
||||
///
|
||||
/// Given:
|
||||
/// \code
|
||||
|
@ -56,7 +56,7 @@ class ArgKind {
|
||||
/// \param To the requested destination type.
|
||||
///
|
||||
/// \param Specificity value corresponding to the "specificity" of the
|
||||
/// convertion.
|
||||
/// conversion.
|
||||
bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
|
||||
|
||||
bool operator<(const ArgKind &Other) const {
|
||||
@ -182,7 +182,7 @@ class VariantMatcher {
|
||||
/// \param Kind the requested destination type.
|
||||
///
|
||||
/// \param Specificity value corresponding to the "specificity" of the
|
||||
/// convertion.
|
||||
/// conversion.
|
||||
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
|
||||
unsigned *Specificity) const {
|
||||
if (Value)
|
||||
@ -281,7 +281,7 @@ class VariantValue {
|
||||
/// \param Kind the requested destination type.
|
||||
///
|
||||
/// \param Specificity value corresponding to the "specificity" of the
|
||||
/// convertion.
|
||||
/// conversion.
|
||||
bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
|
||||
|
||||
/// \brief Determines if the contained value can be converted to any kind
|
||||
@ -290,7 +290,7 @@ class VariantValue {
|
||||
/// \param Kinds the requested destination types.
|
||||
///
|
||||
/// \param Specificity value corresponding to the "specificity" of the
|
||||
/// convertion. It is the maximum specificity of all the possible
|
||||
/// conversion. It is the maximum specificity of all the possible
|
||||
/// conversions.
|
||||
bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
|
||||
|
||||
|
@ -98,7 +98,7 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
|
||||
bool VisitFunctionDecl(FunctionDecl *FD) {
|
||||
// We skip function template definitions, as their semantics is
|
||||
// only determined when they are instantiated.
|
||||
if (includeInGraph(FD)) {
|
||||
if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) {
|
||||
// Add all blocks declared inside this function to the graph.
|
||||
addNodesForBlocks(FD);
|
||||
// If this function has external linkage, anything could call it.
|
||||
|
@ -16,9 +16,7 @@
|
||||
#define LLVM_CLANG_AST_CLONEDETECTION_H
|
||||
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
@ -29,7 +27,7 @@ class VarDecl;
|
||||
class ASTContext;
|
||||
class CompoundStmt;
|
||||
|
||||
/// \brief Identifies a list of statements.
|
||||
/// Identifies a list of statements.
|
||||
///
|
||||
/// Can either identify a single arbitrary Stmt object, a continuous sequence of
|
||||
/// child statements inside a CompoundStmt or no statements at all.
|
||||
@ -39,8 +37,8 @@ class StmtSequence {
|
||||
/// Stmt, then S is a pointer to this Stmt.
|
||||
const Stmt *S;
|
||||
|
||||
/// The related ASTContext for S.
|
||||
ASTContext *Context;
|
||||
/// The declaration that contains the statements.
|
||||
const Decl *D;
|
||||
|
||||
/// If EndIndex is non-zero, then S is a CompoundStmt and this StmtSequence
|
||||
/// instance is representing the CompoundStmt children inside the array
|
||||
@ -49,7 +47,7 @@ class StmtSequence {
|
||||
unsigned EndIndex;
|
||||
|
||||
public:
|
||||
/// \brief Constructs a StmtSequence holding multiple statements.
|
||||
/// Constructs a StmtSequence holding multiple statements.
|
||||
///
|
||||
/// The resulting StmtSequence identifies a continuous sequence of statements
|
||||
/// in the body of the given CompoundStmt. Which statements of the body should
|
||||
@ -57,20 +55,20 @@ class StmtSequence {
|
||||
/// that describe a non-empty sub-array in the body of the given CompoundStmt.
|
||||
///
|
||||
/// \param Stmt A CompoundStmt that contains all statements in its body.
|
||||
/// \param Context The ASTContext for the given CompoundStmt.
|
||||
/// \param D The Decl containing this Stmt.
|
||||
/// \param StartIndex The inclusive start index in the children array of
|
||||
/// \p Stmt
|
||||
/// \param EndIndex The exclusive end index in the children array of \p Stmt.
|
||||
StmtSequence(const CompoundStmt *Stmt, ASTContext &Context,
|
||||
unsigned StartIndex, unsigned EndIndex);
|
||||
StmtSequence(const CompoundStmt *Stmt, const Decl *D, unsigned StartIndex,
|
||||
unsigned EndIndex);
|
||||
|
||||
/// \brief Constructs a StmtSequence holding a single statement.
|
||||
/// Constructs a StmtSequence holding a single statement.
|
||||
///
|
||||
/// \param Stmt An arbitrary Stmt.
|
||||
/// \param Context The ASTContext for the given Stmt.
|
||||
StmtSequence(const Stmt *Stmt, ASTContext &Context);
|
||||
/// \param D The Decl containing this Stmt.
|
||||
StmtSequence(const Stmt *Stmt, const Decl *D);
|
||||
|
||||
/// \brief Constructs an empty StmtSequence.
|
||||
/// Constructs an empty StmtSequence.
|
||||
StmtSequence();
|
||||
|
||||
typedef const Stmt *const *iterator;
|
||||
@ -110,9 +108,12 @@ class StmtSequence {
|
||||
bool empty() const { return size() == 0; }
|
||||
|
||||
/// Returns the related ASTContext for the stored Stmts.
|
||||
ASTContext &getASTContext() const {
|
||||
assert(Context);
|
||||
return *Context;
|
||||
ASTContext &getASTContext() const;
|
||||
|
||||
/// Returns the declaration that contains the stored Stmts.
|
||||
const Decl *getContainingDecl() const {
|
||||
assert(D);
|
||||
return D;
|
||||
}
|
||||
|
||||
/// Returns true if this objects holds a list of statements.
|
||||
@ -150,106 +151,215 @@ class StmtSequence {
|
||||
bool contains(const StmtSequence &Other) const;
|
||||
};
|
||||
|
||||
/// \brief Searches for clones in source code.
|
||||
/// Searches for similar subtrees in the AST.
|
||||
///
|
||||
/// First, this class needs a translation unit which is passed via
|
||||
/// \p analyzeTranslationUnit . It will then generate and store search data
|
||||
/// for all statements inside the given translation unit.
|
||||
/// Afterwards the generated data can be used to find code clones by calling
|
||||
/// \p findClones .
|
||||
/// First, this class needs several declarations with statement bodies which
|
||||
/// can be passed via analyzeCodeBody. Afterwards all statements can be
|
||||
/// searched for clones by calling findClones with a given list of constraints
|
||||
/// that should specify the wanted properties of the clones.
|
||||
///
|
||||
/// The result of findClones can be further constrained with the constrainClones
|
||||
/// method.
|
||||
///
|
||||
/// This class only searches for clones in exectuable source code
|
||||
/// (e.g. function bodies). Other clones (e.g. cloned comments or declarations)
|
||||
/// are not supported.
|
||||
class CloneDetector {
|
||||
|
||||
public:
|
||||
typedef unsigned DataPiece;
|
||||
/// A collection of StmtSequences that share an arbitrary property.
|
||||
typedef llvm::SmallVector<StmtSequence, 8> CloneGroup;
|
||||
|
||||
/// Holds the data about a StmtSequence that is needed during the search for
|
||||
/// code clones.
|
||||
struct CloneSignature {
|
||||
/// \brief The hash code of the StmtSequence.
|
||||
///
|
||||
/// The initial clone groups that are formed during the search for clones
|
||||
/// consist only of Sequences that share the same hash code. This makes this
|
||||
/// value the central part of this heuristic that is needed to find clones
|
||||
/// in a performant way. For this to work, the type of this variable
|
||||
/// always needs to be small and fast to compare.
|
||||
///
|
||||
/// Also, StmtSequences that are clones of each others have to share
|
||||
/// the same hash code. StmtSequences that are not clones of each other
|
||||
/// shouldn't share the same hash code, but if they do, it will only
|
||||
/// degrade the performance of the hash search but doesn't influence
|
||||
/// the correctness of the result.
|
||||
size_t Hash;
|
||||
|
||||
/// \brief The complexity of the StmtSequence.
|
||||
///
|
||||
/// This value gives an approximation on how many direct or indirect child
|
||||
/// statements are contained in the related StmtSequence. In general, the
|
||||
/// greater this value, the greater the amount of statements. However, this
|
||||
/// is only an approximation and the actual amount of statements can be
|
||||
/// higher or lower than this value. Statements that are generated by the
|
||||
/// compiler (e.g. macro expansions) for example barely influence the
|
||||
/// complexity value.
|
||||
///
|
||||
/// The main purpose of this value is to filter clones that are too small
|
||||
/// and therefore probably not interesting enough for the user.
|
||||
unsigned Complexity;
|
||||
|
||||
/// \brief Creates an empty CloneSignature without any data.
|
||||
CloneSignature() : Complexity(1) {}
|
||||
|
||||
CloneSignature(llvm::hash_code Hash, unsigned Complexity)
|
||||
: Hash(Hash), Complexity(Complexity) {}
|
||||
};
|
||||
|
||||
/// Holds group of StmtSequences that are clones of each other and the
|
||||
/// complexity value (see CloneSignature::Complexity) that all stored
|
||||
/// StmtSequences have in common.
|
||||
struct CloneGroup {
|
||||
std::vector<StmtSequence> Sequences;
|
||||
CloneSignature Signature;
|
||||
|
||||
CloneGroup() {}
|
||||
|
||||
CloneGroup(const StmtSequence &Seq, CloneSignature Signature)
|
||||
: Signature(Signature) {
|
||||
Sequences.push_back(Seq);
|
||||
}
|
||||
|
||||
/// \brief Returns false if and only if this group should be skipped when
|
||||
/// searching for clones.
|
||||
bool isValid() const {
|
||||
// A clone group with only one member makes no sense, so we skip them.
|
||||
return Sequences.size() > 1;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Generates and stores search data for all statements in the body of
|
||||
/// the given Decl.
|
||||
/// Generates and stores search data for all statements in the body of
|
||||
/// the given Decl.
|
||||
void analyzeCodeBody(const Decl *D);
|
||||
|
||||
/// \brief Stores the CloneSignature to allow future querying.
|
||||
void add(const StmtSequence &S, const CloneSignature &Signature);
|
||||
|
||||
/// \brief Searches the provided statements for clones.
|
||||
/// Constrains the given list of clone groups with the given constraint.
|
||||
///
|
||||
/// \param Result Output parameter that is filled with a list of found
|
||||
/// clone groups. Each group contains multiple StmtSequences
|
||||
/// that were identified to be clones of each other.
|
||||
/// \param MinGroupComplexity Only return clones which have at least this
|
||||
/// complexity value.
|
||||
/// \param CheckPatterns Returns only clone groups in which the referenced
|
||||
/// variables follow the same pattern.
|
||||
void findClones(std::vector<CloneGroup> &Result, unsigned MinGroupComplexity,
|
||||
bool CheckPatterns = true);
|
||||
/// The constraint is expected to have a method with the signature
|
||||
/// `void constrain(std::vector<CloneDetector::CloneGroup> &Sequences)`
|
||||
/// as this is the interface that the CloneDetector uses for applying the
|
||||
/// constraint. The constraint is supposed to directly modify the passed list
|
||||
/// so that all clones in the list fulfill the specific property this
|
||||
/// constraint ensures.
|
||||
template <typename T>
|
||||
static void constrainClones(std::vector<CloneGroup> &CloneGroups, T C) {
|
||||
C.constrain(CloneGroups);
|
||||
}
|
||||
|
||||
/// \brief Describes two clones that reference their variables in a different
|
||||
/// pattern which could indicate a programming error.
|
||||
/// Constrains the given list of clone groups with the given list of
|
||||
/// constraints.
|
||||
///
|
||||
/// The constraints are applied in sequence in the order in which they are
|
||||
/// passed to this function.
|
||||
template <typename T1, typename... Ts>
|
||||
static void constrainClones(std::vector<CloneGroup> &CloneGroups, T1 C,
|
||||
Ts... ConstraintList) {
|
||||
constrainClones(CloneGroups, C);
|
||||
constrainClones(CloneGroups, ConstraintList...);
|
||||
}
|
||||
|
||||
/// Searches for clones in all previously passed statements.
|
||||
/// \param Result Output parameter to which all created clone groups are
|
||||
/// added.
|
||||
/// \param ConstraintList The constraints that should be applied to the
|
||||
// result.
|
||||
template <typename... Ts>
|
||||
void findClones(std::vector<CloneGroup> &Result, Ts... ConstraintList) {
|
||||
// The initial assumption is that there is only one clone group and every
|
||||
// statement is a clone of the others. This clone group will then be
|
||||
// split up with the help of the constraints.
|
||||
CloneGroup AllClones;
|
||||
AllClones.reserve(Sequences.size());
|
||||
for (const auto &C : Sequences) {
|
||||
AllClones.push_back(C);
|
||||
}
|
||||
|
||||
Result.push_back(AllClones);
|
||||
|
||||
constrainClones(Result, ConstraintList...);
|
||||
}
|
||||
|
||||
private:
|
||||
CloneGroup Sequences;
|
||||
};
|
||||
|
||||
/// This class is a utility class that contains utility functions for building
|
||||
/// custom constraints.
|
||||
class CloneConstraint {
|
||||
public:
|
||||
/// Removes all groups by using a filter function.
|
||||
/// \param CloneGroups The list of CloneGroups that is supposed to be
|
||||
/// filtered.
|
||||
/// \param Filter The filter function that should return true for all groups
|
||||
/// that should be removed from the list.
|
||||
static void
|
||||
filterGroups(std::vector<CloneDetector::CloneGroup> &CloneGroups,
|
||||
std::function<bool(const CloneDetector::CloneGroup &)> Filter) {
|
||||
CloneGroups.erase(
|
||||
std::remove_if(CloneGroups.begin(), CloneGroups.end(), Filter),
|
||||
CloneGroups.end());
|
||||
}
|
||||
|
||||
/// Splits the given CloneGroups until the given Compare function returns true
|
||||
/// for all clones in a single group.
|
||||
/// \param CloneGroups A list of CloneGroups that should be modified.
|
||||
/// \param Compare The comparison function that all clones are supposed to
|
||||
/// pass. Should return true if and only if two clones belong
|
||||
/// to the same CloneGroup.
|
||||
static void splitCloneGroups(
|
||||
std::vector<CloneDetector::CloneGroup> &CloneGroups,
|
||||
std::function<bool(const StmtSequence &, const StmtSequence &)> Compare);
|
||||
};
|
||||
|
||||
/// Searches all children of the given clones for type II clones (i.e. they are
|
||||
/// identical in every aspect beside the used variable names).
|
||||
class RecursiveCloneTypeIIConstraint {
|
||||
|
||||
/// Generates and saves a hash code for the given Stmt.
|
||||
/// \param S The given Stmt.
|
||||
/// \param D The Decl containing S.
|
||||
/// \param StmtsByHash Output parameter that will contain the hash codes for
|
||||
/// each StmtSequence in the given Stmt.
|
||||
/// \return The hash code of the given Stmt.
|
||||
///
|
||||
/// If the given Stmt is a CompoundStmt, this method will also generate
|
||||
/// hashes for all possible StmtSequences in the children of this Stmt.
|
||||
size_t saveHash(const Stmt *S, const Decl *D,
|
||||
std::vector<std::pair<size_t, StmtSequence>> &StmtsByHash);
|
||||
|
||||
public:
|
||||
void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
|
||||
};
|
||||
|
||||
/// Ensures that every clone has at least the given complexity.
|
||||
///
|
||||
/// Complexity is here defined as the total amount of children of a statement.
|
||||
/// This constraint assumes the first statement in the group is representative
|
||||
/// for all other statements in the group in terms of complexity.
|
||||
class MinComplexityConstraint {
|
||||
unsigned MinComplexity;
|
||||
|
||||
public:
|
||||
MinComplexityConstraint(unsigned MinComplexity)
|
||||
: MinComplexity(MinComplexity) {}
|
||||
|
||||
size_t calculateStmtComplexity(const StmtSequence &Seq,
|
||||
const std::string &ParentMacroStack = "");
|
||||
|
||||
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
|
||||
CloneConstraint::filterGroups(
|
||||
CloneGroups, [this](const CloneDetector::CloneGroup &A) {
|
||||
if (!A.empty())
|
||||
return calculateStmtComplexity(A.front()) < MinComplexity;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/// Ensures that all clone groups contain at least the given amount of clones.
|
||||
class MinGroupSizeConstraint {
|
||||
unsigned MinGroupSize;
|
||||
|
||||
public:
|
||||
MinGroupSizeConstraint(unsigned MinGroupSize = 2)
|
||||
: MinGroupSize(MinGroupSize) {}
|
||||
|
||||
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
|
||||
CloneConstraint::filterGroups(CloneGroups,
|
||||
[this](const CloneDetector::CloneGroup &A) {
|
||||
return A.size() < MinGroupSize;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/// Ensures that no clone group fully contains another clone group.
|
||||
struct OnlyLargestCloneConstraint {
|
||||
void constrain(std::vector<CloneDetector::CloneGroup> &Result);
|
||||
};
|
||||
|
||||
/// Analyzes the pattern of the referenced variables in a statement.
|
||||
class VariablePattern {
|
||||
|
||||
/// Describes an occurence of a variable reference in a statement.
|
||||
struct VariableOccurence {
|
||||
/// The index of the associated VarDecl in the Variables vector.
|
||||
size_t KindID;
|
||||
/// The statement in the code where the variable was referenced.
|
||||
const Stmt *Mention;
|
||||
|
||||
VariableOccurence(size_t KindID, const Stmt *Mention)
|
||||
: KindID(KindID), Mention(Mention) {}
|
||||
};
|
||||
|
||||
/// All occurences of referenced variables in the order of appearance.
|
||||
std::vector<VariableOccurence> Occurences;
|
||||
/// List of referenced variables in the order of appearance.
|
||||
/// Every item in this list is unique.
|
||||
std::vector<const VarDecl *> Variables;
|
||||
|
||||
/// Adds a new variable referenced to this pattern.
|
||||
/// \param VarDecl The declaration of the variable that is referenced.
|
||||
/// \param Mention The SourceRange where this variable is referenced.
|
||||
void addVariableOccurence(const VarDecl *VarDecl, const Stmt *Mention);
|
||||
|
||||
/// Adds each referenced variable from the given statement.
|
||||
void addVariables(const Stmt *S);
|
||||
|
||||
public:
|
||||
/// Creates an VariablePattern object with information about the given
|
||||
/// StmtSequence.
|
||||
VariablePattern(const StmtSequence &Sequence) {
|
||||
for (const Stmt *S : Sequence)
|
||||
addVariables(S);
|
||||
}
|
||||
|
||||
/// Describes two clones that reference their variables in a different pattern
|
||||
/// which could indicate a programming error.
|
||||
struct SuspiciousClonePair {
|
||||
/// \brief Utility class holding the relevant information about a single
|
||||
/// clone in this pair.
|
||||
/// Utility class holding the relevant information about a single
|
||||
/// clone in this pair.
|
||||
struct SuspiciousCloneInfo {
|
||||
/// The variable which referencing in this clone was against the pattern.
|
||||
const VarDecl *Variable;
|
||||
@ -270,17 +380,37 @@ class CloneDetector {
|
||||
SuspiciousCloneInfo SecondCloneInfo;
|
||||
};
|
||||
|
||||
/// \brief Searches the provided statements for pairs of clones that don't
|
||||
/// follow the same pattern when referencing variables.
|
||||
/// \param Result Output parameter that will contain the clone pairs.
|
||||
/// \param MinGroupComplexity Only clone pairs in which the clones have at
|
||||
/// least this complexity value.
|
||||
void findSuspiciousClones(std::vector<SuspiciousClonePair> &Result,
|
||||
unsigned MinGroupComplexity);
|
||||
/// Counts the differences between this pattern and the given one.
|
||||
/// \param Other The given VariablePattern to compare with.
|
||||
/// \param FirstMismatch Output parameter that will be filled with information
|
||||
/// about the first difference between the two patterns. This parameter
|
||||
/// can be a nullptr, in which case it will be ignored.
|
||||
/// \return Returns the number of differences between the pattern this object
|
||||
/// is following and the given VariablePattern.
|
||||
///
|
||||
/// For example, the following statements all have the same pattern and this
|
||||
/// function would return zero:
|
||||
///
|
||||
/// if (a < b) return a; return b;
|
||||
/// if (x < y) return x; return y;
|
||||
/// if (u2 < u1) return u2; return u1;
|
||||
///
|
||||
/// But the following statement has a different pattern (note the changed
|
||||
/// variables in the return statements) and would have two differences when
|
||||
/// compared with one of the statements above.
|
||||
///
|
||||
/// if (a < b) return b; return a;
|
||||
///
|
||||
/// This function should only be called if the related statements of the given
|
||||
/// pattern and the statements of this objects are clones of each other.
|
||||
unsigned countPatternDifferences(
|
||||
const VariablePattern &Other,
|
||||
VariablePattern::SuspiciousClonePair *FirstMismatch = nullptr);
|
||||
};
|
||||
|
||||
private:
|
||||
/// Stores all encountered StmtSequences alongside their CloneSignature.
|
||||
std::vector<std::pair<CloneSignature, StmtSequence>> Sequences;
|
||||
/// Ensures that all clones reference variables in the same pattern.
|
||||
struct MatchingVariablePatternConstraint {
|
||||
void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups);
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
@ -20,24 +20,32 @@ namespace clang {
|
||||
|
||||
namespace LangAS {
|
||||
|
||||
/// \brief Defines the set of possible language-specific address spaces.
|
||||
/// \brief Defines the address space values used by the address space qualifier
|
||||
/// of QualType.
|
||||
///
|
||||
/// This uses a high starting offset so as not to conflict with any address
|
||||
/// space used by a target.
|
||||
enum ID {
|
||||
Offset = 0x7FFF00,
|
||||
// The default value 0 is the value used in QualType for the the situation
|
||||
// where there is no address space qualifier. For most languages, this also
|
||||
// corresponds to the situation where there is no address space qualifier in
|
||||
// the source code, except for OpenCL, where the address space value 0 in
|
||||
// QualType represents private address space in OpenCL source code.
|
||||
Default = 0,
|
||||
|
||||
opencl_global = Offset,
|
||||
// OpenCL specific address spaces.
|
||||
opencl_global,
|
||||
opencl_local,
|
||||
opencl_constant,
|
||||
opencl_generic,
|
||||
|
||||
// CUDA specific address spaces.
|
||||
cuda_device,
|
||||
cuda_constant,
|
||||
cuda_shared,
|
||||
|
||||
Last,
|
||||
Count = Last-Offset
|
||||
// This denotes the count of language-specific address spaces and also
|
||||
// the offset added to the target-specific address spaces, which are usually
|
||||
// specified by address space attributes __attribute__(address_space(n))).
|
||||
Count
|
||||
};
|
||||
|
||||
/// The type of a lookup table which maps from language-specific address spaces
|
||||
|
@ -258,6 +258,7 @@ class TargetArch<list<string> arches> {
|
||||
list<string> CXXABIs;
|
||||
}
|
||||
def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
|
||||
def TargetAVR : TargetArch<["avr"]>;
|
||||
def TargetMips : TargetArch<["mips", "mipsel"]>;
|
||||
def TargetMSP430 : TargetArch<["msp430"]>;
|
||||
def TargetX86 : TargetArch<["x86"]>;
|
||||
@ -301,6 +302,9 @@ class Attr {
|
||||
// Set to true if this attribute can be duplicated on a subject when merging
|
||||
// attributes. By default, attributes are not merged.
|
||||
bit DuplicatesAllowedWhileMerging = 0;
|
||||
// Set to true if this attribute meaningful when applied to or inherited
|
||||
// in a class template definition.
|
||||
bit MeaningfulToClassTemplateDefinition = 0;
|
||||
// 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 = [];
|
||||
@ -340,7 +344,7 @@ class TargetSpecificAttr<TargetArch target> {
|
||||
// should contain a shared value between the attributes.
|
||||
//
|
||||
// Target-specific attributes which use this feature should ensure that the
|
||||
// spellings match exactly betweeen the attributes, and if the arguments or
|
||||
// spellings match exactly between the attributes, and if the arguments or
|
||||
// subjects differ, should specify HasCustomParsing = 1 and implement their
|
||||
// own parsing and semantic handling requirements as-needed.
|
||||
string ParseKind;
|
||||
@ -372,6 +376,7 @@ def AbiTag : Attr {
|
||||
let Args = [VariadicStringArgument<"Tags">];
|
||||
let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag,
|
||||
"ExpectedStructClassVariableFunctionOrInlineNamespace">;
|
||||
let MeaningfulToClassTemplateDefinition = 1;
|
||||
let Documentation = [AbiTagsDocs];
|
||||
}
|
||||
|
||||
@ -449,6 +454,15 @@ def XRayInstrument : InheritableAttr {
|
||||
let Documentation = [XRayDocs];
|
||||
}
|
||||
|
||||
def XRayLogArgs : InheritableAttr {
|
||||
let Spellings = [GNU<"xray_log_args">, CXX11<"clang", "xray_log_args">];
|
||||
let Subjects = SubjectList<
|
||||
[CXXMethod, ObjCMethod, Function], WarnDiag, "ExpectedFunctionOrMethod"
|
||||
>;
|
||||
let Args = [UnsignedArgument<"ArgumentCount">];
|
||||
let Documentation = [XRayDocs];
|
||||
}
|
||||
|
||||
def TLSModel : InheritableAttr {
|
||||
let Spellings = [GCC<"tls_model">];
|
||||
let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">;
|
||||
@ -480,6 +494,19 @@ def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
|
||||
let Documentation = [ARMInterruptDocs];
|
||||
}
|
||||
|
||||
def AVRInterrupt : InheritableAttr, TargetSpecificAttr<TargetAVR> {
|
||||
let Spellings = [GNU<"interrupt">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let ParseKind = "Interrupt";
|
||||
let Documentation = [AVRInterruptDocs];
|
||||
}
|
||||
|
||||
def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> {
|
||||
let Spellings = [GNU<"signal">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [AVRSignalDocs];
|
||||
}
|
||||
|
||||
def AsmLabel : InheritableAttr {
|
||||
let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
|
||||
let Args = [StringArgument<"Label">];
|
||||
@ -513,6 +540,17 @@ def Availability : InheritableAttr {
|
||||
let Documentation = [AvailabilityDocs];
|
||||
}
|
||||
|
||||
def ExternalSourceSymbol : InheritableAttr {
|
||||
let Spellings = [GNU<"external_source_symbol">,
|
||||
CXX11<"clang", "external_source_symbol">];
|
||||
let Args = [StringArgument<"language", 1>,
|
||||
StringArgument<"definedIn", 1>,
|
||||
BoolArgument<"generatedDeclaration", 1>];
|
||||
let HasCustomParsing = 1;
|
||||
// let Subjects = SubjectList<[Named]>;
|
||||
let Documentation = [ExternalSourceSymbolDocs];
|
||||
}
|
||||
|
||||
def Blocks : InheritableAttr {
|
||||
let Spellings = [GNU<"blocks">];
|
||||
let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
|
||||
@ -771,6 +809,7 @@ def Deprecated : InheritableAttr {
|
||||
// An optional string argument that enables us to provide a
|
||||
// Fix-It.
|
||||
StringArgument<"Replacement", 1>];
|
||||
let MeaningfulToClassTemplateDefinition = 1;
|
||||
let Documentation = [DeprecatedDocs];
|
||||
}
|
||||
|
||||
@ -847,7 +886,15 @@ def FlagEnum : InheritableAttr {
|
||||
let Spellings = [GNU<"flag_enum">];
|
||||
let Subjects = SubjectList<[Enum]>;
|
||||
let Documentation = [FlagEnumDocs];
|
||||
let LangOpts = [COnly];
|
||||
}
|
||||
|
||||
def EnumExtensibility : InheritableAttr {
|
||||
let Spellings = [GNU<"enum_extensibility">,
|
||||
CXX11<"clang", "enum_extensibility">];
|
||||
let Subjects = SubjectList<[Enum]>;
|
||||
let Args = [EnumArgument<"Extensibility", "Kind",
|
||||
["closed", "open"], ["Closed", "Open"]>];
|
||||
let Documentation = [EnumExtensibilityDocs];
|
||||
}
|
||||
|
||||
def Flatten : InheritableAttr {
|
||||
@ -1115,7 +1162,7 @@ def NoSplitStack : InheritableAttr {
|
||||
let Documentation = [NoSplitStackDocs];
|
||||
}
|
||||
|
||||
def NonNull : InheritableAttr {
|
||||
def NonNull : InheritableParamAttr {
|
||||
let Spellings = [GCC<"nonnull">];
|
||||
let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
|
||||
"ExpectedFunctionMethodOrParameter">;
|
||||
@ -1178,6 +1225,14 @@ def AssumeAligned : InheritableAttr {
|
||||
let Documentation = [AssumeAlignedDocs];
|
||||
}
|
||||
|
||||
def AllocAlign : InheritableAttr {
|
||||
let Spellings = [GCC<"alloc_align">];
|
||||
let Subjects = SubjectList<[HasFunctionProto], WarnDiag,
|
||||
"ExpectedFunctionWithProtoType">;
|
||||
let Args = [IntArgument<"ParamIndex">];
|
||||
let Documentation = [AllocAlignDocs];
|
||||
}
|
||||
|
||||
def NoReturn : InheritableAttr {
|
||||
let Spellings = [GCC<"noreturn">, Declspec<"noreturn">];
|
||||
// FIXME: Does GCC allow this on the function instead?
|
||||
@ -1498,6 +1553,12 @@ def SwiftIndirectResult : ParameterABIAttr {
|
||||
let Documentation = [SwiftIndirectResultDocs];
|
||||
}
|
||||
|
||||
def Suppress : StmtAttr {
|
||||
let Spellings = [CXX11<"gsl", "suppress">];
|
||||
let Args = [VariadicStringArgument<"DiagnosticIdentifiers">];
|
||||
let Documentation = [SuppressDocs];
|
||||
}
|
||||
|
||||
def SysVABI : InheritableAttr {
|
||||
let Spellings = [GCC<"sysv_abi">];
|
||||
// let Subjects = [Function, ObjCMethod];
|
||||
@ -1681,6 +1742,7 @@ def Visibility : InheritableAttr {
|
||||
let Args = [EnumArgument<"Visibility", "VisibilityType",
|
||||
["default", "hidden", "internal", "protected"],
|
||||
["Default", "Hidden", "Hidden", "Protected"]>];
|
||||
let MeaningfulToClassTemplateDefinition = 1;
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,36 @@ An example of how to use ``alloc_size``
|
||||
}];
|
||||
}
|
||||
|
||||
def AllocAlignDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
Use ``__attribute__((alloc_align(<alignment>))`` on a function
|
||||
declaration to specify that the return value of the function (which must be a
|
||||
pointer type) is at least as aligned as the value of the indicated parameter. The
|
||||
parameter is given by its index in the list of formal parameters; the first
|
||||
parameter has index 1 unless the function is a C++ non-static member function,
|
||||
in which case the first parameter has index 2 to account for the implicit ``this``
|
||||
parameter.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// The returned pointer has the alignment specified by the first parameter.
|
||||
void *a(size_t align) __attribute__((alloc_align(1)));
|
||||
|
||||
// The returned pointer has the alignment specified by the second parameter.
|
||||
void *b(void *v, size_t align) __attribute__((alloc_align(2)));
|
||||
|
||||
// The returned pointer has the alignment specified by the second visible
|
||||
// parameter, however it must be adjusted for the implicit 'this' parameter.
|
||||
void *Foo::b(void *v, size_t align) __attribute__((alloc_align(3)));
|
||||
|
||||
Note that this attribute merely informs the compiler that a function always
|
||||
returns a sufficiently aligned pointer. It does not cause the compiler to
|
||||
emit code to enforce that alignment. The behavior is undefined if the returned
|
||||
poitner is not sufficiently aligned.
|
||||
}];
|
||||
}
|
||||
|
||||
def EnableIfDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
@ -960,6 +990,63 @@ When one method overrides another, the overriding method can be more widely avai
|
||||
}];
|
||||
}
|
||||
|
||||
def ExternalSourceSymbolDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
The ``external_source_symbol`` attribute specifies that a declaration originates
|
||||
from an external source and describes the nature of that source.
|
||||
|
||||
The fact that Clang is capable of recognizing declarations that were defined
|
||||
externally can be used to provide better tooling support for mixed-language
|
||||
projects or projects that rely on auto-generated code. For instance, an IDE that
|
||||
uses Clang and that supports mixed-language projects can use this attribute to
|
||||
provide a correct 'jump-to-definition' feature. For a concrete example,
|
||||
consider a protocol that's defined in a Swift file:
|
||||
|
||||
.. code-block:: swift
|
||||
|
||||
@objc public protocol SwiftProtocol {
|
||||
func method()
|
||||
}
|
||||
|
||||
This protocol can be used from Objective-C code by including a header file that
|
||||
was generated by the Swift compiler. The declarations in that header can use
|
||||
the ``external_source_symbol`` attribute to make Clang aware of the fact
|
||||
that ``SwiftProtocol`` actually originates from a Swift module:
|
||||
|
||||
.. code-block:: objc
|
||||
|
||||
__attribute__((external_source_symbol(language="Swift",defined_in="module")))
|
||||
@protocol SwiftProtocol
|
||||
@required
|
||||
- (void) method;
|
||||
@end
|
||||
|
||||
Consequently, when 'jump-to-definition' is performed at a location that
|
||||
references ``SwiftProtocol``, the IDE can jump to the original definition in
|
||||
the Swift source file rather than jumping to the Objective-C declaration in the
|
||||
auto-generated header file.
|
||||
|
||||
The ``external_source_symbol`` attribute is a comma-separated list that includes
|
||||
clauses that describe the origin and the nature of the particular declaration.
|
||||
Those clauses can be:
|
||||
|
||||
language=\ *string-literal*
|
||||
The name of the source language in which this declaration was defined.
|
||||
|
||||
defined_in=\ *string-literal*
|
||||
The name of the source container in which the declaration was defined. The
|
||||
exact definition of source container is language-specific, e.g. Swift's
|
||||
source containers are modules, so ``defined_in`` should specify the Swift
|
||||
module name.
|
||||
|
||||
generated_declaration
|
||||
This declaration was automatically generated by some tool.
|
||||
|
||||
The clauses can be specified in any order. The clauses that are listed above are
|
||||
all optional, but the attribute has to have at least one clause.
|
||||
}];
|
||||
}
|
||||
|
||||
def RequireConstantInitDocs : Documentation {
|
||||
let Category = DocCatVariable;
|
||||
@ -1182,6 +1269,33 @@ The semantics are as follows:
|
||||
}];
|
||||
}
|
||||
|
||||
def AVRInterruptDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
Clang supports the GNU style ``__attribute__((interrupt))`` attribute on
|
||||
AVR targets. This attribute may be attached to a function definition and instructs
|
||||
the backend to generate appropriate function entry/exit code so that it can be used
|
||||
directly as an interrupt service routine.
|
||||
|
||||
On the AVR, the hardware globally disables interrupts when an interrupt is executed.
|
||||
The first instruction of an interrupt handler declared with this attribute is a SEI
|
||||
instruction to re-enable interrupts. See also the signal attribute that
|
||||
does not insert a SEI instruction.
|
||||
}];
|
||||
}
|
||||
|
||||
def AVRSignalDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
Clang supports the GNU style ``__attribute__((signal))`` attribute on
|
||||
AVR targets. This attribute may be attached to a function definition and instructs
|
||||
the backend to generate appropriate function entry/exit code so that it can be used
|
||||
directly as an interrupt service routine.
|
||||
|
||||
Interrupt handler functions defined with the signal attribute do not re-enable interrupts.
|
||||
}];
|
||||
}
|
||||
|
||||
def TargetDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
@ -1879,6 +1993,55 @@ manipulating bits of the enumerator when issuing warnings.
|
||||
}];
|
||||
}
|
||||
|
||||
def EnumExtensibilityDocs : Documentation {
|
||||
let Category = DocCatType;
|
||||
let Content = [{
|
||||
Attribute ``enum_extensibility`` is used to distinguish between enum definitions
|
||||
that are extensible and those that are not. The attribute can take either
|
||||
``closed`` or ``open`` as an argument. ``closed`` indicates a variable of the
|
||||
enum type takes a value that corresponds to one of the enumerators listed in the
|
||||
enum definition or, when the enum is annotated with ``flag_enum``, a value that
|
||||
can be constructed using values corresponding to the enumerators. ``open``
|
||||
indicates a variable of the enum type can take any values allowed by the
|
||||
standard and instructs clang to be more lenient when issuing warnings.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
enum __attribute__((enum_extensibility(closed))) ClosedEnum {
|
||||
A0, A1
|
||||
};
|
||||
|
||||
enum __attribute__((enum_extensibility(open))) OpenEnum {
|
||||
B0, B1
|
||||
};
|
||||
|
||||
enum __attribute__((enum_extensibility(closed),flag_enum)) ClosedFlagEnum {
|
||||
C0 = 1 << 0, C1 = 1 << 1
|
||||
};
|
||||
|
||||
enum __attribute__((enum_extensibility(open),flag_enum)) OpenFlagEnum {
|
||||
D0 = 1 << 0, D1 = 1 << 1
|
||||
};
|
||||
|
||||
void foo1() {
|
||||
enum ClosedEnum ce;
|
||||
enum OpenEnum oe;
|
||||
enum ClosedFlagEnum cfe;
|
||||
enum OpenFlagEnum ofe;
|
||||
|
||||
ce = A1; // no warnings
|
||||
ce = 100; // warning issued
|
||||
oe = B1; // no warnings
|
||||
oe = 100; // no warnings
|
||||
cfe = C0 | C1; // no warnings
|
||||
cfe = C0 | C1 | 4; // warning issued
|
||||
ofe = D0 | D1; // no warnings
|
||||
ofe = D0 | D1 | 4; // no warnings
|
||||
}
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
def EmptyBasesDocs : Documentation {
|
||||
let Category = DocCatType;
|
||||
let Content = [{
|
||||
@ -2638,6 +2801,32 @@ optimizations like C++'s named return value optimization (NRVO).
|
||||
}];
|
||||
}
|
||||
|
||||
def SuppressDocs : Documentation {
|
||||
let Category = DocCatStmt;
|
||||
let Content = [{
|
||||
The ``[[gsl::suppress]]`` attribute suppresses specific
|
||||
clang-tidy diagnostics for rules of the `C++ Core Guidelines`_ in a portable
|
||||
way. The attribute can be attached to declarations, statements, and at
|
||||
namespace scope.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
[[gsl::suppress("Rh-public")]]
|
||||
void f_() {
|
||||
int *p;
|
||||
[[gsl::suppress("type")]] {
|
||||
p = reinterpret_cast<int*>(7);
|
||||
}
|
||||
}
|
||||
namespace N {
|
||||
[[clang::suppress("type", "bounds")]];
|
||||
...
|
||||
}
|
||||
|
||||
.. _`C++ Core Guidelines`: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#inforce-enforcement
|
||||
}];
|
||||
}
|
||||
|
||||
def AbiTagsDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
@ -2777,13 +2966,15 @@ 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)";
|
||||
let Heading = "xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument), xray_log_args (clang::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.
|
||||
|
||||
Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points.
|
||||
|
||||
If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise.
|
||||
|
||||
``__attribute__((xray_log_args(N)))`` or ``[[clang::xray_log_args(N)]]`` is used to preserve N function arguments for the logging function. Currently, only N==1 is supported.
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -756,11 +756,11 @@ LANGBUILTIN(_InterlockedOr, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_InterlockedXor, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_interlockedbittestandset, "UcLiD*Li", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__popcnt64, "ULLiULLi", "nc", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES)
|
||||
@ -773,6 +773,7 @@ LANGBUILTIN(_rotr, "UiUii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_lrotr, "ULiULii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(_rotr64, "ULLiULLii", "n", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
|
||||
LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES)
|
||||
|
||||
// Microsoft library builtins.
|
||||
LIBBUILTIN(_setjmpex, "iJ", "fj", "setjmpex.h", ALL_MS_LANGUAGES)
|
||||
@ -1086,9 +1087,11 @@ LIBBUILTIN(ilogb, "id", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ilogbf, "if", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(ilogbl, "iLd", "fne", "math.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(lgamma, "dd", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(lgammaf, "ff", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(lgammal, "LdLd", "fne", "math.h", ALL_LANGUAGES)
|
||||
// POSIX math.h declares a global, signgam, that lgamma writes to, so these
|
||||
// shouldn't have "e" or "c" attributes
|
||||
LIBBUILTIN(lgamma, "dd", "fn", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(lgammaf, "ff", "fn", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(lgammal, "LdLd", "fn", "math.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(llrint, "LLid", "fne", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(llrintf, "LLif", "fne", "math.h", ALL_LANGUAGES)
|
||||
@ -1362,7 +1365,7 @@ BUILTIN(__builtin_coro_free, "v*v*", "n")
|
||||
BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n")
|
||||
BUILTIN(__builtin_coro_alloc, "b", "n")
|
||||
BUILTIN(__builtin_coro_begin, "v*v*", "n")
|
||||
BUILTIN(__builtin_coro_end, "vv*Ib", "n")
|
||||
BUILTIN(__builtin_coro_end, "bv*Ib", "n")
|
||||
BUILTIN(__builtin_coro_suspend, "cIb", "n")
|
||||
BUILTIN(__builtin_coro_param, "bv*v*", "n")
|
||||
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
|
||||
|
@ -35,8 +35,14 @@ BUILTIN(__builtin_amdgcn_workitem_id_z, "Ui", "nc")
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction builtins.
|
||||
//===----------------------------------------------------------------------===//
|
||||
BUILTIN(__builtin_amdgcn_s_getreg, "UiIi", "n")
|
||||
BUILTIN(__builtin_amdgcn_s_waitcnt, "vIi", "n")
|
||||
BUILTIN(__builtin_amdgcn_s_sendmsg, "vIiUi", "n")
|
||||
BUILTIN(__builtin_amdgcn_s_sendmsghalt, "vIiUi", "n")
|
||||
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")
|
||||
BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n")
|
||||
BUILTIN(__builtin_amdgcn_div_scalef, "fffbb*", "n")
|
||||
BUILTIN(__builtin_amdgcn_div_fmas, "ddddb", "nc")
|
||||
@ -80,6 +86,11 @@ BUILTIN(__builtin_amdgcn_sicmpl, "LUiLiLiIi", "nc")
|
||||
BUILTIN(__builtin_amdgcn_fcmp, "LUiddIi", "nc")
|
||||
BUILTIN(__builtin_amdgcn_fcmpf, "LUiffIi", "nc")
|
||||
BUILTIN(__builtin_amdgcn_ds_swizzle, "iiIi", "nc")
|
||||
BUILTIN(__builtin_amdgcn_ds_permute, "iii", "nc")
|
||||
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")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// VI+ only builtins.
|
||||
@ -96,6 +107,13 @@ TARGET_BUILTIN(__builtin_amdgcn_frexp_exph, "sh", "nc", "16-bit-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_fracth, "hh", "nc", "16-bit-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_classh, "bhi", "nc", "16-bit-insts")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime")
|
||||
TARGET_BUILTIN(__builtin_amdgcn_mov_dpp, "iiIiIiIiIb", "nc", "dpp")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// GFX9+ only builtins.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Special builtins.
|
||||
|
@ -64,24 +64,10 @@ BUILTIN(__nvvm_read_ptx_sreg_pm3, "i", "n")
|
||||
|
||||
// MISC
|
||||
|
||||
BUILTIN(__nvvm_clz_i, "ii", "")
|
||||
BUILTIN(__nvvm_clz_ll, "iLLi", "")
|
||||
BUILTIN(__nvvm_popc_i, "ii", "")
|
||||
BUILTIN(__nvvm_popc_ll, "iLLi", "")
|
||||
BUILTIN(__nvvm_prmt, "UiUiUiUi", "")
|
||||
|
||||
// Min Max
|
||||
|
||||
BUILTIN(__nvvm_min_i, "iii", "")
|
||||
BUILTIN(__nvvm_min_ui, "UiUiUi", "")
|
||||
BUILTIN(__nvvm_min_ll, "LLiLLiLLi", "")
|
||||
BUILTIN(__nvvm_min_ull, "ULLiULLiULLi", "")
|
||||
|
||||
BUILTIN(__nvvm_max_i, "iii", "")
|
||||
BUILTIN(__nvvm_max_ui, "UiUiUi", "")
|
||||
BUILTIN(__nvvm_max_ll, "LLiLLiLLi", "")
|
||||
BUILTIN(__nvvm_max_ull, "ULLiULLiULLi", "")
|
||||
|
||||
BUILTIN(__nvvm_fmax_ftz_f, "fff", "")
|
||||
BUILTIN(__nvvm_fmax_f, "fff", "")
|
||||
BUILTIN(__nvvm_fmin_ftz_f, "fff", "")
|
||||
@ -133,11 +119,6 @@ BUILTIN(__nvvm_div_rz_d, "ddd", "")
|
||||
BUILTIN(__nvvm_div_rm_d, "ddd", "")
|
||||
BUILTIN(__nvvm_div_rp_d, "ddd", "")
|
||||
|
||||
// Brev
|
||||
|
||||
BUILTIN(__nvvm_brev32, "UiUi", "")
|
||||
BUILTIN(__nvvm_brev64, "ULLiULLi", "")
|
||||
|
||||
// Sad
|
||||
|
||||
BUILTIN(__nvvm_sad_i, "iiii", "")
|
||||
@ -155,9 +136,6 @@ BUILTIN(__nvvm_ceil_d, "dd", "")
|
||||
|
||||
// Abs
|
||||
|
||||
BUILTIN(__nvvm_abs_i, "ii", "")
|
||||
BUILTIN(__nvvm_abs_ll, "LLiLLi", "")
|
||||
|
||||
BUILTIN(__nvvm_fabs_ftz_f, "ff", "")
|
||||
BUILTIN(__nvvm_fabs_f, "ff", "")
|
||||
BUILTIN(__nvvm_fabs_d, "dd", "")
|
||||
@ -385,8 +363,6 @@ BUILTIN(__nvvm_ull2d_rp, "dULLi", "")
|
||||
BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "")
|
||||
BUILTIN(__nvvm_f2h_rn, "Usf", "")
|
||||
|
||||
BUILTIN(__nvvm_h2f, "fUs", "")
|
||||
|
||||
// Bitcast
|
||||
|
||||
BUILTIN(__nvvm_bitcast_f2i, "if", "")
|
||||
|
@ -16,9 +16,9 @@
|
||||
|
||||
// The format of this database matches clang/Basic/Builtins.def.
|
||||
|
||||
// Note that current_memory is not "c" (readnone) because it must be sequenced with
|
||||
// respect to grow_memory calls.
|
||||
// Note that current_memory is not "c" (readnone) because it must be sequenced
|
||||
// with respect to grow_memory calls.
|
||||
BUILTIN(__builtin_wasm_current_memory, "z", "n")
|
||||
BUILTIN(__builtin_wasm_grow_memory, "vz", "n")
|
||||
BUILTIN(__builtin_wasm_grow_memory, "zz", "n")
|
||||
|
||||
#undef BUILTIN
|
||||
|
@ -391,7 +391,6 @@ TARGET_BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2dIi", "", "sse4.1")
|
||||
TARGET_BUILTIN(__builtin_ia32_roundpd, "V2dV2dIi", "", "sse4.1")
|
||||
TARGET_BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fIc", "", "sse4.1")
|
||||
TARGET_BUILTIN(__builtin_ia32_dppd, "V2dV2dV2dIc", "", "sse4.1")
|
||||
TARGET_BUILTIN(__builtin_ia32_movntdqa, "V2LLiV2LLiC*", "", "sse4.1")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "", "sse4.1")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "", "sse4.1")
|
||||
TARGET_BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "", "sse4.1")
|
||||
@ -576,7 +575,6 @@ TARGET_BUILTIN(__builtin_ia32_psrldi256, "V8iV8ii", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_psrld256, "V8iV8iV4i", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_psrlqi256, "V4LLiV4LLii", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_psrlq256, "V4LLiV4LLiV2LLi", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_movntdqa256, "V4LLiV4LLiC*", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8i", "", "avx2")
|
||||
TARGET_BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIc", "", "avx2")
|
||||
@ -832,8 +830,6 @@ TARGET_BUILTIN(__builtin_ia32_vphaddudq, "V2LLiV4i", "", "xop")
|
||||
TARGET_BUILTIN(__builtin_ia32_vphsubbw, "V8sV16c", "", "xop")
|
||||
TARGET_BUILTIN(__builtin_ia32_vphsubwd, "V4iV8s", "", "xop")
|
||||
TARGET_BUILTIN(__builtin_ia32_vphsubdq, "V2LLiV4i", "", "xop")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpcmov, "V2LLiV2LLiV2LLiV2LLi", "", "xop")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpcmov_256, "V4LLiV4LLiV4LLiV4LLi", "", "xop")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpperm, "V16cV16cV16cV16c", "", "xop")
|
||||
TARGET_BUILTIN(__builtin_ia32_vprotb, "V16cV16cV16c", "", "xop")
|
||||
TARGET_BUILTIN(__builtin_ia32_vprotw, "V8sV8sV8s", "", "xop")
|
||||
@ -997,22 +993,22 @@ TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "",
|
||||
TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_mask, "V16fV16iV16fV16fUs", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_mask, "V8dV8LLiV8dV8dUc", "", "avx512f")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUci","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLiLLiC*V2LLiUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLiLLiC*V4LLiUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLiLLiC*V4iUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLiLLiC*V4iUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUcIi","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8ddC*V8iUcIi", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16ffC*V16fUsIi", "", "avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8ddC*V8LLiUcIi", "", "avx512f")
|
||||
@ -1068,10 +1064,10 @@ TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "", "avx512bw")
|
||||
|
||||
TARGET_BUILTIN(__builtin_ia32_pabsb512_mask, "V64cV64cV64cULLi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pabsw512_mask, "V32sV32sV32sUi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_packssdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_packsswb512_mask, "V64cV32sV32sV64cULLi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_packusdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_packuswb512_mask, "V64cV32sV32sV64cULLi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_packssdw512, "V32sV16iV16i", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_packsswb512, "V64cV32sV32s", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_packusdw512, "V32sV16iV16i", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_packuswb512, "V64cV32sV32s", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw")
|
||||
@ -1590,27 +1586,15 @@ TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmb512, "V8LLiUc","","avx512cd")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmw512, "V16iUs","","avx512cd")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastf32x4_512, "V16fV4fV16fUs","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastf64x4_512, "V8dV4dV8dUc","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti32x4_512, "V16iV4iV16iUs","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti64x4_512, "V8LLiV4LLiV8LLiUc","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmb128, "V2LLiUc","","avx512cd,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmb256, "V4LLiUc","","avx512cd,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmw128, "V4iUs","","avx512cd,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastmw256, "V8iUs","","avx512cd,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_512_mask, "V16fV4fV16fUs","","avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastf32x8_512_mask, "V16fV8fV16fUs","","avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastf64x2_512_mask, "V8dV2dV8dUc","","avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_512_mask, "V16iV4iV16iUs","","avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti32x8_512_mask, "V16iV8iV16iUs","","avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti64x2_512_mask, "V8LLiV2LLiV8LLiUc","","avx512dq")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_256_mask, "V8fV4fV8fUc","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastf64x2_256_mask, "V4dV2dV4dUc","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_128_mask, "V4iV4iV4iUc","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_256_mask, "V8iV4iV8iUc","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti64x2_256_mask, "V4LLiV2LLiV4LLiUc","","avx512dq,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcastf32x4_256_mask, "V8fV4fV8fUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_broadcasti32x4_256_mask, "V8iV4iV8iUc","","avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pbroadcastw512_gpr_mask, "V32shV32sUi","","avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_pbroadcastw256_gpr_mask, "V16shV16sUs","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_pbroadcastw128_gpr_mask, "V8ssV8sUc","","avx512bw,avx512vl")
|
||||
@ -1761,7 +1745,6 @@ TARGET_BUILTIN(__builtin_ia32_kortestzhi, "iUsUs","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kunpckhi, "UsUsUs","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_movntdqa512, "V8LLiV8LLi*","","avx512f")
|
||||
TARGET_BUILTIN(__builtin_ia32_palignr512_mask, "V64cV64cV64cIiV64cULLi","","avx512bw")
|
||||
TARGET_BUILTIN(__builtin_ia32_dbpsadbw128_mask, "V8sV16cV16cIiV8sUc","","avx512bw,avx512vl")
|
||||
TARGET_BUILTIN(__builtin_ia32_dbpsadbw256_mask, "V16sV32cV32cIiV16sUs","","avx512bw,avx512vl")
|
||||
@ -1826,6 +1809,9 @@ TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "", "")
|
||||
TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx")
|
||||
TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx")
|
||||
|
||||
// CLZERO
|
||||
TARGET_BUILTIN(__builtin_ia32_clzero, "vv*", "", "clzero")
|
||||
|
||||
// MSVC
|
||||
TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
@ -1840,6 +1826,18 @@ TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nh", "intrin.h", ALL_MS_LANGUAGES, "
|
||||
TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(__int2c, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(__ud2, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(__readfsbyte, "UcULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(__readfsword, "UsULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(__readfsdword, "ULiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(__readfsqword, "ULLiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
TARGET_HEADER_BUILTIN(__readgsbyte, "UcULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(__readgsword, "UsULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(__readgsdword, "ULiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(__readgsqword, "ULLiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
#undef BUILTIN
|
||||
#undef TARGET_BUILTIN
|
||||
|
@ -45,6 +45,7 @@ def Named : Decl<1>;
|
||||
def ObjCAtDefsField : DDecl<Field>;
|
||||
def MSProperty : DDecl<Declarator>;
|
||||
def Function : DDecl<Declarator>, DeclContext;
|
||||
def CXXDeductionGuide : DDecl<Function>;
|
||||
def CXXMethod : DDecl<Function>;
|
||||
def CXXConstructor : DDecl<CXXMethod>;
|
||||
def CXXDestructor : DDecl<CXXMethod>;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
@ -222,6 +223,9 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
|
||||
void setMapping(diag::kind Diag, DiagnosticMapping Info) {
|
||||
DiagMap[Diag] = Info;
|
||||
}
|
||||
DiagnosticMapping lookupMapping(diag::kind Diag) const {
|
||||
return DiagMap.lookup(Diag);
|
||||
}
|
||||
|
||||
DiagnosticMapping &getOrAddMapping(diag::kind Diag);
|
||||
|
||||
@ -232,59 +236,97 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
|
||||
/// \brief Keeps and automatically disposes all DiagStates that we create.
|
||||
std::list<DiagState> DiagStates;
|
||||
|
||||
/// \brief Represents a point in source where the diagnostic state was
|
||||
/// modified because of a pragma.
|
||||
///
|
||||
/// 'Loc' can be null if the point represents the diagnostic state
|
||||
/// modifications done through the command-line.
|
||||
struct DiagStatePoint {
|
||||
DiagState *State;
|
||||
FullSourceLoc Loc;
|
||||
DiagStatePoint(DiagState *State, FullSourceLoc Loc)
|
||||
: State(State), Loc(Loc) { }
|
||||
|
||||
bool operator<(const DiagStatePoint &RHS) const {
|
||||
// If Loc is invalid it means it came from <command-line>, in which case
|
||||
// we regard it as coming before any valid source location.
|
||||
if (RHS.Loc.isInvalid())
|
||||
return false;
|
||||
if (Loc.isInvalid())
|
||||
return true;
|
||||
return Loc.isBeforeInTranslationUnitThan(RHS.Loc);
|
||||
/// A mapping from files to the diagnostic states for those files. Lazily
|
||||
/// built on demand for files in which the diagnostic state has not changed.
|
||||
class DiagStateMap {
|
||||
public:
|
||||
/// Add an initial diagnostic state.
|
||||
void appendFirst(DiagState *State);
|
||||
/// Add a new latest state point.
|
||||
void append(SourceManager &SrcMgr, SourceLocation Loc, DiagState *State);
|
||||
/// Look up the diagnostic state at a given source location.
|
||||
DiagState *lookup(SourceManager &SrcMgr, SourceLocation Loc) const;
|
||||
/// Determine whether this map is empty.
|
||||
bool empty() const { return Files.empty(); }
|
||||
/// Clear out this map.
|
||||
void clear() {
|
||||
Files.clear();
|
||||
FirstDiagState = CurDiagState = nullptr;
|
||||
CurDiagStateLoc = SourceLocation();
|
||||
}
|
||||
|
||||
/// Grab the most-recently-added state point.
|
||||
DiagState *getCurDiagState() const { return CurDiagState; }
|
||||
/// Get the location at which a diagnostic state was last added.
|
||||
SourceLocation getCurDiagStateLoc() const { return CurDiagStateLoc; }
|
||||
|
||||
private:
|
||||
/// \brief Represents a point in source where the diagnostic state was
|
||||
/// modified because of a pragma.
|
||||
///
|
||||
/// 'Loc' can be null if the point represents the diagnostic state
|
||||
/// modifications done through the command-line.
|
||||
struct DiagStatePoint {
|
||||
DiagState *State;
|
||||
unsigned Offset;
|
||||
DiagStatePoint(DiagState *State, unsigned Offset)
|
||||
: State(State), Offset(Offset) { }
|
||||
};
|
||||
|
||||
/// Description of the diagnostic states and state transitions for a
|
||||
/// particular FileID.
|
||||
struct File {
|
||||
/// The diagnostic state for the parent file. This is strictly redundant,
|
||||
/// as looking up the DecomposedIncludedLoc for the FileID in the Files
|
||||
/// map would give us this, but we cache it here for performance.
|
||||
File *Parent = nullptr;
|
||||
/// The offset of this file within its parent.
|
||||
unsigned ParentOffset = 0;
|
||||
/// Whether this file has any local (not imported from an AST file)
|
||||
/// diagnostic state transitions.
|
||||
bool HasLocalTransitions = false;
|
||||
/// The points within the file where the state changes. There will always
|
||||
/// be at least one of these (the state on entry to the file).
|
||||
llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
|
||||
|
||||
DiagState *lookup(unsigned Offset) const;
|
||||
};
|
||||
|
||||
/// The diagnostic states for each file.
|
||||
mutable std::map<FileID, File> Files;
|
||||
|
||||
/// The initial diagnostic state.
|
||||
DiagState *FirstDiagState;
|
||||
/// The current diagnostic state.
|
||||
DiagState *CurDiagState;
|
||||
/// The location at which the current diagnostic state was established.
|
||||
SourceLocation CurDiagStateLoc;
|
||||
|
||||
/// Get the diagnostic state information for a file.
|
||||
File *getFile(SourceManager &SrcMgr, FileID ID) const;
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTWriter;
|
||||
};
|
||||
|
||||
/// \brief A sorted vector of all DiagStatePoints representing changes in
|
||||
/// diagnostic state due to diagnostic pragmas.
|
||||
///
|
||||
/// The vector is always sorted according to the SourceLocation of the
|
||||
/// DiagStatePoint.
|
||||
typedef std::vector<DiagStatePoint> DiagStatePointsTy;
|
||||
mutable DiagStatePointsTy DiagStatePoints;
|
||||
DiagStateMap DiagStatesByLoc;
|
||||
|
||||
/// \brief Keeps the DiagState that was active during each diagnostic 'push'
|
||||
/// so we can get back at it when we 'pop'.
|
||||
std::vector<DiagState *> DiagStateOnPushStack;
|
||||
|
||||
DiagState *GetCurDiagState() const {
|
||||
assert(!DiagStatePoints.empty());
|
||||
return DiagStatePoints.back().State;
|
||||
return DiagStatesByLoc.getCurDiagState();
|
||||
}
|
||||
|
||||
void PushDiagStatePoint(DiagState *State, SourceLocation L) {
|
||||
FullSourceLoc Loc(L, getSourceManager());
|
||||
// Make sure that DiagStatePoints is always sorted according to Loc.
|
||||
assert(Loc.isValid() && "Adding invalid loc point");
|
||||
assert(!DiagStatePoints.empty() &&
|
||||
(DiagStatePoints.back().Loc.isInvalid() ||
|
||||
DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) &&
|
||||
"Previous point loc comes after or is the same as new one");
|
||||
DiagStatePoints.push_back(DiagStatePoint(State, Loc));
|
||||
}
|
||||
void PushDiagStatePoint(DiagState *State, SourceLocation L);
|
||||
|
||||
/// \brief Finds the DiagStatePoint that contains the diagnostic state of
|
||||
/// the given source location.
|
||||
DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const;
|
||||
DiagState *GetDiagStateForLoc(SourceLocation Loc) const {
|
||||
return SourceMgr ? DiagStatesByLoc.lookup(*SourceMgr, Loc)
|
||||
: DiagStatesByLoc.getCurDiagState();
|
||||
}
|
||||
|
||||
/// \brief Sticky flag set to \c true when an error is emitted.
|
||||
bool ErrorOccurred;
|
||||
@ -390,7 +432,11 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
|
||||
assert(SourceMgr && "SourceManager not set!");
|
||||
return *SourceMgr;
|
||||
}
|
||||
void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; }
|
||||
void setSourceManager(SourceManager *SrcMgr) {
|
||||
assert(DiagStatesByLoc.empty() &&
|
||||
"Leftover diag state from a different SourceManager.");
|
||||
SourceMgr = SrcMgr;
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// DiagnosticsEngine characterization methods, used by a client to customize
|
||||
|
@ -44,7 +44,8 @@ def note_constexpr_non_global : Note<
|
||||
def note_constexpr_uninitialized : Note<
|
||||
"%select{|sub}0object of type %1 is not initialized">;
|
||||
def note_constexpr_array_index : Note<"cannot refer to element %0 of "
|
||||
"%select{array of %2 elements|non-array object}1 in a constant expression">;
|
||||
"%select{array of %2 element%plural{1:|:s}2|non-array object}1 "
|
||||
"in a constant expression">;
|
||||
def note_constexpr_float_arithmetic : Note<
|
||||
"floating point arithmetic produces %select{an infinity|a NaN}0">;
|
||||
def note_constexpr_pointer_subtraction_not_same_array : Note<
|
||||
|
@ -45,7 +45,9 @@ def err_expected_colon_after_setter_name : Error<
|
||||
"must end with ':'">;
|
||||
def err_expected_string_literal : Error<"expected string literal "
|
||||
"%select{in %1|for diagnostic message in static_assert|"
|
||||
"for optional message in 'availability' attribute}0">;
|
||||
"for optional message in 'availability' attribute|"
|
||||
"for %select{language|source container}1 name in "
|
||||
"'external_source_symbol' attribute}0">;
|
||||
def err_invalid_string_udl : Error<
|
||||
"string literal with user-defined suffix cannot be used here">;
|
||||
def err_invalid_character_udl : Error<
|
||||
@ -88,10 +90,10 @@ def err_module_unavailable : Error<
|
||||
"module '%0' %select{is incompatible with|requires}1 feature '%2'">;
|
||||
def err_module_header_missing : Error<
|
||||
"%select{|umbrella }0header '%1' not found">;
|
||||
def err_module_lock_failure : Error<
|
||||
"could not acquire lock file for module '%0': %1">, DefaultFatal;
|
||||
def err_module_lock_timeout : Error<
|
||||
"timed out waiting to acquire lock file for module '%0'">, DefaultFatal;
|
||||
def remark_module_lock_failure : Remark<
|
||||
"could not acquire lock file for module '%0': %1">, InGroup<ModuleBuild>;
|
||||
def remark_module_lock_timeout : Remark<
|
||||
"timed out waiting to acquire lock file for module '%0'">, InGroup<ModuleBuild>;
|
||||
def err_module_cycle : Error<"cyclic dependency in module '%0': %1">,
|
||||
DefaultFatal;
|
||||
def err_module_prebuilt : Error<
|
||||
|
@ -85,6 +85,8 @@ def err_drv_clang_unsupported : Error<
|
||||
"the clang compiler does not support '%0'">;
|
||||
def err_drv_clang_unsupported_opt_cxx_darwin_i386 : Error<
|
||||
"the clang compiler does not support '%0' for C++ on Darwin/i386">;
|
||||
def err_drv_clang_unsupported_opt_faltivec : Error<
|
||||
"the clang compiler does not support '%0', %1">;
|
||||
def err_drv_command_failed : Error<
|
||||
"%0 command failed with exit code %1 (use -v to see invocation)">;
|
||||
def err_drv_compilationdatabase : Error<
|
||||
@ -92,7 +94,7 @@ def err_drv_compilationdatabase : Error<
|
||||
def err_drv_command_signalled : Error<
|
||||
"%0 command failed due to signal (use -v to see invocation)">;
|
||||
def err_drv_force_crash : Error<
|
||||
"failing because environment variable '%0' is set">;
|
||||
"failing because %select{environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set|'-gen-reproducer' is used}0">;
|
||||
def err_drv_invalid_mfloat_abi : Error<
|
||||
"invalid float ABI '%0'">;
|
||||
def err_drv_invalid_libcxx_deployment : Error<
|
||||
@ -133,6 +135,7 @@ def err_drv_invalid_gcc_output_type : Error<
|
||||
"invalid output type '%0' for use with gcc tool">;
|
||||
def err_drv_cc_print_options_failure : Error<
|
||||
"unable to open CC_PRINT_OPTIONS file: %0">;
|
||||
def err_drv_lto_without_lld : Error<"LTO requires -fuse-ld=lld">;
|
||||
def err_drv_preamble_format : Error<
|
||||
"incorrect format for -preamble-bytes=N,END">;
|
||||
def err_drv_conflicting_deployment_targets : Error<
|
||||
@ -230,6 +233,7 @@ def note_drv_t_option_is_global : Note<
|
||||
"The last /TC or /TP option takes precedence over earlier instances">;
|
||||
def note_drv_address_sanitizer_debug_runtime : Note<
|
||||
"AddressSanitizer doesn't support linking with debug runtime libraries yet">;
|
||||
def note_drv_use_standard : Note<"use '%0' for '%1' standard">;
|
||||
|
||||
def err_analyzer_config_no_value : Error<
|
||||
"analyzer-config option '%0' has a key but no value">;
|
||||
@ -247,6 +251,10 @@ def err_test_module_file_extension_format : Error<
|
||||
def warn_drv_invoking_fallback : Warning<"falling back to %0">,
|
||||
InGroup<Fallback>;
|
||||
|
||||
def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">,
|
||||
InGroup<DiagGroup<"slash-u-filename">>;
|
||||
def note_use_dashdash : Note<"Use '--' to treat subsequent arguments as filenames">;
|
||||
|
||||
def err_drv_ropi_rwpi_incompatible_with_pic : Error<
|
||||
"embedded and GOT-based position independence are incompatible">;
|
||||
def err_drv_ropi_incompatible_with_cxx : Error<
|
||||
@ -277,4 +285,8 @@ def warn_drv_ps4_sdk_dir : Warning<
|
||||
def err_drv_unsupported_linker : Error<"unsupported value '%0' for -linker option">;
|
||||
def err_drv_defsym_invalid_format : Error<"defsym must be of the form: sym=value: %0">;
|
||||
def err_drv_defsym_invalid_symval : Error<"Value is not an integer: %0">;
|
||||
def warn_drv_msvc_not_found : Warning<
|
||||
"unable to find a Visual Studio installation; "
|
||||
"try running Clang from a developer command prompt">,
|
||||
InGroup<DiagGroup<"msvc-not-found">>;
|
||||
}
|
||||
|
@ -34,7 +34,9 @@ def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">;
|
||||
def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">;
|
||||
def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">;
|
||||
def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">;
|
||||
def BitFieldEnumConversion : DiagGroup<"bitfield-enum-conversion">;
|
||||
def BitFieldWidth : DiagGroup<"bitfield-width">;
|
||||
def Coroutine : DiagGroup<"coroutine">;
|
||||
def ConstantConversion :
|
||||
DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >;
|
||||
def LiteralConversion : DiagGroup<"literal-conversion">;
|
||||
@ -175,6 +177,8 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
|
||||
|
||||
def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
|
||||
|
||||
def CXX11WarnOverrideDestructor :
|
||||
DiagGroup<"inconsistent-missing-destructor-override">;
|
||||
def CXX11WarnOverrideMethod : DiagGroup<"inconsistent-missing-override">;
|
||||
|
||||
// Original name of this warning in Clang
|
||||
@ -355,6 +359,7 @@ def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
|
||||
def Sentinel : DiagGroup<"sentinel">;
|
||||
def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
|
||||
|
||||
def ShadowField : DiagGroup<"shadow-field">;
|
||||
def ShadowFieldInConstructorModified : DiagGroup<"shadow-field-in-constructor-modified">;
|
||||
def ShadowFieldInConstructor : DiagGroup<"shadow-field-in-constructor",
|
||||
[ShadowFieldInConstructorModified]>;
|
||||
@ -366,7 +371,7 @@ def ShadowUncapturedLocal : DiagGroup<"shadow-uncaptured-local">;
|
||||
def Shadow : DiagGroup<"shadow", [ShadowFieldInConstructorModified,
|
||||
ShadowIvar]>;
|
||||
def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor,
|
||||
ShadowUncapturedLocal]>;
|
||||
ShadowUncapturedLocal, ShadowField]>;
|
||||
|
||||
def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
|
||||
def : DiagGroup<"sign-promo">;
|
||||
@ -480,6 +485,7 @@ def UnusedFunction : DiagGroup<"unused-function", [UnneededInternalDecl]>;
|
||||
def UnusedMemberFunction : DiagGroup<"unused-member-function",
|
||||
[UnneededMemberFunction]>;
|
||||
def UnusedLabel : DiagGroup<"unused-label">;
|
||||
def UnusedLambdaCapture : DiagGroup<"unused-lambda-capture">;
|
||||
def UnusedParameter : DiagGroup<"unused-parameter">;
|
||||
def UnusedResult : DiagGroup<"unused-result">;
|
||||
def PotentiallyEvaluatedExpression : DiagGroup<"potentially-evaluated-expression">;
|
||||
@ -602,6 +608,7 @@ def Conversion : DiagGroup<"conversion",
|
||||
[BoolConversion,
|
||||
ConstantConversion,
|
||||
EnumConversion,
|
||||
BitFieldEnumConversion,
|
||||
FloatConversion,
|
||||
Shorten64To32,
|
||||
IntConversion,
|
||||
@ -617,8 +624,9 @@ def Unused : DiagGroup<"unused",
|
||||
[UnusedArgument, UnusedFunction, UnusedLabel,
|
||||
// UnusedParameter, (matches GCC's behavior)
|
||||
// UnusedMemberFunction, (clean-up llvm before enabling)
|
||||
UnusedPrivateField, UnusedLocalTypedef,
|
||||
UnusedValue, UnusedVariable, UnusedPropertyIvar]>,
|
||||
UnusedPrivateField, UnusedLambdaCapture,
|
||||
UnusedLocalTypedef, UnusedValue, UnusedVariable,
|
||||
UnusedPropertyIvar]>,
|
||||
DiagCategory<"Unused Entity Issue">;
|
||||
|
||||
// Format settings.
|
||||
@ -881,7 +889,7 @@ def BackendOptimizationFailure : DiagGroup<"pass-failed">;
|
||||
def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
|
||||
def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
|
||||
|
||||
// AddressSanitizer frontent instrumentation remarks.
|
||||
// AddressSanitizer frontend instrumentation remarks.
|
||||
def SanitizeAddressRemarks : DiagGroup<"sanitize-address">;
|
||||
|
||||
// Issues with serialized diagnostics.
|
||||
|
@ -84,6 +84,7 @@ class DiagnosticMapping {
|
||||
unsigned IsPragma : 1;
|
||||
unsigned HasNoWarningAsError : 1;
|
||||
unsigned HasNoErrorAsFatal : 1;
|
||||
unsigned WasUpgradedFromWarning : 1;
|
||||
|
||||
public:
|
||||
static DiagnosticMapping Make(diag::Severity Severity, bool IsUser,
|
||||
@ -94,6 +95,7 @@ class DiagnosticMapping {
|
||||
Result.IsPragma = IsPragma;
|
||||
Result.HasNoWarningAsError = 0;
|
||||
Result.HasNoErrorAsFatal = 0;
|
||||
Result.WasUpgradedFromWarning = 0;
|
||||
return Result;
|
||||
}
|
||||
|
||||
@ -103,11 +105,33 @@ class DiagnosticMapping {
|
||||
bool isUser() const { return IsUser; }
|
||||
bool isPragma() const { return IsPragma; }
|
||||
|
||||
bool isErrorOrFatal() const {
|
||||
return getSeverity() == diag::Severity::Error ||
|
||||
getSeverity() == diag::Severity::Fatal;
|
||||
}
|
||||
|
||||
bool hasNoWarningAsError() const { return HasNoWarningAsError; }
|
||||
void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; }
|
||||
|
||||
bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; }
|
||||
void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; }
|
||||
|
||||
/// Whether this mapping attempted to map the diagnostic to a warning, but
|
||||
/// was overruled because the diagnostic was already mapped to an error or
|
||||
/// fatal error.
|
||||
bool wasUpgradedFromWarning() const { return WasUpgradedFromWarning; }
|
||||
void setUpgradedFromWarning(bool Value) { WasUpgradedFromWarning = Value; }
|
||||
|
||||
/// Serialize the bits that aren't based on context.
|
||||
unsigned serializeBits() const {
|
||||
return (WasUpgradedFromWarning << 3) | Severity;
|
||||
}
|
||||
static diag::Severity deserializeSeverity(unsigned Bits) {
|
||||
return (diag::Severity)(Bits & 0x7);
|
||||
}
|
||||
static bool deserializeUpgradedFromWarning(unsigned Bits) {
|
||||
return Bits >> 3;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Used for handling and querying diagnostic IDs.
|
||||
|
@ -176,6 +176,9 @@ def warn_gcc_attribute_location : Warning<
|
||||
def warn_attribute_no_decl : Warning<
|
||||
"attribute %0 ignored, because it is not attached to a declaration">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
def err_ms_attributes_not_enabled : Error<
|
||||
"'__declspec' attributes are not enabled; use '-fdeclspec' or "
|
||||
"'-fms-extensions' to enable support for __declspec attributes">;
|
||||
def err_expected_method_body : Error<"expected method body">;
|
||||
def err_declspec_after_virtspec : Error<
|
||||
"'%0' qualifier may not appear after the virtual specifier '%1'">;
|
||||
@ -361,8 +364,6 @@ def ext_decomp_decl_empty : ExtWarn<
|
||||
/// Objective-C parser diagnostics
|
||||
def err_expected_minus_or_plus : Error<
|
||||
"method type specifier must start with '-' or '+'">;
|
||||
def err_objc_no_attributes_on_category : Error<
|
||||
"attributes may not be specified on a category">;
|
||||
def err_objc_missing_end : Error<"missing '@end'">;
|
||||
def note_objc_container_start : Note<
|
||||
"%select{class|protocol|category|class extension|implementation"
|
||||
@ -435,6 +436,13 @@ def err_declaration_does_not_declare_param : Error<
|
||||
"declaration does not declare a parameter">;
|
||||
def err_no_matching_param : Error<"parameter named %0 is missing">;
|
||||
|
||||
/// Objective-C++ parser diagnostics
|
||||
def err_expected_token_instead_of_objcxx_keyword : Error<
|
||||
"expected %0; %1 is a keyword in Objective-C++">;
|
||||
def err_expected_member_name_or_semi_objcxx_keyword : Error<
|
||||
"expected member name or ';' after declaration specifiers; "
|
||||
"%0 is a keyword in Objective-C++">;
|
||||
|
||||
/// C++ parser diagnostics
|
||||
def err_invalid_operator_on_type : Error<
|
||||
"cannot use %select{dot|arrow}0 operator on a type">;
|
||||
@ -669,9 +677,6 @@ def warn_static_inline_explicit_inst_ignored : Warning<
|
||||
// Constructor template diagnostics.
|
||||
def err_out_of_line_constructor_template_id : Error<
|
||||
"out-of-line constructor for %0 cannot have template arguments">;
|
||||
def err_out_of_line_template_id_type_names_constructor : Error<
|
||||
"qualified reference to %0 is a constructor name rather than a "
|
||||
"%select{template name|type}1 wherever a constructor can be declared">;
|
||||
|
||||
def err_expected_qualified_after_typename : Error<
|
||||
"expected a qualified name after 'typename'">;
|
||||
@ -859,6 +864,12 @@ def err_availability_query_repeated_platform: Error<
|
||||
def err_availability_query_repeated_star : Error<
|
||||
"'*' query has already been specified">;
|
||||
|
||||
// External source symbol attribute
|
||||
def err_external_source_symbol_expected_keyword : Error<
|
||||
"expected 'language', 'defined_in', or 'generated_declaration'">;
|
||||
def err_external_source_symbol_duplicate_clause : Error<
|
||||
"duplicate %0 clause in an 'external_source_symbol' attribute">;
|
||||
|
||||
// Type safety attributes
|
||||
def err_type_safety_unknown_flag : Error<
|
||||
"invalid comparison flag %0; use 'layout_compatible' or 'must_be_null'">;
|
||||
@ -1036,6 +1047,16 @@ def err_pragma_loop_missing_argument : Error<
|
||||
def err_pragma_loop_invalid_option : Error<
|
||||
"%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
|
||||
"vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute">;
|
||||
|
||||
def err_pragma_fp_invalid_option : Error<
|
||||
"%select{invalid|missing}0 option%select{ %1|}0; expected contract">;
|
||||
def err_pragma_fp_invalid_argument : Error<
|
||||
"unexpected argument '%0' to '#pragma clang fp %1'; "
|
||||
"expected 'on', 'fast' or 'off'">;
|
||||
def err_pragma_fp_scope : Error<
|
||||
"'#pragma clang fp' can only appear at file scope or at the start of a "
|
||||
"compound statement">;
|
||||
|
||||
def err_pragma_invalid_keyword : Error<
|
||||
"invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">;
|
||||
|
||||
|
@ -259,6 +259,9 @@ def err_anyx86_interrupt_attribute : Error<
|
||||
"a pointer as the first parameter|a %2 type as the second parameter}1">;
|
||||
def err_anyx86_interrupt_called : Error<
|
||||
"interrupt service routine cannot be called directly">;
|
||||
def warn_arm_interrupt_calling_convention : Warning<
|
||||
"call to function without interrupt attribute could clobber interruptee's VFP registers">,
|
||||
InGroup<Extra>;
|
||||
def warn_mips_interrupt_attribute : Warning<
|
||||
"MIPS 'interrupt' attribute only applies to functions that have "
|
||||
"%select{no parameters|a 'void' return type}0">,
|
||||
@ -316,6 +319,9 @@ def warn_unneeded_member_function : Warning<
|
||||
InGroup<UnneededMemberFunction>, DefaultIgnore;
|
||||
def warn_unused_private_field: Warning<"private field %0 is not used">,
|
||||
InGroup<UnusedPrivateField>, DefaultIgnore;
|
||||
def warn_unused_lambda_capture: Warning<"lambda capture %0 is not "
|
||||
"%select{used|required to be captured for this use}1">,
|
||||
InGroup<UnusedLambdaCapture>, DefaultIgnore;
|
||||
|
||||
def warn_parameter_size: Warning<
|
||||
"%0 is a large (%1 bytes) pass-by-value argument; "
|
||||
@ -363,7 +369,9 @@ def warn_decl_shadow :
|
||||
"local variable|"
|
||||
"variable in %2|"
|
||||
"static data member of %2|"
|
||||
"field of %2}1">,
|
||||
"field of %2|"
|
||||
"typedef in %2|"
|
||||
"type alias in %2}1">,
|
||||
InGroup<Shadow>, DefaultIgnore;
|
||||
def warn_decl_shadow_uncaptured_local :
|
||||
Warning<warn_decl_shadow.Text>,
|
||||
@ -1201,8 +1209,9 @@ def warn_cxx98_compat_unelaborated_friend_type : Warning<
|
||||
def err_qualified_friend_not_found : Error<
|
||||
"no function named %0 with type %1 was found in the specified scope">;
|
||||
def err_introducing_special_friend : Error<
|
||||
"must use a qualified name when declaring a %select{constructor|"
|
||||
"destructor|conversion operator}0 as a friend">;
|
||||
"%plural{[0,2]:must use a qualified name when declaring|3:cannot declare}0"
|
||||
" a %select{constructor|destructor|conversion operator|deduction guide}0 "
|
||||
"as a friend">;
|
||||
def err_tagless_friend_type_template : Error<
|
||||
"friend type templates must use an elaborated type">;
|
||||
def err_no_matching_local_friend : Error<
|
||||
@ -1447,6 +1456,15 @@ def err_nested_name_spec_is_not_class : Error<
|
||||
def ext_nested_name_spec_is_enum : ExtWarn<
|
||||
"use of enumeration in a nested name specifier is a C++11 extension">,
|
||||
InGroup<CXX11>;
|
||||
def err_out_of_line_qualified_id_type_names_constructor : Error<
|
||||
"qualified reference to %0 is a constructor name rather than a "
|
||||
"%select{template name|type}1 in this context">;
|
||||
def ext_out_of_line_qualified_id_type_names_constructor : ExtWarn<
|
||||
"ISO C++ specifies that "
|
||||
"qualified reference to %0 is a constructor name rather than a "
|
||||
"%select{template name|type}1 in this context, despite preceding "
|
||||
"%select{'typename'|'template'}2 keyword">, SFINAEFailure,
|
||||
InGroup<DiagGroup<"injected-class-name">>;
|
||||
|
||||
// C++ class members
|
||||
def err_storageclass_invalid_for_member : Error<
|
||||
@ -1608,7 +1626,14 @@ def err_covariant_return_type_class_type_more_qualified : Error<
|
||||
"return type of virtual function %0 is not covariant with the return type of "
|
||||
"the function it overrides (class type %1 is more qualified than class "
|
||||
"type %2">;
|
||||
|
||||
|
||||
// C++ implicit special member functions
|
||||
def note_in_declaration_of_implicit_special_member : Note<
|
||||
"while declaring the implicit "
|
||||
"%select{default constructor|copy constructor|move constructor|"
|
||||
"copy assignment operator|move assignment operator|destructor}1"
|
||||
" for %0">;
|
||||
|
||||
// C++ constructors
|
||||
def err_constructor_cannot_be : Error<"constructor cannot be declared '%0'">;
|
||||
def err_invalid_qualified_constructor : Error<
|
||||
@ -1664,8 +1689,8 @@ def err_init_conversion_failed : Error<
|
||||
"cannot initialize %select{a variable|a parameter|return object|an "
|
||||
"exception object|a member subobject|an array element|a new value|a value|a "
|
||||
"base class|a constructor delegation|a vector element|a block element|a "
|
||||
"complex element|a lambda capture|a compound literal initializer|a "
|
||||
"related result|a parameter of CF audited function}0 "
|
||||
"block element|a complex element|a lambda capture|a compound literal "
|
||||
"initializer|a related result|a parameter of CF audited function}0 "
|
||||
"%diff{of type $ with an %select{rvalue|lvalue}2 of type $|"
|
||||
"with an %select{rvalue|lvalue}2 of incompatible type}1,3"
|
||||
"%select{|: different classes%diff{ ($ vs $)|}5,6"
|
||||
@ -1791,8 +1816,9 @@ def note_uninit_fixit_remove_cond : Note<
|
||||
"remove the %select{'%1' if its condition|condition if it}0 "
|
||||
"is always %select{false|true}2">;
|
||||
def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
|
||||
def err_list_init_in_parens : Error<"list-initializer for non-class type %0 "
|
||||
"must not be parenthesized">;
|
||||
def err_list_init_in_parens : Error<
|
||||
"cannot initialize %select{non-class|reference}0 type %1 with a "
|
||||
"parenthesized initializer list">;
|
||||
|
||||
def warn_unsequenced_mod_mod : Warning<
|
||||
"multiple unsequenced modifications to %0">, InGroup<Unsequenced>;
|
||||
@ -1833,8 +1859,8 @@ def warn_cxx98_compat_temp_copy : Warning<
|
||||
InGroup<CXX98CompatBindToTemporaryCopy>, DefaultIgnore;
|
||||
def err_selected_explicit_constructor : Error<
|
||||
"chosen constructor is explicit in copy-initialization">;
|
||||
def note_constructor_declared_here : Note<
|
||||
"constructor declared here">;
|
||||
def note_explicit_ctor_deduction_guide_here : Note<
|
||||
"explicit %select{constructor|deduction guide}0 declared here">;
|
||||
|
||||
// C++11 decltype
|
||||
def err_decltype_in_declarator : Error<
|
||||
@ -1845,8 +1871,8 @@ def warn_cxx98_compat_auto_type_specifier : Warning<
|
||||
"'auto' type specifier is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def err_auto_variable_cannot_appear_in_own_initializer : Error<
|
||||
"variable %0 declared with %select{'auto'|'decltype(auto)'|'__auto_type'}1 "
|
||||
"type cannot appear in its own initializer">;
|
||||
"variable %0 declared with deduced type %1 "
|
||||
"cannot appear in its own initializer">;
|
||||
def err_binding_cannot_appear_in_own_initializer : Error<
|
||||
"binding %0 cannot appear in the initializer of its own "
|
||||
"decomposition declaration">;
|
||||
@ -1855,20 +1881,29 @@ def err_illegal_decl_array_of_auto : Error<
|
||||
def err_new_array_of_auto : Error<
|
||||
"cannot allocate array of 'auto'">;
|
||||
def err_auto_not_allowed : Error<
|
||||
"%select{'auto'|'decltype(auto)'|'__auto_type'}0 not allowed "
|
||||
"%select{'auto'|'decltype(auto)'|'__auto_type'|"
|
||||
"use of "
|
||||
"%select{class template|function template|variable template|alias template|"
|
||||
"template template parameter|template}2 %3 requires template arguments; "
|
||||
"argument deduction}0 not allowed "
|
||||
"%select{in function prototype"
|
||||
"|in non-static struct member|in struct member"
|
||||
"|in non-static union member|in union member"
|
||||
"|in non-static class member|in interface member"
|
||||
"|in exception declaration|in template parameter|in block literal"
|
||||
"|in exception declaration|in template parameter until C++1z|in block literal"
|
||||
"|in template argument|in typedef|in type alias|in function return type"
|
||||
"|in conversion function type|here|in lambda parameter"
|
||||
"|in type allocated by 'new'|in K&R-style function parameter}1"
|
||||
"%select{|||||||| until C++1z||||||||||}1">;
|
||||
"|in type allocated by 'new'|in K&R-style function parameter"
|
||||
"|in template parameter|in friend declaration}1">;
|
||||
def err_dependent_deduced_tst : Error<
|
||||
"typename specifier refers to "
|
||||
"%select{class template|function template|variable template|alias template|"
|
||||
"template template parameter|template}0 member in %1; "
|
||||
"argument deduction not allowed here">;
|
||||
def err_auto_not_allowed_var_inst : Error<
|
||||
"'auto' variable template instantiation is not allowed">;
|
||||
def err_auto_var_requires_init : Error<
|
||||
"declaration of variable %0 with type %1 requires an initializer">;
|
||||
"declaration of variable %0 with deduced type %1 requires an initializer">;
|
||||
def err_auto_new_requires_ctor_arg : Error<
|
||||
"new expression for type %0 requires a constructor argument">;
|
||||
def err_auto_new_list_init : Error<
|
||||
@ -1898,8 +1933,13 @@ def err_auto_var_deduction_failure_from_init_list : Error<
|
||||
def err_auto_new_deduction_failure : Error<
|
||||
"new expression for type %0 has incompatible constructor argument of type %1">;
|
||||
def err_auto_different_deductions : Error<
|
||||
"'%select{auto|decltype(auto)|__auto_type}0' deduced as %1 in declaration "
|
||||
"of %2 and deduced as %3 in declaration of %4">;
|
||||
"%select{'auto'|'decltype(auto)'|'__auto_type'|template arguments}0 "
|
||||
"deduced as %1 in declaration of %2 and "
|
||||
"deduced as %3 in declaration of %4">;
|
||||
def err_auto_non_deduced_not_alone : Error<
|
||||
"%select{function with deduced return type|"
|
||||
"declaration with trailing return type}0 "
|
||||
"must be the only declaration in its group">;
|
||||
def err_implied_std_initializer_list_not_found : Error<
|
||||
"cannot deduce type of initializer list because std::initializer_list was "
|
||||
"not found; include <initializer_list>">;
|
||||
@ -1915,6 +1955,8 @@ def err_auto_bitfield : Error<
|
||||
"cannot pass bit-field as __auto_type initializer in C">;
|
||||
|
||||
// C++1y decltype(auto) type
|
||||
def err_decltype_auto_invalid : Error<
|
||||
"'decltype(auto)' not allowed here">;
|
||||
def err_decltype_auto_cannot_be_combined : Error<
|
||||
"'decltype(auto)' cannot be combined with other type specifiers">;
|
||||
def err_decltype_auto_function_declarator_not_declaration : Error<
|
||||
@ -1925,6 +1967,56 @@ def err_decltype_auto_compound_type : Error<
|
||||
def err_decltype_auto_initializer_list : Error<
|
||||
"cannot deduce 'decltype(auto)' from initializer list">;
|
||||
|
||||
// C++1z deduced class template specialization types
|
||||
def err_deduced_class_template_compound_type : Error<
|
||||
"cannot %select{form pointer to|form reference to|form array of|"
|
||||
"form function returning|use parentheses when declaring variable with}0 "
|
||||
"deduced class template specialization type">;
|
||||
def err_deduced_non_class_template_specialization_type : Error<
|
||||
"%select{<error>|function template|variable template|alias template|"
|
||||
"template template parameter|template}0 %1 requires template arguments; "
|
||||
"argument deduction only allowed for class templates">;
|
||||
def err_deduced_class_template_ctor_ambiguous : Error<
|
||||
"ambiguous deduction for template arguments of %0">;
|
||||
def err_deduced_class_template_ctor_no_viable : Error<
|
||||
"no viable constructor or deduction guide for deduction of "
|
||||
"template arguments of %0">;
|
||||
def err_deduced_class_template_incomplete : Error<
|
||||
"template %0 has no definition and no %select{|viable }1deduction guides "
|
||||
"for deduction of template arguments">;
|
||||
def err_deduced_class_template_deleted : Error<
|
||||
"class template argument deduction for %0 selected a deleted constructor">;
|
||||
def err_deduced_class_template_explicit : Error<
|
||||
"class template argument deduction for %0 selected an explicit "
|
||||
"%select{constructor|deduction guide}1 for copy-list-initialization">;
|
||||
def err_deduction_guide_no_trailing_return_type : Error<
|
||||
"deduction guide declaration without trailing return type">;
|
||||
def err_deduction_guide_bad_trailing_return_type : Error<
|
||||
"deduced type %1 of deduction guide is not %select{|written as }2"
|
||||
"a specialization of template %0">;
|
||||
def err_deduction_guide_with_complex_decl : Error<
|
||||
"cannot specify any part of a return type in the "
|
||||
"declaration of a deduction guide">;
|
||||
def err_deduction_guide_invalid_specifier : Error<
|
||||
"deduction guide cannot be declared '%0'">;
|
||||
def err_deduction_guide_name_not_class_template : Error<
|
||||
"cannot specify deduction guide for "
|
||||
"%select{<error>|function template|variable template|alias template|"
|
||||
"template template parameter|dependent template name}0 %1">;
|
||||
def err_deduction_guide_wrong_scope : Error<
|
||||
"deduction guide must be declared in the same scope as template %q0">;
|
||||
def err_deduction_guide_defines_function : Error<
|
||||
"deduction guide cannot have a function definition">;
|
||||
def err_deduction_guide_explicit_mismatch : Error<
|
||||
"deduction guide is %select{not |}0declared 'explicit' but "
|
||||
"previous declaration was%select{ not|}0">;
|
||||
def err_deduction_guide_specialized : Error<"deduction guide cannot be "
|
||||
"%select{explicitly instantiated|explicitly specialized}0">;
|
||||
def err_deduction_guide_template_not_deducible : Error<
|
||||
"deduction guide template contains "
|
||||
"%select{a template parameter|template parameters}0 that cannot be "
|
||||
"deduced">;
|
||||
|
||||
// C++1y deduced return types
|
||||
def err_auto_fn_deduction_failure : Error<
|
||||
"cannot deduce return type %0 from returned value of type %1">;
|
||||
@ -1950,6 +2042,9 @@ def override_keyword_hides_virtual_member_function : Error<
|
||||
"%select{function|functions}1">;
|
||||
def err_function_marked_override_not_overriding : Error<
|
||||
"%0 marked 'override' but does not override any member functions">;
|
||||
def warn_destructor_marked_not_override_overriding : Warning <
|
||||
"%0 overrides a destructor but is not marked 'override'">,
|
||||
InGroup<CXX11WarnOverrideDestructor>, DefaultIgnore;
|
||||
def warn_function_marked_not_override_overriding : Warning <
|
||||
"%0 overrides a member function but is not marked 'override'">,
|
||||
InGroup<CXX11WarnOverrideMethod>;
|
||||
@ -2215,6 +2310,9 @@ def err_concept_specialized : Error<
|
||||
"%select{function|variable}0 concept cannot be "
|
||||
"%select{explicitly instantiated|explicitly specialized|partially specialized}1">;
|
||||
|
||||
def err_template_different_associated_constraints : Error<
|
||||
"associated constraints differ in template redeclaration">;
|
||||
|
||||
// C++11 char16_t/char32_t
|
||||
def warn_cxx98_compat_unicode_type : Warning<
|
||||
"'%0' type specifier is incompatible with C++98">,
|
||||
@ -2261,7 +2359,7 @@ def warn_unsupported_target_attribute
|
||||
InGroup<IgnoredAttributes>;
|
||||
def err_attribute_unsupported
|
||||
: Error<"%0 attribute is not supported for this target">;
|
||||
// The err_*_attribute_argument_not_int are seperate because they're used by
|
||||
// The err_*_attribute_argument_not_int are separate because they're used by
|
||||
// VerifyIntegerConstantExpression.
|
||||
def err_aligned_attribute_argument_not_int : Error<
|
||||
"'aligned' attribute requires integer constant">;
|
||||
@ -2659,7 +2757,8 @@ def warn_attribute_wrong_decl_type : Warning<
|
||||
"|functions, methods, enums, and classes"
|
||||
"|structs, classes, variables, functions, and inline namespaces"
|
||||
"|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members"
|
||||
"|classes and enumerations}1">,
|
||||
"|classes and enumerations"
|
||||
"|named declarations}1">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
|
||||
def warn_type_attribute_wrong_type : Warning<
|
||||
@ -3132,7 +3231,8 @@ def err_attribute_regparm_invalid_number : Error<
|
||||
"'regparm' parameter must be between 0 and %0 inclusive">;
|
||||
def err_attribute_not_supported_in_lang : Error<
|
||||
"%0 attribute is not supported in %select{C|C++|Objective-C}1">;
|
||||
|
||||
def err_attribute_not_supported_on_arch
|
||||
: Error<"%0 attribute is not supported on '%1'">;
|
||||
|
||||
// Clang-Specific Attributes
|
||||
def warn_attribute_iboutlet : Warning<
|
||||
@ -3380,7 +3480,7 @@ def note_ovl_candidate_disabled_by_function_cond_attr : Note<
|
||||
def note_ovl_candidate_disabled_by_extension : Note<
|
||||
"candidate disabled due to OpenCL extension">;
|
||||
def err_addrof_function_disabled_by_enable_if_attr : Error<
|
||||
"cannot take address of function %0 becuase it has one or more "
|
||||
"cannot take address of function %0 because it has one or more "
|
||||
"non-tautological enable_if conditions">;
|
||||
def note_addrof_ovl_candidate_disabled_by_enable_if_attr : Note<
|
||||
"candidate function made ineligible by enable_if">;
|
||||
@ -3789,11 +3889,13 @@ def err_template_decl_ref : Error<
|
||||
|
||||
// C++ Template Argument Lists
|
||||
def err_template_missing_args : Error<
|
||||
"use of class template %0 requires template arguments">;
|
||||
"use of "
|
||||
"%select{class template|function template|variable template|alias template|"
|
||||
"template template parameter|template}0 %1 requires template arguments">;
|
||||
def err_template_arg_list_different_arity : Error<
|
||||
"%select{too few|too many}0 template arguments for "
|
||||
"%select{class template|function template|template template parameter"
|
||||
"|template}1 %2">;
|
||||
"%select{class template|function template|variable template|alias template|"
|
||||
"template template parameter|template}1 %2">;
|
||||
def note_template_decl_here : Note<"template is declared here">;
|
||||
def err_template_arg_must_be_type : Error<
|
||||
"template argument for template type parameter must be a type">;
|
||||
@ -4063,7 +4165,7 @@ def ext_partial_specs_not_deducible : ExtWarn<
|
||||
"%select{a template parameter|template parameters}1 that cannot be "
|
||||
"deduced; this partial specialization will never be used">,
|
||||
DefaultError, InGroup<DiagGroup<"unusable-partial-specialization">>;
|
||||
def note_partial_spec_unused_parameter : Note<
|
||||
def note_non_deducible_parameter : Note<
|
||||
"non-deducible template parameter %0">;
|
||||
def err_partial_spec_ordering_ambiguous : Error<
|
||||
"ambiguous partial specializations of %0">;
|
||||
@ -4286,6 +4388,8 @@ def note_typename_refers_here : Note<
|
||||
"referenced member %0 is declared here">;
|
||||
def err_typename_missing : Error<
|
||||
"missing 'typename' prior to dependent type name '%0%1'">;
|
||||
def err_typename_missing_template : Error<
|
||||
"missing 'typename' prior to dependent type template name '%0%1'">;
|
||||
def ext_typename_missing : ExtWarn<
|
||||
"missing 'typename' prior to dependent type name '%0%1'">,
|
||||
InGroup<DiagGroup<"typename-missing">>;
|
||||
@ -4304,7 +4408,7 @@ def err_template_kw_refers_to_non_template : Error<
|
||||
"%0 following the 'template' keyword does not refer to a template">;
|
||||
def err_template_kw_refers_to_class_template : Error<
|
||||
"'%0%1' instantiated to a class template, not a function template">;
|
||||
def note_referenced_class_template : Error<
|
||||
def note_referenced_class_template : Note<
|
||||
"class template declared here">;
|
||||
def err_template_kw_missing : Error<
|
||||
"missing 'template' keyword prior to dependent template name '%0%1'">;
|
||||
@ -4808,6 +4912,21 @@ def warn_bitfield_width_exceeds_type_width: Warning<
|
||||
def warn_anon_bitfield_width_exceeds_type_width : Warning<
|
||||
"width of anonymous bit-field (%0 bits) exceeds width of its type; value "
|
||||
"will be truncated to %1 bit%s1">, InGroup<BitFieldWidth>;
|
||||
def warn_bitfield_too_small_for_enum : Warning<
|
||||
"bit-field %0 is not wide enough to store all enumerators of %1">,
|
||||
InGroup<BitFieldEnumConversion>, DefaultIgnore;
|
||||
def note_widen_bitfield : Note<
|
||||
"widen this field to %0 bits to store all values of %1">;
|
||||
def warn_unsigned_bitfield_assigned_signed_enum : Warning<
|
||||
"assigning value of signed enum type %1 to unsigned bit-field %0; "
|
||||
"negative enumerators of enum %1 will be converted to positive values">,
|
||||
InGroup<BitFieldEnumConversion>, DefaultIgnore;
|
||||
def warn_signed_bitfield_enum_conversion : Warning<
|
||||
"signed bit-field %0 needs an extra bit to represent the largest positive "
|
||||
"enumerators of %1">,
|
||||
InGroup<BitFieldEnumConversion>, DefaultIgnore;
|
||||
def note_change_bitfield_sign : Note<
|
||||
"consider making the bitfield type %select{unsigned|signed}0">;
|
||||
|
||||
def warn_missing_braces : Warning<
|
||||
"suggest braces around initialization of subobject">,
|
||||
@ -5164,7 +5283,7 @@ def err_arc_inconsistent_property_ownership : Error<
|
||||
def warn_block_capture_autoreleasing : Warning<
|
||||
"block captures an autoreleasing out-parameter, which may result in "
|
||||
"use-after-free bugs">,
|
||||
InGroup<BlockCaptureAutoReleasing>, DefaultIgnore;
|
||||
InGroup<BlockCaptureAutoReleasing>;
|
||||
def note_declare_parameter_autoreleasing : Note<
|
||||
"declare the parameter __autoreleasing explicitly to suppress this warning">;
|
||||
def note_declare_parameter_strong : Note<
|
||||
@ -5725,8 +5844,8 @@ def err_this_static_member_func : Error<
|
||||
def err_invalid_member_use_in_static_method : Error<
|
||||
"invalid use of member %0 in static member function">;
|
||||
def err_invalid_qualified_function_type : Error<
|
||||
"%select{static |non-}0member function %select{of type %2 |}1"
|
||||
"cannot have '%3' qualifier">;
|
||||
"%select{non-member function|static member function|deduction guide}0 "
|
||||
"%select{of type %2 |}1cannot have '%3' qualifier">;
|
||||
def err_compound_qualified_function_type : Error<
|
||||
"%select{block pointer|pointer|reference}0 to function type %select{%2 |}1"
|
||||
"cannot have '%3' qualifier">;
|
||||
@ -5750,8 +5869,8 @@ def err_builtin_func_cast_more_than_one_arg : Error<
|
||||
"function-style cast to a builtin type can only take one argument">;
|
||||
def err_value_init_for_array_type : Error<
|
||||
"array types cannot be value-initialized">;
|
||||
def err_value_init_for_function_type : Error<
|
||||
"function types cannot be value-initialized">;
|
||||
def err_init_for_function_type : Error<
|
||||
"cannot create object of function type %0">;
|
||||
def warn_format_nonliteral_noargs : Warning<
|
||||
"format string is not a string literal (potentially insecure)">,
|
||||
InGroup<FormatSecurity>;
|
||||
@ -5916,6 +6035,12 @@ def warn_objc_circular_container : Warning<
|
||||
"adding '%0' to '%1' might cause circular dependency in container">,
|
||||
InGroup<DiagGroup<"objc-circular-container">>;
|
||||
def note_objc_circular_container_declared_here : Note<"'%0' declared here">;
|
||||
def warn_objc_unsafe_perform_selector : Warning<
|
||||
"%0 is incompatible with selectors that return a "
|
||||
"%select{struct|union|vector}1 type">,
|
||||
InGroup<DiagGroup<"objc-unsafe-perform-selector">>;
|
||||
def note_objc_unsafe_perform_selector_method_declared_here : Note<
|
||||
"method %0 that returns %1 declared here">;
|
||||
|
||||
def warn_setter_getter_impl_required : Warning<
|
||||
"property %0 requires method %1 to be defined - "
|
||||
@ -7001,7 +7126,7 @@ def err_incomplete_type_used_in_type_trait_expr : Error<
|
||||
def err_require_constant_init_failed : Error<
|
||||
"variable does not have a constant initializer">;
|
||||
def note_declared_required_constant_init_here : Note<
|
||||
"required by 'require_constant_initializer' attribute here">;
|
||||
"required by 'require_constant_initialization' attribute here">;
|
||||
|
||||
def err_dimension_expr_not_constant_integer : Error<
|
||||
"dimension expression does not evaluate to a constant unsigned int">;
|
||||
@ -7899,6 +8024,8 @@ def err_x86_builtin_32_bit_tgt : Error<
|
||||
"this builtin is only available on x86-64 targets">;
|
||||
def err_x86_builtin_invalid_rounding : Error<
|
||||
"invalid rounding argument">;
|
||||
def err_x86_builtin_invalid_scale : Error<
|
||||
"scale argument must be 1, 2, 4, or 8">;
|
||||
|
||||
def err_builtin_longjmp_unsupported : Error<
|
||||
"__builtin_longjmp is not supported for the current target">;
|
||||
@ -8113,6 +8240,8 @@ def err_opencl_ptrptr_kernel_param : Error<
|
||||
def err_kernel_arg_address_space : Error<
|
||||
"pointer arguments to kernel functions must reside in '__global', "
|
||||
"'__constant' or '__local' address space">;
|
||||
def err_opencl_ext_vector_component_invalid_length : Error<
|
||||
"vector component access has invalid length %0. Supported: 1,2,3,4,8,16.">;
|
||||
def err_opencl_function_variable : Error<
|
||||
"%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">;
|
||||
def err_static_function_scope : Error<
|
||||
@ -8158,9 +8287,9 @@ def err_opencl_return_value_with_address_space : Error<
|
||||
"return value cannot be qualified with address space">;
|
||||
def err_opencl_constant_no_init : Error<
|
||||
"variable in constant address space must be initialized">;
|
||||
def err_atomic_init_constant : Error<
|
||||
"atomic variable can only be assigned to a compile time constant"
|
||||
" in the declaration statement in the program scope">;
|
||||
def err_opencl_atomic_init: Error<
|
||||
"atomic variable can be %select{assigned|initialized}0 to a variable only "
|
||||
"in global address space">;
|
||||
def err_opencl_implicit_vector_conversion : Error<
|
||||
"implicit conversions between vector types (%0 and %1) are not permitted">;
|
||||
def err_opencl_invalid_type_array : Error<
|
||||
@ -8210,6 +8339,8 @@ def err_opencl_invalid_block_declaration : Error<
|
||||
"invalid block variable declaration - must be %select{const qualified|initialized}0">;
|
||||
def err_opencl_extern_block_declaration : Error<
|
||||
"invalid block variable declaration - using 'extern' storage class is disallowed">;
|
||||
def err_opencl_block_ref_block : Error<
|
||||
"cannot refer to a block inside block">;
|
||||
|
||||
// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
|
||||
def err_opencl_builtin_to_addr_arg_num : Error<
|
||||
@ -8227,9 +8358,9 @@ def err_opencl_enqueue_kernel_local_size_args : Error<
|
||||
def err_opencl_enqueue_kernel_invalid_local_size_type : Error<
|
||||
"illegal call to enqueue_kernel, parameter needs to be specified as integer type">;
|
||||
def err_opencl_enqueue_kernel_blocks_non_local_void_args : Error<
|
||||
"blocks used in device side enqueue are expected to have parameters of type 'local void*'">;
|
||||
"blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'">;
|
||||
def err_opencl_enqueue_kernel_blocks_no_args : Error<
|
||||
"blocks in this form of device side enqueue call are expected to have have no parameters">;
|
||||
"blocks with parameters are not accepted in this prototype of enqueue_kernel call">;
|
||||
|
||||
// OpenCL v2.2 s2.1.2.3 - Vector Component Access
|
||||
def ext_opencl_ext_vector_type_rgba_selector: ExtWarn<
|
||||
@ -8708,8 +8839,7 @@ let CategoryName = "Coroutines Issue" in {
|
||||
def err_return_in_coroutine : Error<
|
||||
"return statement not allowed in coroutine; did you mean 'co_return'?">;
|
||||
def note_declared_coroutine_here : Note<
|
||||
"function is a coroutine due to use of "
|
||||
"'%select{co_await|co_yield|co_return}0' here">;
|
||||
"function is a coroutine due to use of '%0' here">;
|
||||
def err_coroutine_objc_method : Error<
|
||||
"Objective-C methods as coroutines are not yet supported">;
|
||||
def err_coroutine_unevaluated_context : Error<
|
||||
@ -8721,24 +8851,38 @@ def err_coroutine_invalid_func_context : Error<
|
||||
"|a copy assignment operator|a move assignment operator|the 'main' function"
|
||||
"|a constexpr function|a function with a deduced return type"
|
||||
"|a varargs function}0">;
|
||||
def err_implied_std_coroutine_traits_not_found : Error<
|
||||
"you need to include <experimental/coroutine> before defining a coroutine">;
|
||||
def err_implied_coroutine_type_not_found : Error<
|
||||
"%0 type was not found; include <experimental/coroutine> before defining "
|
||||
"a coroutine">;
|
||||
def err_malformed_std_coroutine_handle : Error<
|
||||
"std::experimental::coroutine_handle must be a class template">;
|
||||
def err_coroutine_handle_missing_member : Error<
|
||||
"std::experimental::coroutine_handle missing a member named '%0'">;
|
||||
def err_malformed_std_coroutine_traits : Error<
|
||||
"'std::experimental::coroutine_traits' must be a class template">;
|
||||
def err_implied_std_coroutine_traits_promise_type_not_found : Error<
|
||||
"this function cannot be a coroutine: %q0 has no member named 'promise_type'">;
|
||||
def err_implied_std_coroutine_traits_promise_type_not_class : Error<
|
||||
"this function cannot be a coroutine: %0 is not a class">;
|
||||
def err_coroutine_traits_missing_specialization : Error<
|
||||
def err_coroutine_promise_type_incomplete : Error<
|
||||
"this function cannot be a coroutine: %0 is an incomplete type">;
|
||||
def err_coroutine_type_missing_specialization : Error<
|
||||
"this function cannot be a coroutine: missing definition of "
|
||||
"specialization %q0">;
|
||||
def err_implied_std_current_exception_not_found : Error<
|
||||
"you need to include <exception> before defining a coroutine that implicitly "
|
||||
"uses 'set_exception'">;
|
||||
def err_malformed_std_current_exception : Error<
|
||||
"'std::current_exception' must be a function">;
|
||||
def err_coroutine_promise_return_ill_formed : Error<
|
||||
"%0 declares both 'return_value' and 'return_void'">;
|
||||
def note_coroutine_promise_implicit_await_transform_required_here : Note<
|
||||
"call to 'await_transform' implicitly required by 'co_await' here">;
|
||||
def note_coroutine_promise_call_implicitly_required : Note<
|
||||
"call to '%select{initial_suspend|final_suspend}0' implicitly "
|
||||
"required by the %select{initial suspend point|final suspend point}0">;
|
||||
def err_coroutine_promise_unhandled_exception_required : Error<
|
||||
"%0 is required to declare the member 'unhandled_exception()'">;
|
||||
def warn_coroutine_promise_unhandled_exception_required_with_exceptions : Warning<
|
||||
"%0 is required to declare the member 'unhandled_exception()' when exceptions are enabled">,
|
||||
InGroup<Coroutine>;
|
||||
def err_coroutine_promise_get_return_object_on_allocation_failure : Error<
|
||||
"%0: 'get_return_object_on_allocation_failure()' must be a static member function">;
|
||||
}
|
||||
|
||||
let CategoryName = "Documentation Issue" in {
|
||||
@ -8905,4 +9049,9 @@ def ext_warn_gnu_final : ExtWarn<
|
||||
"__final is a GNU extension, consider using C++11 final">,
|
||||
InGroup<GccCompat>;
|
||||
|
||||
def warn_shadow_field :
|
||||
Warning<"non-static data member '%0' of '%1' shadows member inherited from type '%2'">,
|
||||
InGroup<ShadowField>, DefaultIgnore;
|
||||
def note_shadow_field : Note<"declared here">;
|
||||
|
||||
} // end of sema component.
|
||||
|
@ -117,6 +117,57 @@ def note_module_odr_violation_different_definitions : Note<
|
||||
def err_module_odr_violation_different_instantiations : Error<
|
||||
"instantiation of %q0 is different in different modules">;
|
||||
|
||||
def err_module_odr_violation_mismatch_decl : Error<
|
||||
"%q0 has different definitions in different modules; first difference is "
|
||||
"%select{definition in module '%2'|defined here}1 found "
|
||||
"%select{end of class|public access specifier|private access specifier|"
|
||||
"protected access specifier|static assert|field|method}3">;
|
||||
def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
|
||||
"%select{end of class|public access specifier|private access specifier|"
|
||||
"protected access specifier|static assert|field|method}1">;
|
||||
|
||||
def err_module_odr_violation_mismatch_decl_diff : Error<
|
||||
"%q0 has different definitions in different modules; first difference is "
|
||||
"%select{definition in module '%2'|defined here}1 found "
|
||||
"%select{"
|
||||
"static assert with condition|"
|
||||
"static assert with message|"
|
||||
"static assert with %select{|no }4message|"
|
||||
"field %4|"
|
||||
"field %4 with type %5|"
|
||||
"%select{non-|}5bitfield %4|"
|
||||
"bitfield %4 with one width expression|"
|
||||
"%select{non-|}5mutable field %4|"
|
||||
"field %4 with %select{no|an}5 initalizer|"
|
||||
"field %4 with an initializer|"
|
||||
"method %4|"
|
||||
"method %4 is %select{not deleted|deleted}5|"
|
||||
"method %4 is %select{|pure }5%select{not virtual|virtual}6|"
|
||||
"method %4 is %select{not static|static}5|"
|
||||
"method %4 is %select{not volatile|volatile}5|"
|
||||
"method %4 is %select{not const|const}5|"
|
||||
"method %4 is %select{not inline|inline}5}3">;
|
||||
|
||||
def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
|
||||
"%select{"
|
||||
"static assert with different condition|"
|
||||
"static assert with different message|"
|
||||
"static assert with %select{|no }2message|"
|
||||
"field %2|"
|
||||
"field %2 with type %3|"
|
||||
"%select{non-|}3bitfield %2|"
|
||||
"bitfield %2 with different width expression|"
|
||||
"%select{non-|}3mutable field %2|"
|
||||
"field %2 with %select{no|an}3 initializer|"
|
||||
"field %2 with a different initializer|"
|
||||
"method %2|"
|
||||
"method %2 is %select{not deleted|deleted}3|"
|
||||
"method %2 is %select{|pure }3%select{not virtual|virtual}4|"
|
||||
"method %2 is %select{not static|static}3|"
|
||||
"method %2 is %select{not volatile|volatile}3|"
|
||||
"method %2 is %select{not const|const}3|"
|
||||
"method %2 is %select{not inline|inline}3}1">;
|
||||
|
||||
def warn_module_uses_date_time : Warning<
|
||||
"%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
|
||||
InGroup<DiagGroup<"pch-date-time">>;
|
||||
@ -125,6 +176,11 @@ def warn_duplicate_module_file_extension : Warning<
|
||||
"duplicate module file extension block name '%0'">,
|
||||
InGroup<ModuleFileExtension>;
|
||||
|
||||
def warn_module_system_bit_conflict : Warning<
|
||||
"module file '%0' was validated as a system module and is now being imported "
|
||||
"as a non-system module; any difference in diagnostic options will be ignored">,
|
||||
InGroup<ModuleConflict>;
|
||||
|
||||
} // let CategoryName
|
||||
} // let Component
|
||||
|
||||
|
@ -280,7 +280,11 @@ class IdentifierInfo {
|
||||
bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
|
||||
|
||||
/// \brief Return true if this token is a keyword in the specified language.
|
||||
bool isKeyword(const LangOptions &LangOpts);
|
||||
bool isKeyword(const LangOptions &LangOpts) const;
|
||||
|
||||
/// \brief Return true if this token is a C++ keyword in the specified
|
||||
/// language.
|
||||
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const;
|
||||
|
||||
/// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
|
||||
/// associate arbitrary metadata with this token.
|
||||
@ -818,6 +822,7 @@ class DeclarationNameExtra {
|
||||
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
|
||||
CXXOperator##Name,
|
||||
#include "clang/Basic/OperatorKinds.def"
|
||||
CXXDeductionGuide,
|
||||
CXXLiteralOperator,
|
||||
CXXUsingDirective,
|
||||
NUM_EXTRA_KINDS
|
||||
|
@ -107,7 +107,7 @@ LANGOPT(WChar , 1, CPlusPlus, "wchar_t keyword")
|
||||
LANGOPT(DeclSpecKeyword , 1, 0, "__declspec keyword")
|
||||
BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers")
|
||||
BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
|
||||
BENIGN_LANGOPT(GNUMode , 1, 1, "GNU extensions")
|
||||
LANGOPT(GNUMode , 1, 1, "GNU extensions")
|
||||
LANGOPT(GNUKeywords , 1, 1, "GNU keywords")
|
||||
BENIGN_LANGOPT(ImplicitInt, 1, !C99 && !CPlusPlus, "C89 implicit 'int'")
|
||||
LANGOPT(Digraphs , 1, 0, "digraphs")
|
||||
@ -201,6 +201,8 @@ LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
|
||||
LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
|
||||
LANGOPT(NewAlignOverride , 32, 0, "maximum alignment guaranteed by '::operator new(size_t)'")
|
||||
LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts")
|
||||
BENIGN_LANGOPT(ModulesCodegen , 1, 0, "Modules code generation")
|
||||
BENIGN_LANGOPT(ModulesDebugInfo , 1, 0, "Modules debug info")
|
||||
BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
|
||||
BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records")
|
||||
BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form")
|
||||
@ -215,7 +217,8 @@ BENIGN_LANGOPT(DebuggerObjCLiteral , 1, 0, "debugger Objective-C literals and su
|
||||
BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
|
||||
LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
|
||||
LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
|
||||
LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT")
|
||||
/// \brief FP_CONTRACT mode (on/off/fast).
|
||||
ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP contraction type")
|
||||
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
|
||||
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
|
||||
LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
|
||||
@ -261,6 +264,8 @@ LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
|
||||
"field padding (0: none, 1:least "
|
||||
"aggressive, 2: more aggressive)")
|
||||
|
||||
LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation")
|
||||
|
||||
#undef LANGOPT
|
||||
#undef COMPATIBLE_LANGOPT
|
||||
#undef BENIGN_LANGOPT
|
||||
|
@ -88,6 +88,12 @@ class LangOptions : public LangOptionsBase {
|
||||
MSVC2015 = 19
|
||||
};
|
||||
|
||||
enum FPContractModeKind {
|
||||
FPC_Off, // Form fused FP ops only where result will not be affected.
|
||||
FPC_On, // Form fused FP ops according to FP_CONTRACT rules.
|
||||
FPC_Fast // Aggressively fuse FP ops (E.g. FMA).
|
||||
};
|
||||
|
||||
public:
|
||||
/// \brief Set of enabled sanitizers.
|
||||
SanitizerSet Sanitize;
|
||||
@ -96,6 +102,16 @@ class LangOptions : public LangOptionsBase {
|
||||
/// (files, functions, variables) should not be instrumented.
|
||||
std::vector<std::string> SanitizerBlacklistFiles;
|
||||
|
||||
/// \brief Paths to the XRay "always instrument" files specifying which
|
||||
/// objects (files, functions, variables) should be imbued with the XRay
|
||||
/// "always instrument" attribute.
|
||||
std::vector<std::string> XRayAlwaysInstrumentFiles;
|
||||
|
||||
/// \brief Paths to the XRay "never instrument" files specifying which
|
||||
/// objects (files, functions, variables) should be imbued with the XRay
|
||||
/// "never instrument" attribute.
|
||||
std::vector<std::string> XRayNeverInstrumentFiles;
|
||||
|
||||
clang::ObjCRuntime ObjCRuntime;
|
||||
|
||||
std::string ObjCConstantStringClass;
|
||||
@ -170,17 +186,45 @@ class LangOptions : public LangOptionsBase {
|
||||
/// \brief Is this a libc/libm function that is no longer recognized as a
|
||||
/// builtin because a -fno-builtin-* option has been specified?
|
||||
bool isNoBuiltinFunc(StringRef Name) const;
|
||||
|
||||
/// \brief True if any ObjC types may have non-trivial lifetime qualifiers.
|
||||
bool allowsNonTrivialObjCLifetimeQualifiers() const {
|
||||
return ObjCAutoRefCount || ObjCWeak;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Floating point control options
|
||||
class FPOptions {
|
||||
public:
|
||||
unsigned fp_contract : 1;
|
||||
FPOptions() : fp_contract(LangOptions::FPC_Off) {}
|
||||
|
||||
FPOptions() : fp_contract(0) {}
|
||||
// Used for serializing.
|
||||
explicit FPOptions(unsigned I)
|
||||
: fp_contract(static_cast<LangOptions::FPContractModeKind>(I)) {}
|
||||
|
||||
FPOptions(const LangOptions &LangOpts) :
|
||||
fp_contract(LangOpts.DefaultFPContract) {}
|
||||
explicit FPOptions(const LangOptions &LangOpts)
|
||||
: fp_contract(LangOpts.getDefaultFPContractMode()) {}
|
||||
|
||||
bool allowFPContractWithinStatement() const {
|
||||
return fp_contract == LangOptions::FPC_On;
|
||||
}
|
||||
bool allowFPContractAcrossStatement() const {
|
||||
return fp_contract == LangOptions::FPC_Fast;
|
||||
}
|
||||
void setAllowFPContractWithinStatement() {
|
||||
fp_contract = LangOptions::FPC_On;
|
||||
}
|
||||
void setAllowFPContractAcrossStatement() {
|
||||
fp_contract = LangOptions::FPC_Fast;
|
||||
}
|
||||
void setDisallowFPContract() { fp_contract = LangOptions::FPC_Off; }
|
||||
|
||||
/// Used to serialize this.
|
||||
unsigned getInt() const { return fp_contract; }
|
||||
|
||||
private:
|
||||
/// Adjust BinaryOperator::FPFeatures to match the bit-field size of this.
|
||||
unsigned fp_contract : 2;
|
||||
};
|
||||
|
||||
/// \brief Describes the kind of translation unit being processed.
|
||||
|
@ -0,0 +1,80 @@
|
||||
//===- MemoryBufferCache.h - Cache for loaded memory buffers ----*- 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_MEMORYBUFFERCACHE_H
|
||||
#define LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
|
||||
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
} // end namespace llvm
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// Manage memory buffers across multiple users.
|
||||
///
|
||||
/// Ensures that multiple users have a consistent view of each buffer. This is
|
||||
/// used by \a CompilerInstance when building PCMs to ensure that each \a
|
||||
/// ModuleManager sees the same files.
|
||||
///
|
||||
/// \a finalizeCurrentBuffers() should be called before creating a new user.
|
||||
/// This locks in the current buffers, ensuring that no buffer that has already
|
||||
/// been accessed can be purged, preventing use-after-frees.
|
||||
class MemoryBufferCache : public llvm::RefCountedBase<MemoryBufferCache> {
|
||||
struct BufferEntry {
|
||||
std::unique_ptr<llvm::MemoryBuffer> Buffer;
|
||||
|
||||
/// Track the timeline of when this was added to the cache.
|
||||
unsigned Index;
|
||||
};
|
||||
|
||||
/// Cache of buffers.
|
||||
llvm::StringMap<BufferEntry> Buffers;
|
||||
|
||||
/// Monotonically increasing index.
|
||||
unsigned NextIndex = 0;
|
||||
|
||||
/// Bumped to prevent "older" buffers from being removed.
|
||||
unsigned FirstRemovableIndex = 0;
|
||||
|
||||
public:
|
||||
/// Store the Buffer under the Filename.
|
||||
///
|
||||
/// \pre There is not already buffer is not already in the cache.
|
||||
/// \return a reference to the buffer as a convenience.
|
||||
llvm::MemoryBuffer &addBuffer(llvm::StringRef Filename,
|
||||
std::unique_ptr<llvm::MemoryBuffer> Buffer);
|
||||
|
||||
/// Try to remove a buffer from the cache.
|
||||
///
|
||||
/// \return false on success, iff \c !isBufferFinal().
|
||||
bool tryToRemoveBuffer(llvm::StringRef Filename);
|
||||
|
||||
/// Get a pointer to the buffer if it exists; else nullptr.
|
||||
llvm::MemoryBuffer *lookupBuffer(llvm::StringRef Filename);
|
||||
|
||||
/// Check whether the buffer is final.
|
||||
///
|
||||
/// \return true iff \a finalizeCurrentBuffers() has been called since the
|
||||
/// buffer was added. This prevents buffers from being removed.
|
||||
bool isBufferFinal(llvm::StringRef Filename);
|
||||
|
||||
/// Finalize the current buffers in the cache.
|
||||
///
|
||||
/// Should be called when creating a new user to ensure previous uses aren't
|
||||
/// invalidated.
|
||||
void finalizeCurrentBuffers();
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
|
@ -42,7 +42,17 @@ class IdentifierInfo;
|
||||
|
||||
/// \brief Describes the name of a module.
|
||||
typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
|
||||
|
||||
|
||||
/// The signature of a module, which is a hash of the AST content.
|
||||
struct ASTFileSignature : std::array<uint32_t, 5> {
|
||||
ASTFileSignature(std::array<uint32_t, 5> S = {{0}})
|
||||
: std::array<uint32_t, 5>(std::move(S)) {}
|
||||
|
||||
explicit operator bool() const {
|
||||
return *this != std::array<uint32_t, 5>({{0}});
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Describes a module or submodule.
|
||||
class Module {
|
||||
public:
|
||||
@ -65,7 +75,7 @@ class Module {
|
||||
llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
|
||||
|
||||
/// \brief The module signature.
|
||||
uint64_t Signature;
|
||||
ASTFileSignature Signature;
|
||||
|
||||
/// \brief The name of the umbrella entry, as written in the module map.
|
||||
std::string UmbrellaAsWritten;
|
||||
|
@ -326,6 +326,20 @@ class ObjCRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
/// Are the empty collection symbols available?
|
||||
bool hasEmptyCollections() const {
|
||||
switch (getKind()) {
|
||||
default:
|
||||
return false;
|
||||
case MacOSX:
|
||||
return getVersion() >= VersionTuple(10, 11);
|
||||
case iOS:
|
||||
return getVersion() >= VersionTuple(9);
|
||||
case WatchOS:
|
||||
return getVersion() >= VersionTuple(2);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Try to parse an Objective-C runtime specification from the given
|
||||
/// string.
|
||||
///
|
||||
|
@ -66,7 +66,7 @@ IMAGE_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA, "cl_khr_gl_msaa_sharing")
|
||||
IMAGE_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing")
|
||||
IMAGE_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing")
|
||||
IMAGE_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing")
|
||||
IMAGE_WRITE_TYPE(image3d, OCLImage3d, "")
|
||||
IMAGE_WRITE_TYPE(image3d, OCLImage3d, "cl_khr_3d_image_writes")
|
||||
|
||||
IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d, "")
|
||||
IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray, "")
|
||||
|
@ -234,6 +234,11 @@ bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind);
|
||||
/// directives that need loop bound sharing across loops outlined in nested
|
||||
/// functions
|
||||
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind);
|
||||
|
||||
/// Return the captured regions of an OpenMP directive.
|
||||
void getOpenMPCaptureRegions(
|
||||
llvm::SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
|
||||
OpenMPDirectiveKind DKind);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -64,6 +64,11 @@ SANITIZER("function", Function)
|
||||
SANITIZER("integer-divide-by-zero", IntegerDivideByZero)
|
||||
SANITIZER("nonnull-attribute", NonnullAttribute)
|
||||
SANITIZER("null", Null)
|
||||
SANITIZER("nullability-arg", NullabilityArg)
|
||||
SANITIZER("nullability-assign", NullabilityAssign)
|
||||
SANITIZER("nullability-return", NullabilityReturn)
|
||||
SANITIZER_GROUP("nullability", Nullability,
|
||||
NullabilityArg | NullabilityAssign | NullabilityReturn)
|
||||
SANITIZER("object-size", ObjectSize)
|
||||
SANITIZER("return", Return)
|
||||
SANITIZER("returns-nonnull-attribute", ReturnsNonnullAttribute)
|
||||
|
@ -321,8 +321,7 @@ class FullSourceLoc : public SourceLocation {
|
||||
}
|
||||
|
||||
/// \brief Comparison function class, useful for sorting FullSourceLocs.
|
||||
struct BeforeThanCompare : public std::binary_function<FullSourceLoc,
|
||||
FullSourceLoc, bool> {
|
||||
struct BeforeThanCompare {
|
||||
bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
|
||||
return lhs.isBeforeInTranslationUnitThan(rhs);
|
||||
}
|
||||
|
@ -82,11 +82,12 @@ namespace clang {
|
||||
/// \brief Structure that packs information about the type specifiers that
|
||||
/// were written in a particular type specifier sequence.
|
||||
struct WrittenBuiltinSpecs {
|
||||
/*DeclSpec::TST*/ unsigned Type : 5;
|
||||
static_assert(TST_error < 1 << 6, "Type bitfield not wide enough for TST");
|
||||
/*DeclSpec::TST*/ unsigned Type : 6;
|
||||
/*DeclSpec::TSS*/ unsigned Sign : 2;
|
||||
/*DeclSpec::TSW*/ unsigned Width : 2;
|
||||
unsigned ModeAttr : 1;
|
||||
};
|
||||
};
|
||||
|
||||
/// \brief A C++ access specifier (public, private, protected), plus the
|
||||
/// special value "none" which means different things in different contexts.
|
||||
|
@ -43,7 +43,7 @@ def ObjCAtSynchronizedStmt : Stmt;
|
||||
def ObjCForCollectionStmt : Stmt;
|
||||
def ObjCAutoreleasePoolStmt : Stmt;
|
||||
|
||||
// C++ statments
|
||||
// C++ statements
|
||||
def CXXCatchStmt : Stmt;
|
||||
def CXXTryStmt : Stmt;
|
||||
def CXXForRangeStmt : Stmt;
|
||||
@ -150,6 +150,7 @@ def CXXFoldExpr : DStmt<Expr>;
|
||||
// C++ Coroutines TS expressions
|
||||
def CoroutineSuspendExpr : DStmt<Expr, 1>;
|
||||
def CoawaitExpr : DStmt<CoroutineSuspendExpr>;
|
||||
def DependentCoawaitExpr : DStmt<Expr>;
|
||||
def CoyieldExpr : DStmt<CoroutineSuspendExpr>;
|
||||
|
||||
// Obj-C Expressions.
|
||||
|
@ -154,7 +154,7 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
|
||||
/// typedef void* __builtin_va_list;
|
||||
VoidPtrBuiltinVaList,
|
||||
|
||||
/// __builtin_va_list as defind by the AArch64 ABI
|
||||
/// __builtin_va_list as defined by the AArch64 ABI
|
||||
/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055a/IHI0055A_aapcs64.pdf
|
||||
AArch64ABIBuiltinVaList,
|
||||
|
||||
@ -168,7 +168,7 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
|
||||
PowerABIBuiltinVaList,
|
||||
|
||||
/// __builtin_va_list as defined by the x86-64 ABI:
|
||||
/// http://www.x86-64.org/documentation/abi.pdf
|
||||
/// http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf
|
||||
X86_64ABIBuiltinVaList,
|
||||
|
||||
/// __builtin_va_list as defined by ARM AAPCS ABI
|
||||
@ -823,8 +823,9 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
|
||||
/// \brief Set forced language options.
|
||||
///
|
||||
/// Apply changes to the target information with respect to certain
|
||||
/// language options which change the target configuration.
|
||||
virtual void adjust(const LangOptions &Opts);
|
||||
/// language options which change the target configuration and adjust
|
||||
/// the language based on the target options where applicable.
|
||||
virtual void adjust(LangOptions &Opts);
|
||||
|
||||
/// \brief Adjust target options based on codegen options.
|
||||
virtual void adjustTargetOptions(const CodeGenOptions &CGOpts,
|
||||
@ -1032,6 +1033,21 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
|
||||
return LangAS::opencl_global;
|
||||
}
|
||||
|
||||
/// \returns Target specific vtbl ptr address space.
|
||||
virtual unsigned getVtblPtrAddressSpace() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \returns If a target requires an address within a target specific address
|
||||
/// space \p AddressSpace to be converted in order to be used, then return the
|
||||
/// corresponding target specific DWARF address space.
|
||||
///
|
||||
/// \returns Otherwise return None and no conversion will be emitted in the
|
||||
/// DWARF.
|
||||
virtual Optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const {
|
||||
return None;
|
||||
}
|
||||
|
||||
/// \brief Check the target is valid after it is fully initialized.
|
||||
virtual bool validateTarget(DiagnosticsEngine &Diags) const {
|
||||
return true;
|
||||
|
@ -432,6 +432,7 @@ TYPE_TRAIT_1(__has_trivial_move_constructor, HasTrivialMoveConstructor, KEYCXX)
|
||||
TYPE_TRAIT_1(__has_trivial_destructor, HasTrivialDestructor, KEYCXX)
|
||||
TYPE_TRAIT_1(__has_virtual_destructor, HasVirtualDestructor, KEYCXX)
|
||||
TYPE_TRAIT_1(__is_abstract, IsAbstract, KEYCXX)
|
||||
TYPE_TRAIT_1(__is_aggregate, IsAggregate, KEYCXX)
|
||||
TYPE_TRAIT_2(__is_base_of, IsBaseOf, KEYCXX)
|
||||
TYPE_TRAIT_1(__is_class, IsClass, KEYCXX)
|
||||
TYPE_TRAIT_2(__is_convertible_to, IsConvertibleTo, KEYCXX)
|
||||
@ -787,6 +788,8 @@ ANNOTATION(pragma_openmp_end)
|
||||
// handles #pragma loop ... directives.
|
||||
ANNOTATION(pragma_loop_hint)
|
||||
|
||||
ANNOTATION(pragma_fp)
|
||||
|
||||
// Annotations for module import translated from #include etc.
|
||||
ANNOTATION(module_include)
|
||||
ANNOTATION(module_begin)
|
||||
|
@ -31,6 +31,7 @@ namespace clang {
|
||||
UTT_HasTrivialDestructor,
|
||||
UTT_HasVirtualDestructor,
|
||||
UTT_IsAbstract,
|
||||
UTT_IsAggregate,
|
||||
UTT_IsArithmetic,
|
||||
UTT_IsArray,
|
||||
UTT_IsClass,
|
||||
|
@ -161,7 +161,7 @@ class directory_iterator {
|
||||
directory_iterator &increment(std::error_code &EC) {
|
||||
assert(Impl && "attempting to increment past end");
|
||||
EC = Impl->increment();
|
||||
if (EC || !Impl->CurrentEntry.isStatusKnown())
|
||||
if (!Impl->CurrentEntry.isStatusKnown())
|
||||
Impl.reset(); // Normalize the end iterator to Impl == nullptr.
|
||||
return *this;
|
||||
}
|
||||
|
54
contrib/llvm/tools/clang/include/clang/Basic/XRayLists.h
Normal file
54
contrib/llvm/tools/clang/include/clang/Basic/XRayLists.h
Normal file
@ -0,0 +1,54 @@
|
||||
//===--- XRayLists.h - XRay automatic attribution ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// User-provided filters for always/never XRay instrumenting certain functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_BASIC_XRAYLISTS_H
|
||||
#define LLVM_CLANG_BASIC_XRAYLISTS_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/SpecialCaseList.h"
|
||||
#include <memory>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class XRayFunctionFilter {
|
||||
std::unique_ptr<llvm::SpecialCaseList> AlwaysInstrument;
|
||||
std::unique_ptr<llvm::SpecialCaseList> NeverInstrument;
|
||||
SourceManager &SM;
|
||||
|
||||
public:
|
||||
XRayFunctionFilter(ArrayRef<std::string> AlwaysInstrumentPaths,
|
||||
ArrayRef<std::string> NeverInstrumentPaths,
|
||||
SourceManager &SM);
|
||||
|
||||
enum class ImbueAttribute {
|
||||
NONE,
|
||||
ALWAYS,
|
||||
NEVER,
|
||||
};
|
||||
|
||||
ImbueAttribute shouldImbueFunction(StringRef FunctionName) const;
|
||||
|
||||
ImbueAttribute
|
||||
shouldImbueFunctionsInFile(StringRef Filename,
|
||||
StringRef Category = StringRef()) const;
|
||||
|
||||
ImbueAttribute shouldImbueLocation(SourceLocation Loc,
|
||||
StringRef Category = StringRef()) const;
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
@ -1362,7 +1362,7 @@ def SCALAR_SHL: SInst<"vshl", "sss", "SlSUl">;
|
||||
def SCALAR_QSHL: SInst<"vqshl", "sss", "ScSsSiSlSUcSUsSUiSUl">;
|
||||
// Scalar Saturating Rounding Shift Left
|
||||
def SCALAR_QRSHL: SInst<"vqrshl", "sss", "ScSsSiSlSUcSUsSUiSUl">;
|
||||
// Scalar Shift Rouding Left
|
||||
// Scalar Shift Rounding Left
|
||||
def SCALAR_RSHL: SInst<"vrshl", "sss", "SlSUl">;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
class BitcodeModule;
|
||||
template <typename T> class Expected;
|
||||
class Module;
|
||||
class MemoryBufferRef;
|
||||
}
|
||||
@ -44,6 +46,9 @@ namespace clang {
|
||||
|
||||
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
|
||||
llvm::MemoryBufferRef Buf);
|
||||
|
||||
llvm::Expected<llvm::BitcodeModule>
|
||||
FindThinLTOModule(llvm::MemoryBufferRef MBRef);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -16,7 +16,7 @@
|
||||
//
|
||||
// It allows other clients, like LLDB, to determine the LLVM types that are
|
||||
// actually used in function calls, which makes it possible to then determine
|
||||
// the acutal ABI locations (e.g. registers, stack locations, etc.) that
|
||||
// the actual ABI locations (e.g. registers, stack locations, etc.) that
|
||||
// these parameters are stored in.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -23,14 +23,36 @@ class BackendConsumer;
|
||||
|
||||
class CodeGenAction : public ASTFrontendAction {
|
||||
private:
|
||||
// Let BackendConsumer access LinkModule.
|
||||
friend class BackendConsumer;
|
||||
|
||||
/// Info about module to link into a module we're generating.
|
||||
struct LinkModule {
|
||||
/// The module to link in.
|
||||
std::unique_ptr<llvm::Module> Module;
|
||||
|
||||
/// If true, we set attributes on Module's functions according to our
|
||||
/// CodeGenOptions and LangOptions, as though we were generating the
|
||||
/// function ourselves.
|
||||
bool PropagateAttrs;
|
||||
|
||||
/// If true, we use LLVM module internalizer.
|
||||
bool Internalize;
|
||||
|
||||
/// Bitwise combination of llvm::LinkerFlags used when we link the module.
|
||||
unsigned LinkFlags;
|
||||
};
|
||||
|
||||
unsigned Act;
|
||||
std::unique_ptr<llvm::Module> TheModule;
|
||||
// Vector of {Linker::Flags, Module*} pairs to specify bitcode
|
||||
// modules to link in using corresponding linker flags.
|
||||
SmallVector<std::pair<unsigned, llvm::Module *>, 4> LinkModules;
|
||||
|
||||
/// Bitcode modules to link in to our module.
|
||||
SmallVector<LinkModule, 4> LinkModules;
|
||||
llvm::LLVMContext *VMContext;
|
||||
bool OwnsVMContext;
|
||||
|
||||
std::unique_ptr<llvm::Module> loadModule(llvm::MemoryBufferRef MBRef);
|
||||
|
||||
protected:
|
||||
/// Create a new code generation action. If the optional \p _VMContext
|
||||
/// parameter is supplied, the action uses it without taking ownership,
|
||||
@ -49,13 +71,6 @@ class CodeGenAction : public ASTFrontendAction {
|
||||
public:
|
||||
~CodeGenAction() override;
|
||||
|
||||
/// setLinkModule - Set the link module to be used by this action. If a link
|
||||
/// module is not provided, and CodeGenOptions::LinkBitcodeFile is non-empty,
|
||||
/// the action will load it from the specified file.
|
||||
void addLinkModule(llvm::Module *Mod, unsigned LinkFlags) {
|
||||
LinkModules.push_back(std::make_pair(LinkFlags, Mod));
|
||||
}
|
||||
|
||||
/// Take the generated LLVM module, for use after the action has been run.
|
||||
/// The result may be null on failure.
|
||||
std::unique_ptr<llvm::Module> takeModule();
|
||||
|
@ -0,0 +1,561 @@
|
||||
//===- ConstantInitBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class provides a convenient interface for building complex
|
||||
// global initializers of the sort that are frequently required for
|
||||
// language ABIs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
|
||||
#define LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "clang/AST/CharUnits.h"
|
||||
#include "clang/CodeGen/ConstantInitFuture.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
namespace CodeGen {
|
||||
|
||||
class CodeGenModule;
|
||||
|
||||
/// A convenience builder class for complex constant initializers,
|
||||
/// especially for anonymous global structures used by various language
|
||||
/// runtimes.
|
||||
///
|
||||
/// The basic usage pattern is expected to be something like:
|
||||
/// ConstantInitBuilder builder(CGM);
|
||||
/// auto toplevel = builder.beginStruct();
|
||||
/// toplevel.addInt(CGM.SizeTy, widgets.size());
|
||||
/// auto widgetArray = builder.beginArray();
|
||||
/// for (auto &widget : widgets) {
|
||||
/// auto widgetDesc = widgetArray.beginStruct();
|
||||
/// widgetDesc.addInt(CGM.SizeTy, widget.getPower());
|
||||
/// widgetDesc.add(CGM.GetAddrOfConstantString(widget.getName()));
|
||||
/// widgetDesc.add(CGM.GetAddrOfGlobal(widget.getInitializerDecl()));
|
||||
/// widgetDesc.finishAndAddTo(widgetArray);
|
||||
/// }
|
||||
/// widgetArray.finishAndAddTo(toplevel);
|
||||
/// auto global = toplevel.finishAndCreateGlobal("WIDGET_LIST", Align,
|
||||
/// /*constant*/ true);
|
||||
class ConstantInitBuilderBase {
|
||||
struct SelfReference {
|
||||
llvm::GlobalVariable *Dummy;
|
||||
llvm::SmallVector<llvm::Constant*, 4> Indices;
|
||||
|
||||
SelfReference(llvm::GlobalVariable *dummy) : Dummy(dummy) {}
|
||||
};
|
||||
CodeGenModule &CGM;
|
||||
llvm::SmallVector<llvm::Constant*, 16> Buffer;
|
||||
std::vector<SelfReference> SelfReferences;
|
||||
bool Frozen = false;
|
||||
|
||||
friend class ConstantInitFuture;
|
||||
friend class ConstantAggregateBuilderBase;
|
||||
template <class, class>
|
||||
friend class ConstantAggregateBuilderTemplateBase;
|
||||
|
||||
protected:
|
||||
explicit ConstantInitBuilderBase(CodeGenModule &CGM) : CGM(CGM) {}
|
||||
|
||||
~ConstantInitBuilderBase() {
|
||||
assert(Buffer.empty() && "didn't claim all values out of buffer");
|
||||
assert(SelfReferences.empty() && "didn't apply all self-references");
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,
|
||||
const llvm::Twine &name,
|
||||
CharUnits alignment,
|
||||
bool constant = false,
|
||||
llvm::GlobalValue::LinkageTypes linkage
|
||||
= llvm::GlobalValue::InternalLinkage,
|
||||
unsigned addressSpace = 0);
|
||||
|
||||
ConstantInitFuture createFuture(llvm::Constant *initializer);
|
||||
|
||||
void setGlobalInitializer(llvm::GlobalVariable *GV,
|
||||
llvm::Constant *initializer);
|
||||
|
||||
void resolveSelfReferences(llvm::GlobalVariable *GV);
|
||||
|
||||
void abandon(size_t newEnd);
|
||||
};
|
||||
|
||||
/// A concrete base class for struct and array aggregate
|
||||
/// initializer builders.
|
||||
class ConstantAggregateBuilderBase {
|
||||
protected:
|
||||
ConstantInitBuilderBase &Builder;
|
||||
ConstantAggregateBuilderBase *Parent;
|
||||
size_t Begin;
|
||||
mutable size_t CachedOffsetEnd = 0;
|
||||
bool Finished = false;
|
||||
bool Frozen = false;
|
||||
bool Packed = false;
|
||||
mutable CharUnits CachedOffsetFromGlobal;
|
||||
|
||||
llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() {
|
||||
return Builder.Buffer;
|
||||
}
|
||||
|
||||
const llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() const {
|
||||
return Builder.Buffer;
|
||||
}
|
||||
|
||||
ConstantAggregateBuilderBase(ConstantInitBuilderBase &builder,
|
||||
ConstantAggregateBuilderBase *parent)
|
||||
: Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {
|
||||
if (parent) {
|
||||
assert(!parent->Frozen && "parent already has child builder active");
|
||||
parent->Frozen = true;
|
||||
} else {
|
||||
assert(!builder.Frozen && "builder already has child builder active");
|
||||
builder.Frozen = true;
|
||||
}
|
||||
}
|
||||
|
||||
~ConstantAggregateBuilderBase() {
|
||||
assert(Finished && "didn't finish aggregate builder");
|
||||
}
|
||||
|
||||
void markFinished() {
|
||||
assert(!Frozen && "child builder still active");
|
||||
assert(!Finished && "builder already finished");
|
||||
Finished = true;
|
||||
if (Parent) {
|
||||
assert(Parent->Frozen &&
|
||||
"parent not frozen while child builder active");
|
||||
Parent->Frozen = false;
|
||||
} else {
|
||||
assert(Builder.Frozen &&
|
||||
"builder not frozen while child builder active");
|
||||
Builder.Frozen = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// Not copyable.
|
||||
ConstantAggregateBuilderBase(const ConstantAggregateBuilderBase &) = delete;
|
||||
ConstantAggregateBuilderBase &operator=(const ConstantAggregateBuilderBase &)
|
||||
= delete;
|
||||
|
||||
// Movable, mostly to allow returning. But we have to write this out
|
||||
// properly to satisfy the assert in the destructor.
|
||||
ConstantAggregateBuilderBase(ConstantAggregateBuilderBase &&other)
|
||||
: Builder(other.Builder), Parent(other.Parent), Begin(other.Begin),
|
||||
CachedOffsetEnd(other.CachedOffsetEnd),
|
||||
Finished(other.Finished), Frozen(other.Frozen), Packed(other.Packed),
|
||||
CachedOffsetFromGlobal(other.CachedOffsetFromGlobal) {
|
||||
other.Finished = true;
|
||||
}
|
||||
ConstantAggregateBuilderBase &operator=(ConstantAggregateBuilderBase &&other)
|
||||
= delete;
|
||||
|
||||
/// Return the number of elements that have been added to
|
||||
/// this struct or array.
|
||||
size_t size() const {
|
||||
assert(!this->Finished && "cannot query after finishing builder");
|
||||
assert(!this->Frozen && "cannot query while sub-builder is active");
|
||||
assert(this->Begin <= this->getBuffer().size());
|
||||
return this->getBuffer().size() - this->Begin;
|
||||
}
|
||||
|
||||
/// Return true if no elements have yet been added to this struct or array.
|
||||
bool empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
/// Abandon this builder completely.
|
||||
void abandon() {
|
||||
markFinished();
|
||||
Builder.abandon(Begin);
|
||||
}
|
||||
|
||||
/// Add a new value to this initializer.
|
||||
void add(llvm::Constant *value) {
|
||||
assert(value && "adding null value to constant initializer");
|
||||
assert(!Finished && "cannot add more values after finishing builder");
|
||||
assert(!Frozen && "cannot add values while subbuilder is active");
|
||||
Builder.Buffer.push_back(value);
|
||||
}
|
||||
|
||||
/// Add an integer value of type size_t.
|
||||
void addSize(CharUnits size);
|
||||
|
||||
/// Add an integer value of a specific type.
|
||||
void addInt(llvm::IntegerType *intTy, uint64_t value,
|
||||
bool isSigned = false) {
|
||||
add(llvm::ConstantInt::get(intTy, value, isSigned));
|
||||
}
|
||||
|
||||
/// Add a null pointer of a specific type.
|
||||
void addNullPointer(llvm::PointerType *ptrTy) {
|
||||
add(llvm::ConstantPointerNull::get(ptrTy));
|
||||
}
|
||||
|
||||
/// Add a bitcast of a value to a specific type.
|
||||
void addBitCast(llvm::Constant *value, llvm::Type *type) {
|
||||
add(llvm::ConstantExpr::getBitCast(value, type));
|
||||
}
|
||||
|
||||
/// Add a bunch of new values to this initializer.
|
||||
void addAll(llvm::ArrayRef<llvm::Constant *> values) {
|
||||
assert(!Finished && "cannot add more values after finishing builder");
|
||||
assert(!Frozen && "cannot add values while subbuilder is active");
|
||||
Builder.Buffer.append(values.begin(), values.end());
|
||||
}
|
||||
|
||||
/// Add a relative offset to the given target address, i.e. the
|
||||
/// static difference between the target address and the address
|
||||
/// of the relative offset. The target must be known to be defined
|
||||
/// in the current linkage unit. The offset will have the given
|
||||
/// integer type, which must be no wider than intptr_t. Some
|
||||
/// targets may not fully support this operation.
|
||||
void addRelativeOffset(llvm::IntegerType *type, llvm::Constant *target) {
|
||||
add(getRelativeOffset(type, target));
|
||||
}
|
||||
|
||||
/// Add a relative offset to the target address, plus a small
|
||||
/// constant offset. This is primarily useful when the relative
|
||||
/// offset is known to be a multiple of (say) four and therefore
|
||||
/// the tag can be used to express an extra two bits of information.
|
||||
void addTaggedRelativeOffset(llvm::IntegerType *type,
|
||||
llvm::Constant *address,
|
||||
unsigned tag) {
|
||||
llvm::Constant *offset = getRelativeOffset(type, address);
|
||||
if (tag) {
|
||||
offset = llvm::ConstantExpr::getAdd(offset,
|
||||
llvm::ConstantInt::get(type, tag));
|
||||
}
|
||||
add(offset);
|
||||
}
|
||||
|
||||
/// Return the offset from the start of the initializer to the
|
||||
/// next position, assuming no padding is required prior to it.
|
||||
///
|
||||
/// This operation will not succeed if any unsized placeholders are
|
||||
/// currently in place in the initializer.
|
||||
CharUnits getNextOffsetFromGlobal() const {
|
||||
assert(!Finished && "cannot add more values after finishing builder");
|
||||
assert(!Frozen && "cannot add values while subbuilder is active");
|
||||
return getOffsetFromGlobalTo(Builder.Buffer.size());
|
||||
}
|
||||
|
||||
/// An opaque class to hold the abstract position of a placeholder.
|
||||
class PlaceholderPosition {
|
||||
size_t Index;
|
||||
friend class ConstantAggregateBuilderBase;
|
||||
PlaceholderPosition(size_t index) : Index(index) {}
|
||||
};
|
||||
|
||||
/// Add a placeholder value to the structure. The returned position
|
||||
/// can be used to set the value later; it will not be invalidated by
|
||||
/// any intermediate operations except (1) filling the same position or
|
||||
/// (2) finishing the entire builder.
|
||||
///
|
||||
/// This is useful for emitting certain kinds of structure which
|
||||
/// contain some sort of summary field, generaly a count, before any
|
||||
/// of the data. By emitting a placeholder first, the structure can
|
||||
/// be emitted eagerly.
|
||||
PlaceholderPosition addPlaceholder() {
|
||||
assert(!Finished && "cannot add more values after finishing builder");
|
||||
assert(!Frozen && "cannot add values while subbuilder is active");
|
||||
Builder.Buffer.push_back(nullptr);
|
||||
return Builder.Buffer.size() - 1;
|
||||
}
|
||||
|
||||
/// Add a placeholder, giving the expected type that will be filled in.
|
||||
PlaceholderPosition addPlaceholderWithSize(llvm::Type *expectedType);
|
||||
|
||||
/// Fill a previously-added placeholder.
|
||||
void fillPlaceholderWithInt(PlaceholderPosition position,
|
||||
llvm::IntegerType *type, uint64_t value,
|
||||
bool isSigned = false) {
|
||||
fillPlaceholder(position, llvm::ConstantInt::get(type, value, isSigned));
|
||||
}
|
||||
|
||||
/// Fill a previously-added placeholder.
|
||||
void fillPlaceholder(PlaceholderPosition position, llvm::Constant *value) {
|
||||
assert(!Finished && "cannot change values after finishing builder");
|
||||
assert(!Frozen && "cannot add values while subbuilder is active");
|
||||
llvm::Constant *&slot = Builder.Buffer[position.Index];
|
||||
assert(slot == nullptr && "placeholder already filled");
|
||||
slot = value;
|
||||
}
|
||||
|
||||
/// Produce an address which will eventually point to the the next
|
||||
/// position to be filled. This is computed with an indexed
|
||||
/// getelementptr rather than by computing offsets.
|
||||
///
|
||||
/// The returned pointer will have type T*, where T is the given
|
||||
/// position.
|
||||
llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type);
|
||||
|
||||
llvm::ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
|
||||
llvm::SmallVectorImpl<llvm::Constant*> &indices) {
|
||||
getGEPIndicesTo(indices, Builder.Buffer.size());
|
||||
return indices;
|
||||
}
|
||||
|
||||
protected:
|
||||
llvm::Constant *finishArray(llvm::Type *eltTy);
|
||||
llvm::Constant *finishStruct(llvm::StructType *structTy);
|
||||
|
||||
private:
|
||||
void getGEPIndicesTo(llvm::SmallVectorImpl<llvm::Constant*> &indices,
|
||||
size_t position) const;
|
||||
|
||||
llvm::Constant *getRelativeOffset(llvm::IntegerType *offsetType,
|
||||
llvm::Constant *target);
|
||||
|
||||
CharUnits getOffsetFromGlobalTo(size_t index) const;
|
||||
};
|
||||
|
||||
template <class Impl, class Traits>
|
||||
class ConstantAggregateBuilderTemplateBase
|
||||
: public Traits::AggregateBuilderBase {
|
||||
using super = typename Traits::AggregateBuilderBase;
|
||||
public:
|
||||
using InitBuilder = typename Traits::InitBuilder;
|
||||
using ArrayBuilder = typename Traits::ArrayBuilder;
|
||||
using StructBuilder = typename Traits::StructBuilder;
|
||||
using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
|
||||
|
||||
protected:
|
||||
ConstantAggregateBuilderTemplateBase(InitBuilder &builder,
|
||||
AggregateBuilderBase *parent)
|
||||
: super(builder, parent) {}
|
||||
|
||||
Impl &asImpl() { return *static_cast<Impl*>(this); }
|
||||
|
||||
public:
|
||||
ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
|
||||
return ArrayBuilder(static_cast<InitBuilder&>(this->Builder), this, eltTy);
|
||||
}
|
||||
|
||||
StructBuilder beginStruct(llvm::StructType *ty = nullptr) {
|
||||
return StructBuilder(static_cast<InitBuilder&>(this->Builder), this, ty);
|
||||
}
|
||||
|
||||
/// Given that this builder was created by beginning an array or struct
|
||||
/// component on the given parent builder, finish the array/struct
|
||||
/// component and add it to the parent.
|
||||
///
|
||||
/// It is an intentional choice that the parent is passed in explicitly
|
||||
/// despite it being redundant with information already kept in the
|
||||
/// builder. This aids in readability by making it easier to find the
|
||||
/// places that add components to a builder, as well as "bookending"
|
||||
/// the sub-builder more explicitly.
|
||||
void finishAndAddTo(AggregateBuilderBase &parent) {
|
||||
assert(this->Parent == &parent && "adding to non-parent builder");
|
||||
parent.add(asImpl().finishImpl());
|
||||
}
|
||||
|
||||
/// Given that this builder was created by beginning an array or struct
|
||||
/// directly on a ConstantInitBuilder, finish the array/struct and
|
||||
/// create a global variable with it as the initializer.
|
||||
template <class... As>
|
||||
llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
|
||||
assert(!this->Parent && "finishing non-root builder");
|
||||
return this->Builder.createGlobal(asImpl().finishImpl(),
|
||||
std::forward<As>(args)...);
|
||||
}
|
||||
|
||||
/// Given that this builder was created by beginning an array or struct
|
||||
/// directly on a ConstantInitBuilder, finish the array/struct and
|
||||
/// set it as the initializer of the given global variable.
|
||||
void finishAndSetAsInitializer(llvm::GlobalVariable *global) {
|
||||
assert(!this->Parent && "finishing non-root builder");
|
||||
return this->Builder.setGlobalInitializer(global, asImpl().finishImpl());
|
||||
}
|
||||
|
||||
/// Given that this builder was created by beginning an array or struct
|
||||
/// directly on a ConstantInitBuilder, finish the array/struct and
|
||||
/// return a future which can be used to install the initializer in
|
||||
/// a global later.
|
||||
///
|
||||
/// This is useful for allowing a finished initializer to passed to
|
||||
/// an API which will build the global. However, the "future" preserves
|
||||
/// a dependency on the original builder; it is an error to pass it aside.
|
||||
ConstantInitFuture finishAndCreateFuture() {
|
||||
assert(!this->Parent && "finishing non-root builder");
|
||||
return this->Builder.createFuture(asImpl().finishImpl());
|
||||
}
|
||||
};
|
||||
|
||||
template <class Traits>
|
||||
class ConstantArrayBuilderTemplateBase
|
||||
: public ConstantAggregateBuilderTemplateBase<typename Traits::ArrayBuilder,
|
||||
Traits> {
|
||||
using super =
|
||||
ConstantAggregateBuilderTemplateBase<typename Traits::ArrayBuilder, Traits>;
|
||||
|
||||
public:
|
||||
using InitBuilder = typename Traits::InitBuilder;
|
||||
using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
|
||||
|
||||
private:
|
||||
llvm::Type *EltTy;
|
||||
|
||||
template <class, class>
|
||||
friend class ConstantAggregateBuilderTemplateBase;
|
||||
|
||||
protected:
|
||||
ConstantArrayBuilderTemplateBase(InitBuilder &builder,
|
||||
AggregateBuilderBase *parent,
|
||||
llvm::Type *eltTy)
|
||||
: super(builder, parent), EltTy(eltTy) {}
|
||||
|
||||
private:
|
||||
/// Form an array constant from the values that have been added to this
|
||||
/// builder.
|
||||
llvm::Constant *finishImpl() {
|
||||
return AggregateBuilderBase::finishArray(EltTy);
|
||||
}
|
||||
};
|
||||
|
||||
/// A template class designed to allow other frontends to
|
||||
/// easily customize the builder classes used by ConstantInitBuilder,
|
||||
/// and thus to extend the API to work with the abstractions they
|
||||
/// prefer. This would probably not be necessary if C++ just
|
||||
/// supported extension methods.
|
||||
template <class Traits>
|
||||
class ConstantStructBuilderTemplateBase
|
||||
: public ConstantAggregateBuilderTemplateBase<typename Traits::StructBuilder,
|
||||
Traits> {
|
||||
using super =
|
||||
ConstantAggregateBuilderTemplateBase<typename Traits::StructBuilder,Traits>;
|
||||
|
||||
public:
|
||||
using InitBuilder = typename Traits::InitBuilder;
|
||||
using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
|
||||
|
||||
private:
|
||||
llvm::StructType *StructTy;
|
||||
|
||||
template <class, class>
|
||||
friend class ConstantAggregateBuilderTemplateBase;
|
||||
|
||||
protected:
|
||||
ConstantStructBuilderTemplateBase(InitBuilder &builder,
|
||||
AggregateBuilderBase *parent,
|
||||
llvm::StructType *structTy)
|
||||
: super(builder, parent), StructTy(structTy) {
|
||||
if (structTy) this->Packed = structTy->isPacked();
|
||||
}
|
||||
|
||||
public:
|
||||
void setPacked(bool packed) {
|
||||
this->Packed = packed;
|
||||
}
|
||||
|
||||
/// Use the given type for the struct if its element count is correct.
|
||||
/// Don't add more elements after calling this.
|
||||
void suggestType(llvm::StructType *structTy) {
|
||||
if (this->size() == structTy->getNumElements()) {
|
||||
StructTy = structTy;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/// Form an array constant from the values that have been added to this
|
||||
/// builder.
|
||||
llvm::Constant *finishImpl() {
|
||||
return AggregateBuilderBase::finishStruct(StructTy);
|
||||
}
|
||||
};
|
||||
|
||||
/// A template class designed to allow other frontends to
|
||||
/// easily customize the builder classes used by ConstantInitBuilder,
|
||||
/// and thus to extend the API to work with the abstractions they
|
||||
/// prefer. This would probably not be necessary if C++ just
|
||||
/// supported extension methods.
|
||||
template <class Traits>
|
||||
class ConstantInitBuilderTemplateBase : public ConstantInitBuilderBase {
|
||||
protected:
|
||||
ConstantInitBuilderTemplateBase(CodeGenModule &CGM)
|
||||
: ConstantInitBuilderBase(CGM) {}
|
||||
|
||||
public:
|
||||
using InitBuilder = typename Traits::InitBuilder;
|
||||
using ArrayBuilder = typename Traits::ArrayBuilder;
|
||||
using StructBuilder = typename Traits::StructBuilder;
|
||||
|
||||
ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
|
||||
return ArrayBuilder(static_cast<InitBuilder&>(*this), nullptr, eltTy);
|
||||
}
|
||||
|
||||
StructBuilder beginStruct(llvm::StructType *structTy = nullptr) {
|
||||
return StructBuilder(static_cast<InitBuilder&>(*this), nullptr, structTy);
|
||||
}
|
||||
};
|
||||
|
||||
class ConstantInitBuilder;
|
||||
class ConstantStructBuilder;
|
||||
class ConstantArrayBuilder;
|
||||
|
||||
struct ConstantInitBuilderTraits {
|
||||
using InitBuilder = ConstantInitBuilder;
|
||||
using AggregateBuilderBase = ConstantAggregateBuilderBase;
|
||||
using ArrayBuilder = ConstantArrayBuilder;
|
||||
using StructBuilder = ConstantStructBuilder;
|
||||
};
|
||||
|
||||
/// The standard implementation of ConstantInitBuilder used in Clang.
|
||||
class ConstantInitBuilder
|
||||
: public ConstantInitBuilderTemplateBase<ConstantInitBuilderTraits> {
|
||||
public:
|
||||
explicit ConstantInitBuilder(CodeGenModule &CGM) :
|
||||
ConstantInitBuilderTemplateBase(CGM) {}
|
||||
};
|
||||
|
||||
/// A helper class of ConstantInitBuilder, used for building constant
|
||||
/// array initializers.
|
||||
class ConstantArrayBuilder
|
||||
: public ConstantArrayBuilderTemplateBase<ConstantInitBuilderTraits> {
|
||||
template <class Traits>
|
||||
friend class ConstantInitBuilderTemplateBase;
|
||||
|
||||
// The use of explicit qualification is a GCC workaround.
|
||||
template <class Impl, class Traits>
|
||||
friend class CodeGen::ConstantAggregateBuilderTemplateBase;
|
||||
|
||||
ConstantArrayBuilder(ConstantInitBuilder &builder,
|
||||
ConstantAggregateBuilderBase *parent,
|
||||
llvm::Type *eltTy)
|
||||
: ConstantArrayBuilderTemplateBase(builder, parent, eltTy) {}
|
||||
};
|
||||
|
||||
/// A helper class of ConstantInitBuilder, used for building constant
|
||||
/// struct initializers.
|
||||
class ConstantStructBuilder
|
||||
: public ConstantStructBuilderTemplateBase<ConstantInitBuilderTraits> {
|
||||
template <class Traits>
|
||||
friend class ConstantInitBuilderTemplateBase;
|
||||
|
||||
// The use of explicit qualification is a GCC workaround.
|
||||
template <class Impl, class Traits>
|
||||
friend class CodeGen::ConstantAggregateBuilderTemplateBase;
|
||||
|
||||
ConstantStructBuilder(ConstantInitBuilder &builder,
|
||||
ConstantAggregateBuilderBase *parent,
|
||||
llvm::StructType *structTy)
|
||||
: ConstantStructBuilderTemplateBase(builder, parent, structTy) {}
|
||||
};
|
||||
|
||||
} // end namespace CodeGen
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
@ -0,0 +1,111 @@
|
||||
//===- ConstantInitFuture.h - "Future" constant initializers ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class defines the ConstantInitFuture class. This is split out
|
||||
// from ConstantInitBuilder.h in order to allow APIs to work with it
|
||||
// without having to include that entire header. This is particularly
|
||||
// important because it is often useful to be able to default-construct
|
||||
// a future in, say, a default argument.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
|
||||
#define LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
|
||||
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
|
||||
// Forward-declare ConstantInitBuilderBase and give it a
|
||||
// PointerLikeTypeTraits specialization so that we can safely use it
|
||||
// in a PointerUnion below.
|
||||
namespace clang {
|
||||
namespace CodeGen {
|
||||
class ConstantInitBuilderBase;
|
||||
}
|
||||
}
|
||||
namespace llvm {
|
||||
template <>
|
||||
class PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> {
|
||||
public:
|
||||
using T = ::clang::CodeGen::ConstantInitBuilderBase*;
|
||||
|
||||
static inline void *getAsVoidPointer(T p) { return p; }
|
||||
static inline T getFromVoidPointer(void *p) {return static_cast<T>(p);}
|
||||
enum { NumLowBitsAvailable = 2 };
|
||||
};
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
namespace CodeGen {
|
||||
|
||||
/// A "future" for a completed constant initializer, which can be passed
|
||||
/// around independently of any sub-builders (but not the original parent).
|
||||
class ConstantInitFuture {
|
||||
using PairTy = llvm::PointerUnion<ConstantInitBuilderBase*, llvm::Constant*>;
|
||||
|
||||
PairTy Data;
|
||||
|
||||
friend class ConstantInitBuilderBase;
|
||||
explicit ConstantInitFuture(ConstantInitBuilderBase *builder);
|
||||
|
||||
public:
|
||||
ConstantInitFuture() {}
|
||||
|
||||
/// A future can be explicitly created from a fixed initializer.
|
||||
explicit ConstantInitFuture(llvm::Constant *initializer) : Data(initializer) {
|
||||
assert(initializer && "creating null future");
|
||||
}
|
||||
|
||||
/// Is this future non-null?
|
||||
explicit operator bool() const { return bool(Data); }
|
||||
|
||||
/// Return the type of the initializer.
|
||||
llvm::Type *getType() const;
|
||||
|
||||
/// Abandon this initializer.
|
||||
void abandon();
|
||||
|
||||
/// Install the initializer into a global variable. This cannot
|
||||
/// be called multiple times.
|
||||
void installInGlobal(llvm::GlobalVariable *global);
|
||||
|
||||
void *getOpaqueValue() const { return Data.getOpaqueValue(); }
|
||||
static ConstantInitFuture getFromOpaqueValue(void *value) {
|
||||
ConstantInitFuture result;
|
||||
result.Data = PairTy::getFromOpaqueValue(value);
|
||||
return result;
|
||||
}
|
||||
enum {
|
||||
NumLowBitsAvailable =
|
||||
llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable
|
||||
};
|
||||
};
|
||||
|
||||
} // end namespace CodeGen
|
||||
} // end namespace clang
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <>
|
||||
class PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> {
|
||||
public:
|
||||
using T = ::clang::CodeGen::ConstantInitFuture;
|
||||
|
||||
static inline void *getAsVoidPointer(T future) {
|
||||
return future.getOpaqueValue();
|
||||
}
|
||||
static inline T getFromVoidPointer(void *p) {
|
||||
return T::getFromOpaqueValue(p);
|
||||
}
|
||||
enum { NumLowBitsAvailable = T::NumLowBitsAvailable };
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -35,6 +35,7 @@ namespace clang {
|
||||
|
||||
namespace CodeGen {
|
||||
class CodeGenModule;
|
||||
class CGDebugInfo;
|
||||
}
|
||||
|
||||
/// The primary public interface to the Clang code generator.
|
||||
@ -65,6 +66,9 @@ class CodeGenerator : public ASTConsumer {
|
||||
/// CodeGenerator after releasing its module.
|
||||
llvm::Module *ReleaseModule();
|
||||
|
||||
/// Return debug info code generator.
|
||||
CodeGen::CGDebugInfo *getCGDebugInfo();
|
||||
|
||||
/// Given a mangled name, return a declaration which mangles that way
|
||||
/// which has been added to this code generator via a Handle method.
|
||||
///
|
||||
|
@ -136,6 +136,8 @@ def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">,
|
||||
let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
|
||||
|
||||
def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">;
|
||||
def debug_info_macro : Flag<["-"], "debug-info-macro">,
|
||||
HelpText<"Emit macro debug information">;
|
||||
def dwarf_version_EQ : Joined<["-"], "dwarf-version=">;
|
||||
def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">;
|
||||
def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
|
||||
@ -307,6 +309,11 @@ def fprofile_instrument_use_path_EQ :
|
||||
def flto_visibility_public_std:
|
||||
Flag<["-"], "flto-visibility-public-std">,
|
||||
HelpText<"Use public LTO visibility for classes in std and stdext namespaces">;
|
||||
def flto_unit: Flag<["-"], "flto-unit">,
|
||||
HelpText<"Emit IR to support LTO unit features (CFI, whole program vtable opt)">;
|
||||
def fno_lto_unit: Flag<["-"], "fno-lto-unit">;
|
||||
def fthin_link_bitcode_EQ : Joined<["-"], "fthin-link-bitcode=">,
|
||||
HelpText<"Write minimized bitcode to <file> for the ThinLTO thin link only">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Dependency Output Options
|
||||
@ -429,6 +436,14 @@ def fmodules_local_submodule_visibility :
|
||||
Flag<["-"], "fmodules-local-submodule-visibility">,
|
||||
HelpText<"Enforce name visibility rules across submodules of the same "
|
||||
"top-level module.">;
|
||||
def fmodules_codegen :
|
||||
Flag<["-"], "fmodules-codegen">,
|
||||
HelpText<"Generate code for uses of this module that assumes an explicit "
|
||||
"object file will be built for the module">;
|
||||
def fmodules_debuginfo :
|
||||
Flag<["-"], "fmodules-debuginfo">,
|
||||
HelpText<"Generate debug info for types in an object file built from this "
|
||||
"module and do not generate them elsewhere">;
|
||||
def fmodule_format_EQ : Joined<["-"], "fmodule-format=">,
|
||||
HelpText<"Select the container format for clang modules and PCH. "
|
||||
"Supported options are 'raw' and 'obj'.">;
|
||||
@ -466,6 +481,8 @@ def ast_list : Flag<["-"], "ast-list">,
|
||||
HelpText<"Build ASTs and print the list of declaration node qualified names">;
|
||||
def ast_dump : Flag<["-"], "ast-dump">,
|
||||
HelpText<"Build ASTs and then debug dump them">;
|
||||
def ast_dump_all : Flag<["-"], "ast-dump-all">,
|
||||
HelpText<"Build ASTs and then debug dump them, forcing deserialization">;
|
||||
def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">,
|
||||
HelpText<"Build ASTs and then debug dump their name lookup tables">;
|
||||
def ast_view : Flag<["-"], "ast-view">,
|
||||
@ -579,6 +596,8 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">,
|
||||
HelpText<"File is for a position independent executable">;
|
||||
def fno_validate_pch : Flag<["-"], "fno-validate-pch">,
|
||||
HelpText<"Disable validation of precompiled headers">;
|
||||
def fallow_pch_with_errors : Flag<["-"], "fallow-pch-with-compiler-errors">,
|
||||
HelpText<"Accept a PCH file that was created with compiler errors">;
|
||||
def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">,
|
||||
HelpText<"Dump declarations that are deserialized from PCH, for testing">;
|
||||
def error_on_deserialized_pch_decl : Separate<["-"], "error-on-deserialized-decl">,
|
||||
@ -643,6 +662,8 @@ def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">,
|
||||
HelpText<"Set default MS calling convention">;
|
||||
def finclude_default_header : Flag<["-"], "finclude-default-header">,
|
||||
HelpText<"Include the default header file for OpenCL">;
|
||||
def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">,
|
||||
HelpText<"Preserve 3-component vector type">;
|
||||
|
||||
// FIXME: Remove these entirely once functionality/tests have been excised.
|
||||
def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>,
|
||||
@ -658,6 +679,8 @@ def nostdsysteminc : Flag<["-"], "nostdsysteminc">,
|
||||
HelpText<"Disable standard system #include directories">;
|
||||
def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">,
|
||||
HelpText<"Disable the module hash">;
|
||||
def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">,
|
||||
HelpText<"Enable hashing the content of a module file">;
|
||||
def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">,
|
||||
HelpText<"Add directory to the C SYSTEM include search path">;
|
||||
def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
|
||||
|
@ -11,7 +11,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def cl_Group : OptionGroup<"<clang-cl options>">,
|
||||
def cl_Group : OptionGroup<"<clang-cl options>">, Flags<[CLOption]>,
|
||||
HelpText<"CL.EXE COMPATIBILITY OPTIONS">;
|
||||
|
||||
def cl_compile_Group : OptionGroup<"<clang-cl compile-only options>">,
|
||||
|
@ -0,0 +1,36 @@
|
||||
//==--- ClangOptionDocs.td - Option documentation -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def GlobalDocumentation {
|
||||
code Intro =[{..
|
||||
-------------------------------------------------------------------
|
||||
NOTE: This file is automatically generated by running clang-tblgen
|
||||
-gen-opt-docs. Do not edit this file by hand!!
|
||||
-------------------------------------------------------------------
|
||||
|
||||
=====================================
|
||||
Clang command line argument reference
|
||||
=====================================
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This page lists the command line arguments currently supported by the
|
||||
GCC-compatible ``clang`` and ``clang++`` drivers.
|
||||
|
||||
}];
|
||||
|
||||
string Program = "clang";
|
||||
list<string> ExcludedFlags = ["HelpHidden", "NoDriverOption",
|
||||
"CLOption", "Unsupported", "Ignored"];
|
||||
}
|
||||
|
||||
include "Options.td"
|
@ -14,6 +14,7 @@
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Driver/Action.h"
|
||||
#include "clang/Driver/Phases.h"
|
||||
#include "clang/Driver/ToolChain.h"
|
||||
#include "clang/Driver/Types.h"
|
||||
#include "clang/Driver/Util.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
@ -62,7 +63,7 @@ enum LTOKind {
|
||||
/// Driver - Encapsulate logic for constructing compilation processes
|
||||
/// from a set of gcc-driver-like command line arguments.
|
||||
class Driver {
|
||||
llvm::opt::OptTable *Opts;
|
||||
std::unique_ptr<llvm::opt::OptTable> Opts;
|
||||
|
||||
DiagnosticsEngine &Diags;
|
||||
|
||||
@ -215,6 +216,11 @@ class Driver {
|
||||
/// Use lazy precompiled headers for PCH support.
|
||||
unsigned CCCUsePCH : 1;
|
||||
|
||||
/// Force clang to emit reproducer for driver invocation. This is enabled
|
||||
/// indirectly by setting FORCE_CLANG_DIAGNOSTICS_CRASH environment variable
|
||||
/// or when using the -gen-reproducer driver flag.
|
||||
unsigned GenReproducer : 1;
|
||||
|
||||
private:
|
||||
/// Certain options suppress the 'no input files' warning.
|
||||
unsigned SuppressMissingInputWarning : 1;
|
||||
@ -227,7 +233,7 @@ class Driver {
|
||||
/// This maps from the string representation of a triple to a ToolChain
|
||||
/// created targeting that triple. The driver owns all the ToolChain objects
|
||||
/// stored in it, and will clean them up when torn down.
|
||||
mutable llvm::StringMap<ToolChain *> ToolChains;
|
||||
mutable llvm::StringMap<std::unique_ptr<ToolChain>> ToolChains;
|
||||
|
||||
private:
|
||||
/// TranslateInputArgs - Create a new derived argument list from the input
|
||||
@ -264,7 +270,6 @@ class Driver {
|
||||
Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,
|
||||
DiagnosticsEngine &Diags,
|
||||
IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
|
||||
~Driver();
|
||||
|
||||
/// @name Accessors
|
||||
/// @{
|
||||
@ -304,13 +309,8 @@ class Driver {
|
||||
bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }
|
||||
|
||||
bool embedBitcodeEnabled() const { return BitcodeEmbed != EmbedNone; }
|
||||
bool embedBitcodeInObject() const {
|
||||
// LTO has no object file output so ignore embed bitcode option in LTO.
|
||||
return (BitcodeEmbed == EmbedBitcode) && !isUsingLTO();
|
||||
}
|
||||
bool embedBitcodeMarkerOnly() const {
|
||||
return (BitcodeEmbed == EmbedMarker) && !isUsingLTO();
|
||||
}
|
||||
bool embedBitcodeInObject() const { return (BitcodeEmbed == EmbedBitcode); }
|
||||
bool embedBitcodeMarkerOnly() const { return (BitcodeEmbed == EmbedMarker); }
|
||||
|
||||
/// Compute the desired OpenMP runtime from the flags provided.
|
||||
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define LLVM_CLANG_DRIVER_JOB_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/iterator.h"
|
||||
#include "llvm/Option/Option.h"
|
||||
@ -69,6 +70,9 @@ class Command {
|
||||
/// file
|
||||
std::string ResponseFileFlag;
|
||||
|
||||
/// See Command::setEnvironment
|
||||
std::vector<const char *> Environment;
|
||||
|
||||
/// When a response file is needed, we try to put most arguments in an
|
||||
/// exclusive file, while others remains as regular command line arguments.
|
||||
/// This functions fills a vector with the regular command line arguments,
|
||||
@ -111,6 +115,12 @@ class Command {
|
||||
InputFileList = std::move(List);
|
||||
}
|
||||
|
||||
/// \brief Sets the environment to be used by the new process.
|
||||
/// \param NewEnvironment An array of environment variables.
|
||||
/// \remark If the environment remains unset, then the environment
|
||||
/// from the parent process will be used.
|
||||
void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment);
|
||||
|
||||
const char *getExecutable() const { return Executable; }
|
||||
|
||||
const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
|
||||
|
@ -10,6 +10,8 @@
|
||||
#ifndef LLVM_CLANG_DRIVER_OPTIONS_H
|
||||
#define LLVM_CLANG_DRIVER_OPTIONS_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
namespace opt {
|
||||
class OptTable;
|
||||
@ -31,7 +33,8 @@ enum ClangFlags {
|
||||
CLOption = (1 << 9),
|
||||
CC1Option = (1 << 10),
|
||||
CC1AsOption = (1 << 11),
|
||||
NoDriverOption = (1 << 12)
|
||||
NoDriverOption = (1 << 12),
|
||||
Ignored = (1 << 13)
|
||||
};
|
||||
|
||||
enum ID {
|
||||
@ -44,7 +47,7 @@ enum ID {
|
||||
};
|
||||
}
|
||||
|
||||
llvm::opt::OptTable *createDriverOptTable();
|
||||
std::unique_ptr<llvm::opt::OptTable> createDriverOptTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,9 @@ def NoArgumentUnused : OptionFlag;
|
||||
// lines that use it.
|
||||
def Unsupported : OptionFlag;
|
||||
|
||||
// Ignored - The option is unsupported, and the driver will silently ignore it.
|
||||
def Ignored : OptionFlag;
|
||||
|
||||
// CoreOption - This is considered a "core" Clang option, available in both
|
||||
// clang and clang-cl modes.
|
||||
def CoreOption : OptionFlag;
|
||||
@ -50,72 +53,150 @@ def CC1AsOption : OptionFlag;
|
||||
// NoDriverOption - This option should not be accepted by the driver.
|
||||
def NoDriverOption : OptionFlag;
|
||||
|
||||
// A short name to show in documentation. The name will be interpreted as rST.
|
||||
class DocName<string name> { string DocName = name; }
|
||||
|
||||
// A brief description to show in documentation, interpreted as rST.
|
||||
class DocBrief<code descr> { code DocBrief = descr; }
|
||||
|
||||
// Indicates that this group should be flattened into its parent when generating
|
||||
// documentation.
|
||||
class DocFlatten { bit DocFlatten = 1; }
|
||||
|
||||
// Indicates that this warning is ignored, but accepted with a warning for
|
||||
// GCC compatibility.
|
||||
class IgnoredGCCCompat : Flags<[HelpHidden]> {}
|
||||
|
||||
/////////
|
||||
// Groups
|
||||
|
||||
def Action_Group : OptionGroup<"<action group>">, DocName<"Actions">,
|
||||
DocBrief<[{The action to perform on the input.}]>;
|
||||
|
||||
// Meta-group for options which are only used for compilation,
|
||||
// and not linking etc.
|
||||
def CompileOnly_Group : OptionGroup<"<CompileOnly group>">;
|
||||
def CompileOnly_Group : OptionGroup<"<CompileOnly group>">,
|
||||
DocName<"Compilation flags">, DocBrief<[{
|
||||
Flags controlling the behavior of Clang during compilation. These flags have
|
||||
no effect during actions that do not perform compilation.}]>;
|
||||
|
||||
def Action_Group : OptionGroup<"<action group>">;
|
||||
def Preprocessor_Group : OptionGroup<"<Preprocessor group>">,
|
||||
Group<CompileOnly_Group>,
|
||||
DocName<"Preprocessor flags">, DocBrief<[{
|
||||
Flags controlling the behavior of the Clang preprocessor.}]>;
|
||||
|
||||
def I_Group : OptionGroup<"<I group>">, Group<CompileOnly_Group>;
|
||||
def M_Group : OptionGroup<"<M group>">, Group<CompileOnly_Group>;
|
||||
def T_Group : OptionGroup<"<T group>">;
|
||||
def O_Group : OptionGroup<"<O group>">, Group<CompileOnly_Group>;
|
||||
def R_Group : OptionGroup<"<R group>">, Group<CompileOnly_Group>;
|
||||
def R_value_Group : OptionGroup<"<R (with value) group>">, Group<R_Group>;
|
||||
def W_Group : OptionGroup<"<W group>">, Group<CompileOnly_Group>;
|
||||
def W_value_Group : OptionGroup<"<W (with value) group>">, Group<W_Group>;
|
||||
def d_Group : OptionGroup<"<d group>">;
|
||||
def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
|
||||
def f_clang_Group : OptionGroup<"<f (clang-only) group>">, Group<CompileOnly_Group>;
|
||||
def g_Group : OptionGroup<"<g group>">;
|
||||
def gN_Group : OptionGroup<"<gN group>">, Group<g_Group>;
|
||||
def ggdbN_Group : OptionGroup<"<ggdbN group>">, Group<gN_Group>;
|
||||
def gTune_Group : OptionGroup<"<gTune group>">, Group<g_Group>;
|
||||
def g_flags_Group : OptionGroup<"<g flags group>">;
|
||||
def i_Group : OptionGroup<"<i group>">, Group<CompileOnly_Group>;
|
||||
def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>;
|
||||
def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>;
|
||||
def opencl_Group : OptionGroup<"<opencl group>">, Group<CompileOnly_Group>;
|
||||
def IncludePath_Group : OptionGroup<"<I/i group>">, Group<Preprocessor_Group>,
|
||||
DocName<"Include path management">,
|
||||
DocBrief<[{
|
||||
Flags controlling how ``#include``\s are resolved to files.}]>;
|
||||
|
||||
def I_Group : OptionGroup<"<I group>">, Group<IncludePath_Group>, DocFlatten;
|
||||
def i_Group : OptionGroup<"<i group>">, Group<IncludePath_Group>, DocFlatten;
|
||||
def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>, DocFlatten;
|
||||
|
||||
def M_Group : OptionGroup<"<M group>">, Group<Preprocessor_Group>,
|
||||
DocName<"Dependency file generation">, DocBrief<[{
|
||||
Flags controlling generation of a dependency file for ``make``-like build
|
||||
systems.}]>;
|
||||
|
||||
def d_Group : OptionGroup<"<d group>">, Group<Preprocessor_Group>,
|
||||
DocName<"Dumping preprocessor state">, DocBrief<[{
|
||||
Flags allowing the state of the preprocessor to be dumped in various ways.}]>;
|
||||
|
||||
def Diag_Group : OptionGroup<"<W/R group>">, Group<CompileOnly_Group>,
|
||||
DocName<"Diagnostic flags">, DocBrief<[{
|
||||
Flags controlling which warnings, errors, and remarks Clang will generate.
|
||||
See the :doc:`full list of warning and remark flags <DiagnosticsReference>`.}]>;
|
||||
|
||||
def R_Group : OptionGroup<"<R group>">, Group<Diag_Group>, DocFlatten;
|
||||
def R_value_Group : OptionGroup<"<R (with value) group>">, Group<R_Group>,
|
||||
DocFlatten;
|
||||
def W_Group : OptionGroup<"<W group>">, Group<Diag_Group>, DocFlatten;
|
||||
def W_value_Group : OptionGroup<"<W (with value) group>">, Group<W_Group>,
|
||||
DocFlatten;
|
||||
|
||||
def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>,
|
||||
DocName<"Target-independent compilation options">;
|
||||
|
||||
def f_clang_Group : OptionGroup<"<f (clang-only) group>">,
|
||||
Group<CompileOnly_Group>, DocFlatten;
|
||||
def pedantic_Group : OptionGroup<"<pedantic group>">, Group<f_Group>,
|
||||
DocFlatten;
|
||||
def opencl_Group : OptionGroup<"<opencl group>">, Group<f_Group>,
|
||||
DocName<"OpenCL flags">;
|
||||
|
||||
def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>,
|
||||
DocName<"Target-dependent compilation options">;
|
||||
|
||||
// Feature groups - these take command line options that correspond directly to
|
||||
// target specific features and can be translated directly from command line
|
||||
// options.
|
||||
def m_x86_Features_Group : OptionGroup<"<x86 features group>">,
|
||||
Group<m_Group>,
|
||||
Flags<[CoreOption]>;
|
||||
def m_hexagon_Features_Group : OptionGroup<"<hexagon features group>">,
|
||||
Group<m_Group>;
|
||||
def m_arm_Features_Group : OptionGroup<"<arm features group>">,
|
||||
Group<m_Group>;
|
||||
def m_aarch64_Features_Group : OptionGroup<"<aarch64 features group>">,
|
||||
Group<m_Group>;
|
||||
def m_ppc_Features_Group : OptionGroup<"<ppc features group>">,
|
||||
Group<m_Group>;
|
||||
def m_wasm_Features_Group : OptionGroup<"<wasm features group>">,
|
||||
Group<m_Group>;
|
||||
Group<m_Group>, DocName<"AARCH64">;
|
||||
def m_amdgpu_Features_Group : OptionGroup<"<amdgpu features group>">,
|
||||
Group<m_Group>;
|
||||
Group<m_Group>, DocName<"AMDGPU">;
|
||||
def m_arm_Features_Group : OptionGroup<"<arm features group>">,
|
||||
Group<m_Group>, DocName<"ARM">;
|
||||
def m_hexagon_Features_Group : OptionGroup<"<hexagon features group>">,
|
||||
Group<m_Group>, DocName<"Hexagon">;
|
||||
def m_ppc_Features_Group : OptionGroup<"<ppc features group>">,
|
||||
Group<m_Group>, DocName<"PowerPC">;
|
||||
def m_wasm_Features_Group : OptionGroup<"<wasm features group>">,
|
||||
Group<m_Group>, DocName<"WebAssembly">;
|
||||
def m_x86_Features_Group : OptionGroup<"<x86 features group>">,
|
||||
Group<m_Group>, Flags<[CoreOption]>, DocName<"X86">;
|
||||
|
||||
def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_Group>;
|
||||
def u_Group : OptionGroup<"<u group>">;
|
||||
def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_Group>,
|
||||
Flags<[HelpHidden]>;
|
||||
|
||||
def pedantic_Group : OptionGroup<"<pedantic group>">,
|
||||
Group<CompileOnly_Group>;
|
||||
def reserved_lib_Group : OptionGroup<"<reserved libs group>">;
|
||||
def O_Group : OptionGroup<"<O group>">, Group<CompileOnly_Group>,
|
||||
DocName<"Optimization level">, DocBrief<[{
|
||||
Flags controlling how much optimization should be performed.}]>;
|
||||
|
||||
def DebugInfo_Group : OptionGroup<"<g group>">, Group<CompileOnly_Group>,
|
||||
DocName<"Debug information generation">, DocBrief<[{
|
||||
Flags controlling how much and what kind of debug information should be
|
||||
generated.}]>;
|
||||
|
||||
def g_Group : OptionGroup<"<g group>">, Group<DebugInfo_Group>,
|
||||
DocName<"Kind and level of debug information">;
|
||||
def gN_Group : OptionGroup<"<gN group>">, Group<g_Group>,
|
||||
DocName<"Debug level">;
|
||||
def ggdbN_Group : OptionGroup<"<ggdbN group>">, Group<gN_Group>, DocFlatten;
|
||||
def gTune_Group : OptionGroup<"<gTune group>">, Group<g_Group>,
|
||||
DocName<"Debugger to tune debug information for">;
|
||||
def g_flags_Group : OptionGroup<"<g flags group>">, Group<DebugInfo_Group>,
|
||||
DocName<"Debug information flags">;
|
||||
|
||||
def StaticAnalyzer_Group : OptionGroup<"<Static analyzer group>">,
|
||||
DocName<"Static analyzer flags">, DocBrief<[{
|
||||
Flags controlling the behavior of the Clang Static Analyzer.}]>;
|
||||
|
||||
// gfortran options that we recognize in the driver and pass along when
|
||||
// invoking GCC to compile Fortran code.
|
||||
def gfortran_Group : OptionGroup<"<gfortran group>">,
|
||||
DocName<"Fortran compilation flags">, DocBrief<[{
|
||||
Flags that will be passed onto the ``gfortran`` compiler when Clang is given
|
||||
a Fortran input.}]>;
|
||||
|
||||
def Link_Group : OptionGroup<"<T/e/s/t/u group>">, DocName<"Linker flags">,
|
||||
DocBrief<[{Flags that are passed on to the linker}]>;
|
||||
def T_Group : OptionGroup<"<T group>">, Group<Link_Group>, DocFlatten;
|
||||
def u_Group : OptionGroup<"<u group>">, Group<Link_Group>, DocFlatten;
|
||||
|
||||
def reserved_lib_Group : OptionGroup<"<reserved libs group>">,
|
||||
Flags<[Unsupported]>;
|
||||
|
||||
// Temporary groups for clang options which we know we don't support,
|
||||
// but don't want to verbosely warn the user about.
|
||||
def clang_ignored_f_Group : OptionGroup<"<clang ignored f group>">,
|
||||
Group<f_Group>;
|
||||
Group<f_Group>, Flags<[Ignored]>;
|
||||
def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
|
||||
Group<m_Group>;
|
||||
Group<m_Group>, Flags<[Ignored]>;
|
||||
|
||||
// Group that ignores all gcc optimizations that won't be implemented
|
||||
def clang_ignored_gcc_optimization_f_Group : OptionGroup<
|
||||
"<clang_ignored_gcc_optimization_f_Group>">, Group<f_Group>;
|
||||
"<clang_ignored_gcc_optimization_f_Group>">, Group<f_Group>, Flags<[Ignored]>;
|
||||
|
||||
/////////
|
||||
// Options
|
||||
@ -141,7 +222,7 @@ def clang_ignored_gcc_optimization_f_Group : OptionGroup<
|
||||
|
||||
// Developer Driver Options
|
||||
|
||||
def internal_Group : OptionGroup<"<clang internal options>">;
|
||||
def internal_Group : OptionGroup<"<clang internal options>">, Flags<[HelpHidden]>;
|
||||
def internal_driver_Group : OptionGroup<"<clang driver internal options>">,
|
||||
Group<internal_Group>, HelpText<"DRIVER OPTIONS">;
|
||||
def internal_debug_Group :
|
||||
@ -184,6 +265,8 @@ def arcmt_migrate_report_output : Separate<["-"], "arcmt-migrate-report-output">
|
||||
def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">,
|
||||
HelpText<"Emit ARC errors even if the migrator can fix them">,
|
||||
Flags<[CC1Option]>;
|
||||
def gen_reproducer: Flag<["-"], "gen-reproducer">, InternalDebugOpt,
|
||||
HelpText<"Auto-generates preprocessed source files and a reproduction script">;
|
||||
|
||||
def _migrate : Flag<["--"], "migrate">, Flags<[DriverOption]>,
|
||||
HelpText<"Run the migrator">;
|
||||
@ -236,23 +319,34 @@ def _HASH_HASH_HASH : Flag<["-"], "###">, Flags<[DriverOption, CoreOption]>,
|
||||
HelpText<"Print (but do not run) the commands to run for this compilation">;
|
||||
def _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>,
|
||||
Flags<[DriverOption, CoreOption]>;
|
||||
def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>;
|
||||
def B : JoinedOrSeparate<["-"], "B">;
|
||||
def CC : Flag<["-"], "CC">, Flags<[CC1Option]>;
|
||||
def C : Flag<["-"], "C">, Flags<[CC1Option]>;
|
||||
def D : JoinedOrSeparate<["-"], "D">, Group<CompileOnly_Group>, Flags<[CC1Option]>;
|
||||
def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>, Group<gfortran_Group>;
|
||||
def B : JoinedOrSeparate<["-"], "B">, MetaVarName<"<dir>">,
|
||||
HelpText<"Add <dir> to search path for binaries and object files used implicitly">;
|
||||
def CC : Flag<["-"], "CC">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
|
||||
HelpText<"Include comments from within macros in preprocessed output">;
|
||||
def C : Flag<["-"], "C">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
|
||||
HelpText<"Include comments in preprocessed output">;
|
||||
def D : JoinedOrSeparate<["-"], "D">, Group<Preprocessor_Group>,
|
||||
Flags<[CC1Option]>, MetaVarName<"<macro>=<value>">,
|
||||
HelpText<"Define <macro> to <value> (or 1 if <value> omitted)">;
|
||||
def E : Flag<["-"], "E">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
|
||||
HelpText<"Only run the preprocessor">;
|
||||
HelpText<"Only run the preprocessor">;
|
||||
def F : JoinedOrSeparate<["-"], "F">, Flags<[RenderJoined,CC1Option]>,
|
||||
HelpText<"Add directory to framework include search path">;
|
||||
def G : JoinedOrSeparate<["-"], "G">, Flags<[DriverOption]>;
|
||||
def G_EQ : Joined<["-"], "G=">, Flags<[DriverOption]>;
|
||||
def H : Flag<["-"], "H">, Flags<[CC1Option]>,
|
||||
def G : JoinedOrSeparate<["-"], "G">, Flags<[DriverOption]>, Group<m_Group>,
|
||||
MetaVarName<"<size>">, HelpText<"Put objects of at most <size> bytes "
|
||||
"into small data section (MIPS / Hexagon)">;
|
||||
def G_EQ : Joined<["-"], "G=">, Flags<[DriverOption]>, Group<m_Group>, Alias<G>;
|
||||
def H : Flag<["-"], "H">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
|
||||
HelpText<"Show header includes and nesting depth">;
|
||||
def I_ : Flag<["-"], "I-">, Group<I_Group>;
|
||||
def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>, Flags<[CC1Option,CC1AsOption]>,
|
||||
def I_ : Flag<["-"], "I-">, Group<I_Group>,
|
||||
HelpText<"Restrict all prior -I flags to double-quoted inclusion and "
|
||||
"remove current directory from include path">;
|
||||
def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>,
|
||||
Flags<[CC1Option,CC1AsOption]>, MetaVarName<"<dir>">,
|
||||
HelpText<"Add directory to include search path">;
|
||||
def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>;
|
||||
def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>, Group<Link_Group>,
|
||||
MetaVarName<"<dir>">, HelpText<"Add directory to library search path">;
|
||||
def MD : Flag<["-"], "MD">, Group<M_Group>,
|
||||
HelpText<"Write a depfile containing user and system headers">;
|
||||
def MMD : Flag<["-"], "MMD">, Group<M_Group>,
|
||||
@ -276,9 +370,9 @@ def MT : JoinedOrSeparate<["-"], "MT">, Group<M_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Specify name of main file output in depfile">;
|
||||
def MV : Flag<["-"], "MV">, Group<M_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Use NMake/Jom format for the depfile">;
|
||||
def Mach : Flag<["-"], "Mach">;
|
||||
def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option]>;
|
||||
def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option]>;
|
||||
def Mach : Flag<["-"], "Mach">, Group<Link_Group>;
|
||||
def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option, HelpHidden]>;
|
||||
def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option, HelpHidden]>;
|
||||
def ObjCXX : Flag<["-"], "ObjC++">, Flags<[DriverOption]>,
|
||||
HelpText<"Treat source input files as Objective-C++ inputs">;
|
||||
def ObjC : Flag<["-"], "ObjC">, Flags<[DriverOption]>,
|
||||
@ -286,12 +380,12 @@ def ObjC : Flag<["-"], "ObjC">, Flags<[DriverOption]>,
|
||||
def O : Joined<["-"], "O">, Group<O_Group>, Flags<[CC1Option]>;
|
||||
def O_flag : Flag<["-"], "O">, Flags<[CC1Option]>, Alias<O>, AliasArgs<["2"]>;
|
||||
def Ofast : Joined<["-"], "Ofast">, Group<O_Group>, Flags<[CC1Option]>;
|
||||
def P : Flag<["-"], "P">, Flags<[CC1Option]>,
|
||||
def P : Flag<["-"], "P">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
|
||||
HelpText<"Disable linemarker output in -E mode">;
|
||||
def Qn : Flag<["-"], "Qn">;
|
||||
def Qn : Flag<["-"], "Qn">, IgnoredGCCCompat;
|
||||
def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[DriverOption, CoreOption]>,
|
||||
HelpText<"Don't emit warning for unused driver arguments">;
|
||||
def Q : Flag<["-"], "Q">;
|
||||
def Q : Flag<["-"], "Q">, IgnoredGCCCompat;
|
||||
def Rpass_EQ : Joined<["-"], "Rpass=">, Group<R_value_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Report transformations performed by optimization passes whose "
|
||||
"name matches the given POSIX regular expression">;
|
||||
@ -307,23 +401,28 @@ def R_Joined : Joined<["-"], "R">, Group<R_Group>, Flags<[CC1Option, CoreOption]
|
||||
MetaVarName<"<remark>">, HelpText<"Enable the specified remark">;
|
||||
def S : Flag<["-"], "S">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
|
||||
HelpText<"Only run preprocess and compilation steps">;
|
||||
def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>;
|
||||
def Tdata : JoinedOrSeparate<["-"], "Tdata">, Group<T_Group>;
|
||||
def Ttext : JoinedOrSeparate<["-"], "Ttext">, Group<T_Group>;
|
||||
def T : JoinedOrSeparate<["-"], "T">, Group<T_Group>;
|
||||
def U : JoinedOrSeparate<["-"], "U">, Group<CompileOnly_Group>, Flags<[CC1Option]>;
|
||||
def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>,
|
||||
MetaVarName<"<addr>">, HelpText<"Set starting address of BSS to <addr>">;
|
||||
def Tdata : JoinedOrSeparate<["-"], "Tdata">, Group<T_Group>,
|
||||
MetaVarName<"<addr>">, HelpText<"Set starting address of BSS to <addr>">;
|
||||
def Ttext : JoinedOrSeparate<["-"], "Ttext">, Group<T_Group>,
|
||||
MetaVarName<"<addr>">, HelpText<"Set starting address of BSS to <addr>">;
|
||||
def T : JoinedOrSeparate<["-"], "T">, Group<T_Group>,
|
||||
MetaVarName<"<script>">, HelpText<"Specify <script> as linker script">;
|
||||
def U : JoinedOrSeparate<["-"], "U">, Group<Preprocessor_Group>,
|
||||
Flags<[CC1Option]>, MetaVarName<"<macro>">, HelpText<"Undefine macro <macro>">;
|
||||
def V : JoinedOrSeparate<["-"], "V">, Flags<[DriverOption, Unsupported]>;
|
||||
def Wa_COMMA : CommaJoined<["-"], "Wa,">,
|
||||
HelpText<"Pass the comma separated arguments in <arg> to the assembler">,
|
||||
MetaVarName<"<arg>">;
|
||||
def Wall : Flag<["-"], "Wall">, Group<W_Group>, Flags<[CC1Option]>;
|
||||
def WCL4 : Flag<["-"], "WCL4">, Group<W_Group>, Flags<[CC1Option]>;
|
||||
def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>, Flags<[CC1Option]>;
|
||||
def Wall : Flag<["-"], "Wall">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
|
||||
def WCL4 : Flag<["-"], "WCL4">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
|
||||
def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Enable warnings for deprecated constructs and define __DEPRECATED">;
|
||||
def Wno_deprecated : Flag<["-"], "Wno-deprecated">, Group<W_Group>, Flags<[CC1Option]>;
|
||||
def Wextra : Flag<["-"], "Wextra">, Group<W_Group>, Flags<[CC1Option]>;
|
||||
def Wl_COMMA : CommaJoined<["-"], "Wl,">, Flags<[LinkerInput, RenderAsInput]>,
|
||||
HelpText<"Pass the comma separated arguments in <arg> to the linker">,
|
||||
MetaVarName<"<arg>">;
|
||||
MetaVarName<"<arg>">, Group<Link_Group>;
|
||||
// FIXME: This is broken; these should not be Joined arguments.
|
||||
def Wno_nonportable_cfstrings : Joined<["-"], "Wno-nonportable-cfstrings">, Group<W_Group>,
|
||||
Flags<[CC1Option]>;
|
||||
@ -331,16 +430,18 @@ def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group<W_Gr
|
||||
Flags<[CC1Option]>;
|
||||
def Wp_COMMA : CommaJoined<["-"], "Wp,">,
|
||||
HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
|
||||
MetaVarName<"<arg>">;
|
||||
def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option]>;
|
||||
def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option]>;
|
||||
MetaVarName<"<arg>">, Group<Preprocessor_Group>;
|
||||
def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
|
||||
def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
|
||||
def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>,
|
||||
MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
|
||||
def Xanalyzer : Separate<["-"], "Xanalyzer">,
|
||||
HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">;
|
||||
HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">,
|
||||
Group<StaticAnalyzer_Group>;
|
||||
def Xarch__ : JoinedAndSeparate<["-"], "Xarch_">, Flags<[DriverOption]>;
|
||||
def Xassembler : Separate<["-"], "Xassembler">,
|
||||
HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">;
|
||||
HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">,
|
||||
Group<CompileOnly_Group>;
|
||||
def Xclang : Separate<["-"], "Xclang">,
|
||||
HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">,
|
||||
Flags<[DriverOption, CoreOption]>, Group<CompileOnly_Group>;
|
||||
@ -349,14 +450,17 @@ def Xcuda_fatbinary : Separate<["-"], "Xcuda-fatbinary">,
|
||||
def Xcuda_ptxas : Separate<["-"], "Xcuda-ptxas">,
|
||||
HelpText<"Pass <arg> to the ptxas assembler">, MetaVarName<"<arg>">;
|
||||
def z : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>,
|
||||
HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">;
|
||||
HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">,
|
||||
Group<Link_Group>;
|
||||
def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
|
||||
HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">;
|
||||
def Xpreprocessor : Separate<["-"], "Xpreprocessor">,
|
||||
HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">,
|
||||
Group<Link_Group>;
|
||||
def Xpreprocessor : Separate<["-"], "Xpreprocessor">, Group<Preprocessor_Group>,
|
||||
HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">;
|
||||
def X_Flag : Flag<["-"], "X">;
|
||||
def X_Joined : Joined<["-"], "X">;
|
||||
def Z_Flag : Flag<["-"], "Z">;
|
||||
def X_Flag : Flag<["-"], "X">, Group<Link_Group>;
|
||||
def X_Joined : Joined<["-"], "X">, IgnoredGCCCompat;
|
||||
def Z_Flag : Flag<["-"], "Z">, Group<Link_Group>;
|
||||
// FIXME: All we do with this is reject it. Remove.
|
||||
def Z_Joined : Joined<["-"], "Z">;
|
||||
def all__load : Flag<["-"], "all_load">;
|
||||
def allowable__client : Separate<["-"], "allowable_client">;
|
||||
@ -402,7 +506,7 @@ def current__version : JoinedOrSeparate<["-"], "current_version">;
|
||||
def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>,
|
||||
HelpText<"Add directory to the C++ SYSTEM include search path">, Flags<[CC1Option]>,
|
||||
MetaVarName<"<directory>">;
|
||||
def c : Flag<["-"], "c">, Flags<[DriverOption]>,
|
||||
def c : Flag<["-"], "c">, Flags<[DriverOption]>, Group<Action_Group>,
|
||||
HelpText<"Only run preprocess, compile, and assemble steps">;
|
||||
def cuda_device_only : Flag<["--"], "cuda-device-only">,
|
||||
HelpText<"Compile CUDA code for device only">;
|
||||
@ -462,7 +566,7 @@ def emit_ast : Flag<["-"], "emit-ast">,
|
||||
def emit_llvm : Flag<["-"], "emit-llvm">, Flags<[CC1Option]>, Group<Action_Group>,
|
||||
HelpText<"Use the LLVM representation for assembler and object files">;
|
||||
def exported__symbols__list : Separate<["-"], "exported_symbols_list">;
|
||||
def e : JoinedOrSeparate<["-"], "e">;
|
||||
def e : JoinedOrSeparate<["-"], "e">, Group<Link_Group>;
|
||||
def fPIC : Flag<["-"], "fPIC">, Group<f_Group>;
|
||||
def fno_PIC : Flag<["-"], "fno-PIC">, Group<f_Group>;
|
||||
def fPIE : Flag<["-"], "fPIE">, Group<f_Group>;
|
||||
@ -511,14 +615,28 @@ def fno_gnu_inline_asm : Flag<["-"], "fno-gnu-inline-asm">, Group<f_Group>,
|
||||
Flags<[DriverOption, CC1Option]>,
|
||||
HelpText<"Disable GNU style inline asm">;
|
||||
|
||||
def fprofile_sample_use : Flag<["-"], "fprofile-sample-use">, Group<f_Group>,
|
||||
Flags<[CoreOption]>;
|
||||
def fno_profile_sample_use : Flag<["-"], "fno-profile-sample-use">, Group<f_Group>,
|
||||
Flags<[CoreOption]>;
|
||||
def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">,
|
||||
Group<f_Group>, Flags<[DriverOption, CC1Option]>,
|
||||
HelpText<"Enable sample-based profile guided optimizations">;
|
||||
def fauto_profile : Flag<["-"], "fauto-profile">, Group<f_Group>,
|
||||
Alias<fprofile_sample_use>;
|
||||
def fno_auto_profile : Flag<["-"], "fno-auto-profile">, Group<f_Group>,
|
||||
Alias<fno_profile_sample_use>;
|
||||
def fauto_profile_EQ : Joined<["-"], "fauto-profile=">,
|
||||
Alias<fprofile_sample_use_EQ>;
|
||||
def fdebug_info_for_profiling : Flag<["-"], "fdebug-info-for-profiling">, Group<f_Group>,
|
||||
Flags<[CC1Option]>,
|
||||
HelpText<"Emit extra debug info to make sample profile more accurate.">;
|
||||
def fno_debug_info_for_profiling : Flag<["-"], "fno-debug-info-for-profiling">, Group<f_Group>,
|
||||
Flags<[DriverOption]>,
|
||||
HelpText<"Do not emit extra debug info for sample profiler.">;
|
||||
def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
|
||||
Group<f_Group>, Flags<[CoreOption]>,
|
||||
HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overriden by '=' form of option or LLVM_PROFILE_FILE env var)">;
|
||||
HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
|
||||
def fprofile_instr_generate_EQ : Joined<["-"], "fprofile-instr-generate=">,
|
||||
Group<f_Group>, Flags<[CoreOption]>, MetaVarName<"<file>">,
|
||||
HelpText<"Generate instrumented code to collect execution counts into <file> (overridden by LLVM_PROFILE_FILE env var)">;
|
||||
@ -585,7 +703,8 @@ def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>;
|
||||
def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>;
|
||||
def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">,
|
||||
Group<f_Group>;
|
||||
def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>;
|
||||
def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>,
|
||||
HelpText<"Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash">;
|
||||
def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>;
|
||||
def fcxx_exceptions: Flag<["-"], "fcxx-exceptions">, Group<f_Group>,
|
||||
HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>;
|
||||
@ -659,65 +778,71 @@ def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>;
|
||||
def fjump_tables : Flag<["-"], "fjump-tables">, Group<f_Group>;
|
||||
def fno_jump_tables : Flag<["-"], "fno-jump-tables">, Group<f_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Do not use jump tables for lowering switches">;
|
||||
|
||||
// Begin sanitizer flags. These should all be core options exposed in all driver
|
||||
// modes.
|
||||
let Flags = [CC1Option, CoreOption] in {
|
||||
|
||||
def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>,
|
||||
Flags<[CC1Option, CoreOption]>, MetaVarName<"<check>">,
|
||||
MetaVarName<"<check>">,
|
||||
HelpText<"Turn on runtime checks for various forms of undefined "
|
||||
"or suspicious behavior. See user manual for available checks">;
|
||||
def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>,
|
||||
Flags<[CoreOption]>;
|
||||
Flags<[CoreOption, DriverOption]>;
|
||||
def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option, CoreOption]>,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Path to blacklist file for sanitizers">;
|
||||
def fno_sanitize_blacklist : Flag<["-"], "fno-sanitize-blacklist">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Don't use blacklist file for sanitizers">;
|
||||
def fsanitize_coverage
|
||||
: CommaJoined<["-"], "fsanitize-coverage=">,
|
||||
Group<f_clang_Group>, Flags<[CoreOption]>,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Specify the type of coverage instrumentation for Sanitizers">;
|
||||
def fno_sanitize_coverage
|
||||
: CommaJoined<["-"], "fno-sanitize-coverage=">,
|
||||
Group<f_clang_Group>, Flags<[CoreOption]>,
|
||||
Group<f_clang_Group>, Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable specified features of coverage instrumentation for "
|
||||
"Sanitizers">;
|
||||
def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable origins tracking in MemorySanitizer">;
|
||||
def fsanitize_memory_track_origins : Flag<["-"], "fsanitize-memory-track-origins">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable origins tracking in MemorySanitizer">;
|
||||
def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Group<f_clang_Group>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable origins tracking in MemorySanitizer">;
|
||||
def fsanitize_memory_use_after_dtor : Flag<["-"], "fsanitize-memory-use-after-dtor">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable use-after-destroy detection in MemorySanitizer">;
|
||||
def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-padding=">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Level of field padding for AddressSanitizer">;
|
||||
def fsanitize_address_use_after_scope : Flag<["-"], "fsanitize-address-use-after-scope">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable use-after-scope detection in AddressSanitizer">;
|
||||
def fno_sanitize_address_use_after_scope : Flag<["-"], "fno-sanitize-address-use-after-scope">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Group<f_clang_Group>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable use-after-scope detection in AddressSanitizer">;
|
||||
def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>,
|
||||
Flags<[CoreOption]>;
|
||||
def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>;
|
||||
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
|
||||
Group<f_clang_Group>, Flags<[CoreOption]>;
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
Group<f_clang_Group>;
|
||||
def fsanitize_recover_EQ : CommaJoined<["-"], "fsanitize-recover=">,
|
||||
Group<f_clang_Group>,
|
||||
Flags<[CC1Option, CoreOption]>,
|
||||
HelpText<"Enable recovery for specified sanitizers">;
|
||||
def fno_sanitize_recover_EQ
|
||||
: CommaJoined<["-"], "fno-sanitize-recover=">,
|
||||
Group<f_clang_Group>, Flags<[CoreOption]>,
|
||||
Group<f_clang_Group>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable recovery for specified sanitizers">;
|
||||
def fsanitize_trap_EQ : CommaJoined<["-"], "fsanitize-trap=">, Group<f_clang_Group>,
|
||||
Flags<[CC1Option, CoreOption]>,
|
||||
HelpText<"Enable trapping for specified sanitizers">;
|
||||
def fno_sanitize_trap_EQ : CommaJoined<["-"], "fno-sanitize-trap=">, Group<f_clang_Group>,
|
||||
Flags<[CoreOption]>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable trapping for specified sanitizers">;
|
||||
def fsanitize_undefined_trap_on_error : Flag<["-"], "fsanitize-undefined-trap-on-error">,
|
||||
Group<f_clang_Group>;
|
||||
@ -726,39 +851,47 @@ def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-t
|
||||
def fsanitize_link_cxx_runtime : Flag<["-"], "fsanitize-link-c++-runtime">,
|
||||
Group<f_clang_Group>;
|
||||
def fsanitize_cfi_cross_dso : Flag<["-"], "fsanitize-cfi-cross-dso">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable control flow integrity (CFI) checks for cross-DSO calls.">;
|
||||
def fno_sanitize_cfi_cross_dso : Flag<["-"], "fno-sanitize-cfi-cross-dso">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Disable control flow integrity (CFI) checks for cross-DSO calls.">;
|
||||
def fsanitize_stats : Flag<["-"], "fsanitize-stats">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable sanitizer statistics gathering.">;
|
||||
def fno_sanitize_stats : Flag<["-"], "fno-sanitize-stats">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
Group<f_clang_Group>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable sanitizer statistics gathering.">;
|
||||
def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable memory access instrumentation in ThreadSanitizer (default)">;
|
||||
def fno_sanitize_thread_memory_access : Flag<["-"], "fno-sanitize-thread-memory-access">,
|
||||
Group<f_clang_Group>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable memory access instrumentation in ThreadSanitizer">;
|
||||
def fsanitize_thread_func_entry_exit : Flag<["-"], "fsanitize-thread-func-entry-exit">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable function entry/exit instrumentation in ThreadSanitizer (default)">;
|
||||
def fno_sanitize_thread_func_entry_exit : Flag<["-"], "fno-sanitize-thread-func-entry-exit">,
|
||||
Group<f_clang_Group>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable function entry/exit instrumentation in ThreadSanitizer">;
|
||||
def fsanitize_thread_atomics : Flag<["-"], "fsanitize-thread-atomics">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable atomic operations instrumentation in ThreadSanitizer (default)">;
|
||||
def fno_sanitize_thread_atomics : Flag<["-"], "fno-sanitize-thread-atomics">,
|
||||
Group<f_clang_Group>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable atomic operations instrumentation in ThreadSanitizer">;
|
||||
def fsanitize_undefined_strip_path_components_EQ : Joined<["-"], "fsanitize-undefined-strip-path-components=">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>, MetaVarName<"<number>">,
|
||||
Group<f_clang_Group>, MetaVarName<"<number>">,
|
||||
HelpText<"Strip (or keep only, if negative) a given number of path components "
|
||||
"when emitting check metadata.">;
|
||||
|
||||
} // end -f[no-]sanitize* flags
|
||||
|
||||
def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">,
|
||||
Group<f_Group>;
|
||||
def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">,
|
||||
@ -816,12 +949,13 @@ def fno_gnu89_inline : Flag<["-"], "fno-gnu89-inline">, Group<f_Group>;
|
||||
def fgnu_runtime : Flag<["-"], "fgnu-runtime">, Group<f_Group>,
|
||||
HelpText<"Generate output compatible with the standard GNU Objective-C runtime">;
|
||||
def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>;
|
||||
def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>;
|
||||
def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>,
|
||||
Group<Link_Group>;
|
||||
def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
|
||||
def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Inline suitable functions">;
|
||||
def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Inline functions wich are (explicitly or implicitly) marked inline">;
|
||||
HelpText<"Inline functions which are (explicitly or implicitly) marked inline">;
|
||||
def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
|
||||
def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">,
|
||||
Group<f_clang_Group>, Flags<[CC1Option]>,
|
||||
@ -845,10 +979,19 @@ def fxray_instruction_threshold_ :
|
||||
JoinedOrSeparate<["-"], "fxray-instruction-threshold">,
|
||||
Group<f_Group>, Flags<[CC1Option]>;
|
||||
|
||||
def fxray_always_instrument :
|
||||
JoinedOrSeparate<["-"], "fxray-always-instrument=">,
|
||||
Group<f_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Filename defining the whitelist for imbuing the 'always instrument' XRay attribute.">;
|
||||
def fxray_never_instrument :
|
||||
JoinedOrSeparate<["-"], "fxray-never-instrument=">,
|
||||
Group<f_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">;
|
||||
|
||||
def flat__namespace : Flag<["-"], "flat_namespace">;
|
||||
def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>;
|
||||
def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
|
||||
def flto_EQ : Joined<["-"], "flto=">, Flags<[CC1Option]>, Group<f_Group>,
|
||||
def flto_EQ : Joined<["-"], "flto=">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
|
||||
HelpText<"Set LTO mode to either 'full' or 'thin'">;
|
||||
def flto : Flag<["-"], "flto">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
|
||||
HelpText<"Enable LTO in 'full' mode">;
|
||||
@ -1213,6 +1356,10 @@ def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>,
|
||||
HelpText<"Limit debug information produced to reduce size of debug binary">;
|
||||
def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Flags<[CoreOption]>, Alias<fno_standalone_debug>;
|
||||
def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Flags<[CoreOption]>, Alias<fstandalone_debug>;
|
||||
def fdebug_macro : Flag<["-"], "fdebug-macro">, Group<f_Group>, Flags<[CoreOption]>,
|
||||
HelpText<"Emit macro debug information">;
|
||||
def fno_debug_macro : Flag<["-"], "fno-debug-macro">, Group<f_Group>, Flags<[CoreOption]>,
|
||||
HelpText<"Do not emit macro debug information">;
|
||||
def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>,
|
||||
Flags<[DriverOption, CoreOption]>;
|
||||
def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>,
|
||||
@ -1335,8 +1482,8 @@ def fno_unique_section_names : Flag <["-"], "fno-unique-section-names">,
|
||||
|
||||
def fstrict_return : Flag<["-"], "fstrict-return">, Group<f_Group>,
|
||||
Flags<[CC1Option]>,
|
||||
HelpText<"Always treat control flow paths that fall off the end of a non-void"
|
||||
"function as unreachable">;
|
||||
HelpText<"Always treat control flow paths that fall off the end of a "
|
||||
"non-void function as unreachable">;
|
||||
def fno_strict_return : Flag<["-"], "fno-strict-return">, Group<f_Group>,
|
||||
Flags<[CC1Option]>;
|
||||
|
||||
@ -1411,6 +1558,11 @@ def idirafter : JoinedOrSeparate<["-"], "idirafter">, Group<clang_i_Group>, Flag
|
||||
HelpText<"Add directory to AFTER include search path">;
|
||||
def iframework : JoinedOrSeparate<["-"], "iframework">, Group<clang_i_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Add directory to SYSTEM framework search path">;
|
||||
def iframeworkwithsysroot : JoinedOrSeparate<["-"], "iframeworkwithsysroot">,
|
||||
Group<clang_i_Group>,
|
||||
HelpText<"Add directory to SYSTEM framework search path, "
|
||||
"absolute paths are relative to -isysroot">,
|
||||
MetaVarName<"<directory>">, Flags<[CC1Option]>;
|
||||
def imacros : JoinedOrSeparate<["-", "--"], "imacros">, Group<clang_i_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Include macros from file before parsing">, MetaVarName<"<file>">;
|
||||
def image__base : Separate<["-"], "image_base">;
|
||||
@ -1449,7 +1601,8 @@ def ivfsoverlay : JoinedOrSeparate<["-"], "ivfsoverlay">, Group<clang_i_Group>,
|
||||
HelpText<"Overlay the virtual filesystem described by file over the real file system">;
|
||||
def i : Joined<["-"], "i">, Group<i_Group>;
|
||||
def keep__private__externs : Flag<["-"], "keep_private_externs">;
|
||||
def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>;
|
||||
def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>,
|
||||
Group<Link_Group>;
|
||||
def lazy__framework : Separate<["-"], "lazy_framework">, Flags<[LinkerInput]>;
|
||||
def lazy__library : Separate<["-"], "lazy_library">, Flags<[LinkerInput]>;
|
||||
def mlittle_endian : Flag<["-"], "mlittle-endian">, Flags<[DriverOption]>;
|
||||
@ -1484,11 +1637,11 @@ def mpure_code : Flag<["-"], "mpure-code">, Alias<mexecute_only>; // Alias for G
|
||||
def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias<mno_execute_only>;
|
||||
def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>;
|
||||
def mappletvos_version_min_EQ : Joined<["-"], "mappletvos-version-min=">, Alias<mtvos_version_min_EQ>;
|
||||
def mtvos_simulator_version_min_EQ : Joined<["-"], "mtvos-simulator-version-min=">, Alias<mtvos_version_min_EQ>;
|
||||
def mappletvsimulator_version_min_EQ : Joined<["-"], "mappletvsimulator-version-min=">, Alias<mtvos_version_min_EQ>;
|
||||
def mtvos_simulator_version_min_EQ : Joined<["-"], "mtvos-simulator-version-min=">;
|
||||
def mappletvsimulator_version_min_EQ : Joined<["-"], "mappletvsimulator-version-min=">, Alias<mtvos_simulator_version_min_EQ>;
|
||||
def mwatchos_version_min_EQ : Joined<["-"], "mwatchos-version-min=">, Group<m_Group>;
|
||||
def mwatchos_simulator_version_min_EQ : Joined<["-"], "mwatchos-simulator-version-min=">, Alias<mwatchos_version_min_EQ>;
|
||||
def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=">, Alias<mwatchos_version_min_EQ>;
|
||||
def mwatchos_simulator_version_min_EQ : Joined<["-"], "mwatchos-simulator-version-min=">;
|
||||
def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=">, Alias<mwatchos_simulator_version_min_EQ>;
|
||||
def march_EQ : Joined<["-"], "march=">, Group<m_Group>;
|
||||
def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>;
|
||||
def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>;
|
||||
@ -1517,8 +1670,8 @@ def mhard_float : Flag<["-"], "mhard-float">, Group<m_Group>;
|
||||
def miphoneos_version_min_EQ : Joined<["-"], "miphoneos-version-min=">, Group<m_Group>;
|
||||
def mios_version_min_EQ : Joined<["-"], "mios-version-min=">,
|
||||
Alias<miphoneos_version_min_EQ>, HelpText<"Set iOS deployment target">;
|
||||
def mios_simulator_version_min_EQ : Joined<["-"], "mios-simulator-version-min=">, Alias<miphoneos_version_min_EQ>;
|
||||
def miphonesimulator_version_min_EQ : Joined<["-"], "miphonesimulator-version-min=">, Alias<miphoneos_version_min_EQ>;
|
||||
def mios_simulator_version_min_EQ : Joined<["-"], "mios-simulator-version-min=">;
|
||||
def miphonesimulator_version_min_EQ : Joined<["-"], "miphonesimulator-version-min=">, Alias<mios_simulator_version_min_EQ>;
|
||||
def mkernel : Flag<["-"], "mkernel">, Group<m_Group>;
|
||||
def mlinker_version_EQ : Joined<["-"], "mlinker-version=">,
|
||||
Flags<[DriverOption]>;
|
||||
@ -1604,7 +1757,14 @@ def mno_xsaveopt : Flag<["-"], "mno-xsaveopt">, Group<m_x86_Features_Group>;
|
||||
def mno_xsavec : Flag<["-"], "mno-xsavec">, Group<m_x86_Features_Group>;
|
||||
def mno_xsaves : Flag<["-"], "mno-xsaves">, Group<m_x86_Features_Group>;
|
||||
def mno_mwaitx : Flag<["-"], "mno-mwaitx">, Group<m_x86_Features_Group>;
|
||||
def mno_clzero : Flag<["-"], "mno-clzero">, Group<m_x86_Features_Group>;
|
||||
def mno_pku : Flag<["-"], "mno-pku">, Group<m_x86_Features_Group>;
|
||||
def mno_clflushopt : Flag<["-"], "mno-clflushopt">, Group<m_x86_Features_Group>;
|
||||
def mno_clwb : Flag<["-"], "mno-clwb">, Group<m_x86_Features_Group>;
|
||||
def mno_movbe : Flag<["-"], "mno-movbe">, Group<m_x86_Features_Group>;
|
||||
def mno_mpx : Flag<["-"], "mno-mpx">, Group<m_x86_Features_Group>;
|
||||
def mno_sgx : Flag<["-"], "mno-sgx">, Group<m_x86_Features_Group>;
|
||||
def mno_prefetchwt1 : Flag<["-"], "mno-prefetchwt1">, Group<m_x86_Features_Group>;
|
||||
|
||||
def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>,
|
||||
HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">;
|
||||
@ -1626,6 +1786,8 @@ def mcrc : Flag<["-"], "mcrc">, Group<m_arm_Features_Group>,
|
||||
HelpText<"Allow use of CRC instructions (ARM only)">;
|
||||
def mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>,
|
||||
HelpText<"Disallow use of CRC instructions (ARM only)">;
|
||||
def mno_neg_immediates: Flag<["-"], "mno-neg-immediates">, Group<m_arm_Features_Group>,
|
||||
HelpText<"Disallow converting instructions with negative immediates to their negation or inversion.">;
|
||||
|
||||
def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>,
|
||||
HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
|
||||
@ -1648,6 +1810,10 @@ def mamdgpu_debugger_abi : Joined<["-"], "mamdgpu-debugger-abi=">,
|
||||
HelpText<"Generate additional code for specified <version> of debugger ABI (AMDGPU only)">,
|
||||
MetaVarName<"<version>">;
|
||||
|
||||
def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[DriverOption]>;
|
||||
def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[DriverOption]>;
|
||||
def maltivec : Flag<["-"], "maltivec">, Group<m_ppc_Features_Group>;
|
||||
def mno_altivec : Flag<["-"], "mno-altivec">, Group<m_ppc_Features_Group>;
|
||||
def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
|
||||
def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
|
||||
def mpower8_vector : Flag<["-"], "mpower8-vector">,
|
||||
@ -1698,12 +1864,6 @@ def mlongcall: Flag<["-"], "mlongcall">,
|
||||
def mno_longcall : Flag<["-"], "mno-longcall">,
|
||||
Group<m_ppc_Features_Group>;
|
||||
|
||||
def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Enable AltiVec vector initializer syntax">;
|
||||
def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[CC1Option]>;
|
||||
def maltivec : Flag<["-"], "maltivec">, Alias<faltivec>;
|
||||
def mno_altivec : Flag<["-"], "mno-altivec">, Alias<fno_altivec>;
|
||||
|
||||
def mvx : Flag<["-"], "mvx">, Group<m_Group>;
|
||||
def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>;
|
||||
|
||||
@ -1735,7 +1895,8 @@ def mno_incremental_linker_compatible : Flag<["-"], "mno-incremental-linker-comp
|
||||
HelpText<"(integrated-as) Emit an object file which cannot be used with an incremental linker">;
|
||||
def mrtd : Flag<["-"], "mrtd">, Group<m_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Make StdCall calling convention the default">;
|
||||
def msmall_data_threshold_EQ : Joined <["-"], "msmall-data-threshold=">, Group<m_Group>;
|
||||
def msmall_data_threshold_EQ : Joined <["-"], "msmall-data-threshold=">,
|
||||
Group<m_Group>, Alias<G>;
|
||||
def msoft_float : Flag<["-"], "msoft-float">, Group<m_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Use software floating point">;
|
||||
def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>,
|
||||
@ -1747,6 +1908,8 @@ def mpie_copy_relocations : Flag<["-"], "mpie-copy-relocations">, Group<m_Group>
|
||||
Flags<[CC1Option]>,
|
||||
HelpText<"Use copy relocations support for PIE builds">;
|
||||
def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, Group<m_Group>;
|
||||
def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86 only)">,
|
||||
Flags<[CC1Option]>, Group<m_Group>;
|
||||
def mx87 : Flag<["-"], "mx87">, Group<m_x86_Features_Group>;
|
||||
def m80387 : Flag<["-"], "m80387">, Alias<mx87>;
|
||||
def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>;
|
||||
@ -1794,6 +1957,13 @@ def mxsaveopt : Flag<["-"], "mxsaveopt">, Group<m_x86_Features_Group>;
|
||||
def mxsavec : Flag<["-"], "mxsavec">, Group<m_x86_Features_Group>;
|
||||
def mxsaves : Flag<["-"], "mxsaves">, Group<m_x86_Features_Group>;
|
||||
def mmwaitx : Flag<["-"], "mmwaitx">, Group<m_x86_Features_Group>;
|
||||
def mclzero : Flag<["-"], "mclzero">, Group<m_x86_Features_Group>;
|
||||
def mclflushopt : Flag<["-"], "mclflushopt">, Group<m_x86_Features_Group>;
|
||||
def mclwb : Flag<["-"], "mclwb">, Group<m_x86_Features_Group>;
|
||||
def mmovbe : Flag<["-"], "mmovbe">, Group<m_x86_Features_Group>;
|
||||
def mmpx : Flag<["-"], "mmpx">, Group<m_x86_Features_Group>;
|
||||
def msgx : Flag<["-"], "msgx">, Group<m_x86_Features_Group>;
|
||||
def mprefetchwt1 : Flag<["-"], "mprefetchwt1">, Group<m_x86_Features_Group>;
|
||||
def mips16 : Flag<["-"], "mips16">, Group<m_Group>;
|
||||
def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_Group>;
|
||||
def mmicromips : Flag<["-"], "mmicromips">, Group<m_Group>;
|
||||
@ -1938,6 +2108,8 @@ def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">,
|
||||
Flags<[Unsupported]>;
|
||||
def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">,
|
||||
HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">;
|
||||
def print_resource_dir : Flag<["-", "--"], "print-resource-dir">,
|
||||
HelpText<"Print the resource directory pathname">;
|
||||
def print_search_dirs : Flag<["-", "--"], "print-search-dirs">,
|
||||
HelpText<"Print the paths used for finding libraries and programs">;
|
||||
def private__bundle : Flag<["-"], "private_bundle">;
|
||||
@ -1959,10 +2131,15 @@ def resource_dir : Separate<["-"], "resource-dir">,
|
||||
HelpText<"The directory which holds the compiler resource files">;
|
||||
def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption, CoreOption]>,
|
||||
Alias<resource_dir>;
|
||||
def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>;
|
||||
def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>, Group<Link_Group>;
|
||||
def rtlib_EQ : Joined<["-", "--"], "rtlib=">,
|
||||
HelpText<"Compiler runtime library to use">;
|
||||
def r : Flag<["-"], "r">, Flags<[LinkerInput,NoArgumentUnused]>;
|
||||
def frtlib_add_rpath: Flag<["-"], "frtlib-add-rpath">, Flags<[NoArgumentUnused]>,
|
||||
HelpText<"Add -rpath with architecture-specific resource directory to the linker flags">;
|
||||
def fno_rtlib_add_rpath: Flag<["-"], "fno-rtlib-add-rpath">, Flags<[NoArgumentUnused]>,
|
||||
HelpText<"Do not add -rpath with architecture-specific resource directory to the linker flags">;
|
||||
def r : Flag<["-"], "r">, Flags<[LinkerInput,NoArgumentUnused]>,
|
||||
Group<Link_Group>;
|
||||
def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[DriverOption]>,
|
||||
HelpText<"Save intermediate compilation results.">;
|
||||
def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>,
|
||||
@ -2014,7 +2191,7 @@ def no_system_header_prefix : Joined<["--"], "no-system-header-prefix=">,
|
||||
HelpText<"Treat all #include paths starting with <prefix> as not including a "
|
||||
"system header.">;
|
||||
def : Separate<["--"], "no-system-header-prefix">, Alias<no_system_header_prefix>;
|
||||
def s : Flag<["-"], "s">;
|
||||
def s : Flag<["-"], "s">, Group<Link_Group>;
|
||||
def target : Joined<["--"], "target=">, Flags<[DriverOption, CoreOption]>,
|
||||
HelpText<"Generate code for the given target">;
|
||||
def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[DriverOption]>,
|
||||
@ -2028,7 +2205,7 @@ def trigraphs : Flag<["-", "--"], "trigraphs">, Alias<ftrigraphs>,
|
||||
HelpText<"Process trigraph sequences">;
|
||||
def twolevel__namespace__hints : Flag<["-"], "twolevel_namespace_hints">;
|
||||
def twolevel__namespace : Flag<["-"], "twolevel_namespace">;
|
||||
def t : Flag<["-"], "t">;
|
||||
def t : Flag<["-"], "t">, Group<Link_Group>;
|
||||
def umbrella : Separate<["-"], "umbrella">;
|
||||
def undefined : JoinedOrSeparate<["-"], "undefined">, Group<u_Group>;
|
||||
def undef : Flag<["-"], "undef">, Group<u_Group>, Flags<[CC1Option]>,
|
||||
@ -2185,6 +2362,8 @@ def mv55 : Flag<["-"], "mv55">, Group<m_hexagon_Features_Group>,
|
||||
Alias<mcpu_EQ>, AliasArgs<["hexagonv55"]>;
|
||||
def mv60 : Flag<["-"], "mv60">, Group<m_hexagon_Features_Group>,
|
||||
Alias<mcpu_EQ>, AliasArgs<["hexagonv60"]>;
|
||||
def mv62 : Flag<["-"], "mv62">, Group<m_hexagon_Features_Group>,
|
||||
Alias<mcpu_EQ>, AliasArgs<["hexagonv62"]>;
|
||||
def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_Group>,
|
||||
Flags<[CC1Option]>, HelpText<"Enable Hexagon Vector eXtensions">;
|
||||
def mno_hexagon_hvx : Flag<["-"], "mno-hvx">, Group<m_hexagon_Features_Group>,
|
||||
@ -2322,10 +2501,6 @@ defm devirtualize : BooleanFFlag<"devirtualize">, Group<clang_ignored_gcc_optimi
|
||||
defm devirtualize_speculatively : BooleanFFlag<"devirtualize-speculatively">,
|
||||
Group<clang_ignored_gcc_optimization_f_Group>;
|
||||
|
||||
// gfortran options that we recognize in the driver and pass along when
|
||||
// invoking GCC to compile Fortran code.
|
||||
def gfortran_Group : OptionGroup<"gfortran Group">;
|
||||
|
||||
// Generic gfortran options.
|
||||
def A_DASH : Joined<["-"], "A-">, Group<gfortran_Group>;
|
||||
def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined]>, Group<gfortran_Group>;
|
||||
|
@ -34,7 +34,7 @@ class SanitizerArgs {
|
||||
bool CfiCrossDso = false;
|
||||
int AsanFieldPadding = 0;
|
||||
bool AsanSharedRuntime = false;
|
||||
bool AsanUseAfterScope = false;
|
||||
bool AsanUseAfterScope = true;
|
||||
bool LinkCXXRuntimes = false;
|
||||
bool NeedPIE = false;
|
||||
bool Stats = false;
|
||||
|
@ -35,7 +35,7 @@ class Tool {
|
||||
public:
|
||||
// Documents the level of support for response files in this tool.
|
||||
// Response files are necessary if the command line gets too large,
|
||||
// requiring the arguments to be transfered to a file.
|
||||
// requiring the arguments to be transferred to a file.
|
||||
enum ResponseFileSupport {
|
||||
// Provides full support for response files, which means we can transfer
|
||||
// all tool input arguments to a file. E.g.: clang, gcc, binutils and MSVC
|
||||
|
@ -44,6 +44,7 @@ namespace driver {
|
||||
class RegisterEffectiveTriple;
|
||||
class SanitizerArgs;
|
||||
class Tool;
|
||||
class XRayArgs;
|
||||
|
||||
/// ToolChain - Access to tools for a single platform.
|
||||
class ToolChain {
|
||||
@ -94,12 +95,15 @@ class ToolChain {
|
||||
Tool *getOffloadBundler() const;
|
||||
|
||||
mutable std::unique_ptr<SanitizerArgs> SanitizerArguments;
|
||||
mutable std::unique_ptr<XRayArgs> XRayArguments;
|
||||
|
||||
/// The effective clang triple for the current Job.
|
||||
mutable llvm::Triple EffectiveTriple;
|
||||
|
||||
/// Set the toolchain's effective clang triple.
|
||||
void setEffectiveTriple(llvm::Triple ET) const { EffectiveTriple = ET; }
|
||||
void setEffectiveTriple(llvm::Triple ET) const {
|
||||
EffectiveTriple = std::move(ET);
|
||||
}
|
||||
|
||||
friend class RegisterEffectiveTriple;
|
||||
|
||||
@ -175,6 +179,8 @@ class ToolChain {
|
||||
|
||||
const SanitizerArgs& getSanitizerArgs() const;
|
||||
|
||||
const XRayArgs& getXRayArgs() const;
|
||||
|
||||
// Returns the Arg * that explicitly turned on/off rtti, or nullptr.
|
||||
const llvm::opt::Arg *getRTTIArg() const { return CachedRTTIArg; }
|
||||
|
||||
@ -299,6 +305,11 @@ class ToolChain {
|
||||
const char *getCompilerRTArgString(const llvm::opt::ArgList &Args,
|
||||
StringRef Component,
|
||||
bool Shared = false) const;
|
||||
|
||||
// Returns <ResourceDir>/lib/<OSName>/<arch>. This is used by runtimes (such
|
||||
// as OpenMP) to find arch-specific libraries.
|
||||
std::string getArchSpecificLibPath() const;
|
||||
|
||||
/// needsProfileRT - returns true if instrumentation profile is on.
|
||||
static bool needsProfileRT(const llvm::opt::ArgList &Args);
|
||||
|
||||
@ -471,7 +482,7 @@ class RegisterEffectiveTriple {
|
||||
|
||||
public:
|
||||
RegisterEffectiveTriple(const ToolChain &TC, llvm::Triple T) : TC(TC) {
|
||||
TC.setEffectiveTriple(T);
|
||||
TC.setEffectiveTriple(std::move(T));
|
||||
}
|
||||
|
||||
~RegisterEffectiveTriple() { TC.setEffectiveTriple(llvm::Triple()); }
|
||||
|
38
contrib/llvm/tools/clang/include/clang/Driver/XRayArgs.h
Normal file
38
contrib/llvm/tools/clang/include/clang/Driver/XRayArgs.h
Normal file
@ -0,0 +1,38 @@
|
||||
//===--- XRayArgs.h - Arguments for XRay ------------------------*- 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_DRIVER_XRAYARGS_H
|
||||
#define LLVM_CLANG_DRIVER_XRAYARGS_H
|
||||
|
||||
#include "clang/Driver/Types.h"
|
||||
#include "llvm/Option/Arg.h"
|
||||
#include "llvm/Option/ArgList.h"
|
||||
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
|
||||
class ToolChain;
|
||||
|
||||
class XRayArgs {
|
||||
std::vector<std::string> AlwaysInstrumentFiles;
|
||||
std::vector<std::string> NeverInstrumentFiles;
|
||||
std::vector<std::string> ExtraDeps;
|
||||
bool XRayInstrument = false;
|
||||
int InstructionThreshold = 200;
|
||||
|
||||
public:
|
||||
/// Parses the XRay arguments from an argument list.
|
||||
XRayArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
|
||||
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
|
||||
llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const;
|
||||
};
|
||||
|
||||
} // namespace driver
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_DRIVER_XRAYARGS_H
|
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,7 @@ std::unique_ptr<ASTConsumer> CreateASTPrinter(std::unique_ptr<raw_ostream> OS,
|
||||
// AST dumper: dumps the raw AST in human-readable form to stderr; this is
|
||||
// intended for debugging.
|
||||
std::unique_ptr<ASTConsumer> CreateASTDumper(StringRef FilterString,
|
||||
bool DumpDecls,
|
||||
bool DumpDecls, bool Deserialize,
|
||||
bool DumpLookups);
|
||||
|
||||
// AST Decl node lister: prints qualified names of all filterable AST Decl
|
||||
|
@ -51,6 +51,7 @@ class DiagnosticsEngine;
|
||||
class FileEntry;
|
||||
class FileManager;
|
||||
class HeaderSearch;
|
||||
class MemoryBufferCache;
|
||||
class Preprocessor;
|
||||
class PCHContainerOperations;
|
||||
class PCHContainerReader;
|
||||
@ -84,6 +85,7 @@ class ASTUnit : public ModuleLoader {
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
|
||||
IntrusiveRefCntPtr<FileManager> FileMgr;
|
||||
IntrusiveRefCntPtr<SourceManager> SourceMgr;
|
||||
IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
|
||||
std::unique_ptr<HeaderSearch> HeaderInfo;
|
||||
IntrusiveRefCntPtr<TargetInfo> Target;
|
||||
std::shared_ptr<Preprocessor> PP;
|
||||
@ -519,6 +521,8 @@ class ASTUnit : public ModuleLoader {
|
||||
|
||||
const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
|
||||
|
||||
IntrusiveRefCntPtr<ASTReader> getASTReader() const;
|
||||
|
||||
StringRef getOriginalSourceFileName() {
|
||||
return OriginalSourceFile;
|
||||
}
|
||||
|
@ -65,8 +65,6 @@ CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA.
|
||||
CODEGENOPT(EmitGcovNotes , 1, 0) ///< Emit coverage "notes" files, aka GCNO.
|
||||
CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata.
|
||||
CODEGENOPT(EmulatedTLS , 1, 0) ///< Set when -femulated-tls is enabled.
|
||||
/// \brief FP_CONTRACT mode (on/off/fast).
|
||||
ENUM_CODEGENOPT(FPContractMode, FPContractModeKind, 2, FPC_On)
|
||||
/// \brief Embed Bitcode mode (off/all/bitcode/marker).
|
||||
ENUM_CODEGENOPT(EmbedBitcode, EmbedBitcodeKind, 2, Embed_Off)
|
||||
CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
|
||||
@ -83,12 +81,15 @@ CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
|
||||
VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
|
||||
|
||||
CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
|
||||
CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled.
|
||||
CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to
|
||||
///< be generated.
|
||||
CODEGENOPT(PrepareForLTO , 1, 0) ///< Set when -flto is enabled on the
|
||||
///< compile step.
|
||||
CODEGENOPT(EmitSummaryIndex, 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(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
|
||||
///< be used with an incremental
|
||||
///< linker.
|
||||
@ -221,6 +222,9 @@ VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
|
||||
/// The kind of generated debug info.
|
||||
ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 3, codegenoptions::NoDebugInfo)
|
||||
|
||||
/// Whether to generate macro debug info.
|
||||
CODEGENOPT(MacroDebugInfo, 1, 0)
|
||||
|
||||
/// Tune the debug info for this debugger.
|
||||
ENUM_CODEGENOPT(DebuggerTuning, llvm::DebuggerKind, 2,
|
||||
llvm::DebuggerKind::Default)
|
||||
@ -256,6 +260,12 @@ CODEGENOPT(PIECopyRelocations, 1, 0)
|
||||
/// paths that reach the end of a function without executing a required return.
|
||||
CODEGENOPT(StrictReturn, 1, 1)
|
||||
|
||||
/// Whether emit extra debug info for sample pgo profile collection.
|
||||
CODEGENOPT(DebugInfoForProfiling, 1, 0)
|
||||
|
||||
/// Whether 3-component vector type is preserved.
|
||||
CODEGENOPT(PreserveVec3Type, 1, 0)
|
||||
|
||||
#undef CODEGENOPT
|
||||
#undef ENUM_CODEGENOPT
|
||||
#undef VALUE_CODEGENOPT
|
||||
|
@ -69,12 +69,6 @@ class CodeGenOptions : public CodeGenOptionsBase {
|
||||
LocalExecTLSModel
|
||||
};
|
||||
|
||||
enum FPContractModeKind {
|
||||
FPC_Off, // Form fused FP ops only where result will not be affected.
|
||||
FPC_On, // Form fused FP ops according to FP_CONTRACT rules.
|
||||
FPC_Fast // Aggressively fuse FP ops (E.g. FMA).
|
||||
};
|
||||
|
||||
enum StructReturnConventionKind {
|
||||
SRCK_Default, // No special option was passed.
|
||||
SRCK_OnStack, // Small structs on the stack (-fpcc-struct-return).
|
||||
@ -130,8 +124,21 @@ class CodeGenOptions : public CodeGenOptionsBase {
|
||||
/// The float precision limit to use, if non-empty.
|
||||
std::string LimitFloatPrecision;
|
||||
|
||||
/// The name of the bitcode file to link before optzns.
|
||||
std::vector<std::pair<unsigned, std::string>> LinkBitcodeFiles;
|
||||
struct BitcodeFileToLink {
|
||||
/// The filename of the bitcode file to link in.
|
||||
std::string Filename;
|
||||
/// If true, we set attributes functions in the bitcode library according to
|
||||
/// our CodeGenOptions, much as we set attrs on functions that we generate
|
||||
/// ourselves.
|
||||
bool PropagateAttrs = false;
|
||||
/// If true, we use LLVM module internalizer.
|
||||
bool Internalize = false;
|
||||
/// Bitwise combination of llvm::Linker::Flags, passed to the LLVM linker.
|
||||
unsigned LinkFlags = 0;
|
||||
};
|
||||
|
||||
/// The files specified here are linked in to the module before optimizations.
|
||||
std::vector<BitcodeFileToLink> LinkBitcodeFiles;
|
||||
|
||||
/// The user provided name for the "main file", if non-empty. This is useful
|
||||
/// in situations where the input file name does not match the original input
|
||||
@ -175,6 +182,11 @@ class CodeGenOptions : public CodeGenOptionsBase {
|
||||
/// importing.
|
||||
std::string ThinLTOIndexFile;
|
||||
|
||||
/// Name of a file that can optionally be written with minimized bitcode
|
||||
/// to be used as input for the ThinLTO thin link step, which only needs
|
||||
/// the summary and module symbol table (and not, e.g. any debug metadata).
|
||||
std::string ThinLinkBitcodeFile;
|
||||
|
||||
/// A list of file names passed with -fcuda-include-gpubinary options to
|
||||
/// forward to CUDA runtime back-end for incorporating them into host-side
|
||||
/// object file.
|
||||
@ -206,7 +218,7 @@ class CodeGenOptions : public CodeGenOptionsBase {
|
||||
/// flag.
|
||||
std::shared_ptr<llvm::Regex> OptimizationRemarkAnalysisPattern;
|
||||
|
||||
/// Set of files definining the rules for the symbol rewriting.
|
||||
/// Set of files defining the rules for the symbol rewriting.
|
||||
std::vector<std::string> RewriteMapFiles;
|
||||
|
||||
/// Set of sanitizer checks that are non-fatal (i.e. execution should be
|
||||
|
@ -44,6 +44,7 @@ class ExternalASTSource;
|
||||
class FileEntry;
|
||||
class FileManager;
|
||||
class FrontendAction;
|
||||
class MemoryBufferCache;
|
||||
class Module;
|
||||
class Preprocessor;
|
||||
class Sema;
|
||||
@ -90,6 +91,9 @@ class CompilerInstance : public ModuleLoader {
|
||||
/// The source manager.
|
||||
IntrusiveRefCntPtr<SourceManager> SourceMgr;
|
||||
|
||||
/// The cache of PCM files.
|
||||
IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
|
||||
|
||||
/// The preprocessor.
|
||||
std::shared_ptr<Preprocessor> PP;
|
||||
|
||||
@ -142,13 +146,13 @@ class CompilerInstance : public ModuleLoader {
|
||||
|
||||
/// \brief Whether we should (re)build the global module index once we
|
||||
/// have finished with this translation unit.
|
||||
bool BuildGlobalModuleIndex;
|
||||
bool BuildGlobalModuleIndex = false;
|
||||
|
||||
/// \brief We have a full global module index, with all modules.
|
||||
bool HaveFullGlobalModuleIndex;
|
||||
bool HaveFullGlobalModuleIndex = false;
|
||||
|
||||
/// \brief One or more modules failed to build.
|
||||
bool ModuleBuildFailed;
|
||||
bool ModuleBuildFailed = false;
|
||||
|
||||
/// \brief Holds information about the output file.
|
||||
///
|
||||
@ -178,7 +182,7 @@ class CompilerInstance : public ModuleLoader {
|
||||
explicit CompilerInstance(
|
||||
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
|
||||
std::make_shared<PCHContainerOperations>(),
|
||||
bool BuildingModule = false);
|
||||
MemoryBufferCache *SharedPCMCache = nullptr);
|
||||
~CompilerInstance() override;
|
||||
|
||||
/// @name High-Level Operations
|
||||
@ -658,6 +662,8 @@ class CompilerInstance : public ModuleLoader {
|
||||
bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
|
||||
const PCHContainerReader &PCHContainerRdr,
|
||||
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
|
||||
DependencyFileGenerator *DependencyFile,
|
||||
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
|
||||
void *DeserializationListener, bool OwnDeserializationListener,
|
||||
bool Preamble, bool UseGlobalModuleIndex);
|
||||
|
||||
@ -783,6 +789,8 @@ class CompilerInstance : public ModuleLoader {
|
||||
}
|
||||
|
||||
void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
|
||||
|
||||
MemoryBufferCache &getPCMCache() const { return *PCMCache; }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
@ -80,6 +80,8 @@ class GeneratePCHAction : public ASTFrontendAction {
|
||||
|
||||
bool hasASTFileSupport() const override { return false; }
|
||||
|
||||
bool shouldEraseOutputFiles() override;
|
||||
|
||||
public:
|
||||
/// \brief Compute the AST consumer arguments that will be used to
|
||||
/// create the PCHGenerator instance returned by CreateASTConsumer.
|
||||
|
@ -81,7 +81,7 @@ enum InputKind {
|
||||
IK_LLVM_IR
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// \brief An input file for the front end.
|
||||
class FrontendInputFile {
|
||||
/// \brief The file name, or "-" to read from standard input.
|
||||
@ -109,6 +109,13 @@ class FrontendInputFile {
|
||||
bool isEmpty() const { return File.empty() && Buffer == nullptr; }
|
||||
bool isFile() const { return !isBuffer(); }
|
||||
bool isBuffer() const { return Buffer != nullptr; }
|
||||
bool isPreprocessed() const {
|
||||
return Kind == IK_PreprocessedC ||
|
||||
Kind == IK_PreprocessedCXX ||
|
||||
Kind == IK_PreprocessedObjC ||
|
||||
Kind == IK_PreprocessedObjCXX ||
|
||||
Kind == IK_PreprocessedCuda;
|
||||
}
|
||||
|
||||
StringRef getFile() const {
|
||||
assert(isFile());
|
||||
@ -150,6 +157,8 @@ class FrontendOptions {
|
||||
///< global module index if needed.
|
||||
unsigned ASTDumpDecls : 1; ///< Whether we include declaration
|
||||
///< dumps in AST dumps.
|
||||
unsigned ASTDumpAll : 1; ///< Whether we deserialize all decls
|
||||
///< when forming AST dumps.
|
||||
unsigned ASTDumpLookups : 1; ///< Whether we include lookup table
|
||||
///< dumps in AST dumps.
|
||||
unsigned BuildingImplicitModule : 1; ///< Whether we are performing an
|
||||
|
@ -29,7 +29,8 @@ enum LangFeatures {
|
||||
Digraphs = (1 << 8),
|
||||
GNUMode = (1 << 9),
|
||||
HexFloat = (1 << 10),
|
||||
ImplicitInt = (1 << 11)
|
||||
ImplicitInt = (1 << 11),
|
||||
OpenCL = (1 << 12)
|
||||
};
|
||||
|
||||
}
|
||||
@ -91,6 +92,9 @@ struct LangStandard {
|
||||
/// hasImplicitInt - Language allows variables to be typed as int implicitly.
|
||||
bool hasImplicitInt() const { return Flags & frontend::ImplicitInt; }
|
||||
|
||||
/// isOpenCL - Language is a OpenCL variant.
|
||||
bool isOpenCL() const { return Flags & frontend::OpenCL; }
|
||||
|
||||
static const LangStandard &getLangStandardForKind(Kind K);
|
||||
static const LangStandard *getLangStandardForName(StringRef Name);
|
||||
};
|
||||
|
@ -142,16 +142,16 @@ LANGSTANDARD(gnucxx1z, "gnu++1z",
|
||||
// OpenCL
|
||||
LANGSTANDARD(opencl, "cl",
|
||||
"OpenCL 1.0",
|
||||
LineComment | C99 | Digraphs | HexFloat)
|
||||
LineComment | C99 | Digraphs | HexFloat | OpenCL)
|
||||
LANGSTANDARD(opencl11, "cl1.1",
|
||||
"OpenCL 1.1",
|
||||
LineComment | C99 | Digraphs | HexFloat)
|
||||
LineComment | C99 | Digraphs | HexFloat | OpenCL)
|
||||
LANGSTANDARD(opencl12, "cl1.2",
|
||||
"OpenCL 1.2",
|
||||
LineComment | C99 | Digraphs | HexFloat)
|
||||
LineComment | C99 | Digraphs | HexFloat | OpenCL)
|
||||
LANGSTANDARD(opencl20, "cl2.0",
|
||||
"OpenCL 2.0",
|
||||
LineComment | C99 | Digraphs | HexFloat)
|
||||
LineComment | C99 | Digraphs | HexFloat | OpenCL)
|
||||
|
||||
LANGSTANDARD_ALIAS(opencl, "CL")
|
||||
LANGSTANDARD_ALIAS(opencl11, "CL1.1")
|
||||
|
@ -10,6 +10,7 @@
|
||||
#ifndef LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
|
||||
#define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
|
||||
|
||||
#include "clang/Basic/Module.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
@ -29,7 +30,7 @@ class DiagnosticsEngine;
|
||||
class CompilerInstance;
|
||||
|
||||
struct PCHBuffer {
|
||||
uint64_t Signature;
|
||||
ASTFileSignature Signature;
|
||||
llvm::SmallVector<char, 0> Data;
|
||||
bool IsComplete;
|
||||
};
|
||||
|
@ -51,6 +51,8 @@ enum class SymbolKind : uint8_t {
|
||||
Constructor,
|
||||
Destructor,
|
||||
ConversionFunction,
|
||||
|
||||
Parameter,
|
||||
};
|
||||
|
||||
enum class SymbolLanguage {
|
||||
@ -77,8 +79,9 @@ enum class SymbolProperty : uint8_t {
|
||||
IBAnnotated = 1 << 4,
|
||||
IBOutletCollection = 1 << 5,
|
||||
GKInspectable = 1 << 6,
|
||||
Local = 1 << 7,
|
||||
};
|
||||
static const unsigned SymbolPropertyBitNum = 7;
|
||||
static const unsigned SymbolPropertyBitNum = 8;
|
||||
typedef unsigned SymbolPropertySet;
|
||||
|
||||
/// Set of roles that are attributed to symbol occurrences.
|
||||
@ -125,8 +128,12 @@ struct SymbolInfo {
|
||||
|
||||
SymbolInfo getSymbolInfo(const Decl *D);
|
||||
|
||||
bool isFunctionLocalSymbol(const Decl *D);
|
||||
|
||||
void applyForEachSymbolRole(SymbolRoleSet Roles,
|
||||
llvm::function_ref<void(SymbolRole)> Fn);
|
||||
bool applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,
|
||||
llvm::function_ref<bool(SymbolRole)> Fn);
|
||||
void printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS);
|
||||
|
||||
/// \returns true if no name was printed, false otherwise.
|
||||
|
@ -14,9 +14,14 @@
|
||||
#include <memory>
|
||||
|
||||
namespace clang {
|
||||
class ASTReader;
|
||||
class ASTUnit;
|
||||
class FrontendAction;
|
||||
|
||||
namespace serialization {
|
||||
class ModuleFile;
|
||||
}
|
||||
|
||||
namespace index {
|
||||
class IndexDataConsumer;
|
||||
|
||||
@ -42,6 +47,11 @@ void indexASTUnit(ASTUnit &Unit,
|
||||
std::shared_ptr<IndexDataConsumer> DataConsumer,
|
||||
IndexingOptions Opts);
|
||||
|
||||
void indexModuleFile(serialization::ModuleFile &Mod,
|
||||
ASTReader &Reader,
|
||||
std::shared_ptr<IndexDataConsumer> DataConsumer,
|
||||
IndexingOptions Opts);
|
||||
|
||||
} // namespace index
|
||||
} // namespace clang
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
namespace clang {
|
||||
class Decl;
|
||||
class MacroDefinitionRecord;
|
||||
class SourceLocation;
|
||||
class SourceManager;
|
||||
|
||||
namespace index {
|
||||
@ -54,6 +55,8 @@ void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS);
|
||||
/// \returns true on error, false on success.
|
||||
bool generateUSRForMacro(const MacroDefinitionRecord *MD,
|
||||
const SourceManager &SM, SmallVectorImpl<char> &Buf);
|
||||
bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
|
||||
const SourceManager &SM, SmallVectorImpl<char> &Buf);
|
||||
|
||||
} // namespace index
|
||||
} // namespace clang
|
||||
|
@ -178,6 +178,8 @@ class HeaderSearchOptions {
|
||||
|
||||
unsigned ModulesValidateDiagnosticOptions : 1;
|
||||
|
||||
unsigned ModulesHashContent : 1;
|
||||
|
||||
HeaderSearchOptions(StringRef _Sysroot = "/")
|
||||
: Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0),
|
||||
ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0),
|
||||
@ -186,8 +188,8 @@ class HeaderSearchOptions {
|
||||
UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
|
||||
UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
|
||||
ModulesValidateOncePerBuildSession(false),
|
||||
ModulesValidateSystemHeaders(false),
|
||||
UseDebugInfo(false), ModulesValidateDiagnosticOptions(true) {}
|
||||
ModulesValidateSystemHeaders(false), UseDebugInfo(false),
|
||||
ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {}
|
||||
|
||||
/// AddPath - Add the \p Path path to the specified \p Group list.
|
||||
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
|
||||
|
@ -47,6 +47,7 @@ class ExternalPreprocessorSource;
|
||||
class FileManager;
|
||||
class FileEntry;
|
||||
class HeaderSearch;
|
||||
class MemoryBufferCache;
|
||||
class PragmaNamespace;
|
||||
class PragmaHandler;
|
||||
class CommentHandler;
|
||||
@ -102,6 +103,7 @@ class Preprocessor {
|
||||
const TargetInfo *AuxTarget;
|
||||
FileManager &FileMgr;
|
||||
SourceManager &SourceMgr;
|
||||
MemoryBufferCache &PCMCache;
|
||||
std::unique_ptr<ScratchBuffer> ScratchBuf;
|
||||
HeaderSearch &HeaderInfo;
|
||||
ModuleLoader &TheModuleLoader;
|
||||
@ -652,6 +654,7 @@ class Preprocessor {
|
||||
public:
|
||||
Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
|
||||
DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM,
|
||||
MemoryBufferCache &PCMCache,
|
||||
HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
|
||||
IdentifierInfoLookup *IILookup = nullptr,
|
||||
bool OwnsHeaderSearch = false,
|
||||
@ -691,6 +694,7 @@ class Preprocessor {
|
||||
const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
|
||||
FileManager &getFileManager() const { return FileMgr; }
|
||||
SourceManager &getSourceManager() const { return SourceMgr; }
|
||||
MemoryBufferCache &getPCMCache() const { return PCMCache; }
|
||||
HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
|
||||
|
||||
IdentifierTable &getIdentifierTable() { return Identifiers; }
|
||||
@ -1077,6 +1081,24 @@ class Preprocessor {
|
||||
/// \brief Disable the last EnableBacktrackAtThisPos call.
|
||||
void CommitBacktrackedTokens();
|
||||
|
||||
struct CachedTokensRange {
|
||||
CachedTokensTy::size_type Begin, End;
|
||||
};
|
||||
|
||||
private:
|
||||
/// \brief A range of cached tokens that should be erased after lexing
|
||||
/// when backtracking requires the erasure of such cached tokens.
|
||||
Optional<CachedTokensRange> CachedTokenRangeToErase;
|
||||
|
||||
public:
|
||||
/// \brief Returns the range of cached tokens that were lexed since
|
||||
/// EnableBacktrackAtThisPos() was previously called.
|
||||
CachedTokensRange LastCachedTokenRange();
|
||||
|
||||
/// \brief Erase the range of cached tokens that were lexed since
|
||||
/// EnableBacktrackAtThisPos() was previously called.
|
||||
void EraseCachedTokens(CachedTokensRange TokenRange);
|
||||
|
||||
/// \brief Make Preprocessor re-lex the tokens that were lexed since
|
||||
/// EnableBacktrackAtThisPos() was previously called.
|
||||
void Backtrack();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user