Merge clang trunk r300422 and resolve conflicts.

This commit is contained in:
Dimitry Andric 2017-04-16 16:31:20 +00:00
commit 20e90f04ad
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/clang500-import/; revision=317030
525 changed files with 57991 additions and 32434 deletions

View File

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

View File

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

View File

@ -22,6 +22,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cstddef>
#include <cstring>
#include <memory>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -31,6 +31,7 @@ namespace clang {
UTT_HasTrivialDestructor,
UTT_HasVirtualDestructor,
UTT_IsAbstract,
UTT_IsAggregate,
UTT_IsArithmetic,
UTT_IsArray,
UTT_IsClass,

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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